Version Description
(2022-03-23) =
Release notes: Out now: Activity Log for MainWP 2.0 & WP Activity Log 4.4.1
-
Improvements & changes
- All of the plugin's code is now using the WordPress coding standards.
- Removed the reporting and search code from the free edition plugin that was used by the MainWP extension.
-
Bug fixes
- Fixed: PHP fatal error when index.php file is saved in the custom sensors directory.
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.1 |
Comparing to | |
See all releases |
Code changes from version 4.4.0 to 4.4.1
- classes/AbstractLogger.php +17 -6
- classes/AbstractMetaDataSensor.php +19 -18
- classes/AbstractSandboxTask.php +20 -12
- classes/AbstractSensor.php +25 -32
- classes/AbstractView.php +54 -41
- classes/Adapters/ActiveRecordInterface.php +17 -15
- classes/Adapters/MetaInterface.php +2 -2
- classes/Adapters/MySQL/ActiveRecordAdapter.php +158 -149
- classes/Adapters/MySQL/MetaAdapter.php +18 -18
- classes/Adapters/MySQL/OccurrenceAdapter.php +81 -80
- classes/Adapters/MySQL/QueryAdapter.php +105 -91
- classes/Adapters/MySQL/TmpUserAdapter.php +10 -10
- classes/Adapters/OccurrenceInterface.php +10 -10
- classes/Adapters/QueryInterface.php +18 -7
- classes/Alert.php +76 -61
- classes/AlertFormatter.php +107 -71
- classes/AlertFormatterConfiguration.php +138 -63
- classes/AlertFormatterFactory.php +35 -21
- classes/AlertManager.php +257 -215
- classes/AuditLogGridView.php +99 -120
- classes/AuditLogListView.php +76 -85
- classes/Autoloader.php +10 -4
- classes/Connector/AbstractConnector.php +14 -14
- classes/Connector/ConnectorFactory.php +14 -14
- classes/Connector/ConnectorInterface.php +12 -12
- classes/Connector/MySQLDB.php +126 -127
- classes/Connector/wp-db-custom.php +16 -14
- classes/ConstantManager.php +24 -19
- classes/ExtensionPlaceholderView.php +42 -18
- classes/Helpers/DataHelper.php +4 -4
- classes/Helpers/Options.php +38 -44
- classes/Loggers/Database.php +37 -36
- classes/MainWpApi.php +32 -171
- classes/Models/ActiveRecord.php +79 -75
- classes/Models/Meta.php +19 -19
- classes/Models/Occurrence.php +123 -95
- classes/Models/OccurrenceQuery.php +1 -1
- classes/Models/Query.php +79 -36
- classes/Models/TmpUser.php +1 -1
- classes/Nicer.php +10 -0
- classes/Ref.php +1 -0
- classes/ReportArgs.php +18 -5
- classes/SensorManager.php +16 -15
- classes/Sensors/ACFMeta.php +45 -36
- classes/Sensors/Comments.php +27 -26
- classes/Sensors/Content.php +126 -139
- classes/Sensors/Database.php +75 -69
- classes/Sensors/Files.php +25 -20
- classes/Sensors/LogInOut.php +93 -92
- classes/Sensors/MainWP.php +47 -43
- classes/Sensors/Menus.php +133 -124
- classes/Sensors/MetaData.php +53 -50
- classes/Sensors/Multisite.php +52 -50
- classes/Sensors/MultisiteSignUp.php +4 -4
- classes/Sensors/PluginsThemes.php +120 -102
- classes/Sensors/Register.php +5 -5
- classes/Sensors/System.php +85 -81
- classes/Sensors/UserProfile.php +56 -42
- classes/Sensors/Widgets.php +65 -57
- classes/Settings.php +544 -379
- classes/ThirdPartyExtensions/AbstractExtension.php +41 -6
- classes/ThirdPartyExtensions/BBPressExtension.php +34 -1
- classes/ThirdPartyExtensions/GravityFormsExtension.php +32 -2
- classes/ThirdPartyExtensions/TablePressExtension.php +33 -0
- classes/ThirdPartyExtensions/WFCMExtension.php +46 -5
- classes/ThirdPartyExtensions/WPFormsExtension.php +35 -2
- classes/ThirdPartyExtensions/WooCommerceExtension.php +40 -4
- classes/ThirdPartyExtensions/YoastSeoExtension.php +34 -1
- classes/Uninstall.php +12 -7
- classes/Upgrade/MetadataMigration.php +50 -37
- classes/Upgrade/Upgrade_43000_to_44400.php +53 -22
- classes/Utilities/DateTimeFormatter.php +59 -21
- classes/Utilities/Emailer.php +11 -8
- classes/Utilities/FileSystemUtils.php +8 -2
- classes/Utilities/PluginInstallAndActivate.php +4 -5
- classes/Utilities/PluginInstallerAction.php +3 -4
- classes/Utilities/RequestUtils.php +19 -2
- classes/Utilities/UserUtils.php +16 -6
- classes/ViewManager.php +138 -125
- classes/Views/AuditLog.php +200 -199
- classes/Views/EmailNotifications.php +30 -28
- classes/Views/ExternalDB.php +25 -23
- classes/Views/Help.php +58 -65
- classes/Views/LogInUsers.php +26 -24
- classes/Views/Reports.php +25 -23
- classes/Views/Search.php +27 -27
- classes/Views/Settings.php +674 -642
- classes/Views/SetupWizard.php +68 -63
- classes/Views/ToggleAlerts.php +78 -74
- classes/Views/addons/html-view.php +8 -7
- classes/WidgetManager.php +23 -23
- css/dist/wsal-wizard.css +1 -177
- css/dist/wsal-wizard.min.css +0 -1
- defaults.php +819 -819
classes/AbstractLogger.php
CHANGED
@@ -1,4 +1,15 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Abstract class used in the Logger.
|
@@ -29,12 +40,12 @@ abstract class WSAL_AbstractLogger {
|
|
29 |
/**
|
30 |
* Log alert abstract.
|
31 |
*
|
32 |
-
* @param integer $type
|
33 |
-
* @param array
|
34 |
-
* @param integer $date
|
35 |
* @param integer $site_id (Optional) - Site id.
|
36 |
*/
|
37 |
-
public
|
38 |
|
39 |
/**
|
40 |
* Determines what is the correct timestamp for the event.
|
@@ -43,8 +54,8 @@ abstract class WSAL_AbstractLogger {
|
|
43 |
* action scheduler in 4.3.0. The $legacy_date attribute is only used for migration of legacy data. This should be
|
44 |
* removed in future releases.
|
45 |
*
|
46 |
-
* @param array $metadata
|
47 |
-
* @param int
|
48 |
*
|
49 |
* @return float GMT timestamp including microseconds.
|
50 |
* @since 4.3.0
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Abstract logger class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage loggers
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly.
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
|
14 |
/**
|
15 |
* Abstract class used in the Logger.
|
40 |
/**
|
41 |
* Log alert abstract.
|
42 |
*
|
43 |
+
* @param integer $type - Alert code.
|
44 |
+
* @param array $data - Metadata.
|
45 |
+
* @param integer $date (Optional) - Created on.
|
46 |
* @param integer $site_id (Optional) - Site id.
|
47 |
*/
|
48 |
+
abstract public function log( $type, $data = array(), $date = null, $site_id = null );
|
49 |
|
50 |
/**
|
51 |
* Determines what is the correct timestamp for the event.
|
54 |
* action scheduler in 4.3.0. The $legacy_date attribute is only used for migration of legacy data. This should be
|
55 |
* removed in future releases.
|
56 |
*
|
57 |
+
* @param array $metadata Event metadata.
|
58 |
+
* @param int $legacy_date Legacy date only used when migrating old db event format to the new one.
|
59 |
*
|
60 |
* @return float GMT timestamp including microseconds.
|
61 |
* @since 4.3.0
|
classes/AbstractMetaDataSensor.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Abstract meta data sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -16,9 +17,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
16 |
/**
|
17 |
* Abstract sensor for meta data.
|
18 |
*
|
19 |
-
* @package
|
20 |
* @subpackage sensors
|
21 |
-
* @since
|
22 |
*/
|
23 |
abstract class WSAL_AbstractMetaDataSensor extends WSAL_AbstractSensor {
|
24 |
|
@@ -33,12 +34,12 @@ abstract class WSAL_AbstractMetaDataSensor extends WSAL_AbstractSensor {
|
|
33 |
* Check "Excluded Custom Fields" or meta keys starts with "_".
|
34 |
*
|
35 |
* @param string $object_type Object type - user or post.
|
36 |
-
* @param int
|
37 |
-
* @param string $meta_key
|
38 |
*
|
39 |
-
* @return boolean
|
40 |
*/
|
41 |
-
protected function
|
42 |
// Check if excluded meta key or starts with _.
|
43 |
if ( '_' === substr( $meta_key, 0, 1 ) ) {
|
44 |
/**
|
@@ -54,7 +55,7 @@ abstract class WSAL_AbstractMetaDataSensor extends WSAL_AbstractSensor {
|
|
54 |
}
|
55 |
|
56 |
return false;
|
57 |
-
} elseif ( $this->
|
58 |
return false;
|
59 |
} else {
|
60 |
return true;
|
@@ -68,7 +69,7 @@ abstract class WSAL_AbstractMetaDataSensor extends WSAL_AbstractSensor {
|
|
68 |
*
|
69 |
* @return array $editor_link - Name and value link
|
70 |
*/
|
71 |
-
protected function
|
72 |
$post_id = is_int( $post ) ? intval( $post ) : $post->ID;
|
73 |
return array(
|
74 |
'name' => 'EditorLinkPost',
|
@@ -85,22 +86,22 @@ abstract class WSAL_AbstractMetaDataSensor extends WSAL_AbstractSensor {
|
|
85 |
*
|
86 |
* @return boolean is excluded from monitoring true|false
|
87 |
*/
|
88 |
-
public function
|
89 |
-
$custom_fields =
|
90 |
-
if ('post' === $object_type) {
|
91 |
-
$custom_fields = $this->plugin->settings()->
|
92 |
-
}
|
93 |
-
$custom_fields = $this->plugin->settings()->
|
94 |
}
|
95 |
|
96 |
-
if ( in_array( $custom, $custom_fields ) ) {
|
97 |
return true;
|
98 |
}
|
99 |
|
100 |
foreach ( $custom_fields as $field ) {
|
101 |
if ( false !== strpos( $field, '*' ) ) {
|
102 |
// Wildcard str[any_character] when you enter (str*).
|
103 |
-
if ( substr( $field, - 1 )
|
104 |
$field = rtrim( $field, '*' );
|
105 |
if ( preg_match( "/^$field/", $custom ) ) {
|
106 |
return true;
|
4 |
*
|
5 |
* Abstract meta data sensor file.
|
6 |
*
|
7 |
+
* @since 4.1.3
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
17 |
/**
|
18 |
* Abstract sensor for meta data.
|
19 |
*
|
20 |
+
* @package wsal
|
21 |
* @subpackage sensors
|
22 |
+
* @since 4.1.3
|
23 |
*/
|
24 |
abstract class WSAL_AbstractMetaDataSensor extends WSAL_AbstractSensor {
|
25 |
|
34 |
* Check "Excluded Custom Fields" or meta keys starts with "_".
|
35 |
*
|
36 |
* @param string $object_type Object type - user or post.
|
37 |
+
* @param int $object_id - Object ID.
|
38 |
+
* @param string $meta_key - Meta key.
|
39 |
*
|
40 |
+
* @return boolean Can log true|false
|
41 |
*/
|
42 |
+
protected function can_log_meta_key( $object_type, $object_id, $meta_key ) {
|
43 |
// Check if excluded meta key or starts with _.
|
44 |
if ( '_' === substr( $meta_key, 0, 1 ) ) {
|
45 |
/**
|
55 |
}
|
56 |
|
57 |
return false;
|
58 |
+
} elseif ( $this->is_excluded_custom_fields( $object_type, $meta_key ) ) {
|
59 |
return false;
|
60 |
} else {
|
61 |
return true;
|
69 |
*
|
70 |
* @return array $editor_link - Name and value link
|
71 |
*/
|
72 |
+
protected function get_editor_link( $post ) {
|
73 |
$post_id = is_int( $post ) ? intval( $post ) : $post->ID;
|
74 |
return array(
|
75 |
'name' => 'EditorLinkPost',
|
86 |
*
|
87 |
* @return boolean is excluded from monitoring true|false
|
88 |
*/
|
89 |
+
public function is_excluded_custom_fields( $object_type, $custom ) {
|
90 |
+
$custom_fields = array();
|
91 |
+
if ( 'post' === $object_type ) {
|
92 |
+
$custom_fields = $this->plugin->settings()->get_excluded_post_meta_fields();
|
93 |
+
} elseif ( 'user' === $object_type ) {
|
94 |
+
$custom_fields = $this->plugin->settings()->get_excluded_user_meta_fields();
|
95 |
}
|
96 |
|
97 |
+
if ( in_array( $custom, $custom_fields ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
98 |
return true;
|
99 |
}
|
100 |
|
101 |
foreach ( $custom_fields as $field ) {
|
102 |
if ( false !== strpos( $field, '*' ) ) {
|
103 |
// Wildcard str[any_character] when you enter (str*).
|
104 |
+
if ( '*' === substr( $field, - 1 ) ) {
|
105 |
$field = rtrim( $field, '*' );
|
106 |
if ( preg_match( "/^$field/", $custom ) ) {
|
107 |
return true;
|
classes/AbstractSandboxTask.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Abstract Sandbox Task class.
|
4 |
*
|
@@ -20,17 +26,17 @@ abstract class WSAL_AbstractSandboxTask {
|
|
20 |
}
|
21 |
|
22 |
// Set up shutdown handler.
|
23 |
-
register_shutdown_function( array( $this, '
|
24 |
|
25 |
// Run event sequence.
|
26 |
-
$this->
|
27 |
try {
|
28 |
-
$this->
|
29 |
} catch ( Exception $ex ) {
|
30 |
-
$this->
|
31 |
-
$this->
|
32 |
}
|
33 |
-
$this->
|
34 |
|
35 |
// Shutdown.
|
36 |
die();
|
@@ -39,7 +45,7 @@ abstract class WSAL_AbstractSandboxTask {
|
|
39 |
/**
|
40 |
* Header.
|
41 |
*/
|
42 |
-
protected function
|
43 |
echo '<!DOCTYPE html><html><body style="margin: 0; padding: 8px; font: 12px Arial; color: #333;">';
|
44 |
echo '<div style="position: fixed; top: 0; left: 0; right: 0; padding: 8px; background: #F0F0F0;">';
|
45 |
echo ' <div id="bar" style=" border-top: 2px solid #0AE; top: 20px; height: 0; width: 0%;"> </div>';
|
@@ -58,7 +64,7 @@ abstract class WSAL_AbstractSandboxTask {
|
|
58 |
/**
|
59 |
* Footer.
|
60 |
*/
|
61 |
-
protected function
|
62 |
echo '<div style="display: none;">';
|
63 |
flush();
|
64 |
}
|
@@ -66,12 +72,12 @@ abstract class WSAL_AbstractSandboxTask {
|
|
66 |
/**
|
67 |
* Method: Execute.
|
68 |
*/
|
69 |
-
protected
|
70 |
|
71 |
/**
|
72 |
* Method: Shutdown.
|
73 |
*/
|
74 |
-
public function
|
75 |
echo '</div></body></html>';
|
76 |
flush();
|
77 |
}
|
@@ -81,7 +87,7 @@ abstract class WSAL_AbstractSandboxTask {
|
|
81 |
*
|
82 |
* @param mixed $percent - Progress percentage.
|
83 |
*/
|
84 |
-
protected function
|
85 |
echo '<script>bar.style.width=prg.innerHTML="' . number_format( $percent, 2 ) . '%";</script>';
|
86 |
flush();
|
87 |
}
|
@@ -91,8 +97,10 @@ abstract class WSAL_AbstractSandboxTask {
|
|
91 |
*
|
92 |
* @param string $message - Message.
|
93 |
* @param bool $sticky - True if sticky.
|
|
|
|
|
94 |
*/
|
95 |
-
protected function
|
96 |
if ( $sticky ) {
|
97 |
echo '<script>msgs.appendChild(document.createTextNode(' . json_encode( $message . PHP_EOL ) . ')); window.scroll(0, document.body.scrollHeight);</script>';
|
98 |
} else {
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WSAL_AbstractSandboxTask class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
*/
|
7 |
+
|
8 |
/**
|
9 |
* Abstract Sandbox Task class.
|
10 |
*
|
26 |
}
|
27 |
|
28 |
// Set up shutdown handler.
|
29 |
+
register_shutdown_function( array( $this, 'shutdown' ) );
|
30 |
|
31 |
// Run event sequence.
|
32 |
+
$this->header();
|
33 |
try {
|
34 |
+
$this->execute();
|
35 |
} catch ( Exception $ex ) {
|
36 |
+
$this->message( get_class( $ex ) . ' [' . basename( $ex->getFile() ) . ':' . $ex->getLine() . ']: ' . $ex->getMessage() );
|
37 |
+
$this->message( $ex->getTraceAsString(), true );
|
38 |
}
|
39 |
+
$this->footer();
|
40 |
|
41 |
// Shutdown.
|
42 |
die();
|
45 |
/**
|
46 |
* Header.
|
47 |
*/
|
48 |
+
protected function header() {
|
49 |
echo '<!DOCTYPE html><html><body style="margin: 0; padding: 8px; font: 12px Arial; color: #333;">';
|
50 |
echo '<div style="position: fixed; top: 0; left: 0; right: 0; padding: 8px; background: #F0F0F0;">';
|
51 |
echo ' <div id="bar" style=" border-top: 2px solid #0AE; top: 20px; height: 0; width: 0%;"> </div>';
|
64 |
/**
|
65 |
* Footer.
|
66 |
*/
|
67 |
+
protected function footer() {
|
68 |
echo '<div style="display: none;">';
|
69 |
flush();
|
70 |
}
|
72 |
/**
|
73 |
* Method: Execute.
|
74 |
*/
|
75 |
+
abstract protected function execute();
|
76 |
|
77 |
/**
|
78 |
* Method: Shutdown.
|
79 |
*/
|
80 |
+
public function shutdown() {
|
81 |
echo '</div></body></html>';
|
82 |
flush();
|
83 |
}
|
87 |
*
|
88 |
* @param mixed $percent - Progress percentage.
|
89 |
*/
|
90 |
+
protected function progress( $percent ) {
|
91 |
echo '<script>bar.style.width=prg.innerHTML="' . number_format( $percent, 2 ) . '%";</script>';
|
92 |
flush();
|
93 |
}
|
97 |
*
|
98 |
* @param string $message - Message.
|
99 |
* @param bool $sticky - True if sticky.
|
100 |
+
*
|
101 |
+
* @phpcs:disable WordPress.WP.AlternativeFunctions.json_encode_json_encode
|
102 |
*/
|
103 |
+
protected function message( $message, $sticky = false ) {
|
104 |
if ( $sticky ) {
|
105 |
echo '<script>msgs.appendChild(document.createTextNode(' . json_encode( $message . PHP_EOL ) . ')); window.scroll(0, document.body.scrollHeight);</script>';
|
106 |
} else {
|
classes/AbstractSensor.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Abstract sensor class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -16,8 +17,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
16 |
/**
|
17 |
* Abstract class used in all the sensors.
|
18 |
*
|
19 |
-
* @see
|
20 |
-
* @package
|
|
|
21 |
*/
|
22 |
abstract class WSAL_AbstractSensor {
|
23 |
|
@@ -42,14 +44,17 @@ abstract class WSAL_AbstractSensor {
|
|
42 |
*
|
43 |
* @return boolean
|
44 |
*/
|
45 |
-
protected function
|
46 |
-
return $this->plugin->
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
* Method: Hook events related to sensor.
|
51 |
*/
|
52 |
-
|
|
|
|
|
|
|
53 |
|
54 |
/**
|
55 |
* Method: Log the message for sensor.
|
@@ -58,13 +63,13 @@ abstract class WSAL_AbstractSensor {
|
|
58 |
* @param string $message - Alert message.
|
59 |
* @param mixed $args - Message arguments.
|
60 |
*/
|
61 |
-
protected function
|
62 |
-
$this->plugin->alerts->
|
63 |
$type,
|
64 |
array(
|
65 |
'Message' => $message,
|
66 |
'Context' => $args,
|
67 |
-
'Trace' => debug_backtrace(),
|
68 |
)
|
69 |
);
|
70 |
}
|
@@ -75,8 +80,8 @@ abstract class WSAL_AbstractSensor {
|
|
75 |
* @param string $message - Alert message.
|
76 |
* @param mixed $args - Message arguments.
|
77 |
*/
|
78 |
-
protected function
|
79 |
-
$this->
|
80 |
}
|
81 |
|
82 |
/**
|
@@ -85,8 +90,8 @@ abstract class WSAL_AbstractSensor {
|
|
85 |
* @param string $message - Alert message.
|
86 |
* @param mixed $args - Message arguments.
|
87 |
*/
|
88 |
-
protected function
|
89 |
-
$this->
|
90 |
}
|
91 |
|
92 |
/**
|
@@ -95,28 +100,16 @@ abstract class WSAL_AbstractSensor {
|
|
95 |
* @param string $message - Alert message.
|
96 |
* @param mixed $args - Message arguments.
|
97 |
*/
|
98 |
-
protected function
|
99 |
-
$this->
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
-
*
|
104 |
*
|
105 |
-
* @
|
106 |
*
|
107 |
-
* @
|
108 |
*/
|
109 |
-
|
110 |
-
if ( ! is_dir( $dir_path ) ) {
|
111 |
-
return false;
|
112 |
-
}
|
113 |
-
if ( ! is_readable( $dir_path ) ) {
|
114 |
-
return false;
|
115 |
-
}
|
116 |
-
if ( ! is_writable( $dir_path ) ) {
|
117 |
-
return false;
|
118 |
-
}
|
119 |
-
|
120 |
-
return true;
|
121 |
-
}
|
122 |
}
|
4 |
*
|
5 |
* Abstract sensor class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
17 |
/**
|
18 |
* Abstract class used in all the sensors.
|
19 |
*
|
20 |
+
* @see Sensors/*.php
|
21 |
+
* @package wsal
|
22 |
+
* @subpackage sensors
|
23 |
*/
|
24 |
abstract class WSAL_AbstractSensor {
|
25 |
|
44 |
*
|
45 |
* @return boolean
|
46 |
*/
|
47 |
+
protected function is_multisite() {
|
48 |
+
return $this->plugin->is_multisite();
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
* Method: Hook events related to sensor.
|
53 |
*/
|
54 |
+
public function hook_events() {
|
55 |
+
// We call the deprecated function for backwards compatibility.
|
56 |
+
$this->HookEvents();
|
57 |
+
}
|
58 |
|
59 |
/**
|
60 |
* Method: Log the message for sensor.
|
63 |
* @param string $message - Alert message.
|
64 |
* @param mixed $args - Message arguments.
|
65 |
*/
|
66 |
+
protected function log( $type, $message, $args ) {
|
67 |
+
$this->plugin->alerts->trigger_event(
|
68 |
$type,
|
69 |
array(
|
70 |
'Message' => $message,
|
71 |
'Context' => $args,
|
72 |
+
'Trace' => debug_backtrace(), // phpcs:ignore
|
73 |
)
|
74 |
);
|
75 |
}
|
80 |
* @param string $message - Alert message.
|
81 |
* @param mixed $args - Message arguments.
|
82 |
*/
|
83 |
+
protected function log_error( $message, $args ) {
|
84 |
+
$this->log( 0001, $message, $args );
|
85 |
}
|
86 |
|
87 |
/**
|
90 |
* @param string $message - Alert message.
|
91 |
* @param mixed $args - Message arguments.
|
92 |
*/
|
93 |
+
protected function log_warn( $message, $args ) {
|
94 |
+
$this->log( 0002, $message, $args );
|
95 |
}
|
96 |
|
97 |
/**
|
100 |
* @param string $message - Alert message.
|
101 |
* @param mixed $args - Message arguments.
|
102 |
*/
|
103 |
+
protected function log_info( $message, $args ) {
|
104 |
+
$this->log( 0003, $message, $args );
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* Deprecated placeholder function.
|
109 |
*
|
110 |
+
* @see WSAL_AbstractSensor::hook_events()
|
111 |
*
|
112 |
+
* @deprecated 4.4.1 Replaced by function hook_events.
|
113 |
*/
|
114 |
+
public function HookEvents() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
classes/AbstractView.php
CHANGED
@@ -1,9 +1,22 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Abstract class used in all the views.
|
4 |
*
|
5 |
-
* @see
|
6 |
-
* @package
|
|
|
7 |
*/
|
8 |
abstract class WSAL_AbstractView {
|
9 |
|
@@ -12,14 +25,14 @@ abstract class WSAL_AbstractView {
|
|
12 |
*
|
13 |
* @var WpSecurityAuditLog
|
14 |
*/
|
15 |
-
protected $
|
16 |
|
17 |
/**
|
18 |
* WordPress version.
|
19 |
*
|
20 |
* @var string
|
21 |
*/
|
22 |
-
protected $
|
23 |
|
24 |
/**
|
25 |
* Contains the result to a call to add_submenu_page().
|
@@ -40,25 +53,25 @@ abstract class WSAL_AbstractView {
|
|
40 |
*
|
41 |
* @var array
|
42 |
*/
|
43 |
-
public static $
|
44 |
|
45 |
/**
|
46 |
* Method: Constructor.
|
47 |
*
|
48 |
-
* @param
|
49 |
*/
|
50 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
51 |
-
$this->
|
52 |
|
53 |
// Get and store WordPress version.
|
54 |
global $wp_version;
|
55 |
if ( ! isset( $wp_version ) ) {
|
56 |
-
$wp_version = get_bloginfo( 'version' );
|
57 |
}
|
58 |
-
$this->
|
59 |
|
60 |
// Handle admin notices.
|
61 |
-
add_action( 'wp_ajax_AjaxDismissNotice', array( $this, '
|
62 |
}
|
63 |
|
64 |
/**
|
@@ -66,8 +79,8 @@ abstract class WSAL_AbstractView {
|
|
66 |
*
|
67 |
* @internal
|
68 |
*/
|
69 |
-
public function
|
70 |
-
if ( ! $this->
|
71 |
die( 'Access Denied.' );
|
72 |
}
|
73 |
|
@@ -78,7 +91,7 @@ abstract class WSAL_AbstractView {
|
|
78 |
die( 'Notice name expected as "notice" parameter.' );
|
79 |
}
|
80 |
|
81 |
-
$this->
|
82 |
}
|
83 |
|
84 |
/**
|
@@ -87,11 +100,11 @@ abstract class WSAL_AbstractView {
|
|
87 |
* @param string $name — Name of notice.
|
88 |
* @return boolean — Whether notice got dismissed or not.
|
89 |
*/
|
90 |
-
public function
|
91 |
$user_id = get_current_user_id();
|
92 |
$meta_key = 'wsal-notice-' . $name;
|
93 |
|
94 |
-
self::$
|
95 |
return get_user_meta( $user_id, $meta_key, true );
|
96 |
}
|
97 |
|
@@ -100,11 +113,11 @@ abstract class WSAL_AbstractView {
|
|
100 |
*
|
101 |
* @param string $name — Name of notice to dismiss.
|
102 |
*/
|
103 |
-
public function
|
104 |
$user_id = get_current_user_id();
|
105 |
$meta_key = 'wsal-notice-' . $name;
|
106 |
$old_value = get_user_meta( $user_id, $meta_key, true );
|
107 |
-
if ( in_array( $name, self::$
|
108 |
update_user_meta( $user_id, $meta_key, '1' );
|
109 |
}
|
110 |
}
|
@@ -114,8 +127,8 @@ abstract class WSAL_AbstractView {
|
|
114 |
*
|
115 |
* @param string $name — Makes this notice available.
|
116 |
*/
|
117 |
-
public function
|
118 |
-
self::$
|
119 |
}
|
120 |
|
121 |
/**
|
@@ -123,38 +136,38 @@ abstract class WSAL_AbstractView {
|
|
123 |
*
|
124 |
* @return string
|
125 |
*/
|
126 |
-
abstract public function
|
127 |
|
128 |
/**
|
129 |
* Method: Return page title.
|
130 |
*
|
131 |
* @return string
|
132 |
*/
|
133 |
-
abstract public function
|
134 |
|
135 |
/**
|
136 |
* Method: Page icon name.
|
137 |
*
|
138 |
* @return string
|
139 |
*/
|
140 |
-
abstract public function
|
141 |
|
142 |
/**
|
143 |
* Method: Menu weight, the higher this is, the lower it goes.
|
144 |
*
|
145 |
* @return int
|
146 |
*/
|
147 |
-
abstract public function
|
148 |
|
149 |
/**
|
150 |
* Renders and outputs the view directly.
|
151 |
*/
|
152 |
-
abstract public function
|
153 |
|
154 |
/**
|
155 |
* Renders the view icon (this has been deprecated in newwer WP versions).
|
156 |
*/
|
157 |
-
public function
|
158 |
?>
|
159 |
<div id="icon-plugins" class="icon32"><br></div>
|
160 |
<?php
|
@@ -163,19 +176,19 @@ abstract class WSAL_AbstractView {
|
|
163 |
/**
|
164 |
* Renders the view title.
|
165 |
*/
|
166 |
-
public function
|
167 |
if ( $this->is_title_visible() ) {
|
168 |
-
echo '<h2>' . esc_html( $this->
|
169 |
}
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
* Method: Render content of the view.
|
174 |
*
|
175 |
-
* @
|
176 |
*/
|
177 |
-
public function
|
178 |
-
$this->
|
179 |
}
|
180 |
|
181 |
/**
|
@@ -183,7 +196,7 @@ abstract class WSAL_AbstractView {
|
|
183 |
*
|
184 |
* @return boolean
|
185 |
*/
|
186 |
-
public function
|
187 |
return true;
|
188 |
}
|
189 |
|
@@ -192,7 +205,7 @@ abstract class WSAL_AbstractView {
|
|
192 |
*
|
193 |
* @return boolean
|
194 |
*/
|
195 |
-
public function
|
196 |
return true;
|
197 |
}
|
198 |
|
@@ -208,20 +221,20 @@ abstract class WSAL_AbstractView {
|
|
208 |
/**
|
209 |
* Used for rendering stuff into head tag.
|
210 |
*/
|
211 |
-
public function
|
212 |
|
213 |
/**
|
214 |
-
* Used for rendering stuff in page
|
215 |
*/
|
216 |
-
public function
|
217 |
|
218 |
/**
|
219 |
* Method: Safe view menu name.
|
220 |
*
|
221 |
* @return string
|
222 |
*/
|
223 |
-
public function
|
224 |
-
return 'wsal-' . preg_replace( '/[^A-Za-z0-9\-]/', '-', $this->
|
225 |
}
|
226 |
|
227 |
/**
|
@@ -229,7 +242,7 @@ abstract class WSAL_AbstractView {
|
|
229 |
*
|
230 |
* @return boolean
|
231 |
*/
|
232 |
-
public function
|
233 |
return false;
|
234 |
}
|
235 |
|
@@ -238,9 +251,9 @@ abstract class WSAL_AbstractView {
|
|
238 |
*
|
239 |
* @return string
|
240 |
*/
|
241 |
-
public function
|
242 |
$fn = function_exists( 'network_admin_url' ) ? 'network_admin_url' : 'admin_url';
|
243 |
-
return $fn( 'admin.php?page=' . $this->
|
244 |
}
|
245 |
|
246 |
/**
|
@@ -248,7 +261,7 @@ abstract class WSAL_AbstractView {
|
|
248 |
*
|
249 |
* @return string
|
250 |
*/
|
251 |
-
public function
|
252 |
return strtolower( str_replace( array( 'WSAL_Views_', 'WSAL_' ), '', get_class( $this ) ) );
|
253 |
}
|
254 |
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Abstract view class file.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage views
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly.
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
/**
|
15 |
* Abstract class used in all the views.
|
16 |
*
|
17 |
+
* @see Views/*.php
|
18 |
+
* @package wsal
|
19 |
+
* @subpackage views
|
20 |
*/
|
21 |
abstract class WSAL_AbstractView {
|
22 |
|
25 |
*
|
26 |
* @var WpSecurityAuditLog
|
27 |
*/
|
28 |
+
protected $plugin;
|
29 |
|
30 |
/**
|
31 |
* WordPress version.
|
32 |
*
|
33 |
* @var string
|
34 |
*/
|
35 |
+
protected $wp_version;
|
36 |
|
37 |
/**
|
38 |
* Contains the result to a call to add_submenu_page().
|
53 |
*
|
54 |
* @var array
|
55 |
*/
|
56 |
+
public static $allowed_notice_names = array();
|
57 |
|
58 |
/**
|
59 |
* Method: Constructor.
|
60 |
*
|
61 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
62 |
*/
|
63 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
64 |
+
$this->plugin = $plugin;
|
65 |
|
66 |
// Get and store WordPress version.
|
67 |
global $wp_version;
|
68 |
if ( ! isset( $wp_version ) ) {
|
69 |
+
$wp_version = get_bloginfo( 'version' ); // phpcs:ignore
|
70 |
}
|
71 |
+
$this->wp_version = floatval( $wp_version );
|
72 |
|
73 |
// Handle admin notices.
|
74 |
+
add_action( 'wp_ajax_AjaxDismissNotice', array( $this, 'ajax_dismiss_notice' ) );
|
75 |
}
|
76 |
|
77 |
/**
|
79 |
*
|
80 |
* @internal
|
81 |
*/
|
82 |
+
public function ajax_dismiss_notice() {
|
83 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
84 |
die( 'Access Denied.' );
|
85 |
}
|
86 |
|
91 |
die( 'Notice name expected as "notice" parameter.' );
|
92 |
}
|
93 |
|
94 |
+
$this->dismiss_notice( $post_array['notice'] );
|
95 |
}
|
96 |
|
97 |
/**
|
100 |
* @param string $name — Name of notice.
|
101 |
* @return boolean — Whether notice got dismissed or not.
|
102 |
*/
|
103 |
+
public function is_notice_dismissed( $name ) {
|
104 |
$user_id = get_current_user_id();
|
105 |
$meta_key = 'wsal-notice-' . $name;
|
106 |
|
107 |
+
self::$allowed_notice_names[] = $name;
|
108 |
return get_user_meta( $user_id, $meta_key, true );
|
109 |
}
|
110 |
|
113 |
*
|
114 |
* @param string $name — Name of notice to dismiss.
|
115 |
*/
|
116 |
+
public function dismiss_notice( $name ) {
|
117 |
$user_id = get_current_user_id();
|
118 |
$meta_key = 'wsal-notice-' . $name;
|
119 |
$old_value = get_user_meta( $user_id, $meta_key, true );
|
120 |
+
if ( in_array( $name, self::$allowed_notice_names ) || false === $old_value || empty( $old_value ) ) { // phpcs:ignore
|
121 |
update_user_meta( $user_id, $meta_key, '1' );
|
122 |
}
|
123 |
}
|
127 |
*
|
128 |
* @param string $name — Makes this notice available.
|
129 |
*/
|
130 |
+
public function register_notice( $name ) {
|
131 |
+
self::$allowed_notice_names[] = $name;
|
132 |
}
|
133 |
|
134 |
/**
|
136 |
*
|
137 |
* @return string
|
138 |
*/
|
139 |
+
abstract public function get_name();
|
140 |
|
141 |
/**
|
142 |
* Method: Return page title.
|
143 |
*
|
144 |
* @return string
|
145 |
*/
|
146 |
+
abstract public function get_title();
|
147 |
|
148 |
/**
|
149 |
* Method: Page icon name.
|
150 |
*
|
151 |
* @return string
|
152 |
*/
|
153 |
+
abstract public function get_icon();
|
154 |
|
155 |
/**
|
156 |
* Method: Menu weight, the higher this is, the lower it goes.
|
157 |
*
|
158 |
* @return int
|
159 |
*/
|
160 |
+
abstract public function get_weight();
|
161 |
|
162 |
/**
|
163 |
* Renders and outputs the view directly.
|
164 |
*/
|
165 |
+
abstract public function render();
|
166 |
|
167 |
/**
|
168 |
* Renders the view icon (this has been deprecated in newwer WP versions).
|
169 |
*/
|
170 |
+
public function render_icon() {
|
171 |
?>
|
172 |
<div id="icon-plugins" class="icon32"><br></div>
|
173 |
<?php
|
176 |
/**
|
177 |
* Renders the view title.
|
178 |
*/
|
179 |
+
public function render_title() {
|
180 |
if ( $this->is_title_visible() ) {
|
181 |
+
echo '<h2>' . esc_html( $this->get_title() ) . '</h2>';
|
182 |
}
|
183 |
}
|
184 |
|
185 |
/**
|
186 |
* Method: Render content of the view.
|
187 |
*
|
188 |
+
* @see WSAL_AbstractView::render()
|
189 |
*/
|
190 |
+
public function render_content() {
|
191 |
+
$this->render();
|
192 |
}
|
193 |
|
194 |
/**
|
196 |
*
|
197 |
* @return boolean
|
198 |
*/
|
199 |
+
public function is_visible() {
|
200 |
return true;
|
201 |
}
|
202 |
|
205 |
*
|
206 |
* @return boolean
|
207 |
*/
|
208 |
+
public function is_accessible() {
|
209 |
return true;
|
210 |
}
|
211 |
|
221 |
/**
|
222 |
* Used for rendering stuff into head tag.
|
223 |
*/
|
224 |
+
public function header() {}
|
225 |
|
226 |
/**
|
227 |
+
* Used for rendering stuff in page footer.
|
228 |
*/
|
229 |
+
public function footer() {}
|
230 |
|
231 |
/**
|
232 |
* Method: Safe view menu name.
|
233 |
*
|
234 |
* @return string
|
235 |
*/
|
236 |
+
public function get_safe_view_name() {
|
237 |
+
return 'wsal-' . preg_replace( '/[^A-Za-z0-9\-]/', '-', $this->get_view_name() );
|
238 |
}
|
239 |
|
240 |
/**
|
242 |
*
|
243 |
* @return boolean
|
244 |
*/
|
245 |
+
public function has_plugin_shortcut_link() {
|
246 |
return false;
|
247 |
}
|
248 |
|
251 |
*
|
252 |
* @return string
|
253 |
*/
|
254 |
+
public function get_url() {
|
255 |
$fn = function_exists( 'network_admin_url' ) ? 'network_admin_url' : 'admin_url';
|
256 |
+
return $fn( 'admin.php?page=' . $this->get_safe_view_name() );
|
257 |
}
|
258 |
|
259 |
/**
|
261 |
*
|
262 |
* @return string
|
263 |
*/
|
264 |
+
public function get_view_name() {
|
265 |
return strtolower( str_replace( array( 'WSAL_Views_', 'WSAL_' ), '', get_class( $this ) ) );
|
266 |
}
|
267 |
|
classes/Adapters/ActiveRecordInterface.php
CHANGED
@@ -25,17 +25,17 @@ interface WSAL_Adapters_ActiveRecordInterface {
|
|
25 |
* @deprecated
|
26 |
* @return boolean
|
27 |
*/
|
28 |
-
public function
|
29 |
|
30 |
/**
|
31 |
* Install this ActiveRecord structure into DB.
|
32 |
*/
|
33 |
-
public function
|
34 |
|
35 |
/**
|
36 |
* Remove this ActiveRecord structure from DB.
|
37 |
*/
|
38 |
-
public function
|
39 |
|
40 |
/**
|
41 |
* Load.
|
@@ -43,33 +43,35 @@ interface WSAL_Adapters_ActiveRecordInterface {
|
|
43 |
* @param string $cond - Query Condition.
|
44 |
* @param array $args - Query arguments.
|
45 |
*/
|
46 |
-
public function
|
47 |
|
48 |
/**
|
49 |
* Save an active record into DB.
|
50 |
*
|
51 |
-
* @param
|
|
|
52 |
* @return integer|boolean - Either the number of modified/inserted rows or false on failure.
|
53 |
*/
|
54 |
-
public function
|
55 |
|
56 |
/**
|
57 |
* Delete DB record.
|
58 |
*
|
59 |
-
* @param
|
|
|
60 |
* @return int|boolean - Either the amount of deleted rows or False on error.
|
61 |
*/
|
62 |
-
public function
|
63 |
|
64 |
/**
|
65 |
* Load multiple records from DB.
|
66 |
*
|
67 |
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
68 |
-
* @param array
|
69 |
*
|
70 |
* @return self[] List of loaded records.
|
71 |
*/
|
72 |
-
public function
|
73 |
|
74 |
/**
|
75 |
* Load multiple records from DB and call a callback for each record.
|
@@ -79,7 +81,7 @@ interface WSAL_Adapters_ActiveRecordInterface {
|
|
79 |
* @param string $cond (Optional) Load condition.
|
80 |
* @param array $args (Optional) Load condition arguments.
|
81 |
*/
|
82 |
-
public function
|
83 |
|
84 |
/**
|
85 |
* Count records in the DB matching a condition.
|
@@ -89,23 +91,23 @@ interface WSAL_Adapters_ActiveRecordInterface {
|
|
89 |
* @param array $args (Optional) Condition arguments.
|
90 |
* @return int Number of matching records.
|
91 |
*/
|
92 |
-
public function
|
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
|
99 |
*
|
100 |
* @return array List of loaded records.
|
101 |
* @throws Exception
|
102 |
*/
|
103 |
-
public function
|
104 |
|
105 |
/**
|
106 |
* Returns the model class for adapter.
|
107 |
*
|
108 |
* @return WSAL_Models_ActiveRecord
|
109 |
*/
|
110 |
-
public function
|
111 |
}
|
25 |
* @deprecated
|
26 |
* @return boolean
|
27 |
*/
|
28 |
+
public function is_installed();
|
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 |
|
40 |
/**
|
41 |
* Load.
|
43 |
* @param string $cond - Query Condition.
|
44 |
* @param array $args - Query arguments.
|
45 |
*/
|
46 |
+
public function load( $cond = '%d', $args = array( 1 ) );
|
47 |
|
48 |
/**
|
49 |
* Save an active record into DB.
|
50 |
*
|
51 |
+
* @param WSAL_Models_ActiveRecord $active_record - ActiveRecord object.
|
52 |
+
*
|
53 |
* @return integer|boolean - Either the number of modified/inserted rows or false on failure.
|
54 |
*/
|
55 |
+
public function save( $active_record );
|
56 |
|
57 |
/**
|
58 |
* Delete DB record.
|
59 |
*
|
60 |
+
* @param WSAL_Models_ActiveRecord $active_record - ActiveRecord object.
|
61 |
+
*
|
62 |
* @return int|boolean - Either the amount of deleted rows or False on error.
|
63 |
*/
|
64 |
+
public function delete( $active_record );
|
65 |
|
66 |
/**
|
67 |
* Load multiple records from DB.
|
68 |
*
|
69 |
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
70 |
+
* @param array $args (Optional) Load condition arguments (rg: array(45) ).
|
71 |
*
|
72 |
* @return self[] List of loaded records.
|
73 |
*/
|
74 |
+
public function load_multi( $cond, $args = array() );
|
75 |
|
76 |
/**
|
77 |
* Load multiple records from DB and call a callback for each record.
|
81 |
* @param string $cond (Optional) Load condition.
|
82 |
* @param array $args (Optional) Load condition arguments.
|
83 |
*/
|
84 |
+
public function load_and_call_for_each( $callback, $cond = '%d', $args = array( 1 ) );
|
85 |
|
86 |
/**
|
87 |
* Count records in the DB matching a condition.
|
91 |
* @param array $args (Optional) Condition arguments.
|
92 |
* @return int Number of matching records.
|
93 |
*/
|
94 |
+
public function count( $cond = '%d', $args = array( 1 ) );
|
95 |
|
96 |
/**
|
97 |
* Similar to LoadMulti but allows the use of a full SQL query.
|
98 |
*
|
99 |
* @param string $query Full SQL query.
|
100 |
+
* @param array $args (Optional) Query arguments.
|
101 |
*
|
102 |
* @return array List of loaded records.
|
103 |
* @throws Exception
|
104 |
*/
|
105 |
+
public function load_multi_query( $query, $args = array() );
|
106 |
|
107 |
/**
|
108 |
* Returns the model class for adapter.
|
109 |
*
|
110 |
* @return WSAL_Models_ActiveRecord
|
111 |
*/
|
112 |
+
public function get_model();
|
113 |
}
|
classes/Adapters/MetaInterface.php
CHANGED
@@ -24,7 +24,7 @@ interface WSAL_Adapters_MetaInterface {
|
|
24 |
*
|
25 |
* @param int[] $occurrence_ids - Array of occurrence IDs.
|
26 |
*/
|
27 |
-
public function
|
28 |
|
29 |
/**
|
30 |
* Load meta by name and occurrence id.
|
@@ -32,5 +32,5 @@ interface WSAL_Adapters_MetaInterface {
|
|
32 |
* @param string $meta_name - Meta name.
|
33 |
* @param int $occurrence_id - Occurrence ID.
|
34 |
*/
|
35 |
-
public function
|
36 |
}
|
24 |
*
|
25 |
* @param int[] $occurrence_ids - Array of occurrence IDs.
|
26 |
*/
|
27 |
+
public function delete_by_occurrence_ids( $occurrence_ids );
|
28 |
|
29 |
/**
|
30 |
* Load meta by name and occurrence id.
|
32 |
* @param string $meta_name - Meta name.
|
33 |
* @param int $occurrence_id - Occurrence ID.
|
34 |
*/
|
35 |
+
public function load_by_name_and_occurrence_id( $meta_name, $occurrence_id );
|
36 |
}
|
classes/Adapters/MySQL/ActiveRecordAdapter.php
CHANGED
@@ -36,21 +36,21 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
36 |
*
|
37 |
* @var string
|
38 |
*/
|
39 |
-
protected $
|
40 |
|
41 |
/**
|
42 |
* Contains primary key column name, override as required.
|
43 |
*
|
44 |
* @var string
|
45 |
*/
|
46 |
-
protected $
|
47 |
|
48 |
/**
|
49 |
* Local cache for a list of columns.
|
50 |
*
|
51 |
* @var string[]
|
52 |
*/
|
53 |
-
protected $
|
54 |
|
55 |
/**
|
56 |
* Method: Constructor.
|
@@ -125,18 +125,18 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
125 |
*
|
126 |
* @return string Returns table name of WordPress.
|
127 |
*/
|
128 |
-
public function
|
129 |
global $wpdb;
|
130 |
|
131 |
-
return $wpdb->base_prefix . $this->
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
-
* @inheritDoc
|
136 |
*/
|
137 |
-
public function
|
138 |
$_wpdb = $this->connection;
|
139 |
-
$_wpdb->query( $this->
|
140 |
}
|
141 |
|
142 |
/**
|
@@ -146,18 +146,18 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
146 |
*
|
147 |
* @return string - Must return SQL for creating table.
|
148 |
*/
|
149 |
-
protected function
|
150 |
$_wpdb = $this->connection;
|
151 |
$class = get_class( $this );
|
152 |
$copy = new $class( $this->connection );
|
153 |
-
$table_name = $this->
|
154 |
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
155 |
-
$cols = $this->
|
156 |
foreach ( $cols as $key ) {
|
157 |
-
$sql .= $this->
|
158 |
}
|
159 |
|
160 |
-
$sql .= $this->
|
161 |
$sql .= ') ' . $_wpdb->get_charset_collate();
|
162 |
|
163 |
return $sql;
|
@@ -168,10 +168,10 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
168 |
*
|
169 |
* @return string
|
170 |
*/
|
171 |
-
public function
|
172 |
$_wpdb = $this->connection;
|
173 |
|
174 |
-
return $_wpdb->base_prefix . $this->
|
175 |
}
|
176 |
|
177 |
/**
|
@@ -179,40 +179,40 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
179 |
*
|
180 |
* @return array
|
181 |
*/
|
182 |
-
public function
|
183 |
-
$model = $this->
|
184 |
|
185 |
-
if ( empty( $this->
|
186 |
-
$this->
|
187 |
foreach ( array_keys( get_object_vars( $model ) ) as $col ) {
|
188 |
-
if ( trim( $col ) && $col[0] != '_' ) {
|
189 |
-
$this->
|
190 |
}
|
191 |
}
|
192 |
}
|
193 |
|
194 |
-
return $this->
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
-
* @inheritDoc
|
199 |
*/
|
200 |
-
public function
|
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
|
213 |
$result = ' ';
|
214 |
switch ( true ) {
|
215 |
-
case ( $key === $this->
|
216 |
$result .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
|
217 |
break;
|
218 |
case is_int( $copy->$key ):
|
@@ -238,7 +238,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
238 |
$result .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
239 |
break;
|
240 |
default:
|
241 |
-
//
|
242 |
break;
|
243 |
}
|
244 |
|
@@ -250,27 +250,27 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
250 |
*
|
251 |
* @return string
|
252 |
*/
|
253 |
-
protected function
|
254 |
-
return ' PRIMARY KEY (' . $this->
|
255 |
}
|
256 |
|
257 |
/**
|
258 |
* Install this ActiveRecord structure into DB WordPress.
|
259 |
*/
|
260 |
-
public function
|
261 |
global $wpdb;
|
262 |
-
$wpdb->query( $this->
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
-
* @inheritDoc
|
267 |
*/
|
268 |
-
public function
|
269 |
$_wpdb = $this->connection;
|
270 |
|
271 |
// Check if table exists.
|
272 |
if ( $this->table_exists() ) {
|
273 |
-
$_wpdb->query( $this->
|
274 |
}
|
275 |
}
|
276 |
|
@@ -283,7 +283,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
283 |
$_wpdb = $this->connection;
|
284 |
|
285 |
// Query table exists.
|
286 |
-
$table_exists_query = "SHOW TABLES LIKE '" . $this->
|
287 |
|
288 |
return $_wpdb->query( $table_exists_query );
|
289 |
}
|
@@ -293,23 +293,23 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
293 |
*
|
294 |
* @return string
|
295 |
*/
|
296 |
-
protected function
|
297 |
-
return 'DROP TABLE IF EXISTS ' . $this->
|
298 |
}
|
299 |
|
300 |
/**
|
301 |
-
* @inheritDoc
|
302 |
*/
|
303 |
-
public function
|
304 |
$_wpdb = $this->connection;
|
305 |
$copy = $active_record;
|
306 |
$data = array();
|
307 |
$format = array();
|
308 |
|
309 |
-
$columns = $this->
|
310 |
foreach ( $columns as $index => $key ) {
|
311 |
-
if ( $key == $this->
|
312 |
-
$
|
313 |
}
|
314 |
|
315 |
$val = $copy->$key;
|
@@ -323,7 +323,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
323 |
}
|
324 |
|
325 |
if ( is_array( $copy->$key ) || is_object( $copy->$key ) ) {
|
326 |
-
$data[ $key ] = WSAL_Helpers_DataHelper::
|
327 |
} else {
|
328 |
$data[ $key ] = $val;
|
329 |
}
|
@@ -331,15 +331,15 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
331 |
$format[] = $deffmt;
|
332 |
}
|
333 |
|
334 |
-
if ( isset( $data[ $this->
|
335 |
-
unset( $data[ $this->
|
336 |
-
unset( $format[ $
|
337 |
}
|
338 |
|
339 |
-
$result = $_wpdb->replace( $this->
|
340 |
|
341 |
if ( false !== $result && $_wpdb->insert_id ) {
|
342 |
-
$copy->
|
343 |
}
|
344 |
|
345 |
return $result;
|
@@ -353,9 +353,9 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
353 |
*
|
354 |
* @return array
|
355 |
*/
|
356 |
-
public function
|
357 |
$_wpdb = $this->connection;
|
358 |
-
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->
|
359 |
|
360 |
return $_wpdb->get_row( $sql, ARRAY_A );
|
361 |
}
|
@@ -367,29 +367,28 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
367 |
* @param array $args (Optional) Load condition arguments.
|
368 |
*
|
369 |
* @return array
|
370 |
-
* @throws Exception
|
371 |
*/
|
372 |
-
public function
|
373 |
$_wpdb = $this->connection;
|
374 |
$result = array();
|
375 |
-
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->
|
376 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
377 |
-
$result[] = $this->
|
378 |
}
|
379 |
|
380 |
return $result;
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
-
* @inheritDoc
|
385 |
*/
|
386 |
-
public function
|
387 |
$_wpdb = $this->connection;
|
388 |
|
389 |
return $_wpdb->delete(
|
390 |
-
$this->
|
391 |
array(
|
392 |
-
$this->
|
393 |
),
|
394 |
array( '%d' )
|
395 |
);
|
@@ -403,7 +402,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
403 |
*
|
404 |
* @return int|bool
|
405 |
*/
|
406 |
-
public function
|
407 |
$_wpdb = $this->connection;
|
408 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
409 |
|
@@ -411,39 +410,39 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
411 |
}
|
412 |
|
413 |
/**
|
414 |
-
* @inheritDoc
|
415 |
*/
|
416 |
-
public function
|
417 |
$_wpdb = $this->connection;
|
418 |
$result = array();
|
419 |
$sql = ( ! is_array( $args ) || ! count( $args ) ) // Do we really need to prepare() or not?
|
420 |
? ( $cond )
|
421 |
: $_wpdb->prepare( $cond, $args );
|
422 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
423 |
-
$result[] = $this->
|
424 |
}
|
425 |
|
426 |
return $result;
|
427 |
}
|
428 |
|
429 |
/**
|
430 |
-
* @inheritDoc
|
431 |
*/
|
432 |
-
public function
|
433 |
$_wpdb = $this->connection;
|
434 |
$class = get_called_class();
|
435 |
-
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->
|
436 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
437 |
call_user_func( $callback, new $class( $data ) );
|
438 |
}
|
439 |
}
|
440 |
|
441 |
/**
|
442 |
-
* @inheritDoc
|
443 |
*/
|
444 |
-
public function
|
445 |
$_wpdb = $this->connection;
|
446 |
-
$sql = $_wpdb->prepare( 'SELECT COUNT(*) FROM ' . $this->
|
447 |
|
448 |
return (int) $_wpdb->get_var( $sql );
|
449 |
}
|
@@ -456,7 +455,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
456 |
*
|
457 |
* @return int Number of matching records.
|
458 |
*/
|
459 |
-
public function
|
460 |
$_wpdb = $this->connection;
|
461 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
462 |
|
@@ -464,14 +463,14 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
464 |
}
|
465 |
|
466 |
/**
|
467 |
-
* @inheritDoc
|
468 |
*/
|
469 |
-
public function
|
470 |
$_wpdb = $this->connection;
|
471 |
$result = array();
|
472 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
473 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
474 |
-
$result[] = $this->
|
475 |
}
|
476 |
|
477 |
return $result;
|
@@ -529,38 +528,38 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
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->
|
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 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
"replace( replace( replace( occ.user_roles, '[', ''), ']', ''), '\\'', '') AS roles",
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
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,
|
564 |
array_push( $group_by, 'user' );
|
565 |
break;
|
566 |
case 'posts':
|
@@ -593,14 +592,17 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
593 |
}
|
594 |
|
595 |
if ( isset( $group_by ) && ! empty( $group_by ) ) {
|
596 |
-
$sql
|
597 |
-
$orderby_parts = array_map(
|
598 |
-
|
599 |
-
|
|
|
|
|
|
|
600 |
|
601 |
-
$sql .=
|
602 |
} else {
|
603 |
-
$sql .=
|
604 |
}
|
605 |
|
606 |
if ( ! empty( $limit ) ) {
|
@@ -621,92 +623,92 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
621 |
$_site_id = null;
|
622 |
$sites_negate_expression = '';
|
623 |
if ( $report_args->site__in ) {
|
624 |
-
$_site_id = $this->
|
625 |
} elseif ( $report_args->site__not_in ) {
|
626 |
-
$_site_id = $this->
|
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->
|
634 |
} elseif ( $report_args->user__not_in ) {
|
635 |
-
$_user_id = $this->
|
636 |
$users_negate_expression = 'NOT';
|
637 |
}
|
638 |
|
639 |
-
$user_names = $this->
|
640 |
|
641 |
$_role_name = null;
|
642 |
$roles_negate_expression = '';
|
643 |
if ( $report_args->role__in ) {
|
644 |
-
$_role_name = $this->
|
645 |
} elseif ( $report_args->role__not_in ) {
|
646 |
-
$_role_name = $this->
|
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->
|
654 |
} elseif ( $report_args->code__not_in ) {
|
655 |
-
$_alert_code = $this->
|
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->
|
663 |
} elseif ( $report_args->post__not_in ) {
|
664 |
-
$_post_ids = $this->
|
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->
|
672 |
} elseif ( $report_args->post_type__not_in ) {
|
673 |
-
$_post_types = $this->
|
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->
|
681 |
-
}
|
682 |
-
$_post_statuses = $this->
|
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->
|
690 |
-
}
|
691 |
-
$_ip_addresses = $this->
|
692 |
$ip_addresses_negate_expression = 'NOT';
|
693 |
}
|
694 |
|
695 |
$_objects = null;
|
696 |
$objects_negate_expression = '';
|
697 |
if ( $report_args->object__in ) {
|
698 |
-
$_objects = $this->
|
699 |
} elseif ( $report_args->object__not_in ) {
|
700 |
-
$_objects = $this->
|
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->
|
708 |
} elseif ( $report_args->type__not_in ) {
|
709 |
-
$_event_types = $this->
|
710 |
$event_types_negate_expression = 'NOT';
|
711 |
}
|
712 |
|
@@ -731,7 +733,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
731 |
array_push( $users_condition_parts, " {$users_negate_expression} replace( occ.username, '\"', '' ) IN ( $user_names ) " );
|
732 |
}
|
733 |
|
734 |
-
$where_statement =
|
735 |
|
736 |
if ( ! empty( $users_condition_parts ) ) {
|
737 |
$where_statement .= ' AND ( ' . implode( 'OR', $users_condition_parts ) . ' ) ';
|
@@ -785,30 +787,32 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
785 |
}
|
786 |
|
787 |
/**
|
788 |
-
*
|
|
|
|
|
789 |
*
|
790 |
* @return string
|
791 |
* @since 4.3.2
|
792 |
*/
|
793 |
-
protected function
|
794 |
return "'" . implode( ',', $data ) . "'";
|
795 |
}
|
796 |
|
797 |
/**
|
798 |
* Get Users user_login.
|
799 |
*
|
800 |
-
* @param int $
|
801 |
*
|
802 |
* @return string comma separated users login
|
803 |
*/
|
804 |
-
private function
|
805 |
global $wpdb;
|
806 |
|
807 |
$user_names = null;
|
808 |
-
if ( ! empty( $
|
809 |
$sql = 'SELECT user_login FROM ' . $wpdb->users . ' WHERE find_in_set(ID, @userId) > 0';
|
810 |
-
$wpdb->query( "SET @userId = $
|
811 |
-
$result = $wpdb->get_results( $sql, ARRAY_A );
|
812 |
$users_array = array();
|
813 |
foreach ( $result as $item ) {
|
814 |
$users_array[] = '"' . $item['user_login'] . '"';
|
@@ -820,15 +824,17 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
820 |
}
|
821 |
|
822 |
/**
|
823 |
-
*
|
|
|
|
|
824 |
*
|
825 |
* @return string
|
826 |
* @since 4.3.2
|
827 |
*/
|
828 |
-
protected function
|
829 |
$result = array();
|
830 |
foreach ( $data as $item ) {
|
831 |
-
array_push( $result, esc_sql( preg_quote( $item ) ) );
|
832 |
}
|
833 |
|
834 |
return "'" . implode( '|', $result ) . "'";
|
@@ -840,9 +846,9 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
840 |
*
|
841 |
* @param WSAL_ReportArgs $report_args - Query conditions.
|
842 |
*
|
843 |
-
* @return int
|
844 |
*/
|
845 |
-
public function
|
846 |
$query = $this->build_reporting_query( $report_args, true );
|
847 |
|
848 |
return (int) $this->connection->get_var( $query );
|
@@ -864,14 +870,14 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
864 |
|
865 |
// Tables.
|
866 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
867 |
-
$table_occ = $occurrence->
|
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->
|
873 |
-
$table_users = $tmp_users->
|
874 |
-
$this->
|
875 |
} else {
|
876 |
$table_users = $wpdb->users;
|
877 |
}
|
@@ -912,8 +918,8 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
912 |
|
913 |
$where_statement = $this->build_where_statement( $report_args );
|
914 |
|
915 |
-
$sql =
|
916 |
-
SELECT
|
917 |
SELECT occ.created_on, occ.site_id, occ.username, occ.client_ip
|
918 |
FROM $table_occ AS occ
|
919 |
{$where_statement}
|
@@ -927,11 +933,14 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
927 |
) ip_logins
|
928 |
GROUP BY " . implode( ',', $group_by_columns );
|
929 |
|
930 |
-
$orderby_parts = array_map(
|
931 |
-
|
932 |
-
|
|
|
|
|
|
|
933 |
|
934 |
-
$sql .=
|
935 |
|
936 |
if ( ! empty( $limit ) ) {
|
937 |
$sql .= " LIMIT {$limit}";
|
@@ -946,19 +955,19 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
946 |
}
|
947 |
|
948 |
/**
|
949 |
-
* @inheritDoc
|
950 |
*/
|
951 |
-
public function
|
952 |
$_wpdb = $this->connection;
|
953 |
-
$sql = "SHOW TABLES LIKE '" . $this->
|
954 |
|
955 |
// Table transient.
|
956 |
-
$wsal_table_transient = 'wsal_' . strtolower( $this->
|
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 ) )
|
962 |
set_transient( $wsal_table_transient, $wsal_db_table_status, DAY_IN_SECONDS );
|
963 |
}
|
964 |
|
@@ -971,7 +980,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
971 |
*
|
972 |
* @param string $table_users - Table name.
|
973 |
*/
|
974 |
-
private function
|
975 |
$_wpdb = $this->connection;
|
976 |
$sql = "DELETE FROM $table_users";
|
977 |
$_wpdb->query( $sql );
|
@@ -992,7 +1001,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
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
|
@@ -1006,7 +1015,7 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
|
|
1006 |
* @return int|false The number of rows updated, or false on error.
|
1007 |
* @since 4.1.3
|
1008 |
*/
|
1009 |
-
public function
|
1010 |
return $this->connection->update( $table, $data, $where );
|
1011 |
}
|
1012 |
}
|
36 |
*
|
37 |
* @var string
|
38 |
*/
|
39 |
+
protected $table;
|
40 |
|
41 |
/**
|
42 |
* Contains primary key column name, override as required.
|
43 |
*
|
44 |
* @var string
|
45 |
*/
|
46 |
+
protected $idkey = '';
|
47 |
|
48 |
/**
|
49 |
* Local cache for a list of columns.
|
50 |
*
|
51 |
* @var string[]
|
52 |
*/
|
53 |
+
protected $column_cache = array();
|
54 |
|
55 |
/**
|
56 |
* Method: Constructor.
|
125 |
*
|
126 |
* @return string Returns table name of WordPress.
|
127 |
*/
|
128 |
+
public function get_wp_table() {
|
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->get_install_query() );
|
140 |
}
|
141 |
|
142 |
/**
|
146 |
*
|
147 |
* @return string - Must return SQL for creating table.
|
148 |
*/
|
149 |
+
protected function get_install_query( $prefix = false ) {
|
150 |
$_wpdb = $this->connection;
|
151 |
$class = get_class( $this );
|
152 |
$copy = new $class( $this->connection );
|
153 |
+
$table_name = $this->get_table();
|
154 |
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
155 |
+
$cols = $this->get_columns();
|
156 |
foreach ( $cols as $key ) {
|
157 |
+
$sql .= $this->get_sql_column_definition( $copy, $key );
|
158 |
}
|
159 |
|
160 |
+
$sql .= $this->get_table_options() . PHP_EOL;
|
161 |
$sql .= ') ' . $_wpdb->get_charset_collate();
|
162 |
|
163 |
return $sql;
|
168 |
*
|
169 |
* @return string
|
170 |
*/
|
171 |
+
public function get_table() {
|
172 |
$_wpdb = $this->connection;
|
173 |
|
174 |
+
return $_wpdb->base_prefix . $this->table;
|
175 |
}
|
176 |
|
177 |
/**
|
179 |
*
|
180 |
* @return array
|
181 |
*/
|
182 |
+
public function get_columns() {
|
183 |
+
$model = $this->get_model();
|
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] != '_' ) { // phpcs:ignore
|
189 |
+
$this->column_cache[] = $col;
|
190 |
}
|
191 |
}
|
192 |
}
|
193 |
|
194 |
+
return $this->column_cache;
|
195 |
}
|
196 |
|
197 |
/**
|
198 |
+
* {@inheritDoc}
|
199 |
*/
|
200 |
+
public function get_model() {
|
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 Object copy to populate.
|
208 |
+
* @param string $key Column key.
|
209 |
*
|
210 |
* @return string
|
211 |
*/
|
212 |
+
protected function get_sql_column_definition( $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 ):
|
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 |
|
250 |
*
|
251 |
* @return string
|
252 |
*/
|
253 |
+
protected function get_table_options() {
|
254 |
+
return ' PRIMARY KEY (' . $this->idkey . ')';
|
255 |
}
|
256 |
|
257 |
/**
|
258 |
* Install this ActiveRecord structure into DB WordPress.
|
259 |
*/
|
260 |
+
public function install_original() {
|
261 |
global $wpdb;
|
262 |
+
$wpdb->query( $this->get_install_query( true ) ); // phpcs:ignore
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
+
* {@inheritDoc}
|
267 |
*/
|
268 |
+
public function uninstall() {
|
269 |
$_wpdb = $this->connection;
|
270 |
|
271 |
// Check if table exists.
|
272 |
if ( $this->table_exists() ) {
|
273 |
+
$_wpdb->query( $this->get_uninstall_query() );
|
274 |
}
|
275 |
}
|
276 |
|
283 |
$_wpdb = $this->connection;
|
284 |
|
285 |
// Query table exists.
|
286 |
+
$table_exists_query = "SHOW TABLES LIKE '" . $this->get_table() . "'";
|
287 |
|
288 |
return $_wpdb->query( $table_exists_query );
|
289 |
}
|
293 |
*
|
294 |
* @return string
|
295 |
*/
|
296 |
+
protected function get_uninstall_query() {
|
297 |
+
return 'DROP TABLE IF EXISTS ' . $this->get_table();
|
298 |
}
|
299 |
|
300 |
/**
|
301 |
+
* {@inheritDoc}
|
302 |
*/
|
303 |
+
public function save( $active_record ) {
|
304 |
$_wpdb = $this->connection;
|
305 |
$copy = $active_record;
|
306 |
$data = array();
|
307 |
$format = array();
|
308 |
|
309 |
+
$columns = $this->get_columns();
|
310 |
foreach ( $columns as $index => $key ) {
|
311 |
+
if ( $key == $this->idkey ) { // phpcs:ignore
|
312 |
+
$id_index = $index;
|
313 |
}
|
314 |
|
315 |
$val = $copy->$key;
|
323 |
}
|
324 |
|
325 |
if ( is_array( $copy->$key ) || is_object( $copy->$key ) ) {
|
326 |
+
$data[ $key ] = WSAL_Helpers_DataHelper::json_encode( $val );
|
327 |
} else {
|
328 |
$data[ $key ] = $val;
|
329 |
}
|
331 |
$format[] = $deffmt;
|
332 |
}
|
333 |
|
334 |
+
if ( isset( $data[ $this->idkey ] ) && empty( $data[ $this->idkey ] ) ) {
|
335 |
+
unset( $data[ $this->idkey ] );
|
336 |
+
unset( $format[ $id_index ] );
|
337 |
}
|
338 |
|
339 |
+
$result = $_wpdb->replace( $this->get_table(), $data, $format );
|
340 |
|
341 |
if ( false !== $result && $_wpdb->insert_id ) {
|
342 |
+
$copy->set_id( $_wpdb->insert_id );
|
343 |
}
|
344 |
|
345 |
return $result;
|
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->get_table() . ' WHERE ' . $cond, $args );
|
359 |
|
360 |
return $_wpdb->get_row( $sql, ARRAY_A );
|
361 |
}
|
367 |
* @param array $args (Optional) Load condition arguments.
|
368 |
*
|
369 |
* @return array
|
|
|
370 |
*/
|
371 |
+
public function load_array( $cond, $args = array() ) {
|
372 |
$_wpdb = $this->connection;
|
373 |
$result = array();
|
374 |
+
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->get_table() . ' WHERE ' . $cond, $args );
|
375 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
376 |
+
$result[] = $this->get_model()->load_data( $data );
|
377 |
}
|
378 |
|
379 |
return $result;
|
380 |
}
|
381 |
|
382 |
/**
|
383 |
+
* {@inheritDoc}
|
384 |
*/
|
385 |
+
public function delete( $active_record ) {
|
386 |
$_wpdb = $this->connection;
|
387 |
|
388 |
return $_wpdb->delete(
|
389 |
+
$this->get_table(),
|
390 |
array(
|
391 |
+
$this->idkey => $active_record->get_id(),
|
392 |
),
|
393 |
array( '%d' )
|
394 |
);
|
402 |
*
|
403 |
* @return int|bool
|
404 |
*/
|
405 |
+
public function delete_query( $query, $args = array() ) {
|
406 |
$_wpdb = $this->connection;
|
407 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
408 |
|
410 |
}
|
411 |
|
412 |
/**
|
413 |
+
* {@inheritDoc}
|
414 |
*/
|
415 |
+
public function load_multi( $cond, $args = array() ) {
|
416 |
$_wpdb = $this->connection;
|
417 |
$result = array();
|
418 |
$sql = ( ! is_array( $args ) || ! count( $args ) ) // Do we really need to prepare() or not?
|
419 |
? ( $cond )
|
420 |
: $_wpdb->prepare( $cond, $args );
|
421 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
422 |
+
$result[] = $this->get_model()->load_data( $data );
|
423 |
}
|
424 |
|
425 |
return $result;
|
426 |
}
|
427 |
|
428 |
/**
|
429 |
+
* {@inheritDoc}
|
430 |
*/
|
431 |
+
public function load_and_call_for_each( $callback, $cond = '%d', $args = array( 1 ) ) {
|
432 |
$_wpdb = $this->connection;
|
433 |
$class = get_called_class();
|
434 |
+
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->get_table() . ' WHERE ' . $cond, $args );
|
435 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
436 |
call_user_func( $callback, new $class( $data ) );
|
437 |
}
|
438 |
}
|
439 |
|
440 |
/**
|
441 |
+
* {@inheritDoc}
|
442 |
*/
|
443 |
+
public function count( $cond = '%d', $args = array( 1 ) ) {
|
444 |
$_wpdb = $this->connection;
|
445 |
+
$sql = $_wpdb->prepare( 'SELECT COUNT(*) FROM ' . $this->get_table() . ' WHERE ' . $cond, $args );
|
446 |
|
447 |
return (int) $_wpdb->get_var( $sql );
|
448 |
}
|
455 |
*
|
456 |
* @return int Number of matching records.
|
457 |
*/
|
458 |
+
public function count_query( $query, $args = array() ) {
|
459 |
$_wpdb = $this->connection;
|
460 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
461 |
|
463 |
}
|
464 |
|
465 |
/**
|
466 |
+
* {@inheritDoc}
|
467 |
*/
|
468 |
+
public function load_multi_query( $query, $args = array() ) {
|
469 |
$_wpdb = $this->connection;
|
470 |
$result = array();
|
471 |
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
472 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
473 |
+
$result[] = $this->get_model()->load_data( $data );
|
474 |
}
|
475 |
|
476 |
return $result;
|
528 |
*/
|
529 |
private function build_reporting_query( $report_args, $count_only, $grouping = null, $next_date = null, $limit = 0 ) {
|
530 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
531 |
+
$table_occ = $occurrence->get_table();
|
532 |
|
533 |
if ( $count_only ) {
|
534 |
$select_fields = array( 'COUNT(1) as count' );
|
535 |
$group_by = array( 'occ.id' );
|
536 |
} elseif ( is_null( $grouping ) ) {
|
537 |
$select_fields = array(
|
538 |
+
'occ.id',
|
539 |
+
'occ.alert_id',
|
540 |
+
'occ.site_id',
|
541 |
+
'occ.created_on',
|
542 |
"replace( replace( replace( occ.user_roles, '[', ''), ']', ''), '\\'', '') AS roles",
|
543 |
+
'occ.client_ip AS ip',
|
544 |
+
'occ.user_agent AS ua',
|
545 |
+
'COALESCE( occ.username, occ.user_id ) as user_id',
|
546 |
+
'occ.object',
|
547 |
+
'occ.event_type',
|
548 |
+
'occ.post_id',
|
549 |
+
'occ.post_type',
|
550 |
+
'occ.post_status',
|
551 |
);
|
552 |
} else {
|
553 |
$select_fields = array();
|
554 |
$group_by = array();
|
555 |
foreach ( $grouping as $grouping_item ) {
|
556 |
+
switch ( $grouping_item ) {
|
557 |
case 'site':
|
558 |
array_push( $select_fields, 'site_id' );
|
559 |
array_push( $group_by, 'site_id' );
|
560 |
break;
|
561 |
case 'users':
|
562 |
+
array_push( $select_fields, 'COALESCE( occ.username, occ.user_id ) as user' );
|
563 |
array_push( $group_by, 'user' );
|
564 |
break;
|
565 |
case 'posts':
|
592 |
}
|
593 |
|
594 |
if ( isset( $group_by ) && ! empty( $group_by ) ) {
|
595 |
+
$sql .= ' GROUP BY ' . implode( ',', $group_by );
|
596 |
+
$orderby_parts = array_map(
|
597 |
+
function ( $item ) {
|
598 |
+
return 'period' === $item ? $item . ' DESC ' : $item . ' ASC ';
|
599 |
+
},
|
600 |
+
$group_by
|
601 |
+
);
|
602 |
|
603 |
+
$sql .= ' ORDER BY ' . implode( ',', $orderby_parts );
|
604 |
} else {
|
605 |
+
$sql .= ' ORDER BY created_on DESC ';
|
606 |
}
|
607 |
|
608 |
if ( ! empty( $limit ) ) {
|
623 |
$_site_id = null;
|
624 |
$sites_negate_expression = '';
|
625 |
if ( $report_args->site__in ) {
|
626 |
+
$_site_id = $this->format_array_for_query( $report_args->site__in );
|
627 |
} elseif ( $report_args->site__not_in ) {
|
628 |
+
$_site_id = $this->format_array_for_query( $report_args->site__not_in );
|
629 |
$sites_negate_expression = 'NOT';
|
630 |
}
|
631 |
|
632 |
$_user_id = null;
|
633 |
$users_negate_expression = '';
|
634 |
if ( $report_args->user__in ) {
|
635 |
+
$_user_id = $this->format_array_for_query( $report_args->user__in );
|
636 |
} elseif ( $report_args->user__not_in ) {
|
637 |
+
$_user_id = $this->format_array_for_query( $report_args->user__not_in );
|
638 |
$users_negate_expression = 'NOT';
|
639 |
}
|
640 |
|
641 |
+
$user_names = $this->get_user_names( $_user_id );
|
642 |
|
643 |
$_role_name = null;
|
644 |
$roles_negate_expression = '';
|
645 |
if ( $report_args->role__in ) {
|
646 |
+
$_role_name = $this->format_array_for_query_regex( $report_args->role__in );
|
647 |
} elseif ( $report_args->role__not_in ) {
|
648 |
+
$_role_name = $this->format_array_for_query_regex( $report_args->role__not_in );
|
649 |
$roles_negate_expression = 'NOT';
|
650 |
}
|
651 |
|
652 |
$_alert_code = null;
|
653 |
$alert_code_negate_expression = '';
|
654 |
if ( $report_args->code__in ) {
|
655 |
+
$_alert_code = $this->format_array_for_query( $report_args->code__in );
|
656 |
} elseif ( $report_args->code__not_in ) {
|
657 |
+
$_alert_code = $this->format_array_for_query( $report_args->code__not_in );
|
658 |
$alert_code_negate_expression = 'NOT';
|
659 |
}
|
660 |
|
661 |
$_post_ids = null;
|
662 |
$post_ids_negate_expression = '';
|
663 |
if ( $report_args->post__in ) {
|
664 |
+
$_post_ids = $this->format_array_for_query_regex( $report_args->post__in );
|
665 |
} elseif ( $report_args->post__not_in ) {
|
666 |
+
$_post_ids = $this->format_array_for_query_regex( $report_args->post__not_in );
|
667 |
$post_ids_negate_expression = 'NOT';
|
668 |
}
|
669 |
|
670 |
$_post_types = null;
|
671 |
$post_types_negate_expression = '';
|
672 |
if ( $report_args->post_type__in ) {
|
673 |
+
$_post_types = $this->format_array_for_query_regex( $report_args->post_type__in );
|
674 |
} elseif ( $report_args->post_type__not_in ) {
|
675 |
+
$_post_types = $this->format_array_for_query_regex( $report_args->post_type__not_in );
|
676 |
$post_types_negate_expression = 'NOT';
|
677 |
}
|
678 |
|
679 |
$_post_statuses = null;
|
680 |
$post_statuses_negate_expression = '';
|
681 |
if ( $report_args->post_status__in ) {
|
682 |
+
$_post_statuses = $this->format_array_for_query_regex( $report_args->post_status__in );
|
683 |
+
} elseif ( $report_args->post_status__not_in ) {
|
684 |
+
$_post_statuses = $this->format_array_for_query_regex( $report_args->post_status__not_in );
|
685 |
$post_statuses_negate_expression = 'NOT';
|
686 |
}
|
687 |
|
688 |
$_ip_addresses = null;
|
689 |
$ip_addresses_negate_expression = '';
|
690 |
if ( $report_args->ip__in ) {
|
691 |
+
$_ip_addresses = $this->format_array_for_query( $report_args->ip__in );
|
692 |
+
} elseif ( $report_args->ip__not_in ) {
|
693 |
+
$_ip_addresses = $this->format_array_for_query( $report_args->ip__not_in );
|
694 |
$ip_addresses_negate_expression = 'NOT';
|
695 |
}
|
696 |
|
697 |
$_objects = null;
|
698 |
$objects_negate_expression = '';
|
699 |
if ( $report_args->object__in ) {
|
700 |
+
$_objects = $this->format_array_for_query( $report_args->object__in );
|
701 |
} elseif ( $report_args->object__not_in ) {
|
702 |
+
$_objects = $this->format_array_for_query( $report_args->object__not_in );
|
703 |
$objects_negate_expression = 'NOT';
|
704 |
}
|
705 |
|
706 |
$_event_types = null;
|
707 |
$event_types_negate_expression = '';
|
708 |
if ( $report_args->type__in ) {
|
709 |
+
$_event_types = $this->format_array_for_query( $report_args->type__in );
|
710 |
} elseif ( $report_args->type__not_in ) {
|
711 |
+
$_event_types = $this->format_array_for_query( $report_args->type__not_in );
|
712 |
$event_types_negate_expression = 'NOT';
|
713 |
}
|
714 |
|
733 |
array_push( $users_condition_parts, " {$users_negate_expression} replace( occ.username, '\"', '' ) IN ( $user_names ) " );
|
734 |
}
|
735 |
|
736 |
+
$where_statement = ' WHERE 1 = 1 ';
|
737 |
|
738 |
if ( ! empty( $users_condition_parts ) ) {
|
739 |
$where_statement .= ' AND ( ' . implode( 'OR', $users_condition_parts ) . ' ) ';
|
787 |
}
|
788 |
|
789 |
/**
|
790 |
+
* Formats array for use in SQL query.
|
791 |
+
*
|
792 |
+
* @param array $data Data to format.
|
793 |
*
|
794 |
* @return string
|
795 |
* @since 4.3.2
|
796 |
*/
|
797 |
+
protected function format_array_for_query( $data ) {
|
798 |
return "'" . implode( ',', $data ) . "'";
|
799 |
}
|
800 |
|
801 |
/**
|
802 |
* Get Users user_login.
|
803 |
*
|
804 |
+
* @param int $user_id - User ID.
|
805 |
*
|
806 |
* @return string comma separated users login
|
807 |
*/
|
808 |
+
private function get_user_names( $user_id ) {
|
809 |
global $wpdb;
|
810 |
|
811 |
$user_names = null;
|
812 |
+
if ( ! empty( $user_id ) && 'null' !== $user_id && ! is_null( $user_id ) ) {
|
813 |
$sql = 'SELECT user_login FROM ' . $wpdb->users . ' WHERE find_in_set(ID, @userId) > 0';
|
814 |
+
$wpdb->query( "SET @userId = $user_id" ); // phpcs:ignore
|
815 |
+
$result = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore
|
816 |
$users_array = array();
|
817 |
foreach ( $result as $item ) {
|
818 |
$users_array[] = '"' . $item['user_login'] . '"';
|
824 |
}
|
825 |
|
826 |
/**
|
827 |
+
* Formats data as SQL query regex.
|
828 |
+
*
|
829 |
+
* @param array $data Data to format.
|
830 |
*
|
831 |
* @return string
|
832 |
* @since 4.3.2
|
833 |
*/
|
834 |
+
protected function format_array_for_query_regex( $data ) {
|
835 |
$result = array();
|
836 |
foreach ( $data as $item ) {
|
837 |
+
array_push( $result, esc_sql( preg_quote( $item ) ) ); // phpcs:ignore
|
838 |
}
|
839 |
|
840 |
return "'" . implode( '|', $result ) . "'";
|
846 |
*
|
847 |
* @param WSAL_ReportArgs $report_args - Query conditions.
|
848 |
*
|
849 |
+
* @return int Count of distinct values.
|
850 |
*/
|
851 |
+
public function check_match_report_criteria( $report_args ) {
|
852 |
$query = $this->build_reporting_query( $report_args, true );
|
853 |
|
854 |
return (int) $this->connection->get_var( $query );
|
870 |
|
871 |
// Tables.
|
872 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
873 |
+
$table_occ = $occurrence->get_table();
|
874 |
|
875 |
// Get temp table `wsal_tmp_users`.
|
876 |
$tmp_users = new WSAL_Adapters_MySQL_TmpUser( $_wpdb );
|
877 |
// If the table exist.
|
878 |
+
if ( $tmp_users->is_installed() ) {
|
879 |
+
$table_users = $tmp_users->get_table();
|
880 |
+
$this->temp_users( $table_users );
|
881 |
} else {
|
882 |
$table_users = $wpdb->users;
|
883 |
}
|
918 |
|
919 |
$where_statement = $this->build_where_statement( $report_args );
|
920 |
|
921 |
+
$sql = '
|
922 |
+
SELECT ' . implode( ',', $select_fields ) . " FROM (
|
923 |
SELECT occ.created_on, occ.site_id, occ.username, occ.client_ip
|
924 |
FROM $table_occ AS occ
|
925 |
{$where_statement}
|
933 |
) ip_logins
|
934 |
GROUP BY " . implode( ',', $group_by_columns );
|
935 |
|
936 |
+
$orderby_parts = array_map(
|
937 |
+
function ( $item ) {
|
938 |
+
return 'period' === $item ? $item . ' DESC ' : $item . ' ASC ';
|
939 |
+
},
|
940 |
+
$group_by_columns
|
941 |
+
);
|
942 |
|
943 |
+
$sql .= ' ORDER BY ' . implode( ',', $orderby_parts );
|
944 |
|
945 |
if ( ! empty( $limit ) ) {
|
946 |
$sql .= " LIMIT {$limit}";
|
955 |
}
|
956 |
|
957 |
/**
|
958 |
+
* {@inheritDoc}
|
959 |
*/
|
960 |
+
public function is_installed() {
|
961 |
$_wpdb = $this->connection;
|
962 |
+
$sql = "SHOW TABLES LIKE '" . $this->get_table() . "'";
|
963 |
|
964 |
// Table transient.
|
965 |
+
$wsal_table_transient = 'wsal_' . strtolower( $this->get_table() ) . '_status';
|
966 |
$wsal_db_table_status = get_transient( $wsal_table_transient );
|
967 |
|
968 |
// If transient does not exist, then run SQL query.
|
969 |
if ( ! $wsal_db_table_status ) {
|
970 |
+
$wsal_db_table_status = strtolower( $_wpdb->get_var( $sql ) ) === strtolower( $this->get_table() );
|
971 |
set_transient( $wsal_table_transient, $wsal_db_table_status, DAY_IN_SECONDS );
|
972 |
}
|
973 |
|
980 |
*
|
981 |
* @param string $table_users - Table name.
|
982 |
*/
|
983 |
+
private function temp_users( $table_users ) {
|
984 |
$_wpdb = $this->connection;
|
985 |
$sql = "DELETE FROM $table_users";
|
986 |
$_wpdb->query( $sql );
|
1001 |
/**
|
1002 |
* Updates records in DB matching a query.
|
1003 |
*
|
1004 |
+
* @param string $table Table name.
|
1005 |
* @param array $data Data to update (in column => value pairs).
|
1006 |
* Both $data columns and $data values should be "raw" (neither should be SQL
|
1007 |
* escaped). Sending a null value will cause the column to be set to NULL - the
|
1015 |
* @return int|false The number of rows updated, or false on error.
|
1016 |
* @since 4.1.3
|
1017 |
*/
|
1018 |
+
public function update_query( $table, $data, $where ) {
|
1019 |
return $this->connection->update( $table, $data, $where );
|
1020 |
}
|
1021 |
}
|
classes/Adapters/MySQL/MetaAdapter.php
CHANGED
@@ -27,14 +27,14 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
27 |
*
|
28 |
* @var string
|
29 |
*/
|
30 |
-
protected $
|
31 |
|
32 |
/**
|
33 |
* Contains primary key column name, override as required.
|
34 |
*
|
35 |
* @var string
|
36 |
*/
|
37 |
-
protected $
|
38 |
|
39 |
/**
|
40 |
* Meta id.
|
@@ -72,13 +72,13 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
72 |
public $value = array(); // Force mixed type.
|
73 |
|
74 |
/**
|
75 |
-
* @inheritDoc
|
76 |
*
|
77 |
* @return WSAL_Models_Meta
|
78 |
*/
|
79 |
-
public function
|
80 |
$result = new WSAL_Models_Meta();
|
81 |
-
$result->
|
82 |
|
83 |
return $result;
|
84 |
}
|
@@ -88,35 +88,35 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
88 |
*
|
89 |
* @return string
|
90 |
*/
|
91 |
-
protected function
|
92 |
-
return parent::
|
93 |
. ' KEY occurrence_name (occurrence_id,name)';
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
-
* @inheritDoc
|
98 |
*/
|
99 |
-
public function
|
100 |
if ( ! empty( $occurrence_ids ) ) {
|
101 |
-
$sql = 'DELETE FROM ' . $this->
|
102 |
// Execute query.
|
103 |
-
parent::
|
104 |
}
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
-
* @inheritDoc
|
109 |
*/
|
110 |
-
public function
|
111 |
-
//
|
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->
|
120 |
}
|
121 |
|
122 |
/**
|
@@ -126,13 +126,13 @@ class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implemen
|
|
126 |
$db_connection = $this->get_connection();
|
127 |
// check if an index exists.
|
128 |
$index_exists = false;
|
129 |
-
if ( $db_connection->query( 'SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name="' . $this->
|
130 |
// query succeeded, does index exist?
|
131 |
$index_exists = ( isset( $db_connection->last_result[0]->IndexIsThere ) ) ? $db_connection->last_result[0]->IndexIsThere : false;
|
132 |
}
|
133 |
// if no index exists then make one.
|
134 |
if ( ! $index_exists ) {
|
135 |
-
$db_connection->query( 'CREATE INDEX name_value ON ' . $this->
|
136 |
}
|
137 |
}
|
138 |
}
|
27 |
*
|
28 |
* @var string
|
29 |
*/
|
30 |
+
protected $table = 'wsal_metadata';
|
31 |
|
32 |
/**
|
33 |
* Contains primary key column name, override as required.
|
34 |
*
|
35 |
* @var string
|
36 |
*/
|
37 |
+
protected $idkey = 'id';
|
38 |
|
39 |
/**
|
40 |
* Meta id.
|
72 |
public $value = array(); // Force mixed type.
|
73 |
|
74 |
/**
|
75 |
+
* {@inheritDoc}
|
76 |
*
|
77 |
* @return WSAL_Models_Meta
|
78 |
*/
|
79 |
+
public function get_model() {
|
80 |
$result = new WSAL_Models_Meta();
|
81 |
+
$result->set_adapter( $this );
|
82 |
|
83 |
return $result;
|
84 |
}
|
88 |
*
|
89 |
* @return string
|
90 |
*/
|
91 |
+
protected function get_table_options() {
|
92 |
+
return parent::get_table_options() . ',' . PHP_EOL
|
93 |
. ' KEY occurrence_name (occurrence_id,name)';
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
+
* {@inheritDoc}
|
98 |
*/
|
99 |
+
public function delete_by_occurrence_ids( $occurrence_ids ) {
|
100 |
if ( ! empty( $occurrence_ids ) ) {
|
101 |
+
$sql = 'DELETE FROM ' . $this->get_table() . ' WHERE occurrence_id IN (' . implode( ',', $occurrence_ids ) . ')';
|
102 |
// Execute query.
|
103 |
+
parent::delete_query( $sql );
|
104 |
}
|
105 |
}
|
106 |
|
107 |
/**
|
108 |
+
* {@inheritDoc}
|
109 |
*/
|
110 |
+
public function load_by_name_and_occurrence_id( $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 ), true ) ) {
|
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 |
/**
|
126 |
$db_connection = $this->get_connection();
|
127 |
// check if an index exists.
|
128 |
$index_exists = false;
|
129 |
+
if ( $db_connection->query( 'SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name="' . $this->get_table() . '" AND index_name="name_value"' ) ) {
|
130 |
// query succeeded, does index exist?
|
131 |
$index_exists = ( isset( $db_connection->last_result[0]->IndexIsThere ) ) ? $db_connection->last_result[0]->IndexIsThere : false;
|
132 |
}
|
133 |
// if no index exists then make one.
|
134 |
if ( ! $index_exists ) {
|
135 |
+
$db_connection->query( 'CREATE INDEX name_value ON ' . $this->get_table() . ' (name, value(64))' );
|
136 |
}
|
137 |
}
|
138 |
}
|
classes/Adapters/MySQL/OccurrenceAdapter.php
CHANGED
@@ -22,16 +22,18 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
22 |
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface {
|
23 |
|
24 |
/**
|
25 |
-
*
|
|
|
|
|
26 |
*/
|
27 |
-
protected $
|
28 |
|
29 |
/**
|
30 |
* Contains primary key column name, override as required.
|
31 |
*
|
32 |
* @var string
|
33 |
*/
|
34 |
-
protected $
|
35 |
|
36 |
/**
|
37 |
* Occurrence id.
|
@@ -158,90 +160,90 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
158 |
public $post_id = 0;
|
159 |
|
160 |
/**
|
161 |
-
* @inheritDoc
|
162 |
*/
|
163 |
-
protected function
|
164 |
-
return parent::
|
165 |
-
|
166 |
}
|
167 |
|
168 |
/**
|
169 |
-
* @inheritDoc
|
170 |
*
|
171 |
* @return WSAL_Models_Occurrence
|
172 |
*/
|
173 |
-
public function
|
174 |
$result = new WSAL_Models_Occurrence();
|
175 |
-
$result->
|
176 |
|
177 |
return $result;
|
178 |
}
|
179 |
|
180 |
/**
|
181 |
-
* @inheritDoc
|
182 |
*/
|
183 |
-
public function
|
184 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
185 |
|
186 |
-
return $meta->
|
187 |
}
|
188 |
|
189 |
/**
|
190 |
-
* @inheritDoc
|
191 |
*/
|
192 |
-
public function
|
193 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
194 |
|
195 |
-
return $meta->
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
-
* @inheritDoc
|
200 |
*/
|
201 |
-
public function
|
202 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
203 |
$query = '(' . str_repeat( 'name = %s OR ', count( $names ) ) . '0)';
|
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->
|
208 |
}
|
209 |
|
210 |
/**
|
211 |
-
* @inheritDoc
|
212 |
*/
|
213 |
-
public function
|
214 |
-
return $this->
|
215 |
-
"SELECT * FROM `{$this->
|
216 |
-
.
|
217 |
-
.
|
218 |
-
.
|
219 |
-
.
|
220 |
-
.
|
221 |
$args
|
222 |
);
|
223 |
}
|
224 |
|
225 |
/**
|
226 |
-
* @inheritDoc
|
227 |
*/
|
228 |
-
public function
|
229 |
-
return $this->
|
230 |
-
"SELECT * FROM `{$this->
|
231 |
-
.
|
232 |
-
.
|
233 |
-
.
|
234 |
-
.
|
235 |
$args
|
236 |
);
|
237 |
}
|
238 |
|
239 |
/**
|
240 |
-
* @inheritDoc
|
241 |
*/
|
242 |
public function check_alert_1003( $args = array() ) {
|
243 |
-
return $this->
|
244 |
-
'SELECT * FROM `' . $this->
|
245 |
WHERE (alert_id = %d)
|
246 |
AND (site_id = %d)
|
247 |
AND (created_on BETWEEN %d AND %d);',
|
@@ -250,13 +252,13 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
-
* @inheritDoc
|
254 |
*/
|
255 |
-
public function
|
256 |
-
return $this->
|
257 |
-
"SELECT occurrence.* FROM `{$this->
|
258 |
-
.
|
259 |
-
.
|
260 |
array( $post_id )
|
261 |
);
|
262 |
}
|
@@ -268,34 +270,37 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
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->
|
272 |
// query succeeded, does index exist?
|
273 |
$index_exists = ( isset( $db_connection->last_result[0]->IndexIsThere ) ) ? $db_connection->last_result[0]->IndexIsThere : false;
|
274 |
}
|
275 |
// if no index exists then make one.
|
276 |
if ( ! $index_exists ) {
|
277 |
-
$db_connection->query( 'CREATE INDEX created_on ON ' . $this->
|
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(
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
. "
|
297 |
-
.
|
298 |
-
.
|
|
|
|
|
|
|
299 |
array( $limit )
|
300 |
);
|
301 |
}
|
@@ -307,9 +312,9 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
307 |
*
|
308 |
* @return array - Distinct values of IPs.
|
309 |
*/
|
310 |
-
public function
|
311 |
$_wpdb = $this->connection;
|
312 |
-
$sql = "SELECT DISTINCT client_ip FROM {$this->
|
313 |
if ( ! is_null( $limit ) ) {
|
314 |
$sql .= ' LIMIT ' . $limit;
|
315 |
}
|
@@ -326,51 +331,47 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
|
|
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
|
338 |
-
if ( ! empty( $this->
|
339 |
-
return $this->
|
340 |
}
|
341 |
|
342 |
-
$result = parent::
|
343 |
-
foreach (
|
344 |
-
if ( ! in_array( $extra_column, $result ) ) {
|
345 |
array_push( $result, $extra_column );
|
346 |
}
|
347 |
}
|
348 |
|
349 |
-
$this->
|
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
|
362 |
if ( 'username' === $key ) {
|
363 |
-
return
|
364 |
}
|
365 |
|
366 |
if ( 'user_id' === $key ) {
|
367 |
-
return
|
368 |
}
|
369 |
|
370 |
if ( is_string( $copy->$key ) ) {
|
371 |
return $key . ' VARCHAR(255) NOT NULL,' . PHP_EOL;
|
372 |
}
|
373 |
|
374 |
-
return parent::
|
375 |
}
|
376 |
}
|
22 |
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface {
|
23 |
|
24 |
/**
|
25 |
+
* Contains the table name
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
*/
|
29 |
+
protected $table = 'wsal_occurrences';
|
30 |
|
31 |
/**
|
32 |
* Contains primary key column name, override as required.
|
33 |
*
|
34 |
* @var string
|
35 |
*/
|
36 |
+
protected $idkey = 'id';
|
37 |
|
38 |
/**
|
39 |
* Occurrence id.
|
160 |
public $post_id = 0;
|
161 |
|
162 |
/**
|
163 |
+
* {@inheritDoc}
|
164 |
*/
|
165 |
+
protected function get_table_options() {
|
166 |
+
return parent::get_table_options() . ',' . PHP_EOL
|
167 |
+
. ' KEY site_alert_created (site_id,alert_id,created_on)';
|
168 |
}
|
169 |
|
170 |
/**
|
171 |
+
* {@inheritDoc}
|
172 |
*
|
173 |
* @return WSAL_Models_Occurrence
|
174 |
*/
|
175 |
+
public function get_model() {
|
176 |
$result = new WSAL_Models_Occurrence();
|
177 |
+
$result->set_adapter( $this );
|
178 |
|
179 |
return $result;
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
+
* {@inheritDoc}
|
184 |
*/
|
185 |
+
public function get_multi_meta( $occurrence ) {
|
186 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
187 |
|
188 |
+
return $meta->load_array( 'occurrence_id = %d', array( $occurrence->id ) );
|
189 |
}
|
190 |
|
191 |
/**
|
192 |
+
* {@inheritDoc}
|
193 |
*/
|
194 |
+
public function get_named_meta( $occurrence, $name ) {
|
195 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
196 |
|
197 |
+
return $meta->load_by_name_and_occurrence_id( $name, $occurrence->id );
|
198 |
}
|
199 |
|
200 |
/**
|
201 |
+
* {@inheritDoc}
|
202 |
*/
|
203 |
+
public function get_first_named_meta( $occurrence, $names ) {
|
204 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
205 |
$query = '(' . str_repeat( 'name = %s OR ', count( $names ) ) . '0)';
|
206 |
$query = 'occurrence_id = %d AND ' . $query . ' ORDER BY name DESC LIMIT 1';
|
207 |
array_unshift( $names, $occurrence->id ); // Prepend args with occurrence id.
|
208 |
|
209 |
+
return $meta->get_model()->load_data( $meta->load( $query, $names ) );
|
210 |
}
|
211 |
|
212 |
/**
|
213 |
+
* {@inheritDoc}
|
214 |
*/
|
215 |
+
public function check_known_users( $args = array() ) {
|
216 |
+
return $this->load_multi_query(
|
217 |
+
"SELECT * FROM `{$this->get_table()}` "
|
218 |
+
. ' WHERE client_ip = %s '
|
219 |
+
. ' AND username = %s '
|
220 |
+
. ' AND alert_id = %d '
|
221 |
+
. ' AND site_id = %d '
|
222 |
+
. ' AND ( created_on BETWEEN %d AND %d );',
|
223 |
$args
|
224 |
);
|
225 |
}
|
226 |
|
227 |
/**
|
228 |
+
* {@inheritDoc}
|
229 |
*/
|
230 |
+
public function check_unknown_users( $args = array() ) {
|
231 |
+
return $this->load_multi_query(
|
232 |
+
"SELECT * FROM `{$this->get_table()}` "
|
233 |
+
. ' WHERE client_ip = %s '
|
234 |
+
. ' AND alert_id = %d '
|
235 |
+
. ' AND site_id = %d '
|
236 |
+
. ' AND ( created_on BETWEEN %d AND %d );',
|
237 |
$args
|
238 |
);
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
+
* {@inheritDoc}
|
243 |
*/
|
244 |
public function check_alert_1003( $args = array() ) {
|
245 |
+
return $this->load_multi_query(
|
246 |
+
'SELECT * FROM `' . $this->get_table() . '`
|
247 |
WHERE (alert_id = %d)
|
248 |
AND (site_id = %d)
|
249 |
AND (created_on BETWEEN %d AND %d);',
|
252 |
}
|
253 |
|
254 |
/**
|
255 |
+
* {@inheritDoc}
|
256 |
*/
|
257 |
+
public function get_by_post_id( $post_id ) {
|
258 |
+
return $this->load_multi_query(
|
259 |
+
"SELECT occurrence.* FROM `{$this->get_table()}` "
|
260 |
+
. ' WHERE post_id = %d '
|
261 |
+
. ' ORDER BY created_on DESC;',
|
262 |
array( $post_id )
|
263 |
);
|
264 |
}
|
270 |
$index_exists = false;
|
271 |
$db_connection = $this->get_connection();
|
272 |
// check if an index exists.
|
273 |
+
if ( $db_connection->query( 'SELECT COUNT(1) IndexIsThere FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name="' . $this->get_table() . '" AND index_name="created_on"' ) ) {
|
274 |
// query succeeded, does index exist?
|
275 |
$index_exists = ( isset( $db_connection->last_result[0]->IndexIsThere ) ) ? $db_connection->last_result[0]->IndexIsThere : false;
|
276 |
}
|
277 |
// if no index exists then make one.
|
278 |
if ( ! $index_exists ) {
|
279 |
+
$db_connection->query( 'CREATE INDEX created_on ON ' . $this->get_table() . ' (created_on)' );
|
280 |
}
|
281 |
}
|
282 |
|
283 |
/**
|
284 |
+
* {@inheritDoc}
|
285 |
*/
|
286 |
public function get_all_with_meta_to_migrate( $limit ) {
|
287 |
$meta_adapter = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
288 |
|
289 |
+
$meta_keys = array_map(
|
290 |
+
function ( $value ) {
|
291 |
+
return '"' . $value . '"';
|
292 |
+
},
|
293 |
+
array_keys( WSAL_Models_Occurrence::$migrated_meta )
|
294 |
+
);
|
295 |
+
|
296 |
+
return $this->load_multi_query(
|
297 |
+
"SELECT o.* FROM `{$this->get_table()}` o "
|
298 |
+
. " INNER JOIN `{$meta_adapter->get_table()}` m "
|
299 |
+
. ' ON m.occurrence_id = o.id '
|
300 |
+
. ' WHERE m.name IN (' . implode( ',', $meta_keys ) . ') '
|
301 |
+
. ' GROUP BY o.id '
|
302 |
+
. ' ORDER BY created_on DESC '
|
303 |
+
. ' LIMIT 0, %d;',
|
304 |
array( $limit )
|
305 |
);
|
306 |
}
|
312 |
*
|
313 |
* @return array - Distinct values of IPs.
|
314 |
*/
|
315 |
+
public function get_matching_ips( $limit = null ) {
|
316 |
$_wpdb = $this->connection;
|
317 |
+
$sql = "SELECT DISTINCT client_ip FROM {$this->get_table()}";
|
318 |
if ( ! is_null( $limit ) ) {
|
319 |
$sql .= ' LIMIT ' . $limit;
|
320 |
}
|
331 |
}
|
332 |
|
333 |
/**
|
334 |
+
* {@inheritDoc}
|
335 |
*
|
336 |
+
* "username" and user_id columns have to be added manually because function get_object_vars doesn't return
|
337 |
* uninitialised properties. These two cannot have the default value set because some database queries rely on
|
338 |
* having null values in the database.
|
339 |
*
|
340 |
* @since 4.4.0
|
341 |
*/
|
342 |
+
public function get_columns() {
|
343 |
+
if ( ! empty( $this->column_cache ) ) {
|
344 |
+
return $this->column_cache;
|
345 |
}
|
346 |
|
347 |
+
$result = parent::get_columns();
|
348 |
+
foreach ( array( 'username', 'user_id' ) as $extra_column ) {
|
349 |
+
if ( ! in_array( $extra_column, $result, true ) ) {
|
350 |
array_push( $result, $extra_column );
|
351 |
}
|
352 |
}
|
353 |
|
354 |
+
$this->column_cache = $result;
|
355 |
|
356 |
return $result;
|
357 |
}
|
358 |
|
359 |
/**
|
360 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
|
|
361 |
*/
|
362 |
+
protected function get_sql_column_definition( $copy, $key ) {
|
363 |
if ( 'username' === $key ) {
|
364 |
+
return ' username VARCHAR(255) NULL, ';
|
365 |
}
|
366 |
|
367 |
if ( 'user_id' === $key ) {
|
368 |
+
return ' user_id BIGINT NULL, ';
|
369 |
}
|
370 |
|
371 |
if ( is_string( $copy->$key ) ) {
|
372 |
return $key . ' VARCHAR(255) NOT NULL,' . PHP_EOL;
|
373 |
}
|
374 |
|
375 |
+
return parent::get_sql_column_definition( $copy, $key );
|
376 |
}
|
377 |
}
|
classes/Adapters/MySQL/QueryAdapter.php
CHANGED
@@ -42,14 +42,15 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
42 |
/**
|
43 |
* Get the SQL filled with the args.
|
44 |
*
|
45 |
-
* @param
|
46 |
-
* @param array
|
|
|
47 |
* @return string Generated sql.
|
48 |
*/
|
49 |
-
protected function
|
50 |
-
$conditions
|
51 |
-
$search_condition = $this->
|
52 |
-
$s_where_clause
|
53 |
foreach ( $conditions as $field_name => $field_value ) {
|
54 |
if ( empty( $s_where_clause ) ) {
|
55 |
$s_where_clause .= ' WHERE ';
|
@@ -62,47 +63,48 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
62 |
foreach ( $field_value as $or_field_name => $or_field_value ) {
|
63 |
if ( is_array( $or_field_value ) ) {
|
64 |
foreach ( $or_field_value as $value ) {
|
65 |
-
if ( '(' != $sub_where_clause ) {
|
66 |
$sub_where_clause .= ' OR ';
|
67 |
}
|
68 |
$sub_where_clause .= $or_field_name;
|
69 |
-
$args[]
|
70 |
}
|
71 |
} else {
|
72 |
-
if ( '(' != $sub_where_clause ) {
|
73 |
$sub_where_clause .= ' OR ';
|
74 |
}
|
75 |
$sub_where_clause .= $or_field_name;
|
76 |
-
$args[]
|
77 |
}
|
78 |
}
|
79 |
$sub_where_clause .= ')';
|
80 |
-
$s_where_clause
|
81 |
} else {
|
82 |
$s_where_clause .= $field_name;
|
83 |
-
$args[]
|
84 |
}
|
85 |
}
|
86 |
|
87 |
-
$from_data_sets = $query->
|
88 |
-
$columns
|
89 |
-
$order_bys
|
90 |
|
91 |
$s_limit_clause = '';
|
92 |
-
if ( $query->
|
93 |
$s_limit_clause .= ' LIMIT ';
|
94 |
-
if ( $query->
|
95 |
-
$s_limit_clause .= $query->
|
96 |
}
|
97 |
-
$s_limit_clause .= $query->
|
98 |
}
|
|
|
99 |
$join_clause = '';
|
100 |
-
if ( $query->
|
101 |
-
$meta
|
102 |
-
$occurrence
|
103 |
-
$join_clause = ' LEFT JOIN ' . $meta->
|
104 |
}
|
105 |
-
$fields = (empty( $columns )) ? $from_data_sets[0] . '.*' : implode( ',', $columns );
|
106 |
if ( ! empty( $search_condition ) ) {
|
107 |
$args[] = $search_condition['args'];
|
108 |
}
|
@@ -118,7 +120,7 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
118 |
. $s_where_clause
|
119 |
. $search_statement
|
120 |
// @todo GROUP BY goes here
|
121 |
-
. ( ! empty( $order_bys ) ? (' ORDER BY ' . implode( ', ', array_keys( $order_bys ) ) . ' ' . implode( ', ', array_values( $order_bys ) )) : '')
|
122 |
. $s_limit_clause;
|
123 |
return $sql;
|
124 |
}
|
@@ -128,46 +130,49 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
128 |
*
|
129 |
* @return WSAL_Adapters_MySQL_ActiveRecord
|
130 |
*/
|
131 |
-
protected function
|
132 |
return new WSAL_Adapters_MySQL_ActiveRecord( $this->connection );
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
-
* @inheritDoc
|
137 |
*/
|
138 |
-
public function
|
139 |
$args = array();
|
140 |
-
$sql = $this->
|
141 |
|
142 |
-
$args = array_filter(
|
143 |
-
|
144 |
-
|
|
|
|
|
|
|
145 |
|
146 |
-
$occurrence_adapter = $query->
|
147 |
|
148 |
-
if ( in_array( $occurrence_adapter->
|
149 |
-
return $occurrence_adapter->
|
150 |
} else {
|
151 |
-
return $this->
|
152 |
}
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
-
* @inheritDoc
|
157 |
*/
|
158 |
-
public function
|
159 |
// Back up columns, use COUNT as default column and generate sql.
|
160 |
-
$cols = $query->
|
161 |
-
$query->
|
162 |
-
$query->
|
163 |
|
164 |
$args = array();
|
165 |
-
$sql = $this->
|
166 |
|
167 |
// Restore columns.
|
168 |
-
$query->
|
169 |
// Execute query and return result.
|
170 |
-
return $this->
|
171 |
}
|
172 |
|
173 |
/**
|
@@ -176,61 +181,62 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
176 |
* @param object $query - Query object.
|
177 |
* @return integer counting records.
|
178 |
*/
|
179 |
-
public function
|
180 |
-
$result = $this->
|
181 |
// Execute query and return result.
|
182 |
-
return $this->
|
183 |
}
|
184 |
|
185 |
/**
|
186 |
-
* @inheritDoc
|
187 |
*/
|
188 |
-
public function
|
189 |
-
$result = $this->
|
190 |
-
$this->
|
191 |
-
return $this->
|
192 |
}
|
193 |
|
194 |
/**
|
195 |
* Load occurrence IDs then delete Metadata by occurrence_id
|
196 |
*
|
197 |
-
* @param
|
198 |
-
* @param array
|
199 |
*/
|
200 |
-
public function
|
201 |
// Back up columns, use COUNT as default column and generate sql.
|
202 |
-
$cols = $query->
|
203 |
-
$query->
|
204 |
-
$query->
|
205 |
-
$sql = $this->
|
206 |
// Restore columns.
|
207 |
-
$query->
|
208 |
|
209 |
-
$_wpdb
|
210 |
$occ_ids = array();
|
211 |
-
$sql
|
212 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
213 |
$occ_ids[] = $data['id'];
|
214 |
}
|
215 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
216 |
-
$meta->
|
217 |
}
|
218 |
|
219 |
/**
|
220 |
* Get the DELETE query SQL filled with the args.
|
221 |
*
|
222 |
-
* @param
|
223 |
-
* @param bool
|
|
|
224 |
* @return string - Generated sql.
|
225 |
*/
|
226 |
-
public function
|
227 |
$result = array();
|
228 |
-
$args
|
229 |
// Back up columns, remove them for DELETE and generate sql.
|
230 |
-
$cols = $query->
|
231 |
-
$query->
|
232 |
|
233 |
-
$conditions = $query->
|
234 |
|
235 |
$s_where_clause = '';
|
236 |
foreach ( $conditions as $field_name => $field_value ) {
|
@@ -240,28 +246,28 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
240 |
$s_where_clause .= ' AND ';
|
241 |
}
|
242 |
$s_where_clause .= $field_name;
|
243 |
-
$args[]
|
244 |
}
|
245 |
|
246 |
-
$from_data_sets = $query->
|
247 |
-
$order_bys
|
248 |
|
249 |
$s_limit_clause = '';
|
250 |
-
if ( $query->
|
251 |
$s_limit_clause .= ' LIMIT ';
|
252 |
-
if ( $query->
|
253 |
-
$s_limit_clause .= $query->
|
254 |
}
|
255 |
-
$s_limit_clause .= $query->
|
256 |
}
|
257 |
-
$result['sql']
|
258 |
. implode( ',', $from_data_sets )
|
259 |
. $s_where_clause
|
260 |
-
. ( ! empty( $order_bys ) ? (' ORDER BY ' . implode( ', ', array_keys( $order_bys ) ) . ' ' . implode( ', ', array_values( $order_bys ) )) : '')
|
261 |
. $s_limit_clause;
|
262 |
$result['args'] = $args;
|
263 |
// Restore columns.
|
264 |
-
$query->
|
265 |
|
266 |
return $result;
|
267 |
}
|
@@ -269,22 +275,23 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
269 |
/**
|
270 |
* Search by alert code OR by Metadata value.
|
271 |
*
|
272 |
-
* @param
|
273 |
*/
|
274 |
-
public function
|
275 |
-
$condition = $query->
|
276 |
if ( empty( $condition ) ) {
|
277 |
return null;
|
278 |
}
|
|
|
279 |
$search_conditions = array();
|
280 |
-
$meta
|
281 |
-
$occurrence
|
282 |
-
if ( is_numeric( $condition ) && strlen( $condition )
|
283 |
-
$search_conditions['sql'] = $occurrence->
|
284 |
} else {
|
285 |
-
$search_conditions['sql'] = $occurrence->
|
286 |
SELECT DISTINCT occurrence_id
|
287 |
-
FROM ' . $meta->
|
288 |
WHERE TRIM(BOTH "\"" FROM value) LIKE %s
|
289 |
)';
|
290 |
}
|
@@ -293,9 +300,16 @@ class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
|
293 |
}
|
294 |
|
295 |
/**
|
296 |
-
* @inheritDoc
|
297 |
*/
|
298 |
-
public function
|
299 |
return ( $this->connection && $this->connection->has_connected );
|
300 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
}
|
42 |
/**
|
43 |
* Get the SQL filled with the args.
|
44 |
*
|
45 |
+
* @param WSAL_Models_Query $query - Query object.
|
46 |
+
* @param array $args - Args of the query.
|
47 |
+
*
|
48 |
* @return string Generated sql.
|
49 |
*/
|
50 |
+
protected function get_sql( $query, &$args = array() ) {
|
51 |
+
$conditions = $query->get_conditions();
|
52 |
+
$search_condition = $this->search_condition( $query );
|
53 |
+
$s_where_clause = '';
|
54 |
foreach ( $conditions as $field_name => $field_value ) {
|
55 |
if ( empty( $s_where_clause ) ) {
|
56 |
$s_where_clause .= ' WHERE ';
|
63 |
foreach ( $field_value as $or_field_name => $or_field_value ) {
|
64 |
if ( is_array( $or_field_value ) ) {
|
65 |
foreach ( $or_field_value as $value ) {
|
66 |
+
if ( '(' != $sub_where_clause ) { // phpcs:ignore
|
67 |
$sub_where_clause .= ' OR ';
|
68 |
}
|
69 |
$sub_where_clause .= $or_field_name;
|
70 |
+
$args[] = $value;
|
71 |
}
|
72 |
} else {
|
73 |
+
if ( '(' != $sub_where_clause ) { // phpcs:ignore
|
74 |
$sub_where_clause .= ' OR ';
|
75 |
}
|
76 |
$sub_where_clause .= $or_field_name;
|
77 |
+
$args[] = $or_field_value;
|
78 |
}
|
79 |
}
|
80 |
$sub_where_clause .= ')';
|
81 |
+
$s_where_clause .= $sub_where_clause;
|
82 |
} else {
|
83 |
$s_where_clause .= $field_name;
|
84 |
+
$args[] = $field_value;
|
85 |
}
|
86 |
}
|
87 |
|
88 |
+
$from_data_sets = $query->get_from();
|
89 |
+
$columns = $query->get_columns();
|
90 |
+
$order_bys = $query->get_order_by();
|
91 |
|
92 |
$s_limit_clause = '';
|
93 |
+
if ( $query->get_limit() ) {
|
94 |
$s_limit_clause .= ' LIMIT ';
|
95 |
+
if ( $query->get_offset() ) {
|
96 |
+
$s_limit_clause .= $query->get_offset() . ', ';
|
97 |
}
|
98 |
+
$s_limit_clause .= $query->get_limit();
|
99 |
}
|
100 |
+
|
101 |
$join_clause = '';
|
102 |
+
if ( $query->has_meta_join() ) {
|
103 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
104 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
105 |
+
$join_clause = ' LEFT JOIN ' . $meta->get_table() . ' AS meta ON meta.occurrence_id = ' . $occurrence->get_table() . '.id ';
|
106 |
}
|
107 |
+
$fields = ( empty( $columns ) ) ? $from_data_sets[0] . '.*' : implode( ',', $columns );
|
108 |
if ( ! empty( $search_condition ) ) {
|
109 |
$args[] = $search_condition['args'];
|
110 |
}
|
120 |
. $s_where_clause
|
121 |
. $search_statement
|
122 |
// @todo GROUP BY goes here
|
123 |
+
. ( ! empty( $order_bys ) ? ( ' ORDER BY ' . implode( ', ', array_keys( $order_bys ) ) . ' ' . implode( ', ', array_values( $order_bys ) ) ) : '' )
|
124 |
. $s_limit_clause;
|
125 |
return $sql;
|
126 |
}
|
130 |
*
|
131 |
* @return WSAL_Adapters_MySQL_ActiveRecord
|
132 |
*/
|
133 |
+
protected function get_active_record_adapter() {
|
134 |
return new WSAL_Adapters_MySQL_ActiveRecord( $this->connection );
|
135 |
}
|
136 |
|
137 |
/**
|
138 |
+
* {@inheritDoc}
|
139 |
*/
|
140 |
+
public function execute_query( $query ) {
|
141 |
$args = array();
|
142 |
+
$sql = $this->get_sql( $query, $args );
|
143 |
|
144 |
+
$args = array_filter(
|
145 |
+
$args,
|
146 |
+
function ( $item ) {
|
147 |
+
return ( '' !== $item );
|
148 |
+
}
|
149 |
+
);
|
150 |
|
151 |
+
$occurrence_adapter = $query->get_connector()->get_adapter( 'Occurrence' );
|
152 |
|
153 |
+
if ( in_array( $occurrence_adapter->get_table(), $query->get_from(), true ) ) {
|
154 |
+
return $occurrence_adapter->load_multi( $sql, $args );
|
155 |
} else {
|
156 |
+
return $this->get_active_record_adapter()->load_multi( $sql, $args );
|
157 |
}
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
+
* {@inheritDoc}
|
162 |
*/
|
163 |
+
public function count( $query ) {
|
164 |
// Back up columns, use COUNT as default column and generate sql.
|
165 |
+
$cols = $query->get_columns();
|
166 |
+
$query->clear_columns();
|
167 |
+
$query->add_column( 'COUNT(*)' );
|
168 |
|
169 |
$args = array();
|
170 |
+
$sql = $this->get_sql( $query, $args );
|
171 |
|
172 |
// Restore columns.
|
173 |
+
$query->set_columns( $cols );
|
174 |
// Execute query and return result.
|
175 |
+
return $this->get_active_record_adapter()->count_query( $sql, $args );
|
176 |
}
|
177 |
|
178 |
/**
|
181 |
* @param object $query - Query object.
|
182 |
* @return integer counting records.
|
183 |
*/
|
184 |
+
public function count_delete( $query ) {
|
185 |
+
$result = $this->get_sql_delete( $query, true );
|
186 |
// Execute query and return result.
|
187 |
+
return $this->get_active_record_adapter()->count_query( $result['sql'], $result['args'] );
|
188 |
}
|
189 |
|
190 |
/**
|
191 |
+
* {@inheritDoc}
|
192 |
*/
|
193 |
+
public function delete( $query ) {
|
194 |
+
$result = $this->get_sql_delete( $query );
|
195 |
+
$this->delete_metas( $query, $result['args'] );
|
196 |
+
return $this->get_active_record_adapter()->delete_query( $result['sql'], $result['args'] );
|
197 |
}
|
198 |
|
199 |
/**
|
200 |
* Load occurrence IDs then delete Metadata by occurrence_id
|
201 |
*
|
202 |
+
* @param WSAL_Models_Query $query - Query object.
|
203 |
+
* @param array $args - Args of the query.
|
204 |
*/
|
205 |
+
public function delete_metas( $query, $args ) {
|
206 |
// Back up columns, use COUNT as default column and generate sql.
|
207 |
+
$cols = $query->get_columns();
|
208 |
+
$query->clear_columns();
|
209 |
+
$query->add_column( 'id' );
|
210 |
+
$sql = $this->get_sql( $query );
|
211 |
// Restore columns.
|
212 |
+
$query->set_columns( $cols );
|
213 |
|
214 |
+
$_wpdb = $this->connection;
|
215 |
$occ_ids = array();
|
216 |
+
$sql = ( ! empty( $args ) ? $_wpdb->prepare( $sql, $args ) : $sql );
|
217 |
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
218 |
$occ_ids[] = $data['id'];
|
219 |
}
|
220 |
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
221 |
+
$meta->delete_by_occurrence_ids( $occ_ids );
|
222 |
}
|
223 |
|
224 |
/**
|
225 |
* Get the DELETE query SQL filled with the args.
|
226 |
*
|
227 |
+
* @param WSAL_Models_Query $query - Query object.
|
228 |
+
* @param bool $get_count - Get count.
|
229 |
+
*
|
230 |
* @return string - Generated sql.
|
231 |
*/
|
232 |
+
public function get_sql_delete( $query, $get_count = false ) {
|
233 |
$result = array();
|
234 |
+
$args = array();
|
235 |
// Back up columns, remove them for DELETE and generate sql.
|
236 |
+
$cols = $query->get_columns();
|
237 |
+
$query->clear_columns();
|
238 |
|
239 |
+
$conditions = $query->get_conditions();
|
240 |
|
241 |
$s_where_clause = '';
|
242 |
foreach ( $conditions as $field_name => $field_value ) {
|
246 |
$s_where_clause .= ' AND ';
|
247 |
}
|
248 |
$s_where_clause .= $field_name;
|
249 |
+
$args[] = $field_value;
|
250 |
}
|
251 |
|
252 |
+
$from_data_sets = $query->get_from();
|
253 |
+
$order_bys = $query->get_order_by();
|
254 |
|
255 |
$s_limit_clause = '';
|
256 |
+
if ( $query->get_limit() ) {
|
257 |
$s_limit_clause .= ' LIMIT ';
|
258 |
+
if ( $query->get_offset() ) {
|
259 |
+
$s_limit_clause .= $query->get_offset() . ', ';
|
260 |
}
|
261 |
+
$s_limit_clause .= $query->get_limit();
|
262 |
}
|
263 |
+
$result['sql'] = ( $get_count ? 'SELECT COUNT(*) FROM ' : 'DELETE FROM ' )
|
264 |
. implode( ',', $from_data_sets )
|
265 |
. $s_where_clause
|
266 |
+
. ( ! empty( $order_bys ) ? ( ' ORDER BY ' . implode( ', ', array_keys( $order_bys ) ) . ' ' . implode( ', ', array_values( $order_bys ) ) ) : '' )
|
267 |
. $s_limit_clause;
|
268 |
$result['args'] = $args;
|
269 |
// Restore columns.
|
270 |
+
$query->set_columns( $cols );
|
271 |
|
272 |
return $result;
|
273 |
}
|
275 |
/**
|
276 |
* Search by alert code OR by Metadata value.
|
277 |
*
|
278 |
+
* @param WSAL_Models_Query $query - Query object.
|
279 |
*/
|
280 |
+
public function search_condition( $query ) {
|
281 |
+
$condition = $query->get_search_condition();
|
282 |
if ( empty( $condition ) ) {
|
283 |
return null;
|
284 |
}
|
285 |
+
|
286 |
$search_conditions = array();
|
287 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
288 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
289 |
+
if ( is_numeric( $condition ) && 4 === strlen( $condition ) ) {
|
290 |
+
$search_conditions['sql'] = $occurrence->get_table() . '.alert_id LIKE %s';
|
291 |
} else {
|
292 |
+
$search_conditions['sql'] = $occurrence->get_table() . '.id IN (
|
293 |
SELECT DISTINCT occurrence_id
|
294 |
+
FROM ' . $meta->get_table() . '
|
295 |
WHERE TRIM(BOTH "\"" FROM value) LIKE %s
|
296 |
)';
|
297 |
}
|
300 |
}
|
301 |
|
302 |
/**
|
303 |
+
* {@inheritDoc}
|
304 |
*/
|
305 |
+
public function is_connected() {
|
306 |
return ( $this->connection && $this->connection->has_connected );
|
307 |
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* {@inheritDoc}
|
311 |
+
*/
|
312 |
+
public function Execute( $query ) {
|
313 |
+
return $this->execute_query( $query );
|
314 |
+
}
|
315 |
}
|
classes/Adapters/MySQL/TmpUserAdapter.php
CHANGED
@@ -29,28 +29,28 @@ class WSAL_Adapters_MySQL_TmpUser extends WSAL_Adapters_MySQL_ActiveRecord {
|
|
29 |
*
|
30 |
* @var string
|
31 |
*/
|
32 |
-
protected $
|
33 |
|
34 |
/**
|
35 |
-
* @inheritDoc
|
36 |
*
|
37 |
* @return WSAL_Models_TmpUser
|
38 |
*/
|
39 |
-
public function
|
40 |
return new WSAL_Models_TmpUser();
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
-
* @inheritDoc
|
45 |
*/
|
46 |
-
protected function
|
47 |
$_wpdb = $this->connection;
|
48 |
-
$table_name = ( $prefix ) ? $this->
|
49 |
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
50 |
-
$sql
|
51 |
-
$sql
|
52 |
-
$sql
|
53 |
-
$sql
|
54 |
|
55 |
return $sql;
|
56 |
}
|
29 |
*
|
30 |
* @var string
|
31 |
*/
|
32 |
+
protected $table = 'wsal_tmp_users';
|
33 |
|
34 |
/**
|
35 |
+
* {@inheritDoc}
|
36 |
*
|
37 |
* @return WSAL_Models_TmpUser
|
38 |
*/
|
39 |
+
public function get_model() {
|
40 |
return new WSAL_Models_TmpUser();
|
41 |
}
|
42 |
|
43 |
/**
|
44 |
+
* {@inheritDoc}
|
45 |
*/
|
46 |
+
protected function get_install_query( $prefix = false ) {
|
47 |
$_wpdb = $this->connection;
|
48 |
+
$table_name = ( $prefix ) ? $this->get_wp_table() : $this->get_table();
|
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 |
}
|
classes/Adapters/OccurrenceInterface.php
CHANGED
@@ -25,9 +25,9 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
25 |
* @param WSAL_Models_Occurrence $occurrence - Occurrence model instance.
|
26 |
*
|
27 |
* @return WSAL_Models_Meta[]
|
28 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::
|
29 |
*/
|
30 |
-
public function
|
31 |
|
32 |
/**
|
33 |
* Loads a meta item given its name.
|
@@ -36,9 +36,9 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
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::
|
40 |
*/
|
41 |
-
public function
|
42 |
|
43 |
/**
|
44 |
* Returns the first meta value from a given set of names.
|
@@ -46,11 +46,11 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
46 |
* a particular detail.
|
47 |
*
|
48 |
* @param object $occurrence - Occurrence model instance.
|
49 |
-
* @param array
|
50 |
*
|
51 |
* @return WSAL_Models_Meta The first meta item that exists.
|
52 |
*/
|
53 |
-
public function
|
54 |
|
55 |
/**
|
56 |
* Gets occurrences of the same type by IP and Username within specified time frame.
|
@@ -59,7 +59,7 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
59 |
*
|
60 |
* @return WSAL_Models_Occurrence[]
|
61 |
*/
|
62 |
-
public function
|
63 |
|
64 |
/**
|
65 |
* Gets occurrences of the same type by IP within specified time frame.
|
@@ -68,7 +68,7 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
68 |
*
|
69 |
* @return WSAL_Models_Occurrence[]
|
70 |
*/
|
71 |
-
public function
|
72 |
|
73 |
/**
|
74 |
* Gets occurrence by Post_id.
|
@@ -77,7 +77,7 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
77 |
*
|
78 |
* @return WSAL_Models_Occurrence[]
|
79 |
*/
|
80 |
-
public function
|
81 |
|
82 |
/**
|
83 |
* Gets occurrences of the alert 1003.
|
@@ -92,7 +92,7 @@ interface WSAL_Adapters_OccurrenceInterface {
|
|
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
|
25 |
* @param WSAL_Models_Occurrence $occurrence - Occurrence model instance.
|
26 |
*
|
27 |
* @return WSAL_Models_Meta[]
|
28 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::load_array()
|
29 |
*/
|
30 |
+
public function get_multi_meta( $occurrence );
|
31 |
|
32 |
/**
|
33 |
* Loads a meta item given its name.
|
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 get_named_meta( $occurrence, $name );
|
42 |
|
43 |
/**
|
44 |
* Returns the first meta value from a given set of names.
|
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 get_first_named_meta( $occurrence, $names );
|
54 |
|
55 |
/**
|
56 |
* Gets occurrences of the same type by IP and Username within specified time frame.
|
59 |
*
|
60 |
* @return WSAL_Models_Occurrence[]
|
61 |
*/
|
62 |
+
public function check_known_users( $args = array() );
|
63 |
|
64 |
/**
|
65 |
* Gets occurrences of the same type by IP within specified time frame.
|
68 |
*
|
69 |
* @return WSAL_Models_Occurrence[]
|
70 |
*/
|
71 |
+
public function check_unknown_users( $args = array() );
|
72 |
|
73 |
/**
|
74 |
* Gets occurrence by Post_id.
|
77 |
*
|
78 |
* @return WSAL_Models_Occurrence[]
|
79 |
*/
|
80 |
+
public function get_by_post_id( $post_id );
|
81 |
|
82 |
/**
|
83 |
* Gets occurrences of the alert 1003.
|
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 Limits the number of results.
|
96 |
*
|
97 |
* @return WSAL_Models_Occurrence[]
|
98 |
* @since 4.4.0
|
classes/Adapters/QueryInterface.php
CHANGED
@@ -22,23 +22,23 @@ interface WSAL_Adapters_QueryInterface {
|
|
22 |
/**
|
23 |
* Execute query and return data as $ar_cls objects.
|
24 |
*
|
25 |
-
* @param
|
26 |
*/
|
27 |
-
public function
|
28 |
|
29 |
/**
|
30 |
* Count query.
|
31 |
*
|
32 |
-
* @param
|
33 |
*/
|
34 |
-
public function
|
35 |
|
36 |
/**
|
37 |
* Query for deleting records.
|
38 |
*
|
39 |
-
* @param
|
40 |
*/
|
41 |
-
public function
|
42 |
|
43 |
/**
|
44 |
* Checks if the adapter is successfully connected.
|
@@ -46,5 +46,16 @@ interface WSAL_Adapters_QueryInterface {
|
|
46 |
* @return bool True if the adapter is connected. False otherwise.
|
47 |
* @since 4.3.2
|
48 |
*/
|
49 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
22 |
/**
|
23 |
* Execute query and return data as $ar_cls objects.
|
24 |
*
|
25 |
+
* @param WSAL_Models_Query $query - Query object.
|
26 |
*/
|
27 |
+
public function execute_query( $query );
|
28 |
|
29 |
/**
|
30 |
* Count query.
|
31 |
*
|
32 |
+
* @param WSAL_Models_Query $query - Query object.
|
33 |
*/
|
34 |
+
public function count( $query );
|
35 |
|
36 |
/**
|
37 |
* Query for deleting records.
|
38 |
*
|
39 |
+
* @param WSAL_Models_Query $query - Query object.
|
40 |
*/
|
41 |
+
public function delete( $query );
|
42 |
|
43 |
/**
|
44 |
* Checks if the adapter is successfully connected.
|
46 |
* @return bool True if the adapter is connected. False otherwise.
|
47 |
* @since 4.3.2
|
48 |
*/
|
49 |
+
public function is_connected();
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Deprecated placeholder function.
|
53 |
+
*
|
54 |
+
* @param WSAL_Models_Query $query - Query object.
|
55 |
+
*
|
56 |
+
* @see WSAL_Adapters_QueryInterface::execute_query()
|
57 |
+
*
|
58 |
+
* @deprecated 4.4.1 Replaced by function execute_query.
|
59 |
+
*/
|
60 |
+
public function Execute( $query );
|
61 |
}
|
classes/Alert.php
CHANGED
@@ -1,4 +1,14 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* WSAL_Alert Object class.
|
@@ -69,7 +79,7 @@ final class WSAL_Alert {
|
|
69 |
* @var array
|
70 |
* @since 4.2.1
|
71 |
*/
|
72 |
-
public $metadata =
|
73 |
|
74 |
/**
|
75 |
* List of metadata items containing metadata key and a label to be displayed.
|
@@ -77,23 +87,23 @@ final class WSAL_Alert {
|
|
77 |
* @var string[]
|
78 |
* @since 4.2.1
|
79 |
*/
|
80 |
-
public $links =
|
81 |
|
82 |
/**
|
83 |
* Constructor.
|
84 |
*
|
85 |
* @param integer $type - Type of alert.
|
86 |
* @param integer $code - Code of alert.
|
87 |
-
* @param string
|
88 |
-
* @param string
|
89 |
-
* @param string
|
90 |
-
* @param string
|
91 |
-
* @param array
|
92 |
-
* @param string
|
93 |
-
* @param string
|
94 |
-
* @param string
|
95 |
*/
|
96 |
-
public function __construct( $type = 0, $code = 0, $catg = '', $subcatg = '', $desc = '', $mesg = '', $metadata =
|
97 |
$this->code = $type;
|
98 |
$this->severity = $code;
|
99 |
$this->catg = $catg;
|
@@ -111,46 +121,45 @@ final class WSAL_Alert {
|
|
111 |
*
|
112 |
* Note: not to be used to display any messages. Use WSAL_Models_Occurrence::GetMessage() instead.
|
113 |
*
|
114 |
-
* @param array
|
115 |
-
* @param string|null
|
116 |
-
* @param integer
|
117 |
* @param string|false $context - Context in which the message will be used/displayed.
|
118 |
*
|
119 |
* @return string Fully formatted message.
|
120 |
-
*
|
121 |
-
* @see WSAL_Models_Occurrence::
|
122 |
*/
|
123 |
-
public function
|
124 |
-
return $this->
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
* Expands a message with variables by replacing variables with meta data values.
|
129 |
*
|
130 |
-
* @param string
|
131 |
-
* @param array
|
132 |
-
* @param integer
|
133 |
* @param string|false $context - Context in which the message will be used/displayed.
|
134 |
*
|
135 |
* @return string The expanded message.
|
136 |
-
* @throws Freemius_Exception
|
137 |
*/
|
138 |
-
protected function
|
139 |
|
140 |
$result = '';
|
141 |
|
142 |
-
//
|
143 |
if ( false === $context ) {
|
144 |
$context = 'default';
|
145 |
}
|
146 |
|
147 |
-
//
|
148 |
-
$formatter = WSAL_AlertFormatterFactory::
|
149 |
|
150 |
// Tokenize message with regex.
|
151 |
$message_parts = preg_split( '/(%.*?%)/', (string) $original_message, - 1, PREG_SPLIT_DELIM_CAPTURE );
|
152 |
if ( ! is_array( $message_parts ) ) {
|
153 |
-
//
|
154 |
$result = (string) $original_message;
|
155 |
} else {
|
156 |
// Handle tokenized message.
|
@@ -160,11 +169,11 @@ final class WSAL_Alert {
|
|
160 |
continue;
|
161 |
}
|
162 |
// Handle escaped percent sign.
|
163 |
-
if ( '%%'
|
164 |
$message_parts[ $i ] = '%';
|
165 |
-
} elseif ( substr( $token, 0, 1 )
|
166 |
// Handle complex expressions.
|
167 |
-
$message_parts[ $i ] = $this->
|
168 |
$message_parts[ $i ] = $formatter->format_meta_expression( $token, $message_parts[ $i ], $occurrence_id );
|
169 |
if ( ! empty( $message_parts[ $i ] ) ) {
|
170 |
$message_parts[ $i ] = $formatter->wrap_in_hightlight_markup( $message_parts[ $i ] );
|
@@ -172,12 +181,12 @@ final class WSAL_Alert {
|
|
172 |
}
|
173 |
}
|
174 |
|
175 |
-
// Compact message
|
176 |
$result = implode( '', $message_parts );
|
177 |
}
|
178 |
}
|
179 |
|
180 |
-
//
|
181 |
$result = $formatter->process_html_tags_in_message( $result );
|
182 |
|
183 |
$end_of_line = $formatter->get_end_of_line();
|
@@ -214,7 +223,7 @@ final class WSAL_Alert {
|
|
214 |
*
|
215 |
* @return mixed The value nearest to the expression.
|
216 |
*/
|
217 |
-
protected function
|
218 |
$expr = preg_replace( '/%/', '', $expr );
|
219 |
if ( 'IPAddress' === $expr ) {
|
220 |
if ( array_key_exists( 'IPAddress', $meta_data ) ) {
|
@@ -235,7 +244,7 @@ final class WSAL_Alert {
|
|
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 |
/**
|
@@ -246,7 +255,6 @@ final class WSAL_Alert {
|
|
246 |
* @param int $occurrence_id Occurrence ID.
|
247 |
*
|
248 |
* @return string
|
249 |
-
* @throws Freemius_Exception
|
250 |
* @since 4.2.1
|
251 |
*/
|
252 |
public function get_formatted_metadata( $formatter, $meta_data, $occurrence_id ) {
|
@@ -276,7 +284,6 @@ final class WSAL_Alert {
|
|
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 ) {
|
@@ -288,7 +295,7 @@ final class WSAL_Alert {
|
|
288 |
}
|
289 |
|
290 |
// Pure alert meta lookup based on meta token.
|
291 |
-
$meta_expression = $this->
|
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 );
|
@@ -303,24 +310,25 @@ final class WSAL_Alert {
|
|
303 |
}
|
304 |
|
305 |
/**
|
306 |
-
*
|
307 |
-
*
|
308 |
-
* @param
|
|
|
|
|
309 |
*
|
310 |
* @return string
|
311 |
-
* @throws Freemius_Exception
|
312 |
* @since 4.2.1
|
313 |
*/
|
314 |
public function get_formatted_hyperlinks( $formatter, $meta_data, $occurrence_id ) {
|
315 |
$result = '';
|
316 |
$hyperlinks_as_array = $this->get_hyperlinks_as_array( $formatter, $meta_data, $occurrence_id );
|
317 |
if ( ! empty( $hyperlinks_as_array ) ) {
|
318 |
-
$links_result_parts =
|
319 |
foreach ( $hyperlinks_as_array as $link_data ) {
|
320 |
-
$link_label
|
321 |
-
$link_url
|
322 |
$needs_formatting = $link_data['needs_formatting'];
|
323 |
-
$formatted_link
|
324 |
array_push( $links_result_parts, $formatted_link );
|
325 |
}
|
326 |
|
@@ -333,16 +341,21 @@ final class WSAL_Alert {
|
|
333 |
}
|
334 |
|
335 |
/**
|
336 |
-
*
|
337 |
-
*
|
338 |
-
* @param
|
339 |
-
* @param
|
|
|
|
|
|
|
|
|
|
|
340 |
*
|
341 |
* @return string
|
342 |
* @since 4.2.1
|
343 |
*/
|
344 |
public function get_hyperlinks_as_array( $formatter, $meta_data, $occurrence_id, $exclude_links_not_needing_formatting = false ) {
|
345 |
-
$result =
|
346 |
if ( ! empty( $this->links ) ) {
|
347 |
foreach ( $this->links as $link_label => $link_data ) {
|
348 |
|
@@ -360,27 +373,29 @@ final class WSAL_Alert {
|
|
360 |
$link_title = $link_data['label'];
|
361 |
}
|
362 |
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
|
|
|
|
368 |
$needs_formatting = true;
|
369 |
if ( ! WSAL_Utilities_RequestUtils::is_valid_url( $link_url ) ) {
|
370 |
|
371 |
-
$meta_expression = $this->
|
372 |
$meta_expression = $formatter->format_meta_expression( $link_url, $meta_expression, $occurrence_id, $meta_data );
|
373 |
if ( ! empty( $meta_expression ) ) {
|
374 |
if ( WSAL_Utilities_RequestUtils::is_valid_url( $meta_expression ) ) {
|
375 |
|
376 |
$link_url = $meta_expression;
|
377 |
-
}
|
378 |
$link_url = $meta_expression;
|
379 |
$needs_formatting = false;
|
380 |
} else {
|
381 |
|
382 |
preg_match( '/href=["\']https?:\/\/([^"\']+)["\']/', $meta_expression, $url_matches );
|
383 |
-
if ( count( $url_matches )
|
384 |
$link_url = $url_matches[1];
|
385 |
}
|
386 |
}
|
@@ -394,12 +409,12 @@ final class WSAL_Alert {
|
|
394 |
}
|
395 |
|
396 |
if ( ! empty( $link_url ) ) {
|
397 |
-
$result[ $link_label ] =
|
398 |
'url' => $link_url,
|
399 |
'needs_formatting' => $needs_formatting,
|
400 |
'title' => $link_title,
|
401 |
-
'label' => $link_label
|
402 |
-
|
403 |
}
|
404 |
}
|
405 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WSAL_Alert class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
*/
|
7 |
+
|
8 |
+
// Exit if accessed directly.
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
|
13 |
/**
|
14 |
* WSAL_Alert Object class.
|
79 |
* @var array
|
80 |
* @since 4.2.1
|
81 |
*/
|
82 |
+
public $metadata = array();
|
83 |
|
84 |
/**
|
85 |
* List of metadata items containing metadata key and a label to be displayed.
|
87 |
* @var string[]
|
88 |
* @since 4.2.1
|
89 |
*/
|
90 |
+
public $links = array();
|
91 |
|
92 |
/**
|
93 |
* Constructor.
|
94 |
*
|
95 |
* @param integer $type - Type of alert.
|
96 |
* @param integer $code - Code of alert.
|
97 |
+
* @param string $catg - Category of alert.
|
98 |
+
* @param string $subcatg - Subcategory of alert.
|
99 |
+
* @param string $desc - Description.
|
100 |
+
* @param string $mesg - Alert message.
|
101 |
+
* @param array $metadata - List of metadata items containing metadata key and a label to be displayed.
|
102 |
+
* @param string $links - This should be a list of links in form of dynamic placeholders or a metadata names.
|
103 |
+
* @param string $object - Event object.
|
104 |
+
* @param string $event_type - Event type.
|
105 |
*/
|
106 |
+
public function __construct( $type = 0, $code = 0, $catg = '', $subcatg = '', $desc = '', $mesg = '', $metadata = array(), $links = '', $object = '', $event_type = '' ) {
|
107 |
$this->code = $type;
|
108 |
$this->severity = $code;
|
109 |
$this->catg = $catg;
|
121 |
*
|
122 |
* Note: not to be used to display any messages. Use WSAL_Models_Occurrence::GetMessage() instead.
|
123 |
*
|
124 |
+
* @param array $meta_data - (Optional) Meta data relevant to message.
|
125 |
+
* @param string|null $message - (Optional) Override message template to use.
|
126 |
+
* @param integer $occurrence_id - (Optional) Event occurrence ID.
|
127 |
* @param string|false $context - Context in which the message will be used/displayed.
|
128 |
*
|
129 |
* @return string Fully formatted message.
|
130 |
+
*
|
131 |
+
* @see WSAL_Models_Occurrence::get_message()
|
132 |
*/
|
133 |
+
public function get_message( $meta_data = array(), $message = null, $occurrence_id = 0, $context = false ) {
|
134 |
+
return $this->get_formatted_message( is_null( $message ) ? $this->mesg : $message, $meta_data, $occurrence_id, $context );
|
135 |
}
|
136 |
|
137 |
/**
|
138 |
* Expands a message with variables by replacing variables with meta data values.
|
139 |
*
|
140 |
+
* @param string $original_message - The original message.
|
141 |
+
* @param array $meta_data - (Optional) Meta data relevant to message.
|
142 |
+
* @param integer $occurrence_id - (Optional) Event occurrence ID.
|
143 |
* @param string|false $context - Context in which the message will be used/displayed.
|
144 |
*
|
145 |
* @return string The expanded message.
|
|
|
146 |
*/
|
147 |
+
protected function get_formatted_message( $original_message, $meta_data = array(), $occurrence_id = 0, $context = false ) {
|
148 |
|
149 |
$result = '';
|
150 |
|
151 |
+
// Fallback on the default context.
|
152 |
if ( false === $context ) {
|
153 |
$context = 'default';
|
154 |
}
|
155 |
|
156 |
+
// Get the alert formatter for given context.
|
157 |
+
$formatter = WSAL_AlertFormatterFactory::get_formatter( $context );
|
158 |
|
159 |
// Tokenize message with regex.
|
160 |
$message_parts = preg_split( '/(%.*?%)/', (string) $original_message, - 1, PREG_SPLIT_DELIM_CAPTURE );
|
161 |
if ( ! is_array( $message_parts ) ) {
|
162 |
+
// Use the message as is.
|
163 |
$result = (string) $original_message;
|
164 |
} else {
|
165 |
// Handle tokenized message.
|
169 |
continue;
|
170 |
}
|
171 |
// Handle escaped percent sign.
|
172 |
+
if ( '%%' === $token ) {
|
173 |
$message_parts[ $i ] = '%';
|
174 |
+
} elseif ( substr( $token, 0, 1 ) === '%' && substr( $token, - 1, 1 ) === '%' ) {
|
175 |
// Handle complex expressions.
|
176 |
+
$message_parts[ $i ] = $this->get_meta_expression_value( substr( $token, 1, - 1 ), $meta_data );
|
177 |
$message_parts[ $i ] = $formatter->format_meta_expression( $token, $message_parts[ $i ], $occurrence_id );
|
178 |
if ( ! empty( $message_parts[ $i ] ) ) {
|
179 |
$message_parts[ $i ] = $formatter->wrap_in_hightlight_markup( $message_parts[ $i ] );
|
181 |
}
|
182 |
}
|
183 |
|
184 |
+
// Compact message.
|
185 |
$result = implode( '', $message_parts );
|
186 |
}
|
187 |
}
|
188 |
|
189 |
+
// Process message to make sure it any HTML tags are handled correctly.
|
190 |
$result = $formatter->process_html_tags_in_message( $result );
|
191 |
|
192 |
$end_of_line = $formatter->get_end_of_line();
|
223 |
*
|
224 |
* @return mixed The value nearest to the expression.
|
225 |
*/
|
226 |
+
protected function get_meta_expression_value( $expr, $meta_data = array() ) {
|
227 |
$expr = preg_replace( '/%/', '', $expr );
|
228 |
if ( 'IPAddress' === $expr ) {
|
229 |
if ( array_key_exists( 'IPAddress', $meta_data ) ) {
|
244 |
$meta = is_array( $meta ) && array_key_exists( $part, $meta ) ? $meta[ $part ] : ( isset( $meta->$part ) ? $meta->$part : 'NULL' );
|
245 |
}
|
246 |
|
247 |
+
return is_scalar( $meta ) ? (string) $meta : var_export( $meta, true ); // phpcs:ignore
|
248 |
}
|
249 |
|
250 |
/**
|
255 |
* @param int $occurrence_id Occurrence ID.
|
256 |
*
|
257 |
* @return string
|
|
|
258 |
* @since 4.2.1
|
259 |
*/
|
260 |
public function get_formatted_metadata( $formatter, $meta_data, $occurrence_id ) {
|
284 |
* @param int $occurrence_id Occurrence ID.
|
285 |
*
|
286 |
* @return array
|
|
|
287 |
* @since 4.2.1
|
288 |
*/
|
289 |
public function get_metadata_as_array( $formatter, $meta_data, $occurrence_id ) {
|
295 |
}
|
296 |
|
297 |
// Pure alert meta lookup based on meta token.
|
298 |
+
$meta_expression = $this->get_meta_expression_value( $meta_token, $meta_data );
|
299 |
|
300 |
// Additional alert meta processing - handles derived or decorated alert data.
|
301 |
$meta_expression = $formatter->format_meta_expression( $meta_token, $meta_expression, $occurrence_id );
|
310 |
}
|
311 |
|
312 |
/**
|
313 |
+
* Get formatter hyperlinks.
|
314 |
+
*
|
315 |
+
* @param WSAL_AlertFormatter $formatter Alert formatter.
|
316 |
+
* @param array $meta_data Meta data.
|
317 |
+
* @param int $occurrence_id Occurrence ID.
|
318 |
*
|
319 |
* @return string
|
|
|
320 |
* @since 4.2.1
|
321 |
*/
|
322 |
public function get_formatted_hyperlinks( $formatter, $meta_data, $occurrence_id ) {
|
323 |
$result = '';
|
324 |
$hyperlinks_as_array = $this->get_hyperlinks_as_array( $formatter, $meta_data, $occurrence_id );
|
325 |
if ( ! empty( $hyperlinks_as_array ) ) {
|
326 |
+
$links_result_parts = array();
|
327 |
foreach ( $hyperlinks_as_array as $link_data ) {
|
328 |
+
$link_label = $link_data['label'];
|
329 |
+
$link_url = $link_data['url'];
|
330 |
$needs_formatting = $link_data['needs_formatting'];
|
331 |
+
$formatted_link = $needs_formatting ? $formatter->format_link( $link_url, $link_label ) : $link_url;
|
332 |
array_push( $links_result_parts, $formatted_link );
|
333 |
}
|
334 |
|
341 |
}
|
342 |
|
343 |
/**
|
344 |
+
* Retrieves hyperlinks as an array.
|
345 |
+
*
|
346 |
+
* @param WSAL_AlertFormatter $formatter Alert formatter.
|
347 |
+
* @param array $meta_data Meta data.
|
348 |
+
* @param int $occurrence_id Occurrence ID.
|
349 |
+
* @param bool $exclude_links_not_needing_formatting If true, links that don't need formatting will
|
350 |
+
* be excluded. For example special links that
|
351 |
+
* contain onclick attribute already from the meta
|
352 |
+
* formatter.
|
353 |
*
|
354 |
* @return string
|
355 |
* @since 4.2.1
|
356 |
*/
|
357 |
public function get_hyperlinks_as_array( $formatter, $meta_data, $occurrence_id, $exclude_links_not_needing_formatting = false ) {
|
358 |
+
$result = array();
|
359 |
if ( ! empty( $this->links ) ) {
|
360 |
foreach ( $this->links as $link_label => $link_data ) {
|
361 |
|
373 |
$link_title = $link_data['label'];
|
374 |
}
|
375 |
|
376 |
+
/**
|
377 |
+
* Link url can be:
|
378 |
+
* - an actual URL
|
379 |
+
* - placeholder for an existing metadata field that contains a URL (or the full HTML A tag markup)
|
380 |
+
* -- before 4.2.1 the CommentLink meta would contain the full HTML markup for the link, now it contains only the URL
|
381 |
+
* - other placeholder for a dynamic or JS infused link that will be processed by the meta formatter.
|
382 |
+
*/
|
383 |
$needs_formatting = true;
|
384 |
if ( ! WSAL_Utilities_RequestUtils::is_valid_url( $link_url ) ) {
|
385 |
|
386 |
+
$meta_expression = $this->get_meta_expression_value( $link_url, $meta_data );
|
387 |
$meta_expression = $formatter->format_meta_expression( $link_url, $meta_expression, $occurrence_id, $meta_data );
|
388 |
if ( ! empty( $meta_expression ) ) {
|
389 |
if ( WSAL_Utilities_RequestUtils::is_valid_url( $meta_expression ) ) {
|
390 |
|
391 |
$link_url = $meta_expression;
|
392 |
+
} elseif ( preg_match( '/onclick=/', $meta_expression ) ) {
|
393 |
$link_url = $meta_expression;
|
394 |
$needs_formatting = false;
|
395 |
} else {
|
396 |
|
397 |
preg_match( '/href=["\']https?:\/\/([^"\']+)["\']/', $meta_expression, $url_matches );
|
398 |
+
if ( count( $url_matches ) === 2 ) {
|
399 |
$link_url = $url_matches[1];
|
400 |
}
|
401 |
}
|
409 |
}
|
410 |
|
411 |
if ( ! empty( $link_url ) ) {
|
412 |
+
$result[ $link_label ] = array(
|
413 |
'url' => $link_url,
|
414 |
'needs_formatting' => $needs_formatting,
|
415 |
'title' => $link_title,
|
416 |
+
'label' => $link_label,
|
417 |
+
);
|
418 |
}
|
419 |
}
|
420 |
}
|
classes/AlertFormatter.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* Class file for alert formatter.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -26,44 +26,70 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
26 |
final class WSAL_AlertFormatter {
|
27 |
|
28 |
/**
|
29 |
-
*
|
|
|
|
|
30 |
*/
|
31 |
protected $plugin;
|
32 |
|
33 |
-
/**
|
|
|
|
|
|
|
|
|
34 |
private $configuration;
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
public function __construct( $plugin, $configuration ) {
|
37 |
$this->plugin = $plugin;
|
38 |
$this->configuration = $configuration;
|
39 |
}
|
40 |
|
|
|
|
|
|
|
|
|
|
|
41 |
public function get_end_of_line() {
|
42 |
-
return $this->configuration->
|
43 |
}
|
44 |
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
-
*
|
51 |
-
*
|
|
|
|
|
52 |
* @param int|null $occurrence_id Occurrence ID. Only present if the event was already written to the database.
|
|
|
53 |
*
|
54 |
* @return false|mixed|string|void|WP_Error
|
55 |
-
* @throws Freemius_Exception
|
56 |
*
|
57 |
* @since 4.2.1
|
58 |
*/
|
59 |
-
public function format_meta_expression( $expression, $value, $occurrence_id = null, $metadata =
|
60 |
switch ( true ) {
|
61 |
-
case '%Message%'
|
62 |
return esc_html( $value );
|
63 |
|
64 |
-
case '%MetaLink%'
|
65 |
-
//
|
66 |
-
if ( $this->configuration->
|
67 |
$label = __( 'Exclude custom field from the monitoring', 'wp-security-audit-log' );
|
68 |
$result = "<a href=\"#\" data-object-type='{$metadata['Object']}' data-disable-custom-nonce='" . wp_create_nonce( 'disable-custom-nonce' . $value ) . "' onclick=\"return WsalDisableCustom(this, '" . $value . "');\"> {$label}</a>";
|
69 |
|
@@ -72,32 +98,36 @@ final class WSAL_AlertFormatter {
|
|
72 |
|
73 |
return '';
|
74 |
|
75 |
-
case in_array( $expression, array( '%path%', '%old_path%', '%FilePath%' ) ):
|
76 |
-
//
|
77 |
$max_length = 50;
|
78 |
-
if ( $this->configuration->
|
79 |
-
$result = '<span>'
|
80 |
-
$result .= "<a href=\"#\" data-shortened-text='{$value}'>" . $this->configuration->
|
81 |
|
82 |
return $result;
|
83 |
}
|
84 |
|
85 |
return $value;
|
86 |
|
87 |
-
case in_array( $expression, array( '%MetaValue%', '%MetaValueOld%', '%MetaValueNew%' ) ):
|
88 |
-
//
|
89 |
-
$result = mb_strlen( $value ) > $this->configuration->
|
90 |
|
91 |
return $this->wrap_in_hightlight_markup( esc_html( $result ) );
|
92 |
|
93 |
-
case '%ClientIP%'
|
94 |
-
case '%IPAddress%'
|
95 |
if ( is_string( $value ) ) {
|
96 |
-
$sanitized_ips = str_replace(
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
101 |
|
102 |
return $this->wrap_in_hightlight_markup( $sanitized_ips );
|
103 |
} else {
|
@@ -112,7 +142,7 @@ final class WSAL_AlertFormatter {
|
|
112 |
$post_id = $this->get_occurrence_meta_item( $occurrence_id, 'PostID' );
|
113 |
}
|
114 |
|
115 |
-
$occ_post = $post_id
|
116 |
if ( null !== $occ_post && 'publish' === $occ_post->post_status ) {
|
117 |
return get_permalink( $occ_post->ID );
|
118 |
}
|
@@ -121,7 +151,7 @@ final class WSAL_AlertFormatter {
|
|
121 |
|
122 |
case '%MenuUrl%' === $expression:
|
123 |
$menu_id = null;
|
124 |
-
if (
|
125 |
$menu_id = $metadata['MenuID'];
|
126 |
} else {
|
127 |
$menu_id = $this->get_occurrence_meta_item( $occurrence_id, 'MenuID' );
|
@@ -147,7 +177,7 @@ final class WSAL_AlertFormatter {
|
|
147 |
}
|
148 |
|
149 |
case '%LogFileText%' === $expression: // Failed login file text.
|
150 |
-
if ( $this->configuration->
|
151 |
$result = '<a href="javascript:;" onclick="download_failed_login_log( this )" data-download-nonce="' . esc_attr( wp_create_nonce( 'wsal-download-failed-logins' ) ) . '" title="' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '">' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '</a>';
|
152 |
|
153 |
return $this->wrap_in_hightlight_markup( $result );
|
@@ -161,7 +191,7 @@ final class WSAL_AlertFormatter {
|
|
161 |
return $this->wrap_in_hightlight_markup( esc_html( $result ) );
|
162 |
|
163 |
case '%multisite_text%' === $expression:
|
164 |
-
if ( $this->plugin->
|
165 |
$site_info = get_blog_details( $value, true );
|
166 |
if ( $site_info ) {
|
167 |
$site_url = $site_info->siteurl;
|
@@ -182,7 +212,7 @@ final class WSAL_AlertFormatter {
|
|
182 |
return $this->wrap_in_hightlight_markup( esc_html( $value ) );
|
183 |
|
184 |
case '%LineBreak%' === $expression:
|
185 |
-
return $this->configuration->
|
186 |
|
187 |
case '%PluginFile%' === $expression:
|
188 |
return $this->wrap_in_hightlight_markup( dirname( $value ) );
|
@@ -195,12 +225,16 @@ final class WSAL_AlertFormatter {
|
|
195 |
* @param string $value Meta value.
|
196 |
*
|
197 |
* @deprecated 4.3.0 Use 'wsal_format_custom_meta' instead.
|
198 |
-
*
|
199 |
*/
|
200 |
-
$result = apply_filters_deprecated(
|
201 |
-
|
202 |
-
|
203 |
-
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
/**
|
206 |
* Allows meta formatting via filter if no match was found. Runs after the legacy filter 'wsal_meta_formatter_custom_formatter' that is kept for backwards compatibility.
|
@@ -211,7 +245,6 @@ final class WSAL_AlertFormatter {
|
|
211 |
* @param int|null $occurrence_id Occurrence ID. Only present if the event was already written to the database. Default null.
|
212 |
*
|
213 |
* @since 4.3.0
|
214 |
-
*
|
215 |
*/
|
216 |
return apply_filters( 'wsal_format_custom_meta', $result, $expression, $this, $occurrence_id );
|
217 |
}
|
@@ -222,12 +255,12 @@ final class WSAL_AlertFormatter {
|
|
222 |
*
|
223 |
* For example meta values displayed as <strong>{meta value}</strong> in the WP admin UI.
|
224 |
*
|
225 |
-
* @param string $value
|
226 |
*
|
227 |
* @return string
|
228 |
*/
|
229 |
public function wrap_in_hightlight_markup( $value ) {
|
230 |
-
return $this->configuration->
|
231 |
}
|
232 |
|
233 |
/**
|
@@ -235,32 +268,32 @@ final class WSAL_AlertFormatter {
|
|
235 |
*
|
236 |
* For example an unknown IP address is displayed as <i>unknown</i> in the WP admin UI.
|
237 |
*
|
238 |
-
* @param string $value
|
239 |
*
|
240 |
* @return string
|
241 |
*/
|
242 |
public function wrap_in_emphasis_markup( $value ) {
|
243 |
-
return $this->configuration->
|
244 |
}
|
245 |
|
246 |
/**
|
247 |
* Helper function to get meta value from an occurrence.
|
248 |
*
|
249 |
-
* @param int
|
250 |
-
* @param string $meta_key
|
251 |
*
|
252 |
* @return mixed|null Meta value if exists. Otherwise null
|
253 |
* @since 4.2.1
|
254 |
*/
|
255 |
private function get_occurrence_meta_item( $occurrence_id, $meta_key ) {
|
256 |
// get connection.
|
257 |
-
$db_config = WSAL_Connector_ConnectorFactory::
|
258 |
-
$connector = $this->plugin->
|
259 |
-
$wsal_db = $connector->
|
260 |
|
261 |
// get values needed.
|
262 |
$meta_adapter = new WSAL_Adapters_MySQL_Meta( $wsal_db );
|
263 |
-
$meta_result = $meta_adapter->
|
264 |
|
265 |
return isset( $meta_result['value'] ) ? $meta_result['value'] : null;
|
266 |
}
|
@@ -273,17 +306,16 @@ final class WSAL_AlertFormatter {
|
|
273 |
* - check if the link is disabled
|
274 |
* - optional URL processing
|
275 |
*
|
276 |
-
* @param string $url
|
277 |
-
* @param string $label
|
278 |
-
* @param string $title
|
279 |
-
* @param string $target
|
280 |
*
|
281 |
* @return string
|
282 |
* @see process_url())
|
283 |
-
*
|
284 |
*/
|
285 |
-
public
|
286 |
-
//
|
287 |
if ( null === $url || empty( $url ) ) {
|
288 |
return '';
|
289 |
}
|
@@ -301,7 +333,7 @@ final class WSAL_AlertFormatter {
|
|
301 |
*
|
302 |
* Default implementation returns URL as is.
|
303 |
*
|
304 |
-
* @param string $url
|
305 |
*
|
306 |
* @return string
|
307 |
*/
|
@@ -316,16 +348,16 @@ final class WSAL_AlertFormatter {
|
|
316 |
* we moved to a different implementation. Introducing another link markup would require adding link format with
|
317 |
* placeholders to the formatter configuration.
|
318 |
*
|
319 |
-
* @param string $url
|
320 |
-
* @param string $label
|
321 |
-
* @param string $title
|
322 |
-
* @param string $target
|
323 |
*
|
324 |
* @return string
|
325 |
*/
|
326 |
protected function build_link_markup( $url, $label, $title = '', $target = '_blank' ) {
|
327 |
$title = empty( $title ) ? $label : $title;
|
328 |
-
if ( $this->configuration->
|
329 |
return '<a href="' . esc_url( $url ) . '" title="' . $title . '" target="' . $target . '">' . $label . '</a>';
|
330 |
}
|
331 |
|
@@ -333,17 +365,21 @@ final class WSAL_AlertFormatter {
|
|
333 |
}
|
334 |
|
335 |
/**
|
336 |
-
*
|
|
|
|
|
337 |
*/
|
338 |
public function supports_hyperlinks() {
|
339 |
-
return $this->configuration->
|
340 |
}
|
341 |
|
342 |
/**
|
343 |
-
*
|
|
|
|
|
344 |
*/
|
345 |
public function supports_metadata() {
|
346 |
-
return $this->configuration->
|
347 |
}
|
348 |
|
349 |
/**
|
@@ -353,17 +389,17 @@ final class WSAL_AlertFormatter {
|
|
353 |
*
|
354 |
* It also strips any additional HTML tags apart from hyperlink and an end of line to support legacy messages.
|
355 |
*
|
356 |
-
* @param string $message
|
357 |
*
|
358 |
* @return string
|
359 |
*/
|
360 |
public function process_html_tags_in_message( $message ) {
|
361 |
$result = preg_replace(
|
362 |
-
|
363 |
-
|
364 |
$message
|
365 |
);
|
366 |
|
367 |
-
return strip_tags( $result, $this->configuration->
|
368 |
}
|
369 |
}
|
4 |
*
|
5 |
* Class file for alert formatter.
|
6 |
*
|
7 |
+
* @since 4.2.1
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
26 |
final class WSAL_AlertFormatter {
|
27 |
|
28 |
/**
|
29 |
+
* Plugin instance.
|
30 |
+
*
|
31 |
+
* @var WpSecurityAuditLog
|
32 |
*/
|
33 |
protected $plugin;
|
34 |
|
35 |
+
/**
|
36 |
+
* Alert formatter configuration.
|
37 |
+
*
|
38 |
+
* @var WSAL_AlertFormatterConfiguration
|
39 |
+
*/
|
40 |
private $configuration;
|
41 |
|
42 |
+
/**
|
43 |
+
* Constructor.
|
44 |
+
*
|
45 |
+
* @param WpSecurityAuditLog $plugin Plugin instance.
|
46 |
+
* @param WSAL_AlertFormatterConfiguration $configuration Alert formatter configuration.
|
47 |
+
*/
|
48 |
public function __construct( $plugin, $configuration ) {
|
49 |
$this->plugin = $plugin;
|
50 |
$this->configuration = $configuration;
|
51 |
}
|
52 |
|
53 |
+
/**
|
54 |
+
* Gets the end of line character sequence.
|
55 |
+
*
|
56 |
+
* @return string End of line character sequence.
|
57 |
+
*/
|
58 |
public function get_end_of_line() {
|
59 |
+
return $this->configuration->get_end_of_line();
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* Updates the end of line character sequence.
|
64 |
+
*
|
65 |
+
* @param string $value End of line character sequence.
|
66 |
+
*
|
67 |
+
* @return WSAL_AlertFormatterConfiguration
|
68 |
+
*/
|
69 |
+
public function set_end_of_line( $value ) {
|
70 |
+
return $this->configuration->set_end_of_line( $value );
|
71 |
}
|
72 |
|
73 |
/**
|
74 |
+
* Formats given meta expression.
|
75 |
+
*
|
76 |
+
* @param string $expression Meta expression including the surrounding percentage chars.
|
77 |
+
* @param string $value Meta value.
|
78 |
* @param int|null $occurrence_id Occurrence ID. Only present if the event was already written to the database.
|
79 |
+
* @param array $metadata Meta data.
|
80 |
*
|
81 |
* @return false|mixed|string|void|WP_Error
|
|
|
82 |
*
|
83 |
* @since 4.2.1
|
84 |
*/
|
85 |
+
public function format_meta_expression( $expression, $value, $occurrence_id = null, $metadata = array() ) {
|
86 |
switch ( true ) {
|
87 |
+
case '%Message%' === $expression:
|
88 |
return esc_html( $value );
|
89 |
|
90 |
+
case '%MetaLink%' === $expression:
|
91 |
+
// NULL value check is here because events related to user meta fields didn't have the MetaLink meta prior to version 4.3.2.
|
92 |
+
if ( $this->configuration->is_js_in_links_allowed() && 'NULL' !== $value ) {
|
93 |
$label = __( 'Exclude custom field from the monitoring', 'wp-security-audit-log' );
|
94 |
$result = "<a href=\"#\" data-object-type='{$metadata['Object']}' data-disable-custom-nonce='" . wp_create_nonce( 'disable-custom-nonce' . $value ) . "' onclick=\"return WsalDisableCustom(this, '" . $value . "');\"> {$label}</a>";
|
95 |
|
98 |
|
99 |
return '';
|
100 |
|
101 |
+
case in_array( $expression, array( '%path%', '%old_path%', '%FilePath%' ), true ):
|
102 |
+
// Concatenate directory and file paths.
|
103 |
$max_length = 50;
|
104 |
+
if ( $this->configuration->is_js_in_links_allowed() && strlen( $value ) > $max_length ) {
|
105 |
+
$result = '<span>' . substr( $value, 0, $max_length ) . '</span>'; // phpcs:ignore
|
106 |
+
$result .= "<a href=\"#\" data-shortened-text='{$value}'>" . $this->configuration->get_ellipses_sequence() . "</a>"; // phpcs:ignore
|
107 |
|
108 |
return $result;
|
109 |
}
|
110 |
|
111 |
return $value;
|
112 |
|
113 |
+
case in_array( $expression, array( '%MetaValue%', '%MetaValueOld%', '%MetaValueNew%' ), true ):
|
114 |
+
// Trim the meta value to the maximum length and append configured ellipses sequence.
|
115 |
+
$result = mb_strlen( $value ) > $this->configuration->get_max_meta_value_length() ? ( mb_substr( $value, 0, 50 ) . $this->configuration->get_ellipses_sequence() ) : $value;
|
116 |
|
117 |
return $this->wrap_in_hightlight_markup( esc_html( $result ) );
|
118 |
|
119 |
+
case '%ClientIP%' === $expression:
|
120 |
+
case '%IPAddress%' === $expression:
|
121 |
if ( is_string( $value ) ) {
|
122 |
+
$sanitized_ips = str_replace(
|
123 |
+
array(
|
124 |
+
'"',
|
125 |
+
'[',
|
126 |
+
']',
|
127 |
+
),
|
128 |
+
'',
|
129 |
+
$value
|
130 |
+
);
|
131 |
|
132 |
return $this->wrap_in_hightlight_markup( $sanitized_ips );
|
133 |
} else {
|
142 |
$post_id = $this->get_occurrence_meta_item( $occurrence_id, 'PostID' );
|
143 |
}
|
144 |
|
145 |
+
$occ_post = ! is_null( $post_id ) ? get_post( $post_id ) : null;
|
146 |
if ( null !== $occ_post && 'publish' === $occ_post->post_status ) {
|
147 |
return get_permalink( $occ_post->ID );
|
148 |
}
|
151 |
|
152 |
case '%MenuUrl%' === $expression:
|
153 |
$menu_id = null;
|
154 |
+
if ( 0 === $occurrence_id && is_array( $metadata ) && array_key_exists( 'MenuID', $metadata ) ) {
|
155 |
$menu_id = $metadata['MenuID'];
|
156 |
} else {
|
157 |
$menu_id = $this->get_occurrence_meta_item( $occurrence_id, 'MenuID' );
|
177 |
}
|
178 |
|
179 |
case '%LogFileText%' === $expression: // Failed login file text.
|
180 |
+
if ( $this->configuration->is_js_in_links_allowed() ) {
|
181 |
$result = '<a href="javascript:;" onclick="download_failed_login_log( this )" data-download-nonce="' . esc_attr( wp_create_nonce( 'wsal-download-failed-logins' ) ) . '" title="' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '">' . esc_html__( 'Download the log file.', 'wp-security-audit-log' ) . '</a>';
|
182 |
|
183 |
return $this->wrap_in_hightlight_markup( $result );
|
191 |
return $this->wrap_in_hightlight_markup( esc_html( $result ) );
|
192 |
|
193 |
case '%multisite_text%' === $expression:
|
194 |
+
if ( $this->plugin->is_multisite() && $value ) {
|
195 |
$site_info = get_blog_details( $value, true );
|
196 |
if ( $site_info ) {
|
197 |
$site_url = $site_info->siteurl;
|
212 |
return $this->wrap_in_hightlight_markup( esc_html( $value ) );
|
213 |
|
214 |
case '%LineBreak%' === $expression:
|
215 |
+
return $this->configuration->get_end_of_line();
|
216 |
|
217 |
case '%PluginFile%' === $expression:
|
218 |
return $this->wrap_in_hightlight_markup( dirname( $value ) );
|
225 |
* @param string $value Meta value.
|
226 |
*
|
227 |
* @deprecated 4.3.0 Use 'wsal_format_custom_meta' instead.
|
|
|
228 |
*/
|
229 |
+
$result = apply_filters_deprecated(
|
230 |
+
'wsal_meta_formatter_custom_formatter',
|
231 |
+
array(
|
232 |
+
$value,
|
233 |
+
$expression,
|
234 |
+
),
|
235 |
+
'WSAL 4.3.0',
|
236 |
+
'wsal_format_custom_meta'
|
237 |
+
);
|
238 |
|
239 |
/**
|
240 |
* Allows meta formatting via filter if no match was found. Runs after the legacy filter 'wsal_meta_formatter_custom_formatter' that is kept for backwards compatibility.
|
245 |
* @param int|null $occurrence_id Occurrence ID. Only present if the event was already written to the database. Default null.
|
246 |
*
|
247 |
* @since 4.3.0
|
|
|
248 |
*/
|
249 |
return apply_filters( 'wsal_format_custom_meta', $result, $expression, $this, $occurrence_id );
|
250 |
}
|
255 |
*
|
256 |
* For example meta values displayed as <strong>{meta value}</strong> in the WP admin UI.
|
257 |
*
|
258 |
+
* @param string $value Value.
|
259 |
*
|
260 |
* @return string
|
261 |
*/
|
262 |
public function wrap_in_hightlight_markup( $value ) {
|
263 |
+
return $this->configuration->get_highlight_start_tag() . $value . $this->configuration->get_highlight_end_tag();
|
264 |
}
|
265 |
|
266 |
/**
|
268 |
*
|
269 |
* For example an unknown IP address is displayed as <i>unknown</i> in the WP admin UI.
|
270 |
*
|
271 |
+
* @param string $value Value.
|
272 |
*
|
273 |
* @return string
|
274 |
*/
|
275 |
public function wrap_in_emphasis_markup( $value ) {
|
276 |
+
return $this->configuration->get_emphasis_start_tag() . $value . $this->configuration->get_emphasis_end_tag();
|
277 |
}
|
278 |
|
279 |
/**
|
280 |
* Helper function to get meta value from an occurrence.
|
281 |
*
|
282 |
+
* @param int $occurrence_id Occurrence ID.
|
283 |
+
* @param string $meta_key Meta key.
|
284 |
*
|
285 |
* @return mixed|null Meta value if exists. Otherwise null
|
286 |
* @since 4.2.1
|
287 |
*/
|
288 |
private function get_occurrence_meta_item( $occurrence_id, $meta_key ) {
|
289 |
// get connection.
|
290 |
+
$db_config = WSAL_Connector_ConnectorFactory::get_config(); // Get DB connector configuration.
|
291 |
+
$connector = $this->plugin->get_connector( $db_config ); // Get connector for DB.
|
292 |
+
$wsal_db = $connector->get_connection(); // Get DB connection.
|
293 |
|
294 |
// get values needed.
|
295 |
$meta_adapter = new WSAL_Adapters_MySQL_Meta( $wsal_db );
|
296 |
+
$meta_result = $meta_adapter->load_by_name_and_occurrence_id( $meta_key, $occurrence_id );
|
297 |
|
298 |
return isset( $meta_result['value'] ) ? $meta_result['value'] : null;
|
299 |
}
|
306 |
* - check if the link is disabled
|
307 |
* - optional URL processing
|
308 |
*
|
309 |
+
* @param string $url URL.
|
310 |
+
* @param string $label Label.
|
311 |
+
* @param string $title Title.
|
312 |
+
* @param string $target Target attribute.
|
313 |
*
|
314 |
* @return string
|
315 |
* @see process_url())
|
|
|
316 |
*/
|
317 |
+
public function format_link( $url, $label, $title = '', $target = '_blank' ) {
|
318 |
+
// Check for empty values.
|
319 |
if ( null === $url || empty( $url ) ) {
|
320 |
return '';
|
321 |
}
|
333 |
*
|
334 |
* Default implementation returns URL as is.
|
335 |
*
|
336 |
+
* @param string $url URL.
|
337 |
*
|
338 |
* @return string
|
339 |
*/
|
348 |
* we moved to a different implementation. Introducing another link markup would require adding link format with
|
349 |
* placeholders to the formatter configuration.
|
350 |
*
|
351 |
+
* @param string $url URL.
|
352 |
+
* @param string $label Label.
|
353 |
+
* @param string $title Title.
|
354 |
+
* @param string $target Target attribute.
|
355 |
*
|
356 |
* @return string
|
357 |
*/
|
358 |
protected function build_link_markup( $url, $label, $title = '', $target = '_blank' ) {
|
359 |
$title = empty( $title ) ? $label : $title;
|
360 |
+
if ( $this->configuration->can_use_html_markup_for_links() ) {
|
361 |
return '<a href="' . esc_url( $url ) . '" title="' . $title . '" target="' . $target . '">' . $label . '</a>';
|
362 |
}
|
363 |
|
365 |
}
|
366 |
|
367 |
/**
|
368 |
+
* Checks if formatter supports hyperlinks.
|
369 |
+
*
|
370 |
+
* @return bool True if formatter supports hyperlinks.
|
371 |
*/
|
372 |
public function supports_hyperlinks() {
|
373 |
+
return $this->configuration->is_supports_hyperlinks();
|
374 |
}
|
375 |
|
376 |
/**
|
377 |
+
* Checks if the formatter supports metadata.
|
378 |
+
*
|
379 |
+
* @return bool True if formatter supports metadata.
|
380 |
*/
|
381 |
public function supports_metadata() {
|
382 |
+
return $this->configuration->is_supports_metadata();
|
383 |
}
|
384 |
|
385 |
/**
|
389 |
*
|
390 |
* It also strips any additional HTML tags apart from hyperlink and an end of line to support legacy messages.
|
391 |
*
|
392 |
+
* @param string $message Message text.
|
393 |
*
|
394 |
* @return string
|
395 |
*/
|
396 |
public function process_html_tags_in_message( $message ) {
|
397 |
$result = preg_replace(
|
398 |
+
array( '/<strong>/', '/<\/strong>/' ),
|
399 |
+
array( $this->configuration->get_highlight_start_tag(), $this->configuration->get_highlight_end_tag() ),
|
400 |
$message
|
401 |
);
|
402 |
|
403 |
+
return strip_tags( $result, $this->configuration->get_tags_allowed_in_message() );
|
404 |
}
|
405 |
}
|
classes/AlertFormatterConfiguration.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
// Exit if accessed directly.
|
4 |
if ( ! defined( 'ABSPATH' ) ) {
|
@@ -15,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
15 |
* All setter methods are fluent to allow for method chaining.
|
16 |
*
|
17 |
* @package wsal
|
18 |
-
* @since
|
19 |
*/
|
20 |
class WSAL_AlertFormatterConfiguration {
|
21 |
|
@@ -27,56 +33,78 @@ class WSAL_AlertFormatterConfiguration {
|
|
27 |
protected $tags_allowed_in_message = '';
|
28 |
|
29 |
/**
|
|
|
|
|
30 |
* @var bool
|
31 |
*/
|
32 |
protected $is_js_in_links_allowed = false;
|
33 |
|
34 |
/**
|
|
|
|
|
35 |
* @var string
|
36 |
*/
|
37 |
protected $highlight_end_tag = '';
|
38 |
|
39 |
/**
|
|
|
|
|
40 |
* @var bool
|
41 |
*/
|
42 |
protected $supports_hyperlinks = false;
|
43 |
|
44 |
/**
|
|
|
|
|
45 |
* @var bool
|
46 |
*/
|
47 |
protected $supports_metadata = false;
|
48 |
|
49 |
/**
|
|
|
|
|
50 |
* @var int
|
51 |
*/
|
52 |
protected $max_meta_value_length = 50;
|
53 |
|
54 |
/**
|
|
|
|
|
55 |
* @var string
|
56 |
*/
|
57 |
protected $emphasis_start_tag = '';
|
58 |
|
59 |
/**
|
|
|
|
|
60 |
* @var string
|
61 |
*/
|
62 |
protected $end_of_line = ' ';
|
63 |
|
64 |
/**
|
|
|
|
|
65 |
* @var string
|
66 |
*/
|
67 |
protected $highlight_start_tag = '';
|
68 |
|
69 |
/**
|
|
|
|
|
70 |
* @var string
|
71 |
*/
|
72 |
protected $emphasis_end_tag = '';
|
73 |
|
74 |
/**
|
|
|
|
|
75 |
* @var string
|
76 |
*/
|
77 |
protected $ellipses_sequence = '...';
|
78 |
|
79 |
/**
|
|
|
|
|
80 |
* @var bool
|
81 |
* @since 4.3.2
|
82 |
*/
|
@@ -96,9 +124,8 @@ class WSAL_AlertFormatterConfiguration {
|
|
96 |
*
|
97 |
* @return WSAL_AlertFormatterConfiguration
|
98 |
*/
|
99 |
-
public static function
|
100 |
return new WSAL_AlertFormatterConfiguration();
|
101 |
-
|
102 |
}
|
103 |
|
104 |
/**
|
@@ -106,234 +133,282 @@ class WSAL_AlertFormatterConfiguration {
|
|
106 |
*
|
107 |
* @return WSAL_AlertFormatterConfiguration
|
108 |
*/
|
109 |
-
public static function
|
110 |
return ( new WSAL_AlertFormatterConfiguration() )
|
111 |
-
->
|
112 |
-
->
|
113 |
-
->
|
114 |
-
->
|
115 |
-
->
|
116 |
-
->
|
117 |
-
->
|
118 |
-
->
|
119 |
-
->
|
120 |
-
->
|
121 |
}
|
122 |
|
123 |
/**
|
124 |
-
*
|
|
|
|
|
125 |
*
|
126 |
* @return WSAL_AlertFormatterConfiguration
|
127 |
*/
|
128 |
-
public function
|
129 |
$this->is_js_in_links_allowed = $is_js_in_links_allowed;
|
130 |
|
131 |
return $this;
|
132 |
}
|
133 |
|
134 |
/**
|
135 |
-
*
|
|
|
|
|
136 |
* @since 4.3.2
|
137 |
*/
|
138 |
-
public function
|
139 |
return $this->use_html_markup_for_links;
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
-
*
|
|
|
|
|
144 |
*
|
145 |
* @return WSAL_AlertFormatterConfiguration
|
146 |
* @since 4.3.2
|
147 |
-
*
|
148 |
*/
|
149 |
-
public function
|
150 |
$this->use_html_markup_for_links = $use_html_markup_for_links;
|
151 |
|
152 |
return $this;
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
-
*
|
|
|
|
|
157 |
*/
|
158 |
-
public function
|
159 |
return $this->tags_allowed_in_message;
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
-
*
|
|
|
|
|
164 |
*
|
165 |
* @return WSAL_AlertFormatterConfiguration
|
166 |
*/
|
167 |
-
public function
|
168 |
$this->tags_allowed_in_message = $tags_allowed_in_message;
|
169 |
|
170 |
return $this;
|
171 |
}
|
172 |
|
173 |
/**
|
174 |
-
*
|
|
|
|
|
175 |
*/
|
176 |
-
public function
|
177 |
return $this->is_js_in_links_allowed;
|
178 |
}
|
179 |
|
180 |
/**
|
181 |
-
*
|
|
|
|
|
182 |
*/
|
183 |
-
public function
|
184 |
return $this->highlight_end_tag;
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
-
*
|
|
|
|
|
|
|
189 |
*
|
190 |
* @return WSAL_AlertFormatterConfiguration
|
191 |
*/
|
192 |
-
public function
|
193 |
$this->highlight_end_tag = $highlight_end_tag;
|
194 |
|
195 |
return $this;
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
-
*
|
|
|
|
|
200 |
*/
|
201 |
-
public function
|
202 |
return $this->supports_hyperlinks;
|
203 |
}
|
204 |
|
205 |
/**
|
206 |
-
*
|
|
|
|
|
207 |
*
|
208 |
* @return WSAL_AlertFormatterConfiguration
|
209 |
*/
|
210 |
-
public function
|
211 |
$this->supports_hyperlinks = $supports_hyperlinks;
|
212 |
|
213 |
return $this;
|
214 |
}
|
215 |
|
216 |
/**
|
217 |
-
*
|
|
|
|
|
218 |
*/
|
219 |
-
public function
|
220 |
return $this->supports_metadata;
|
221 |
}
|
222 |
|
223 |
/**
|
224 |
-
*
|
|
|
|
|
225 |
*
|
226 |
* @return WSAL_AlertFormatterConfiguration
|
227 |
*/
|
228 |
-
public function
|
229 |
$this->supports_metadata = $supports_metadata;
|
230 |
|
231 |
return $this;
|
232 |
}
|
233 |
|
234 |
/**
|
235 |
-
*
|
|
|
|
|
236 |
*/
|
237 |
-
public function
|
238 |
return $this->max_meta_value_length;
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
-
*
|
|
|
|
|
243 |
*
|
244 |
* @return WSAL_AlertFormatterConfiguration
|
245 |
*/
|
246 |
-
public function
|
247 |
$this->max_meta_value_length = $max_meta_value_length;
|
248 |
|
249 |
return $this;
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
-
*
|
|
|
|
|
254 |
*/
|
255 |
-
public function
|
256 |
return $this->emphasis_start_tag;
|
257 |
}
|
258 |
|
259 |
/**
|
260 |
-
*
|
|
|
|
|
261 |
*
|
262 |
* @return WSAL_AlertFormatterConfiguration
|
263 |
*/
|
264 |
-
public function
|
265 |
$this->emphasis_start_tag = $emphasis_start_tag;
|
266 |
|
267 |
return $this;
|
268 |
}
|
269 |
|
270 |
/**
|
271 |
-
*
|
|
|
|
|
272 |
*/
|
273 |
-
public function
|
274 |
return $this->end_of_line;
|
275 |
}
|
276 |
|
277 |
/**
|
278 |
-
*
|
|
|
|
|
279 |
*
|
280 |
* @return WSAL_AlertFormatterConfiguration
|
281 |
*/
|
282 |
-
public function
|
283 |
$this->end_of_line = $end_of_line;
|
284 |
|
285 |
return $this;
|
286 |
}
|
287 |
|
288 |
/**
|
289 |
-
*
|
|
|
|
|
290 |
*/
|
291 |
-
public function
|
292 |
return $this->highlight_start_tag;
|
293 |
}
|
294 |
|
295 |
/**
|
296 |
-
*
|
|
|
|
|
297 |
*
|
298 |
* @return WSAL_AlertFormatterConfiguration
|
299 |
*/
|
300 |
-
public function
|
301 |
$this->highlight_start_tag = $highlight_start_tag;
|
302 |
|
303 |
return $this;
|
304 |
}
|
305 |
|
306 |
/**
|
307 |
-
*
|
|
|
|
|
308 |
*/
|
309 |
-
public function
|
310 |
return $this->emphasis_end_tag;
|
311 |
}
|
312 |
|
313 |
/**
|
314 |
-
*
|
|
|
|
|
315 |
*
|
316 |
* @return WSAL_AlertFormatterConfiguration
|
317 |
*/
|
318 |
-
public function
|
319 |
$this->emphasis_end_tag = $emphasis_end_tag;
|
320 |
|
321 |
return $this;
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
-
*
|
|
|
|
|
326 |
*/
|
327 |
-
public function
|
328 |
return $this->ellipses_sequence;
|
329 |
}
|
330 |
|
331 |
/**
|
332 |
-
*
|
|
|
|
|
333 |
*
|
334 |
* @return WSAL_AlertFormatterConfiguration
|
335 |
*/
|
336 |
-
public function
|
337 |
$this->ellipses_sequence = $ellipses_sequence;
|
338 |
|
339 |
return $this;
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Alert formatter configuration class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @since 4.3.0
|
7 |
+
*/
|
8 |
|
9 |
// Exit if accessed directly.
|
10 |
if ( ! defined( 'ABSPATH' ) ) {
|
21 |
* All setter methods are fluent to allow for method chaining.
|
22 |
*
|
23 |
* @package wsal
|
24 |
+
* @since 4.3.0
|
25 |
*/
|
26 |
class WSAL_AlertFormatterConfiguration {
|
27 |
|
33 |
protected $tags_allowed_in_message = '';
|
34 |
|
35 |
/**
|
36 |
+
* True if JS is allowed in the links.
|
37 |
+
*
|
38 |
* @var bool
|
39 |
*/
|
40 |
protected $is_js_in_links_allowed = false;
|
41 |
|
42 |
/**
|
43 |
+
* Ending tag of highlighted section.
|
44 |
+
*
|
45 |
* @var string
|
46 |
*/
|
47 |
protected $highlight_end_tag = '';
|
48 |
|
49 |
/**
|
50 |
+
* True if formatter supports hyperlinks.
|
51 |
+
*
|
52 |
* @var bool
|
53 |
*/
|
54 |
protected $supports_hyperlinks = false;
|
55 |
|
56 |
/**
|
57 |
+
* True if formatter supports metadata.
|
58 |
+
*
|
59 |
* @var bool
|
60 |
*/
|
61 |
protected $supports_metadata = false;
|
62 |
|
63 |
/**
|
64 |
+
* Maximum length of metadata value to display.
|
65 |
+
*
|
66 |
* @var int
|
67 |
*/
|
68 |
protected $max_meta_value_length = 50;
|
69 |
|
70 |
/**
|
71 |
+
* Starting tag of emphasised section.
|
72 |
+
*
|
73 |
* @var string
|
74 |
*/
|
75 |
protected $emphasis_start_tag = '';
|
76 |
|
77 |
/**
|
78 |
+
* End of line character sequence.
|
79 |
+
*
|
80 |
* @var string
|
81 |
*/
|
82 |
protected $end_of_line = ' ';
|
83 |
|
84 |
/**
|
85 |
+
* Starting tag of highlighted section.
|
86 |
+
*
|
87 |
* @var string
|
88 |
*/
|
89 |
protected $highlight_start_tag = '';
|
90 |
|
91 |
/**
|
92 |
+
* Ending tag of emphasised section.
|
93 |
+
*
|
94 |
* @var string
|
95 |
*/
|
96 |
protected $emphasis_end_tag = '';
|
97 |
|
98 |
/**
|
99 |
+
* Ellipses character sequence.
|
100 |
+
*
|
101 |
* @var string
|
102 |
*/
|
103 |
protected $ellipses_sequence = '...';
|
104 |
|
105 |
/**
|
106 |
+
* True if formatter uses HTML markup for links.
|
107 |
+
*
|
108 |
* @var bool
|
109 |
* @since 4.3.2
|
110 |
*/
|
124 |
*
|
125 |
* @return WSAL_AlertFormatterConfiguration
|
126 |
*/
|
127 |
+
public static function build_plain_text_configuration() {
|
128 |
return new WSAL_AlertFormatterConfiguration();
|
|
|
129 |
}
|
130 |
|
131 |
/**
|
133 |
*
|
134 |
* @return WSAL_AlertFormatterConfiguration
|
135 |
*/
|
136 |
+
public static function build_html_configuration() {
|
137 |
return ( new WSAL_AlertFormatterConfiguration() )
|
138 |
+
->set_tags_allowed_in_message( '<strong><br><a>' )
|
139 |
+
->set_is_js_in_links_allowed( true )
|
140 |
+
->set_supports_metadata( true )
|
141 |
+
->set_supports_hyperlinks( true )
|
142 |
+
->set_emphasis_start_tag( '<i>' )
|
143 |
+
->set_emphasis_end_tag( '</i>' )
|
144 |
+
->set_highlight_start_tag( '<strong>' )
|
145 |
+
->set_highlight_end_tag( '</strong>' )
|
146 |
+
->set_end_of_line( '<br />' )
|
147 |
+
->set_ellipses_sequence( '…' );
|
148 |
}
|
149 |
|
150 |
/**
|
151 |
+
* Sets the JS allowed in links settings.
|
152 |
+
*
|
153 |
+
* @param bool $is_js_in_links_allowed True if JS is supposed to allowed in the links.
|
154 |
*
|
155 |
* @return WSAL_AlertFormatterConfiguration
|
156 |
*/
|
157 |
+
public function set_is_js_in_links_allowed( $is_js_in_links_allowed ) {
|
158 |
$this->is_js_in_links_allowed = $is_js_in_links_allowed;
|
159 |
|
160 |
return $this;
|
161 |
}
|
162 |
|
163 |
/**
|
164 |
+
* Checks if HTML markup can be used for links.
|
165 |
+
*
|
166 |
+
* @return bool True if HTML markup can be used for links.
|
167 |
* @since 4.3.2
|
168 |
*/
|
169 |
+
public function can_use_html_markup_for_links(): bool {
|
170 |
return $this->use_html_markup_for_links;
|
171 |
}
|
172 |
|
173 |
/**
|
174 |
+
* Sets the "HTML markup can be used for links" option.
|
175 |
+
*
|
176 |
+
* @param bool $use_html_markup_for_links If true, HTML markup can be used for links.
|
177 |
*
|
178 |
* @return WSAL_AlertFormatterConfiguration
|
179 |
* @since 4.3.2
|
|
|
180 |
*/
|
181 |
+
public function set_use_html_markup_for_links( bool $use_html_markup_for_links ) {
|
182 |
$this->use_html_markup_for_links = $use_html_markup_for_links;
|
183 |
|
184 |
return $this;
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
+
* Returns a list of tags that are allowed in the message in format digestible by function strip_tags.
|
189 |
+
*
|
190 |
+
* @return string List of tags that are allowed in the message.
|
191 |
*/
|
192 |
+
public function get_tags_allowed_in_message() {
|
193 |
return $this->tags_allowed_in_message;
|
194 |
}
|
195 |
|
196 |
/**
|
197 |
+
* Sets the tags allowed in the message in format digestible by function strip_tags.
|
198 |
+
*
|
199 |
+
* @param string $tags_allowed_in_message List of tags that are allowed in the message.
|
200 |
*
|
201 |
* @return WSAL_AlertFormatterConfiguration
|
202 |
*/
|
203 |
+
public function set_tags_allowed_in_message( $tags_allowed_in_message ) {
|
204 |
$this->tags_allowed_in_message = $tags_allowed_in_message;
|
205 |
|
206 |
return $this;
|
207 |
}
|
208 |
|
209 |
/**
|
210 |
+
* Sets the "JS is allowed in the links" option.
|
211 |
+
*
|
212 |
+
* @return bool True if JS is supposed to be allowed in the links.
|
213 |
*/
|
214 |
+
public function is_js_in_links_allowed() {
|
215 |
return $this->is_js_in_links_allowed;
|
216 |
}
|
217 |
|
218 |
/**
|
219 |
+
* Gets the ending tag of highlighted section.
|
220 |
+
*
|
221 |
+
* @return string Ending tag of highlighted section.
|
222 |
*/
|
223 |
+
public function get_highlight_end_tag() {
|
224 |
return $this->highlight_end_tag;
|
225 |
}
|
226 |
|
227 |
/**
|
228 |
+
*
|
229 |
+
* Sets the ending tag of highlighted section.
|
230 |
+
*
|
231 |
+
* @param string $highlight_end_tag Ending tag of highlighted section.
|
232 |
*
|
233 |
* @return WSAL_AlertFormatterConfiguration
|
234 |
*/
|
235 |
+
public function set_highlight_end_tag( $highlight_end_tag ) {
|
236 |
$this->highlight_end_tag = $highlight_end_tag;
|
237 |
|
238 |
return $this;
|
239 |
}
|
240 |
|
241 |
/**
|
242 |
+
* Checks if formatter supports hyperlinks.
|
243 |
+
*
|
244 |
+
* @return bool True if formatter supports hyperlinks.
|
245 |
*/
|
246 |
+
public function is_supports_hyperlinks() {
|
247 |
return $this->supports_hyperlinks;
|
248 |
}
|
249 |
|
250 |
/**
|
251 |
+
* Sets the "formatter supports hyperlinks" setting.
|
252 |
+
*
|
253 |
+
* @param bool $supports_hyperlinks True if formatter should support hyperlinks.
|
254 |
*
|
255 |
* @return WSAL_AlertFormatterConfiguration
|
256 |
*/
|
257 |
+
public function set_supports_hyperlinks( $supports_hyperlinks ) {
|
258 |
$this->supports_hyperlinks = $supports_hyperlinks;
|
259 |
|
260 |
return $this;
|
261 |
}
|
262 |
|
263 |
/**
|
264 |
+
* Checks if the formatter supports metadata.
|
265 |
+
*
|
266 |
+
* @return bool True if formatter supports metadata.
|
267 |
*/
|
268 |
+
public function is_supports_metadata() {
|
269 |
return $this->supports_metadata;
|
270 |
}
|
271 |
|
272 |
/**
|
273 |
+
* Updates the "formatter supports metadata" setting.
|
274 |
+
*
|
275 |
+
* @param bool $supports_metadata True if formatter should support metadata.
|
276 |
*
|
277 |
* @return WSAL_AlertFormatterConfiguration
|
278 |
*/
|
279 |
+
public function set_supports_metadata( $supports_metadata ) {
|
280 |
$this->supports_metadata = $supports_metadata;
|
281 |
|
282 |
return $this;
|
283 |
}
|
284 |
|
285 |
/**
|
286 |
+
* Gets the maximum length of metadata value to display.
|
287 |
+
*
|
288 |
+
* @return int Maximum length of metadata value to display.
|
289 |
*/
|
290 |
+
public function get_max_meta_value_length() {
|
291 |
return $this->max_meta_value_length;
|
292 |
}
|
293 |
|
294 |
/**
|
295 |
+
* Sets the maximum length of metadata value to display.
|
296 |
+
*
|
297 |
+
* @param int $max_meta_value_length Maximum length of metadata value to display.
|
298 |
*
|
299 |
* @return WSAL_AlertFormatterConfiguration
|
300 |
*/
|
301 |
+
public function set_max_meta_value_length( $max_meta_value_length ) {
|
302 |
$this->max_meta_value_length = $max_meta_value_length;
|
303 |
|
304 |
return $this;
|
305 |
}
|
306 |
|
307 |
/**
|
308 |
+
* Gets the starting tag of emphasised section.
|
309 |
+
*
|
310 |
+
* @return string Starting tag of emphasised section.
|
311 |
*/
|
312 |
+
public function get_emphasis_start_tag() {
|
313 |
return $this->emphasis_start_tag;
|
314 |
}
|
315 |
|
316 |
/**
|
317 |
+
* Updates the starting tag of emphasised section.
|
318 |
+
*
|
319 |
+
* @param string $emphasis_start_tag Starting tag of emphasised section.
|
320 |
*
|
321 |
* @return WSAL_AlertFormatterConfiguration
|
322 |
*/
|
323 |
+
public function set_emphasis_start_tag( $emphasis_start_tag ) {
|
324 |
$this->emphasis_start_tag = $emphasis_start_tag;
|
325 |
|
326 |
return $this;
|
327 |
}
|
328 |
|
329 |
/**
|
330 |
+
* Gets the end of line character sequence.
|
331 |
+
*
|
332 |
+
* @return string End of line character sequence.
|
333 |
*/
|
334 |
+
public function get_end_of_line() {
|
335 |
return $this->end_of_line;
|
336 |
}
|
337 |
|
338 |
/**
|
339 |
+
* Updates the end of line character sequence.
|
340 |
+
*
|
341 |
+
* @param string $end_of_line End of line character sequence.
|
342 |
*
|
343 |
* @return WSAL_AlertFormatterConfiguration
|
344 |
*/
|
345 |
+
public function set_end_of_line( $end_of_line ) {
|
346 |
$this->end_of_line = $end_of_line;
|
347 |
|
348 |
return $this;
|
349 |
}
|
350 |
|
351 |
/**
|
352 |
+
* Gets the starting tag of highlighted section.
|
353 |
+
*
|
354 |
+
* @return string Starting tag of highlighted section.
|
355 |
*/
|
356 |
+
public function get_highlight_start_tag() {
|
357 |
return $this->highlight_start_tag;
|
358 |
}
|
359 |
|
360 |
/**
|
361 |
+
* Sets the starting tag of highlighted section.
|
362 |
+
*
|
363 |
+
* @param string $highlight_start_tag Starting tag of highlighted section.
|
364 |
*
|
365 |
* @return WSAL_AlertFormatterConfiguration
|
366 |
*/
|
367 |
+
public function set_highlight_start_tag( $highlight_start_tag ) {
|
368 |
$this->highlight_start_tag = $highlight_start_tag;
|
369 |
|
370 |
return $this;
|
371 |
}
|
372 |
|
373 |
/**
|
374 |
+
* Ending tag of emphasised section.
|
375 |
+
*
|
376 |
+
* @return string Ending tag of emphasised section.
|
377 |
*/
|
378 |
+
public function get_emphasis_end_tag() {
|
379 |
return $this->emphasis_end_tag;
|
380 |
}
|
381 |
|
382 |
/**
|
383 |
+
* Sets the ending tag of emphasised section.
|
384 |
+
*
|
385 |
+
* @param string $emphasis_end_tag Ending tag of emphasised section.
|
386 |
*
|
387 |
* @return WSAL_AlertFormatterConfiguration
|
388 |
*/
|
389 |
+
public function set_emphasis_end_tag( $emphasis_end_tag ) {
|
390 |
$this->emphasis_end_tag = $emphasis_end_tag;
|
391 |
|
392 |
return $this;
|
393 |
}
|
394 |
|
395 |
/**
|
396 |
+
* Gets the ellipses character sequence.
|
397 |
+
*
|
398 |
+
* @return string Ellipses character sequence.
|
399 |
*/
|
400 |
+
public function get_ellipses_sequence() {
|
401 |
return $this->ellipses_sequence;
|
402 |
}
|
403 |
|
404 |
/**
|
405 |
+
* Sets the ellipses character sequence.
|
406 |
+
*
|
407 |
+
* @param string $ellipses_sequence Ellipses character sequence.
|
408 |
*
|
409 |
* @return WSAL_AlertFormatterConfiguration
|
410 |
*/
|
411 |
+
public function set_ellipses_sequence( $ellipses_sequence ) {
|
412 |
$this->ellipses_sequence = $ellipses_sequence;
|
413 |
|
414 |
return $this;
|
classes/AlertFormatterFactory.php
CHANGED
@@ -23,28 +23,38 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
23 |
class WSAL_AlertFormatterFactory {
|
24 |
|
25 |
/**
|
|
|
|
|
26 |
* @var WSAL_AlertFormatter[]
|
27 |
*/
|
28 |
-
private static $formatter_instances =
|
29 |
|
30 |
/**
|
|
|
|
|
31 |
* @var WSAL_AlertFormatterConfiguration[]
|
32 |
*/
|
33 |
-
private static $configurations =
|
34 |
|
|
|
|
|
|
|
35 |
public static function bootstrap() {
|
36 |
|
37 |
-
$html_configuration = WSAL_AlertFormatterConfiguration::
|
38 |
$dashboard_widget_configuration = ( clone $html_configuration )
|
39 |
-
->
|
40 |
-
->
|
41 |
-
->
|
42 |
|
43 |
-
//
|
44 |
-
$formatters = apply_filters(
|
45 |
-
'
|
46 |
-
|
47 |
-
|
|
|
|
|
|
|
48 |
|
49 |
if ( ! empty( $formatters ) ) {
|
50 |
foreach ( $formatters as $context => $formatter_configuration ) {
|
@@ -54,37 +64,41 @@ class WSAL_AlertFormatterFactory {
|
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
-
*
|
|
|
|
|
58 |
*
|
59 |
* @return WSAL_AlertFormatter
|
60 |
*/
|
61 |
-
public static function
|
62 |
try {
|
63 |
-
//
|
64 |
-
//
|
65 |
if ( array_key_exists( $context, self::$formatter_instances ) ) {
|
66 |
return self::$formatter_instances[ $context ];
|
67 |
}
|
68 |
|
69 |
if ( array_key_exists( $context, self::$configurations ) ) {
|
70 |
-
$formatter = new WSAL_AlertFormatter( WpSecurityAuditLog::
|
71 |
|
72 |
self::$formatter_instances[ $context ] = $formatter;
|
73 |
|
74 |
return self::$formatter_instances[ $context ];
|
75 |
}
|
76 |
} catch ( Exception $exception ) {
|
77 |
-
return self::
|
78 |
}
|
79 |
|
80 |
-
return self::
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
-
*
|
|
|
|
|
85 |
* @since 4.3.0
|
86 |
*/
|
87 |
-
private static function
|
88 |
-
return new WSAL_AlertFormatter( WpSecurityAuditLog::
|
89 |
}
|
90 |
}
|
23 |
class WSAL_AlertFormatterFactory {
|
24 |
|
25 |
/**
|
26 |
+
* Alert formatter instances.
|
27 |
+
*
|
28 |
* @var WSAL_AlertFormatter[]
|
29 |
*/
|
30 |
+
private static $formatter_instances = array();
|
31 |
|
32 |
/**
|
33 |
+
* Alert formatter configuration.
|
34 |
+
*
|
35 |
* @var WSAL_AlertFormatterConfiguration[]
|
36 |
*/
|
37 |
+
private static $configurations = array();
|
38 |
|
39 |
+
/**
|
40 |
+
* Boostraps the factory.
|
41 |
+
*/
|
42 |
public static function bootstrap() {
|
43 |
|
44 |
+
$html_configuration = WSAL_AlertFormatterConfiguration::build_html_configuration();
|
45 |
$dashboard_widget_configuration = ( clone $html_configuration )
|
46 |
+
->set_is_js_in_links_allowed( false )
|
47 |
+
->set_supports_metadata( false )
|
48 |
+
->set_supports_hyperlinks( false );
|
49 |
|
50 |
+
// Let extensions register custom alert formatters.
|
51 |
+
$formatters = apply_filters(
|
52 |
+
'wsal_alert_formatters',
|
53 |
+
array(
|
54 |
+
'default' => $html_configuration,
|
55 |
+
'dashboard-widget' => $dashboard_widget_configuration,
|
56 |
+
)
|
57 |
+
);
|
58 |
|
59 |
if ( ! empty( $formatters ) ) {
|
60 |
foreach ( $formatters as $context => $formatter_configuration ) {
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
+
* Gets alert formatter for given context.
|
68 |
+
*
|
69 |
+
* @param string $context Context.
|
70 |
*
|
71 |
* @return WSAL_AlertFormatter
|
72 |
*/
|
73 |
+
public static function get_formatter( $context = 'default' ) {
|
74 |
try {
|
75 |
+
// @todo we could allow late formatter registration using a filter here to improve performance in some cases
|
76 |
+
// (for example SMS formatter would only be registered if the 'sms' context will be used to display alert message)
|
77 |
if ( array_key_exists( $context, self::$formatter_instances ) ) {
|
78 |
return self::$formatter_instances[ $context ];
|
79 |
}
|
80 |
|
81 |
if ( array_key_exists( $context, self::$configurations ) ) {
|
82 |
+
$formatter = new WSAL_AlertFormatter( WpSecurityAuditLog::get_instance(), self::$configurations[ $context ] );
|
83 |
|
84 |
self::$formatter_instances[ $context ] = $formatter;
|
85 |
|
86 |
return self::$formatter_instances[ $context ];
|
87 |
}
|
88 |
} catch ( Exception $exception ) {
|
89 |
+
return self::create_default_formatter();
|
90 |
}
|
91 |
|
92 |
+
return self::create_default_formatter();
|
93 |
}
|
94 |
|
95 |
/**
|
96 |
+
* Creates default formatter (HTML).
|
97 |
+
*
|
98 |
+
* @return WSAL_AlertFormatter Default formatter using full-featured HTML configuration.
|
99 |
* @since 4.3.0
|
100 |
*/
|
101 |
+
private static function create_default_formatter() {
|
102 |
+
return new WSAL_AlertFormatter( WpSecurityAuditLog::get_instance(), WSAL_AlertFormatterConfiguration::build_html_configuration() );
|
103 |
}
|
104 |
}
|
classes/AlertManager.php
CHANGED
@@ -27,7 +27,7 @@ final class WSAL_AlertManager {
|
|
27 |
*
|
28 |
* @var WSAL_Alert[]
|
29 |
*/
|
30 |
-
protected $
|
31 |
|
32 |
/**
|
33 |
* Array of Deprecated Events
|
@@ -43,7 +43,7 @@ final class WSAL_AlertManager {
|
|
43 |
*
|
44 |
* @var WSAL_AbstractLogger[]
|
45 |
*/
|
46 |
-
protected $
|
47 |
|
48 |
/**
|
49 |
* Instance of WpSecurityAuditLog.
|
@@ -57,14 +57,14 @@ final class WSAL_AlertManager {
|
|
57 |
*
|
58 |
* @var array
|
59 |
*/
|
60 |
-
protected $
|
61 |
|
62 |
/**
|
63 |
* Contains an array of alerts that have been triggered for this request.
|
64 |
*
|
65 |
* @var int[]
|
66 |
*/
|
67 |
-
protected $
|
68 |
|
69 |
/**
|
70 |
* WP Users
|
@@ -105,10 +105,10 @@ final class WSAL_AlertManager {
|
|
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->
|
109 |
}
|
110 |
|
111 |
-
add_action( 'shutdown', array( $this, '
|
112 |
|
113 |
/**
|
114 |
* Filter: `wsal_deprecated_event_ids`
|
@@ -129,13 +129,13 @@ final class WSAL_AlertManager {
|
|
129 |
* @param array $ignored_cpts - Array of custom post types.
|
130 |
*
|
131 |
* @since 3.3.1
|
132 |
-
*
|
133 |
*/
|
134 |
$this->ignored_cpts = apply_filters(
|
135 |
'wsal_ignored_custom_post_types',
|
136 |
array_unique(
|
137 |
array_merge(
|
138 |
-
$this->get_disabled_post_types(),
|
|
|
139 |
'attachment', // Attachment CPT.
|
140 |
'revision', // Revision CPT.
|
141 |
'nav_menu_item', // Nav menu item CPT.
|
@@ -146,8 +146,8 @@ final class WSAL_AlertManager {
|
|
146 |
)
|
147 |
);
|
148 |
|
149 |
-
$this->date_format = $this->plugin->settings()->
|
150 |
-
$this->sanitized_date_format = $this->plugin->settings()->
|
151 |
}
|
152 |
|
153 |
/**
|
@@ -155,9 +155,9 @@ final class WSAL_AlertManager {
|
|
155 |
*
|
156 |
* @param string $file Path to file.
|
157 |
*/
|
158 |
-
public function
|
159 |
$file = basename( $file, '.php' );
|
160 |
-
$this->
|
161 |
}
|
162 |
|
163 |
/**
|
@@ -165,8 +165,8 @@ final class WSAL_AlertManager {
|
|
165 |
*
|
166 |
* @param string $class Class name.
|
167 |
*/
|
168 |
-
public function
|
169 |
-
$this->
|
170 |
}
|
171 |
|
172 |
/**
|
@@ -174,8 +174,8 @@ final class WSAL_AlertManager {
|
|
174 |
*
|
175 |
* @param WSAL_AbstractLogger $logger The new logger.
|
176 |
*/
|
177 |
-
public function
|
178 |
-
$this->
|
179 |
}
|
180 |
|
181 |
/**
|
@@ -185,16 +185,15 @@ final class WSAL_AlertManager {
|
|
185 |
* @param array $data - Alert data.
|
186 |
* @param mixed $delayed - False if delayed, function if not.
|
187 |
*/
|
188 |
-
public function
|
189 |
-
//
|
190 |
$username = wp_get_current_user()->user_login;
|
191 |
|
192 |
-
//
|
193 |
if ( apply_filters( 'wsal_disable_user_switching_plugin_tracking', false ) && class_exists( 'user_switching' ) ) {
|
194 |
$old_user = user_switching::get_old_user();
|
195 |
if ( isset( $old_user->user_login ) ) {
|
196 |
-
//
|
197 |
-
// values for use when logging.
|
198 |
$username = $old_user->user_login;
|
199 |
$data['Username'] = $old_user->user_login;
|
200 |
$data['CurrentUserID'] = $old_user->ID;
|
@@ -216,14 +215,14 @@ final class WSAL_AlertManager {
|
|
216 |
$data['CurrentUserRoles'] = $roles;
|
217 |
} else {
|
218 |
// not a switched user so get the current user roles.
|
219 |
-
$roles = $this->plugin->settings()->
|
220 |
}
|
221 |
if ( empty( $roles ) && ! empty( $data['CurrentUserRoles'] ) ) {
|
222 |
$roles = $data['CurrentUserRoles'];
|
223 |
}
|
224 |
|
225 |
// Check if IP is disabled.
|
226 |
-
if ( $this->
|
227 |
return;
|
228 |
}
|
229 |
|
@@ -235,14 +234,14 @@ final class WSAL_AlertManager {
|
|
235 |
}
|
236 |
}
|
237 |
|
238 |
-
// If user or user role is
|
239 |
-
if ( $this->
|
240 |
|
241 |
$data['Timestamp'] = ( isset( $data['Timestamp'] ) && ! empty( $data['Timestamp'] ) ) ? $data['Timestamp'] : current_time( 'U.u', 'true' );
|
242 |
if ( $delayed ) {
|
243 |
-
$this->
|
244 |
} else {
|
245 |
-
$this->
|
246 |
}
|
247 |
}
|
248 |
}
|
@@ -255,15 +254,15 @@ final class WSAL_AlertManager {
|
|
255 |
*
|
256 |
* @return boolean - True if enable false otherwise.
|
257 |
*/
|
258 |
-
public function
|
259 |
-
$
|
260 |
-
|
261 |
-
$is_enable = false;
|
262 |
}
|
263 |
-
|
264 |
-
|
|
|
265 |
}
|
266 |
-
return
|
267 |
}
|
268 |
|
269 |
/**
|
@@ -273,7 +272,7 @@ final class WSAL_AlertManager {
|
|
273 |
* @param array $data - Alert data.
|
274 |
* @param callable $cond - A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
275 |
*/
|
276 |
-
public function
|
277 |
$username = null;
|
278 |
|
279 |
// if user switching plugin class exists and filter is set to disable then try get the old user.
|
@@ -288,12 +287,12 @@ final class WSAL_AlertManager {
|
|
288 |
}
|
289 |
}
|
290 |
|
291 |
-
$roles =
|
292 |
if ( 1000 === $type ) {
|
293 |
-
//
|
294 |
-
//
|
295 |
$username = array_key_exists( 'Username', $data ) ? $data['Username'] : null;
|
296 |
-
$roles
|
297 |
} elseif ( class_exists( 'user_switching' ) && isset( $old_user ) && false !== $old_user ) {
|
298 |
// looks like this is a switched user so setup original user
|
299 |
// roles and values for later user.
|
@@ -304,11 +303,11 @@ final class WSAL_AlertManager {
|
|
304 |
$data['CurrentUserRoles'] = $roles;
|
305 |
} else {
|
306 |
$username = wp_get_current_user()->user_login;
|
307 |
-
$roles = $this->plugin->settings()->
|
308 |
}
|
309 |
|
310 |
// Check if IP is disabled.
|
311 |
-
if ( $this->
|
312 |
return;
|
313 |
}
|
314 |
|
@@ -320,11 +319,11 @@ final class WSAL_AlertManager {
|
|
320 |
}
|
321 |
}
|
322 |
|
323 |
-
if ( $this->
|
324 |
if ( ! array_key_exists( 'Timestamp', $data ) ) {
|
325 |
$data['Timestamp'] = current_time( 'U.u', 'true' );
|
326 |
}
|
327 |
-
$this->
|
328 |
'type' => $type,
|
329 |
'data' => $data,
|
330 |
'cond' => $cond,
|
@@ -343,19 +342,19 @@ final class WSAL_AlertManager {
|
|
343 |
* @return mixed
|
344 |
* @internal
|
345 |
*/
|
346 |
-
protected function
|
347 |
// Double NOT operation here is intentional. Same as ! ( bool ) [ $value ]
|
348 |
// NOTE: return false on a true condition to compensate.
|
349 |
if ( ! $cond || ! ! call_user_func( $cond, $this ) ) {
|
350 |
-
if ( $this->
|
351 |
-
if ( isset( $this->
|
352 |
// Ok, convert alert to a log entry.
|
353 |
-
$this->
|
354 |
-
$this->
|
355 |
} elseif ( $_retry ) {
|
356 |
// This is the last attempt at loading alerts from default file.
|
357 |
$this->plugin->load_defaults();
|
358 |
-
return $this->
|
359 |
} else {
|
360 |
// In general this shouldn't happen, but it could, so we handle it here.
|
361 |
/* translators: Event ID */
|
@@ -371,25 +370,26 @@ final class WSAL_AlertManager {
|
|
371 |
*
|
372 |
* @internal
|
373 |
*/
|
374 |
-
public function
|
375 |
-
foreach ( $this->
|
376 |
-
$this->
|
377 |
}
|
378 |
}
|
379 |
|
380 |
/**
|
381 |
* Method: True if at the end of request an alert of this type will be triggered.
|
382 |
*
|
383 |
-
* @param integer $type
|
384 |
-
* @param int
|
|
|
385 |
* @return boolean
|
386 |
*/
|
387 |
-
public function
|
388 |
$number_found = 0;
|
389 |
-
foreach ( $this->
|
390 |
-
if ( $item['type'] == $type ) {
|
391 |
$number_found++;
|
392 |
-
if ($count == 1 || $number_found == $count) {
|
393 |
return true;
|
394 |
}
|
395 |
}
|
@@ -404,8 +404,8 @@ final class WSAL_AlertManager {
|
|
404 |
* @param int $count - A minimum number of event occurrences.
|
405 |
* @return boolean
|
406 |
*/
|
407 |
-
public function
|
408 |
-
return in_array( $type, $this->
|
409 |
}
|
410 |
|
411 |
/**
|
@@ -415,7 +415,7 @@ final class WSAL_AlertManager {
|
|
415 |
* @param string $subcategory Subcategory name.
|
416 |
* @param array $info Event information from defaults.php.
|
417 |
*/
|
418 |
-
public function
|
419 |
|
420 |
// Default for optional fields.
|
421 |
$metadata = array();
|
@@ -439,7 +439,7 @@ final class WSAL_AlertManager {
|
|
439 |
$links = array( $links );
|
440 |
}
|
441 |
|
442 |
-
if ( isset( $this->
|
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 );
|
@@ -451,7 +451,7 @@ final class WSAL_AlertManager {
|
|
451 |
/**
|
452 |
* WSAL Filter: `wsal_event_metadata_definition`
|
453 |
*
|
454 |
-
* Filters event
|
455 |
* preferred way to change metadata definition of built-in events.
|
456 |
*
|
457 |
* @param array $metadata - Event data.
|
@@ -461,7 +461,7 @@ final class WSAL_AlertManager {
|
|
461 |
*/
|
462 |
$metadata = apply_filters( 'wsal_event_metadata_definition', $metadata, $code );
|
463 |
|
464 |
-
$this->
|
465 |
}
|
466 |
|
467 |
/**
|
@@ -470,11 +470,11 @@ final class WSAL_AlertManager {
|
|
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
|
474 |
foreach ( $groups as $name => $group ) {
|
475 |
foreach ( $group as $subname => $subgroup ) {
|
476 |
foreach ( $subgroup as $item ) {
|
477 |
-
$this->
|
478 |
}
|
479 |
}
|
480 |
}
|
@@ -504,36 +504,18 @@ final class WSAL_AlertManager {
|
|
504 |
* @param integer $type Alert type.
|
505 |
* @return boolean True if enabled, false otherwise.
|
506 |
*/
|
507 |
-
public function
|
508 |
-
$disabled_events = $this->
|
509 |
return ! in_array( $type, $disabled_events, true );
|
510 |
}
|
511 |
|
512 |
-
/**
|
513 |
-
* Disables a set of alerts by type.
|
514 |
-
*
|
515 |
-
* @param int[] $types Alert type codes to be disabled.
|
516 |
-
*/
|
517 |
-
public function SetDisabledAlerts( $types ) {
|
518 |
-
$this->plugin->settings()->SetDisabledAlerts( $types );
|
519 |
-
}
|
520 |
-
|
521 |
-
/**
|
522 |
-
* Method: Returns an array of disabled alerts' type code.
|
523 |
-
*
|
524 |
-
* @return int[]
|
525 |
-
*/
|
526 |
-
public function GetDisabledAlerts() {
|
527 |
-
return $this->plugin->settings()->GetDisabledAlerts();
|
528 |
-
}
|
529 |
-
|
530 |
/**
|
531 |
* Method: Returns an array of loaded loggers.
|
532 |
*
|
533 |
* @return WSAL_AbstractLogger[]
|
534 |
*/
|
535 |
-
public function
|
536 |
-
return $this->
|
537 |
}
|
538 |
|
539 |
/**
|
@@ -543,22 +525,22 @@ final class WSAL_AlertManager {
|
|
543 |
* @param integer $event_id - Alert type.
|
544 |
* @param array $event_data - Misc alert data.
|
545 |
*/
|
546 |
-
protected function
|
547 |
if ( ! isset( $event_data['ClientIP'] ) ) {
|
548 |
-
$client_ip = $this->plugin->settings()->
|
549 |
if ( ! empty( $client_ip ) ) {
|
550 |
$event_data['ClientIP'] = $client_ip;
|
551 |
}
|
552 |
}
|
553 |
-
if ( ! isset( $event_data['OtherIPs'] ) && $this->plugin->settings()->
|
554 |
-
$other_ips = $this->plugin->settings()->
|
555 |
if ( ! empty( $other_ips ) ) {
|
556 |
$event_data['OtherIPs'] = $other_ips;
|
557 |
}
|
558 |
}
|
559 |
if ( ! isset( $event_data['UserAgent'] ) ) {
|
560 |
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
|
561 |
-
$event_data['UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
|
562 |
}
|
563 |
}
|
564 |
if ( ! isset( $event_data['Username'] ) && ! isset( $event_data['CurrentUserID'] ) ) {
|
@@ -567,26 +549,26 @@ final class WSAL_AlertManager {
|
|
567 |
}
|
568 |
}
|
569 |
if ( ! isset( $event_data['CurrentUserRoles'] ) && function_exists( 'is_user_logged_in' ) && is_user_logged_in() ) {
|
570 |
-
$current_user_roles = $this->plugin->settings()->
|
571 |
if ( ! empty( $current_user_roles ) ) {
|
572 |
$event_data['CurrentUserRoles'] = $current_user_roles;
|
573 |
}
|
574 |
}
|
575 |
|
576 |
-
// If the user sessions plugin is loaded try attach the SessionID.
|
577 |
if ( ! isset( $event_data['SessionID'] ) && class_exists( 'WSAL_UserSessions_Helpers' ) ) {
|
578 |
-
//
|
579 |
$session_id = WSAL_UserSessions_Helpers::get_session_id_from_logged_in_user_cookie();
|
580 |
-
//
|
581 |
if ( ! empty( $session_id ) ) {
|
582 |
$event_data['SessionID'] = $session_id;
|
583 |
}
|
584 |
}
|
585 |
|
586 |
// Get event severity.
|
587 |
-
$alert_obj = $this->
|
588 |
$alert_code = $alert_obj ? $alert_obj->severity : 0;
|
589 |
-
$severity = $this->plugin->constants->
|
590 |
|
591 |
/**
|
592 |
* Events Severity.
|
@@ -603,13 +585,13 @@ final class WSAL_AlertManager {
|
|
603 |
*/
|
604 |
if ( is_object( $severity ) && property_exists( $severity, 'name' ) ) {
|
605 |
if ( 'E_CRITICAL' === $severity->name ) {
|
606 |
-
//
|
607 |
$event_data['Severity'] = 500;
|
608 |
} elseif ( 'E_WARNING' === $severity->name ) {
|
609 |
-
//
|
610 |
$event_data['Severity'] = 300;
|
611 |
} elseif ( 'E_NOTICE' === $severity->name ) {
|
612 |
-
//
|
613 |
$event_data['Severity'] = 100;
|
614 |
} elseif ( property_exists( $severity, 'value' ) ) {
|
615 |
$event_data['Severity'] = $severity->value;
|
@@ -623,8 +605,8 @@ final class WSAL_AlertManager {
|
|
623 |
* @since 4.3.0
|
624 |
*/
|
625 |
if ( ! isset( $event_data['Severity'] ) ) {
|
626 |
-
//
|
627 |
-
//
|
628 |
$event_data['Severity'] = 200;
|
629 |
}
|
630 |
|
@@ -639,7 +621,7 @@ final class WSAL_AlertManager {
|
|
639 |
}
|
640 |
|
641 |
// Append further details if in multisite.
|
642 |
-
if ( $this->plugin->
|
643 |
$event_data['SiteID'] = get_current_blog_id();
|
644 |
$event_data['SiteURL'] = get_site_url( $event_data['SiteID'] );
|
645 |
}
|
@@ -668,8 +650,8 @@ final class WSAL_AlertManager {
|
|
668 |
*/
|
669 |
$event_data = apply_filters( 'wsal_event_data_before_log', $event_data, $event_id );
|
670 |
|
671 |
-
foreach ( $this->
|
672 |
-
$logger->
|
673 |
}
|
674 |
}
|
675 |
|
@@ -680,9 +662,9 @@ final class WSAL_AlertManager {
|
|
680 |
* @param mixed $default - Returned if alert is not found.
|
681 |
* @return WSAL_Alert
|
682 |
*/
|
683 |
-
public function
|
684 |
-
if ( isset( $this->
|
685 |
-
return $this->
|
686 |
}
|
687 |
return $default;
|
688 |
}
|
@@ -692,8 +674,8 @@ final class WSAL_AlertManager {
|
|
692 |
*
|
693 |
* @return WSAL_Alert[]
|
694 |
*/
|
695 |
-
public function
|
696 |
-
return $this->
|
697 |
}
|
698 |
|
699 |
/**
|
@@ -716,7 +698,7 @@ final class WSAL_AlertManager {
|
|
716 |
public function get_alerts_by_category( $category ) {
|
717 |
// Categorized alerts array.
|
718 |
$alerts = array();
|
719 |
-
foreach ( $this->
|
720 |
if ( $category === $alert->catg ) {
|
721 |
$alerts[ $alert->code ] = $alert;
|
722 |
}
|
@@ -733,7 +715,7 @@ final class WSAL_AlertManager {
|
|
733 |
public function get_alerts_by_sub_category( $sub_category ) {
|
734 |
// Sub-categorized alerts array.
|
735 |
$alerts = array();
|
736 |
-
foreach ( $this->
|
737 |
if ( $sub_category === $alert->subcatg ) {
|
738 |
$alerts[ $alert->code ] = $alert;
|
739 |
}
|
@@ -747,9 +729,9 @@ final class WSAL_AlertManager {
|
|
747 |
* @param bool $sorted – Sort the alerts array or not.
|
748 |
* @return array
|
749 |
*/
|
750 |
-
public function
|
751 |
$result = array();
|
752 |
-
foreach ( $this->
|
753 |
if ( ! isset( $result[ $alert->catg ] ) ) {
|
754 |
$result[ $alert->catg ] = array();
|
755 |
}
|
@@ -771,8 +753,8 @@ final class WSAL_AlertManager {
|
|
771 |
* @param string $user - Username.
|
772 |
* @return boolean True if disabled, false otherwise.
|
773 |
*/
|
774 |
-
public function
|
775 |
-
return
|
776 |
}
|
777 |
|
778 |
/**
|
@@ -780,8 +762,8 @@ final class WSAL_AlertManager {
|
|
780 |
*
|
781 |
* @return array.
|
782 |
*/
|
783 |
-
public function
|
784 |
-
return $this->plugin->settings()->
|
785 |
}
|
786 |
|
787 |
/**
|
@@ -790,10 +772,10 @@ final class WSAL_AlertManager {
|
|
790 |
* @param array $roles - User roles.
|
791 |
* @return boolean True if disabled, false otherwise.
|
792 |
*/
|
793 |
-
public function
|
794 |
$is_disabled = false;
|
795 |
foreach ( $roles as $role ) {
|
796 |
-
if ( in_array( $role, $this->
|
797 |
$is_disabled = true;
|
798 |
}
|
799 |
}
|
@@ -805,8 +787,8 @@ final class WSAL_AlertManager {
|
|
805 |
*
|
806 |
* @return array
|
807 |
*/
|
808 |
-
public function
|
809 |
-
return $this->plugin->settings()->
|
810 |
}
|
811 |
|
812 |
/**
|
@@ -817,7 +799,7 @@ final class WSAL_AlertManager {
|
|
817 |
* @since 2.6.7
|
818 |
*/
|
819 |
public function is_disabled_post_type( $post_type ) {
|
820 |
-
return
|
821 |
}
|
822 |
|
823 |
/**
|
@@ -832,11 +814,13 @@ final class WSAL_AlertManager {
|
|
832 |
|
833 |
/**
|
834 |
* Method: Returns if IP is disabled or not.
|
|
|
|
|
835 |
*/
|
836 |
-
private function
|
837 |
$is_disabled = false;
|
838 |
-
$ip = $this->plugin->settings()->
|
839 |
-
$excluded_ips = $this->plugin->settings()->
|
840 |
|
841 |
if ( ! empty( $excluded_ips ) ) {
|
842 |
foreach ( $excluded_ips as $excluded_ip ) {
|
@@ -920,26 +904,26 @@ final class WSAL_AlertManager {
|
|
920 |
* @since 3.2.4
|
921 |
*
|
922 |
* @param integer $limit – Number of events.
|
923 |
-
* @return
|
924 |
*/
|
925 |
public function get_latest_events( $limit = 1 ) {
|
926 |
// Occurrence query.
|
927 |
$occ_query = new WSAL_Models_OccurrenceQuery();
|
928 |
-
if ( ! $occ_query->
|
929 |
-
//
|
930 |
-
//
|
931 |
return false;
|
932 |
}
|
933 |
|
934 |
// Get site id.
|
935 |
$site_id = (int) $this->plugin->settings()->get_view_site_id();
|
936 |
if ( $site_id ) {
|
937 |
-
$occ_query->
|
938 |
}
|
939 |
|
940 |
-
$occ_query->
|
941 |
-
$occ_query->
|
942 |
-
$events = $occ_query->
|
943 |
|
944 |
if ( ! empty( $events ) && is_array( $events ) ) {
|
945 |
return $events;
|
@@ -960,8 +944,8 @@ final class WSAL_AlertManager {
|
|
960 |
$event_transient = 'wsal_admin_bar_event';
|
961 |
|
962 |
// Check for multisite.
|
963 |
-
$get_fn = $this->plugin->
|
964 |
-
$set_fn = $this->plugin->
|
965 |
|
966 |
$admin_bar_event = $get_fn( $event_transient );
|
967 |
if ( false === $admin_bar_event || false !== $from_db ) {
|
@@ -1003,29 +987,30 @@ final class WSAL_AlertManager {
|
|
1003 |
*/
|
1004 |
public function get_event_objects_data( $object = '' ) {
|
1005 |
$objects = array(
|
1006 |
-
'user'
|
1007 |
-
'system'
|
1008 |
-
'plugin'
|
1009 |
-
'database'
|
1010 |
-
'post'
|
1011 |
-
'file'
|
1012 |
-
'tag'
|
1013 |
-
'comment'
|
1014 |
-
'setting'
|
1015 |
-
'file'
|
1016 |
-
'system-setting'
|
1017 |
-
'mainwp-network'
|
1018 |
-
'mainwp'
|
1019 |
-
'category'
|
1020 |
-
'custom-field'
|
1021 |
-
'widget'
|
1022 |
-
'menu'
|
1023 |
-
'theme'
|
1024 |
-
'activity-log'
|
1025 |
-
'wp-activity-log'
|
1026 |
-
'multisite-network'
|
1027 |
-
'ip-address'
|
1028 |
);
|
|
|
1029 |
asort( $objects );
|
1030 |
$objects = apply_filters(
|
1031 |
'wsal_event_objects',
|
@@ -1077,36 +1062,36 @@ final class WSAL_AlertManager {
|
|
1077 |
*/
|
1078 |
public function get_event_type_data( $type = '' ) {
|
1079 |
$types = array(
|
1080 |
-
'login' =>
|
1081 |
-
'logout' =>
|
1082 |
-
'installed' =>
|
1083 |
-
'activated' =>
|
1084 |
-
'deactivated' =>
|
1085 |
-
'uninstalled' =>
|
1086 |
-
'updated' =>
|
1087 |
-
'created' =>
|
1088 |
-
'modified' =>
|
1089 |
-
'deleted' =>
|
1090 |
-
'published' =>
|
1091 |
-
'approved' =>
|
1092 |
-
'unapproved' =>
|
1093 |
-
'enabled' =>
|
1094 |
-
'disabled' =>
|
1095 |
-
'added' =>
|
1096 |
-
'failed-login' =>
|
1097 |
-
'blocked' =>
|
1098 |
-
'uploaded' =>
|
1099 |
-
'restored' =>
|
1100 |
-
'opened' =>
|
1101 |
-
'viewed' =>
|
1102 |
-
'started' =>
|
1103 |
-
'stopped' =>
|
1104 |
-
'removed' =>
|
1105 |
-
'unblocked' =>
|
1106 |
-
'renamed' =>
|
1107 |
-
'duplicated' =>
|
1108 |
-
'submitted' =>
|
1109 |
-
'revoked' =>
|
1110 |
);
|
1111 |
// sort the types alphabetically.
|
1112 |
asort( $types );
|
@@ -1148,27 +1133,17 @@ final class WSAL_AlertManager {
|
|
1148 |
* @return string
|
1149 |
*/
|
1150 |
public function get_display_event_type_text( $event_type ) {
|
1151 |
-
// Try get string from the companion data method.
|
1152 |
return get_event_type_data( $event_type );
|
1153 |
}
|
1154 |
|
1155 |
-
/**
|
1156 |
-
* Modify post name values to include MySQL wildcards.
|
1157 |
-
*
|
1158 |
-
* @param string $search_value – Searched post name.
|
1159 |
-
* @return string
|
1160 |
-
*/
|
1161 |
-
private function add_string_wildcards( $search_value ) {
|
1162 |
-
return '%' . $search_value . '%';
|
1163 |
-
}
|
1164 |
-
|
1165 |
/**
|
1166 |
* Return sub-categorized events of WSAL.
|
1167 |
*
|
1168 |
* @return array
|
1169 |
*/
|
1170 |
public function get_sub_categorized_events() {
|
1171 |
-
$cg_alerts = $this->
|
1172 |
$events = array();
|
1173 |
|
1174 |
foreach ( $cg_alerts as $group ) {
|
@@ -1220,7 +1195,7 @@ final class WSAL_AlertManager {
|
|
1220 |
}
|
1221 |
|
1222 |
// Get MainWP dashboard user ids.
|
1223 |
-
$result = $wpdb->get_results( $sql, ARRAY_A );
|
1224 |
|
1225 |
$users = array();
|
1226 |
if ( ! empty( $result ) ) {
|
@@ -1314,7 +1289,6 @@ final class WSAL_AlertManager {
|
|
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;
|
@@ -1338,16 +1312,16 @@ final class WSAL_AlertManager {
|
|
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->
|
1342 |
$code = $code ? $code->severity : 0;
|
1343 |
$const = (object) array(
|
1344 |
'name' => 'E_UNKNOWN',
|
1345 |
'value' => 0,
|
1346 |
'description' => __( 'Unknown error code.', 'wp-security-audit-log' ),
|
1347 |
);
|
1348 |
-
$const = $this->plugin->constants->
|
1349 |
|
1350 |
-
$blog_info =
|
1351 |
|
1352 |
// Get the alert message - properly.
|
1353 |
$occurrence->id = $entry_id;
|
@@ -1362,18 +1336,18 @@ final class WSAL_AlertManager {
|
|
1362 |
$occurrence->post_id = $entry->post_id;
|
1363 |
$occurrence->post_type = $entry->post_type;
|
1364 |
$occurrence->post_status = $entry->post_status;
|
1365 |
-
$occurrence->
|
1366 |
|
1367 |
-
$event_metadata = $occurrence->
|
1368 |
-
if ( ! $occurrence->
|
1369 |
-
$occurrence->
|
1370 |
}
|
1371 |
|
1372 |
if ( ! $user_id ) {
|
1373 |
$username = __( 'System', 'wp-security-audit-log' );
|
1374 |
$roles = '';
|
1375 |
} else {
|
1376 |
-
$username = WSAL_Utilities_UsersUtils::
|
1377 |
}
|
1378 |
|
1379 |
// Meta details.
|
@@ -1382,13 +1356,13 @@ final class WSAL_AlertManager {
|
|
1382 |
'blog_name' => $blog_info['name'],
|
1383 |
'blog_url' => $blog_info['url'],
|
1384 |
'alert_id' => $alert_id,
|
1385 |
-
'date' => WSAL_Utilities_DateTimeFormatter::instance()->
|
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->
|
1392 |
'user_id' => $user_id,
|
1393 |
'user_name' => $username,
|
1394 |
'user_data' => $user_id ? $this->get_event_user_data( $username ) : false,
|
@@ -1412,7 +1386,7 @@ final class WSAL_AlertManager {
|
|
1412 |
*/
|
1413 |
public static function get_blog_info( $plugin, $site_id ) {
|
1414 |
// Blog details.
|
1415 |
-
if ( $plugin->
|
1416 |
$blog_info = get_blog_details( $site_id, true );
|
1417 |
$blog_name = esc_html__( 'Unknown Site', 'wp-security-audit-log' );
|
1418 |
$blog_url = '';
|
@@ -1449,4 +1423,72 @@ final class WSAL_AlertManager {
|
|
1449 |
public function get_wp_users(): array {
|
1450 |
return $this->wp_users;
|
1451 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1452 |
}
|
27 |
*
|
28 |
* @var WSAL_Alert[]
|
29 |
*/
|
30 |
+
protected $alerts = array();
|
31 |
|
32 |
/**
|
33 |
* Array of Deprecated Events
|
43 |
*
|
44 |
* @var WSAL_AbstractLogger[]
|
45 |
*/
|
46 |
+
protected $loggers = array();
|
47 |
|
48 |
/**
|
49 |
* Instance of WpSecurityAuditLog.
|
57 |
*
|
58 |
* @var array
|
59 |
*/
|
60 |
+
protected $pipeline = array();
|
61 |
|
62 |
/**
|
63 |
* Contains an array of alerts that have been triggered for this request.
|
64 |
*
|
65 |
* @var int[]
|
66 |
*/
|
67 |
+
protected $triggered_types = array();
|
68 |
|
69 |
/**
|
70 |
* WP Users
|
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->add_logger_from_file( $file );
|
109 |
}
|
110 |
|
111 |
+
add_action( 'shutdown', array( $this, 'commit_pipeline' ), 8 );
|
112 |
|
113 |
/**
|
114 |
* Filter: `wsal_deprecated_event_ids`
|
129 |
* @param array $ignored_cpts - Array of custom post types.
|
130 |
*
|
131 |
* @since 3.3.1
|
|
|
132 |
*/
|
133 |
$this->ignored_cpts = apply_filters(
|
134 |
'wsal_ignored_custom_post_types',
|
135 |
array_unique(
|
136 |
array_merge(
|
137 |
+
$this->get_disabled_post_types(),
|
138 |
+
array(
|
139 |
'attachment', // Attachment CPT.
|
140 |
'revision', // Revision CPT.
|
141 |
'nav_menu_item', // Nav menu item CPT.
|
146 |
)
|
147 |
);
|
148 |
|
149 |
+
$this->date_format = $this->plugin->settings()->get_date_format();
|
150 |
+
$this->sanitized_date_format = $this->plugin->settings()->get_date_format( true );
|
151 |
}
|
152 |
|
153 |
/**
|
155 |
*
|
156 |
* @param string $file Path to file.
|
157 |
*/
|
158 |
+
public function add_logger_from_file( $file ) {
|
159 |
$file = basename( $file, '.php' );
|
160 |
+
$this->add_logger_from_class( WSAL_CLASS_PREFIX . 'Loggers_' . $file );
|
161 |
}
|
162 |
|
163 |
/**
|
165 |
*
|
166 |
* @param string $class Class name.
|
167 |
*/
|
168 |
+
public function add_logger_from_class( $class ) {
|
169 |
+
$this->add_logger_instance( new $class( $this->plugin ) );
|
170 |
}
|
171 |
|
172 |
/**
|
174 |
*
|
175 |
* @param WSAL_AbstractLogger $logger The new logger.
|
176 |
*/
|
177 |
+
public function add_logger_instance( WSAL_AbstractLogger $logger ) {
|
178 |
+
$this->loggers[] = $logger;
|
179 |
}
|
180 |
|
181 |
/**
|
185 |
* @param array $data - Alert data.
|
186 |
* @param mixed $delayed - False if delayed, function if not.
|
187 |
*/
|
188 |
+
public function trigger_event( $type, $data = array(), $delayed = false ) {
|
189 |
+
// Figure out the username.
|
190 |
$username = wp_get_current_user()->user_login;
|
191 |
|
192 |
+
// If user switching plugin class exists and filter is set to disable then try to get the old user.
|
193 |
if ( apply_filters( 'wsal_disable_user_switching_plugin_tracking', false ) && class_exists( 'user_switching' ) ) {
|
194 |
$old_user = user_switching::get_old_user();
|
195 |
if ( isset( $old_user->user_login ) ) {
|
196 |
+
// Looks like this is a switched user so setup original user values for use when logging.
|
|
|
197 |
$username = $old_user->user_login;
|
198 |
$data['Username'] = $old_user->user_login;
|
199 |
$data['CurrentUserID'] = $old_user->ID;
|
215 |
$data['CurrentUserRoles'] = $roles;
|
216 |
} else {
|
217 |
// not a switched user so get the current user roles.
|
218 |
+
$roles = $this->plugin->settings()->get_current_user_roles();
|
219 |
}
|
220 |
if ( empty( $roles ) && ! empty( $data['CurrentUserRoles'] ) ) {
|
221 |
$roles = $data['CurrentUserRoles'];
|
222 |
}
|
223 |
|
224 |
// Check if IP is disabled.
|
225 |
+
if ( $this->is_ip_address_disabled() ) {
|
226 |
return;
|
227 |
}
|
228 |
|
234 |
}
|
235 |
}
|
236 |
|
237 |
+
// If user or user role is enabled then go ahead.
|
238 |
+
if ( $this->check_enable_user_roles( $username, $roles ) ) {
|
239 |
|
240 |
$data['Timestamp'] = ( isset( $data['Timestamp'] ) && ! empty( $data['Timestamp'] ) ) ? $data['Timestamp'] : current_time( 'U.u', 'true' );
|
241 |
if ( $delayed ) {
|
242 |
+
$this->trigger_event_if( $type, $data, null );
|
243 |
} else {
|
244 |
+
$this->commit_item( $type, $data, null );
|
245 |
}
|
246 |
}
|
247 |
}
|
254 |
*
|
255 |
* @return boolean - True if enable false otherwise.
|
256 |
*/
|
257 |
+
public function check_enable_user_roles( $user, $roles ) {
|
258 |
+
if ( '' != $user && $this->is_disabled_user( $user ) ) { // phpcs:ignore
|
259 |
+
return false;
|
|
|
260 |
}
|
261 |
+
|
262 |
+
if ( '' != $roles && $this->is_disabled_role( $roles ) ) { // phpcs:ignore
|
263 |
+
return false;
|
264 |
}
|
265 |
+
return true;
|
266 |
}
|
267 |
|
268 |
/**
|
272 |
* @param array $data - Alert data.
|
273 |
* @param callable $cond - A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
274 |
*/
|
275 |
+
public function trigger_event_if( $type, $data, $cond = null ) {
|
276 |
$username = null;
|
277 |
|
278 |
// if user switching plugin class exists and filter is set to disable then try get the old user.
|
287 |
}
|
288 |
}
|
289 |
|
290 |
+
$roles = array();
|
291 |
if ( 1000 === $type ) {
|
292 |
+
// When event 1000 is triggered, the user is not logged in.
|
293 |
+
// We need to extract the username and user roles from the event data.
|
294 |
$username = array_key_exists( 'Username', $data ) ? $data['Username'] : null;
|
295 |
+
$roles = array_key_exists( 'CurrentUserRoles', $data ) ? $data['CurrentUserRoles'] : array();
|
296 |
} elseif ( class_exists( 'user_switching' ) && isset( $old_user ) && false !== $old_user ) {
|
297 |
// looks like this is a switched user so setup original user
|
298 |
// roles and values for later user.
|
303 |
$data['CurrentUserRoles'] = $roles;
|
304 |
} else {
|
305 |
$username = wp_get_current_user()->user_login;
|
306 |
+
$roles = $this->plugin->settings()->get_current_user_roles();
|
307 |
}
|
308 |
|
309 |
// Check if IP is disabled.
|
310 |
+
if ( $this->is_ip_address_disabled() ) {
|
311 |
return;
|
312 |
}
|
313 |
|
319 |
}
|
320 |
}
|
321 |
|
322 |
+
if ( $this->check_enable_user_roles( $username, $roles ) ) {
|
323 |
if ( ! array_key_exists( 'Timestamp', $data ) ) {
|
324 |
$data['Timestamp'] = current_time( 'U.u', 'true' );
|
325 |
}
|
326 |
+
$this->pipeline[] = array(
|
327 |
'type' => $type,
|
328 |
'data' => $data,
|
329 |
'cond' => $cond,
|
342 |
* @return mixed
|
343 |
* @internal
|
344 |
*/
|
345 |
+
protected function commit_item( $type, $data, $cond, $_retry = true ) {
|
346 |
// Double NOT operation here is intentional. Same as ! ( bool ) [ $value ]
|
347 |
// NOTE: return false on a true condition to compensate.
|
348 |
if ( ! $cond || ! ! call_user_func( $cond, $this ) ) {
|
349 |
+
if ( $this->is_enabled( $type ) ) {
|
350 |
+
if ( isset( $this->alerts[ $type ] ) ) {
|
351 |
// Ok, convert alert to a log entry.
|
352 |
+
$this->triggered_types[] = $type;
|
353 |
+
$this->log( $type, $data );
|
354 |
} elseif ( $_retry ) {
|
355 |
// This is the last attempt at loading alerts from default file.
|
356 |
$this->plugin->load_defaults();
|
357 |
+
return $this->commit_item( $type, $data, $cond, false );
|
358 |
} else {
|
359 |
// In general this shouldn't happen, but it could, so we handle it here.
|
360 |
/* translators: Event ID */
|
370 |
*
|
371 |
* @internal
|
372 |
*/
|
373 |
+
public function commit_pipeline() {
|
374 |
+
foreach ( $this->pipeline as $item ) {
|
375 |
+
$this->commit_item( $item['type'], $item['data'], $item['cond'] );
|
376 |
}
|
377 |
}
|
378 |
|
379 |
/**
|
380 |
* Method: True if at the end of request an alert of this type will be triggered.
|
381 |
*
|
382 |
+
* @param integer $type - Alert type ID.
|
383 |
+
* @param int $count - A minimum number of event occurrences.
|
384 |
+
*
|
385 |
* @return boolean
|
386 |
*/
|
387 |
+
public function will_trigger( $type, $count = 1 ) {
|
388 |
$number_found = 0;
|
389 |
+
foreach ( $this->pipeline as $item ) {
|
390 |
+
if ( $item['type'] == $type ) { // phpcs:ignore
|
391 |
$number_found++;
|
392 |
+
if ($count == 1 || $number_found == $count) { // phpcs:ignore
|
393 |
return true;
|
394 |
}
|
395 |
}
|
404 |
* @param int $count - A minimum number of event occurrences.
|
405 |
* @return boolean
|
406 |
*/
|
407 |
+
public function will_or_has_triggered( $type, $count = 1 ) {
|
408 |
+
return in_array( $type, $this->triggered_types ) || $this->will_trigger( $type, $count ); // phpcs:ignore
|
409 |
}
|
410 |
|
411 |
/**
|
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();
|
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 );
|
451 |
/**
|
452 |
* WSAL Filter: `wsal_event_metadata_definition`
|
453 |
*
|
454 |
+
* Filters event metadata definition before registering specific event with the alert manager. This is the
|
455 |
* preferred way to change metadata definition of built-in events.
|
456 |
*
|
457 |
* @param array $metadata - Event data.
|
461 |
*/
|
462 |
$metadata = apply_filters( 'wsal_event_metadata_definition', $metadata, $code );
|
463 |
|
464 |
+
$this->alerts[ $code ] = new WSAL_Alert( $code, $severity, $category, $subcategory, $desc, $message, $metadata, $links, $object, $event_type );
|
465 |
}
|
466 |
|
467 |
/**
|
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 register_group( $groups ) {
|
474 |
foreach ( $groups as $name => $group ) {
|
475 |
foreach ( $group as $subname => $subgroup ) {
|
476 |
foreach ( $subgroup as $item ) {
|
477 |
+
$this->register( $name, $subname, $item );
|
478 |
}
|
479 |
}
|
480 |
}
|
504 |
* @param integer $type Alert type.
|
505 |
* @return boolean True if enabled, false otherwise.
|
506 |
*/
|
507 |
+
public function is_enabled( $type ) {
|
508 |
+
$disabled_events = $this->plugin->settings()->get_disabled_alerts();
|
509 |
return ! in_array( $type, $disabled_events, true );
|
510 |
}
|
511 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
/**
|
513 |
* Method: Returns an array of loaded loggers.
|
514 |
*
|
515 |
* @return WSAL_AbstractLogger[]
|
516 |
*/
|
517 |
+
public function get_loggers() {
|
518 |
+
return $this->loggers;
|
519 |
}
|
520 |
|
521 |
/**
|
525 |
* @param integer $event_id - Alert type.
|
526 |
* @param array $event_data - Misc alert data.
|
527 |
*/
|
528 |
+
protected function log( $event_id, $event_data = array() ) {
|
529 |
if ( ! isset( $event_data['ClientIP'] ) ) {
|
530 |
+
$client_ip = $this->plugin->settings()->get_main_client_ip();
|
531 |
if ( ! empty( $client_ip ) ) {
|
532 |
$event_data['ClientIP'] = $client_ip;
|
533 |
}
|
534 |
}
|
535 |
+
if ( ! isset( $event_data['OtherIPs'] ) && $this->plugin->settings()->is_main_ip_from_proxy() ) {
|
536 |
+
$other_ips = $this->plugin->settings()->get_client_ips();
|
537 |
if ( ! empty( $other_ips ) ) {
|
538 |
$event_data['OtherIPs'] = $other_ips;
|
539 |
}
|
540 |
}
|
541 |
if ( ! isset( $event_data['UserAgent'] ) ) {
|
542 |
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
|
543 |
+
$event_data['UserAgent'] = $_SERVER['HTTP_USER_AGENT']; // phpcs:ignore
|
544 |
}
|
545 |
}
|
546 |
if ( ! isset( $event_data['Username'] ) && ! isset( $event_data['CurrentUserID'] ) ) {
|
549 |
}
|
550 |
}
|
551 |
if ( ! isset( $event_data['CurrentUserRoles'] ) && function_exists( 'is_user_logged_in' ) && is_user_logged_in() ) {
|
552 |
+
$current_user_roles = $this->plugin->settings()->get_current_user_roles();
|
553 |
if ( ! empty( $current_user_roles ) ) {
|
554 |
$event_data['CurrentUserRoles'] = $current_user_roles;
|
555 |
}
|
556 |
}
|
557 |
|
558 |
+
// If the user sessions plugin is loaded try to attach the SessionID.
|
559 |
if ( ! isset( $event_data['SessionID'] ) && class_exists( 'WSAL_UserSessions_Helpers' ) ) {
|
560 |
+
// Try to get the session id generated from logged in cookie.
|
561 |
$session_id = WSAL_UserSessions_Helpers::get_session_id_from_logged_in_user_cookie();
|
562 |
+
// If we have a SessionID then add it to event_data.
|
563 |
if ( ! empty( $session_id ) ) {
|
564 |
$event_data['SessionID'] = $session_id;
|
565 |
}
|
566 |
}
|
567 |
|
568 |
// Get event severity.
|
569 |
+
$alert_obj = $this->get_alert( $event_id );
|
570 |
$alert_code = $alert_obj ? $alert_obj->severity : 0;
|
571 |
+
$severity = $this->plugin->constants->get_constant_by( 'value', $alert_code );
|
572 |
|
573 |
/**
|
574 |
* Events Severity.
|
585 |
*/
|
586 |
if ( is_object( $severity ) && property_exists( $severity, 'name' ) ) {
|
587 |
if ( 'E_CRITICAL' === $severity->name ) {
|
588 |
+
// CRITICAL (500): Critical conditions.
|
589 |
$event_data['Severity'] = 500;
|
590 |
} elseif ( 'E_WARNING' === $severity->name ) {
|
591 |
+
// WARNING (300): Exceptional occurrences that are not errors.
|
592 |
$event_data['Severity'] = 300;
|
593 |
} elseif ( 'E_NOTICE' === $severity->name ) {
|
594 |
+
// DEBUG (100): Detailed debug information.
|
595 |
$event_data['Severity'] = 100;
|
596 |
} elseif ( property_exists( $severity, 'value' ) ) {
|
597 |
$event_data['Severity'] = $severity->value;
|
605 |
* @since 4.3.0
|
606 |
*/
|
607 |
if ( ! isset( $event_data['Severity'] ) ) {
|
608 |
+
// Assuming this is a misclassified item and using info code.
|
609 |
+
// INFO (200): Interesting events.
|
610 |
$event_data['Severity'] = 200;
|
611 |
}
|
612 |
|
621 |
}
|
622 |
|
623 |
// Append further details if in multisite.
|
624 |
+
if ( $this->plugin->is_multisite() ) {
|
625 |
$event_data['SiteID'] = get_current_blog_id();
|
626 |
$event_data['SiteURL'] = get_site_url( $event_data['SiteID'] );
|
627 |
}
|
650 |
*/
|
651 |
$event_data = apply_filters( 'wsal_event_data_before_log', $event_data, $event_id );
|
652 |
|
653 |
+
foreach ( $this->loggers as $logger ) {
|
654 |
+
$logger->log( $event_id, $event_data );
|
655 |
}
|
656 |
}
|
657 |
|
662 |
* @param mixed $default - Returned if alert is not found.
|
663 |
* @return WSAL_Alert
|
664 |
*/
|
665 |
+
public function get_alert( $type, $default = null ) {
|
666 |
+
if ( isset( $this->alerts[ $type ] ) ) {
|
667 |
+
return $this->alerts[ $type ];
|
668 |
}
|
669 |
return $default;
|
670 |
}
|
674 |
*
|
675 |
* @return WSAL_Alert[]
|
676 |
*/
|
677 |
+
public function get_alerts() {
|
678 |
+
return $this->alerts;
|
679 |
}
|
680 |
|
681 |
/**
|
698 |
public function get_alerts_by_category( $category ) {
|
699 |
// Categorized alerts array.
|
700 |
$alerts = array();
|
701 |
+
foreach ( $this->alerts as $alert ) {
|
702 |
if ( $category === $alert->catg ) {
|
703 |
$alerts[ $alert->code ] = $alert;
|
704 |
}
|
715 |
public function get_alerts_by_sub_category( $sub_category ) {
|
716 |
// Sub-categorized alerts array.
|
717 |
$alerts = array();
|
718 |
+
foreach ( $this->alerts as $alert ) {
|
719 |
if ( $sub_category === $alert->subcatg ) {
|
720 |
$alerts[ $alert->code ] = $alert;
|
721 |
}
|
729 |
* @param bool $sorted – Sort the alerts array or not.
|
730 |
* @return array
|
731 |
*/
|
732 |
+
public function get_categorized_alerts( $sorted = true ) {
|
733 |
$result = array();
|
734 |
+
foreach ( $this->alerts as $alert ) {
|
735 |
if ( ! isset( $result[ $alert->catg ] ) ) {
|
736 |
$result[ $alert->catg ] = array();
|
737 |
}
|
753 |
* @param string $user - Username.
|
754 |
* @return boolean True if disabled, false otherwise.
|
755 |
*/
|
756 |
+
public function is_disabled_user( $user ) {
|
757 |
+
return in_array( $user, $this->get_disabled_users() ); // phpcs:ignore
|
758 |
}
|
759 |
|
760 |
/**
|
762 |
*
|
763 |
* @return array.
|
764 |
*/
|
765 |
+
public function get_disabled_users() {
|
766 |
+
return $this->plugin->settings()->get_excluded_monitoring_users();
|
767 |
}
|
768 |
|
769 |
/**
|
772 |
* @param array $roles - User roles.
|
773 |
* @return boolean True if disabled, false otherwise.
|
774 |
*/
|
775 |
+
public function is_disabled_role( $roles ) {
|
776 |
$is_disabled = false;
|
777 |
foreach ( $roles as $role ) {
|
778 |
+
if ( in_array( $role, $this->get_disabled_roles() ) ) { // phpcs:ignore
|
779 |
$is_disabled = true;
|
780 |
}
|
781 |
}
|
787 |
*
|
788 |
* @return array
|
789 |
*/
|
790 |
+
public function get_disabled_roles() {
|
791 |
+
return $this->plugin->settings()->get_excluded_monitoring_roles();
|
792 |
}
|
793 |
|
794 |
/**
|
799 |
* @since 2.6.7
|
800 |
*/
|
801 |
public function is_disabled_post_type( $post_type ) {
|
802 |
+
return in_array( $post_type, $this->get_disabled_post_types(), true );
|
803 |
}
|
804 |
|
805 |
/**
|
814 |
|
815 |
/**
|
816 |
* Method: Returns if IP is disabled or not.
|
817 |
+
*
|
818 |
+
* @return bool True if current IP address is disabled.
|
819 |
*/
|
820 |
+
private function is_ip_address_disabled() {
|
821 |
$is_disabled = false;
|
822 |
+
$ip = $this->plugin->settings()->get_main_client_ip();
|
823 |
+
$excluded_ips = $this->plugin->settings()->get_excluded_monitoring_ip();
|
824 |
|
825 |
if ( ! empty( $excluded_ips ) ) {
|
826 |
foreach ( $excluded_ips as $excluded_ip ) {
|
904 |
* @since 3.2.4
|
905 |
*
|
906 |
* @param integer $limit – Number of events.
|
907 |
+
* @return WSAL_Models_Occurrence[]|boolean
|
908 |
*/
|
909 |
public function get_latest_events( $limit = 1 ) {
|
910 |
// Occurrence query.
|
911 |
$occ_query = new WSAL_Models_OccurrenceQuery();
|
912 |
+
if ( ! $occ_query->get_adapter()->is_connected() ) {
|
913 |
+
// Connection problem while using external database (if local database is used, we would see WordPress's
|
914 |
+
// "Error Establishing a Database Connection" screen).
|
915 |
return false;
|
916 |
}
|
917 |
|
918 |
// Get site id.
|
919 |
$site_id = (int) $this->plugin->settings()->get_view_site_id();
|
920 |
if ( $site_id ) {
|
921 |
+
$occ_query->add_condition( 'site_id = %d ', $site_id );
|
922 |
}
|
923 |
|
924 |
+
$occ_query->add_order_by( 'created_on', true ); // Set order for latest events.
|
925 |
+
$occ_query->set_limit( $limit ); // Set limit.
|
926 |
+
$events = $occ_query->get_adapter()->execute_query( $occ_query );
|
927 |
|
928 |
if ( ! empty( $events ) && is_array( $events ) ) {
|
929 |
return $events;
|
944 |
$event_transient = 'wsal_admin_bar_event';
|
945 |
|
946 |
// Check for multisite.
|
947 |
+
$get_fn = $this->plugin->is_multisite() ? 'get_site_transient' : 'get_transient';
|
948 |
+
$set_fn = $this->plugin->is_multisite() ? 'set_site_transient' : 'set_transient';
|
949 |
|
950 |
$admin_bar_event = $get_fn( $event_transient );
|
951 |
if ( false === $admin_bar_event || false !== $from_db ) {
|
987 |
*/
|
988 |
public function get_event_objects_data( $object = '' ) {
|
989 |
$objects = array(
|
990 |
+
'user' => esc_html__( 'User', 'wp-security-audit-log' ),
|
991 |
+
'system' => esc_html__( 'System', 'wp-security-audit-log' ),
|
992 |
+
'plugin' => esc_html__( 'Plugin', 'wp-security-audit-log' ),
|
993 |
+
'database' => esc_html__( 'Database', 'wp-security-audit-log' ),
|
994 |
+
'post' => esc_html__( 'Post', 'wp-security-audit-log' ),
|
995 |
+
'file' => esc_html__( 'File', 'wp-security-audit-log' ),
|
996 |
+
'tag' => esc_html__( 'Tag', 'wp-security-audit-log' ),
|
997 |
+
'comment' => esc_html__( 'Comment', 'wp-security-audit-log' ),
|
998 |
+
'setting' => esc_html__( 'Setting', 'wp-security-audit-log' ),
|
999 |
+
'file' => esc_html__( 'File', 'wp-security-audit-log' ),
|
1000 |
+
'system-setting' => esc_html__( 'System Setting', 'wp-security-audit-log' ),
|
1001 |
+
'mainwp-network' => esc_html__( 'MainWP Network', 'wp-security-audit-log' ),
|
1002 |
+
'mainwp' => esc_html__( 'MainWP', 'wp-security-audit-log' ),
|
1003 |
+
'category' => esc_html__( 'Category', 'wp-security-audit-log' ),
|
1004 |
+
'custom-field' => esc_html__( 'Custom Field', 'wp-security-audit-log' ),
|
1005 |
+
'widget' => esc_html__( 'Widget', 'wp-security-audit-log' ),
|
1006 |
+
'menu' => esc_html__( 'Menu', 'wp-security-audit-log' ),
|
1007 |
+
'theme' => esc_html__( 'Theme', 'wp-security-audit-log' ),
|
1008 |
+
'activity-log' => esc_html__( 'Activity log', 'wp-security-audit-log' ),
|
1009 |
+
'wp-activity-log' => esc_html__( 'WP Activity Log', 'wp-security-audit-log' ),
|
1010 |
+
'multisite-network' => esc_html__( 'Multisite Network', 'wp-security-audit-log' ),
|
1011 |
+
'ip-address' => esc_html__( 'IP Address', 'wp-security-audit-log' ),
|
1012 |
);
|
1013 |
+
|
1014 |
asort( $objects );
|
1015 |
$objects = apply_filters(
|
1016 |
'wsal_event_objects',
|
1062 |
*/
|
1063 |
public function get_event_type_data( $type = '' ) {
|
1064 |
$types = array(
|
1065 |
+
'login' => esc_html__( 'Login', 'wp-security-audit-log' ),
|
1066 |
+
'logout' => esc_html__( 'Logout', 'wp-security-audit-log' ),
|
1067 |
+
'installed' => esc_html__( 'Installed', 'wp-security-audit-log' ),
|
1068 |
+
'activated' => esc_html__( 'Activated', 'wp-security-audit-log' ),
|
1069 |
+
'deactivated' => esc_html__( 'Deactivated', 'wp-security-audit-log' ),
|
1070 |
+
'uninstalled' => esc_html__( 'Uninstalled', 'wp-security-audit-log' ),
|
1071 |
+
'updated' => esc_html__( 'Updated', 'wp-security-audit-log' ),
|
1072 |
+
'created' => esc_html__( 'Created', 'wp-security-audit-log' ),
|
1073 |
+
'modified' => esc_html__( 'Modified', 'wp-security-audit-log' ),
|
1074 |
+
'deleted' => esc_html__( 'Deleted', 'wp-security-audit-log' ),
|
1075 |
+
'published' => esc_html__( 'Published', 'wp-security-audit-log' ),
|
1076 |
+
'approved' => esc_html__( 'Approved', 'wp-security-audit-log' ),
|
1077 |
+
'unapproved' => esc_html__( 'Unapproved', 'wp-security-audit-log' ),
|
1078 |
+
'enabled' => esc_html__( 'Enabled', 'wp-security-audit-log' ),
|
1079 |
+
'disabled' => esc_html__( 'Disabled', 'wp-security-audit-log' ),
|
1080 |
+
'added' => esc_html__( 'Added', 'wp-security-audit-log' ),
|
1081 |
+
'failed-login' => esc_html__( 'Failed Login', 'wp-security-audit-log' ),
|
1082 |
+
'blocked' => esc_html__( 'Blocked', 'wp-security-audit-log' ),
|
1083 |
+
'uploaded' => esc_html__( 'Uploaded', 'wp-security-audit-log' ),
|
1084 |
+
'restored' => esc_html__( 'Restored', 'wp-security-audit-log' ),
|
1085 |
+
'opened' => esc_html__( 'Opened', 'wp-security-audit-log' ),
|
1086 |
+
'viewed' => esc_html__( 'Viewed', 'wp-security-audit-log' ),
|
1087 |
+
'started' => esc_html__( 'Started', 'wp-security-audit-log' ),
|
1088 |
+
'stopped' => esc_html__( 'Stopped', 'wp-security-audit-log' ),
|
1089 |
+
'removed' => esc_html__( 'Removed', 'wp-security-audit-log' ),
|
1090 |
+
'unblocked' => esc_html__( 'Unblocked', 'wp-security-audit-log' ),
|
1091 |
+
'renamed' => esc_html__( 'Renamed', 'wp-security-audit-log' ),
|
1092 |
+
'duplicated' => esc_html__( 'Duplicated', 'wp-security-audit-log' ),
|
1093 |
+
'submitted' => esc_html__( 'Submitted', 'wp-security-audit-log' ),
|
1094 |
+
'revoked' => esc_html__( 'Revoked', 'wp-security-audit-log' ),
|
1095 |
);
|
1096 |
// sort the types alphabetically.
|
1097 |
asort( $types );
|
1133 |
* @return string
|
1134 |
*/
|
1135 |
public function get_display_event_type_text( $event_type ) {
|
1136 |
+
// Try to get string from the companion data method.
|
1137 |
return get_event_type_data( $event_type );
|
1138 |
}
|
1139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1140 |
/**
|
1141 |
* Return sub-categorized events of WSAL.
|
1142 |
*
|
1143 |
* @return array
|
1144 |
*/
|
1145 |
public function get_sub_categorized_events() {
|
1146 |
+
$cg_alerts = $this->get_categorized_alerts();
|
1147 |
$events = array();
|
1148 |
|
1149 |
foreach ( $cg_alerts as $group ) {
|
1195 |
}
|
1196 |
|
1197 |
// Get MainWP dashboard user ids.
|
1198 |
+
$result = $wpdb->get_results( $sql, ARRAY_A ); // phpcs:ignore
|
1199 |
|
1200 |
$users = array();
|
1201 |
if ( ! empty( $result ) ) {
|
1289 |
* @param string $context Display context.
|
1290 |
*
|
1291 |
* @return array|false Alert details.
|
|
|
1292 |
*/
|
1293 |
public function get_alert_details( $entry, $context = 'default' ) {
|
1294 |
$entry_id = $entry->id;
|
1312 |
$user_id = ( ! is_numeric( $user_id ) && null !== $user_id ) ? WSAL_Utilities_UsersUtils::swap_login_for_id( $user_id ) : $user_id;
|
1313 |
|
1314 |
// Get alert details.
|
1315 |
+
$code = $this->get_alert( $alert_id );
|
1316 |
$code = $code ? $code->severity : 0;
|
1317 |
$const = (object) array(
|
1318 |
'name' => 'E_UNKNOWN',
|
1319 |
'value' => 0,
|
1320 |
'description' => __( 'Unknown error code.', 'wp-security-audit-log' ),
|
1321 |
);
|
1322 |
+
$const = $this->plugin->constants->get_constant_by( 'value', $code, $const );
|
1323 |
|
1324 |
+
$blog_info = self::get_blog_info( $this->plugin, $site_id );
|
1325 |
|
1326 |
// Get the alert message - properly.
|
1327 |
$occurrence->id = $entry_id;
|
1336 |
$occurrence->post_id = $entry->post_id;
|
1337 |
$occurrence->post_type = $entry->post_type;
|
1338 |
$occurrence->post_status = $entry->post_status;
|
1339 |
+
$occurrence->set_user_roles( $roles );
|
1340 |
|
1341 |
+
$event_metadata = $occurrence->get_meta_array();
|
1342 |
+
if ( ! $occurrence->_cached_message ) {
|
1343 |
+
$occurrence->_cached_message = $occurrence->get_alert()->get_message( $event_metadata, null, $entry_id, $context );
|
1344 |
}
|
1345 |
|
1346 |
if ( ! $user_id ) {
|
1347 |
$username = __( 'System', 'wp-security-audit-log' );
|
1348 |
$roles = '';
|
1349 |
} else {
|
1350 |
+
$username = WSAL_Utilities_UsersUtils::get_username( $event_metadata );
|
1351 |
}
|
1352 |
|
1353 |
// Meta details.
|
1356 |
'blog_name' => $blog_info['name'],
|
1357 |
'blog_url' => $blog_info['url'],
|
1358 |
'alert_id' => $alert_id,
|
1359 |
+
'date' => WSAL_Utilities_DateTimeFormatter::instance()->get_formatted_date_time( $created_on ),
|
1360 |
// We need to keep the timestamp to be able to group entries by dates etc. The "date" field is not suitable
|
1361 |
// as it is already translated, thus difficult to parse and process.
|
1362 |
'timestamp' => $created_on,
|
1363 |
'code' => $const->name,
|
1364 |
// Fill variables in message.
|
1365 |
+
'message' => $occurrence->get_message( $event_metadata, $context ),
|
1366 |
'user_id' => $user_id,
|
1367 |
'user_name' => $username,
|
1368 |
'user_data' => $user_id ? $this->get_event_user_data( $username ) : false,
|
1386 |
*/
|
1387 |
public static function get_blog_info( $plugin, $site_id ) {
|
1388 |
// Blog details.
|
1389 |
+
if ( $plugin->is_multisite() ) {
|
1390 |
$blog_info = get_blog_details( $site_id, true );
|
1391 |
$blog_name = esc_html__( 'Unknown Site', 'wp-security-audit-log' );
|
1392 |
$blog_url = '';
|
1423 |
public function get_wp_users(): array {
|
1424 |
return $this->wp_users;
|
1425 |
}
|
1426 |
+
|
1427 |
+
/**
|
1428 |
+
* Deprecated placeholder function.
|
1429 |
+
*
|
1430 |
+
* @param integer $type - Alert type.
|
1431 |
+
* @param array $data - Alert data.
|
1432 |
+
* @param mixed $delayed - False if delayed, function if not.
|
1433 |
+
*
|
1434 |
+
* @deprecated 4.4.1 Replaced by function trigger_event.
|
1435 |
+
*
|
1436 |
+
* @see WSAL_AlertManager::trigger_event()
|
1437 |
+
*
|
1438 |
+
* @phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
|
1439 |
+
*/
|
1440 |
+
public function Trigger( $type, $data = array(), $delayed = false ) {
|
1441 |
+
$this->trigger_event( $type, $data, $delayed );
|
1442 |
+
}
|
1443 |
+
|
1444 |
+
/**
|
1445 |
+
* Deprecated placeholder function.
|
1446 |
+
*
|
1447 |
+
* @param integer $type - Alert type ID.
|
1448 |
+
* @param array $data - Alert data.
|
1449 |
+
* @param callable $cond - A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
1450 |
+
*
|
1451 |
+
* @deprecated 4.4.1 Replaced by function trigger_event_if.
|
1452 |
+
*
|
1453 |
+
* @see WSAL_AlertManager::trigger_event_if()
|
1454 |
+
*
|
1455 |
+
* @phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
|
1456 |
+
*/
|
1457 |
+
public function TriggerIf( $type, $data, $cond = null ) {
|
1458 |
+
$this->trigger_event_if( $type, $data, $cond );
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
/**
|
1462 |
+
* Deprecated placeholder function.
|
1463 |
+
*
|
1464 |
+
* @param integer $type - Alert type ID.
|
1465 |
+
* @param int $count - A minimum number of event occurrences.
|
1466 |
+
*
|
1467 |
+
* @return boolean
|
1468 |
+
*
|
1469 |
+
* @deprecated 4.4.1 Replaced by function will_trigger.
|
1470 |
+
* @see WSAL_AlertManager::will_trigger()
|
1471 |
+
*
|
1472 |
+
* @phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
|
1473 |
+
*/
|
1474 |
+
public function WillTrigger( $type, $count = 1 ) {
|
1475 |
+
return $this->will_trigger( $type, $count );
|
1476 |
+
}
|
1477 |
+
|
1478 |
+
/**
|
1479 |
+
* Deprecated placeholder function.
|
1480 |
+
*
|
1481 |
+
* @param int $type - Alert type ID.
|
1482 |
+
* @param int $count - A minimum number of event occurrences.
|
1483 |
+
*
|
1484 |
+
* @return boolean
|
1485 |
+
*
|
1486 |
+
* @deprecated 4.4.1 Replaced by function will_or_has_triggered.
|
1487 |
+
* @see WSAL_AlertManager::will_or_has_triggered()
|
1488 |
+
*
|
1489 |
+
* @phpcs:disable WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
|
1490 |
+
*/
|
1491 |
+
public function WillOrHasTriggered( $type, $count = 1 ) {
|
1492 |
+
return $this->will_or_has_triggered( $type, $count );
|
1493 |
+
}
|
1494 |
}
|
classes/AuditLogGridView.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* CLass file for audit log list view.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -19,7 +19,7 @@ require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
|
|
19 |
/**
|
20 |
* This view is included in Audit Log Viewer Page.
|
21 |
*
|
22 |
-
* @see
|
23 |
* @package wsal
|
24 |
*/
|
25 |
class WSAL_AuditLogGridView extends WP_List_Table {
|
@@ -29,7 +29,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
29 |
*
|
30 |
* @var WpSecurityAuditLog
|
31 |
*/
|
32 |
-
protected $
|
33 |
|
34 |
/**
|
35 |
* Current Alert ID
|
@@ -78,6 +78,8 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
78 |
private $item_meta = array();
|
79 |
|
80 |
/**
|
|
|
|
|
81 |
* @var WSAL_Views_AuditLog
|
82 |
* @since 4.3.2
|
83 |
*/
|
@@ -86,12 +88,12 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
86 |
/**
|
87 |
* Method: Constructor.
|
88 |
*
|
89 |
-
* @param WpSecurityAuditLog
|
90 |
* @param WSAL_Views_AuditLog $audit_log_view Audit log view.
|
91 |
-
* @param stdClass
|
92 |
*/
|
93 |
public function __construct( $plugin, $audit_log_view, $query_args ) {
|
94 |
-
$this->
|
95 |
$this->audit_log_view = $audit_log_view;
|
96 |
$this->query_args = $query_args;
|
97 |
|
@@ -106,22 +108,21 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
106 |
}
|
107 |
|
108 |
/**
|
109 |
-
*
|
110 |
*/
|
111 |
public function no_items() {
|
112 |
esc_html_e( 'No events so far.', 'wp-security-audit-log' );
|
113 |
}
|
114 |
|
115 |
-
|
|
|
|
|
116 |
protected function get_table_classes() {
|
117 |
return array( 'widefat', 'fixed', 'striped', $this->_args['plural'], 'wsal-table', 'wsal-table-grid' );
|
118 |
}
|
119 |
|
120 |
/**
|
121 |
-
*
|
122 |
-
*
|
123 |
-
* @since 3.2.3
|
124 |
-
* @param string $which – Position of the nav.
|
125 |
*/
|
126 |
protected function display_tablenav( $which ) {
|
127 |
if ( 'top' === $which ) {
|
@@ -144,7 +145,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
144 |
?>
|
145 |
<div class="display-type-buttons">
|
146 |
<?php
|
147 |
-
$user_selected_view = $this->
|
148 |
?>
|
149 |
<a id ="wsal-list-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'list' ) ); ?>" class="button wsal-button dashicons-before dashicons-list-view" <?php echo ( 'list' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'List View', 'wp-security-audit-log' ); ?></a>
|
150 |
<a id ="wsal-grid-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'grid' ) ); ?>" class="button wsal-button dashicons-before dashicons-grid-view" <?php echo ( 'grid' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'Grid View', 'wp-security-audit-log' ); ?></a>
|
@@ -157,15 +158,13 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
157 |
}
|
158 |
|
159 |
/**
|
160 |
-
*
|
161 |
-
*
|
162 |
-
* @param string $which - Position of the nav.
|
163 |
*/
|
164 |
public function extra_tablenav( $which ) {
|
165 |
// If the position is not top then render.
|
166 |
-
if ( 'top' !== $which && ! $this->
|
167 |
// Items-per-page widget.
|
168 |
-
$p = $this->
|
169 |
$items = array( 5, 10, 15, 30, 50 );
|
170 |
if ( ! in_array( $p, $items, true ) ) {
|
171 |
$items[] = $p;
|
@@ -185,7 +184,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
185 |
<?php
|
186 |
endif;
|
187 |
|
188 |
-
if ( 'top' !== $which && $this->
|
189 |
?>
|
190 |
<div id="wsal-auditlog-end"><p><?php esc_html_e( '— End of Activity Log —', 'wp-security-audit-log' ); ?></p></div>
|
191 |
<div id="wsal-event-loader"><div class="wsal-lds-ellipsis"><div></div><div></div><div></div><div></div></div></div>
|
@@ -196,10 +195,10 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
196 |
// NOTE: this is shown when the filter IS NOT true.
|
197 |
if ( $this->is_multisite() && $this->is_main_blog() && ! apply_filters( 'search_extensition_active', false ) ) {
|
198 |
if (
|
199 |
-
( 'top' === $which && $this->
|
200 |
-
|| ! $this->
|
201 |
) {
|
202 |
-
$curr = $this->
|
203 |
?>
|
204 |
<div class="wsal-ssa wsal-ssa-<?php echo esc_attr( $which ); ?>">
|
205 |
<?php if ( $this->get_site_count() > 15 ) : ?>
|
@@ -210,7 +209,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
210 |
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
211 |
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
212 |
<?php foreach ( $this->get_sites() as $info ) : ?>
|
213 |
-
<option value="<?php echo esc_attr( $info->blog_id ); ?>" <?php echo ( $info->blog_id
|
214 |
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
215 |
</option>
|
216 |
<?php endforeach; ?>
|
@@ -238,7 +237,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
238 |
}
|
239 |
|
240 |
// Execute query.
|
241 |
-
$res = $wpdb->get_results( $sql );
|
242 |
|
243 |
// Modify result.
|
244 |
foreach ( $res as $row ) {
|
@@ -257,13 +256,11 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
257 |
public function get_site_count() {
|
258 |
global $wpdb;
|
259 |
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
260 |
-
return (int) $wpdb->get_var( $sql );
|
261 |
}
|
262 |
|
263 |
/**
|
264 |
-
*
|
265 |
-
*
|
266 |
-
* @return array
|
267 |
*/
|
268 |
public function get_columns() {
|
269 |
|
@@ -282,7 +279,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
282 |
|
283 |
// Get selected columns from settings.
|
284 |
if ( empty( $this->selected_columns ) && ! is_array( $this->selected_columns ) ) {
|
285 |
-
$this->selected_columns = $this->
|
286 |
}
|
287 |
|
288 |
// If selected columns are not empty, then unset default columns.
|
@@ -303,9 +300,9 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
303 |
case 'message':
|
304 |
$cols['mesg'] = __( 'Message', 'wp-security-audit-log' );
|
305 |
break;
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
}
|
310 |
}
|
311 |
}
|
@@ -314,19 +311,14 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
314 |
}
|
315 |
|
316 |
/**
|
317 |
-
*
|
318 |
-
*
|
319 |
-
* @param object $item - Item.
|
320 |
-
* @return string
|
321 |
*/
|
322 |
public function column_cb( $item ) {
|
323 |
return '<input type="checkbox" value="' . $item->id . '" name="' . esc_attr( $this->_args['singular'] ) . '[]" />';
|
324 |
}
|
325 |
|
326 |
/**
|
327 |
-
*
|
328 |
-
*
|
329 |
-
* @return array
|
330 |
*/
|
331 |
public function get_sortable_columns() {
|
332 |
return array(
|
@@ -336,15 +328,12 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
336 |
}
|
337 |
|
338 |
/**
|
339 |
-
*
|
340 |
-
*
|
341 |
-
* @param WSAL_Models_Occurrence $item - Column item.
|
342 |
-
* @param string $column_name - Name of the column.
|
343 |
*/
|
344 |
public function column_default( $item, $column_name ) {
|
345 |
// Store meta if not set.
|
346 |
-
if ( ! isset( $this->item_meta[ $item->
|
347 |
-
$this->item_meta[ $item->
|
348 |
}
|
349 |
|
350 |
// Store current alert id.
|
@@ -352,7 +341,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
352 |
|
353 |
switch ( $column_name ) {
|
354 |
case 'type':
|
355 |
-
$code = $this->
|
356 |
$extra_msg = '';
|
357 |
$data_link = '';
|
358 |
$modification_alerts = array( 1002, 1003 );
|
@@ -361,7 +350,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
361 |
$data_link = add_query_arg( 'page', 'wsal-togglealerts#tab-users-profiles---activity', admin_url( 'admin.php' ) );
|
362 |
}
|
363 |
|
364 |
-
if ( ! $this->
|
365 |
return '<span class="log-disable">' . str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
366 |
}
|
367 |
// add description to $extra_msg only if one is available.
|
@@ -370,13 +359,13 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
370 |
. str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
371 |
|
372 |
case 'code':
|
373 |
-
$code = $this->
|
374 |
$code = $code ? $code->severity : 0;
|
375 |
-
$const = $this->
|
376 |
|
377 |
-
$css_classes =
|
378 |
-
if (property_exists($const, 'css')) {
|
379 |
-
array_push($css_classes, 'log-type-' . $const->css);
|
380 |
}
|
381 |
return '<a class="tooltip" href="#" data-tooltip="' . esc_html( $const->name ) . '"><span class="' . implode( ' ', $css_classes ) . '"></span></a>';
|
382 |
case 'site':
|
@@ -386,48 +375,49 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
386 |
case 'mesg':
|
387 |
// login, logout and failed login have no message attached.
|
388 |
if ( ! in_array( $item->alert_id, array( 1000, 1001, 1002 ), true ) ) {
|
389 |
-
$event_meta = $this->item_meta[ $item->
|
390 |
-
$result
|
391 |
-
$result
|
392 |
-
$result
|
393 |
-
$result
|
394 |
-
$result
|
395 |
return $result;
|
396 |
}
|
397 |
return '';
|
398 |
case 'info':
|
399 |
$eventdate = $item->created_on
|
400 |
-
|
401 |
-
|
402 |
|
403 |
$eventtime = $item->created_on
|
404 |
-
|
405 |
-
|
406 |
|
407 |
-
$username = WSAL_Utilities_UsersUtils::
|
408 |
$user = get_user_by( 'login', $username ); // Get user.
|
409 |
if ( empty( $this->name_type ) ) {
|
410 |
-
$this->name_type = $this->
|
411 |
}
|
412 |
|
413 |
// Check if the username and user exists.
|
414 |
if ( $username && $user ) {
|
415 |
|
416 |
-
$display_name
|
417 |
$user_edit_link = admin_url( 'user-edit.php?user_id=' . $user->ID );
|
418 |
-
|
419 |
// Additional user info tooltip.
|
420 |
$tooltip = WSAL_Utilities_UsersUtils::get_tooltip_user_content( $user );
|
421 |
-
$uhtml
|
422 |
|
423 |
-
|
424 |
-
|
|
|
425 |
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
426 |
$roles = '';
|
427 |
-
} elseif ( 'Plugins'
|
428 |
$uhtml = '<i>' . __( 'Plugins', 'wp-security-audit-log' ) . '</i>';
|
429 |
$roles = '';
|
430 |
-
} elseif ( 'Website Visitor'
|
431 |
$uhtml = '<i>' . __( 'Unregistered user', 'wp-security-audit-log' ) . '</i>';
|
432 |
$roles = '';
|
433 |
} else {
|
@@ -448,9 +438,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
448 |
*/
|
449 |
$eventuser = apply_filters( 'wsal_auditlog_row_user_data', $row_user_data, $this->current_alert_id );
|
450 |
|
451 |
-
|
452 |
-
|
453 |
-
$scip = $item->GetSourceIP();
|
454 |
if ( is_string( $scip ) ) {
|
455 |
$scip = str_replace( array( '"', '[', ']' ), '', $scip );
|
456 |
}
|
@@ -458,7 +446,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
458 |
$oips = array();
|
459 |
|
460 |
// If there's no IP...
|
461 |
-
if ( is_null( $scip ) || ''
|
462 |
return '<i>unknown</i>';
|
463 |
}
|
464 |
|
@@ -482,7 +470,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
482 |
|
483 |
$ip_html = "<a class='search-ip' data-tooltip='$tooltip' data-ip='$scip' target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
484 |
foreach ( $oips as $ip ) {
|
485 |
-
if ( $scip != $ip ) {
|
486 |
$ip_html .= '<div>' . $ip . '</div>';
|
487 |
}
|
488 |
}
|
@@ -490,45 +478,43 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
490 |
} else {
|
491 |
$ip_html = "<a target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
492 |
foreach ( $oips as $ip ) {
|
493 |
-
if ( $scip != $ip ) {
|
494 |
$ip_html .= '<div>' . $ip . '</div>';
|
495 |
}
|
496 |
}
|
497 |
$ip_html .= '</div>';
|
498 |
}
|
499 |
|
|
|
500 |
|
501 |
-
|
502 |
-
$eventobj = isset( $this->item_meta[ $item->getId() ]['Object'] ) ? $this->_plugin->alerts->get_event_objects_data( $this->item_meta[ $item->getId() ]['Object'] ) : '';
|
503 |
-
|
504 |
-
$eventtypeobj = isset( $this->item_meta[ $item->getId() ]['EventType'] ) ? $this->_plugin->alerts->get_event_type_data( $this->item_meta[ $item->getId() ]['EventType'] ) : '';
|
505 |
|
506 |
ob_start();
|
507 |
?>
|
508 |
<table>
|
509 |
<tr>
|
510 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Date:' ); ?></td>
|
511 |
-
<td class="wsal-grid-text-data"><?php echo $eventdate; ?></td>
|
512 |
</tr>
|
513 |
<tr>
|
514 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Time:' ); ?></td>
|
515 |
-
<td class="wsal-grid-text-data"><?php echo $eventtime; ?></td>
|
516 |
</tr>
|
517 |
<tr>
|
518 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'User:' ); ?></td>
|
519 |
-
<td class="wsal-grid-text-data"><?php echo $eventuser; ?></td>
|
520 |
</tr>
|
521 |
<tr>
|
522 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'IP:' ); ?></td>
|
523 |
-
<td class="wsal-grid-text-data"><?php echo ( isset( $oips_html ) && ! empty( $oips_html ) ) ? $oips_html : $ip_html ?></td>
|
524 |
</tr>
|
525 |
<tr>
|
526 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Object:' ); ?></td>
|
527 |
-
<td class="wsal-grid-text-data"><?php echo $eventobj; ?></td>
|
528 |
</tr>
|
529 |
<tr>
|
530 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Event Type:' ); ?></td>
|
531 |
-
<td class="wsal-grid-text-data"><?php echo $eventtypeobj; ?></td>
|
532 |
</tr>
|
533 |
</table>
|
534 |
<?php
|
@@ -575,7 +561,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
575 |
* @return bool
|
576 |
*/
|
577 |
protected function is_multisite() {
|
578 |
-
return $this->
|
579 |
}
|
580 |
|
581 |
/**
|
@@ -584,7 +570,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
584 |
* @return bool
|
585 |
*/
|
586 |
protected function is_main_blog() {
|
587 |
-
return get_current_blog_id()
|
588 |
}
|
589 |
|
590 |
/**
|
@@ -593,7 +579,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
593 |
* @return bool
|
594 |
*/
|
595 |
protected function is_specific_view() {
|
596 |
-
return isset( $this->query_args->site_id ) && '0' != $this->query_args->site_id;
|
597 |
}
|
598 |
|
599 |
/**
|
@@ -641,7 +627,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
641 |
$total_items = isset( $query_events['total_items'] ) ? $query_events['total_items'] : false;
|
642 |
$per_page = isset( $query_events['per_page'] ) ? $query_events['per_page'] : false;
|
643 |
|
644 |
-
if ( ! $this->
|
645 |
$this->set_pagination_args(
|
646 |
array(
|
647 |
'total_items' => $total_items,
|
@@ -653,9 +639,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
653 |
}
|
654 |
|
655 |
/**
|
656 |
-
*
|
657 |
-
*
|
658 |
-
* @param object $item - Item.
|
659 |
*/
|
660 |
public function single_row( $item ) {
|
661 |
if ( 9999 === $item->alert_id ) {
|
@@ -668,17 +652,12 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
668 |
}
|
669 |
|
670 |
/**
|
671 |
-
*
|
672 |
-
*
|
673 |
-
* @static var int $cb_counter
|
674 |
-
*
|
675 |
-
* @param bool $with_id – Whether to set the id attribute or not.
|
676 |
-
* @since 3.2.3
|
677 |
*/
|
678 |
public function print_column_headers( $with_id = true ) {
|
679 |
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
|
680 |
|
681 |
-
$current_url = set_url_scheme( esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) );
|
682 |
$current_url = remove_query_arg( 'paged', $current_url );
|
683 |
|
684 |
// Set order by query arg.
|
@@ -704,13 +683,13 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
704 |
foreach ( $columns as $column_key => $column_display_name ) {
|
705 |
$class = array( 'manage-column', "column-$column_key" );
|
706 |
|
707 |
-
if ( in_array( $column_key, $hidden ) ) {
|
708 |
$class[] = 'hidden';
|
709 |
}
|
710 |
|
711 |
if ( 'cb' === $column_key ) {
|
712 |
$class[] = 'check-column';
|
713 |
-
} elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) {
|
714 |
$class[] = 'num';
|
715 |
}
|
716 |
|
@@ -742,7 +721,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
742 |
$class = "class='" . implode( ' ', $class ) . "'";
|
743 |
}
|
744 |
|
745 |
-
echo "<$tag $scope $id $class>";
|
746 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '<div class="wsal-filter-wrap">' : '';
|
747 |
|
748 |
if ( $with_id ) {
|
@@ -757,9 +736,9 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
757 |
do_action( 'wsal_audit_log_column_header', $column_key );
|
758 |
}
|
759 |
|
760 |
-
echo $column_display_name;
|
761 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '</div>' : '';
|
762 |
-
echo "</$tag>";
|
763 |
}
|
764 |
}
|
765 |
|
@@ -787,7 +766,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
787 |
|
788 |
$bid = (int) $this->query_args->site_id;
|
789 |
if ( $bid ) {
|
790 |
-
$query->
|
791 |
}
|
792 |
|
793 |
/**
|
@@ -801,9 +780,9 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
801 |
*/
|
802 |
$query = apply_filters( 'wsal_auditlog_query', $query );
|
803 |
|
804 |
-
if ( ! $this->
|
805 |
-
$total_items = $query->
|
806 |
-
$per_page = $this->
|
807 |
$offset = ( $this->get_pagenum() - 1 ) * $per_page;
|
808 |
} else {
|
809 |
$total_items = false;
|
@@ -816,7 +795,7 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
816 |
$order = isset( $this->query_args->order ) ? $this->query_args->order : false;
|
817 |
|
818 |
if ( ! $order_by ) {
|
819 |
-
$query->
|
820 |
} else {
|
821 |
$is_descending = true;
|
822 |
if ( $order && 'asc' === $order ) {
|
@@ -827,30 +806,30 @@ class WSAL_AuditLogGridView extends WP_List_Table {
|
|
827 |
/*
|
828 |
* Handle the 'code' (Severity) column sorting.
|
829 |
*/
|
830 |
-
$query->
|
831 |
-
$query->
|
832 |
-
$query->
|
833 |
} elseif ( 'info' === $order_by ) {
|
834 |
// for the info col we are ordering just by dates.
|
835 |
-
$query->
|
836 |
} else {
|
837 |
$tmp = new WSAL_Models_Occurrence();
|
838 |
// Making sure the field exists to order by.
|
839 |
if ( isset( $tmp->{$order_by} ) ) {
|
840 |
-
$query->
|
841 |
} else {
|
842 |
-
$query->
|
843 |
}
|
844 |
}
|
845 |
}
|
846 |
|
847 |
-
$query->
|
848 |
-
$query->
|
849 |
|
850 |
return array(
|
851 |
'total_items' => $total_items,
|
852 |
'per_page' => $per_page,
|
853 |
-
'items' => $query->
|
854 |
);
|
855 |
}
|
856 |
}
|
4 |
*
|
5 |
* CLass file for audit log list view.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
19 |
/**
|
20 |
* This view is included in Audit Log Viewer Page.
|
21 |
*
|
22 |
+
* @see Views/AuditLog.php
|
23 |
* @package wsal
|
24 |
*/
|
25 |
class WSAL_AuditLogGridView extends WP_List_Table {
|
29 |
*
|
30 |
* @var WpSecurityAuditLog
|
31 |
*/
|
32 |
+
protected $plugin;
|
33 |
|
34 |
/**
|
35 |
* Current Alert ID
|
78 |
private $item_meta = array();
|
79 |
|
80 |
/**
|
81 |
+
* Audit log view.
|
82 |
+
*
|
83 |
* @var WSAL_Views_AuditLog
|
84 |
* @since 4.3.2
|
85 |
*/
|
88 |
/**
|
89 |
* Method: Constructor.
|
90 |
*
|
91 |
+
* @param WpSecurityAuditLog $plugin Instance of WpSecurityAuditLog.
|
92 |
* @param WSAL_Views_AuditLog $audit_log_view Audit log view.
|
93 |
+
* @param stdClass $query_args Events query arguments.
|
94 |
*/
|
95 |
public function __construct( $plugin, $audit_log_view, $query_args ) {
|
96 |
+
$this->plugin = $plugin;
|
97 |
$this->audit_log_view = $audit_log_view;
|
98 |
$this->query_args = $query_args;
|
99 |
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
+
* {@inheritDoc}
|
112 |
*/
|
113 |
public function no_items() {
|
114 |
esc_html_e( 'No events so far.', 'wp-security-audit-log' );
|
115 |
}
|
116 |
|
117 |
+
/**
|
118 |
+
* {@inheritDoc}
|
119 |
+
*/
|
120 |
protected function get_table_classes() {
|
121 |
return array( 'widefat', 'fixed', 'striped', $this->_args['plural'], 'wsal-table', 'wsal-table-grid' );
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
126 |
*/
|
127 |
protected function display_tablenav( $which ) {
|
128 |
if ( 'top' === $which ) {
|
145 |
?>
|
146 |
<div class="display-type-buttons">
|
147 |
<?php
|
148 |
+
$user_selected_view = $this->plugin->views->views[0]->detect_view_type();
|
149 |
?>
|
150 |
<a id ="wsal-list-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'list' ) ); ?>" class="button wsal-button dashicons-before dashicons-list-view" <?php echo ( 'list' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'List View', 'wp-security-audit-log' ); ?></a>
|
151 |
<a id ="wsal-grid-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'grid' ) ); ?>" class="button wsal-button dashicons-before dashicons-grid-view" <?php echo ( 'grid' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'Grid View', 'wp-security-audit-log' ); ?></a>
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
+
* {@inheritDoc}
|
|
|
|
|
162 |
*/
|
163 |
public function extra_tablenav( $which ) {
|
164 |
// If the position is not top then render.
|
165 |
+
if ( 'top' !== $which && ! $this->plugin->settings()->is_infinite_scroll() ) :
|
166 |
// Items-per-page widget.
|
167 |
+
$p = $this->plugin->settings()->get_views_per_page();
|
168 |
$items = array( 5, 10, 15, 30, 50 );
|
169 |
if ( ! in_array( $p, $items, true ) ) {
|
170 |
$items[] = $p;
|
184 |
<?php
|
185 |
endif;
|
186 |
|
187 |
+
if ( 'top' !== $which && $this->plugin->settings()->is_infinite_scroll() ) :
|
188 |
?>
|
189 |
<div id="wsal-auditlog-end"><p><?php esc_html_e( '— End of Activity Log —', 'wp-security-audit-log' ); ?></p></div>
|
190 |
<div id="wsal-event-loader"><div class="wsal-lds-ellipsis"><div></div><div></div><div></div><div></div></div></div>
|
195 |
// NOTE: this is shown when the filter IS NOT true.
|
196 |
if ( $this->is_multisite() && $this->is_main_blog() && ! apply_filters( 'search_extensition_active', false ) ) {
|
197 |
if (
|
198 |
+
( 'top' === $which && $this->plugin->settings()->is_infinite_scroll() )
|
199 |
+
|| ! $this->plugin->settings()->is_infinite_scroll()
|
200 |
) {
|
201 |
+
$curr = $this->plugin->settings()->get_view_site_id();
|
202 |
?>
|
203 |
<div class="wsal-ssa wsal-ssa-<?php echo esc_attr( $which ); ?>">
|
204 |
<?php if ( $this->get_site_count() > 15 ) : ?>
|
209 |
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
210 |
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
211 |
<?php foreach ( $this->get_sites() as $info ) : ?>
|
212 |
+
<option value="<?php echo esc_attr( $info->blog_id ); ?>" <?php echo ( $info->blog_id === $curr ) ? 'selected="selected"' : false; ?>>
|
213 |
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
214 |
</option>
|
215 |
<?php endforeach; ?>
|
237 |
}
|
238 |
|
239 |
// Execute query.
|
240 |
+
$res = $wpdb->get_results( $sql ); // phpcs:ignore
|
241 |
|
242 |
// Modify result.
|
243 |
foreach ( $res as $row ) {
|
256 |
public function get_site_count() {
|
257 |
global $wpdb;
|
258 |
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
259 |
+
return (int) $wpdb->get_var( $sql ); // phpcs:ignore
|
260 |
}
|
261 |
|
262 |
/**
|
263 |
+
* {@inheritDoc}
|
|
|
|
|
264 |
*/
|
265 |
public function get_columns() {
|
266 |
|
279 |
|
280 |
// Get selected columns from settings.
|
281 |
if ( empty( $this->selected_columns ) && ! is_array( $this->selected_columns ) ) {
|
282 |
+
$this->selected_columns = $this->plugin->settings()->get_columns_selected();
|
283 |
}
|
284 |
|
285 |
// If selected columns are not empty, then unset default columns.
|
300 |
case 'message':
|
301 |
$cols['mesg'] = __( 'Message', 'wp-security-audit-log' );
|
302 |
break;
|
303 |
+
default:
|
304 |
+
// Fallback for any new columns would go here.
|
305 |
+
break;
|
306 |
}
|
307 |
}
|
308 |
}
|
311 |
}
|
312 |
|
313 |
/**
|
314 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
315 |
*/
|
316 |
public function column_cb( $item ) {
|
317 |
return '<input type="checkbox" value="' . $item->id . '" name="' . esc_attr( $this->_args['singular'] ) . '[]" />';
|
318 |
}
|
319 |
|
320 |
/**
|
321 |
+
* {@inheritDoc}
|
|
|
|
|
322 |
*/
|
323 |
public function get_sortable_columns() {
|
324 |
return array(
|
328 |
}
|
329 |
|
330 |
/**
|
331 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
332 |
*/
|
333 |
public function column_default( $item, $column_name ) {
|
334 |
// Store meta if not set.
|
335 |
+
if ( ! isset( $this->item_meta[ $item->get_id() ] ) ) {
|
336 |
+
$this->item_meta[ $item->get_id() ] = $item->get_meta_array();
|
337 |
}
|
338 |
|
339 |
// Store current alert id.
|
341 |
|
342 |
switch ( $column_name ) {
|
343 |
case 'type':
|
344 |
+
$code = $this->plugin->alerts->get_alert( $item->alert_id );
|
345 |
$extra_msg = '';
|
346 |
$data_link = '';
|
347 |
$modification_alerts = array( 1002, 1003 );
|
350 |
$data_link = add_query_arg( 'page', 'wsal-togglealerts#tab-users-profiles---activity', admin_url( 'admin.php' ) );
|
351 |
}
|
352 |
|
353 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
354 |
return '<span class="log-disable">' . str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
355 |
}
|
356 |
// add description to $extra_msg only if one is available.
|
359 |
. str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
360 |
|
361 |
case 'code':
|
362 |
+
$code = $this->plugin->alerts->get_alert( $item->alert_id );
|
363 |
$code = $code ? $code->severity : 0;
|
364 |
+
$const = $this->plugin->constants->get_constant_to_display( $code );
|
365 |
|
366 |
+
$css_classes = array( 'log-type', 'log-type-' . $const->value );
|
367 |
+
if ( property_exists( $const, 'css' ) ) {
|
368 |
+
array_push( $css_classes, 'log-type-' . $const->css );
|
369 |
}
|
370 |
return '<a class="tooltip" href="#" data-tooltip="' . esc_html( $const->name ) . '"><span class="' . implode( ' ', $css_classes ) . '"></span></a>';
|
371 |
case 'site':
|
375 |
case 'mesg':
|
376 |
// login, logout and failed login have no message attached.
|
377 |
if ( ! in_array( $item->alert_id, array( 1000, 1001, 1002 ), true ) ) {
|
378 |
+
$event_meta = $this->item_meta[ $item->get_id() ];
|
379 |
+
$result = '<table id="Event' . absint( $item->id ) . '">';
|
380 |
+
$result .= '<td class="wsal-grid-text-header">' . esc_html__( 'Message:', 'wp-security-audit-log' ) . '</td>';
|
381 |
+
$result .= '<td class="wsal-grid-text-data">' . $item->get_message( $event_meta ) . '</td>';
|
382 |
+
$result .= '</table>';
|
383 |
+
$result .= $this->audit_log_view->maybe_build_teaser_html( $event_meta );
|
384 |
return $result;
|
385 |
}
|
386 |
return '';
|
387 |
case 'info':
|
388 |
$eventdate = $item->created_on
|
389 |
+
? WSAL_Utilities_DateTimeFormatter::instance()->get_formatted_date_time( $item->created_on, 'date' )
|
390 |
+
: '<i>' . __( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
391 |
|
392 |
$eventtime = $item->created_on
|
393 |
+
? WSAL_Utilities_DateTimeFormatter::instance()->get_formatted_date_time( $item->created_on, 'time' )
|
394 |
+
: '<i>' . __( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
395 |
|
396 |
+
$username = WSAL_Utilities_UsersUtils::get_username( $this->item_meta[ $item->get_id() ] ); // Get username.
|
397 |
$user = get_user_by( 'login', $username ); // Get user.
|
398 |
if ( empty( $this->name_type ) ) {
|
399 |
+
$this->name_type = $this->plugin->settings()->get_type_username();
|
400 |
}
|
401 |
|
402 |
// Check if the username and user exists.
|
403 |
if ( $username && $user ) {
|
404 |
|
405 |
+
$display_name = WSAL_Utilities_UsersUtils::get_display_label( $this->plugin, $user );
|
406 |
$user_edit_link = admin_url( 'user-edit.php?user_id=' . $user->ID );
|
407 |
+
|
408 |
// Additional user info tooltip.
|
409 |
$tooltip = WSAL_Utilities_UsersUtils::get_tooltip_user_content( $user );
|
410 |
+
$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>';
|
411 |
|
412 |
+
|
413 |
+
$roles = WSAL_Utilities_UsersUtils::get_roles_label( $item->get_user_roles() );
|
414 |
+
} elseif ( 'Plugin' === $username ) {
|
415 |
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
416 |
$roles = '';
|
417 |
+
} elseif ( 'Plugins' === $username ) {
|
418 |
$uhtml = '<i>' . __( 'Plugins', 'wp-security-audit-log' ) . '</i>';
|
419 |
$roles = '';
|
420 |
+
} elseif ( 'Website Visitor' === $username || 'Unregistered user' === $username ) {
|
421 |
$uhtml = '<i>' . __( 'Unregistered user', 'wp-security-audit-log' ) . '</i>';
|
422 |
$roles = '';
|
423 |
} else {
|
438 |
*/
|
439 |
$eventuser = apply_filters( 'wsal_auditlog_row_user_data', $row_user_data, $this->current_alert_id );
|
440 |
|
441 |
+
$scip = $item->get_source_ip();
|
|
|
|
|
442 |
if ( is_string( $scip ) ) {
|
443 |
$scip = str_replace( array( '"', '[', ']' ), '', $scip );
|
444 |
}
|
446 |
$oips = array();
|
447 |
|
448 |
// If there's no IP...
|
449 |
+
if ( is_null( $scip ) || '' === $scip ) {
|
450 |
return '<i>unknown</i>';
|
451 |
}
|
452 |
|
470 |
|
471 |
$ip_html = "<a class='search-ip' data-tooltip='$tooltip' data-ip='$scip' target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
472 |
foreach ( $oips as $ip ) {
|
473 |
+
if ( $scip != $ip ) { // phpcs:ignore
|
474 |
$ip_html .= '<div>' . $ip . '</div>';
|
475 |
}
|
476 |
}
|
478 |
} else {
|
479 |
$ip_html = "<a target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
480 |
foreach ( $oips as $ip ) {
|
481 |
+
if ( $scip != $ip ) { // phpcs:ignore
|
482 |
$ip_html .= '<div>' . $ip . '</div>';
|
483 |
}
|
484 |
}
|
485 |
$ip_html .= '</div>';
|
486 |
}
|
487 |
|
488 |
+
$eventobj = isset( $this->item_meta[ $item->get_id() ]['Object'] ) ? $this->plugin->alerts->get_event_objects_data( $this->item_meta[ $item->get_id() ]['Object'] ) : '';
|
489 |
|
490 |
+
$eventtypeobj = isset( $this->item_meta[ $item->get_id() ]['EventType'] ) ? $this->plugin->alerts->get_event_type_data( $this->item_meta[ $item->get_id() ]['EventType'] ) : '';
|
|
|
|
|
|
|
491 |
|
492 |
ob_start();
|
493 |
?>
|
494 |
<table>
|
495 |
<tr>
|
496 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Date:' ); ?></td>
|
497 |
+
<td class="wsal-grid-text-data"><?php echo $eventdate; // phpcs:ignore ?></td>
|
498 |
</tr>
|
499 |
<tr>
|
500 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Time:' ); ?></td>
|
501 |
+
<td class="wsal-grid-text-data"><?php echo $eventtime; // phpcs:ignore ?></td>
|
502 |
</tr>
|
503 |
<tr>
|
504 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'User:' ); ?></td>
|
505 |
+
<td class="wsal-grid-text-data"><?php echo $eventuser; // phpcs:ignore ?></td>
|
506 |
</tr>
|
507 |
<tr>
|
508 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'IP:' ); ?></td>
|
509 |
+
<td class="wsal-grid-text-data"><?php echo ( isset( $oips_html ) && ! empty( $oips_html ) ) ? $oips_html : $ip_html; // phpcs:ignore ?></td>
|
510 |
</tr>
|
511 |
<tr>
|
512 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Object:' ); ?></td>
|
513 |
+
<td class="wsal-grid-text-data"><?php echo $eventobj; // phpcs:ignore ?></td>
|
514 |
</tr>
|
515 |
<tr>
|
516 |
<td class="wsal-grid-text-header"><?php esc_html_e( 'Event Type:' ); ?></td>
|
517 |
+
<td class="wsal-grid-text-data"><?php echo $eventtypeobj; // phpcs:ignore ?></td>
|
518 |
</tr>
|
519 |
</table>
|
520 |
<?php
|
561 |
* @return bool
|
562 |
*/
|
563 |
protected function is_multisite() {
|
564 |
+
return $this->plugin->is_multisite();
|
565 |
}
|
566 |
|
567 |
/**
|
570 |
* @return bool
|
571 |
*/
|
572 |
protected function is_main_blog() {
|
573 |
+
return get_current_blog_id() === 1;
|
574 |
}
|
575 |
|
576 |
/**
|
579 |
* @return bool
|
580 |
*/
|
581 |
protected function is_specific_view() {
|
582 |
+
return isset( $this->query_args->site_id ) && '0' != $this->query_args->site_id; // phpcs:ignore
|
583 |
}
|
584 |
|
585 |
/**
|
627 |
$total_items = isset( $query_events['total_items'] ) ? $query_events['total_items'] : false;
|
628 |
$per_page = isset( $query_events['per_page'] ) ? $query_events['per_page'] : false;
|
629 |
|
630 |
+
if ( ! $this->plugin->settings()->is_infinite_scroll() ) {
|
631 |
$this->set_pagination_args(
|
632 |
array(
|
633 |
'total_items' => $total_items,
|
639 |
}
|
640 |
|
641 |
/**
|
642 |
+
* {@inheritDoc}
|
|
|
|
|
643 |
*/
|
644 |
public function single_row( $item ) {
|
645 |
if ( 9999 === $item->alert_id ) {
|
652 |
}
|
653 |
|
654 |
/**
|
655 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
|
|
|
|
656 |
*/
|
657 |
public function print_column_headers( $with_id = true ) {
|
658 |
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
|
659 |
|
660 |
+
$current_url = set_url_scheme( esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) ); // phpcs:ignore
|
661 |
$current_url = remove_query_arg( 'paged', $current_url );
|
662 |
|
663 |
// Set order by query arg.
|
683 |
foreach ( $columns as $column_key => $column_display_name ) {
|
684 |
$class = array( 'manage-column', "column-$column_key" );
|
685 |
|
686 |
+
if ( in_array( $column_key, $hidden, true ) ) {
|
687 |
$class[] = 'hidden';
|
688 |
}
|
689 |
|
690 |
if ( 'cb' === $column_key ) {
|
691 |
$class[] = 'check-column';
|
692 |
+
} elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ), true ) ) {
|
693 |
$class[] = 'num';
|
694 |
}
|
695 |
|
721 |
$class = "class='" . implode( ' ', $class ) . "'";
|
722 |
}
|
723 |
|
724 |
+
echo "<$tag $scope $id $class>"; // phpcs:ignore
|
725 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '<div class="wsal-filter-wrap">' : '';
|
726 |
|
727 |
if ( $with_id ) {
|
736 |
do_action( 'wsal_audit_log_column_header', $column_key );
|
737 |
}
|
738 |
|
739 |
+
echo $column_display_name; // phpcs:ignore
|
740 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '</div>' : '';
|
741 |
+
echo "</$tag>"; // phpcs:ignore
|
742 |
}
|
743 |
}
|
744 |
|
766 |
|
767 |
$bid = (int) $this->query_args->site_id;
|
768 |
if ( $bid ) {
|
769 |
+
$query->add_condition( 'site_id = %s ', $bid );
|
770 |
}
|
771 |
|
772 |
/**
|
780 |
*/
|
781 |
$query = apply_filters( 'wsal_auditlog_query', $query );
|
782 |
|
783 |
+
if ( ! $this->plugin->settings()->is_infinite_scroll() ) {
|
784 |
+
$total_items = $query->get_adapter()->count( $query );
|
785 |
+
$per_page = $this->plugin->settings()->get_views_per_page();
|
786 |
$offset = ( $this->get_pagenum() - 1 ) * $per_page;
|
787 |
} else {
|
788 |
$total_items = false;
|
795 |
$order = isset( $this->query_args->order ) ? $this->query_args->order : false;
|
796 |
|
797 |
if ( ! $order_by ) {
|
798 |
+
$query->add_order_by( 'created_on', true );
|
799 |
} else {
|
800 |
$is_descending = true;
|
801 |
if ( $order && 'asc' === $order ) {
|
806 |
/*
|
807 |
* Handle the 'code' (Severity) column sorting.
|
808 |
*/
|
809 |
+
$query->add_meta_join(); // Since LEFT JOIN clause causes the result values to duplicate.
|
810 |
+
$query->add_condition( '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.
|
811 |
+
$query->add_order_by( 'CASE WHEN meta.name = "Severity" THEN meta.value END', $is_descending );
|
812 |
} elseif ( 'info' === $order_by ) {
|
813 |
// for the info col we are ordering just by dates.
|
814 |
+
$query->add_order_by( 'created_on', $is_descending );
|
815 |
} else {
|
816 |
$tmp = new WSAL_Models_Occurrence();
|
817 |
// Making sure the field exists to order by.
|
818 |
if ( isset( $tmp->{$order_by} ) ) {
|
819 |
+
$query->add_order_by( $order_by, $is_descending );
|
820 |
} else {
|
821 |
+
$query->add_order_by( 'created_on', true );
|
822 |
}
|
823 |
}
|
824 |
}
|
825 |
|
826 |
+
$query->set_offset( $offset ); // Set query offset.
|
827 |
+
$query->set_limit( $per_page ); // Set number of events per page.
|
828 |
|
829 |
return array(
|
830 |
'total_items' => $total_items,
|
831 |
'per_page' => $per_page,
|
832 |
+
'items' => $query->get_adapter()->execute_query( $query ),
|
833 |
);
|
834 |
}
|
835 |
}
|
classes/AuditLogListView.php
CHANGED
@@ -29,7 +29,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
29 |
*
|
30 |
* @var WpSecurityAuditLog
|
31 |
*/
|
32 |
-
protected $
|
33 |
|
34 |
/**
|
35 |
* Current Alert ID
|
@@ -69,6 +69,8 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
69 |
private $item_meta = array();
|
70 |
|
71 |
/**
|
|
|
|
|
72 |
* @var WSAL_Views_AuditLog
|
73 |
* @since 4.3.2
|
74 |
*/
|
@@ -77,12 +79,12 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
77 |
/**
|
78 |
* Method: Constructor.
|
79 |
*
|
80 |
-
* @param WpSecurityAuditLog
|
81 |
* @param WSAL_Views_AuditLog $audit_log_view Audit log view.
|
82 |
-
* @param stdClass
|
83 |
*/
|
84 |
public function __construct( $plugin, $audit_log_view, $query_args ) {
|
85 |
-
$this->
|
86 |
$this->audit_log_view = $audit_log_view;
|
87 |
$this->query_args = $query_args;
|
88 |
|
@@ -106,7 +108,6 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
106 |
/**
|
107 |
* Array of class names that are applied to the table for this view.
|
108 |
*
|
109 |
-
* @method get_table_classes
|
110 |
* @since 4.0.0
|
111 |
* @return array of strings
|
112 |
*/
|
@@ -142,7 +143,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
142 |
?>
|
143 |
<div class="display-type-buttons">
|
144 |
<?php
|
145 |
-
$user_selected_view = $this->
|
146 |
?>
|
147 |
<a id ="wsal-list-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'list' ) ); ?>" class="button wsal-button dashicons-before dashicons-list-view" <?php echo ( 'list' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'List View', 'wp-security-audit-log' ); ?></a>
|
148 |
<a id ="wsal-grid-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'grid' ) ); ?>" class="button wsal-button dashicons-before dashicons-grid-view" <?php echo ( 'grid' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'Grid View', 'wp-security-audit-log' ); ?></a>
|
@@ -161,9 +162,9 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
161 |
*/
|
162 |
public function extra_tablenav( $which ) {
|
163 |
// If the position is not top then render.
|
164 |
-
if ( 'top' !== $which && ! $this->
|
165 |
// Items-per-page widget.
|
166 |
-
$p = $this->
|
167 |
$items = array( 5, 10, 15, 30, 50 );
|
168 |
if ( ! in_array( $p, $items, true ) ) {
|
169 |
$items[] = $p;
|
@@ -183,7 +184,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
183 |
<?php
|
184 |
endif;
|
185 |
|
186 |
-
if ( 'top' !== $which && $this->
|
187 |
?>
|
188 |
<div id="wsal-auditlog-end"><p><?php esc_html_e( '— End of Activity Log —', 'wp-security-audit-log' ); ?></p></div>
|
189 |
<div id="wsal-event-loader"><div class="wsal-lds-ellipsis"><div></div><div></div><div></div><div></div></div></div>
|
@@ -194,10 +195,10 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
194 |
// NOTE: this is shown when the filter IS NOT true.
|
195 |
if ( $this->is_multisite() && $this->is_main_blog() && ! apply_filters( 'search_extensition_active', false ) ) {
|
196 |
if (
|
197 |
-
( 'top' === $which && $this->
|
198 |
-
|| ! $this->
|
199 |
) {
|
200 |
-
$curr = $this->
|
201 |
?>
|
202 |
<div class="wsal-ssa wsal-ssa-<?php echo esc_attr( $which ); ?>">
|
203 |
<?php if ( $this->get_site_count() > 15 ) : ?>
|
@@ -208,7 +209,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
208 |
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
209 |
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
210 |
<?php foreach ( $this->get_sites() as $info ) : ?>
|
211 |
-
<option value="<?php echo esc_attr( $info->blog_id ); ?>" <?php
|
212 |
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
213 |
</option>
|
214 |
<?php endforeach; ?>
|
@@ -236,7 +237,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
236 |
}
|
237 |
|
238 |
// Execute query.
|
239 |
-
$res = $wpdb->get_results( $sql );
|
240 |
|
241 |
// Modify result.
|
242 |
foreach ( $res as $row ) {
|
@@ -255,7 +256,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
255 |
public function get_site_count() {
|
256 |
global $wpdb;
|
257 |
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
258 |
-
return (int) $wpdb->get_var( $sql );
|
259 |
}
|
260 |
|
261 |
/**
|
@@ -284,7 +285,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
284 |
|
285 |
// Get selected columns from settings.
|
286 |
if ( empty( $this->selected_columns ) && ! is_array( $this->selected_columns ) ) {
|
287 |
-
$this->selected_columns = $this->
|
288 |
}
|
289 |
|
290 |
// If selected columns are not empty, then unset default columns.
|
@@ -320,9 +321,9 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
320 |
case 'message':
|
321 |
$cols['mesg'] = __( 'Message', 'wp-security-audit-log' );
|
322 |
break;
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
}
|
327 |
}
|
328 |
}
|
@@ -331,19 +332,14 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
331 |
}
|
332 |
|
333 |
/**
|
334 |
-
*
|
335 |
-
*
|
336 |
-
* @param object $item - Item.
|
337 |
-
* @return string
|
338 |
*/
|
339 |
public function column_cb( $item ) {
|
340 |
return '<input type="checkbox" value="' . $item->id . '" name="' . esc_attr( $this->_args['singular'] ) . '[]" />';
|
341 |
}
|
342 |
|
343 |
/**
|
344 |
-
*
|
345 |
-
*
|
346 |
-
* @return array
|
347 |
*/
|
348 |
public function get_sortable_columns() {
|
349 |
return array(
|
@@ -358,17 +354,12 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
358 |
}
|
359 |
|
360 |
/**
|
361 |
-
*
|
362 |
-
*
|
363 |
-
* @param WSAL_Models_Occurrence $item - Column item.
|
364 |
-
* @param string $column_name - Name of the column.
|
365 |
-
*
|
366 |
-
* @return string
|
367 |
*/
|
368 |
public function column_default( $item, $column_name ) {
|
369 |
// Store meta if not set.
|
370 |
-
if ( ! isset( $this->item_meta[ $item->
|
371 |
-
$this->item_meta[ $item->
|
372 |
}
|
373 |
|
374 |
// Store current alert id.
|
@@ -376,7 +367,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
376 |
|
377 |
switch ( $column_name ) {
|
378 |
case 'type':
|
379 |
-
$code = $this->
|
380 |
$item->alert_id,
|
381 |
(object) array(
|
382 |
'mesg' => __( 'Alert message not found.', 'wp-security-audit-log' ),
|
@@ -391,38 +382,38 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
391 |
$data_link = add_query_arg( 'page', 'wsal-togglealerts#tab-users-profiles---activity', admin_url( 'admin.php' ) );
|
392 |
}
|
393 |
|
394 |
-
if ( ! $this->
|
395 |
return '<span class="log-disable">' . str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
396 |
}
|
397 |
|
398 |
return '<span class="log-disable" data-disable-alert-nonce="' . wp_create_nonce( 'disable-alert-nonce' . $item->alert_id ) . '" data-tooltip="<strong>' . __( 'Disable this type of events.', 'wp-security-audit-log' ) . '</strong><br>' . $item->alert_id . ' - ' . esc_html( $code->desc ) . $extra_msg . '" data-alert-id="' . $item->alert_id . '" ' . esc_attr( 'data-link=' . $data_link ) . ' >'
|
399 |
. str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
400 |
case 'code':
|
401 |
-
$code = $this->
|
402 |
$code = $code ? $code->severity : 0;
|
403 |
-
$const = $this->
|
404 |
|
405 |
-
$css_classes =
|
406 |
-
if (property_exists($const, 'css')) {
|
407 |
-
|
408 |
}
|
409 |
return '<a class="tooltip" href="#" data-tooltip="' . esc_html( $const->name ) . '"><span class="' . implode( ' ', $css_classes ) . '"></span></a>';
|
410 |
case 'crtd':
|
411 |
return $item->created_on
|
412 |
-
? WSAL_Utilities_DateTimeFormatter::instance()->
|
413 |
-
|
414 |
case 'user':
|
415 |
-
$username = WSAL_Utilities_UsersUtils::
|
416 |
$user = get_user_by( 'login', $username );
|
417 |
-
$roles
|
418 |
$image = '<span class="dashicons dashicons-wordpress wsal-system-icon"></span>';
|
419 |
|
420 |
-
//
|
421 |
if ( $user instanceof WP_User ) {
|
422 |
// Get user avatar.
|
423 |
$image = get_avatar( $user->ID, 32 );
|
424 |
|
425 |
-
$display_name
|
426 |
$user_edit_link = admin_url( 'user-edit.php?user_id=' . $user->ID );
|
427 |
|
428 |
// Additional user info tooltip.
|
@@ -431,12 +422,12 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
431 |
$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>';
|
432 |
|
433 |
|
434 |
-
$roles = WSAL_Utilities_UsersUtils::get_roles_label( $item->
|
435 |
-
} elseif ( 'Plugin'
|
436 |
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
437 |
-
} elseif ( 'Plugins'
|
438 |
$uhtml = '<i>' . __( 'Plugins', 'wp-security-audit-log' ) . '</i>';
|
439 |
-
} elseif ( 'Website Visitor'
|
440 |
$uhtml = '<i>' . __( 'Unregistered user', 'wp-security-audit-log' ) . '</i>';
|
441 |
} else {
|
442 |
$uhtml = '<i>' . __( 'System', 'wp-security-audit-log' ) . '</i>';
|
@@ -455,7 +446,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
455 |
*/
|
456 |
return apply_filters( 'wsal_auditlog_row_user_data', $row_user_data, $this->current_alert_id );
|
457 |
case 'scip':
|
458 |
-
$scip = $item->
|
459 |
if ( is_string( $scip ) ) {
|
460 |
$scip = str_replace( array( '"', '[', ']' ), '', $scip );
|
461 |
}
|
@@ -463,7 +454,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
463 |
$oips = array();
|
464 |
|
465 |
// If there's no IP...
|
466 |
-
if ( is_null( $scip ) || ''
|
467 |
return '<i>unknown</i>';
|
468 |
}
|
469 |
|
@@ -487,7 +478,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
487 |
|
488 |
$html = "<a class='search-ip' data-tooltip='$tooltip' data-ip='$scip' target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
489 |
foreach ( $oips as $ip ) {
|
490 |
-
if ( $scip != $ip ) {
|
491 |
$html .= '<div>' . $ip . '</div>';
|
492 |
}
|
493 |
}
|
@@ -496,7 +487,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
496 |
} else {
|
497 |
$html = "<a target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
498 |
foreach ( $oips as $ip ) {
|
499 |
-
if ( $scip != $ip ) {
|
500 |
$html .= '<div>' . $ip . '</div>';
|
501 |
}
|
502 |
}
|
@@ -509,9 +500,9 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
509 |
return ! $info ? ( 'Unknown Site ' . $item->site_id )
|
510 |
: ( '<a href="' . esc_attr( $info->siteurl ) . '">' . esc_html( $info->blogname ) . '</a>' );
|
511 |
case 'mesg':
|
512 |
-
$event_meta = $this->item_meta[ $item->
|
513 |
-
$result = '<div id="Event' . $item->id . '">' . $item->
|
514 |
-
$result
|
515 |
return $result;
|
516 |
case 'data':
|
517 |
$url = admin_url( 'admin-ajax.php' ) . '?action=AjaxInspector&occurrence=' . $item->id;
|
@@ -519,9 +510,9 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
519 |
return '<a class="more-info thickbox" data-tooltip="' . $tooltip . '" title="' . __( 'Alert Data Inspector', 'wp-security-audit-log' ) . '"'
|
520 |
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
521 |
case 'object':
|
522 |
-
return isset( $this->item_meta[ $item->
|
523 |
case 'event_type':
|
524 |
-
return isset( $this->item_meta[ $item->
|
525 |
default:
|
526 |
return isset( $item->$column_name )
|
527 |
? esc_html( $item->$column_name )
|
@@ -559,7 +550,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
559 |
* @return bool
|
560 |
*/
|
561 |
protected function is_multisite() {
|
562 |
-
return $this->
|
563 |
}
|
564 |
|
565 |
/**
|
@@ -568,7 +559,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
568 |
* @return bool
|
569 |
*/
|
570 |
protected function is_main_blog() {
|
571 |
-
return get_current_blog_id()
|
572 |
}
|
573 |
|
574 |
/**
|
@@ -577,7 +568,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
577 |
* @return bool
|
578 |
*/
|
579 |
protected function is_specific_view() {
|
580 |
-
return isset( $this->query_args->site_id ) && '0' != $this->query_args->site_id;
|
581 |
}
|
582 |
|
583 |
/**
|
@@ -625,7 +616,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
625 |
$total_items = isset( $query_events['total_items'] ) ? $query_events['total_items'] : false;
|
626 |
$per_page = isset( $query_events['per_page'] ) ? $query_events['per_page'] : false;
|
627 |
|
628 |
-
if ( ! $this->
|
629 |
$this->set_pagination_args(
|
630 |
array(
|
631 |
'total_items' => $total_items,
|
@@ -662,7 +653,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
662 |
public function print_column_headers( $with_id = true ) {
|
663 |
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
|
664 |
|
665 |
-
$current_url = set_url_scheme( esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) );
|
666 |
$current_url = remove_query_arg( 'paged', $current_url );
|
667 |
|
668 |
// Set order by query arg.
|
@@ -688,13 +679,13 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
688 |
foreach ( $columns as $column_key => $column_display_name ) {
|
689 |
$class = array( 'manage-column', "column-$column_key" );
|
690 |
|
691 |
-
if ( in_array( $column_key, $hidden ) ) {
|
692 |
$class[] = 'hidden';
|
693 |
}
|
694 |
|
695 |
if ( 'cb' === $column_key ) {
|
696 |
$class[] = 'check-column';
|
697 |
-
} elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) {
|
698 |
$class[] = 'num';
|
699 |
}
|
700 |
|
@@ -726,7 +717,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
726 |
$class = "class='" . implode( ' ', $class ) . "'";
|
727 |
}
|
728 |
|
729 |
-
echo "<$tag $scope $id $class>";
|
730 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '<div class="wsal-filter-wrap">' : '';
|
731 |
|
732 |
if ( $with_id ) {
|
@@ -741,9 +732,9 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
741 |
do_action( 'wsal_audit_log_column_header', $column_key );
|
742 |
}
|
743 |
|
744 |
-
echo $column_display_name;
|
745 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '</div>' : '';
|
746 |
-
echo "</$tag>";
|
747 |
}
|
748 |
}
|
749 |
|
@@ -770,7 +761,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
770 |
$query = new WSAL_Models_OccurrenceQuery();
|
771 |
$bid = (int) $this->query_args->site_id;
|
772 |
if ( $bid ) {
|
773 |
-
$query->
|
774 |
}
|
775 |
|
776 |
/**
|
@@ -784,9 +775,9 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
784 |
*/
|
785 |
$query = apply_filters( 'wsal_auditlog_query', $query );
|
786 |
|
787 |
-
if ( ! $this->
|
788 |
-
$total_items = $query->
|
789 |
-
$per_page = $this->
|
790 |
$offset = ( $this->get_pagenum() - 1 ) * $per_page;
|
791 |
} else {
|
792 |
$total_items = false;
|
@@ -799,7 +790,7 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
799 |
$order = isset( $this->query_args->order ) ? $this->query_args->order : false;
|
800 |
|
801 |
if ( ! $order_by ) {
|
802 |
-
$query->
|
803 |
} else {
|
804 |
$is_descending = true;
|
805 |
if ( $order && 'asc' === $order ) {
|
@@ -808,42 +799,42 @@ class WSAL_AuditLogListView extends WP_List_Table {
|
|
808 |
|
809 |
// TO DO: Allow order by meta values.
|
810 |
if ( 'scip' === $order_by ) {
|
811 |
-
$query->
|
812 |
} elseif ( 'user' === $order_by ) {
|
813 |
-
$query->
|
814 |
} elseif ( 'code' === $order_by ) {
|
815 |
/*
|
816 |
* Handle the 'code' (Severity) column sorting.
|
817 |
*/
|
818 |
-
$query->
|
819 |
} elseif ( 'object' === $order_by ) {
|
820 |
/*
|
821 |
* Handle the 'object' column sorting.
|
822 |
*/
|
823 |
-
$query->
|
824 |
} elseif ( 'event_type' === $order_by ) {
|
825 |
/*
|
826 |
* Handle the 'Event Type' column sorting.
|
827 |
*/
|
828 |
-
$query->
|
829 |
} else {
|
830 |
$tmp = new WSAL_Models_Occurrence();
|
831 |
// Making sure the field exists to order by.
|
832 |
if ( isset( $tmp->{$order_by} ) ) {
|
833 |
// TODO: We used to use a custom comparator ... is it safe to let MySQL do the ordering now?.
|
834 |
-
$query->
|
835 |
} else {
|
836 |
-
$query->
|
837 |
}
|
838 |
}
|
839 |
}
|
840 |
|
841 |
-
$query->
|
842 |
-
$query->
|
843 |
return array(
|
844 |
'total_items' => $total_items,
|
845 |
'per_page' => $per_page,
|
846 |
-
'items' => $query->
|
847 |
);
|
848 |
}
|
849 |
}
|
29 |
*
|
30 |
* @var WpSecurityAuditLog
|
31 |
*/
|
32 |
+
protected $plugin;
|
33 |
|
34 |
/**
|
35 |
* Current Alert ID
|
69 |
private $item_meta = array();
|
70 |
|
71 |
/**
|
72 |
+
* Audit log view.
|
73 |
+
*
|
74 |
* @var WSAL_Views_AuditLog
|
75 |
* @since 4.3.2
|
76 |
*/
|
79 |
/**
|
80 |
* Method: Constructor.
|
81 |
*
|
82 |
+
* @param WpSecurityAuditLog $plugin Instance of WpSecurityAuditLog.
|
83 |
* @param WSAL_Views_AuditLog $audit_log_view Audit log view.
|
84 |
+
* @param stdClass $query_args Events query arguments.
|
85 |
*/
|
86 |
public function __construct( $plugin, $audit_log_view, $query_args ) {
|
87 |
+
$this->plugin = $plugin;
|
88 |
$this->audit_log_view = $audit_log_view;
|
89 |
$this->query_args = $query_args;
|
90 |
|
108 |
/**
|
109 |
* Array of class names that are applied to the table for this view.
|
110 |
*
|
|
|
111 |
* @since 4.0.0
|
112 |
* @return array of strings
|
113 |
*/
|
143 |
?>
|
144 |
<div class="display-type-buttons">
|
145 |
<?php
|
146 |
+
$user_selected_view = $this->plugin->views->views[0]->detect_view_type();
|
147 |
?>
|
148 |
<a id ="wsal-list-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'list' ) ); ?>" class="button wsal-button dashicons-before dashicons-list-view" <?php echo ( 'list' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'List View', 'wp-security-audit-log' ); ?></a>
|
149 |
<a id ="wsal-grid-view-toggle" href="<?php echo esc_url( add_query_arg( 'view', 'grid' ) ); ?>" class="button wsal-button dashicons-before dashicons-grid-view" <?php echo ( 'grid' === $user_selected_view ) ? esc_attr( 'disabled' ) : ''; ?>><?php esc_html_e( 'Grid View', 'wp-security-audit-log' ); ?></a>
|
162 |
*/
|
163 |
public function extra_tablenav( $which ) {
|
164 |
// If the position is not top then render.
|
165 |
+
if ( 'top' !== $which && ! $this->plugin->settings()->is_infinite_scroll() ) :
|
166 |
// Items-per-page widget.
|
167 |
+
$p = $this->plugin->settings()->get_views_per_page();
|
168 |
$items = array( 5, 10, 15, 30, 50 );
|
169 |
if ( ! in_array( $p, $items, true ) ) {
|
170 |
$items[] = $p;
|
184 |
<?php
|
185 |
endif;
|
186 |
|
187 |
+
if ( 'top' !== $which && $this->plugin->settings()->is_infinite_scroll() ) :
|
188 |
?>
|
189 |
<div id="wsal-auditlog-end"><p><?php esc_html_e( '— End of Activity Log —', 'wp-security-audit-log' ); ?></p></div>
|
190 |
<div id="wsal-event-loader"><div class="wsal-lds-ellipsis"><div></div><div></div><div></div><div></div></div></div>
|
195 |
// NOTE: this is shown when the filter IS NOT true.
|
196 |
if ( $this->is_multisite() && $this->is_main_blog() && ! apply_filters( 'search_extensition_active', false ) ) {
|
197 |
if (
|
198 |
+
( 'top' === $which && $this->plugin->settings()->is_infinite_scroll() )
|
199 |
+
|| ! $this->plugin->settings()->is_infinite_scroll()
|
200 |
) {
|
201 |
+
$curr = $this->plugin->settings()->get_view_site_id();
|
202 |
?>
|
203 |
<div class="wsal-ssa wsal-ssa-<?php echo esc_attr( $which ); ?>">
|
204 |
<?php if ( $this->get_site_count() > 15 ) : ?>
|
209 |
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
210 |
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
211 |
<?php foreach ( $this->get_sites() as $info ) : ?>
|
212 |
+
<option value="<?php echo esc_attr( $info->blog_id ); ?>" <?php selected( $info->blog_id, $curr ); ?>>
|
213 |
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
214 |
</option>
|
215 |
<?php endforeach; ?>
|
237 |
}
|
238 |
|
239 |
// Execute query.
|
240 |
+
$res = $wpdb->get_results( $sql ); // phpcs:ignore
|
241 |
|
242 |
// Modify result.
|
243 |
foreach ( $res as $row ) {
|
256 |
public function get_site_count() {
|
257 |
global $wpdb;
|
258 |
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
259 |
+
return (int) $wpdb->get_var( $sql ); // phpcs:ignore
|
260 |
}
|
261 |
|
262 |
/**
|
285 |
|
286 |
// Get selected columns from settings.
|
287 |
if ( empty( $this->selected_columns ) && ! is_array( $this->selected_columns ) ) {
|
288 |
+
$this->selected_columns = $this->plugin->settings()->get_columns_selected();
|
289 |
}
|
290 |
|
291 |
// If selected columns are not empty, then unset default columns.
|
321 |
case 'message':
|
322 |
$cols['mesg'] = __( 'Message', 'wp-security-audit-log' );
|
323 |
break;
|
324 |
+
default:
|
325 |
+
// Fallback for any new columns would go here.
|
326 |
+
break;
|
327 |
}
|
328 |
}
|
329 |
}
|
332 |
}
|
333 |
|
334 |
/**
|
335 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
336 |
*/
|
337 |
public function column_cb( $item ) {
|
338 |
return '<input type="checkbox" value="' . $item->id . '" name="' . esc_attr( $this->_args['singular'] ) . '[]" />';
|
339 |
}
|
340 |
|
341 |
/**
|
342 |
+
* {@inheritDoc}
|
|
|
|
|
343 |
*/
|
344 |
public function get_sortable_columns() {
|
345 |
return array(
|
354 |
}
|
355 |
|
356 |
/**
|
357 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
|
|
|
|
358 |
*/
|
359 |
public function column_default( $item, $column_name ) {
|
360 |
// Store meta if not set.
|
361 |
+
if ( ! isset( $this->item_meta[ $item->get_id() ] ) ) {
|
362 |
+
$this->item_meta[ $item->get_id() ] = $item->get_meta_array();
|
363 |
}
|
364 |
|
365 |
// Store current alert id.
|
367 |
|
368 |
switch ( $column_name ) {
|
369 |
case 'type':
|
370 |
+
$code = $this->plugin->alerts->get_alert(
|
371 |
$item->alert_id,
|
372 |
(object) array(
|
373 |
'mesg' => __( 'Alert message not found.', 'wp-security-audit-log' ),
|
382 |
$data_link = add_query_arg( 'page', 'wsal-togglealerts#tab-users-profiles---activity', admin_url( 'admin.php' ) );
|
383 |
}
|
384 |
|
385 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
386 |
return '<span class="log-disable">' . str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
387 |
}
|
388 |
|
389 |
return '<span class="log-disable" data-disable-alert-nonce="' . wp_create_nonce( 'disable-alert-nonce' . $item->alert_id ) . '" data-tooltip="<strong>' . __( 'Disable this type of events.', 'wp-security-audit-log' ) . '</strong><br>' . $item->alert_id . ' - ' . esc_html( $code->desc ) . $extra_msg . '" data-alert-id="' . $item->alert_id . '" ' . esc_attr( 'data-link=' . $data_link ) . ' >'
|
390 |
. str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
391 |
case 'code':
|
392 |
+
$code = $this->plugin->alerts->get_alert( $item->alert_id );
|
393 |
$code = $code ? $code->severity : 0;
|
394 |
+
$const = $this->plugin->constants->get_constant_to_display( $code );
|
395 |
|
396 |
+
$css_classes = array( 'log-type', 'log-type-' . $const->value );
|
397 |
+
if ( property_exists( $const, 'css' ) ) {
|
398 |
+
array_push( $css_classes, 'log-type-' . $const->css );
|
399 |
}
|
400 |
return '<a class="tooltip" href="#" data-tooltip="' . esc_html( $const->name ) . '"><span class="' . implode( ' ', $css_classes ) . '"></span></a>';
|
401 |
case 'crtd':
|
402 |
return $item->created_on
|
403 |
+
? WSAL_Utilities_DateTimeFormatter::instance()->get_formatted_date_time( $item->created_on, 'datetime', true, true )
|
404 |
+
: '<i>' . __( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
405 |
case 'user':
|
406 |
+
$username = WSAL_Utilities_UsersUtils::get_username( $this->item_meta[ $item->get_id() ] );
|
407 |
$user = get_user_by( 'login', $username );
|
408 |
+
$roles = '';
|
409 |
$image = '<span class="dashicons dashicons-wordpress wsal-system-icon"></span>';
|
410 |
|
411 |
+
// Check if there's a user with given username.
|
412 |
if ( $user instanceof WP_User ) {
|
413 |
// Get user avatar.
|
414 |
$image = get_avatar( $user->ID, 32 );
|
415 |
|
416 |
+
$display_name = WSAL_Utilities_UsersUtils::get_display_label( $this->plugin, $user );
|
417 |
$user_edit_link = admin_url( 'user-edit.php?user_id=' . $user->ID );
|
418 |
|
419 |
// Additional user info tooltip.
|
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->get_user_roles() );
|
426 |
+
} elseif ( 'Plugin' === $username ) {
|
427 |
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
428 |
+
} elseif ( 'Plugins' === $username ) {
|
429 |
$uhtml = '<i>' . __( 'Plugins', 'wp-security-audit-log' ) . '</i>';
|
430 |
+
} elseif ( 'Website Visitor' === $username || 'Unregistered user' === $username ) {
|
431 |
$uhtml = '<i>' . __( 'Unregistered user', 'wp-security-audit-log' ) . '</i>';
|
432 |
} else {
|
433 |
$uhtml = '<i>' . __( 'System', 'wp-security-audit-log' ) . '</i>';
|
446 |
*/
|
447 |
return apply_filters( 'wsal_auditlog_row_user_data', $row_user_data, $this->current_alert_id );
|
448 |
case 'scip':
|
449 |
+
$scip = $item->get_source_ip();
|
450 |
if ( is_string( $scip ) ) {
|
451 |
$scip = str_replace( array( '"', '[', ']' ), '', $scip );
|
452 |
}
|
454 |
$oips = array();
|
455 |
|
456 |
// If there's no IP...
|
457 |
+
if ( is_null( $scip ) || '' === $scip ) {
|
458 |
return '<i>unknown</i>';
|
459 |
}
|
460 |
|
478 |
|
479 |
$html = "<a class='search-ip' data-tooltip='$tooltip' data-ip='$scip' target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
480 |
foreach ( $oips as $ip ) {
|
481 |
+
if ( $scip != $ip ) { // phpcs:ignore
|
482 |
$html .= '<div>' . $ip . '</div>';
|
483 |
}
|
484 |
}
|
487 |
} else {
|
488 |
$html = "<a target='_blank' href='https://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
489 |
foreach ( $oips as $ip ) {
|
490 |
+
if ( $scip != $ip ) { // phpcs:ignore
|
491 |
$html .= '<div>' . $ip . '</div>';
|
492 |
}
|
493 |
}
|
500 |
return ! $info ? ( 'Unknown Site ' . $item->site_id )
|
501 |
: ( '<a href="' . esc_attr( $info->siteurl ) . '">' . esc_html( $info->blogname ) . '</a>' );
|
502 |
case 'mesg':
|
503 |
+
$event_meta = $this->item_meta[ $item->get_id() ];
|
504 |
+
$result = '<div id="Event' . $item->id . '">' . $item->get_message( $event_meta ) . '</div>';
|
505 |
+
$result .= $this->audit_log_view->maybe_build_teaser_html( $event_meta );
|
506 |
return $result;
|
507 |
case 'data':
|
508 |
$url = admin_url( 'admin-ajax.php' ) . '?action=AjaxInspector&occurrence=' . $item->id;
|
510 |
return '<a class="more-info thickbox" data-tooltip="' . $tooltip . '" title="' . __( 'Alert Data Inspector', 'wp-security-audit-log' ) . '"'
|
511 |
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
512 |
case 'object':
|
513 |
+
return isset( $this->item_meta[ $item->get_id() ]['Object'] ) ? $this->plugin->alerts->get_event_objects_data( $this->item_meta[ $item->get_id() ]['Object'] ) : '';
|
514 |
case 'event_type':
|
515 |
+
return isset( $this->item_meta[ $item->get_id() ]['EventType'] ) ? $this->plugin->alerts->get_event_type_data( $this->item_meta[ $item->get_id() ]['EventType'] ) : '';
|
516 |
default:
|
517 |
return isset( $item->$column_name )
|
518 |
? esc_html( $item->$column_name )
|
550 |
* @return bool
|
551 |
*/
|
552 |
protected function is_multisite() {
|
553 |
+
return $this->plugin->is_multisite();
|
554 |
}
|
555 |
|
556 |
/**
|
559 |
* @return bool
|
560 |
*/
|
561 |
protected function is_main_blog() {
|
562 |
+
return get_current_blog_id() === 1;
|
563 |
}
|
564 |
|
565 |
/**
|
568 |
* @return bool
|
569 |
*/
|
570 |
protected function is_specific_view() {
|
571 |
+
return isset( $this->query_args->site_id ) && '0' != $this->query_args->site_id; // phpcs:ignore
|
572 |
}
|
573 |
|
574 |
/**
|
616 |
$total_items = isset( $query_events['total_items'] ) ? $query_events['total_items'] : false;
|
617 |
$per_page = isset( $query_events['per_page'] ) ? $query_events['per_page'] : false;
|
618 |
|
619 |
+
if ( ! $this->plugin->settings()->is_infinite_scroll() ) {
|
620 |
$this->set_pagination_args(
|
621 |
array(
|
622 |
'total_items' => $total_items,
|
653 |
public function print_column_headers( $with_id = true ) {
|
654 |
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
|
655 |
|
656 |
+
$current_url = set_url_scheme( esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ) ); // phpcs:ignore
|
657 |
$current_url = remove_query_arg( 'paged', $current_url );
|
658 |
|
659 |
// Set order by query arg.
|
679 |
foreach ( $columns as $column_key => $column_display_name ) {
|
680 |
$class = array( 'manage-column', "column-$column_key" );
|
681 |
|
682 |
+
if ( in_array( $column_key, $hidden, true ) ) {
|
683 |
$class[] = 'hidden';
|
684 |
}
|
685 |
|
686 |
if ( 'cb' === $column_key ) {
|
687 |
$class[] = 'check-column';
|
688 |
+
} elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ), true ) ) {
|
689 |
$class[] = 'num';
|
690 |
}
|
691 |
|
717 |
$class = "class='" . implode( ' ', $class ) . "'";
|
718 |
}
|
719 |
|
720 |
+
echo "<$tag $scope $id $class>"; // phpcs:ignore
|
721 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '<div class="wsal-filter-wrap">' : '';
|
722 |
|
723 |
if ( $with_id ) {
|
732 |
do_action( 'wsal_audit_log_column_header', $column_key );
|
733 |
}
|
734 |
|
735 |
+
echo $column_display_name; // phpcs:ignore
|
736 |
echo ! in_array( $column_key, array( 'code', 'data', 'site' ), true ) ? '</div>' : '';
|
737 |
+
echo "</$tag>"; // phpcs:ignore
|
738 |
}
|
739 |
}
|
740 |
|
761 |
$query = new WSAL_Models_OccurrenceQuery();
|
762 |
$bid = (int) $this->query_args->site_id;
|
763 |
if ( $bid ) {
|
764 |
+
$query->add_condition( 'site_id = %s ', $bid );
|
765 |
}
|
766 |
|
767 |
/**
|
775 |
*/
|
776 |
$query = apply_filters( 'wsal_auditlog_query', $query );
|
777 |
|
778 |
+
if ( ! $this->plugin->settings()->is_infinite_scroll() ) {
|
779 |
+
$total_items = $query->get_adapter()->count( $query );
|
780 |
+
$per_page = $this->plugin->settings()->get_views_per_page();
|
781 |
$offset = ( $this->get_pagenum() - 1 ) * $per_page;
|
782 |
} else {
|
783 |
$total_items = false;
|
790 |
$order = isset( $this->query_args->order ) ? $this->query_args->order : false;
|
791 |
|
792 |
if ( ! $order_by ) {
|
793 |
+
$query->add_order_by( 'created_on', true );
|
794 |
} else {
|
795 |
$is_descending = true;
|
796 |
if ( $order && 'asc' === $order ) {
|
799 |
|
800 |
// TO DO: Allow order by meta values.
|
801 |
if ( 'scip' === $order_by ) {
|
802 |
+
$query->add_order_by( 'client_ip', $is_descending );
|
803 |
} elseif ( 'user' === $order_by ) {
|
804 |
+
$query->add_order_by( 'user_id', $is_descending );
|
805 |
} elseif ( 'code' === $order_by ) {
|
806 |
/*
|
807 |
* Handle the 'code' (Severity) column sorting.
|
808 |
*/
|
809 |
+
$query->add_order_by( 'severity', $is_descending );
|
810 |
} elseif ( 'object' === $order_by ) {
|
811 |
/*
|
812 |
* Handle the 'object' column sorting.
|
813 |
*/
|
814 |
+
$query->add_order_by( 'object', $is_descending );
|
815 |
} elseif ( 'event_type' === $order_by ) {
|
816 |
/*
|
817 |
* Handle the 'Event Type' column sorting.
|
818 |
*/
|
819 |
+
$query->add_order_by( 'event_type', $is_descending );
|
820 |
} else {
|
821 |
$tmp = new WSAL_Models_Occurrence();
|
822 |
// Making sure the field exists to order by.
|
823 |
if ( isset( $tmp->{$order_by} ) ) {
|
824 |
// TODO: We used to use a custom comparator ... is it safe to let MySQL do the ordering now?.
|
825 |
+
$query->add_order_by( $order_by, $is_descending );
|
826 |
} else {
|
827 |
+
$query->add_order_by( 'created_on', true );
|
828 |
}
|
829 |
}
|
830 |
}
|
831 |
|
832 |
+
$query->set_offset( $offset ); // Set query offset.
|
833 |
+
$query->set_limit( $per_page ); // Set number of events per page.
|
834 |
return array(
|
835 |
'total_items' => $total_items,
|
836 |
'per_page' => $per_page,
|
837 |
+
'items' => $query->get_adapter()->execute_query( $query ),
|
838 |
);
|
839 |
}
|
840 |
}
|
classes/Autoloader.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Classes Auto Loader.
|
4 |
*
|
@@ -29,7 +35,7 @@ class WSAL_Autoloader {
|
|
29 |
$this->plugin = $plugin;
|
30 |
|
31 |
// Register autoloader.
|
32 |
-
spl_autoload_register( array( $this, '
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -38,7 +44,7 @@ class WSAL_Autoloader {
|
|
38 |
* @param string $prefix - Prefix of the class.
|
39 |
* @param string $path - Path of the file.
|
40 |
*/
|
41 |
-
public function
|
42 |
if ( ! isset( $this->paths[ $prefix ] ) ) {
|
43 |
$this->paths[ $prefix ] = array();
|
44 |
}
|
@@ -51,7 +57,7 @@ class WSAL_Autoloader {
|
|
51 |
* @param string $class - Class name.
|
52 |
* @return boolean - True if class is found and loaded, false otherwise.
|
53 |
*/
|
54 |
-
public function
|
55 |
foreach ( $this->paths as $prefix => $paths ) {
|
56 |
foreach ( $paths as $path ) {
|
57 |
if ( strstr( $class, $prefix ) !== false ) {
|
@@ -72,7 +78,7 @@ class WSAL_Autoloader {
|
|
72 |
* @param string $file File name.
|
73 |
* @return string|false Class name or false on error.
|
74 |
*/
|
75 |
-
public function
|
76 |
$file = str_replace( '\\', '/', $file ); // Win/DOS hotfix.
|
77 |
|
78 |
foreach ( $this->paths as $prefix => $paths ) {
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Autoloader class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
*/
|
7 |
+
|
8 |
/**
|
9 |
* Classes Auto Loader.
|
10 |
*
|
35 |
$this->plugin = $plugin;
|
36 |
|
37 |
// Register autoloader.
|
38 |
+
spl_autoload_register( array( $this, 'load_class' ) );
|
39 |
}
|
40 |
|
41 |
/**
|
44 |
* @param string $prefix - Prefix of the class.
|
45 |
* @param string $path - Path of the file.
|
46 |
*/
|
47 |
+
public function register( $prefix, $path ) {
|
48 |
if ( ! isset( $this->paths[ $prefix ] ) ) {
|
49 |
$this->paths[ $prefix ] = array();
|
50 |
}
|
57 |
* @param string $class - Class name.
|
58 |
* @return boolean - True if class is found and loaded, false otherwise.
|
59 |
*/
|
60 |
+
public function load_class( $class ) {
|
61 |
foreach ( $this->paths as $prefix => $paths ) {
|
62 |
foreach ( $paths as $path ) {
|
63 |
if ( strstr( $class, $prefix ) !== false ) {
|
78 |
* @param string $file File name.
|
79 |
* @return string|false Class name or false on error.
|
80 |
*/
|
81 |
+
public function get_class_file_class_name( $file ) {
|
82 |
$file = str_replace( '\\', '/', $file ); // Win/DOS hotfix.
|
83 |
|
84 |
foreach ( $this->paths as $prefix => $paths ) {
|
classes/Connector/AbstractConnector.php
CHANGED
@@ -12,8 +12,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
12 |
exit;
|
13 |
}
|
14 |
|
15 |
-
|
16 |
-
require_once( 'wp-db-custom.php' );
|
17 |
|
18 |
/**
|
19 |
* Adapter Classes loader class.
|
@@ -36,14 +35,14 @@ abstract class WSAL_Connector_AbstractConnector {
|
|
36 |
*
|
37 |
* @var null
|
38 |
*/
|
39 |
-
protected $
|
40 |
|
41 |
/**
|
42 |
* Adapter Directory Name.
|
43 |
*
|
44 |
* @var null
|
45 |
*/
|
46 |
-
protected $
|
47 |
|
48 |
/**
|
49 |
* Method: Constructor.
|
@@ -51,14 +50,15 @@ abstract class WSAL_Connector_AbstractConnector {
|
|
51 |
* @param string $adapters_dir_name - Adapter directory name.
|
52 |
*/
|
53 |
public function __construct( $adapters_dir_name = null ) {
|
54 |
-
$this->
|
55 |
if ( ! empty( $adapters_dir_name ) ) {
|
56 |
-
$this->
|
57 |
-
|
58 |
-
require_once
|
59 |
-
require_once
|
60 |
-
require_once
|
61 |
-
require_once
|
|
|
62 |
do_action( 'wsal_require_additional_adapters' );
|
63 |
}
|
64 |
}
|
@@ -66,9 +66,9 @@ abstract class WSAL_Connector_AbstractConnector {
|
|
66 |
/**
|
67 |
* Method: Get adapters directory.
|
68 |
*/
|
69 |
-
public function
|
70 |
-
if ( ! empty( $this->
|
71 |
-
return $this->
|
72 |
} else {
|
73 |
return false;
|
74 |
}
|
12 |
exit;
|
13 |
}
|
14 |
|
15 |
+
require_once 'wp-db-custom.php';
|
|
|
16 |
|
17 |
/**
|
18 |
* Adapter Classes loader class.
|
35 |
*
|
36 |
* @var null
|
37 |
*/
|
38 |
+
protected $adapters_base_path = null;
|
39 |
|
40 |
/**
|
41 |
* Adapter Directory Name.
|
42 |
*
|
43 |
* @var null
|
44 |
*/
|
45 |
+
protected $adapters_dir_name = null;
|
46 |
|
47 |
/**
|
48 |
* Method: Constructor.
|
50 |
* @param string $adapters_dir_name - Adapter directory name.
|
51 |
*/
|
52 |
public function __construct( $adapters_dir_name = null ) {
|
53 |
+
$this->adapters_base_path = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Adapters' . DIRECTORY_SEPARATOR;
|
54 |
if ( ! empty( $adapters_dir_name ) ) {
|
55 |
+
$this->adapters_dir_name = $adapters_dir_name;
|
56 |
+
$adapters_directory = $this->get_adapters_directory();
|
57 |
+
require_once $adapters_directory . DIRECTORY_SEPARATOR . 'ActiveRecordAdapter.php';
|
58 |
+
require_once $adapters_directory . DIRECTORY_SEPARATOR . 'MetaAdapter.php';
|
59 |
+
require_once $adapters_directory . DIRECTORY_SEPARATOR . 'OccurrenceAdapter.php';
|
60 |
+
require_once $adapters_directory . DIRECTORY_SEPARATOR . 'QueryAdapter.php';
|
61 |
+
require_once $adapters_directory . DIRECTORY_SEPARATOR . 'TmpUserAdapter.php';
|
62 |
do_action( 'wsal_require_additional_adapters' );
|
63 |
}
|
64 |
}
|
66 |
/**
|
67 |
* Method: Get adapters directory.
|
68 |
*/
|
69 |
+
public function get_adapters_directory() {
|
70 |
+
if ( ! empty( $this->adapters_base_path ) && ! empty( $this->adapters_dir_name ) ) {
|
71 |
+
return $this->adapters_base_path . $this->adapters_dir_name;
|
72 |
} else {
|
73 |
return false;
|
74 |
}
|
classes/Connector/ConnectorFactory.php
CHANGED
@@ -58,7 +58,7 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
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
|
62 |
return new WSAL_Connector_MySQLDB();
|
63 |
}
|
64 |
|
@@ -71,17 +71,17 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
71 |
* @return WSAL_Connector_ConnectorInterface
|
72 |
* @throws Freemius_Exception
|
73 |
*/
|
74 |
-
public static function
|
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::
|
80 |
-
$connection_name = $plugin->
|
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::
|
85 |
}
|
86 |
} else {
|
87 |
if ( is_string( $config ) ) {
|
@@ -124,9 +124,9 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
124 |
* @return array|null adapter config
|
125 |
* @throws Freemius_Exception
|
126 |
*/
|
127 |
-
public static function
|
128 |
-
$plugin = WpSecurityAuditLog::
|
129 |
-
$connection_name = $plugin->
|
130 |
|
131 |
if ( function_exists( 'wsal_freemius' ) && ! apply_filters( 'wsal_disable_freemius_sdk', false ) ) {
|
132 |
$is_not_paying = wsal_freemius()->is_not_paying();
|
@@ -138,8 +138,8 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
138 |
$connector = new WSAL_Connector_MySQLDB();
|
139 |
|
140 |
if ( ! self::$is_installed ) {
|
141 |
-
self::$is_installed = $connector->
|
142 |
-
$connector->
|
143 |
}
|
144 |
|
145 |
$connection_name = null;
|
@@ -166,9 +166,9 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
166 |
*
|
167 |
* @see WSAL_Ext_Common::get_connection()
|
168 |
*/
|
169 |
-
$plugin = WpSecurityAuditLog::
|
170 |
-
$connection_raw = maybe_unserialize( $plugin->
|
171 |
-
$connection = ( $connection_raw instanceof stdClass ) ? json_decode( json_encode( $connection_raw ), true ) : $connection_raw;
|
172 |
if ( ! is_array( $connection ) || empty( $connection ) ) {
|
173 |
return null;
|
174 |
}
|
@@ -183,7 +183,7 @@ abstract class WSAL_Connector_ConnectorFactory {
|
|
183 |
*
|
184 |
* @return boolean true|false
|
185 |
*/
|
186 |
-
public static function
|
187 |
// Only mysql supported at the moment.
|
188 |
if ( array_key_exists( 'type', $config ) && 'mysql' === $config['type'] ) {
|
189 |
try {
|
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 get_default_connector() {
|
62 |
return new WSAL_Connector_MySQLDB();
|
63 |
}
|
64 |
|
71 |
* @return WSAL_Connector_ConnectorInterface
|
72 |
* @throws Freemius_Exception
|
73 |
*/
|
74 |
+
public static function get_connector( $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::get_instance();
|
80 |
+
$connection_name = $plugin->get_global_setting( '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::get_config( $config );
|
85 |
}
|
86 |
} else {
|
87 |
if ( is_string( $config ) ) {
|
124 |
* @return array|null adapter config
|
125 |
* @throws Freemius_Exception
|
126 |
*/
|
127 |
+
public static function get_config() {
|
128 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
129 |
+
$connection_name = $plugin->get_global_setting( 'adapter-connection' );
|
130 |
|
131 |
if ( function_exists( 'wsal_freemius' ) && ! apply_filters( 'wsal_disable_freemius_sdk', false ) ) {
|
132 |
$is_not_paying = wsal_freemius()->is_not_paying();
|
138 |
$connector = new WSAL_Connector_MySQLDB();
|
139 |
|
140 |
if ( ! self::$is_installed ) {
|
141 |
+
self::$is_installed = $connector->is_installed();
|
142 |
+
$connector->install_all();
|
143 |
}
|
144 |
|
145 |
$connection_name = null;
|
166 |
*
|
167 |
* @see WSAL_Ext_Common::get_connection()
|
168 |
*/
|
169 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
170 |
+
$connection_raw = maybe_unserialize( $plugin->get_global_setting( 'connection-' . $connection_name ) );
|
171 |
+
$connection = ( $connection_raw instanceof stdClass ) ? json_decode( json_encode( $connection_raw ), true ) : $connection_raw; // phpcs:ignore
|
172 |
if ( ! is_array( $connection ) || empty( $connection ) ) {
|
173 |
return null;
|
174 |
}
|
183 |
*
|
184 |
* @return boolean true|false
|
185 |
*/
|
186 |
+
public static function check_config( $config ) {
|
187 |
// Only mysql supported at the moment.
|
188 |
if ( array_key_exists( 'type', $config ) && 'mysql' === $config['type'] ) {
|
189 |
try {
|
classes/Connector/ConnectorInterface.php
CHANGED
@@ -26,53 +26,53 @@ interface WSAL_Connector_ConnectorInterface {
|
|
26 |
*
|
27 |
* @return WSAL_Adapters_ActiveRecordInterface
|
28 |
*/
|
29 |
-
public function
|
30 |
|
31 |
/**
|
32 |
* Get the connection.
|
33 |
*
|
34 |
* @return wpdb
|
35 |
*/
|
36 |
-
public function
|
37 |
|
38 |
/**
|
39 |
* Close the connection.
|
40 |
*/
|
41 |
-
public function
|
42 |
|
43 |
/**
|
44 |
* Checks if the necessary tables are available
|
45 |
*
|
46 |
* @return bool true|false
|
47 |
*/
|
48 |
-
public function
|
49 |
|
50 |
/**
|
51 |
* Install all.
|
52 |
*
|
53 |
-
* @param bool $is_external_database
|
54 |
*/
|
55 |
-
public function
|
56 |
|
57 |
/**
|
58 |
-
*
|
59 |
*
|
60 |
-
* @param $class_name
|
61 |
-
* @param bool
|
62 |
*
|
63 |
* @since 4.1.4.1
|
64 |
*/
|
65 |
-
public function
|
66 |
|
67 |
/**
|
68 |
* Uninstall all.
|
69 |
*/
|
70 |
-
public function
|
71 |
|
72 |
/**
|
73 |
* Run any query.
|
74 |
*
|
75 |
-
* @param string $query
|
76 |
*
|
77 |
* @return mixed
|
78 |
* @since 4.4.0
|
26 |
*
|
27 |
* @return WSAL_Adapters_ActiveRecordInterface
|
28 |
*/
|
29 |
+
public function get_adapter( $class_name );
|
30 |
|
31 |
/**
|
32 |
* Get the connection.
|
33 |
*
|
34 |
* @return wpdb
|
35 |
*/
|
36 |
+
public function get_connection();
|
37 |
|
38 |
/**
|
39 |
* Close the connection.
|
40 |
*/
|
41 |
+
public function close_connection();
|
42 |
|
43 |
/**
|
44 |
* Checks if the necessary tables are available
|
45 |
*
|
46 |
* @return bool true|false
|
47 |
*/
|
48 |
+
public function is_installed();
|
49 |
|
50 |
/**
|
51 |
* Install all.
|
52 |
*
|
53 |
+
* @param bool $is_external_database True if this is external database.
|
54 |
*/
|
55 |
+
public function install_all( $is_external_database = false );
|
56 |
|
57 |
/**
|
58 |
+
* Installs single database table based on its adapter class name.
|
59 |
*
|
60 |
+
* @param string $class_name Adapter class name.
|
61 |
+
* @param bool $is_external_database True if this is external database.
|
62 |
*
|
63 |
* @since 4.1.4.1
|
64 |
*/
|
65 |
+
public function install_single( $class_name, $is_external_database = false );
|
66 |
|
67 |
/**
|
68 |
* Uninstall all.
|
69 |
*/
|
70 |
+
public function uninstall_all();
|
71 |
|
72 |
/**
|
73 |
* Run any query.
|
74 |
*
|
75 |
+
* @param string $query Databse query to execute.
|
76 |
*
|
77 |
* @return mixed
|
78 |
* @since 4.4.0
|
classes/Connector/MySQLDB.php
CHANGED
@@ -26,7 +26,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
26 |
*
|
27 |
* @var array
|
28 |
*/
|
29 |
-
protected $
|
30 |
|
31 |
/**
|
32 |
* Method: Constructor.
|
@@ -34,7 +34,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
34 |
* @param array $connection_config - Connection config.
|
35 |
*/
|
36 |
public function __construct( $connection_config = null ) {
|
37 |
-
$this->
|
38 |
parent::__construct( 'MySQL' );
|
39 |
}
|
40 |
|
@@ -45,21 +45,21 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
45 |
* @throws Exception - Connection failed.
|
46 |
*/
|
47 |
public function TestConnection() {
|
48 |
-
error_reporting( E_ALL ^ ( E_NOTICE | E_WARNING | E_DEPRECATED ) );
|
49 |
-
$connection_config = $this->
|
50 |
-
$password = $this->
|
51 |
|
52 |
$new_wpdb = new wpdbCustom( $connection_config['user'], $password, $connection_config['db_name'], $connection_config['hostname'], $connection_config['is_ssl'], $connection_config['is_cc'], $connection_config['ssl_ca'], $connection_config['ssl_cert'], $connection_config['ssl_key'] );
|
53 |
|
54 |
if ( isset( $new_wpdb->error ) && isset( $new_wpdb->dbh ) ) {
|
55 |
throw new Exception( $new_wpdb->dbh->error, $new_wpdb->dbh->errno );
|
56 |
} elseif ( ! isset( $new_wpdb->dbh ) ) {
|
57 |
-
$error_code = mysqli_connect_errno();
|
58 |
|
59 |
if ( 1045 === $error_code ) {
|
60 |
throw new Exception( __( 'Error establishing a database connection. DB username or password are not valid.' ), $error_code );
|
61 |
} else {
|
62 |
-
$error_message = mysqli_connect_error();
|
63 |
// if we get an error message from mysqli then use it otherwise use a generic message.
|
64 |
if ( $error_message ) {
|
65 |
throw new Exception(
|
@@ -91,7 +91,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
91 |
* @return string
|
92 |
* @since 2.6.3
|
93 |
*/
|
94 |
-
public function
|
95 |
$encrypt_method = 'AES-256-CBC';
|
96 |
$secret_key = $this->truncateKey();
|
97 |
$secret_iv = $this->get_openssl_iv();
|
@@ -102,7 +102,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
102 |
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning.
|
103 |
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
|
104 |
|
105 |
-
return openssl_decrypt( base64_decode( $ciphertext_base64 ), $encrypt_method, $key, 0, $iv );
|
106 |
}
|
107 |
|
108 |
/**
|
@@ -140,24 +140,22 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
-
*
|
144 |
*/
|
145 |
-
public function
|
146 |
-
$current_wpdb = $this->
|
147 |
|
148 |
return $current_wpdb->close();
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
-
*
|
153 |
-
*
|
154 |
-
* @return wpdb
|
155 |
*/
|
156 |
-
public function
|
157 |
if ( ! empty( $this->connection ) ) {
|
158 |
return $this->connection;
|
159 |
} else {
|
160 |
-
$this->connection = $this->
|
161 |
|
162 |
return $this->connection;
|
163 |
}
|
@@ -168,10 +166,10 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
168 |
*
|
169 |
* @return wpdb Instance of WPDB.
|
170 |
*/
|
171 |
-
private function
|
172 |
-
if ( ! empty( $this->
|
173 |
-
$connection_config = $this->
|
174 |
-
$password = $this->
|
175 |
$new_wpdb = new wpdbCustom( $connection_config['user'], $password, $connection_config['db_name'], $connection_config['hostname'], $connection_config['is_ssl'], $connection_config['is_cc'], $connection_config['ssl_ca'], $connection_config['ssl_cert'], $connection_config['ssl_key'] );
|
176 |
if ( array_key_exists( 'baseprefix', $connection_config ) ) {
|
177 |
$new_wpdb->set_prefix( $connection_config['baseprefix'] );
|
@@ -186,12 +184,12 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
186 |
}
|
187 |
|
188 |
/**
|
189 |
-
* @inheritDoc
|
190 |
*/
|
191 |
-
public function
|
192 |
-
$obj_name = $this->
|
193 |
|
194 |
-
return new $obj_name( $this->
|
195 |
}
|
196 |
|
197 |
/**
|
@@ -201,76 +199,71 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
201 |
*
|
202 |
* @return string
|
203 |
*/
|
204 |
-
protected function
|
205 |
return 'WSAL_Adapters_MySQL_' . $class_name;
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
-
* @inheritDoc
|
210 |
*/
|
211 |
-
public function
|
212 |
-
$wpdb = $this->
|
213 |
$table = $wpdb->base_prefix . 'wsal_occurrences';
|
214 |
-
$db_result = $wpdb->query( "SELECT COUNT(1) FROM {$table};" );
|
215 |
|
216 |
return 1 === $db_result;
|
217 |
}
|
218 |
|
219 |
/**
|
220 |
-
*
|
221 |
-
*
|
222 |
-
* @param bool $is_external_database If true, some tables will not be created.
|
223 |
*/
|
224 |
-
public function
|
225 |
-
$adapter_list = WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->
|
226 |
$adapter_list = apply_filters( 'wsal_install_adapters_list', $adapter_list );
|
227 |
foreach ( $adapter_list as $file ) {
|
228 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
229 |
$file_name = $file_path[ count( $file_path ) - 1 ];
|
230 |
-
$class_name = $this->
|
231 |
-
$this->
|
232 |
}
|
233 |
}
|
234 |
|
235 |
/**
|
236 |
-
*
|
237 |
-
*
|
238 |
-
* @param string $class_name
|
239 |
-
* @param bool $is_external_database
|
240 |
*/
|
241 |
-
public function
|
242 |
if ( ! class_exists( $class_name ) ) {
|
243 |
return;
|
244 |
}
|
245 |
|
246 |
-
$class = new $class_name( $this->
|
247 |
if ( $is_external_database && $class instanceof WSAL_Adapters_MySQL_Session ) {
|
248 |
-
//
|
249 |
return;
|
250 |
}
|
251 |
|
252 |
if ( ! $is_external_database && $class instanceof WSAL_Adapters_MySQL_TmpUser ) {
|
253 |
-
//
|
254 |
return;
|
255 |
}
|
256 |
|
257 |
if ( is_subclass_of( $class, 'WSAL_Adapters_MySQL_ActiveRecord' ) ) {
|
258 |
-
$class->
|
259 |
}
|
260 |
}
|
261 |
|
262 |
/**
|
263 |
-
*
|
264 |
*/
|
265 |
-
public function
|
266 |
-
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->
|
267 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
268 |
$file_name = $file_path[ count( $file_path ) - 1 ];
|
269 |
-
$class_name = $this->
|
270 |
|
271 |
-
$class = new $class_name( $this->
|
272 |
if ( is_subclass_of( $class, 'WSAL_Adapters_MySQL_ActiveRecord' ) ) {
|
273 |
-
$class->
|
274 |
}
|
275 |
}
|
276 |
}
|
@@ -282,10 +275,10 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
282 |
*
|
283 |
* @return int
|
284 |
*/
|
285 |
-
public function
|
286 |
global $wpdb;
|
287 |
|
288 |
-
return $this->
|
289 |
}
|
290 |
|
291 |
/**
|
@@ -293,66 +286,70 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
293 |
*
|
294 |
* It also deletes the tables in the source database when there is no more data to migrate.
|
295 |
*
|
296 |
-
* @param wpdb $source_db
|
297 |
-
* @param wpdb $target_db
|
298 |
-
* @param int
|
299 |
*
|
300 |
* @return int Number of occurrence entries migrated.
|
301 |
*/
|
302 |
-
private function
|
303 |
-
//
|
304 |
$occurrence_adapter_source = new WSAL_Adapters_MySQL_Occurrence( $source_db );
|
305 |
-
if ( ! $occurrence_adapter_source->
|
306 |
return 0;
|
307 |
}
|
308 |
|
309 |
-
$sql = 'SELECT * FROM ' . $occurrence_adapter_source->
|
310 |
$occurrences = $source_db->get_results( $sql, ARRAY_A );
|
311 |
|
312 |
-
//
|
313 |
if ( empty( $occurrences ) ) {
|
314 |
-
$this->
|
315 |
-
$this->
|
316 |
|
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->
|
323 |
|
324 |
-
$occurrence_ids_to_delete =
|
325 |
foreach ( $occurrences as $entry ) {
|
326 |
|
327 |
-
$target_db->insert(
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
|
|
|
|
|
|
|
|
344 |
|
345 |
$old_entry_id = intval( $entry['id'] );
|
346 |
$new_entry_id = $target_db->insert_id;
|
347 |
-
$this->
|
348 |
|
349 |
array_push( $occurrence_ids_to_delete, $old_entry_id );
|
350 |
}
|
351 |
|
352 |
-
//
|
353 |
$meta_adapter_source = new WSAL_Adapters_MySQL_Meta( $source_db );
|
354 |
-
$source_db->query( 'DELETE FROM ' . $occurrence_adapter_source->
|
355 |
-
$source_db->query( 'DELETE FROM ' . $meta_adapter_source->
|
356 |
|
357 |
return count( $occurrence_ids_to_delete );
|
358 |
}
|
@@ -362,39 +359,39 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
362 |
*
|
363 |
* @param object $record - Type of record.
|
364 |
*/
|
365 |
-
private function
|
366 |
global $wpdb;
|
367 |
-
$sql = 'DROP TABLE IF EXISTS ' . $record->
|
368 |
-
$wpdb->query( $sql );
|
369 |
}
|
370 |
|
371 |
/**
|
372 |
* Migrate Metadata from WP DB to External DB.
|
373 |
*
|
374 |
-
* @param wpdb $source_db
|
375 |
-
* @param wpdb $target_db
|
376 |
-
* @param int
|
377 |
-
* @param int
|
378 |
*
|
379 |
* @return int Number of metadata migrated.
|
380 |
*/
|
381 |
-
private function
|
382 |
|
383 |
-
//
|
384 |
$meta_adapter_source = new WSAL_Adapters_MySQL_Meta( $source_db );
|
385 |
-
if ( ! $meta_adapter_source->
|
386 |
return 0;
|
387 |
}
|
388 |
|
389 |
-
$query = 'SELECT * FROM ' . $meta_adapter_source->
|
390 |
$prepared_query = $source_db->prepare( $query, $old_occurrence_id );
|
391 |
$metadata = $source_db->get_results( $prepared_query, ARRAY_A );
|
392 |
|
393 |
-
//
|
394 |
if ( ! empty( $metadata ) ) {
|
395 |
$meta_adapter_target = new WSAL_Adapters_MySQL_Meta( $target_db );
|
396 |
|
397 |
-
$query = 'INSERT INTO ' . $meta_adapter_target->
|
398 |
foreach ( $metadata as $entry ) {
|
399 |
$query .= $target_db->prepare(
|
400 |
'( %d, %s, %s ), ',
|
@@ -419,9 +416,9 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
419 |
*
|
420 |
* @return array
|
421 |
*/
|
422 |
-
public function
|
423 |
global $wpdb;
|
424 |
-
return $this->
|
425 |
}
|
426 |
|
427 |
/**
|
@@ -433,7 +430,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
433 |
* @return string
|
434 |
* @since 2.6.3
|
435 |
*/
|
436 |
-
public function
|
437 |
|
438 |
$ciphertext = false;
|
439 |
$encrypt_method = 'AES-256-CBC';
|
@@ -447,7 +444,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
447 |
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
|
448 |
|
449 |
$ciphertext = openssl_encrypt( $plaintext, $encrypt_method, $key, 0, $iv );
|
450 |
-
$ciphertext = base64_encode( $ciphertext );
|
451 |
|
452 |
return $ciphertext;
|
453 |
}
|
@@ -459,24 +456,26 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
459 |
* @param array $args - Archive Database and limit by count OR by date.
|
460 |
*
|
461 |
* @return array|false|null
|
|
|
|
|
462 |
*/
|
463 |
-
public function
|
464 |
-
$_wpdb = $this->
|
465 |
/** @var wpdbCustom $archive_db */
|
466 |
$archive_db = $args['archive_db'];
|
467 |
|
468 |
// Load data Occurrences from WP.
|
469 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
470 |
-
if ( ! $occurrence->
|
471 |
return null;
|
472 |
}
|
473 |
if ( ! empty( $args['by_date'] ) ) {
|
474 |
-
$sql = 'SELECT * FROM ' . $occurrence->
|
475 |
}
|
476 |
|
477 |
if ( ! empty( $args['by_limit'] ) ) {
|
478 |
-
$sql = 'SELECT occ.* FROM ' . $occurrence->
|
479 |
-
LEFT JOIN (SELECT id FROM ' . $occurrence->
|
480 |
on ids.id = occ.id
|
481 |
WHERE ids.id IS NULL';
|
482 |
}
|
@@ -497,7 +496,7 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
497 |
|
498 |
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $archive_db );
|
499 |
|
500 |
-
$sql = 'INSERT INTO ' . $occurrence_new->
|
501 |
foreach ( $occurrences as $entry ) {
|
502 |
|
503 |
$sql .= $archive_db->prepare(
|
@@ -540,25 +539,25 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
540 |
*
|
541 |
* @return array|false|null
|
542 |
*/
|
543 |
-
public function
|
544 |
-
$_wpdb = $this->
|
545 |
/** @var wpdbCustom $archive_db */
|
546 |
$archive_db = $args['archive_db'];
|
547 |
|
548 |
// Load data Meta from WP.
|
549 |
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
550 |
-
if ( ! $meta->
|
551 |
return null;
|
552 |
}
|
553 |
$s_occurrence_ids = implode( ', ', $args['occurrence_ids'] );
|
554 |
-
$sql = 'SELECT * FROM ' . $meta->
|
555 |
$metadata = $_wpdb->get_results( $sql, ARRAY_A );
|
556 |
|
557 |
// Insert data to Archive DB.
|
558 |
if ( ! empty( $metadata ) ) {
|
559 |
$meta_new = new WSAL_Adapters_MySQL_Meta( $archive_db );
|
560 |
|
561 |
-
$sql = 'INSERT INTO ' . $meta_new->
|
562 |
foreach ( $metadata as $entry ) {
|
563 |
$sql .= $archive_db->prepare(
|
564 |
'( %d, %s, %s ), ',
|
@@ -581,17 +580,17 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
581 |
*
|
582 |
* @param array $args - Archive Database and occurrences IDs.
|
583 |
*/
|
584 |
-
public function
|
585 |
-
$_wpdb = $this->
|
586 |
|
587 |
$s_occurrence_ids = implode( ', ', $args['occurrence_ids'] );
|
588 |
|
589 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
590 |
-
$sql = 'DELETE FROM ' . $occurrence->
|
591 |
$_wpdb->query( $sql );
|
592 |
|
593 |
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
594 |
-
$sql = 'DELETE FROM ' . $meta->
|
595 |
$_wpdb->query( $sql );
|
596 |
}
|
597 |
|
@@ -602,26 +601,26 @@ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements
|
|
602 |
*/
|
603 |
public function purge_activity() {
|
604 |
// Get connection.
|
605 |
-
$wpdb = $this->
|
606 |
|
607 |
// Get occurrence model.
|
608 |
$occ = new WSAL_Adapters_MySQL_Occurrence( $wpdb );
|
609 |
-
$sql = 'TRUNCATE ' . $occ->
|
610 |
-
$query_occ = $wpdb->query( $sql );
|
611 |
|
612 |
// Get meta model.
|
613 |
$meta = new WSAL_Adapters_MySQL_Meta( $wpdb );
|
614 |
-
$sql = 'TRUNCATE ' . $meta->
|
615 |
-
$query_meta = $wpdb->query( $sql );
|
616 |
|
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->
|
626 |
}
|
627 |
}
|
26 |
*
|
27 |
* @var array
|
28 |
*/
|
29 |
+
protected $connection_config = null;
|
30 |
|
31 |
/**
|
32 |
* Method: Constructor.
|
34 |
* @param array $connection_config - Connection config.
|
35 |
*/
|
36 |
public function __construct( $connection_config = null ) {
|
37 |
+
$this->connection_config = $connection_config;
|
38 |
parent::__construct( 'MySQL' );
|
39 |
}
|
40 |
|
45 |
* @throws Exception - Connection failed.
|
46 |
*/
|
47 |
public function TestConnection() {
|
48 |
+
error_reporting( E_ALL ^ ( E_NOTICE | E_WARNING | E_DEPRECATED ) ); // phpcs:ignore
|
49 |
+
$connection_config = $this->connection_config;
|
50 |
+
$password = $this->decrypt_string( $connection_config['password'] );
|
51 |
|
52 |
$new_wpdb = new wpdbCustom( $connection_config['user'], $password, $connection_config['db_name'], $connection_config['hostname'], $connection_config['is_ssl'], $connection_config['is_cc'], $connection_config['ssl_ca'], $connection_config['ssl_cert'], $connection_config['ssl_key'] );
|
53 |
|
54 |
if ( isset( $new_wpdb->error ) && isset( $new_wpdb->dbh ) ) {
|
55 |
throw new Exception( $new_wpdb->dbh->error, $new_wpdb->dbh->errno );
|
56 |
} elseif ( ! isset( $new_wpdb->dbh ) ) {
|
57 |
+
$error_code = mysqli_connect_errno(); // phpcs:ignore
|
58 |
|
59 |
if ( 1045 === $error_code ) {
|
60 |
throw new Exception( __( 'Error establishing a database connection. DB username or password are not valid.' ), $error_code );
|
61 |
} else {
|
62 |
+
$error_message = mysqli_connect_error(); // phpcs:ignore
|
63 |
// if we get an error message from mysqli then use it otherwise use a generic message.
|
64 |
if ( $error_message ) {
|
65 |
throw new Exception(
|
91 |
* @return string
|
92 |
* @since 2.6.3
|
93 |
*/
|
94 |
+
public function decrypt_string( $ciphertext_base64 ) {
|
95 |
$encrypt_method = 'AES-256-CBC';
|
96 |
$secret_key = $this->truncateKey();
|
97 |
$secret_iv = $this->get_openssl_iv();
|
102 |
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning.
|
103 |
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
|
104 |
|
105 |
+
return openssl_decrypt( base64_decode( $ciphertext_base64 ), $encrypt_method, $key, 0, $iv ); // phpcs:ignore
|
106 |
}
|
107 |
|
108 |
/**
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
+
* {@inheritDoc}
|
144 |
*/
|
145 |
+
public function close_connection() {
|
146 |
+
$current_wpdb = $this->get_connection();
|
147 |
|
148 |
return $current_wpdb->close();
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
+
* {@inheritDoc}
|
|
|
|
|
153 |
*/
|
154 |
+
public function get_connection() {
|
155 |
if ( ! empty( $this->connection ) ) {
|
156 |
return $this->connection;
|
157 |
} else {
|
158 |
+
$this->connection = $this->create_connection();
|
159 |
|
160 |
return $this->connection;
|
161 |
}
|
166 |
*
|
167 |
* @return wpdb Instance of WPDB.
|
168 |
*/
|
169 |
+
private function create_connection() {
|
170 |
+
if ( ! empty( $this->connection_config ) ) {
|
171 |
+
$connection_config = $this->connection_config;
|
172 |
+
$password = $this->decrypt_string( $connection_config['password'] );
|
173 |
$new_wpdb = new wpdbCustom( $connection_config['user'], $password, $connection_config['db_name'], $connection_config['hostname'], $connection_config['is_ssl'], $connection_config['is_cc'], $connection_config['ssl_ca'], $connection_config['ssl_cert'], $connection_config['ssl_key'] );
|
174 |
if ( array_key_exists( 'baseprefix', $connection_config ) ) {
|
175 |
$new_wpdb->set_prefix( $connection_config['baseprefix'] );
|
184 |
}
|
185 |
|
186 |
/**
|
187 |
+
* {@inheritDoc}
|
188 |
*/
|
189 |
+
public function get_adapter( $class_name ) {
|
190 |
+
$obj_name = $this->get_adapter_class_name( $class_name );
|
191 |
|
192 |
+
return new $obj_name( $this->get_connection() );
|
193 |
}
|
194 |
|
195 |
/**
|
199 |
*
|
200 |
* @return string
|
201 |
*/
|
202 |
+
protected function get_adapter_class_name( $class_name ) {
|
203 |
return 'WSAL_Adapters_MySQL_' . $class_name;
|
204 |
}
|
205 |
|
206 |
/**
|
207 |
+
* {@inheritDoc}
|
208 |
*/
|
209 |
+
public function is_installed() {
|
210 |
+
$wpdb = $this->get_connection();
|
211 |
$table = $wpdb->base_prefix . 'wsal_occurrences';
|
212 |
+
$db_result = $wpdb->query( "SELECT COUNT(1) FROM {$table};" ); // phpcs:ignore
|
213 |
|
214 |
return 1 === $db_result;
|
215 |
}
|
216 |
|
217 |
/**
|
218 |
+
* {@inheritDoc}
|
|
|
|
|
219 |
*/
|
220 |
+
public function install_all( $is_external_database = false ) {
|
221 |
+
$adapter_list = WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->get_adapters_directory(), '*.php' );
|
222 |
$adapter_list = apply_filters( 'wsal_install_adapters_list', $adapter_list );
|
223 |
foreach ( $adapter_list as $file ) {
|
224 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
225 |
$file_name = $file_path[ count( $file_path ) - 1 ];
|
226 |
+
$class_name = $this->get_adapter_class_name( str_replace( 'Adapter.php', '', $file_name ) );
|
227 |
+
$this->install_single( $class_name, $is_external_database );
|
228 |
}
|
229 |
}
|
230 |
|
231 |
/**
|
232 |
+
* {@inheritDoc}
|
|
|
|
|
|
|
233 |
*/
|
234 |
+
public function install_single( $class_name, $is_external_database = false ) {
|
235 |
if ( ! class_exists( $class_name ) ) {
|
236 |
return;
|
237 |
}
|
238 |
|
239 |
+
$class = new $class_name( $this->get_connection() );
|
240 |
if ( $is_external_database && $class instanceof WSAL_Adapters_MySQL_Session ) {
|
241 |
+
// Sessions table should only ever exist only in local database.
|
242 |
return;
|
243 |
}
|
244 |
|
245 |
if ( ! $is_external_database && $class instanceof WSAL_Adapters_MySQL_TmpUser ) {
|
246 |
+
// Exclude the tmp_users table for local database.
|
247 |
return;
|
248 |
}
|
249 |
|
250 |
if ( is_subclass_of( $class, 'WSAL_Adapters_MySQL_ActiveRecord' ) ) {
|
251 |
+
$class->install();
|
252 |
}
|
253 |
}
|
254 |
|
255 |
/**
|
256 |
+
* {@inheritDoc}
|
257 |
*/
|
258 |
+
public function uninstall_all() {
|
259 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->get_adapters_directory(), '*.php' ) as $file ) {
|
260 |
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
261 |
$file_name = $file_path[ count( $file_path ) - 1 ];
|
262 |
+
$class_name = $this->get_adapter_class_name( str_replace( 'Adapter.php', '', $file_name ) );
|
263 |
|
264 |
+
$class = new $class_name( $this->get_connection() );
|
265 |
if ( is_subclass_of( $class, 'WSAL_Adapters_MySQL_ActiveRecord' ) ) {
|
266 |
+
$class->uninstall();
|
267 |
}
|
268 |
}
|
269 |
}
|
275 |
*
|
276 |
* @return int
|
277 |
*/
|
278 |
+
public function migrate_occurrence_from_local_to_external( $limit ) {
|
279 |
global $wpdb;
|
280 |
|
281 |
+
return $this->migrate_occurrence( $wpdb, $this->get_connection(), $limit );
|
282 |
}
|
283 |
|
284 |
/**
|
286 |
*
|
287 |
* It also deletes the tables in the source database when there is no more data to migrate.
|
288 |
*
|
289 |
+
* @param wpdb $source_db Source database.
|
290 |
+
* @param wpdb $target_db Target database.
|
291 |
+
* @param int $limit Number of entries to migrate.
|
292 |
*
|
293 |
* @return int Number of occurrence entries migrated.
|
294 |
*/
|
295 |
+
private function migrate_occurrence( $source_db, $target_db, $limit ) {
|
296 |
+
// Load occurrence data from the source database.
|
297 |
$occurrence_adapter_source = new WSAL_Adapters_MySQL_Occurrence( $source_db );
|
298 |
+
if ( ! $occurrence_adapter_source->is_installed() ) {
|
299 |
return 0;
|
300 |
}
|
301 |
|
302 |
+
$sql = 'SELECT * FROM ' . $occurrence_adapter_source->get_table() . ' LIMIT ' . $limit;
|
303 |
$occurrences = $source_db->get_results( $sql, ARRAY_A );
|
304 |
|
305 |
+
// No more data to migrate, delete the old tables.
|
306 |
if ( empty( $occurrences ) ) {
|
307 |
+
$this->delete_after_migrate( $occurrence_adapter_source );
|
308 |
+
$this->delete_after_migrate( new WSAL_Adapters_MySQL_Meta( $source_db ) );
|
309 |
|
310 |
return 0;
|
311 |
}
|
312 |
|
313 |
// Insert data to the target database.
|
314 |
$occurrence_adapter_target = new WSAL_Adapters_MySQL_Occurrence( $target_db );
|
315 |
+
$occurrence_table_name_target = $occurrence_adapter_target->get_table();
|
316 |
|
317 |
+
$occurrence_ids_to_delete = array();
|
318 |
foreach ( $occurrences as $entry ) {
|
319 |
|
320 |
+
$target_db->insert(
|
321 |
+
$occurrence_table_name_target,
|
322 |
+
array(
|
323 |
+
'site_id' => $entry['site_id'],
|
324 |
+
'alert_id' => $entry['alert_id'],
|
325 |
+
'created_on' => $entry['created_on'],
|
326 |
+
'client_ip' => $entry['client_ip'],
|
327 |
+
'severity' => $entry['severity'],
|
328 |
+
'object' => $entry['object'],
|
329 |
+
'event_type' => $entry['event_type'],
|
330 |
+
'user_agent' => $entry['user_agent'],
|
331 |
+
'user_roles' => $entry['user_roles'],
|
332 |
+
'username' => $entry['username'],
|
333 |
+
'user_id' => $entry['user_id'],
|
334 |
+
'session_id' => $entry['session_id'],
|
335 |
+
'post_status' => $entry['post_status'],
|
336 |
+
'post_type' => $entry['post_type'],
|
337 |
+
'post_id' => $entry['post_id'],
|
338 |
+
),
|
339 |
+
array( '%d', '%d', '%f', '%s', '%d', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%s', '%s', '%d' )
|
340 |
+
);
|
341 |
|
342 |
$old_entry_id = intval( $entry['id'] );
|
343 |
$new_entry_id = $target_db->insert_id;
|
344 |
+
$this->migrate_meta( $source_db, $target_db, $old_entry_id, $new_entry_id );
|
345 |
|
346 |
array_push( $occurrence_ids_to_delete, $old_entry_id );
|
347 |
}
|
348 |
|
349 |
+
// Delete migrated events and associated meta data.
|
350 |
$meta_adapter_source = new WSAL_Adapters_MySQL_Meta( $source_db );
|
351 |
+
$source_db->query( 'DELETE FROM ' . $occurrence_adapter_source->get_table() . ' WHERE id IN (' . implode( ',', $occurrence_ids_to_delete ) . ');' );
|
352 |
+
$source_db->query( 'DELETE FROM ' . $meta_adapter_source->get_table() . ' WHERE occurrence_id IN (' . implode( ',', $occurrence_ids_to_delete ) . ');' );
|
353 |
|
354 |
return count( $occurrence_ids_to_delete );
|
355 |
}
|
359 |
*
|
360 |
* @param object $record - Type of record.
|
361 |
*/
|
362 |
+
private function delete_after_migrate( $record ) {
|
363 |
global $wpdb;
|
364 |
+
$sql = 'DROP TABLE IF EXISTS ' . $record->get_table();
|
365 |
+
$wpdb->query( $sql ); // phpcs:ignore
|
366 |
}
|
367 |
|
368 |
/**
|
369 |
* Migrate Metadata from WP DB to External DB.
|
370 |
*
|
371 |
+
* @param wpdb $source_db Source database.
|
372 |
+
* @param wpdb $target_db Target database.
|
373 |
+
* @param int $old_occurrence_id Old occurrence ID.
|
374 |
+
* @param int $new_occurrence_id New occurrence ID.
|
375 |
*
|
376 |
* @return int Number of metadata migrated.
|
377 |
*/
|
378 |
+
private function migrate_meta( $source_db, $target_db, $old_occurrence_id, $new_occurrence_id ) {
|
379 |
|
380 |
+
// Load meta data from the source database.
|
381 |
$meta_adapter_source = new WSAL_Adapters_MySQL_Meta( $source_db );
|
382 |
+
if ( ! $meta_adapter_source->is_installed() ) {
|
383 |
return 0;
|
384 |
}
|
385 |
|
386 |
+
$query = 'SELECT * FROM ' . $meta_adapter_source->get_table() . ' WHERE occurrence_id = %d;';
|
387 |
$prepared_query = $source_db->prepare( $query, $old_occurrence_id );
|
388 |
$metadata = $source_db->get_results( $prepared_query, ARRAY_A );
|
389 |
|
390 |
+
// Insert meta data to target database.
|
391 |
if ( ! empty( $metadata ) ) {
|
392 |
$meta_adapter_target = new WSAL_Adapters_MySQL_Meta( $target_db );
|
393 |
|
394 |
+
$query = 'INSERT INTO ' . $meta_adapter_target->get_table() . ' (occurrence_id, name, value) VALUES ';
|
395 |
foreach ( $metadata as $entry ) {
|
396 |
$query .= $target_db->prepare(
|
397 |
'( %d, %s, %s ), ',
|
416 |
*
|
417 |
* @return array
|
418 |
*/
|
419 |
+
public function migrate_occurrence_from_external_to_local( $limit ) {
|
420 |
global $wpdb;
|
421 |
+
return $this->migrate_occurrence( $this->get_connection(), $wpdb, $limit );
|
422 |
}
|
423 |
|
424 |
/**
|
430 |
* @return string
|
431 |
* @since 2.6.3
|
432 |
*/
|
433 |
+
public function encrypt_string( $plaintext ) {
|
434 |
|
435 |
$ciphertext = false;
|
436 |
$encrypt_method = 'AES-256-CBC';
|
444 |
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
|
445 |
|
446 |
$ciphertext = openssl_encrypt( $plaintext, $encrypt_method, $key, 0, $iv );
|
447 |
+
$ciphertext = base64_encode( $ciphertext ); // phpcs:ignore
|
448 |
|
449 |
return $ciphertext;
|
450 |
}
|
456 |
* @param array $args - Archive Database and limit by count OR by date.
|
457 |
*
|
458 |
* @return array|false|null
|
459 |
+
*
|
460 |
+
* @phpcs:disable Generic.Commenting.DocComment.MissingShort
|
461 |
*/
|
462 |
+
public function archive_occurrence( $args ) {
|
463 |
+
$_wpdb = $this->get_connection();
|
464 |
/** @var wpdbCustom $archive_db */
|
465 |
$archive_db = $args['archive_db'];
|
466 |
|
467 |
// Load data Occurrences from WP.
|
468 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
469 |
+
if ( ! $occurrence->is_installed() ) {
|
470 |
return null;
|
471 |
}
|
472 |
if ( ! empty( $args['by_date'] ) ) {
|
473 |
+
$sql = 'SELECT * FROM ' . $occurrence->get_table() . ' WHERE created_on <= ' . $args['by_date'];
|
474 |
}
|
475 |
|
476 |
if ( ! empty( $args['by_limit'] ) ) {
|
477 |
+
$sql = 'SELECT occ.* FROM ' . $occurrence->get_table() . ' occ
|
478 |
+
LEFT JOIN (SELECT id FROM ' . $occurrence->get_table() . ' order by created_on DESC limit ' . $args['by_limit'] . ') as ids
|
479 |
on ids.id = occ.id
|
480 |
WHERE ids.id IS NULL';
|
481 |
}
|
496 |
|
497 |
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $archive_db );
|
498 |
|
499 |
+
$sql = 'INSERT INTO ' . $occurrence_new->get_table() . ' ( 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 ';
|
500 |
foreach ( $occurrences as $entry ) {
|
501 |
|
502 |
$sql .= $archive_db->prepare(
|
539 |
*
|
540 |
* @return array|false|null
|
541 |
*/
|
542 |
+
public function archive_meta( $args ) {
|
543 |
+
$_wpdb = $this->get_connection();
|
544 |
/** @var wpdbCustom $archive_db */
|
545 |
$archive_db = $args['archive_db'];
|
546 |
|
547 |
// Load data Meta from WP.
|
548 |
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
549 |
+
if ( ! $meta->is_installed() ) {
|
550 |
return null;
|
551 |
}
|
552 |
$s_occurrence_ids = implode( ', ', $args['occurrence_ids'] );
|
553 |
+
$sql = 'SELECT * FROM ' . $meta->get_table() . ' WHERE occurrence_id IN (' . $s_occurrence_ids . ')';
|
554 |
$metadata = $_wpdb->get_results( $sql, ARRAY_A );
|
555 |
|
556 |
// Insert data to Archive DB.
|
557 |
if ( ! empty( $metadata ) ) {
|
558 |
$meta_new = new WSAL_Adapters_MySQL_Meta( $archive_db );
|
559 |
|
560 |
+
$sql = 'INSERT INTO ' . $meta_new->get_table() . ' (occurrence_id, name, value) VALUES ';
|
561 |
foreach ( $metadata as $entry ) {
|
562 |
$sql .= $archive_db->prepare(
|
563 |
'( %d, %s, %s ), ',
|
580 |
*
|
581 |
* @param array $args - Archive Database and occurrences IDs.
|
582 |
*/
|
583 |
+
public function delete_after_archive( $args ) {
|
584 |
+
$_wpdb = $this->get_connection();
|
585 |
|
586 |
$s_occurrence_ids = implode( ', ', $args['occurrence_ids'] );
|
587 |
|
588 |
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
589 |
+
$sql = 'DELETE FROM ' . $occurrence->get_table() . ' WHERE id IN (' . $s_occurrence_ids . ')';
|
590 |
$_wpdb->query( $sql );
|
591 |
|
592 |
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
593 |
+
$sql = 'DELETE FROM ' . $meta->get_table() . ' WHERE occurrence_id IN (' . $s_occurrence_ids . ')';
|
594 |
$_wpdb->query( $sql );
|
595 |
}
|
596 |
|
601 |
*/
|
602 |
public function purge_activity() {
|
603 |
// Get connection.
|
604 |
+
$wpdb = $this->get_connection();
|
605 |
|
606 |
// Get occurrence model.
|
607 |
$occ = new WSAL_Adapters_MySQL_Occurrence( $wpdb );
|
608 |
+
$sql = 'TRUNCATE ' . $occ->get_table();
|
609 |
+
$query_occ = $wpdb->query( $sql ); // phpcs:ignore
|
610 |
|
611 |
// Get meta model.
|
612 |
$meta = new WSAL_Adapters_MySQL_Meta( $wpdb );
|
613 |
+
$sql = 'TRUNCATE ' . $meta->get_table();
|
614 |
+
$query_meta = $wpdb->query( $sql ); // phpcs:ignore
|
615 |
|
616 |
// If both queries are successful, then return true.
|
617 |
return $query_occ && $query_meta;
|
618 |
}
|
619 |
|
620 |
/**
|
621 |
+
* {@inheritDoc}
|
622 |
*/
|
623 |
public function query( $query ) {
|
624 |
+
return $this->get_connection()->query( $query );
|
625 |
}
|
626 |
}
|
classes/Connector/wp-db-custom.php
CHANGED
@@ -18,6 +18,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
18 |
* It uses wpdb WordPress DB Class.
|
19 |
*
|
20 |
* @package wsal
|
|
|
|
|
21 |
*/
|
22 |
class wpdbCustom extends wpdb {
|
23 |
|
@@ -87,17 +89,17 @@ class wpdbCustom extends wpdb {
|
|
87 |
* If $allow_bail is false, the lack of database connection will need
|
88 |
* to be handled manually.
|
89 |
*
|
90 |
-
* @since 3.0.0
|
91 |
-
* @since 3.9.0 $allow_bail parameter added.
|
92 |
-
*
|
93 |
* @param bool $allow_bail Optional. Allows the function to bail. Default true.
|
|
|
94 |
* @return bool True with a successful connection, false on failure.
|
|
|
|
|
95 |
*/
|
96 |
public function db_connect( $allow_bail = true ) {
|
97 |
$this->is_mysql = true;
|
98 |
-
$client_flags
|
99 |
if ( $this->use_mysqli ) {
|
100 |
-
$this->dbh = mysqli_init();
|
101 |
|
102 |
// mysqli_real_connect doesn't support the host param including a port or socket
|
103 |
// like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
|
@@ -138,7 +140,7 @@ class wpdbCustom extends wpdb {
|
|
138 |
$ssl_opts_set = false;
|
139 |
}
|
140 |
if ( $ssl_opts_set ) {
|
141 |
-
mysqli_ssl_set(
|
142 |
$this->dbh,
|
143 |
$ssl_opts['KEY'],
|
144 |
$ssl_opts['CERT'],
|
@@ -149,9 +151,9 @@ class wpdbCustom extends wpdb {
|
|
149 |
}
|
150 |
|
151 |
if ( WP_DEBUG ) {
|
152 |
-
mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
|
153 |
} else {
|
154 |
-
@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
|
155 |
}
|
156 |
|
157 |
if ( $this->dbh->connect_errno ) {
|
@@ -166,8 +168,8 @@ class wpdbCustom extends wpdb {
|
|
166 |
$attempt_fallback = true;
|
167 |
|
168 |
if ( $this->has_connected
|
169 |
-
|
170 |
-
|
171 |
$attempt_fallback = false;
|
172 |
}
|
173 |
|
@@ -207,7 +209,7 @@ class wpdbCustom extends wpdb {
|
|
207 |
*
|
208 |
* @since 0.71
|
209 |
*
|
210 |
-
* @param string $db MySQL database name
|
211 |
* @param resource|null $dbh Optional link identifier.
|
212 |
*/
|
213 |
public function select( $db, $dbh = null ) {
|
@@ -216,13 +218,13 @@ class wpdbCustom extends wpdb {
|
|
216 |
}
|
217 |
|
218 |
if ( $this->use_mysqli ) {
|
219 |
-
$success = mysqli_select_db( $dbh, $db );
|
220 |
} else {
|
221 |
-
$success = mysql_select_db( $db, $dbh );
|
222 |
}
|
223 |
|
224 |
if ( ! $success ) {
|
225 |
-
$this->ready
|
226 |
$this->db_select_error = true;
|
227 |
}
|
228 |
}
|
18 |
* It uses wpdb WordPress DB Class.
|
19 |
*
|
20 |
* @package wsal
|
21 |
+
*
|
22 |
+
* @phpcs:disable PEAR.NamingConventions.ValidClassName.StartWithCapital
|
23 |
*/
|
24 |
class wpdbCustom extends wpdb {
|
25 |
|
89 |
* If $allow_bail is false, the lack of database connection will need
|
90 |
* to be handled manually.
|
91 |
*
|
|
|
|
|
|
|
92 |
* @param bool $allow_bail Optional. Allows the function to bail. Default true.
|
93 |
+
*
|
94 |
* @return bool True with a successful connection, false on failure.
|
95 |
+
* @since 3.0.0
|
96 |
+
* @since 3.9.0 $allow_bail parameter added.
|
97 |
*/
|
98 |
public function db_connect( $allow_bail = true ) {
|
99 |
$this->is_mysql = true;
|
100 |
+
$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
|
101 |
if ( $this->use_mysqli ) {
|
102 |
+
$this->dbh = mysqli_init(); // phpcs:ignore
|
103 |
|
104 |
// mysqli_real_connect doesn't support the host param including a port or socket
|
105 |
// like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
|
140 |
$ssl_opts_set = false;
|
141 |
}
|
142 |
if ( $ssl_opts_set ) {
|
143 |
+
mysqli_ssl_set( // phpcs:ignore
|
144 |
$this->dbh,
|
145 |
$ssl_opts['KEY'],
|
146 |
$ssl_opts['CERT'],
|
151 |
}
|
152 |
|
153 |
if ( WP_DEBUG ) {
|
154 |
+
mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags ); // phpcs:ignore
|
155 |
} else {
|
156 |
+
@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags ); // phpcs:ignore
|
157 |
}
|
158 |
|
159 |
if ( $this->dbh->connect_errno ) {
|
168 |
$attempt_fallback = true;
|
169 |
|
170 |
if ( $this->has_connected
|
171 |
+
|| ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL )
|
172 |
+
|| ( ! function_exists( 'mysql_connect' ) ) ) {
|
173 |
$attempt_fallback = false;
|
174 |
}
|
175 |
|
209 |
*
|
210 |
* @since 0.71
|
211 |
*
|
212 |
+
* @param string $db MySQL database name.
|
213 |
* @param resource|null $dbh Optional link identifier.
|
214 |
*/
|
215 |
public function select( $db, $dbh = null ) {
|
218 |
}
|
219 |
|
220 |
if ( $this->use_mysqli ) {
|
221 |
+
$success = mysqli_select_db( $dbh, $db ); // phpcs:ignore
|
222 |
} else {
|
223 |
+
$success = mysql_select_db( $db, $dbh ); // phpcs:ignore
|
224 |
}
|
225 |
|
226 |
if ( ! $success ) {
|
227 |
+
$this->ready = false;
|
228 |
$this->db_select_error = true;
|
229 |
}
|
230 |
}
|
classes/ConstantManager.php
CHANGED
@@ -28,7 +28,7 @@ class WSAL_ConstantManager {
|
|
28 |
*
|
29 |
* @var array
|
30 |
*/
|
31 |
-
protected $
|
32 |
|
33 |
/**
|
34 |
* Constants Cache.
|
@@ -43,8 +43,8 @@ class WSAL_ConstantManager {
|
|
43 |
* @param string $name - Constant name.
|
44 |
* @param string $description - Constant description.
|
45 |
*/
|
46 |
-
public function
|
47 |
-
$this->
|
48 |
'name' => $name,
|
49 |
'value' => constant( $name ),
|
50 |
'description' => $description,
|
@@ -60,7 +60,7 @@ class WSAL_ConstantManager {
|
|
60 |
*
|
61 |
* @throws Exception - Error if a constant is already defined.
|
62 |
*/
|
63 |
-
public function
|
64 |
// Check for constant conflict and define new one if required.
|
65 |
if ( defined( $name ) && constant( $name ) !== $value ) {
|
66 |
throw new Exception( 'Constant already defined with a different value.' );
|
@@ -68,17 +68,19 @@ class WSAL_ConstantManager {
|
|
68 |
define( $name, $value );
|
69 |
}
|
70 |
// Add constant to da list.
|
71 |
-
$this->
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
* Add multiple constants in one go.
|
76 |
*
|
77 |
* @param array $items - Array of arrays with name, value, description pairs.
|
|
|
|
|
78 |
*/
|
79 |
-
public function
|
80 |
foreach ( $items as $item ) {
|
81 |
-
$this->
|
82 |
}
|
83 |
}
|
84 |
|
@@ -87,9 +89,9 @@ class WSAL_ConstantManager {
|
|
87 |
*
|
88 |
* @param array $items - Array of arrays with name, description pairs.
|
89 |
*/
|
90 |
-
public function
|
91 |
foreach ( $items as $item ) {
|
92 |
-
$this->
|
93 |
}
|
94 |
}
|
95 |
|
@@ -104,11 +106,11 @@ class WSAL_ConstantManager {
|
|
104 |
*
|
105 |
* @return mixed Either constant details (props: name, value, description) or $default if not found.
|
106 |
*/
|
107 |
-
public function
|
108 |
// Make sure we do have some constants.
|
109 |
-
if ( ! empty( $this->
|
110 |
// Make sure that constants do have a $what property.
|
111 |
-
if ( ! isset( $this->
|
112 |
throw new Exception( 'Unexpected detail type "' . $what . '".' );
|
113 |
}
|
114 |
|
@@ -119,14 +121,14 @@ class WSAL_ConstantManager {
|
|
119 |
|
120 |
$possible_matches = array();
|
121 |
// Return constant match the property value.
|
122 |
-
foreach ( $this->
|
123 |
-
if ( $value == $constant->$what ) {
|
124 |
$this->constants_cache[ $value ] = $constant;
|
125 |
$possible_matches[] = $constant;
|
126 |
}
|
127 |
}
|
128 |
|
129 |
-
// If we got matches then get the last one in the array
|
130 |
if ( ! empty( $possible_matches ) ) {
|
131 |
return end( $possible_matches );
|
132 |
}
|
@@ -138,7 +140,10 @@ class WSAL_ConstantManager {
|
|
138 |
* Get constant object for displaying.
|
139 |
*
|
140 |
* @param integer $code - Value of the constant.
|
|
|
141 |
* @return stdClass
|
|
|
|
|
142 |
*/
|
143 |
public function get_constant_to_display( $code ) {
|
144 |
$const = (object) array(
|
@@ -147,11 +152,11 @@ class WSAL_ConstantManager {
|
|
147 |
'description' => __( 'Unknown error code.', 'wp-security-audit-log' ),
|
148 |
);
|
149 |
|
150 |
-
$const = $this->
|
151 |
|
152 |
-
//
|
153 |
-
//
|
154 |
-
if ( ! property_exists($const, 'css')) {
|
155 |
$const->css = strtolower( $const->name );
|
156 |
}
|
157 |
|
28 |
*
|
29 |
* @var array
|
30 |
*/
|
31 |
+
protected $constants = array();
|
32 |
|
33 |
/**
|
34 |
* Constants Cache.
|
43 |
* @param string $name - Constant name.
|
44 |
* @param string $description - Constant description.
|
45 |
*/
|
46 |
+
public function use_constant( $name, $description = '' ) {
|
47 |
+
$this->constants[] = (object) array(
|
48 |
'name' => $name,
|
49 |
'value' => constant( $name ),
|
50 |
'description' => $description,
|
60 |
*
|
61 |
* @throws Exception - Error if a constant is already defined.
|
62 |
*/
|
63 |
+
public function add_constant( $name, $value, $description = '' ) {
|
64 |
// Check for constant conflict and define new one if required.
|
65 |
if ( defined( $name ) && constant( $name ) !== $value ) {
|
66 |
throw new Exception( 'Constant already defined with a different value.' );
|
68 |
define( $name, $value );
|
69 |
}
|
70 |
// Add constant to da list.
|
71 |
+
$this->use_constant( $name, $description );
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
* Add multiple constants in one go.
|
76 |
*
|
77 |
* @param array $items - Array of arrays with name, value, description pairs.
|
78 |
+
*
|
79 |
+
* @throws Exception Error if a constant is already defined.
|
80 |
*/
|
81 |
+
public function add_constants( $items ) {
|
82 |
foreach ( $items as $item ) {
|
83 |
+
$this->add_constant( $item['name'], $item['value'], $item['description'] );
|
84 |
}
|
85 |
}
|
86 |
|
89 |
*
|
90 |
* @param array $items - Array of arrays with name, description pairs.
|
91 |
*/
|
92 |
+
public function use_constants( $items ) {
|
93 |
foreach ( $items as $item ) {
|
94 |
+
$this->use_constant( $item['name'], $item['description'] );
|
95 |
}
|
96 |
}
|
97 |
|
106 |
*
|
107 |
* @return mixed Either constant details (props: name, value, description) or $default if not found.
|
108 |
*/
|
109 |
+
public function get_constant_by( $what, $value, $default = null ) {
|
110 |
// Make sure we do have some constants.
|
111 |
+
if ( ! empty( $this->constants ) ) {
|
112 |
// Make sure that constants do have a $what property.
|
113 |
+
if ( ! isset( $this->constants[0]->$what ) ) {
|
114 |
throw new Exception( 'Unexpected detail type "' . $what . '".' );
|
115 |
}
|
116 |
|
121 |
|
122 |
$possible_matches = array();
|
123 |
// Return constant match the property value.
|
124 |
+
foreach ( $this->constants as $constant ) {
|
125 |
+
if ( $value == $constant->$what ) { // phpcs:ignore
|
126 |
$this->constants_cache[ $value ] = $constant;
|
127 |
$possible_matches[] = $constant;
|
128 |
}
|
129 |
}
|
130 |
|
131 |
+
// If we got matches then get the last one in the array.
|
132 |
if ( ! empty( $possible_matches ) ) {
|
133 |
return end( $possible_matches );
|
134 |
}
|
140 |
* Get constant object for displaying.
|
141 |
*
|
142 |
* @param integer $code - Value of the constant.
|
143 |
+
*
|
144 |
* @return stdClass
|
145 |
+
*
|
146 |
+
* @throws Exception Error if a constant is already defined.
|
147 |
*/
|
148 |
public function get_constant_to_display( $code ) {
|
149 |
$const = (object) array(
|
152 |
'description' => __( 'Unknown error code.', 'wp-security-audit-log' ),
|
153 |
);
|
154 |
|
155 |
+
$const = $this->get_constant_by( 'value', $code, $const );
|
156 |
|
157 |
+
// CSS property was added in 4.3.0 as part of severity levels refactoring to be able to print language
|
158 |
+
// independent CSS class not based on the constant value.
|
159 |
+
if ( ! property_exists( $const, 'css' ) ) {
|
160 |
$const->css = strtolower( $const->name );
|
161 |
}
|
162 |
|
classes/ExtensionPlaceholderView.php
CHANGED
@@ -1,64 +1,88 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Abstract class used for the plugin extension placeholder views/admin pages.
|
5 |
*
|
6 |
-
* @see
|
7 |
-
* @package
|
8 |
-
* @
|
|
|
9 |
*/
|
10 |
abstract class WSAL_ExtensionPlaceholderView extends WSAL_AbstractView {
|
11 |
|
|
|
|
|
|
|
12 |
public function is_title_visible() {
|
13 |
return false;
|
14 |
}
|
15 |
|
16 |
-
|
|
|
|
|
|
|
17 |
return 'dashicons-external';
|
18 |
}
|
19 |
|
20 |
-
|
|
|
|
|
|
|
21 |
// Extension Page CSS.
|
22 |
-
$
|
23 |
wp_enqueue_style(
|
24 |
'extensions',
|
25 |
-
$this->
|
26 |
array(),
|
27 |
-
filemtime( $this->
|
28 |
);
|
29 |
|
30 |
// Simple lightbox CSS.
|
31 |
-
$
|
32 |
wp_enqueue_style(
|
33 |
'wsal-simple-lightbox-css',
|
34 |
-
$this->
|
35 |
array(),
|
36 |
-
filemtime( $this->
|
37 |
);
|
38 |
}
|
39 |
|
40 |
-
|
|
|
|
|
|
|
41 |
// jQuery.
|
42 |
wp_enqueue_script( 'jquery' );
|
43 |
|
44 |
// Simple lightbox JS.
|
45 |
-
$
|
46 |
wp_register_script(
|
47 |
'wsal-simple-lightbox-js',
|
48 |
-
$this->
|
49 |
array( 'jquery' ),
|
50 |
-
filemtime( $this->
|
51 |
false
|
52 |
);
|
53 |
wp_enqueue_script( 'wsal-simple-lightbox-js' );
|
54 |
|
55 |
// Extensions JS.
|
56 |
-
$
|
57 |
wp_register_script(
|
58 |
'wsal-extensions-js',
|
59 |
-
$this->
|
60 |
array( 'wsal-simple-lightbox-js' ),
|
61 |
-
filemtime( $this->
|
62 |
false
|
63 |
);
|
64 |
wp_enqueue_script( 'wsal-extensions-js' );
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Abstract extension placeholder view class file.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage views
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly.
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
|
14 |
/**
|
15 |
* Abstract class used for the plugin extension placeholder views/admin pages.
|
16 |
*
|
17 |
+
* @see Views/*.php
|
18 |
+
* @package wsal
|
19 |
+
* @subpackage views
|
20 |
+
* @since 4.1.5.2
|
21 |
*/
|
22 |
abstract class WSAL_ExtensionPlaceholderView extends WSAL_AbstractView {
|
23 |
|
24 |
+
/**
|
25 |
+
* {@inheritDoc}
|
26 |
+
*/
|
27 |
public function is_title_visible() {
|
28 |
return false;
|
29 |
}
|
30 |
|
31 |
+
/**
|
32 |
+
* {@inheritDoc}
|
33 |
+
*/
|
34 |
+
public function get_icon() {
|
35 |
return 'dashicons-external';
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* {@inheritDoc}
|
40 |
+
*/
|
41 |
+
public function header() {
|
42 |
// Extension Page CSS.
|
43 |
+
$extensions_file = '/css/extensions.css';
|
44 |
wp_enqueue_style(
|
45 |
'extensions',
|
46 |
+
$this->plugin->get_base_url() . $extensions_file,
|
47 |
array(),
|
48 |
+
filemtime( $this->plugin->get_base_dir() . $extensions_file )
|
49 |
);
|
50 |
|
51 |
// Simple lightbox CSS.
|
52 |
+
$simple_lightbox_file = '/css/dist/simple-lightbox.min.css';
|
53 |
wp_enqueue_style(
|
54 |
'wsal-simple-lightbox-css',
|
55 |
+
$this->plugin->get_base_url() . $simple_lightbox_file,
|
56 |
array(),
|
57 |
+
filemtime( $this->plugin->get_base_dir() . $simple_lightbox_file )
|
58 |
);
|
59 |
}
|
60 |
|
61 |
+
/**
|
62 |
+
* {@inheritDoc}
|
63 |
+
*/
|
64 |
+
public function footer() {
|
65 |
// jQuery.
|
66 |
wp_enqueue_script( 'jquery' );
|
67 |
|
68 |
// Simple lightbox JS.
|
69 |
+
$simple_lightbox_file = '/js/dist/simple-lightbox.jquery.min.js';
|
70 |
wp_register_script(
|
71 |
'wsal-simple-lightbox-js',
|
72 |
+
$this->plugin->get_base_url() . $simple_lightbox_file,
|
73 |
array( 'jquery' ),
|
74 |
+
filemtime( $this->plugin->get_base_dir() . $simple_lightbox_file ),
|
75 |
false
|
76 |
);
|
77 |
wp_enqueue_script( 'wsal-simple-lightbox-js' );
|
78 |
|
79 |
// Extensions JS.
|
80 |
+
$extensions_file = '/js/extensions.js';
|
81 |
wp_register_script(
|
82 |
'wsal-extensions-js',
|
83 |
+
$this->plugin->get_base_url() . $extensions_file,
|
84 |
array( 'wsal-simple-lightbox-js' ),
|
85 |
+
filemtime( $this->plugin->get_base_dir() . $extensions_file ),
|
86 |
false
|
87 |
);
|
88 |
wp_enqueue_script( 'wsal-extensions-js' );
|
classes/Helpers/DataHelper.php
CHANGED
@@ -25,8 +25,8 @@ class WSAL_Helpers_DataHelper {
|
|
25 |
* @param mixed $data The data to encode.
|
26 |
* @return string JSON string.
|
27 |
*/
|
28 |
-
public static function
|
29 |
-
return @json_encode( $data );
|
30 |
}
|
31 |
|
32 |
/**
|
@@ -35,7 +35,7 @@ class WSAL_Helpers_DataHelper {
|
|
35 |
* @param string $data - The JSON string to decode.
|
36 |
* @return mixed Decoded data.
|
37 |
*/
|
38 |
-
public static function
|
39 |
-
return @json_decode( $data );
|
40 |
}
|
41 |
}
|
25 |
* @param mixed $data The data to encode.
|
26 |
* @return string JSON string.
|
27 |
*/
|
28 |
+
public static function json_encode( $data ) {
|
29 |
+
return @json_encode( $data ); // phpcs:ignore
|
30 |
}
|
31 |
|
32 |
/**
|
35 |
* @param string $data - The JSON string to decode.
|
36 |
* @return mixed Decoded data.
|
37 |
*/
|
38 |
+
public static function json_decode( $data ) {
|
39 |
+
return @json_decode( $data ); // phpcs:ignore
|
40 |
}
|
41 |
}
|
classes/Helpers/Options.php
CHANGED
@@ -20,26 +20,17 @@ namespace WSAL\Helpers;
|
|
20 |
*/
|
21 |
class Options {
|
22 |
|
23 |
-
/**
|
24 |
-
* Instance of the main plugin class.
|
25 |
-
*
|
26 |
-
* @since 4.0.2
|
27 |
-
* @var WpSecurityAuditLog
|
28 |
-
*/
|
29 |
-
private $plugin;
|
30 |
-
|
31 |
/**
|
32 |
* Prefix used when setting/getting options.
|
33 |
*
|
34 |
* @since 4.0.2
|
35 |
-
* @var
|
36 |
*/
|
37 |
public $prefix;
|
38 |
|
39 |
/**
|
40 |
* Sets up this class with the main plugin instance and a prefix.
|
41 |
*
|
42 |
-
* @method __construct
|
43 |
* @param string $prefix A prefix to use when setting/getting.
|
44 |
*
|
45 |
* @since 4.0.2
|
@@ -76,12 +67,12 @@ class Options {
|
|
76 |
}
|
77 |
|
78 |
$actual_option_name = $option_name;
|
79 |
-
if (!preg_match( '/\A' .preg_quote($this->prefix) . '/', $option_name)) {
|
80 |
-
//
|
81 |
$actual_option_name = $this->prefix . $option_name;
|
82 |
}
|
83 |
|
84 |
-
return self::
|
85 |
}
|
86 |
|
87 |
/**
|
@@ -101,12 +92,12 @@ class Options {
|
|
101 |
}
|
102 |
|
103 |
$actual_option_name = $option_name;
|
104 |
-
if ( ! preg_match( '/\A' . preg_quote( $this->prefix ) . '/', $option_name ) ) {
|
105 |
-
//
|
106 |
$actual_option_name = $this->prefix . $option_name;
|
107 |
}
|
108 |
|
109 |
-
return self::
|
110 |
}
|
111 |
|
112 |
/**
|
@@ -120,19 +111,19 @@ class Options {
|
|
120 |
*/
|
121 |
public function delete_option( $option_name = '' ) {
|
122 |
|
123 |
-
if (is_multisite()) {
|
124 |
-
switch_to_blog(get_main_network_id());
|
125 |
}
|
126 |
|
127 |
$actual_option_name = $option_name;
|
128 |
-
if ( ! preg_match( '/\A' . preg_quote( $this->prefix ) . '/', $option_name ) ) {
|
129 |
-
//
|
130 |
$actual_option_name = $this->prefix . $option_name;
|
131 |
}
|
132 |
|
133 |
$result = \delete_option( $actual_option_name );
|
134 |
|
135 |
-
if (is_multisite()) {
|
136 |
restore_current_blog();
|
137 |
}
|
138 |
|
@@ -149,41 +140,42 @@ class Options {
|
|
149 |
*
|
150 |
* In all other cases function \WpSecurityAuditLog::GetGlobalSetting() should be used instead.
|
151 |
*
|
152 |
-
* @see \WpSecurityAuditLog::
|
153 |
* @since 4.1.3
|
154 |
* @param string $option_name Option name we want to get a value for including necessary plugin prefix.
|
155 |
* @param mixed $default a default value to use when one doesn't exist.
|
156 |
* @return mixed
|
157 |
*/
|
158 |
-
public static function get_option_value_ignore_prefix( $option_name = '', $default = null) {
|
159 |
-
return self::
|
160 |
}
|
161 |
|
162 |
/**
|
163 |
* Internal function used to get the value of an option. Any necessary prefixes are already contained in the option
|
164 |
* name.
|
165 |
*
|
166 |
-
* @
|
167 |
-
* @param
|
168 |
-
*
|
169 |
* @return mixed
|
|
|
170 |
*/
|
171 |
-
private static function
|
172 |
// bail early if no option name was requested.
|
173 |
if ( empty( $option_name ) || ! is_string( $option_name ) ) {
|
174 |
return;
|
175 |
}
|
176 |
|
177 |
-
if (is_multisite()) {
|
178 |
-
switch_to_blog(get_main_network_id());
|
179 |
}
|
180 |
|
181 |
$result = \get_option( $option_name, $default );
|
182 |
|
183 |
-
if (is_multisite()) {
|
184 |
restore_current_blog();
|
185 |
}
|
186 |
-
return maybe_unserialize($result);
|
187 |
}
|
188 |
|
189 |
/**
|
@@ -197,28 +189,30 @@ class Options {
|
|
197 |
*
|
198 |
* In all other cases function \WpSecurityAuditLog::SetGlobalSetting() should be used instead.
|
199 |
*
|
200 |
-
* @
|
201 |
-
* @
|
202 |
-
* @param
|
203 |
-
*
|
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::
|
209 |
}
|
210 |
|
211 |
/**
|
212 |
* Internal function used to set the value of an option. Any necessary prefixes are already contained in the option
|
213 |
* name.
|
214 |
*
|
|
|
|
|
|
|
|
|
|
|
215 |
* @since 4.1.3
|
216 |
-
* @param string $option_name Option name we want to save a value for including necessary plugin prefix.
|
217 |
-
* @param mixed $value A value to store under the option name.
|
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
|
222 |
// bail early if no option name or value was passed.
|
223 |
if ( empty( $option_name ) || null === $value ) {
|
224 |
return;
|
@@ -249,7 +243,7 @@ class Options {
|
|
249 |
* @return bool
|
250 |
*/
|
251 |
public static function string_to_bool( $string ) {
|
252 |
-
return is_bool( $string ) ? $string : ( 'yes' === $string || 1 === $string || 'true' === $string || '1' === $string || 'on' === $string || 'enable' === $string);
|
253 |
}
|
254 |
|
255 |
/**
|
20 |
*/
|
21 |
class Options {
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
/**
|
24 |
* Prefix used when setting/getting options.
|
25 |
*
|
26 |
* @since 4.0.2
|
27 |
+
* @var string
|
28 |
*/
|
29 |
public $prefix;
|
30 |
|
31 |
/**
|
32 |
* Sets up this class with the main plugin instance and a prefix.
|
33 |
*
|
|
|
34 |
* @param string $prefix A prefix to use when setting/getting.
|
35 |
*
|
36 |
* @since 4.0.2
|
67 |
}
|
68 |
|
69 |
$actual_option_name = $option_name;
|
70 |
+
if ( ! preg_match( '/\A' . preg_quote( $this->prefix ) . '/', $option_name ) ) { // phpcs:ignore WordPress.PHP.PregQuoteDelimiter.Missing
|
71 |
+
// Remove prefix duplicate if present.
|
72 |
$actual_option_name = $this->prefix . $option_name;
|
73 |
}
|
74 |
|
75 |
+
return self::get_option_value_internal( $actual_option_name, $default );
|
76 |
}
|
77 |
|
78 |
/**
|
92 |
}
|
93 |
|
94 |
$actual_option_name = $option_name;
|
95 |
+
if ( ! preg_match( '/\A' . preg_quote( $this->prefix ) . '/', $option_name ) ) { // phpcs:ignore WordPress.PHP.PregQuoteDelimiter.Missing
|
96 |
+
// Prepend prefix if not already present.
|
97 |
$actual_option_name = $this->prefix . $option_name;
|
98 |
}
|
99 |
|
100 |
+
return self::set_option_value_internal( $actual_option_name, $value, $autoload );
|
101 |
}
|
102 |
|
103 |
/**
|
111 |
*/
|
112 |
public function delete_option( $option_name = '' ) {
|
113 |
|
114 |
+
if ( is_multisite() ) {
|
115 |
+
switch_to_blog( get_main_network_id() );
|
116 |
}
|
117 |
|
118 |
$actual_option_name = $option_name;
|
119 |
+
if ( ! preg_match( '/\A' . preg_quote( $this->prefix ) . '/', $option_name ) ) { // phpcs:ignore WordPress.PHP.PregQuoteDelimiter.Missing
|
120 |
+
// Prepend prefix if not already present.
|
121 |
$actual_option_name = $this->prefix . $option_name;
|
122 |
}
|
123 |
|
124 |
$result = \delete_option( $actual_option_name );
|
125 |
|
126 |
+
if ( is_multisite() ) {
|
127 |
restore_current_blog();
|
128 |
}
|
129 |
|
140 |
*
|
141 |
* In all other cases function \WpSecurityAuditLog::GetGlobalSetting() should be used instead.
|
142 |
*
|
143 |
+
* @see \WpSecurityAuditLog::get_global_setting()
|
144 |
* @since 4.1.3
|
145 |
* @param string $option_name Option name we want to get a value for including necessary plugin prefix.
|
146 |
* @param mixed $default a default value to use when one doesn't exist.
|
147 |
* @return mixed
|
148 |
*/
|
149 |
+
public static function get_option_value_ignore_prefix( $option_name = '', $default = null ) {
|
150 |
+
return self::get_option_value_internal( $option_name, $default );
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
* Internal function used to get the value of an option. Any necessary prefixes are already contained in the option
|
155 |
* name.
|
156 |
*
|
157 |
+
* @param string $option_name Option name we want to get a value for including necessary plugin prefix.
|
158 |
+
* @param mixed $default a default value to use when one doesn't exist.
|
159 |
+
*
|
160 |
* @return mixed
|
161 |
+
* @since 4.1.3
|
162 |
*/
|
163 |
+
private static function get_option_value_internal( $option_name = '', $default = null ) {
|
164 |
// bail early if no option name was requested.
|
165 |
if ( empty( $option_name ) || ! is_string( $option_name ) ) {
|
166 |
return;
|
167 |
}
|
168 |
|
169 |
+
if ( is_multisite() ) {
|
170 |
+
switch_to_blog( get_main_network_id() );
|
171 |
}
|
172 |
|
173 |
$result = \get_option( $option_name, $default );
|
174 |
|
175 |
+
if ( is_multisite() ) {
|
176 |
restore_current_blog();
|
177 |
}
|
178 |
+
return maybe_unserialize( $result );
|
179 |
}
|
180 |
|
181 |
/**
|
189 |
*
|
190 |
* In all other cases function \WpSecurityAuditLog::SetGlobalSetting() should be used instead.
|
191 |
*
|
192 |
+
* @param string $option_name Option name we want to get a value for including necessary plugin prefix.
|
193 |
+
* @param mixed $value A value to store under the option name.
|
194 |
+
* @param bool $autoload Whether to autoload this option.
|
195 |
+
*
|
|
|
196 |
* @return mixed
|
197 |
+
* @see \WpSecurityAuditLog::set_global_setting()
|
198 |
+
* @since 4.1.3
|
199 |
*/
|
200 |
public static function set_option_value_ignore_prefix( $option_name = '', $value = null, $autoload = false ) {
|
201 |
+
return self::set_option_value_internal( $option_name, $value, $autoload );
|
202 |
}
|
203 |
|
204 |
/**
|
205 |
* Internal function used to set the value of an option. Any necessary prefixes are already contained in the option
|
206 |
* name.
|
207 |
*
|
208 |
+
* @param string $option_name Option name we want to save a value for including necessary plugin prefix.
|
209 |
+
* @param mixed $value A value to store under the option name.
|
210 |
+
* @param bool $autoload Whether to autoload this option.
|
211 |
+
*
|
212 |
+
* @return bool Whether the option was updated.
|
213 |
* @since 4.1.3
|
|
|
|
|
|
|
|
|
214 |
*/
|
215 |
+
private static function set_option_value_internal( $option_name = '', $value = null, $autoload = false ) {
|
216 |
// bail early if no option name or value was passed.
|
217 |
if ( empty( $option_name ) || null === $value ) {
|
218 |
return;
|
243 |
* @return bool
|
244 |
*/
|
245 |
public static function string_to_bool( $string ) {
|
246 |
+
return is_bool( $string ) ? $string : ( 'yes' === $string || 1 === $string || 'true' === $string || '1' === $string || 'on' === $string || 'enable' === $string );
|
247 |
}
|
248 |
|
249 |
/**
|
classes/Loggers/Database.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Logger class for wsal.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -18,7 +19,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
18 |
*
|
19 |
* This class stores the logs in the database and there is also the function to clean up alerts.
|
20 |
*
|
21 |
-
* @package
|
22 |
* @subpackage loggers
|
23 |
*/
|
24 |
class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
@@ -31,7 +32,7 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
31 |
*/
|
32 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
33 |
parent::__construct( $plugin );
|
34 |
-
$plugin->
|
35 |
}
|
36 |
|
37 |
/**
|
@@ -41,7 +42,7 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
41 |
* @return boolean
|
42 |
*/
|
43 |
public function is_external() {
|
44 |
-
$db_config = WSAL_Connector_ConnectorFactory::
|
45 |
|
46 |
return is_array( $db_config ) && ! empty( $db_config );
|
47 |
}
|
@@ -51,32 +52,32 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
51 |
*
|
52 |
* There is no difference between local and external database handling os of version 4.3.2.
|
53 |
*
|
54 |
-
* @param integer $type
|
55 |
-
* @param array $data
|
56 |
-
* @param integer $date
|
57 |
-
* @param integer $site_id
|
58 |
*/
|
59 |
-
public function
|
60 |
-
//
|
61 |
if ( $type < 0010 ) {
|
62 |
return;
|
63 |
}
|
64 |
|
65 |
// Create new occurrence.
|
66 |
-
$occ
|
67 |
-
$occ->created_on
|
68 |
-
$occ->alert_id
|
69 |
-
$occ->site_id
|
70 |
|
71 |
-
//
|
72 |
unset( $data['Timestamp'] );
|
73 |
|
74 |
// Get DB connector.
|
75 |
-
$db_config = WSAL_Connector_ConnectorFactory::
|
76 |
|
77 |
// Get connector for DB.
|
78 |
-
$connector = $this->plugin->
|
79 |
-
$wsal_db = $connector->
|
80 |
$connection = true;
|
81 |
if ( isset( $wsal_db->dbh->errno ) ) {
|
82 |
$connection = ( 0 === (int) $wsal_db->dbh->errno ); // Database connection error check.
|
@@ -87,12 +88,12 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
87 |
// Check DB connection.
|
88 |
if ( $connection ) { // If connected then save the alert in DB.
|
89 |
// Save the alert occurrence.
|
90 |
-
$occ->
|
91 |
|
92 |
// Set up meta data of the alert.
|
93 |
$occ->SetMeta( $data );
|
94 |
-
} else {
|
95 |
-
//
|
96 |
}
|
97 |
|
98 |
/**
|
@@ -106,12 +107,12 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
106 |
/**
|
107 |
* Clean Up alerts by date OR by max number.
|
108 |
*/
|
109 |
-
public function
|
110 |
-
$now = current_time( 'timestamp' );
|
111 |
-
$max_sdate = $this->plugin->settings()->
|
112 |
-
$max_count = $this->plugin->settings()->
|
113 |
-
$is_date_e = $this->plugin->settings()->
|
114 |
-
$is_limt_e = $this->plugin->settings()->
|
115 |
|
116 |
// Return if retention is disabled.
|
117 |
if ( ! $is_date_e && ! $is_limt_e ) {
|
@@ -120,7 +121,7 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
120 |
|
121 |
|
122 |
$occ = new WSAL_Models_Occurrence();
|
123 |
-
$cnt_items = $occ->
|
124 |
|
125 |
// Check if there is something to delete.
|
126 |
if ( $is_limt_e && ( $cnt_items < $max_count ) ) {
|
@@ -131,23 +132,23 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
|
131 |
$max_items = (int) max( ( $cnt_items - $max_count ) + 1, 0 );
|
132 |
|
133 |
$query = new WSAL_Models_OccurrenceQuery();
|
134 |
-
$query->
|
135 |
// TO DO: Fixing data.
|
136 |
if ( $is_date_e ) {
|
137 |
-
$query->
|
138 |
}
|
139 |
if ( $is_limt_e ) {
|
140 |
-
$query->
|
141 |
}
|
142 |
|
143 |
-
if ( ( $max_items - 1 ) == 0 ) {
|
144 |
return; // Nothing to delete.
|
145 |
}
|
146 |
|
147 |
-
$result = $query->
|
148 |
-
$deleted_count = $query->
|
149 |
|
150 |
-
if ( 0 == $deleted_count ) {
|
151 |
return; // Nothing to delete.
|
152 |
}
|
153 |
|
4 |
*
|
5 |
* Logger class for wsal.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage loggers
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
19 |
*
|
20 |
* This class stores the logs in the database and there is also the function to clean up alerts.
|
21 |
*
|
22 |
+
* @package wsal
|
23 |
* @subpackage loggers
|
24 |
*/
|
25 |
class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
32 |
*/
|
33 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
34 |
parent::__construct( $plugin );
|
35 |
+
$plugin->add_cleanup_hook( array( $this, 'clean_up' ) );
|
36 |
}
|
37 |
|
38 |
/**
|
42 |
* @return boolean
|
43 |
*/
|
44 |
public function is_external() {
|
45 |
+
$db_config = WSAL_Connector_ConnectorFactory::get_config();
|
46 |
|
47 |
return is_array( $db_config ) && ! empty( $db_config );
|
48 |
}
|
52 |
*
|
53 |
* There is no difference between local and external database handling os of version 4.3.2.
|
54 |
*
|
55 |
+
* @param integer $type - Alert code.
|
56 |
+
* @param array $data - Metadata.
|
57 |
+
* @param integer $date - (Optional) created_on.
|
58 |
+
* @param integer $site_id - (Optional) site_id.
|
59 |
*/
|
60 |
+
public function log( $type, $data = array(), $date = null, $site_id = null ) {
|
61 |
+
// PHP alerts logging was deprecated in version 4.2.0.
|
62 |
if ( $type < 0010 ) {
|
63 |
return;
|
64 |
}
|
65 |
|
66 |
// Create new occurrence.
|
67 |
+
$occ = new WSAL_Models_Occurrence();
|
68 |
+
$occ->created_on = $this->get_correct_timestamp( $data, $date );
|
69 |
+
$occ->alert_id = $type;
|
70 |
+
$occ->site_id = ! is_null( $site_id ) ? $site_id : ( function_exists( 'get_current_blog_id' ) ? get_current_blog_id() : 0 );
|
71 |
|
72 |
+
// We need to remove the timestamp to prevent from saving it as meta.
|
73 |
unset( $data['Timestamp'] );
|
74 |
|
75 |
// Get DB connector.
|
76 |
+
$db_config = WSAL_Connector_ConnectorFactory::get_config(); // Get DB connector configuration.
|
77 |
|
78 |
// Get connector for DB.
|
79 |
+
$connector = $this->plugin->get_connector( $db_config );
|
80 |
+
$wsal_db = $connector->get_connection(); // Get DB connection.
|
81 |
$connection = true;
|
82 |
if ( isset( $wsal_db->dbh->errno ) ) {
|
83 |
$connection = ( 0 === (int) $wsal_db->dbh->errno ); // Database connection error check.
|
88 |
// Check DB connection.
|
89 |
if ( $connection ) { // If connected then save the alert in DB.
|
90 |
// Save the alert occurrence.
|
91 |
+
$occ->save();
|
92 |
|
93 |
// Set up meta data of the alert.
|
94 |
$occ->SetMeta( $data );
|
95 |
+
} else { // phpcs:ignore
|
96 |
+
// TODO write to a debug log.
|
97 |
}
|
98 |
|
99 |
/**
|
107 |
/**
|
108 |
* Clean Up alerts by date OR by max number.
|
109 |
*/
|
110 |
+
public function clean_up() {
|
111 |
+
$now = current_time( 'timestamp' ); // phpcs:ignore
|
112 |
+
$max_sdate = $this->plugin->settings()->get_pruning_date();
|
113 |
+
$max_count = $this->plugin->settings()->get_pruning_limit();
|
114 |
+
$is_date_e = $this->plugin->settings()->is_pruning_date_enabled();
|
115 |
+
$is_limt_e = $this->plugin->settings()->is_pruning_limit_enabled();
|
116 |
|
117 |
// Return if retention is disabled.
|
118 |
if ( ! $is_date_e && ! $is_limt_e ) {
|
121 |
|
122 |
|
123 |
$occ = new WSAL_Models_Occurrence();
|
124 |
+
$cnt_items = $occ->count();
|
125 |
|
126 |
// Check if there is something to delete.
|
127 |
if ( $is_limt_e && ( $cnt_items < $max_count ) ) {
|
132 |
$max_items = (int) max( ( $cnt_items - $max_count ) + 1, 0 );
|
133 |
|
134 |
$query = new WSAL_Models_OccurrenceQuery();
|
135 |
+
$query->add_order_by( 'created_on', false );
|
136 |
// TO DO: Fixing data.
|
137 |
if ( $is_date_e ) {
|
138 |
+
$query->add_condition( 'created_on <= %s', intval( $max_stamp ) );
|
139 |
}
|
140 |
if ( $is_limt_e ) {
|
141 |
+
$query->set_limit( $max_items );
|
142 |
}
|
143 |
|
144 |
+
if ( ( $max_items - 1 ) == 0 ) { // phpcs:ignore
|
145 |
return; // Nothing to delete.
|
146 |
}
|
147 |
|
148 |
+
$result = $query->get_adapter()->get_sql_delete( $query );
|
149 |
+
$deleted_count = $query->get_adapter()->delete( $query );
|
150 |
|
151 |
+
if ( 0 == $deleted_count ) { // phpcs:ignore
|
152 |
return; // Nothing to delete.
|
153 |
}
|
154 |
|
classes/MainWpApi.php
CHANGED
@@ -1,11 +1,23 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Handler for MainWP API endpoints.
|
5 |
*
|
6 |
* @package wsal
|
7 |
* @subpackage main-wp
|
8 |
-
* @since
|
9 |
*/
|
10 |
class WSAL_MainWpApi {
|
11 |
|
@@ -54,7 +66,7 @@ class WSAL_MainWpApi {
|
|
54 |
case 'latest_event':
|
55 |
// run the query and return it.
|
56 |
$event = $this->query_for_latest_event();
|
57 |
-
$event = $event->
|
58 |
|
59 |
// Set the return object.
|
60 |
if ( isset( $event[0] ) ) {
|
@@ -111,38 +123,37 @@ class WSAL_MainWpApi {
|
|
111 |
|
112 |
// Initiate query occurrence object.
|
113 |
$events_query = new WSAL_Models_OccurrenceQuery();
|
114 |
-
$events_query->
|
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->
|
121 |
} else {
|
122 |
$mwp_events->total_items = false;
|
123 |
}
|
124 |
}
|
125 |
|
126 |
// Set order by.
|
127 |
-
$events_query->
|
128 |
|
129 |
// Set the limit.
|
130 |
-
$events_query->
|
131 |
|
132 |
// Set the offset.
|
133 |
if ( false !== $offset ) {
|
134 |
-
$events_query->
|
135 |
}
|
136 |
|
137 |
// Execute the query.
|
138 |
-
/** @var
|
139 |
-
$events = $events_query->
|
140 |
|
141 |
if ( ! empty( $events ) && is_array( $events ) ) {
|
142 |
foreach ( $events as $event ) {
|
143 |
// Get event meta.
|
144 |
-
$meta_data = $event->
|
145 |
-
$meta_data['UserData'] = $this->plugin->alerts->get_event_user_data( WSAL_Utilities_UsersUtils::
|
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;
|
@@ -156,138 +167,6 @@ class WSAL_MainWpApi {
|
|
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 |
*
|
@@ -301,24 +180,6 @@ class WSAL_MainWpApi {
|
|
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 |
|
@@ -331,9 +192,9 @@ class WSAL_MainWpApi {
|
|
331 |
public function query_for_latest_event() {
|
332 |
$event_query = new WSAL_Models_OccurrenceQuery();
|
333 |
// order by creation.
|
334 |
-
$event_query->
|
335 |
// only request 1 item.
|
336 |
-
$event_query->
|
337 |
|
338 |
return $event_query;
|
339 |
}
|
@@ -371,20 +232,20 @@ class WSAL_MainWpApi {
|
|
371 |
|
372 |
// Change the existing settings.
|
373 |
if ( array_key_exists( 'pruning_enabled', $settings_to_enforce ) ) {
|
374 |
-
$this->plugin->settings()->
|
375 |
if ( array_key_exists( 'pruning_date', $settings_to_enforce ) && array_key_exists( 'pruning_unit', $settings_to_enforce ) ) {
|
376 |
-
$this->plugin->settings()->
|
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->
|
384 |
}
|
385 |
|
386 |
if ( array_key_exists( 'incognito_mode_enabled', $settings_to_enforce ) ) {
|
387 |
-
$this->plugin->settings()->
|
388 |
}
|
389 |
|
390 |
if ( array_key_exists( 'login_notification_enabled', $settings_to_enforce ) ) {
|
@@ -398,7 +259,7 @@ class WSAL_MainWpApi {
|
|
398 |
$this->plugin->settings()->delete_mainwp_enforced_settings();
|
399 |
}
|
400 |
|
401 |
-
$this->plugin->alerts->
|
402 |
|
403 |
return array(
|
404 |
'success' => 'yes',
|
@@ -430,7 +291,7 @@ class WSAL_MainWpApi {
|
|
430 |
$limit = empty( $filters['limit'] ) ? 0 : $filters['limit'];
|
431 |
$last_date = null;
|
432 |
|
433 |
-
$results = $this->plugin->
|
434 |
|
435 |
if ( ! empty( $results['lastDate'] ) ) {
|
436 |
$last_date = $results['lastDate'];
|
@@ -475,7 +336,7 @@ class WSAL_MainWpApi {
|
|
475 |
$alert_manager = $this->plugin->alerts;
|
476 |
|
477 |
return array(
|
478 |
-
'events' => $alert_manager->
|
479 |
'objects' => $alert_manager->get_event_objects_data(),
|
480 |
'types' => $alert_manager->get_event_type_data(),
|
481 |
);
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Class WSAL_MainWpApi.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage main-wp
|
7 |
+
* @since 4.4.0
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
|
15 |
/**
|
16 |
* Handler for MainWP API endpoints.
|
17 |
*
|
18 |
* @package wsal
|
19 |
* @subpackage main-wp
|
20 |
+
* @since 4.4.0
|
21 |
*/
|
22 |
class WSAL_MainWpApi {
|
23 |
|
66 |
case 'latest_event':
|
67 |
// run the query and return it.
|
68 |
$event = $this->query_for_latest_event();
|
69 |
+
$event = $event->get_adapter()->execute_query( $event );
|
70 |
|
71 |
// Set the return object.
|
72 |
if ( isset( $event[0] ) ) {
|
123 |
|
124 |
// Initiate query occurrence object.
|
125 |
$events_query = new WSAL_Models_OccurrenceQuery();
|
126 |
+
$events_query->add_condition( 'site_id = %s ', 1 ); // Set site id.
|
|
|
127 |
|
128 |
// Check query arguments.
|
129 |
if ( false !== $query_args ) {
|
130 |
if ( isset( $query_args['get_count'] ) && $query_args['get_count'] ) {
|
131 |
+
$mwp_events->total_items = $events_query->get_adapter()->count( $events_query );
|
132 |
} else {
|
133 |
$mwp_events->total_items = false;
|
134 |
}
|
135 |
}
|
136 |
|
137 |
// Set order by.
|
138 |
+
$events_query->add_order_by( 'created_on', true );
|
139 |
|
140 |
// Set the limit.
|
141 |
+
$events_query->set_limit( $limit );
|
142 |
|
143 |
// Set the offset.
|
144 |
if ( false !== $offset ) {
|
145 |
+
$events_query->set_offset( $offset );
|
146 |
}
|
147 |
|
148 |
// Execute the query.
|
149 |
+
/** @var WSAL_Models_Occurrence[] $events */
|
150 |
+
$events = $events_query->get_adapter()->execute_query( $events_query );
|
151 |
|
152 |
if ( ! empty( $events ) && is_array( $events ) ) {
|
153 |
foreach ( $events as $event ) {
|
154 |
// Get event meta.
|
155 |
+
$meta_data = $event->get_meta_array();
|
156 |
+
$meta_data['UserData'] = $this->plugin->alerts->get_event_user_data( WSAL_Utilities_UsersUtils::get_username( $meta_data ) );
|
157 |
$mwp_events->events[ $event->id ] = new stdClass();
|
158 |
$mwp_events->events[ $event->id ]->id = $event->id;
|
159 |
$mwp_events->events[ $event->id ]->alert_id = $event->alert_id;
|
167 |
return $mwp_events;
|
168 |
}
|
169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
/**
|
171 |
* Generate report matching the filter passed.
|
172 |
*
|
180 |
public function get_report_data( array $filters, $report_type ) {
|
181 |
$report = new stdClass();
|
182 |
$report->data = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
return $report;
|
184 |
}
|
185 |
|
192 |
public function query_for_latest_event() {
|
193 |
$event_query = new WSAL_Models_OccurrenceQuery();
|
194 |
// order by creation.
|
195 |
+
$event_query->add_order_by( 'created_on', true );
|
196 |
// only request 1 item.
|
197 |
+
$event_query->set_limit( 1 );
|
198 |
|
199 |
return $event_query;
|
200 |
}
|
232 |
|
233 |
// Change the existing settings.
|
234 |
if ( array_key_exists( 'pruning_enabled', $settings_to_enforce ) ) {
|
235 |
+
$this->plugin->settings()->set_pruning_date_enabled( $settings_to_enforce['pruning_enabled'] );
|
236 |
if ( array_key_exists( 'pruning_date', $settings_to_enforce ) && array_key_exists( 'pruning_unit', $settings_to_enforce ) ) {
|
237 |
+
$this->plugin->settings()->set_pruning_date( $settings_to_enforce['pruning_date'] . ' ' . $settings_to_enforce['pruning_unit'] );
|
238 |
$this->plugin->settings()->set_pruning_unit( $settings_to_enforce['pruning_unit'] );
|
239 |
}
|
240 |
}
|
241 |
|
242 |
if ( array_key_exists( 'disabled_events', $settings_to_enforce ) ) {
|
243 |
$disabled_event_ids = array_map( 'intval', explode( ',', $settings_to_enforce['disabled_events'] ) );
|
244 |
+
$this->plugin->settings()->set_disabled_alerts( $disabled_event_ids );
|
245 |
}
|
246 |
|
247 |
if ( array_key_exists( 'incognito_mode_enabled', $settings_to_enforce ) ) {
|
248 |
+
$this->plugin->settings()->set_incognito( $settings_to_enforce['incognito_mode_enabled'] );
|
249 |
}
|
250 |
|
251 |
if ( array_key_exists( 'login_notification_enabled', $settings_to_enforce ) ) {
|
259 |
$this->plugin->settings()->delete_mainwp_enforced_settings();
|
260 |
}
|
261 |
|
262 |
+
$this->plugin->alerts->trigger_event( 6043 );
|
263 |
|
264 |
return array(
|
265 |
'success' => 'yes',
|
291 |
$limit = empty( $filters['limit'] ) ? 0 : $filters['limit'];
|
292 |
$last_date = null;
|
293 |
|
294 |
+
$results = $this->plugin->get_connector()->get_adapter( 'Occurrence' )->get_report_data( $args, $next_date, $limit );
|
295 |
|
296 |
if ( ! empty( $results['lastDate'] ) ) {
|
297 |
$last_date = $results['lastDate'];
|
336 |
$alert_manager = $this->plugin->alerts;
|
337 |
|
338 |
return array(
|
339 |
+
'events' => $alert_manager->get_alerts(),
|
340 |
'objects' => $alert_manager->get_event_objects_data(),
|
341 |
'types' => $alert_manager->get_event_type_data(),
|
342 |
);
|
classes/Models/ActiveRecord.php
CHANGED
@@ -55,7 +55,7 @@ abstract class WSAL_Models_ActiveRecord {
|
|
55 |
*
|
56 |
* @var null
|
57 |
*/
|
58 |
-
protected $
|
59 |
|
60 |
/**
|
61 |
* Use Default Adapter.
|
@@ -69,25 +69,25 @@ abstract class WSAL_Models_ActiveRecord {
|
|
69 |
*
|
70 |
* @var string
|
71 |
*/
|
72 |
-
protected $
|
73 |
|
74 |
/**
|
75 |
* Cache.
|
76 |
*
|
77 |
* @var array
|
78 |
*/
|
79 |
-
protected static $
|
80 |
|
81 |
/**
|
82 |
* Returns this records' fields.
|
83 |
*
|
84 |
* @return array
|
85 |
*/
|
86 |
-
public function
|
87 |
if ( ! isset( $this->_column_cache ) ) {
|
88 |
$this->_column_cache = array();
|
89 |
foreach ( array_keys( get_object_vars( $this ) ) as $col ) {
|
90 |
-
if ( trim( $col ) && '_' != $col[0] ) {
|
91 |
$this->_column_cache[] = $col;
|
92 |
}
|
93 |
}
|
@@ -100,7 +100,7 @@ abstract class WSAL_Models_ActiveRecord {
|
|
100 |
*
|
101 |
* @param integer $id - ID.
|
102 |
*/
|
103 |
-
public function
|
104 |
$this->id = $id;
|
105 |
}
|
106 |
|
@@ -109,7 +109,7 @@ abstract class WSAL_Models_ActiveRecord {
|
|
109 |
*
|
110 |
* @return integer $id.
|
111 |
*/
|
112 |
-
public function
|
113 |
return $this->id;
|
114 |
}
|
115 |
|
@@ -120,12 +120,12 @@ abstract class WSAL_Models_ActiveRecord {
|
|
120 |
* @throws Exception - Requires adapterName.
|
121 |
*/
|
122 |
public function __construct( $data = null ) {
|
123 |
-
if ( ! $this->
|
124 |
throw new Exception( 'Class "' . __CLASS__ . '" requires "adapterName" to be set.' );
|
125 |
}
|
126 |
if ( ! is_null( $data ) ) {
|
127 |
-
$this->
|
128 |
-
$this->
|
129 |
}
|
130 |
}
|
131 |
|
@@ -134,15 +134,15 @@ abstract class WSAL_Models_ActiveRecord {
|
|
134 |
*
|
135 |
* @return WSAL_Connector_ConnectorInterface
|
136 |
*/
|
137 |
-
protected function
|
138 |
if ( ! empty( $this->connector ) ) {
|
139 |
return $this->connector;
|
140 |
}
|
141 |
|
142 |
if ( $this->use_default_adapter ) {
|
143 |
-
$this->connector = WSAL_Connector_ConnectorFactory::
|
144 |
} else {
|
145 |
-
$this->connector = WSAL_Connector_ConnectorFactory::
|
146 |
}
|
147 |
return $this->connector;
|
148 |
}
|
@@ -153,41 +153,42 @@ abstract class WSAL_Models_ActiveRecord {
|
|
153 |
*
|
154 |
* @return WSAL_Adapters_ActiveRecordInterface
|
155 |
*/
|
156 |
-
public function
|
157 |
-
//
|
158 |
if ( ! empty( $this->adapter ) ) {
|
159 |
return $this->adapter;
|
160 |
}
|
161 |
|
162 |
-
//
|
163 |
-
return $this->
|
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
|
174 |
$this->adapter = $adapter;
|
175 |
}
|
176 |
|
177 |
/**
|
178 |
* Load record from DB.
|
179 |
*
|
180 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
181 |
* @param string $cond (Optional) Load condition.
|
182 |
* @param array $args (Optional) Load condition arguments.
|
|
|
|
|
183 |
*/
|
184 |
-
public function
|
185 |
-
$this->
|
186 |
|
187 |
-
$data = $this->
|
188 |
if ( ! is_null( $data ) ) {
|
189 |
-
$this->
|
190 |
-
$this->
|
191 |
}
|
192 |
}
|
193 |
|
@@ -195,28 +196,28 @@ abstract class WSAL_Models_ActiveRecord {
|
|
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
|
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::
|
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
|
220 |
default:
|
221 |
throw new Exception( 'Unsupported type "' . gettype( $copy->$key ) . '"' );
|
222 |
}
|
@@ -228,12 +229,12 @@ abstract class WSAL_Models_ActiveRecord {
|
|
228 |
* @param array|object $data Data array or object.
|
229 |
* @throws Exception - Unsupported type.
|
230 |
*/
|
231 |
-
public function
|
232 |
$copy = get_class( $this );
|
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;
|
@@ -242,21 +243,22 @@ abstract class WSAL_Models_ActiveRecord {
|
|
242 |
/**
|
243 |
* Save this active record
|
244 |
*
|
245 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::Save()
|
246 |
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
|
|
247 |
*/
|
248 |
-
public function
|
249 |
-
$this->
|
250 |
|
251 |
// Use today's date if not set up.
|
252 |
if ( is_null( $this->created_on ) ) {
|
253 |
-
$this->created_on = $this->
|
254 |
}
|
255 |
-
|
256 |
-
$
|
|
|
257 |
|
258 |
if ( false !== $result ) {
|
259 |
-
$this->
|
260 |
}
|
261 |
return $result;
|
262 |
}
|
@@ -264,15 +266,16 @@ abstract class WSAL_Models_ActiveRecord {
|
|
264 |
/**
|
265 |
* Deletes this active record.
|
266 |
*
|
267 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::Delete()
|
268 |
* @return int|boolean Either the amount of deleted rows or False on error.
|
|
|
269 |
*/
|
270 |
-
public function
|
271 |
-
$this->
|
272 |
-
$result
|
273 |
if ( false !== $result ) {
|
274 |
-
$this->
|
275 |
}
|
|
|
276 |
return $result;
|
277 |
}
|
278 |
|
@@ -281,11 +284,12 @@ abstract class WSAL_Models_ActiveRecord {
|
|
281 |
*
|
282 |
* @param string $cond - Condition.
|
283 |
* @param array $args - Arguments.
|
284 |
-
*
|
285 |
* @return int count
|
|
|
286 |
*/
|
287 |
-
public function
|
288 |
-
return (int) $this->
|
289 |
}
|
290 |
|
291 |
/**
|
@@ -293,8 +297,8 @@ abstract class WSAL_Models_ActiveRecord {
|
|
293 |
*
|
294 |
* @return bool
|
295 |
*/
|
296 |
-
public function
|
297 |
-
return self::STATE_LOADED === $this->
|
298 |
}
|
299 |
|
300 |
/**
|
@@ -302,9 +306,9 @@ abstract class WSAL_Models_ActiveRecord {
|
|
302 |
*
|
303 |
* @return bool
|
304 |
*/
|
305 |
-
public function
|
306 |
-
return self::STATE_CREATED === $this->
|
307 |
-
|| self::STATE_UPDATED === $this->
|
308 |
}
|
309 |
|
310 |
/**
|
@@ -312,8 +316,8 @@ abstract class WSAL_Models_ActiveRecord {
|
|
312 |
*
|
313 |
* @return bool
|
314 |
*/
|
315 |
-
public function
|
316 |
-
return self::STATE_CREATED === $this->
|
317 |
}
|
318 |
|
319 |
/**
|
@@ -321,8 +325,8 @@ abstract class WSAL_Models_ActiveRecord {
|
|
321 |
*
|
322 |
* @return bool
|
323 |
*/
|
324 |
-
public function
|
325 |
-
return self::STATE_UPDATED === $this->
|
326 |
}
|
327 |
|
328 |
/**
|
@@ -330,27 +334,27 @@ abstract class WSAL_Models_ActiveRecord {
|
|
330 |
*
|
331 |
* @return bool
|
332 |
*/
|
333 |
-
public function
|
334 |
-
return self::STATE_DELETED === $this->
|
335 |
}
|
336 |
|
337 |
/**
|
338 |
* Check if the Record structure is created.
|
339 |
*
|
340 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::IsInstalled()
|
341 |
* @return bool
|
|
|
342 |
*/
|
343 |
-
public function
|
344 |
-
return $this->
|
345 |
}
|
346 |
|
347 |
/**
|
348 |
* Install the Record structure.
|
349 |
*
|
350 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::
|
351 |
*/
|
352 |
-
public function
|
353 |
-
return $this->
|
354 |
}
|
355 |
|
356 |
/**
|
@@ -361,13 +365,13 @@ abstract class WSAL_Models_ActiveRecord {
|
|
361 |
* @param array $args Arguments used in condition.
|
362 |
* @return WSAL_Models_ActiveRecord
|
363 |
*/
|
364 |
-
protected static function
|
365 |
$index = $target . '::' . vsprintf( $query, $args );
|
366 |
-
if ( ! isset( self::$
|
367 |
-
self::$
|
368 |
-
self::$
|
369 |
}
|
370 |
-
return self::$
|
371 |
}
|
372 |
|
373 |
/**
|
@@ -377,17 +381,17 @@ abstract class WSAL_Models_ActiveRecord {
|
|
377 |
* @param string $query Load condition.
|
378 |
* @param array $args Arguments used in condition.
|
379 |
*/
|
380 |
-
protected static function
|
381 |
$index = $target . '::' . sprintf( $query, $args );
|
382 |
-
if ( ! isset( self::$
|
383 |
-
unset( self::$
|
384 |
}
|
385 |
}
|
386 |
|
387 |
/**
|
388 |
* Clear the cache.
|
389 |
*/
|
390 |
-
protected static function
|
391 |
-
self::$
|
392 |
}
|
393 |
}
|
55 |
*
|
56 |
* @var null
|
57 |
*/
|
58 |
+
protected $adapter_name = null;
|
59 |
|
60 |
/**
|
61 |
* Use Default Adapter.
|
69 |
*
|
70 |
* @var string
|
71 |
*/
|
72 |
+
protected $state = self::STATE_UNKNOWN;
|
73 |
|
74 |
/**
|
75 |
* Cache.
|
76 |
*
|
77 |
* @var array
|
78 |
*/
|
79 |
+
protected static $cache = array();
|
80 |
|
81 |
/**
|
82 |
* Returns this records' fields.
|
83 |
*
|
84 |
* @return array
|
85 |
*/
|
86 |
+
public function get_fields() {
|
87 |
if ( ! isset( $this->_column_cache ) ) {
|
88 |
$this->_column_cache = array();
|
89 |
foreach ( array_keys( get_object_vars( $this ) ) as $col ) {
|
90 |
+
if ( trim( $col ) && '_' != $col[0] ) { // phpcs:ignore
|
91 |
$this->_column_cache[] = $col;
|
92 |
}
|
93 |
}
|
100 |
*
|
101 |
* @param integer $id - ID.
|
102 |
*/
|
103 |
+
public function set_id( $id ) {
|
104 |
$this->id = $id;
|
105 |
}
|
106 |
|
109 |
*
|
110 |
* @return integer $id.
|
111 |
*/
|
112 |
+
public function get_id() {
|
113 |
return $this->id;
|
114 |
}
|
115 |
|
120 |
* @throws Exception - Requires adapterName.
|
121 |
*/
|
122 |
public function __construct( $data = null ) {
|
123 |
+
if ( ! $this->adapter_name ) {
|
124 |
throw new Exception( 'Class "' . __CLASS__ . '" requires "adapterName" to be set.' );
|
125 |
}
|
126 |
if ( ! is_null( $data ) ) {
|
127 |
+
$this->load_data( $data );
|
128 |
+
$this->state = self::STATE_LOADED;
|
129 |
}
|
130 |
}
|
131 |
|
134 |
*
|
135 |
* @return WSAL_Connector_ConnectorInterface
|
136 |
*/
|
137 |
+
protected function get_connector() {
|
138 |
if ( ! empty( $this->connector ) ) {
|
139 |
return $this->connector;
|
140 |
}
|
141 |
|
142 |
if ( $this->use_default_adapter ) {
|
143 |
+
$this->connector = WSAL_Connector_ConnectorFactory::get_default_connector();
|
144 |
} else {
|
145 |
+
$this->connector = WSAL_Connector_ConnectorFactory::get_connector();
|
146 |
}
|
147 |
return $this->connector;
|
148 |
}
|
153 |
*
|
154 |
* @return WSAL_Adapters_ActiveRecordInterface
|
155 |
*/
|
156 |
+
public function get_adapter() {
|
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 get_connector method.
|
163 |
+
return $this->get_connector()->get_adapter( $this->adapter_name );
|
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 Active record adapter.
|
170 |
*
|
171 |
* @since 4.4.0
|
172 |
*/
|
173 |
+
public function set_adapter( $adapter ) {
|
174 |
$this->adapter = $adapter;
|
175 |
}
|
176 |
|
177 |
/**
|
178 |
* Load record from DB.
|
179 |
*
|
|
|
180 |
* @param string $cond (Optional) Load condition.
|
181 |
* @param array $args (Optional) Load condition arguments.
|
182 |
+
*
|
183 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::load()
|
184 |
*/
|
185 |
+
public function load( $cond = '%d', $args = array( 1 ) ) {
|
186 |
+
$this->state = self::STATE_UNKNOWN;
|
187 |
|
188 |
+
$data = $this->get_adapter()->load( $cond, $args );
|
189 |
if ( ! is_null( $data ) ) {
|
190 |
+
$this->load_data( $data );
|
191 |
+
$this->state = self::STATE_LOADED;
|
192 |
}
|
193 |
}
|
194 |
|
196 |
* Casts given value to a correct type based on the type of property (identified by the $key) in the $copy object.
|
197 |
* This is to allow automatic type casting instead of handling each database column individually.
|
198 |
*
|
199 |
+
* @param object $copy Model object copy to populate.
|
200 |
+
* @param string $key Column key.
|
201 |
+
* @param mixed $val Value.
|
202 |
*
|
203 |
* @return mixed
|
204 |
* @throws Exception
|
205 |
*/
|
206 |
+
protected function cast_to_correct_type( $copy, $key, $val ) {
|
207 |
switch ( true ) {
|
208 |
case is_string( $copy->$key ):
|
209 |
case WSAL_Utilities_RequestUtils::is_ip_address( $val ):
|
210 |
return (string) $val;
|
211 |
case is_array( $copy->$key ):
|
212 |
case is_object( $copy->$key ):
|
213 |
+
$json_decoded_val = WSAL_Helpers_DataHelper::json_decode( $val );
|
214 |
return is_null( $json_decoded_val ) ? $val : $json_decoded_val;
|
215 |
case is_int( $copy->$key ):
|
216 |
return (int) $val;
|
217 |
case is_float( $copy->$key ):
|
218 |
return (float) $val;
|
219 |
case is_bool( $copy->$key ):
|
220 |
+
return (bool) $val;
|
221 |
default:
|
222 |
throw new Exception( 'Unsupported type "' . gettype( $copy->$key ) . '"' );
|
223 |
}
|
229 |
* @param array|object $data Data array or object.
|
230 |
* @throws Exception - Unsupported type.
|
231 |
*/
|
232 |
+
public function load_data( $data ) {
|
233 |
$copy = get_class( $this );
|
234 |
$copy = new $copy();
|
235 |
foreach ( (array) $data as $key => $val ) {
|
236 |
if ( isset( $copy->$key ) ) {
|
237 |
+
$this->$key = $this->cast_to_correct_type( $copy, $key, $val );
|
238 |
}
|
239 |
}
|
240 |
return $this;
|
243 |
/**
|
244 |
* Save this active record
|
245 |
*
|
|
|
246 |
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
247 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::save()
|
248 |
*/
|
249 |
+
public function save() {
|
250 |
+
$this->state = self::STATE_UNKNOWN;
|
251 |
|
252 |
// Use today's date if not set up.
|
253 |
if ( is_null( $this->created_on ) ) {
|
254 |
+
$this->created_on = $this->get_microtime();
|
255 |
}
|
256 |
+
|
257 |
+
$update_id = $this->get_id();
|
258 |
+
$result = $this->get_adapter()->save( $this );
|
259 |
|
260 |
if ( false !== $result ) {
|
261 |
+
$this->state = ( ! empty( $update_id ) ) ? self::STATE_UPDATED : self::STATE_CREATED;
|
262 |
}
|
263 |
return $result;
|
264 |
}
|
266 |
/**
|
267 |
* Deletes this active record.
|
268 |
*
|
|
|
269 |
* @return int|boolean Either the amount of deleted rows or False on error.
|
270 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::delete()
|
271 |
*/
|
272 |
+
public function delete() {
|
273 |
+
$this->state = self::STATE_UNKNOWN;
|
274 |
+
$result = $this->get_adapter()->delete( $this );
|
275 |
if ( false !== $result ) {
|
276 |
+
$this->state = self::STATE_DELETED;
|
277 |
}
|
278 |
+
|
279 |
return $result;
|
280 |
}
|
281 |
|
284 |
*
|
285 |
* @param string $cond - Condition.
|
286 |
* @param array $args - Arguments.
|
287 |
+
*
|
288 |
* @return int count
|
289 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::count()
|
290 |
*/
|
291 |
+
public function count( $cond = '%d', $args = array( 1 ) ) {
|
292 |
+
return (int) $this->get_adapter()->count( $cond, $args );
|
293 |
}
|
294 |
|
295 |
/**
|
297 |
*
|
298 |
* @return bool
|
299 |
*/
|
300 |
+
public function is_loaded() {
|
301 |
+
return self::STATE_LOADED === $this->state;
|
302 |
}
|
303 |
|
304 |
/**
|
306 |
*
|
307 |
* @return bool
|
308 |
*/
|
309 |
+
public function is_saved() {
|
310 |
+
return self::STATE_CREATED === $this->state
|
311 |
+
|| self::STATE_UPDATED === $this->state;
|
312 |
}
|
313 |
|
314 |
/**
|
316 |
*
|
317 |
* @return bool
|
318 |
*/
|
319 |
+
public function is_created() {
|
320 |
+
return self::STATE_CREATED === $this->state;
|
321 |
}
|
322 |
|
323 |
/**
|
325 |
*
|
326 |
* @return bool
|
327 |
*/
|
328 |
+
public function is_updated() {
|
329 |
+
return self::STATE_UPDATED === $this->state;
|
330 |
}
|
331 |
|
332 |
/**
|
334 |
*
|
335 |
* @return bool
|
336 |
*/
|
337 |
+
public function is_deleted() {
|
338 |
+
return self::STATE_DELETED === $this->state;
|
339 |
}
|
340 |
|
341 |
/**
|
342 |
* Check if the Record structure is created.
|
343 |
*
|
|
|
344 |
* @return bool
|
345 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::is_installed()
|
346 |
*/
|
347 |
+
public function is_installed() {
|
348 |
+
return $this->get_adapter()->is_installed();
|
349 |
}
|
350 |
|
351 |
/**
|
352 |
* Install the Record structure.
|
353 |
*
|
354 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::install()
|
355 |
*/
|
356 |
+
public function install() {
|
357 |
+
return $this->get_adapter()->install();
|
358 |
}
|
359 |
|
360 |
/**
|
365 |
* @param array $args Arguments used in condition.
|
366 |
* @return WSAL_Models_ActiveRecord
|
367 |
*/
|
368 |
+
protected static function cache_load( $target, $query, $args ) {
|
369 |
$index = $target . '::' . vsprintf( $query, $args );
|
370 |
+
if ( ! isset( self::$cache[ $index ] ) ) {
|
371 |
+
self::$cache[ $index ] = new $target();
|
372 |
+
self::$cache[ $index ]->Load( $query, $args );
|
373 |
}
|
374 |
+
return self::$cache[ $index ];
|
375 |
}
|
376 |
|
377 |
/**
|
381 |
* @param string $query Load condition.
|
382 |
* @param array $args Arguments used in condition.
|
383 |
*/
|
384 |
+
protected static function cache_remove( $target, $query, $args ) {
|
385 |
$index = $target . '::' . sprintf( $query, $args );
|
386 |
+
if ( ! isset( self::$cache[ $index ] ) ) {
|
387 |
+
unset( self::$cache[ $index ] );
|
388 |
}
|
389 |
}
|
390 |
|
391 |
/**
|
392 |
* Clear the cache.
|
393 |
*/
|
394 |
+
protected static function cache_clear() {
|
395 |
+
self::$cache = array();
|
396 |
}
|
397 |
}
|
classes/Models/Meta.php
CHANGED
@@ -54,21 +54,21 @@ class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
|
54 |
*
|
55 |
* @var string
|
56 |
*/
|
57 |
-
protected $
|
58 |
|
59 |
/**
|
60 |
* Save Metadata into Adapter.
|
61 |
*
|
62 |
-
* @see WSAL_Adapters_MySQL_ActiveRecord::Save()
|
63 |
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
|
|
64 |
*/
|
65 |
-
public function
|
66 |
-
$this->
|
67 |
-
$update_id
|
68 |
-
$result
|
69 |
|
70 |
if ( false !== $result ) {
|
71 |
-
$this->
|
72 |
}
|
73 |
return $result;
|
74 |
}
|
@@ -76,25 +76,25 @@ class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
|
76 |
/**
|
77 |
* Update Metadata by name and occurrence_id.
|
78 |
*
|
79 |
-
* @param string $name
|
80 |
-
* @param mixed
|
81 |
* @param integer $occurrence_id - Occurrence_id.
|
82 |
*
|
83 |
-
* @see WSAL_Adapters_MySQL_Meta::
|
84 |
*/
|
85 |
-
public function
|
86 |
-
$meta = $this->
|
87 |
if ( ! empty( $meta ) ) {
|
88 |
-
$this->id
|
89 |
$this->occurrence_id = $meta['occurrence_id'];
|
90 |
-
$this->name
|
91 |
-
$this->value
|
92 |
-
$this->
|
93 |
} else {
|
94 |
$this->occurrence_id = $occurrence_id;
|
95 |
-
$this->name
|
96 |
-
$this->value
|
97 |
-
$this->
|
98 |
}
|
99 |
}
|
100 |
}
|
54 |
*
|
55 |
* @var string
|
56 |
*/
|
57 |
+
protected $adapter_name = 'Meta';
|
58 |
|
59 |
/**
|
60 |
* Save Metadata into Adapter.
|
61 |
*
|
|
|
62 |
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
63 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::save()
|
64 |
*/
|
65 |
+
public function save_meta() {
|
66 |
+
$this->state = self::STATE_UNKNOWN;
|
67 |
+
$update_id = $this->get_id();
|
68 |
+
$result = $this->get_adapter()->save( $this );
|
69 |
|
70 |
if ( false !== $result ) {
|
71 |
+
$this->state = ( ! empty( $update_id ) ) ? self::STATE_UPDATED : self::STATE_CREATED;
|
72 |
}
|
73 |
return $result;
|
74 |
}
|
76 |
/**
|
77 |
* Update Metadata by name and occurrence_id.
|
78 |
*
|
79 |
+
* @param string $name - Meta name.
|
80 |
+
* @param mixed $value - Meta value.
|
81 |
* @param integer $occurrence_id - Occurrence_id.
|
82 |
*
|
83 |
+
* @see WSAL_Adapters_MySQL_Meta::load_by_name_and_occurrence_id()
|
84 |
*/
|
85 |
+
public function update_by_name_and_occurrence_id( $name, $value, $occurrence_id ) {
|
86 |
+
$meta = $this->get_adapter()->load_by_name_and_occurrence_id( $name, $occurrence_id );
|
87 |
if ( ! empty( $meta ) ) {
|
88 |
+
$this->id = $meta['id'];
|
89 |
$this->occurrence_id = $meta['occurrence_id'];
|
90 |
+
$this->name = $meta['name'];
|
91 |
+
$this->value = maybe_serialize( $value );
|
92 |
+
$this->save_meta();
|
93 |
} else {
|
94 |
$this->occurrence_id = $occurrence_id;
|
95 |
+
$this->name = $name;
|
96 |
+
$this->value = maybe_serialize( $value );
|
97 |
+
$this->save_meta();
|
98 |
}
|
99 |
}
|
100 |
}
|
classes/Models/Occurrence.php
CHANGED
@@ -18,22 +18,29 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
18 |
* used for get the alert, set the meta fields, etc.
|
19 |
*
|
20 |
* @package wsal
|
|
|
|
|
21 |
*/
|
22 |
class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
23 |
|
|
|
|
|
|
|
|
|
|
|
24 |
public static $migrated_meta = array(
|
25 |
-
'ClientIP'
|
26 |
-
'Severity'
|
27 |
-
'Object'
|
28 |
-
'EventType'
|
29 |
-
'UserAgent'
|
30 |
'CurrentUserRoles' => 'user_roles',
|
31 |
-
'Username'
|
32 |
-
'CurrentUserID'
|
33 |
-
'SessionID'
|
34 |
-
'PostStatus'
|
35 |
-
'PostType'
|
36 |
-
'PostID'
|
37 |
);
|
38 |
|
39 |
/**
|
@@ -165,25 +172,27 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
165 |
*
|
166 |
* @var string
|
167 |
*/
|
168 |
-
protected $
|
169 |
|
170 |
/**
|
|
|
|
|
171 |
* @var string
|
172 |
*/
|
173 |
-
public $
|
174 |
|
175 |
/**
|
176 |
* Returns the alert related to this occurrence.
|
177 |
*
|
178 |
-
* @see WSAL_AlertManager::GetAlert()
|
179 |
* @return WSAL_Alert
|
|
|
180 |
*/
|
181 |
-
public function
|
182 |
-
return WpSecurityAuditLog::
|
183 |
$this->alert_id,
|
184 |
(object) array(
|
185 |
-
'mesg' =>
|
186 |
-
'desc' =>
|
187 |
)
|
188 |
);
|
189 |
}
|
@@ -191,24 +200,24 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
191 |
/**
|
192 |
* Returns the value of a meta item.
|
193 |
*
|
194 |
-
* @param string $name
|
195 |
-
* @param mixed
|
196 |
*
|
197 |
* @return mixed The value, if meta item does not exist $default returned.
|
198 |
-
* @see WSAL_Adapters_MySQL_Occurrence::
|
199 |
*/
|
200 |
-
public function
|
201 |
$result = $default;
|
202 |
|
203 |
-
//
|
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->
|
212 |
if ( is_null( $meta ) || ! array_key_exists( 'value', $meta ) ) {
|
213 |
return $default;
|
214 |
}
|
@@ -228,14 +237,14 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
228 |
/**
|
229 |
* Sets the value of a meta item (creates or updates meta item).
|
230 |
*
|
231 |
-
* @param string $name
|
232 |
-
* @param mixed
|
233 |
*/
|
234 |
-
public function
|
235 |
// check explicitly for `0` string values.
|
236 |
if ( '0' === $value || ! empty( $value ) ) {
|
237 |
-
//
|
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 ) {
|
@@ -250,10 +259,10 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
250 |
} else {
|
251 |
// Get meta adapter.
|
252 |
$model = new WSAL_Models_Meta();
|
253 |
-
$model->occurrence_id = $this->
|
254 |
$model->name = $name;
|
255 |
$model->value = maybe_serialize( $value );
|
256 |
-
$model->
|
257 |
}
|
258 |
}
|
259 |
}
|
@@ -261,25 +270,25 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
261 |
/**
|
262 |
* Update Metadata of this occurrence by name.
|
263 |
*
|
264 |
-
* @param string $name
|
265 |
-
* @param mixed
|
266 |
*
|
267 |
-
|
268 |
*/
|
269 |
-
public function
|
270 |
$model = new WSAL_Models_Meta();
|
271 |
-
$model->
|
272 |
}
|
273 |
|
274 |
/**
|
275 |
* Returns a key-value pair of metadata.
|
276 |
*
|
277 |
* @return array
|
278 |
-
* @see WSAL_Adapters_MySQL_Occurrence::
|
279 |
*/
|
280 |
-
public function
|
281 |
$result = array();
|
282 |
-
$metas = $this->
|
283 |
foreach ( $metas as $meta ) {
|
284 |
$result[ $meta->name ] = maybe_unserialize( $meta->value );
|
285 |
}
|
@@ -298,39 +307,38 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
298 |
*/
|
299 |
public function SetMeta( $data ) {
|
300 |
foreach ( (array) $data as $key => $val ) {
|
301 |
-
$this->
|
302 |
}
|
303 |
|
304 |
-
//
|
305 |
-
$this->
|
306 |
}
|
307 |
|
308 |
/**
|
309 |
* Gets alert message.
|
310 |
*
|
311 |
-
* @param array
|
312 |
* @param string $context Message context.
|
313 |
*
|
314 |
* @return string Full-formatted message.
|
315 |
-
* @
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
$this->_cachedMessage = $this->GetAlert()->mesg;
|
323 |
}
|
324 |
// Fill variables in message.
|
325 |
-
$meta_array = null === $meta ? $this->
|
326 |
-
$alert_object = $this->
|
327 |
-
if ( null !== $alert_object && method_exists( $alert_object, '
|
328 |
-
$this->
|
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 |
|
333 |
-
$installer_nonce
|
334 |
foreach ( $addon_event_codes as $key => $addon ) {
|
335 |
if ( in_array( $this->alert_id, $addon['event_ids'], true ) ) {
|
336 |
// check key and update message here.
|
@@ -345,7 +353,7 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
345 |
return $message;
|
346 |
}
|
347 |
}
|
348 |
-
$this->
|
349 |
/* Translators: 1: html that opens a link, 2: html that closes a link. */
|
350 |
__( '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.', 'wp-security-audit-log' ),
|
351 |
'<a href="https://wpactivitylog.com/support/kb/create-custom-events-wordpress-activity-log/" rel="noopener noreferrer" target="_blank">',
|
@@ -353,22 +361,24 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
353 |
);
|
354 |
}
|
355 |
}
|
356 |
-
return $this->
|
357 |
}
|
358 |
|
359 |
/**
|
360 |
* Delete occurrence as well as associated meta data.
|
361 |
*
|
362 |
-
* @see WSAL_Adapters_ActiveRecordInterface::
|
363 |
* @return boolean True on success, false on failure.
|
|
|
|
|
364 |
*/
|
365 |
-
public function
|
366 |
/** @var WSAL_Adapters_MySQL_Occurrence $adapter */
|
367 |
-
$adapter= $this->
|
368 |
-
foreach ( $adapter->
|
369 |
-
$meta->
|
370 |
}
|
371 |
-
return parent::
|
372 |
}
|
373 |
|
374 |
/**
|
@@ -387,8 +397,8 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
387 |
*
|
388 |
* @return string IP address of request.
|
389 |
*/
|
390 |
-
public function
|
391 |
-
return $this->
|
392 |
}
|
393 |
|
394 |
/**
|
@@ -396,9 +406,9 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
396 |
*
|
397 |
* @return string IP address of request (from proxies etc).
|
398 |
*/
|
399 |
-
public function
|
400 |
$result = array();
|
401 |
-
$data = (array) $this->
|
402 |
foreach ( $data as $ips ) {
|
403 |
foreach ( $ips as $ip ) {
|
404 |
$result[] = $ip;
|
@@ -412,12 +422,17 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
412 |
*
|
413 |
* @return array Array of user roles.
|
414 |
*/
|
415 |
-
public function
|
416 |
-
return $this->
|
417 |
}
|
418 |
|
419 |
-
|
420 |
-
|
|
|
|
|
|
|
|
|
|
|
421 |
}
|
422 |
|
423 |
/**
|
@@ -425,8 +440,8 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
425 |
*
|
426 |
* @return string User's username.
|
427 |
*/
|
428 |
-
public function
|
429 |
-
return WSAL_Utilities_UsersUtils::
|
430 |
}
|
431 |
|
432 |
/**
|
@@ -435,8 +450,8 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
435 |
* @return float - Number of seconds (and milliseconds as fraction) since unix Day 0.
|
436 |
* @todo This needs some caching.
|
437 |
*/
|
438 |
-
protected function
|
439 |
-
return microtime( true )
|
440 |
}
|
441 |
|
442 |
/**
|
@@ -445,8 +460,8 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
445 |
* @param array $args - Query args.
|
446 |
* @return WSAL_Models_Occurrence[]
|
447 |
*/
|
448 |
-
public function
|
449 |
-
return $this->
|
450 |
}
|
451 |
|
452 |
/**
|
@@ -455,8 +470,8 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
455 |
* @param array $args - Query args.
|
456 |
* @return WSAL_Models_Occurrence[]
|
457 |
*/
|
458 |
-
public function
|
459 |
-
return $this->
|
460 |
}
|
461 |
|
462 |
/**
|
@@ -466,47 +481,60 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
|
466 |
* @return WSAL_Models_Occurrence[]
|
467 |
*/
|
468 |
public function check_alert_1003( $args = array() ) {
|
469 |
-
return $this->
|
470 |
}
|
471 |
|
472 |
/**
|
473 |
* Gets occurrence by Post_id
|
474 |
*
|
475 |
-
* @see WSAL_Adapters_MySQL_Occurrence::GetByPostID()
|
476 |
* @param integer $post_id - Post ID.
|
|
|
477 |
* @return WSAL_Models_Occurrence[]
|
|
|
478 |
*/
|
479 |
-
public function
|
480 |
-
return $this->
|
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
|
491 |
$copy = get_class( $this );
|
492 |
$copy = new $copy();
|
493 |
foreach ( (array) $data as $key => $val ) {
|
494 |
-
if ( ! is_null( $val ) && in_array($key,
|
495 |
-
//
|
496 |
-
//
|
497 |
if ( 'user_id' === $key ) {
|
498 |
$this->user_id = intval( $val );
|
499 |
-
}
|
500 |
$this->username = (string) $val;
|
501 |
}
|
502 |
-
}
|
503 |
-
$this->
|
504 |
-
}
|
505 |
-
//
|
506 |
$this->$key = $this->cast_to_correct_type( $copy, $key, $val );
|
507 |
}
|
508 |
}
|
509 |
|
510 |
return $this;
|
511 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
}
|
18 |
* used for get the alert, set the meta fields, etc.
|
19 |
*
|
20 |
* @package wsal
|
21 |
+
*
|
22 |
+
* phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
|
23 |
*/
|
24 |
class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord {
|
25 |
|
26 |
+
/**
|
27 |
+
* List of migrated metadata fields.
|
28 |
+
*
|
29 |
+
* @var string[]
|
30 |
+
*/
|
31 |
public static $migrated_meta = array(
|
32 |
+
'ClientIP' => 'client_ip',
|
33 |
+
'Severity' => 'severity',
|
34 |
+
'Object' => 'object',
|
35 |
+
'EventType' => 'event_type',
|
36 |
+
'UserAgent' => 'user_agent',
|
37 |
'CurrentUserRoles' => 'user_roles',
|
38 |
+
'Username' => 'username',
|
39 |
+
'CurrentUserID' => 'user_id',
|
40 |
+
'SessionID' => 'session_id',
|
41 |
+
'PostStatus' => 'post_status',
|
42 |
+
'PostType' => 'post_type',
|
43 |
+
'PostID' => 'post_id',
|
44 |
);
|
45 |
|
46 |
/**
|
172 |
*
|
173 |
* @var string
|
174 |
*/
|
175 |
+
protected $adapter_name = 'Occurrence';
|
176 |
|
177 |
/**
|
178 |
+
* Cached message.
|
179 |
+
*
|
180 |
* @var string
|
181 |
*/
|
182 |
+
public $_cached_message;
|
183 |
|
184 |
/**
|
185 |
* Returns the alert related to this occurrence.
|
186 |
*
|
|
|
187 |
* @return WSAL_Alert
|
188 |
+
* @see WSAL_AlertManager::get_alert()
|
189 |
*/
|
190 |
+
public function get_alert() {
|
191 |
+
return WpSecurityAuditLog::get_instance()->alerts->get_alert(
|
192 |
$this->alert_id,
|
193 |
(object) array(
|
194 |
+
'mesg' => esc_html__( 'Alert message not found.', 'wp-security-audit-log' ),
|
195 |
+
'desc' => esc_html__( 'Alert description not found.', 'wp-security-audit-log' ),
|
196 |
)
|
197 |
);
|
198 |
}
|
200 |
/**
|
201 |
* Returns the value of a meta item.
|
202 |
*
|
203 |
+
* @param string $name - Name of meta item.
|
204 |
+
* @param mixed $default - Default value returned when meta does not exist.
|
205 |
*
|
206 |
* @return mixed The value, if meta item does not exist $default returned.
|
207 |
+
* @see WSAL_Adapters_MySQL_Occurrence::get_named_meta()
|
208 |
*/
|
209 |
+
public function get_meta_value( $name, $default = array() ) {
|
210 |
$result = $default;
|
211 |
|
212 |
+
// Check if the meta is part of the occurrences table.
|
213 |
+
if ( in_array( $name, array_keys( self::$migrated_meta ), true ) ) {
|
214 |
$property_name = self::$migrated_meta[ $name ];
|
215 |
if ( property_exists( $this, $property_name ) ) {
|
216 |
$result = $this->$property_name;
|
217 |
}
|
218 |
} else {
|
219 |
// Get meta adapter.
|
220 |
+
$meta = $this->get_adapter()->get_named_meta( $this, $name );
|
221 |
if ( is_null( $meta ) || ! array_key_exists( 'value', $meta ) ) {
|
222 |
return $default;
|
223 |
}
|
237 |
/**
|
238 |
* Sets the value of a meta item (creates or updates meta item).
|
239 |
*
|
240 |
+
* @param string $name - Meta name.
|
241 |
+
* @param mixed $value - Meta value.
|
242 |
*/
|
243 |
+
public function set_meta_value( $name, $value ) {
|
244 |
// check explicitly for `0` string values.
|
245 |
if ( '0' === $value || ! empty( $value ) ) {
|
246 |
+
// Check if the meta is part of the occurrences table.
|
247 |
+
if ( in_array( $name, array_keys( self::$migrated_meta ), true ) ) {
|
248 |
$property_name = self::$migrated_meta[ $name ];
|
249 |
if ( property_exists( $this, $property_name ) ) {
|
250 |
if ( 'CurrentUserRoles' === $name ) {
|
259 |
} else {
|
260 |
// Get meta adapter.
|
261 |
$model = new WSAL_Models_Meta();
|
262 |
+
$model->occurrence_id = $this->get_id();
|
263 |
$model->name = $name;
|
264 |
$model->value = maybe_serialize( $value );
|
265 |
+
$model->save_meta();
|
266 |
}
|
267 |
}
|
268 |
}
|
270 |
/**
|
271 |
* Update Metadata of this occurrence by name.
|
272 |
*
|
273 |
+
* @param string $name - Meta name.
|
274 |
+
* @param mixed $value - Meta value.
|
275 |
*
|
276 |
+
* @see WSAL_Models_Meta::update_by_name_and_occurrence_id()
|
277 |
*/
|
278 |
+
public function update_meta_value( $name, $value ) {
|
279 |
$model = new WSAL_Models_Meta();
|
280 |
+
$model->update_by_name_and_occurrence_id( $name, $value, $this->get_id() );
|
281 |
}
|
282 |
|
283 |
/**
|
284 |
* Returns a key-value pair of metadata.
|
285 |
*
|
286 |
* @return array
|
287 |
+
* @see WSAL_Adapters_MySQL_Occurrence::get_multi_meta()
|
288 |
*/
|
289 |
+
public function get_meta_array() {
|
290 |
$result = array();
|
291 |
+
$metas = $this->get_adapter()->get_multi_meta( $this );
|
292 |
foreach ( $metas as $meta ) {
|
293 |
$result[ $meta->name ] = maybe_unserialize( $meta->value );
|
294 |
}
|
307 |
*/
|
308 |
public function SetMeta( $data ) {
|
309 |
foreach ( (array) $data as $key => $val ) {
|
310 |
+
$this->set_meta_value( $key, $val );
|
311 |
}
|
312 |
|
313 |
+
// The occurrence object itself needs to be saved again as some metadata is stored as its properties.
|
314 |
+
$this->save();
|
315 |
}
|
316 |
|
317 |
/**
|
318 |
* Gets alert message.
|
319 |
*
|
320 |
+
* @param array $meta - Occurrence meta array.
|
321 |
* @param string $context Message context.
|
322 |
*
|
323 |
* @return string Full-formatted message.
|
324 |
+
* @see WSAL_Alert::get_message()
|
325 |
+
*/
|
326 |
+
public function get_message( $meta = null, $context = false ) {
|
327 |
+
if ( ! isset( $this->_cached_message ) ) {
|
328 |
+
// Message caching.
|
329 |
+
if ( ! $this->_cached_message ) {
|
330 |
+
$this->_cached_message = $this->get_alert()->mesg;
|
|
|
331 |
}
|
332 |
// Fill variables in message.
|
333 |
+
$meta_array = null === $meta ? $this->get_meta_array() : $meta;
|
334 |
+
$alert_object = $this->get_alert();
|
335 |
+
if ( null !== $alert_object && method_exists( $alert_object, 'get_message' ) ) {
|
336 |
+
$this->_cached_message = $alert_object->get_message( $meta_array, $this->_cached_message, $this->get_id(), $context );
|
337 |
} else {
|
338 |
// Filter to allow items to be added elsewhere.
|
339 |
$addon_event_codes = apply_filters( 'wsal_addon_event_codes', $addon_event_codes );
|
340 |
|
341 |
+
$installer_nonce = wp_create_nonce( 'wsal-install-addon' );
|
342 |
foreach ( $addon_event_codes as $key => $addon ) {
|
343 |
if ( in_array( $this->alert_id, $addon['event_ids'], true ) ) {
|
344 |
// check key and update message here.
|
353 |
return $message;
|
354 |
}
|
355 |
}
|
356 |
+
$this->_cached_message = isset( $cached_message ) ? $cached_message : sprintf(
|
357 |
/* Translators: 1: html that opens a link, 2: html that closes a link. */
|
358 |
__( '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.', 'wp-security-audit-log' ),
|
359 |
'<a href="https://wpactivitylog.com/support/kb/create-custom-events-wordpress-activity-log/" rel="noopener noreferrer" target="_blank">',
|
361 |
);
|
362 |
}
|
363 |
}
|
364 |
+
return $this->_cached_message;
|
365 |
}
|
366 |
|
367 |
/**
|
368 |
* Delete occurrence as well as associated meta data.
|
369 |
*
|
370 |
+
* @see WSAL_Adapters_ActiveRecordInterface::delete()
|
371 |
* @return boolean True on success, false on failure.
|
372 |
+
*
|
373 |
+
* @phpcs:disable Generic.Commenting.DocComment.MissingShort
|
374 |
*/
|
375 |
+
public function delete() {
|
376 |
/** @var WSAL_Adapters_MySQL_Occurrence $adapter */
|
377 |
+
$adapter = $this->get_adapter();
|
378 |
+
foreach ( $adapter->get_multi_meta() as $meta ) {
|
379 |
+
$meta->delete();
|
380 |
}
|
381 |
+
return parent::delete();
|
382 |
}
|
383 |
|
384 |
/**
|
397 |
*
|
398 |
* @return string IP address of request.
|
399 |
*/
|
400 |
+
public function get_source_ip() {
|
401 |
+
return $this->get_meta_value( 'ClientIP', array() );
|
402 |
}
|
403 |
|
404 |
/**
|
406 |
*
|
407 |
* @return string IP address of request (from proxies etc).
|
408 |
*/
|
409 |
+
public function get_other_ips() {
|
410 |
$result = array();
|
411 |
+
$data = (array) $this->get_meta_value( 'OtherIPs', array() );
|
412 |
foreach ( $data as $ips ) {
|
413 |
foreach ( $ips as $ip ) {
|
414 |
$result[] = $ip;
|
422 |
*
|
423 |
* @return array Array of user roles.
|
424 |
*/
|
425 |
+
public function get_user_roles() {
|
426 |
+
return $this->get_meta_value( 'CurrentUserRoles', array() );
|
427 |
}
|
428 |
|
429 |
+
/**
|
430 |
+
* Sets the user roles.
|
431 |
+
*
|
432 |
+
* @param string $roles Array of user roles.
|
433 |
+
*/
|
434 |
+
public function set_user_roles( $roles ) {
|
435 |
+
$this->user_roles = is_array( $roles ) ? implode( ',', $roles ) : $roles;
|
436 |
}
|
437 |
|
438 |
/**
|
440 |
*
|
441 |
* @return string User's username.
|
442 |
*/
|
443 |
+
public function get_username() {
|
444 |
+
return WSAL_Utilities_UsersUtils::get_username( $this->get_meta_array() );
|
445 |
}
|
446 |
|
447 |
/**
|
450 |
* @return float - Number of seconds (and milliseconds as fraction) since unix Day 0.
|
451 |
* @todo This needs some caching.
|
452 |
*/
|
453 |
+
protected function get_microtime() {
|
454 |
+
return microtime( true );
|
455 |
}
|
456 |
|
457 |
/**
|
460 |
* @param array $args - Query args.
|
461 |
* @return WSAL_Models_Occurrence[]
|
462 |
*/
|
463 |
+
public function check_known_users( $args = array() ) {
|
464 |
+
return $this->get_adapter()->check_known_users( $args );
|
465 |
}
|
466 |
|
467 |
/**
|
470 |
* @param array $args - Query args.
|
471 |
* @return WSAL_Models_Occurrence[]
|
472 |
*/
|
473 |
+
public function check_unknown_users( $args = array() ) {
|
474 |
+
return $this->get_adapter()->check_unknown_users( $args );
|
475 |
}
|
476 |
|
477 |
/**
|
481 |
* @return WSAL_Models_Occurrence[]
|
482 |
*/
|
483 |
public function check_alert_1003( $args = array() ) {
|
484 |
+
return $this->get_adapter()->check_alert_1003( $args );
|
485 |
}
|
486 |
|
487 |
/**
|
488 |
* Gets occurrence by Post_id
|
489 |
*
|
|
|
490 |
* @param integer $post_id - Post ID.
|
491 |
+
*
|
492 |
* @return WSAL_Models_Occurrence[]
|
493 |
+
* @see WSAL_Adapters_MySQL_Occurrence::get_by_post_id()
|
494 |
*/
|
495 |
+
public function get_by_post_id( $post_id ) {
|
496 |
+
return $this->get_adapter()->get_by_post_id( $post_id );
|
497 |
}
|
498 |
|
499 |
/**
|
500 |
+
* {@inheritDoc}
|
501 |
*
|
502 |
* Extends the default mechanism for loading data to handle the migrated meta fields in version 4.4.0.
|
503 |
*
|
504 |
* @since 4.4.0
|
505 |
*/
|
506 |
+
public function load_data( $data ) {
|
507 |
$copy = get_class( $this );
|
508 |
$copy = new $copy();
|
509 |
foreach ( (array) $data as $key => $val ) {
|
510 |
+
if ( ! is_null( $val ) && in_array( $key, array( 'user_id', 'username' ), true ) ) {
|
511 |
+
// Username and user_id cannot have the default value set because some database queries rely on having
|
512 |
+
// null values in the database.
|
513 |
if ( 'user_id' === $key ) {
|
514 |
$this->user_id = intval( $val );
|
515 |
+
} elseif ( 'username' === $key ) {
|
516 |
$this->username = (string) $val;
|
517 |
}
|
518 |
+
} elseif ( 'roles' === $key ) {
|
519 |
+
$this->set_user_roles( $val );
|
520 |
+
} elseif ( isset( $copy->$key ) ) {
|
521 |
+
// Default type casting is applied to the rest of the fields.
|
522 |
$this->$key = $this->cast_to_correct_type( $copy, $key, $val );
|
523 |
}
|
524 |
}
|
525 |
|
526 |
return $this;
|
527 |
}
|
528 |
+
|
529 |
+
/**
|
530 |
+
* Deprecated placeholder function.
|
531 |
+
*
|
532 |
+
* @return array
|
533 |
+
*
|
534 |
+
* @deprecated 4.4.1 Replaced by function get_meta_array.
|
535 |
+
* @see WSAL_Models_Occurrence::get_meta_array()
|
536 |
+
*/
|
537 |
+
public function GetMetaArray() {
|
538 |
+
return $this->get_meta_array();
|
539 |
+
}
|
540 |
}
|
classes/Models/OccurrenceQuery.php
CHANGED
@@ -57,6 +57,6 @@ class WSAL_Models_OccurrenceQuery extends WSAL_Models_Query {
|
|
57 |
parent::__construct();
|
58 |
|
59 |
// TO DO: Consider if Get Table is the right method to call given that this is mysql specific.
|
60 |
-
$this->
|
61 |
}
|
62 |
}
|
57 |
parent::__construct();
|
58 |
|
59 |
// TO DO: Consider if Get Table is the right method to call given that this is mysql specific.
|
60 |
+
$this->add_from( $this->get_connector()->get_adapter( 'Occurrence' )->get_table() );
|
61 |
}
|
62 |
}
|
classes/Models/Query.php
CHANGED
@@ -40,7 +40,7 @@ class WSAL_Models_Query {
|
|
40 |
*
|
41 |
* @var array
|
42 |
*/
|
43 |
-
protected $
|
44 |
|
45 |
/**
|
46 |
* Offset.
|
@@ -75,7 +75,7 @@ class WSAL_Models_Query {
|
|
75 |
*
|
76 |
* @var mixed
|
77 |
*/
|
78 |
-
protected $
|
79 |
|
80 |
/**
|
81 |
* Use Default Adapter.
|
@@ -97,15 +97,15 @@ class WSAL_Models_Query {
|
|
97 |
*
|
98 |
* @return WSAL_Connector_ConnectorInterface
|
99 |
*/
|
100 |
-
public function
|
101 |
if ( ! empty( $this->connector ) ) {
|
102 |
return $this->connector;
|
103 |
}
|
104 |
|
105 |
if ( $this->use_default_adapter ) {
|
106 |
-
$this->connector = WSAL_Connector_ConnectorFactory::
|
107 |
} else {
|
108 |
-
$this->connector = WSAL_Connector_ConnectorFactory::
|
109 |
}
|
110 |
return $this->connector;
|
111 |
}
|
@@ -115,8 +115,8 @@ class WSAL_Models_Query {
|
|
115 |
*
|
116 |
* @return WSAL_Adapters_QueryInterface
|
117 |
*/
|
118 |
-
public function
|
119 |
-
return $this->
|
120 |
}
|
121 |
|
122 |
/**
|
@@ -125,7 +125,7 @@ class WSAL_Models_Query {
|
|
125 |
* @param mixed $column - Column value.
|
126 |
* @return self
|
127 |
*/
|
128 |
-
public function
|
129 |
$this->columns[] = $column;
|
130 |
return $this;
|
131 |
}
|
@@ -135,7 +135,7 @@ class WSAL_Models_Query {
|
|
135 |
*
|
136 |
* @return self
|
137 |
*/
|
138 |
-
public function
|
139 |
$this->columns = array();
|
140 |
return $this;
|
141 |
}
|
@@ -145,7 +145,7 @@ class WSAL_Models_Query {
|
|
145 |
*
|
146 |
* @return array $columns
|
147 |
*/
|
148 |
-
public function
|
149 |
return $this->columns;
|
150 |
}
|
151 |
|
@@ -155,7 +155,7 @@ class WSAL_Models_Query {
|
|
155 |
* @param array $columns - Columns values.
|
156 |
* @return self
|
157 |
*/
|
158 |
-
public function
|
159 |
$this->columns = $columns;
|
160 |
return $this;
|
161 |
}
|
@@ -167,7 +167,7 @@ class WSAL_Models_Query {
|
|
167 |
* @param mixed $value - Condition value.
|
168 |
* @return self
|
169 |
*/
|
170 |
-
public function
|
171 |
$this->conditions[ $field ] = $value;
|
172 |
return $this;
|
173 |
}
|
@@ -177,7 +177,7 @@ class WSAL_Models_Query {
|
|
177 |
*
|
178 |
* @param array $add_conditions - Multi conditions.
|
179 |
*/
|
180 |
-
public function
|
181 |
$this->conditions[] = $add_conditions;
|
182 |
}
|
183 |
|
@@ -186,7 +186,7 @@ class WSAL_Models_Query {
|
|
186 |
*
|
187 |
* @return self
|
188 |
*/
|
189 |
-
public function
|
190 |
$this->conditions = array();
|
191 |
return $this;
|
192 |
}
|
@@ -196,20 +196,22 @@ class WSAL_Models_Query {
|
|
196 |
*
|
197 |
* @return array $conditions
|
198 |
*/
|
199 |
-
public function
|
200 |
return $this->conditions;
|
201 |
}
|
202 |
|
203 |
/**
|
204 |
* Add order by.
|
205 |
*
|
206 |
-
* @param string $field
|
207 |
* @param boolean $is_descending - (Optional) Ascending/descending.
|
|
|
208 |
* @return self
|
209 |
*/
|
210 |
-
public function
|
211 |
-
$order
|
212 |
-
$this->
|
|
|
213 |
return $this;
|
214 |
}
|
215 |
|
@@ -218,8 +220,8 @@ class WSAL_Models_Query {
|
|
218 |
*
|
219 |
* @return self
|
220 |
*/
|
221 |
-
public function
|
222 |
-
$this->
|
223 |
return $this;
|
224 |
}
|
225 |
|
@@ -228,8 +230,8 @@ class WSAL_Models_Query {
|
|
228 |
*
|
229 |
* @return array $orderBy
|
230 |
*/
|
231 |
-
public function
|
232 |
-
return $this->
|
233 |
}
|
234 |
|
235 |
/**
|
@@ -238,7 +240,7 @@ class WSAL_Models_Query {
|
|
238 |
* @param string $from_data_set - Data set.
|
239 |
* @return self
|
240 |
*/
|
241 |
-
public function
|
242 |
$this->from[] = $from_data_set;
|
243 |
return $this;
|
244 |
}
|
@@ -248,7 +250,7 @@ class WSAL_Models_Query {
|
|
248 |
*
|
249 |
* @return self
|
250 |
*/
|
251 |
-
public function
|
252 |
$this->from = array();
|
253 |
return $this;
|
254 |
}
|
@@ -258,7 +260,7 @@ class WSAL_Models_Query {
|
|
258 |
*
|
259 |
* @return string $from data set
|
260 |
*/
|
261 |
-
public function
|
262 |
return $this->from;
|
263 |
}
|
264 |
|
@@ -267,7 +269,7 @@ class WSAL_Models_Query {
|
|
267 |
*
|
268 |
* @return mixed
|
269 |
*/
|
270 |
-
public function
|
271 |
return $this->limit;
|
272 |
}
|
273 |
|
@@ -277,7 +279,7 @@ class WSAL_Models_Query {
|
|
277 |
* @param mixed $limit - The limit.
|
278 |
* @return self
|
279 |
*/
|
280 |
-
public function
|
281 |
$this->limit = $limit;
|
282 |
return $this;
|
283 |
}
|
@@ -287,7 +289,7 @@ class WSAL_Models_Query {
|
|
287 |
*
|
288 |
* @return mixed
|
289 |
*/
|
290 |
-
public function
|
291 |
return $this->offset;
|
292 |
}
|
293 |
|
@@ -297,7 +299,7 @@ class WSAL_Models_Query {
|
|
297 |
* @param mixed $offset - The offset.
|
298 |
* @return self
|
299 |
*/
|
300 |
-
public function
|
301 |
$this->offset = $offset;
|
302 |
return $this;
|
303 |
}
|
@@ -308,8 +310,8 @@ class WSAL_Models_Query {
|
|
308 |
* @param mixed $value - Condition.
|
309 |
* @return self
|
310 |
*/
|
311 |
-
public function
|
312 |
-
$this->
|
313 |
return $this;
|
314 |
}
|
315 |
|
@@ -318,8 +320,8 @@ class WSAL_Models_Query {
|
|
318 |
*
|
319 |
* @return self
|
320 |
*/
|
321 |
-
public function
|
322 |
-
return $this->
|
323 |
}
|
324 |
|
325 |
/**
|
@@ -327,7 +329,7 @@ class WSAL_Models_Query {
|
|
327 |
*
|
328 |
* @return boolean
|
329 |
*/
|
330 |
-
public function
|
331 |
return $this->meta_join;
|
332 |
}
|
333 |
|
@@ -336,8 +338,49 @@ class WSAL_Models_Query {
|
|
336 |
*
|
337 |
* @return self
|
338 |
*/
|
339 |
-
public function
|
340 |
$this->meta_join = true;
|
341 |
return $this;
|
342 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
343 |
}
|
40 |
*
|
41 |
* @var array
|
42 |
*/
|
43 |
+
protected $order_by = array();
|
44 |
|
45 |
/**
|
46 |
* Offset.
|
75 |
*
|
76 |
* @var mixed
|
77 |
*/
|
78 |
+
protected $search_condition = null;
|
79 |
|
80 |
/**
|
81 |
* Use Default Adapter.
|
97 |
*
|
98 |
* @return WSAL_Connector_ConnectorInterface
|
99 |
*/
|
100 |
+
public function get_connector() {
|
101 |
if ( ! empty( $this->connector ) ) {
|
102 |
return $this->connector;
|
103 |
}
|
104 |
|
105 |
if ( $this->use_default_adapter ) {
|
106 |
+
$this->connector = WSAL_Connector_ConnectorFactory::get_default_connector();
|
107 |
} else {
|
108 |
+
$this->connector = WSAL_Connector_ConnectorFactory::get_connector();
|
109 |
}
|
110 |
return $this->connector;
|
111 |
}
|
115 |
*
|
116 |
* @return WSAL_Adapters_QueryInterface
|
117 |
*/
|
118 |
+
public function get_adapter() {
|
119 |
+
return $this->get_connector()->get_adapter( 'Query' );
|
120 |
}
|
121 |
|
122 |
/**
|
125 |
* @param mixed $column - Column value.
|
126 |
* @return self
|
127 |
*/
|
128 |
+
public function add_column( $column ) {
|
129 |
$this->columns[] = $column;
|
130 |
return $this;
|
131 |
}
|
135 |
*
|
136 |
* @return self
|
137 |
*/
|
138 |
+
public function clear_columns() {
|
139 |
$this->columns = array();
|
140 |
return $this;
|
141 |
}
|
145 |
*
|
146 |
* @return array $columns
|
147 |
*/
|
148 |
+
public function get_columns() {
|
149 |
return $this->columns;
|
150 |
}
|
151 |
|
155 |
* @param array $columns - Columns values.
|
156 |
* @return self
|
157 |
*/
|
158 |
+
public function set_columns( $columns ) {
|
159 |
$this->columns = $columns;
|
160 |
return $this;
|
161 |
}
|
167 |
* @param mixed $value - Condition value.
|
168 |
* @return self
|
169 |
*/
|
170 |
+
public function add_condition( $field, $value ) {
|
171 |
$this->conditions[ $field ] = $value;
|
172 |
return $this;
|
173 |
}
|
177 |
*
|
178 |
* @param array $add_conditions - Multi conditions.
|
179 |
*/
|
180 |
+
public function add_or_condition( $add_conditions ) {
|
181 |
$this->conditions[] = $add_conditions;
|
182 |
}
|
183 |
|
186 |
*
|
187 |
* @return self
|
188 |
*/
|
189 |
+
public function clear_conditions() {
|
190 |
$this->conditions = array();
|
191 |
return $this;
|
192 |
}
|
196 |
*
|
197 |
* @return array $conditions
|
198 |
*/
|
199 |
+
public function get_conditions() {
|
200 |
return $this->conditions;
|
201 |
}
|
202 |
|
203 |
/**
|
204 |
* Add order by.
|
205 |
*
|
206 |
+
* @param string $field - Field name.
|
207 |
* @param boolean $is_descending - (Optional) Ascending/descending.
|
208 |
+
*
|
209 |
* @return self
|
210 |
*/
|
211 |
+
public function add_order_by( $field, $is_descending = false ) {
|
212 |
+
$order = ( $is_descending ) ? 'DESC' : 'ASC';
|
213 |
+
$this->order_by[ $field ] = $order;
|
214 |
+
|
215 |
return $this;
|
216 |
}
|
217 |
|
220 |
*
|
221 |
* @return self
|
222 |
*/
|
223 |
+
public function clear_order_by() {
|
224 |
+
$this->order_by = array();
|
225 |
return $this;
|
226 |
}
|
227 |
|
230 |
*
|
231 |
* @return array $orderBy
|
232 |
*/
|
233 |
+
public function get_order_by() {
|
234 |
+
return $this->order_by;
|
235 |
}
|
236 |
|
237 |
/**
|
240 |
* @param string $from_data_set - Data set.
|
241 |
* @return self
|
242 |
*/
|
243 |
+
public function add_from( $from_data_set ) {
|
244 |
$this->from[] = $from_data_set;
|
245 |
return $this;
|
246 |
}
|
250 |
*
|
251 |
* @return self
|
252 |
*/
|
253 |
+
public function clear_from() {
|
254 |
$this->from = array();
|
255 |
return $this;
|
256 |
}
|
260 |
*
|
261 |
* @return string $from data set
|
262 |
*/
|
263 |
+
public function get_from() {
|
264 |
return $this->from;
|
265 |
}
|
266 |
|
269 |
*
|
270 |
* @return mixed
|
271 |
*/
|
272 |
+
public function get_limit() {
|
273 |
return $this->limit;
|
274 |
}
|
275 |
|
279 |
* @param mixed $limit - The limit.
|
280 |
* @return self
|
281 |
*/
|
282 |
+
public function set_limit( $limit ) {
|
283 |
$this->limit = $limit;
|
284 |
return $this;
|
285 |
}
|
289 |
*
|
290 |
* @return mixed
|
291 |
*/
|
292 |
+
public function get_offset() {
|
293 |
return $this->offset;
|
294 |
}
|
295 |
|
299 |
* @param mixed $offset - The offset.
|
300 |
* @return self
|
301 |
*/
|
302 |
+
public function set_offset( $offset ) {
|
303 |
$this->offset = $offset;
|
304 |
return $this;
|
305 |
}
|
310 |
* @param mixed $value - Condition.
|
311 |
* @return self
|
312 |
*/
|
313 |
+
public function add_search_condition( $value ) {
|
314 |
+
$this->search_condition = $value;
|
315 |
return $this;
|
316 |
}
|
317 |
|
320 |
*
|
321 |
* @return self
|
322 |
*/
|
323 |
+
public function get_search_condition() {
|
324 |
+
return $this->search_condition;
|
325 |
}
|
326 |
|
327 |
/**
|
329 |
*
|
330 |
* @return boolean
|
331 |
*/
|
332 |
+
public function has_meta_join() {
|
333 |
return $this->meta_join;
|
334 |
}
|
335 |
|
338 |
*
|
339 |
* @return self
|
340 |
*/
|
341 |
+
public function add_meta_join() {
|
342 |
$this->meta_join = true;
|
343 |
return $this;
|
344 |
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Deprecated placeholder function.
|
348 |
+
*
|
349 |
+
* @return WSAL_Adapters_QueryInterface
|
350 |
+
* @see WSAL_Models_Query::get_adapter()
|
351 |
+
*
|
352 |
+
* @deprecated 4.4.1 Replaced by function get_adapter.
|
353 |
+
*/
|
354 |
+
public function getAdapter() {
|
355 |
+
return $this->get_adapter();
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Deprecated placeholder function.
|
360 |
+
*
|
361 |
+
* @param string $field - Field name.
|
362 |
+
* @param boolean $is_descending - (Optional) Ascending/descending.
|
363 |
+
*
|
364 |
+
* @return self
|
365 |
+
* @see WSAL_Models_Query::add_order_by()
|
366 |
+
*
|
367 |
+
* @deprecated 4.4.1 Replaced by function add_order_by.
|
368 |
+
*/
|
369 |
+
public function addOrderBy( $field, $is_descending = false ) {
|
370 |
+
return $this->add_order_by( $field, $is_descending );
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Deprecated placeholder function.
|
375 |
+
*
|
376 |
+
* @param mixed $limit - The limit.
|
377 |
+
*
|
378 |
+
* @return self
|
379 |
+
* @see WSAL_Models_Query::set_limit()
|
380 |
+
*
|
381 |
+
* @deprecated 4.4.1 Replaced by function set_limit.
|
382 |
+
*/
|
383 |
+
public function setLimit( $limit ) {
|
384 |
+
return $this->set_limit( $limit );
|
385 |
+
}
|
386 |
}
|
classes/Models/TmpUser.php
CHANGED
@@ -40,5 +40,5 @@ class WSAL_Models_TmpUser extends WSAL_Models_ActiveRecord {
|
|
40 |
*
|
41 |
* @var string
|
42 |
*/
|
43 |
-
protected $
|
44 |
}
|
40 |
*
|
41 |
* @var string
|
42 |
*/
|
43 |
+
protected $adapter_name = 'TmpUser';
|
44 |
}
|
classes/Nicer.php
CHANGED
@@ -1,4 +1,13 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Inspects and prints out PHP values as HTML in a nicer way than print_r().
|
4 |
*
|
@@ -9,6 +18,7 @@
|
|
9 |
* @version 2.0
|
10 |
* @since 2.0
|
11 |
* @package wsal
|
|
|
12 |
*/
|
13 |
class WSAL_Nicer {
|
14 |
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WSAL_Nicer class.
|
4 |
+
*
|
5 |
+
* @since 2.0
|
6 |
+
* @package wsal
|
7 |
+
*/
|
8 |
+
|
9 |
+
// phpcs:disable
|
10 |
+
|
11 |
/**
|
12 |
* Inspects and prints out PHP values as HTML in a nicer way than print_r().
|
13 |
*
|
18 |
* @version 2.0
|
19 |
* @since 2.0
|
20 |
* @package wsal
|
21 |
+
*
|
22 |
*/
|
23 |
class WSAL_Nicer {
|
24 |
|
classes/Ref.php
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Inspects and prints out PHP values as HTML in a nicer way than print_r().
|
4 |
*
|
1 |
<?php
|
2 |
+
// phpcs:ignoreFile
|
3 |
/**
|
4 |
* Inspects and prints out PHP values as HTML in a nicer way than print_r().
|
5 |
*
|
classes/ReportArgs.php
CHANGED
@@ -1,4 +1,13 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
// Exit if accessed directly.
|
4 |
if ( ! defined( 'ABSPATH' ) ) {
|
@@ -175,9 +184,11 @@ class WSAL_ReportArgs {
|
|
175 |
public $post_status__not_in;
|
176 |
|
177 |
/**
|
178 |
-
*
|
|
|
|
|
179 |
*
|
180 |
-
* @return WSAL_ReportArgs
|
181 |
*/
|
182 |
public static function build_from_alternative_filters( $filters ) {
|
183 |
$_filters = array();
|
@@ -191,14 +202,16 @@ class WSAL_ReportArgs {
|
|
191 |
}
|
192 |
}
|
193 |
|
194 |
-
return self::build_from_extension_filters( $_filters, WpSecurityAuditLog::
|
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 |
|
@@ -343,7 +356,7 @@ class WSAL_ReportArgs {
|
|
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->
|
347 |
if ( false === $result ) {
|
348 |
return array();
|
349 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Report arguments class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage reports
|
7 |
+
*
|
8 |
+
* @author Martin Krcho <martin@wpwhitesecurity.com>
|
9 |
+
* @since 4.3.2
|
10 |
+
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
13 |
if ( ! defined( 'ABSPATH' ) ) {
|
184 |
public $post_status__not_in;
|
185 |
|
186 |
/**
|
187 |
+
* Builds the object from alternative filters data.
|
188 |
+
*
|
189 |
+
* @param array $filters Filters data.
|
190 |
*
|
191 |
+
* @return WSAL_ReportArgs Report args object.
|
192 |
*/
|
193 |
public static function build_from_alternative_filters( $filters ) {
|
194 |
$_filters = array();
|
202 |
}
|
203 |
}
|
204 |
|
205 |
+
return self::build_from_extension_filters( $_filters, WpSecurityAuditLog::get_instance()->reports_util );
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
+
* Builds the object from extension filters data.
|
210 |
+
*
|
211 |
* @param array $filters An array of filters as defined in the Reports extension form.
|
212 |
* @param WSAL_Rep_Common $report_utils Reporting utils.
|
213 |
*
|
214 |
+
* @return WSAL_ReportArgs Report args object.
|
215 |
*/
|
216 |
public static function build_from_extension_filters( $filters, $report_utils ) {
|
217 |
|
356 |
$groups = self::is_field_present_and_non_empty_array( $groups_key, $array ) ? $array[ $groups_key ] : array();
|
357 |
$alerts = self::is_field_present_and_non_empty_array( $codes_key, $array ) ? $array[ $codes_key ] : array();
|
358 |
|
359 |
+
$result = $report_utils->get_codes_by_groups( $groups, $alerts, false );
|
360 |
if ( false === $result ) {
|
361 |
return array();
|
362 |
}
|
classes/SensorManager.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* Sensor manager class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -38,7 +38,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
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->
|
42 |
}
|
43 |
|
44 |
/*
|
@@ -53,6 +53,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
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;
|
@@ -72,7 +73,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
72 |
* is retained for back-compat.
|
73 |
*/
|
74 |
$class = ( class_exists( $sensor ) ) ? $sensor : 'WSAL_Sensors_' . $sensor;
|
75 |
-
$this->
|
76 |
}
|
77 |
}
|
78 |
}
|
@@ -81,16 +82,16 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
81 |
/**
|
82 |
* {@inheritDoc}
|
83 |
*/
|
84 |
-
public function
|
85 |
foreach ( $this->sensors as $sensor ) {
|
86 |
-
$sensor->
|
87 |
}
|
88 |
}
|
89 |
|
90 |
/**
|
91 |
* Method: Get the sensors.
|
92 |
*/
|
93 |
-
public function
|
94 |
return $this->sensors;
|
95 |
}
|
96 |
|
@@ -99,7 +100,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
99 |
*
|
100 |
* @param string $file Path to file.
|
101 |
*/
|
102 |
-
public function
|
103 |
/**
|
104 |
* Filter: `wsal_before_sensor_load`
|
105 |
*
|
@@ -112,7 +113,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
112 |
|
113 |
// Initiate the sensor if $load_sensor is true.
|
114 |
if ( $load_sensor ) {
|
115 |
-
$this->
|
116 |
}
|
117 |
}
|
118 |
|
@@ -121,8 +122,8 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
121 |
*
|
122 |
* @param string $class Class name.
|
123 |
*/
|
124 |
-
public function
|
125 |
-
$this->
|
126 |
}
|
127 |
|
128 |
/**
|
@@ -130,7 +131,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
130 |
*
|
131 |
* @param WSAL_AbstractSensor $sensor The new sensor.
|
132 |
*/
|
133 |
-
public function
|
134 |
$this->sensors[] = $sensor;
|
135 |
}
|
136 |
|
@@ -143,7 +144,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
143 |
*/
|
144 |
public function check_sensor_before_load( $load_sensor, $filepath ) {
|
145 |
global $pagenow;
|
146 |
-
if ( ! $this->plugin->
|
147 |
$admin_page = $pagenow;
|
148 |
} else {
|
149 |
/**
|
@@ -189,14 +190,14 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
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->
|
200 |
// Multisite sign-up is happening on front-end.
|
201 |
array_push( $default_public_sensors, 'MultisiteSignUp' );
|
202 |
}
|
@@ -256,7 +257,7 @@ final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
|
256 |
|
257 |
case 'Multisite':
|
258 |
// If site is not multisite then don't load it.
|
259 |
-
if ( ! $this->plugin->
|
260 |
$load_sensor = false;
|
261 |
}
|
262 |
break;
|
4 |
*
|
5 |
* Sensor manager class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
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->add_from_file( $file );
|
42 |
}
|
43 |
|
44 |
/*
|
53 |
foreach ( $paths as $inc_path ) {
|
54 |
// Check directory.
|
55 |
if ( is_dir( $inc_path ) && is_readable( $inc_path ) ) {
|
56 |
+
$inc_path = trailingslashit( $inc_path );
|
57 |
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $inc_path, '*.php' ) as $file ) {
|
58 |
// Include custom sensor file.
|
59 |
require_once $file;
|
73 |
* is retained for back-compat.
|
74 |
*/
|
75 |
$class = ( class_exists( $sensor ) ) ? $sensor : 'WSAL_Sensors_' . $sensor;
|
76 |
+
$this->add_from_class( $class );
|
77 |
}
|
78 |
}
|
79 |
}
|
82 |
/**
|
83 |
* {@inheritDoc}
|
84 |
*/
|
85 |
+
public function hook_events() {
|
86 |
foreach ( $this->sensors as $sensor ) {
|
87 |
+
$sensor->hook_events();
|
88 |
}
|
89 |
}
|
90 |
|
91 |
/**
|
92 |
* Method: Get the sensors.
|
93 |
*/
|
94 |
+
public function get_sensors() {
|
95 |
return $this->sensors;
|
96 |
}
|
97 |
|
100 |
*
|
101 |
* @param string $file Path to file.
|
102 |
*/
|
103 |
+
public function add_from_file( $file ) {
|
104 |
/**
|
105 |
* Filter: `wsal_before_sensor_load`
|
106 |
*
|
113 |
|
114 |
// Initiate the sensor if $load_sensor is true.
|
115 |
if ( $load_sensor ) {
|
116 |
+
$this->add_from_class( $this->plugin->autoloader->get_class_file_class_name( $file ) );
|
117 |
}
|
118 |
}
|
119 |
|
122 |
*
|
123 |
* @param string $class Class name.
|
124 |
*/
|
125 |
+
public function add_from_class( $class ) {
|
126 |
+
$this->add_instance( new $class( $this->plugin ) );
|
127 |
}
|
128 |
|
129 |
/**
|
131 |
*
|
132 |
* @param WSAL_AbstractSensor $sensor The new sensor.
|
133 |
*/
|
134 |
+
public function add_instance( $sensor ) {
|
135 |
$this->sensors[] = $sensor;
|
136 |
}
|
137 |
|
144 |
*/
|
145 |
public function check_sensor_before_load( $load_sensor, $filepath ) {
|
146 |
global $pagenow;
|
147 |
+
if ( ! $this->plugin->is_multisite() ) {
|
148 |
$admin_page = $pagenow;
|
149 |
} else {
|
150 |
/**
|
190 |
|
191 |
// Only LogInOut and Register sensors should load on login page.
|
192 |
if ( WpSecurityAuditLog::is_login_screen() ) {
|
193 |
+
if ( in_array( $filename, array( 'Register', 'LogInOut' ), true ) ) {
|
194 |
return true;
|
195 |
}
|
196 |
return false; // Any other sensor should not load here.
|
197 |
}
|
198 |
|
199 |
$default_public_sensors = array( 'Register', 'LogInOut' );
|
200 |
+
if ( $this->plugin->is_multisite() ) {
|
201 |
// Multisite sign-up is happening on front-end.
|
202 |
array_push( $default_public_sensors, 'MultisiteSignUp' );
|
203 |
}
|
257 |
|
258 |
case 'Multisite':
|
259 |
// If site is not multisite then don't load it.
|
260 |
+
if ( ! $this->plugin->is_multisite() ) {
|
261 |
$load_sensor = false;
|
262 |
}
|
263 |
break;
|
classes/Sensors/ACFMeta.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* Advanced Custom Fields sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -19,9 +19,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
19 |
* 2131 ACF relationship added
|
20 |
* 2132 ACF relationship removed
|
21 |
*
|
22 |
-
* @package
|
23 |
* @subpackage sensors
|
24 |
-
* @since
|
25 |
*/
|
26 |
class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
27 |
|
@@ -35,32 +35,32 @@ class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
|
35 |
/**
|
36 |
* Listening to events using WP hooks.
|
37 |
*/
|
38 |
-
public function
|
39 |
-
add_filter(
|
40 |
|
41 |
-
//
|
42 |
-
add_action(
|
43 |
-
add_action(
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
* Runs before an ACF field value is updated. It stores locally information
|
48 |
* about relationship fields that are being updated.
|
49 |
*
|
50 |
-
* @param mixed
|
51 |
-
* @param mixed
|
52 |
-
* @param int $post_id
|
53 |
-
* @param array
|
54 |
*
|
55 |
* @return mixed
|
56 |
*/
|
57 |
public function prepare_relationship_update_check( $check, $value, $post_id, $field ) {
|
58 |
-
if ( 'relationship'
|
59 |
-
$this->old_meta[ $field['name'] ] =
|
60 |
'field' => $field,
|
61 |
'value' => get_field( $field['name'] ),
|
62 |
-
'post_id' => $post_id
|
63 |
-
|
64 |
}
|
65 |
|
66 |
return $check;
|
@@ -69,14 +69,14 @@ class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
|
69 |
/**
|
70 |
* Fires immediately after updating metadata of a specific type.
|
71 |
*
|
72 |
-
* @param int
|
73 |
-
* @param int
|
74 |
* @param string $meta_key Metadata key.
|
75 |
-
* @param mixed
|
76 |
*/
|
77 |
public function on_field_updated( $meta_id, $object_id, $meta_key, $_meta_value ) {
|
78 |
-
if ( in_array( $meta_key, array_keys( $this->old_meta ) ) ) {
|
79 |
-
if ( $this->
|
80 |
$old_value = $this->convert_to_array_of_post_ids( $this->old_meta[ $meta_key ]['value'] );
|
81 |
$new_value = $this->convert_to_array_of_post_ids( $_meta_value );
|
82 |
$removed = array_diff( $old_value, $new_value );
|
@@ -101,11 +101,14 @@ class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
|
101 |
* @return int[]
|
102 |
*/
|
103 |
private function convert_to_array_of_post_ids( $value ) {
|
104 |
-
$result =
|
105 |
if ( is_array( $value ) ) {
|
106 |
-
$result = array_map(
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
109 |
}
|
110 |
|
111 |
return $result;
|
@@ -114,16 +117,16 @@ class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
|
114 |
/**
|
115 |
* Log event related to ACF relationship field.
|
116 |
*
|
117 |
-
* @param int
|
118 |
-
* @param int[]|WP_Post[] $relationship_post_ids
|
119 |
-
* @param int
|
120 |
-
* @param string
|
121 |
-
* @param int
|
122 |
*/
|
123 |
private function log_event( $event_id, $relationship_post_ids, $object_id, $meta_key, $meta_id ) {
|
124 |
$post = get_post( $object_id );
|
125 |
-
$editor_link = $this->
|
126 |
-
$this->plugin->alerts->
|
127 |
$event_id,
|
128 |
array(
|
129 |
'PostID' => $object_id,
|
@@ -144,13 +147,19 @@ class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
|
144 |
/**
|
145 |
* Formats the relationship label for the activity log entry.
|
146 |
*
|
147 |
-
* @param int[] $post_ids
|
148 |
*
|
149 |
* @return string
|
150 |
*/
|
151 |
private function format_relationships_label( $post_ids ) {
|
152 |
-
return implode(
|
153 |
-
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
}
|
156 |
}
|
4 |
*
|
5 |
* Advanced Custom Fields sensor file.
|
6 |
*
|
7 |
+
* @since 4.1.3
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
19 |
* 2131 ACF relationship added
|
20 |
* 2132 ACF relationship removed
|
21 |
*
|
22 |
+
* @package wsal
|
23 |
* @subpackage sensors
|
24 |
+
* @since 4.1.3
|
25 |
*/
|
26 |
class WSAL_Sensors_ACFMeta extends WSAL_AbstractMetaDataSensor {
|
27 |
|
35 |
/**
|
36 |
* Listening to events using WP hooks.
|
37 |
*/
|
38 |
+
public function hook_events() {
|
39 |
+
add_filter( 'acf/pre_update_value', array( $this, 'prepare_relationship_update_check' ), 10, 4 );
|
40 |
|
41 |
+
// Relationship field is only available for posts to we don't need to check other meta types (comment, term, or user).
|
42 |
+
add_action( 'updated_post_meta', array( $this, 'on_field_updated' ), 10, 4 );
|
43 |
+
add_action( 'deleted_post_meta', array( $this, 'on_field_updated' ), 10, 4 );
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
* Runs before an ACF field value is updated. It stores locally information
|
48 |
* about relationship fields that are being updated.
|
49 |
*
|
50 |
+
* @param mixed $check Variable allowing short-circuiting of update_value logic.
|
51 |
+
* @param mixed $value The new value.
|
52 |
+
* @param int|string $post_id The post id.
|
53 |
+
* @param array $field The field array.
|
54 |
*
|
55 |
* @return mixed
|
56 |
*/
|
57 |
public function prepare_relationship_update_check( $check, $value, $post_id, $field ) {
|
58 |
+
if ( 'relationship' === $field['type'] ) {
|
59 |
+
$this->old_meta[ $field['name'] ] = array(
|
60 |
'field' => $field,
|
61 |
'value' => get_field( $field['name'] ),
|
62 |
+
'post_id' => $post_id,
|
63 |
+
);
|
64 |
}
|
65 |
|
66 |
return $check;
|
69 |
/**
|
70 |
* Fires immediately after updating metadata of a specific type.
|
71 |
*
|
72 |
+
* @param int $meta_id ID of updated metadata entry.
|
73 |
+
* @param int $object_id ID of the object metadata is for.
|
74 |
* @param string $meta_key Metadata key.
|
75 |
+
* @param mixed $_meta_value Metadata value. Serialized if non-scalar.
|
76 |
*/
|
77 |
public function on_field_updated( $meta_id, $object_id, $meta_key, $_meta_value ) {
|
78 |
+
if ( in_array( $meta_key, array_keys( $this->old_meta ) ) ) { // phpcs:ignore
|
79 |
+
if ( $this->can_log_meta_key( 'post', $object_id, $meta_key ) ) {
|
80 |
$old_value = $this->convert_to_array_of_post_ids( $this->old_meta[ $meta_key ]['value'] );
|
81 |
$new_value = $this->convert_to_array_of_post_ids( $_meta_value );
|
82 |
$removed = array_diff( $old_value, $new_value );
|
101 |
* @return int[]
|
102 |
*/
|
103 |
private function convert_to_array_of_post_ids( $value ) {
|
104 |
+
$result = array();
|
105 |
if ( is_array( $value ) ) {
|
106 |
+
$result = array_map(
|
107 |
+
function ( $item ) {
|
108 |
+
return ( $item instanceof WP_Post ) ? $item->ID : intval( $item );
|
109 |
+
},
|
110 |
+
$value
|
111 |
+
);
|
112 |
}
|
113 |
|
114 |
return $result;
|
117 |
/**
|
118 |
* Log event related to ACF relationship field.
|
119 |
*
|
120 |
+
* @param int $event_id Event ID.
|
121 |
+
* @param int[]|WP_Post[] $relationship_post_ids Posts or post IDs.
|
122 |
+
* @param int $object_id Object ID.
|
123 |
+
* @param string $meta_key Meta key.
|
124 |
+
* @param int $meta_id Meta ID.
|
125 |
*/
|
126 |
private function log_event( $event_id, $relationship_post_ids, $object_id, $meta_key, $meta_id ) {
|
127 |
$post = get_post( $object_id );
|
128 |
+
$editor_link = $this->get_editor_link( $object_id );
|
129 |
+
$this->plugin->alerts->trigger_event(
|
130 |
$event_id,
|
131 |
array(
|
132 |
'PostID' => $object_id,
|
147 |
/**
|
148 |
* Formats the relationship label for the activity log entry.
|
149 |
*
|
150 |
+
* @param int[] $post_ids List of post IDs.
|
151 |
*
|
152 |
* @return string
|
153 |
*/
|
154 |
private function format_relationships_label( $post_ids ) {
|
155 |
+
return implode(
|
156 |
+
', ',
|
157 |
+
array_map(
|
158 |
+
function ( $post_id ) {
|
159 |
+
return get_the_title( $post_id ) . ' (' . $post_id . ')';
|
160 |
+
},
|
161 |
+
$post_ids
|
162 |
+
)
|
163 |
+
);
|
164 |
}
|
165 |
}
|
classes/Sensors/Comments.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Comments sensor class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -27,23 +28,23 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
27 |
* 2098 User permanently deleted a comment
|
28 |
* 2099 User posted a comment
|
29 |
*
|
30 |
-
* @package
|
31 |
* @subpackage sensors
|
32 |
*/
|
33 |
class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
34 |
|
35 |
/**
|
36 |
-
*
|
37 |
*/
|
38 |
-
public function
|
39 |
-
add_action( 'edit_comment', array( $this, '
|
40 |
-
add_action( 'transition_comment_status', array( $this, '
|
41 |
-
add_action( 'spammed_comment', array( $this, '
|
42 |
-
add_action( 'unspammed_comment', array( $this, '
|
43 |
-
add_action( 'trashed_comment', array( $this, '
|
44 |
-
add_action( 'untrashed_comment', array( $this, '
|
45 |
-
add_action( 'deleted_comment', array( $this, '
|
46 |
-
add_action( 'comment_post', array( $this, '
|
47 |
}
|
48 |
|
49 |
/**
|
@@ -51,7 +52,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
51 |
*
|
52 |
* @param integer $comment_id - Comment ID.
|
53 |
*/
|
54 |
-
public function
|
55 |
$this->EventGeneric( $comment_id, 2093 );
|
56 |
}
|
57 |
|
@@ -62,7 +63,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
62 |
* @param string $old_status - Old status.
|
63 |
* @param stdClass $comment - Comment.
|
64 |
*/
|
65 |
-
public function
|
66 |
if ( ! empty( $comment ) && $old_status !== $new_status ) {
|
67 |
$post = get_post( $comment->comment_post_ID );
|
68 |
$comment_link = get_permalink( $post->ID ) . '#comment-' . $comment->comment_ID;
|
@@ -78,10 +79,10 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
78 |
);
|
79 |
|
80 |
if ( 'approved' === $new_status ) {
|
81 |
-
$this->plugin->alerts->
|
82 |
}
|
83 |
if ( 'unapproved' === $new_status ) {
|
84 |
-
$this->plugin->alerts->
|
85 |
}
|
86 |
}
|
87 |
}
|
@@ -91,7 +92,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
91 |
*
|
92 |
* @param integer $comment_id - Comment ID.
|
93 |
*/
|
94 |
-
public function
|
95 |
$this->EventGeneric( $comment_id, 2094 );
|
96 |
}
|
97 |
|
@@ -100,7 +101,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
100 |
*
|
101 |
* @param integer $comment_id - Comment ID.
|
102 |
*/
|
103 |
-
public function
|
104 |
$this->EventGeneric( $comment_id, 2095 );
|
105 |
}
|
106 |
|
@@ -109,7 +110,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
109 |
*
|
110 |
* @param integer $comment_id - Comment ID.
|
111 |
*/
|
112 |
-
public function
|
113 |
$this->EventGeneric( $comment_id, 2096 );
|
114 |
}
|
115 |
|
@@ -118,7 +119,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
118 |
*
|
119 |
* @param integer $comment_id comment ID.
|
120 |
*/
|
121 |
-
public function
|
122 |
$this->EventGeneric( $comment_id, 2097 );
|
123 |
}
|
124 |
|
@@ -127,7 +128,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
127 |
*
|
128 |
* @param integer $comment_id comment ID.
|
129 |
*/
|
130 |
-
public function
|
131 |
$this->EventGeneric( $comment_id, 2098 );
|
132 |
}
|
133 |
|
@@ -138,7 +139,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
138 |
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
139 |
* @param array $comment_data Comment data.
|
140 |
*/
|
141 |
-
public function
|
142 |
// Check if the comment is response to another comment.
|
143 |
if ( isset( $comment_data['comment_parent'] ) && $comment_data['comment_parent'] ) {
|
144 |
$this->EventGeneric( $comment_id, 2092 );
|
@@ -157,7 +158,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
157 |
'PostStatus' => $post->post_status,
|
158 |
'CommentID' => $comment->comment_ID,
|
159 |
'Date' => $comment->comment_date,
|
160 |
-
'CommentLink' => $comment_link
|
161 |
);
|
162 |
|
163 |
// Get user data.
|
@@ -175,7 +176,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
175 |
// Set the fields.
|
176 |
$fields['Username'] = $user_data->user_login;
|
177 |
$fields['CurrentUserRoles'] = $user_roles;
|
178 |
-
$this->plugin->alerts->
|
179 |
}
|
180 |
}
|
181 |
}
|
@@ -205,7 +206,7 @@ class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
|
205 |
);
|
206 |
|
207 |
if ( 'shop_order' !== $post->post_type ) {
|
208 |
-
$this->plugin->alerts->
|
209 |
}
|
210 |
}
|
211 |
}
|
4 |
*
|
5 |
* Comments sensor class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpachae sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
28 |
* 2098 User permanently deleted a comment
|
29 |
* 2099 User posted a comment
|
30 |
*
|
31 |
+
* @package wsal
|
32 |
* @subpackage sensors
|
33 |
*/
|
34 |
class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
35 |
|
36 |
/**
|
37 |
+
* {@inheritDoc}
|
38 |
*/
|
39 |
+
public function hook_events() {
|
40 |
+
add_action( 'edit_comment', array( $this, 'event_comment_edit' ), 10, 1 );
|
41 |
+
add_action( 'transition_comment_status', array( $this, 'event_comment_approve' ), 10, 3 );
|
42 |
+
add_action( 'spammed_comment', array( $this, 'event_comment_spam' ), 10, 1 );
|
43 |
+
add_action( 'unspammed_comment', array( $this, 'event_comment_unspam' ), 10, 1 );
|
44 |
+
add_action( 'trashed_comment', array( $this, 'event_comment_trash' ), 10, 1 );
|
45 |
+
add_action( 'untrashed_comment', array( $this, 'event_comment_untrash' ), 10, 1 );
|
46 |
+
add_action( 'deleted_comment', array( $this, 'event_comment_deleted' ), 10, 1 );
|
47 |
+
add_action( 'comment_post', array( $this, 'event_comment' ), 10, 3 );
|
48 |
}
|
49 |
|
50 |
/**
|
52 |
*
|
53 |
* @param integer $comment_id - Comment ID.
|
54 |
*/
|
55 |
+
public function event_comment_edit( $comment_id ) {
|
56 |
$this->EventGeneric( $comment_id, 2093 );
|
57 |
}
|
58 |
|
63 |
* @param string $old_status - Old status.
|
64 |
* @param stdClass $comment - Comment.
|
65 |
*/
|
66 |
+
public function event_comment_approve( $new_status, $old_status, $comment ) {
|
67 |
if ( ! empty( $comment ) && $old_status !== $new_status ) {
|
68 |
$post = get_post( $comment->comment_post_ID );
|
69 |
$comment_link = get_permalink( $post->ID ) . '#comment-' . $comment->comment_ID;
|
79 |
);
|
80 |
|
81 |
if ( 'approved' === $new_status ) {
|
82 |
+
$this->plugin->alerts->trigger_event( 2090, $fields );
|
83 |
}
|
84 |
if ( 'unapproved' === $new_status ) {
|
85 |
+
$this->plugin->alerts->trigger_event( 2091, $fields );
|
86 |
}
|
87 |
}
|
88 |
}
|
92 |
*
|
93 |
* @param integer $comment_id - Comment ID.
|
94 |
*/
|
95 |
+
public function event_comment_spam( $comment_id ) {
|
96 |
$this->EventGeneric( $comment_id, 2094 );
|
97 |
}
|
98 |
|
101 |
*
|
102 |
* @param integer $comment_id - Comment ID.
|
103 |
*/
|
104 |
+
public function event_comment_unspam( $comment_id ) {
|
105 |
$this->EventGeneric( $comment_id, 2095 );
|
106 |
}
|
107 |
|
110 |
*
|
111 |
* @param integer $comment_id - Comment ID.
|
112 |
*/
|
113 |
+
public function event_comment_trash( $comment_id ) {
|
114 |
$this->EventGeneric( $comment_id, 2096 );
|
115 |
}
|
116 |
|
119 |
*
|
120 |
* @param integer $comment_id comment ID.
|
121 |
*/
|
122 |
+
public function event_comment_untrash( $comment_id ) {
|
123 |
$this->EventGeneric( $comment_id, 2097 );
|
124 |
}
|
125 |
|
128 |
*
|
129 |
* @param integer $comment_id comment ID.
|
130 |
*/
|
131 |
+
public function event_comment_deleted( $comment_id ) {
|
132 |
$this->EventGeneric( $comment_id, 2098 );
|
133 |
}
|
134 |
|
139 |
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
140 |
* @param array $comment_data Comment data.
|
141 |
*/
|
142 |
+
public function event_comment( $comment_id, $comment_approved, $comment_data ) {
|
143 |
// Check if the comment is response to another comment.
|
144 |
if ( isset( $comment_data['comment_parent'] ) && $comment_data['comment_parent'] ) {
|
145 |
$this->EventGeneric( $comment_id, 2092 );
|
158 |
'PostStatus' => $post->post_status,
|
159 |
'CommentID' => $comment->comment_ID,
|
160 |
'Date' => $comment->comment_date,
|
161 |
+
'CommentLink' => $comment_link,
|
162 |
);
|
163 |
|
164 |
// Get user data.
|
176 |
// Set the fields.
|
177 |
$fields['Username'] = $user_data->user_login;
|
178 |
$fields['CurrentUserRoles'] = $user_roles;
|
179 |
+
$this->plugin->alerts->trigger_event( 2099, $fields );
|
180 |
}
|
181 |
}
|
182 |
}
|
206 |
);
|
207 |
|
208 |
if ( 'shop_order' !== $post->post_type ) {
|
209 |
+
$this->plugin->alerts->trigger_event( $alert_code, $fields );
|
210 |
}
|
211 |
}
|
212 |
}
|
classes/Sensors/Content.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Content sensor class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -20,7 +21,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
20 |
* 5019 A plugin created a post
|
21 |
* 5025 A plugin deleted a post
|
22 |
*
|
23 |
-
* @package
|
|
|
24 |
*/
|
25 |
class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
26 |
|
@@ -29,42 +31,42 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
29 |
*
|
30 |
* @var stdClass
|
31 |
*/
|
32 |
-
protected $
|
33 |
|
34 |
/**
|
35 |
* Old permalink.
|
36 |
*
|
37 |
* @var string
|
38 |
*/
|
39 |
-
protected $
|
40 |
|
41 |
/**
|
42 |
* Old categories.
|
43 |
*
|
44 |
* @var array
|
45 |
*/
|
46 |
-
protected $
|
47 |
|
48 |
/**
|
49 |
* Old tags.
|
50 |
*
|
51 |
* @var array
|
52 |
*/
|
53 |
-
protected $
|
54 |
|
55 |
/**
|
56 |
* Old path to file.
|
57 |
*
|
58 |
* @var string
|
59 |
*/
|
60 |
-
protected $
|
61 |
|
62 |
/**
|
63 |
* Old post is marked as sticky.
|
64 |
*
|
65 |
* @var boolean
|
66 |
*/
|
67 |
-
protected $
|
68 |
|
69 |
/**
|
70 |
* Old Post Status.
|
@@ -81,9 +83,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
81 |
protected $old_meta = null;
|
82 |
|
83 |
/**
|
84 |
-
*
|
85 |
*/
|
86 |
-
public function
|
87 |
add_action( 'pre_post_update', array( $this, 'get_before_post_edit_data' ), 10, 2 );
|
88 |
add_action( 'save_post', array( $this, 'post_changed' ), 10, 3 );
|
89 |
add_action( 'set_object_terms', array( $this, 'post_terms_changed' ), 10, 4 );
|
@@ -123,12 +125,12 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
123 |
|
124 |
// If post exists.
|
125 |
if ( ! empty( $post ) && $post instanceof WP_Post ) {
|
126 |
-
$this->
|
127 |
-
$this->
|
128 |
-
$this->
|
129 |
-
$this->
|
130 |
-
$this->
|
131 |
-
$this->
|
132 |
$this->old_status = $post->post_status;
|
133 |
$this->old_meta = get_post_meta( $post_id );
|
134 |
}
|
@@ -155,8 +157,8 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
155 |
// Ignorable states.
|
156 |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
157 |
// Check post creation event.
|
158 |
-
if ( $this->
|
159 |
-
$this->check_post_creation( $this->
|
160 |
}
|
161 |
return;
|
162 |
}
|
@@ -191,28 +193,28 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
191 |
}
|
192 |
|
193 |
if ( $update ) {
|
194 |
-
$status_event = $this->check_status_change( $this->
|
195 |
|
196 |
-
if ( 2001 !== $status_event && 'auto-draft' !== $this->
|
197 |
// Handle update post events.
|
198 |
$changes = 0;
|
199 |
-
$changes = $this->check_author_change( $this->
|
200 |
-
+ $this->check_parent_change( $this->
|
201 |
-
+ $this->check_visibility_change( $this->
|
202 |
-
+ $this->check_date_change( $this->
|
203 |
-
+ $this->check_permalink_change( $this->
|
204 |
-
+ $this->check_comments_pings( $this->
|
205 |
|
206 |
// If a status change event has occurred, then don't log event 2002 (post modified).
|
207 |
$changes = $status_event ? true : $changes;
|
208 |
if ( '1' === $changes ) {
|
209 |
remove_action( 'save_post', array( $this, 'post_changed' ), 10, 3 );
|
210 |
}
|
211 |
-
$this->check_modification_change( $post->ID, $this->
|
212 |
}
|
213 |
} else {
|
214 |
// If not update then check post creation.
|
215 |
-
$this->check_post_creation( $this->
|
216 |
}
|
217 |
}
|
218 |
|
@@ -246,10 +248,10 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
246 |
|
247 |
if ( 'post_tag' === $taxonomy ) {
|
248 |
// Check tags change event.
|
249 |
-
$this->check_tags_change( $this->
|
250 |
} else {
|
251 |
// Check categories change event.
|
252 |
-
$this->check_categories_change( $this->
|
253 |
}
|
254 |
}
|
255 |
|
@@ -303,7 +305,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
303 |
);
|
304 |
}
|
305 |
|
306 |
-
$this->plugin->alerts->
|
307 |
}
|
308 |
}
|
309 |
|
@@ -317,7 +319,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
317 |
if ( ! in_array( $post->post_type, $this->plugin->alerts->ignored_cpts, true ) ) {
|
318 |
$editor_link = $this->get_editor_link( $post );
|
319 |
|
320 |
-
$this->plugin->alerts->
|
321 |
2012,
|
322 |
array(
|
323 |
'PostID' => $post->ID,
|
@@ -342,7 +344,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
342 |
if ( ! in_array( $post->post_type, $this->plugin->alerts->ignored_cpts, true ) ) {
|
343 |
$editor_link = $this->get_editor_link( $post );
|
344 |
|
345 |
-
$this->plugin->alerts->
|
346 |
2014,
|
347 |
array(
|
348 |
'PostID' => $post->ID,
|
@@ -369,7 +371,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
369 |
if ( ! in_array( $post->post_type, $this->plugin->alerts->ignored_cpts, true ) ) {
|
370 |
$editor_link = $this->get_editor_link( $post );
|
371 |
|
372 |
-
$this->plugin->alerts->
|
373 |
2001,
|
374 |
array(
|
375 |
'PostID' => $post->ID,
|
@@ -397,9 +399,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
397 |
return;
|
398 |
}
|
399 |
|
400 |
-
//
|
401 |
-
$post_id = isset( $_GET['post'] ) ? (int) sanitize_text_field( wp_unslash( $_GET['post'] ) ) : false;
|
402 |
-
// @codingStandardsIgnoreEnd
|
403 |
|
404 |
// Check post id.
|
405 |
if ( empty( $post_id ) ) {
|
@@ -454,14 +454,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
454 |
$post_data = $this->get_post_event_data( $post ); // Get event post data.
|
455 |
|
456 |
// Update post URL based on current actual path.
|
457 |
-
if ( $this->plugin->
|
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 |
|
464 |
-
// Bail if this
|
465 |
if ( ! isset( $post_data['PostUrl'] ) ) {
|
466 |
return;
|
467 |
}
|
@@ -473,7 +473,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
473 |
|
474 |
// Set editor link.
|
475 |
$post_data[ $edit_link['name'] ] = $edit_link['value'];
|
476 |
-
$this->plugin->alerts->
|
477 |
}
|
478 |
}
|
479 |
}
|
@@ -486,7 +486,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
486 |
public function event_category_creation( $category_id ) {
|
487 |
$category = get_category( $category_id );
|
488 |
$category_link = $this->get_taxonomy_edit_link( $category_id, 'category' );
|
489 |
-
$this->plugin->alerts->
|
490 |
2023,
|
491 |
array(
|
492 |
'CategoryName' => $category->name,
|
@@ -504,7 +504,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
504 |
public function event_tag_creation( $tag_id ) {
|
505 |
$tag = get_tag( $tag_id );
|
506 |
$tag_link = $this->get_taxonomy_edit_link( $tag_id );
|
507 |
-
$this->plugin->alerts->
|
508 |
2121,
|
509 |
array(
|
510 |
'TagName' => $tag->name,
|
@@ -523,7 +523,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
523 |
public function check_taxonomy_term_deletion( $term_id, $taxonomy ) {
|
524 |
if ( 'post_tag' === $taxonomy ) {
|
525 |
$tag = get_tag( $term_id );
|
526 |
-
$this->plugin->alerts->
|
527 |
2122,
|
528 |
array(
|
529 |
'TagID' => $term_id,
|
@@ -534,7 +534,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
534 |
} elseif ( 'category' === $taxonomy ) {
|
535 |
$category = get_category( $term_id );
|
536 |
$category_link = $this->get_taxonomy_edit_link( $term_id, $taxonomy );
|
537 |
-
$this->plugin->alerts->
|
538 |
2024,
|
539 |
array(
|
540 |
'CategoryID' => $term_id,
|
@@ -573,7 +573,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
573 |
if ( 'post_tag' === $taxonomy ) {
|
574 |
// Update if both names are not same.
|
575 |
if ( $old_name !== $new_name ) {
|
576 |
-
$this->plugin->alerts->
|
577 |
2123,
|
578 |
array(
|
579 |
'old_name' => $old_name,
|
@@ -586,7 +586,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
586 |
|
587 |
// Update if both slugs are not same.
|
588 |
if ( $old_slug !== $new_slug ) {
|
589 |
-
$this->plugin->alerts->
|
590 |
2124,
|
591 |
array(
|
592 |
'tag' => $new_name,
|
@@ -599,7 +599,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
599 |
|
600 |
// Update if both descriptions are not same.
|
601 |
if ( $old_desc !== $new_desc ) {
|
602 |
-
$this->plugin->alerts->
|
603 |
2125,
|
604 |
array(
|
605 |
'tag' => $new_name,
|
@@ -612,7 +612,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
612 |
} elseif ( 'category' === $taxonomy ) { // Check if the taxonomy is `category`.
|
613 |
// Log event if both names are not same.
|
614 |
if ( $old_name !== $new_name ) {
|
615 |
-
$this->plugin->alerts->
|
616 |
2127,
|
617 |
array(
|
618 |
'old_name' => $old_name,
|
@@ -625,7 +625,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
625 |
|
626 |
// Log event if both slugs are not same.
|
627 |
if ( $old_slug !== $new_slug ) {
|
628 |
-
$this->plugin->alerts->
|
629 |
2128,
|
630 |
array(
|
631 |
'CategoryName' => $new_name,
|
@@ -650,7 +650,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
650 |
}
|
651 |
|
652 |
if ( $old_parent_name !== $new_parent_name ) {
|
653 |
-
$this->plugin->alerts->
|
654 |
2052,
|
655 |
array(
|
656 |
'CategoryName' => $new_name,
|
@@ -752,11 +752,11 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
752 |
*/
|
753 |
public function check_template_change( $post_id, $meta_value ) {
|
754 |
$post = get_post( $post_id );
|
755 |
-
$old_tmpl = ( $this->
|
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->
|
760 |
2048,
|
761 |
array(
|
762 |
'PostID' => $post->ID,
|
@@ -799,7 +799,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
799 |
|
800 |
$post = get_post( $post_id );
|
801 |
$editor_link = $this->get_editor_link( $post );
|
802 |
-
$this->plugin->alerts->
|
803 |
2130,
|
804 |
array(
|
805 |
'PostID' => $post->ID,
|
@@ -833,12 +833,12 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
833 |
|
834 |
// If post exists.
|
835 |
if ( ! empty( $post ) ) {
|
836 |
-
$this->
|
837 |
-
$this->
|
838 |
-
$this->
|
839 |
-
$this->
|
840 |
-
$this->
|
841 |
-
$this->
|
842 |
}
|
843 |
}
|
844 |
}
|
@@ -931,7 +931,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
931 |
|
932 |
if ( $is_scheduled ) {
|
933 |
$event_data['PublishingDate'] = $new_post->post_date;
|
934 |
-
$this->plugin->alerts->
|
935 |
} else {
|
936 |
|
937 |
// So far we assume that the action is initiated by a user, let's check if it was actually initiated
|
@@ -952,7 +952,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
952 |
);
|
953 |
}
|
954 |
|
955 |
-
$this->plugin->alerts->
|
956 |
}
|
957 |
}
|
958 |
}
|
@@ -962,6 +962,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
962 |
* Get editor link.
|
963 |
*
|
964 |
* @param stdClass $post - The post.
|
|
|
965 |
* @return array $editor_link - Name and value link.
|
966 |
*/
|
967 |
private function get_editor_link( $post ) {
|
@@ -1008,7 +1009,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1008 |
$old_author = ( is_object( $old_author ) ) ? $old_author->user_login : 'N/A';
|
1009 |
$new_author = get_userdata( $newpost->post_author );
|
1010 |
$new_author = ( is_object( $new_author ) ) ? $new_author->user_login : 'N/A';
|
1011 |
-
$this->plugin->alerts->
|
1012 |
2019,
|
1013 |
array(
|
1014 |
'PostID' => $oldpost->ID,
|
@@ -1060,14 +1061,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1060 |
|
1061 |
if ( $is_scheduled ) {
|
1062 |
$event_data['PublishingDate'] = $newpost->post_date;
|
1063 |
-
$this->plugin->alerts->
|
1064 |
} elseif ( 2021 === $event ) {
|
1065 |
$event_data['OldStatus'] = $oldpost->post_status;
|
1066 |
$event_data['NewStatus'] = $newpost->post_status;
|
1067 |
-
$this->plugin->alerts->
|
1068 |
} else {
|
1069 |
// NOTE: this triggers if NOT firing event 5019.
|
1070 |
-
$this->plugin->alerts->
|
1071 |
}
|
1072 |
}
|
1073 |
|
@@ -1084,7 +1085,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1084 |
protected function check_parent_change( $oldpost, $newpost ) {
|
1085 |
if ( $oldpost->post_parent !== $newpost->post_parent && 'page' === $newpost->post_type ) {
|
1086 |
$editor_link = $this->get_editor_link( $oldpost );
|
1087 |
-
$this->plugin->alerts->
|
1088 |
2047,
|
1089 |
array(
|
1090 |
'PostID' => $oldpost->ID,
|
@@ -1112,13 +1113,13 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1112 |
*/
|
1113 |
protected function check_permalink_change( $old_link, $new_link, $post ) {
|
1114 |
if ( in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) {
|
1115 |
-
$old_link = $this->
|
1116 |
$new_link = $post->post_name;
|
1117 |
}
|
1118 |
|
1119 |
if ( $old_link !== $new_link ) {
|
1120 |
$editor_link = $this->get_editor_link( $post );
|
1121 |
-
$this->plugin->alerts->
|
1122 |
2017,
|
1123 |
array(
|
1124 |
'PostID' => $post->ID,
|
@@ -1149,24 +1150,24 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1149 |
$new_visibility = '';
|
1150 |
|
1151 |
if ( $oldpost->post_password ) {
|
1152 |
-
$old_visibility =
|
1153 |
} elseif ( 'private' === $oldpost->post_status ) {
|
1154 |
-
$old_visibility =
|
1155 |
} else {
|
1156 |
-
$old_visibility =
|
1157 |
}
|
1158 |
|
1159 |
if ( $newpost->post_password ) {
|
1160 |
-
$new_visibility =
|
1161 |
} elseif ( 'private' === $newpost->post_status ) {
|
1162 |
-
$new_visibility =
|
1163 |
} else {
|
1164 |
-
$new_visibility =
|
1165 |
}
|
1166 |
|
1167 |
if ( $old_visibility && $new_visibility && ( $old_visibility !== $new_visibility ) ) {
|
1168 |
$editor_link = $this->get_editor_link( $oldpost );
|
1169 |
-
$this->plugin->alerts->
|
1170 |
2025,
|
1171 |
array(
|
1172 |
'PostID' => $oldpost->ID,
|
@@ -1207,7 +1208,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1207 |
|
1208 |
if ( $from !== $to ) {
|
1209 |
$editor_link = $this->get_editor_link( $oldpost );
|
1210 |
-
$this->plugin->alerts->
|
1211 |
2027,
|
1212 |
array(
|
1213 |
'PostID' => $oldpost->ID,
|
@@ -1238,7 +1239,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1238 |
|
1239 |
// Comments.
|
1240 |
if ( $oldpost->comment_status !== $newpost->comment_status ) {
|
1241 |
-
$this->plugin->alerts->
|
1242 |
2111,
|
1243 |
array(
|
1244 |
'PostID' => $newpost->ID,
|
@@ -1257,7 +1258,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1257 |
|
1258 |
// Trackbacks and Pingbacks.
|
1259 |
if ( $oldpost->ping_status !== $newpost->ping_status ) {
|
1260 |
-
$this->plugin->alerts->
|
1261 |
2112,
|
1262 |
array(
|
1263 |
'PostID' => $newpost->ID,
|
@@ -1278,9 +1279,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1278 |
/**
|
1279 |
* Categories changed.
|
1280 |
*
|
1281 |
-
* @param array
|
1282 |
-
* @param array
|
1283 |
-
* @param WP_Post $post
|
1284 |
*/
|
1285 |
protected function check_categories_change( $old_cats, $new_cats, $post ) {
|
1286 |
$old_cats = implode( ', ', (array) $old_cats );
|
@@ -1299,23 +1300,23 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1299 |
'NewCategories' => $new_cats ? $new_cats : 'no categories',
|
1300 |
$editor_link['name'] => $editor_link['value'],
|
1301 |
);
|
1302 |
-
$this->plugin->alerts->
|
1303 |
}
|
1304 |
}
|
1305 |
|
1306 |
/**
|
1307 |
* Reports tags change event. This could be tags addition, removal and possibly other in the future.
|
1308 |
*
|
1309 |
-
* @
|
|
|
|
|
1310 |
*
|
1311 |
-
* @
|
1312 |
-
* @param WP_Post $post
|
1313 |
-
* @param string[] $tags_changed
|
1314 |
*/
|
1315 |
private function report_tags_change_event( $event_code, $post, $tags_changed ) {
|
1316 |
$editor_link = $this->get_editor_link( $post );
|
1317 |
$post_status = ( 'publish' === $post->post_status ) ? 'published' : $post->post_status;
|
1318 |
-
$this->plugin->alerts->
|
1319 |
$event_code,
|
1320 |
array(
|
1321 |
'PostID' => $post->ID,
|
@@ -1324,7 +1325,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1324 |
'PostTitle' => $post->post_title,
|
1325 |
'PostDate' => $post->post_date,
|
1326 |
'PostUrl' => get_permalink( $post->ID ),
|
1327 |
-
'tag' => ! empty( $tags_changed ) ? implode( ', ', $tags_changed ) :
|
1328 |
$editor_link['name'] => $editor_link['value'],
|
1329 |
)
|
1330 |
);
|
@@ -1340,11 +1341,11 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1340 |
protected function check_tags_change( $old_tags, $new_tags, $post ) {
|
1341 |
// Ensure old_tags is not null.
|
1342 |
if ( ! $old_tags ) {
|
1343 |
-
$old_tags =
|
1344 |
}
|
1345 |
$intersection = array_intersect( $old_tags, $new_tags );
|
1346 |
if ( count( $intersection ) === count( $old_tags ) && count( $old_tags ) === count( $new_tags ) ) {
|
1347 |
-
//
|
1348 |
return;
|
1349 |
}
|
1350 |
|
@@ -1364,10 +1365,10 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1364 |
/**
|
1365 |
* Post modified content.
|
1366 |
*
|
1367 |
-
* @param integer
|
1368 |
* @param stdClass $oldpost – Old post.
|
1369 |
* @param stdClass $newpost – New post.
|
1370 |
-
* @param int
|
1371 |
*
|
1372 |
* @return int|void
|
1373 |
*/
|
@@ -1376,7 +1377,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1376 |
return;
|
1377 |
}
|
1378 |
|
1379 |
-
$content_changed = $oldpost->post_content
|
1380 |
|
1381 |
/*
|
1382 |
* If the content hasn't changed and this looks to be a draft resave
|
@@ -1403,7 +1404,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1403 |
$yoast_alerts = $yoast_alerts + $yoast_metabox_alerts;
|
1404 |
// Check all alerts.
|
1405 |
foreach ( $yoast_alerts as $alert_code => $alert ) {
|
1406 |
-
if ( $this->plugin->alerts->
|
1407 |
return 0; // Return if any Yoast alert has or will trigger.
|
1408 |
}
|
1409 |
}
|
@@ -1427,18 +1428,19 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1427 |
}
|
1428 |
|
1429 |
if ( $old_post_excerpt !== $post_excerpt ) {
|
1430 |
-
$event
|
1431 |
-
// We are
|
1432 |
$event_data['old_post_excerpt'] = ( $old_post_excerpt ) ? $old_post_excerpt : ' ';
|
1433 |
$event_data['post_excerpt'] = ( $post_excerpt ) ? $post_excerpt : ' ';
|
1434 |
}
|
1435 |
|
1436 |
if ( 2002 === $event ) {
|
1437 |
-
// If we reach this point, we no longer need to check if the content has changed as we already have
|
1438 |
-
// So trigger 2002 regardless and "something" has changed in the post, we
|
1439 |
-
|
|
|
1440 |
} else {
|
1441 |
-
$this->plugin->alerts->
|
1442 |
}
|
1443 |
}
|
1444 |
}
|
@@ -1455,7 +1457,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1455 |
$post_events = array_keys( $this->plugin->alerts->get_alerts_by_sub_category( 'Content' ) );
|
1456 |
|
1457 |
foreach ( $post_events as $event ) {
|
1458 |
-
if ( $manager->
|
1459 |
return false;
|
1460 |
}
|
1461 |
}
|
@@ -1472,7 +1474,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1472 |
private function check_title_change( $oldpost, $newpost ) {
|
1473 |
if ( $oldpost->post_title !== $newpost->post_title ) {
|
1474 |
$editor_link = $this->get_editor_link( $oldpost );
|
1475 |
-
$this->plugin->alerts->
|
1476 |
2086,
|
1477 |
array(
|
1478 |
'PostID' => $newpost->ID,
|
@@ -1534,7 +1536,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1534 |
$event_data = $this->get_post_event_data( $post ); // Event data.
|
1535 |
|
1536 |
$event_data[ $editor_link['name'] ] = $editor_link['value'];
|
1537 |
-
$this->plugin->alerts->
|
1538 |
}
|
1539 |
|
1540 |
/**
|
@@ -1547,26 +1549,11 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1547 |
private function check_auto_draft( $code, $title ) {
|
1548 |
$ignore = 0;
|
1549 |
if ( 2008 === $code && ( 'auto-draft' === $title || 'Auto Draft' === $title ) ) {
|
1550 |
-
$ignore = ! $this->plugin->settings()->
|
1551 |
}
|
1552 |
return $ignore;
|
1553 |
}
|
1554 |
|
1555 |
-
/**
|
1556 |
-
* Comments/Trackbacks and Pingbacks event code.
|
1557 |
-
*
|
1558 |
-
* @param stdClass $post - The post.
|
1559 |
-
* @param string $status - The status.
|
1560 |
-
*/
|
1561 |
-
private function get_comments_pings_event( $post, $status ) {
|
1562 |
-
if ( 'disable' === $status ) {
|
1563 |
-
$event = 2111;
|
1564 |
-
} else {
|
1565 |
-
$event = 2112;
|
1566 |
-
}
|
1567 |
-
return $event;
|
1568 |
-
}
|
1569 |
-
|
1570 |
/**
|
1571 |
* Post Opened for Editing in WP Editors.
|
1572 |
*
|
@@ -1600,7 +1587,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1600 |
$event = 2100;
|
1601 |
if ( ! $this->was_triggered( $event ) ) {
|
1602 |
$editor_link = $this->get_editor_link( $post );
|
1603 |
-
$this->plugin->alerts->
|
1604 |
$event,
|
1605 |
array(
|
1606 |
'PostID' => $post->ID,
|
@@ -1624,14 +1611,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1624 |
*/
|
1625 |
private function was_triggered( $alert_id ) {
|
1626 |
$query = new WSAL_Models_OccurrenceQuery();
|
1627 |
-
$query->
|
1628 |
-
$query->
|
1629 |
-
$
|
1630 |
|
1631 |
-
if ( ! empty( $
|
1632 |
-
if ( ! is_array( $alert_id ) && $
|
1633 |
return true;
|
1634 |
-
} elseif ( is_array( $alert_id ) && in_array( $
|
1635 |
return true;
|
1636 |
}
|
1637 |
}
|
@@ -1690,7 +1677,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1690 |
* @return boolean
|
1691 |
*/
|
1692 |
public function plugin_not_created_post( $manager ) {
|
1693 |
-
$triggered = $manager->
|
1694 |
// inverting value here to account for the double NOT in _CommitItem().
|
1695 |
return ! $triggered;
|
1696 |
}
|
@@ -1698,29 +1685,29 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1698 |
/**
|
1699 |
* Check if the alert was triggered recently.
|
1700 |
*
|
1701 |
-
* Checks last 5 events if they
|
1702 |
*
|
1703 |
* @param integer|array $alert_id - Alert code.
|
1704 |
* @return boolean
|
1705 |
*/
|
1706 |
private function was_triggered_recently( $alert_id ) {
|
1707 |
// if we have already checked this don't check again.
|
1708 |
-
if ( isset( $this->cached_alert_checks ) && array_key_exists( $alert_id, $this->cached_alert_checks ) && $this->cached_alert_checks[$alert_id] ) {
|
1709 |
return true;
|
1710 |
}
|
1711 |
$query = new WSAL_Models_OccurrenceQuery();
|
1712 |
-
$query->
|
1713 |
-
$query->
|
1714 |
-
$
|
1715 |
$known_to_trigger = false;
|
1716 |
-
foreach ( $
|
1717 |
if ( $known_to_trigger ) {
|
1718 |
break;
|
1719 |
}
|
1720 |
-
if ( ! empty( $
|
1721 |
-
if ( ! is_array( $alert_id ) && $
|
1722 |
$known_to_trigger = true;
|
1723 |
-
} elseif ( is_array( $alert_id ) && in_array( $
|
1724 |
$known_to_trigger = true;
|
1725 |
}
|
1726 |
}
|
4 |
*
|
5 |
* Content sensor class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
21 |
* 5019 A plugin created a post
|
22 |
* 5025 A plugin deleted a post
|
23 |
*
|
24 |
+
* @package wsal
|
25 |
+
* @subpackage sensors
|
26 |
*/
|
27 |
class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
28 |
|
31 |
*
|
32 |
* @var stdClass
|
33 |
*/
|
34 |
+
protected $old_post = null;
|
35 |
|
36 |
/**
|
37 |
* Old permalink.
|
38 |
*
|
39 |
* @var string
|
40 |
*/
|
41 |
+
protected $old_link = null;
|
42 |
|
43 |
/**
|
44 |
* Old categories.
|
45 |
*
|
46 |
* @var array
|
47 |
*/
|
48 |
+
protected $old_cats = null;
|
49 |
|
50 |
/**
|
51 |
* Old tags.
|
52 |
*
|
53 |
* @var array
|
54 |
*/
|
55 |
+
protected $old_tags = null;
|
56 |
|
57 |
/**
|
58 |
* Old path to file.
|
59 |
*
|
60 |
* @var string
|
61 |
*/
|
62 |
+
protected $old_tmpl = null;
|
63 |
|
64 |
/**
|
65 |
* Old post is marked as sticky.
|
66 |
*
|
67 |
* @var boolean
|
68 |
*/
|
69 |
+
protected $old_stky = null;
|
70 |
|
71 |
/**
|
72 |
* Old Post Status.
|
83 |
protected $old_meta = null;
|
84 |
|
85 |
/**
|
86 |
+
* {@inheritDoc}
|
87 |
*/
|
88 |
+
public function hook_events() {
|
89 |
add_action( 'pre_post_update', array( $this, 'get_before_post_edit_data' ), 10, 2 );
|
90 |
add_action( 'save_post', array( $this, 'post_changed' ), 10, 3 );
|
91 |
add_action( 'set_object_terms', array( $this, 'post_terms_changed' ), 10, 4 );
|
125 |
|
126 |
// If post exists.
|
127 |
if ( ! empty( $post ) && $post instanceof WP_Post ) {
|
128 |
+
$this->old_post = $post;
|
129 |
+
$this->old_link = get_permalink( $post_id );
|
130 |
+
$this->old_tmpl = $this->get_post_template( $this->old_post );
|
131 |
+
$this->old_cats = $this->get_post_categories( $this->old_post );
|
132 |
+
$this->old_tags = $this->get_post_tags( $this->old_post );
|
133 |
+
$this->old_stky = in_array( $post_id, get_option( 'sticky_posts' ), true );
|
134 |
$this->old_status = $post->post_status;
|
135 |
$this->old_meta = get_post_meta( $post_id );
|
136 |
}
|
157 |
// Ignorable states.
|
158 |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
159 |
// Check post creation event.
|
160 |
+
if ( $this->old_post && 'auto-draft' === $this->old_post->post_status && 'draft' === $post->post_status ) {
|
161 |
+
$this->check_post_creation( $this->old_post, $post );
|
162 |
}
|
163 |
return;
|
164 |
}
|
193 |
}
|
194 |
|
195 |
if ( $update ) {
|
196 |
+
$status_event = $this->check_status_change( $this->old_post, $post );
|
197 |
|
198 |
+
if ( 2001 !== $status_event && 'auto-draft' !== $this->old_post->post_status ) {
|
199 |
// Handle update post events.
|
200 |
$changes = 0;
|
201 |
+
$changes = $this->check_author_change( $this->old_post, $post )
|
202 |
+
+ $this->check_parent_change( $this->old_post, $post )
|
203 |
+
+ $this->check_visibility_change( $this->old_post, $post, $this->old_status, $post->post_status )
|
204 |
+
+ $this->check_date_change( $this->old_post, $post )
|
205 |
+
+ $this->check_permalink_change( $this->old_link, get_permalink( $post->ID ), $post )
|
206 |
+
+ $this->check_comments_pings( $this->old_post, $post );
|
207 |
|
208 |
// If a status change event has occurred, then don't log event 2002 (post modified).
|
209 |
$changes = $status_event ? true : $changes;
|
210 |
if ( '1' === $changes ) {
|
211 |
remove_action( 'save_post', array( $this, 'post_changed' ), 10, 3 );
|
212 |
}
|
213 |
+
$this->check_modification_change( $post->ID, $this->old_post, $post, $changes );
|
214 |
}
|
215 |
} else {
|
216 |
// If not update then check post creation.
|
217 |
+
$this->check_post_creation( $this->old_post, $post );
|
218 |
}
|
219 |
}
|
220 |
|
248 |
|
249 |
if ( 'post_tag' === $taxonomy ) {
|
250 |
// Check tags change event.
|
251 |
+
$this->check_tags_change( $this->old_tags, $this->get_post_tags( $post ), $post );
|
252 |
} else {
|
253 |
// Check categories change event.
|
254 |
+
$this->check_categories_change( $this->old_cats, $this->get_post_categories( $post ), $post );
|
255 |
}
|
256 |
}
|
257 |
|
305 |
);
|
306 |
}
|
307 |
|
308 |
+
$this->plugin->alerts->trigger_event( $event, $event_data ); // Log event.
|
309 |
}
|
310 |
}
|
311 |
|
319 |
if ( ! in_array( $post->post_type, $this->plugin->alerts->ignored_cpts, true ) ) {
|
320 |
$editor_link = $this->get_editor_link( $post );
|
321 |
|
322 |
+
$this->plugin->alerts->trigger_event(
|
323 |
2012,
|
324 |
array(
|
325 |
'PostID' => $post->ID,
|
344 |
if ( ! in_array( $post->post_type, $this->plugin->alerts->ignored_cpts, true ) ) {
|
345 |
$editor_link = $this->get_editor_link( $post );
|
346 |
|
347 |
+
$this->plugin->alerts->trigger_event(
|
348 |
2014,
|
349 |
array(
|
350 |
'PostID' => $post->ID,
|
371 |
if ( ! in_array( $post->post_type, $this->plugin->alerts->ignored_cpts, true ) ) {
|
372 |
$editor_link = $this->get_editor_link( $post );
|
373 |
|
374 |
+
$this->plugin->alerts->trigger_event(
|
375 |
2001,
|
376 |
array(
|
377 |
'PostID' => $post->ID,
|
399 |
return;
|
400 |
}
|
401 |
|
402 |
+
$post_id = isset( $_GET['post'] ) ? (int) sanitize_text_field( wp_unslash( $_GET['post'] ) ) : false; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
|
|
|
403 |
|
404 |
// Check post id.
|
405 |
if ( empty( $post_id ) ) {
|
454 |
$post_data = $this->get_post_event_data( $post ); // Get event post data.
|
455 |
|
456 |
// Update post URL based on current actual path.
|
457 |
+
if ( $this->plugin->is_multisite() && ! is_subdomain_install() ) {
|
458 |
// For multisite using subfolders, remove the subfolder.
|
459 |
+
$subdir_path = parse_url( home_url(), PHP_URL_PATH ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
|
460 |
+
$escaped = str_replace( '/', '\/', preg_quote( $subdir_path ) ); // phpcs:ignore WordPress.PHP.PregQuoteDelimiter.Missing
|
461 |
$current_path = preg_replace( '/' . $escaped . '/', '', $current_path );
|
462 |
}
|
463 |
|
464 |
+
// Bail if this don't have this, as it's probably an archive.
|
465 |
if ( ! isset( $post_data['PostUrl'] ) ) {
|
466 |
return;
|
467 |
}
|
473 |
|
474 |
// Set editor link.
|
475 |
$post_data[ $edit_link['name'] ] = $edit_link['value'];
|
476 |
+
$this->plugin->alerts->trigger_event( 2101, $post_data );
|
477 |
}
|
478 |
}
|
479 |
}
|
486 |
public function event_category_creation( $category_id ) {
|
487 |
$category = get_category( $category_id );
|
488 |
$category_link = $this->get_taxonomy_edit_link( $category_id, 'category' );
|
489 |
+
$this->plugin->alerts->trigger_event(
|
490 |
2023,
|
491 |
array(
|
492 |
'CategoryName' => $category->name,
|
504 |
public function event_tag_creation( $tag_id ) {
|
505 |
$tag = get_tag( $tag_id );
|
506 |
$tag_link = $this->get_taxonomy_edit_link( $tag_id );
|
507 |
+
$this->plugin->alerts->trigger_event(
|
508 |
2121,
|
509 |
array(
|
510 |
'TagName' => $tag->name,
|
523 |
public function check_taxonomy_term_deletion( $term_id, $taxonomy ) {
|
524 |
if ( 'post_tag' === $taxonomy ) {
|
525 |
$tag = get_tag( $term_id );
|
526 |
+
$this->plugin->alerts->trigger_event(
|
527 |
2122,
|
528 |
array(
|
529 |
'TagID' => $term_id,
|
534 |
} elseif ( 'category' === $taxonomy ) {
|
535 |
$category = get_category( $term_id );
|
536 |
$category_link = $this->get_taxonomy_edit_link( $term_id, $taxonomy );
|
537 |
+
$this->plugin->alerts->trigger_event(
|
538 |
2024,
|
539 |
array(
|
540 |
'CategoryID' => $term_id,
|
573 |
if ( 'post_tag' === $taxonomy ) {
|
574 |
// Update if both names are not same.
|
575 |
if ( $old_name !== $new_name ) {
|
576 |
+
$this->plugin->alerts->trigger_event(
|
577 |
2123,
|
578 |
array(
|
579 |
'old_name' => $old_name,
|
586 |
|
587 |
// Update if both slugs are not same.
|
588 |
if ( $old_slug !== $new_slug ) {
|
589 |
+
$this->plugin->alerts->trigger_event(
|
590 |
2124,
|
591 |
array(
|
592 |
'tag' => $new_name,
|
599 |
|
600 |
// Update if both descriptions are not same.
|
601 |
if ( $old_desc !== $new_desc ) {
|
602 |
+
$this->plugin->alerts->trigger_event(
|
603 |
2125,
|
604 |
array(
|
605 |
'tag' => $new_name,
|
612 |
} elseif ( 'category' === $taxonomy ) { // Check if the taxonomy is `category`.
|
613 |
// Log event if both names are not same.
|
614 |
if ( $old_name !== $new_name ) {
|
615 |
+
$this->plugin->alerts->trigger_event(
|
616 |
2127,
|
617 |
array(
|
618 |
'old_name' => $old_name,
|
625 |
|
626 |
// Log event if both slugs are not same.
|
627 |
if ( $old_slug !== $new_slug ) {
|
628 |
+
$this->plugin->alerts->trigger_event(
|
629 |
2128,
|
630 |
array(
|
631 |
'CategoryName' => $new_name,
|
650 |
}
|
651 |
|
652 |
if ( $old_parent_name !== $new_parent_name ) {
|
653 |
+
$this->plugin->alerts->trigger_event(
|
654 |
2052,
|
655 |
array(
|
656 |
'CategoryName' => $new_name,
|
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_event(
|
760 |
2048,
|
761 |
array(
|
762 |
'PostID' => $post->ID,
|
799 |
|
800 |
$post = get_post( $post_id );
|
801 |
$editor_link = $this->get_editor_link( $post );
|
802 |
+
$this->plugin->alerts->trigger_event(
|
803 |
2130,
|
804 |
array(
|
805 |
'PostID' => $post->ID,
|
833 |
|
834 |
// If post exists.
|
835 |
if ( ! empty( $post ) ) {
|
836 |
+
$this->old_post = $post;
|
837 |
+
$this->old_link = get_permalink( $post_id );
|
838 |
+
$this->old_tmpl = $this->get_post_template( $this->old_post );
|
839 |
+
$this->old_cats = $this->get_post_categories( $this->old_post );
|
840 |
+
$this->old_tags = $this->get_post_tags( $this->old_post );
|
841 |
+
$this->old_stky = in_array( $post_id, get_option( 'sticky_posts' ), true );
|
842 |
}
|
843 |
}
|
844 |
}
|
931 |
|
932 |
if ( $is_scheduled ) {
|
933 |
$event_data['PublishingDate'] = $new_post->post_date;
|
934 |
+
$this->plugin->alerts->trigger_event( $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
|
952 |
);
|
953 |
}
|
954 |
|
955 |
+
$this->plugin->alerts->trigger_event( $event, $event_data );
|
956 |
}
|
957 |
}
|
958 |
}
|
962 |
* Get editor link.
|
963 |
*
|
964 |
* @param stdClass $post - The post.
|
965 |
+
*
|
966 |
* @return array $editor_link - Name and value link.
|
967 |
*/
|
968 |
private function get_editor_link( $post ) {
|
1009 |
$old_author = ( is_object( $old_author ) ) ? $old_author->user_login : 'N/A';
|
1010 |
$new_author = get_userdata( $newpost->post_author );
|
1011 |
$new_author = ( is_object( $new_author ) ) ? $new_author->user_login : 'N/A';
|
1012 |
+
$this->plugin->alerts->trigger_event(
|
1013 |
2019,
|
1014 |
array(
|
1015 |
'PostID' => $oldpost->ID,
|
1061 |
|
1062 |
if ( $is_scheduled ) {
|
1063 |
$event_data['PublishingDate'] = $newpost->post_date;
|
1064 |
+
$this->plugin->alerts->trigger_event( $event, $event_data );
|
1065 |
} elseif ( 2021 === $event ) {
|
1066 |
$event_data['OldStatus'] = $oldpost->post_status;
|
1067 |
$event_data['NewStatus'] = $newpost->post_status;
|
1068 |
+
$this->plugin->alerts->trigger_event( $event, $event_data );
|
1069 |
} else {
|
1070 |
// NOTE: this triggers if NOT firing event 5019.
|
1071 |
+
$this->plugin->alerts->trigger_event_if( $event, $event_data, array( $this, 'plugin_not_created_post' ) );
|
1072 |
}
|
1073 |
}
|
1074 |
|
1085 |
protected function check_parent_change( $oldpost, $newpost ) {
|
1086 |
if ( $oldpost->post_parent !== $newpost->post_parent && 'page' === $newpost->post_type ) {
|
1087 |
$editor_link = $this->get_editor_link( $oldpost );
|
1088 |
+
$this->plugin->alerts->trigger_event(
|
1089 |
2047,
|
1090 |
array(
|
1091 |
'PostID' => $oldpost->ID,
|
1113 |
*/
|
1114 |
protected function check_permalink_change( $old_link, $new_link, $post ) {
|
1115 |
if ( in_array( $post->post_status, array( 'draft', 'pending' ), true ) ) {
|
1116 |
+
$old_link = $this->old_post->post_name;
|
1117 |
$new_link = $post->post_name;
|
1118 |
}
|
1119 |
|
1120 |
if ( $old_link !== $new_link ) {
|
1121 |
$editor_link = $this->get_editor_link( $post );
|
1122 |
+
$this->plugin->alerts->trigger_event(
|
1123 |
2017,
|
1124 |
array(
|
1125 |
'PostID' => $post->ID,
|
1150 |
$new_visibility = '';
|
1151 |
|
1152 |
if ( $oldpost->post_password ) {
|
1153 |
+
$old_visibility = esc_html__( 'Password Protected', 'wp-security-audit-log' );
|
1154 |
} elseif ( 'private' === $oldpost->post_status ) {
|
1155 |
+
$old_visibility = esc_html__( 'Private', 'wp-security-audit-log' );
|
1156 |
} else {
|
1157 |
+
$old_visibility = esc_html__( 'Public', 'wp-security-audit-log' );
|
1158 |
}
|
1159 |
|
1160 |
if ( $newpost->post_password ) {
|
1161 |
+
$new_visibility = esc_html__( 'Password Protected', 'wp-security-audit-log' );
|
1162 |
} elseif ( 'private' === $newpost->post_status ) {
|
1163 |
+
$new_visibility = esc_html__( 'Private', 'wp-security-audit-log' );
|
1164 |
} else {
|
1165 |
+
$new_visibility = esc_html__( 'Public', 'wp-security-audit-log' );
|
1166 |
}
|
1167 |
|
1168 |
if ( $old_visibility && $new_visibility && ( $old_visibility !== $new_visibility ) ) {
|
1169 |
$editor_link = $this->get_editor_link( $oldpost );
|
1170 |
+
$this->plugin->alerts->trigger_event(
|
1171 |
2025,
|
1172 |
array(
|
1173 |
'PostID' => $oldpost->ID,
|
1208 |
|
1209 |
if ( $from !== $to ) {
|
1210 |
$editor_link = $this->get_editor_link( $oldpost );
|
1211 |
+
$this->plugin->alerts->trigger_event(
|
1212 |
2027,
|
1213 |
array(
|
1214 |
'PostID' => $oldpost->ID,
|
1239 |
|
1240 |
// Comments.
|
1241 |
if ( $oldpost->comment_status !== $newpost->comment_status ) {
|
1242 |
+
$this->plugin->alerts->trigger_event(
|
1243 |
2111,
|
1244 |
array(
|
1245 |
'PostID' => $newpost->ID,
|
1258 |
|
1259 |
// Trackbacks and Pingbacks.
|
1260 |
if ( $oldpost->ping_status !== $newpost->ping_status ) {
|
1261 |
+
$this->plugin->alerts->trigger_event(
|
1262 |
2112,
|
1263 |
array(
|
1264 |
'PostID' => $newpost->ID,
|
1279 |
/**
|
1280 |
* Categories changed.
|
1281 |
*
|
1282 |
+
* @param array $old_cats - Old categories.
|
1283 |
+
* @param array $new_cats - New categories.
|
1284 |
+
* @param WP_Post $post - The post.
|
1285 |
*/
|
1286 |
protected function check_categories_change( $old_cats, $new_cats, $post ) {
|
1287 |
$old_cats = implode( ', ', (array) $old_cats );
|
1300 |
'NewCategories' => $new_cats ? $new_cats : 'no categories',
|
1301 |
$editor_link['name'] => $editor_link['value'],
|
1302 |
);
|
1303 |
+
$this->plugin->alerts->trigger_event( 2016, $alert_data );
|
1304 |
}
|
1305 |
}
|
1306 |
|
1307 |
/**
|
1308 |
* Reports tags change event. This could be tags addition, removal and possibly other in the future.
|
1309 |
*
|
1310 |
+
* @param int $event_code Event code.
|
1311 |
+
* @param WP_Post $post WordPress post object.
|
1312 |
+
* @param string[] $tags_changed Changed tags.
|
1313 |
*
|
1314 |
+
* @since 4.1.5
|
|
|
|
|
1315 |
*/
|
1316 |
private function report_tags_change_event( $event_code, $post, $tags_changed ) {
|
1317 |
$editor_link = $this->get_editor_link( $post );
|
1318 |
$post_status = ( 'publish' === $post->post_status ) ? 'published' : $post->post_status;
|
1319 |
+
$this->plugin->alerts->trigger_event(
|
1320 |
$event_code,
|
1321 |
array(
|
1322 |
'PostID' => $post->ID,
|
1325 |
'PostTitle' => $post->post_title,
|
1326 |
'PostDate' => $post->post_date,
|
1327 |
'PostUrl' => get_permalink( $post->ID ),
|
1328 |
+
'tag' => ! empty( $tags_changed ) ? implode( ', ', $tags_changed ) : esc_html__( 'no tags', 'wp-security-audit-log' ),
|
1329 |
$editor_link['name'] => $editor_link['value'],
|
1330 |
)
|
1331 |
);
|
1341 |
protected function check_tags_change( $old_tags, $new_tags, $post ) {
|
1342 |
// Ensure old_tags is not null.
|
1343 |
if ( ! $old_tags ) {
|
1344 |
+
$old_tags = array();
|
1345 |
}
|
1346 |
$intersection = array_intersect( $old_tags, $new_tags );
|
1347 |
if ( count( $intersection ) === count( $old_tags ) && count( $old_tags ) === count( $new_tags ) ) {
|
1348 |
+
// No change, let's leave.
|
1349 |
return;
|
1350 |
}
|
1351 |
|
1365 |
/**
|
1366 |
* Post modified content.
|
1367 |
*
|
1368 |
+
* @param integer $post_id – Post ID.
|
1369 |
* @param stdClass $oldpost – Old post.
|
1370 |
* @param stdClass $newpost – New post.
|
1371 |
+
* @param int $modified – Set to 0 if no changes done to the post.
|
1372 |
*
|
1373 |
* @return int|void
|
1374 |
*/
|
1377 |
return;
|
1378 |
}
|
1379 |
|
1380 |
+
$content_changed = $oldpost->post_content !== $newpost->post_content;
|
1381 |
|
1382 |
/*
|
1383 |
* If the content hasn't changed and this looks to be a draft resave
|
1404 |
$yoast_alerts = $yoast_alerts + $yoast_metabox_alerts;
|
1405 |
// Check all alerts.
|
1406 |
foreach ( $yoast_alerts as $alert_code => $alert ) {
|
1407 |
+
if ( $this->plugin->alerts->will_or_has_triggered( $alert_code ) ) {
|
1408 |
return 0; // Return if any Yoast alert has or will trigger.
|
1409 |
}
|
1410 |
}
|
1428 |
}
|
1429 |
|
1430 |
if ( $old_post_excerpt !== $post_excerpt ) {
|
1431 |
+
$event = 2129;
|
1432 |
+
// We are purposefully showing an empty, not NULL value.
|
1433 |
$event_data['old_post_excerpt'] = ( $old_post_excerpt ) ? $old_post_excerpt : ' ';
|
1434 |
$event_data['post_excerpt'] = ( $post_excerpt ) ? $post_excerpt : ' ';
|
1435 |
}
|
1436 |
|
1437 |
if ( 2002 === $event ) {
|
1438 |
+
// If we reach this point, we no longer need to check if the content has changed as we already have
|
1439 |
+
// an event to handle it. So trigger 2002 regardless and "something" has changed in the post, we
|
1440 |
+
// just don't detect it elsewhere.
|
1441 |
+
$this->plugin->alerts->trigger_event_if( $event, $event_data, array( $this, 'ignore_other_post_events' ) );
|
1442 |
} else {
|
1443 |
+
$this->plugin->alerts->trigger_event( $event, $event_data );
|
1444 |
}
|
1445 |
}
|
1446 |
}
|
1457 |
$post_events = array_keys( $this->plugin->alerts->get_alerts_by_sub_category( 'Content' ) );
|
1458 |
|
1459 |
foreach ( $post_events as $event ) {
|
1460 |
+
if ( $manager->will_or_has_triggered( $event ) || $this->was_triggered_recently( $event ) ) {
|
1461 |
return false;
|
1462 |
}
|
1463 |
}
|
1474 |
private function check_title_change( $oldpost, $newpost ) {
|
1475 |
if ( $oldpost->post_title !== $newpost->post_title ) {
|
1476 |
$editor_link = $this->get_editor_link( $oldpost );
|
1477 |
+
$this->plugin->alerts->trigger_event(
|
1478 |
2086,
|
1479 |
array(
|
1480 |
'PostID' => $newpost->ID,
|
1536 |
$event_data = $this->get_post_event_data( $post ); // Event data.
|
1537 |
|
1538 |
$event_data[ $editor_link['name'] ] = $editor_link['value'];
|
1539 |
+
$this->plugin->alerts->trigger_event( $event, $event_data );
|
1540 |
}
|
1541 |
|
1542 |
/**
|
1549 |
private function check_auto_draft( $code, $title ) {
|
1550 |
$ignore = 0;
|
1551 |
if ( 2008 === $code && ( 'auto-draft' === $title || 'Auto Draft' === $title ) ) {
|
1552 |
+
$ignore = ! $this->plugin->settings()->is_wp_backend();
|
1553 |
}
|
1554 |
return $ignore;
|
1555 |
}
|
1556 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1557 |
/**
|
1558 |
* Post Opened for Editing in WP Editors.
|
1559 |
*
|
1587 |
$event = 2100;
|
1588 |
if ( ! $this->was_triggered( $event ) ) {
|
1589 |
$editor_link = $this->get_editor_link( $post );
|
1590 |
+
$this->plugin->alerts->trigger_event(
|
1591 |
$event,
|
1592 |
array(
|
1593 |
'PostID' => $post->ID,
|
1611 |
*/
|
1612 |
private function was_triggered( $alert_id ) {
|
1613 |
$query = new WSAL_Models_OccurrenceQuery();
|
1614 |
+
$query->add_order_by( 'created_on', true );
|
1615 |
+
$query->set_limit( 1 );
|
1616 |
+
$last_occurrence = $query->get_adapter()->execute_query( $query );
|
1617 |
|
1618 |
+
if ( ! empty( $last_occurrence ) ) {
|
1619 |
+
if ( ! is_array( $alert_id ) && $last_occurrence[0]->alert_id === $alert_id ) {
|
1620 |
return true;
|
1621 |
+
} elseif ( is_array( $alert_id ) && in_array( $last_occurrence[0]->alert_id, $alert_id, true ) ) {
|
1622 |
return true;
|
1623 |
}
|
1624 |
}
|
1677 |
* @return boolean
|
1678 |
*/
|
1679 |
public function plugin_not_created_post( $manager ) {
|
1680 |
+
$triggered = $manager->will_or_has_triggered( 5019 );
|
1681 |
// inverting value here to account for the double NOT in _CommitItem().
|
1682 |
return ! $triggered;
|
1683 |
}
|
1685 |
/**
|
1686 |
* Check if the alert was triggered recently.
|
1687 |
*
|
1688 |
+
* Checks last 5 events if they occurred less than 20 seconds ago.
|
1689 |
*
|
1690 |
* @param integer|array $alert_id - Alert code.
|
1691 |
* @return boolean
|
1692 |
*/
|
1693 |
private function was_triggered_recently( $alert_id ) {
|
1694 |
// if we have already checked this don't check again.
|
1695 |
+
if ( isset( $this->cached_alert_checks ) && array_key_exists( $alert_id, $this->cached_alert_checks ) && $this->cached_alert_checks[ $alert_id ] ) {
|
1696 |
return true;
|
1697 |
}
|
1698 |
$query = new WSAL_Models_OccurrenceQuery();
|
1699 |
+
$query->add_order_by( 'created_on', true );
|
1700 |
+
$query->set_limit( 5 );
|
1701 |
+
$last_occurrences = $query->get_adapter()->execute_query( $query );
|
1702 |
$known_to_trigger = false;
|
1703 |
+
foreach ( $last_occurrences as $last_occurrence ) {
|
1704 |
if ( $known_to_trigger ) {
|
1705 |
break;
|
1706 |
}
|
1707 |
+
if ( ! empty( $last_occurrence ) && ( $last_occurrence->created_on + 5 ) > time() ) {
|
1708 |
+
if ( ! is_array( $alert_id ) && $last_occurrence->alert_id === $alert_id ) {
|
1709 |
$known_to_trigger = true;
|
1710 |
+
} elseif ( is_array( $alert_id ) && in_array( $last_occurrence[0]->alert_id, $alert_id, true ) ) {
|
1711 |
$known_to_trigger = true;
|
1712 |
}
|
1713 |
}
|
classes/Sensors/Database.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Database sensors class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -29,13 +30,13 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
29 |
* 5023 WordPress modified tables structure
|
30 |
* 5024 WordPress deleted tables
|
31 |
*
|
32 |
-
* @package
|
33 |
* @subpackage sensors
|
34 |
*/
|
35 |
class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
36 |
|
37 |
/**
|
38 |
-
* Local cache for basename of current script. It
|
39 |
* of determining the actor of current action.
|
40 |
*
|
41 |
* @var string|bool
|
@@ -58,14 +59,14 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
58 |
* @var string[]
|
59 |
* @since 4.1.5
|
60 |
*/
|
61 |
-
private static $already_logged =
|
62 |
|
63 |
/**
|
64 |
* Listening to events using WP hooks.
|
65 |
*/
|
66 |
-
public function
|
67 |
-
add_action( 'dbdelta_queries', array( $this, '
|
68 |
-
add_filter( 'query', array( $this, '
|
69 |
}
|
70 |
|
71 |
/**
|
@@ -75,7 +76,7 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
75 |
*
|
76 |
* @return string
|
77 |
*/
|
78 |
-
public function
|
79 |
if ( ! self::$enabled ) {
|
80 |
return $query;
|
81 |
}
|
@@ -85,16 +86,16 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
85 |
$query_type = '';
|
86 |
if ( preg_match( '|DROP TABLE( IF EXISTS)? ([^ ]*)|', $query ) ) {
|
87 |
$table_name = empty( $str[4] ) ? $str[2] : $str[4];
|
88 |
-
//
|
89 |
-
if ( $this->is_table_operation_check_enabled($table_name, 'delete')
|
90 |
-
|
91 |
array_push( $table_names, $table_name );
|
92 |
$query_type = 'delete';
|
93 |
}
|
94 |
} elseif ( preg_match( '/CREATE TABLE( IF NOT EXISTS)? ([^ ]*)/i', $query, $matches ) || preg_match( '/CREATE TABLE ([^ ]*)/i', $query, $matches ) ) {
|
95 |
-
$table_name = $matches[count($matches) - 1];
|
96 |
-
if ( $this->is_table_operation_check_enabled($table_name, 'create')
|
97 |
-
|
98 |
/**
|
99 |
* Some plugins keep trying to create tables even
|
100 |
* when they already exist - would result in too
|
@@ -105,7 +106,7 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
105 |
}
|
106 |
}
|
107 |
|
108 |
-
$this->
|
109 |
|
110 |
return $query;
|
111 |
}
|
@@ -114,28 +115,28 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
114 |
* Triggers an event if the list of tables is not empty. It also checks if
|
115 |
* the event should be logged for events originated by WordPress.
|
116 |
*
|
117 |
-
* @param string
|
118 |
-
* @param string[] $table_names
|
119 |
*/
|
120 |
-
private function
|
121 |
if ( ! empty( $table_names ) ) {
|
122 |
-
$actor = $this->
|
123 |
-
if ( '
|
124 |
-
//
|
125 |
return;
|
126 |
}
|
127 |
|
128 |
// Loop through each item to report event per table.
|
129 |
foreach ( $table_names as $table_name ) {
|
130 |
-
$alert_options
|
131 |
-
$event_code
|
132 |
-
$db_op_key
|
133 |
-
if ( in_array( $db_op_key, self::$already_logged ) ) {
|
134 |
continue;
|
135 |
}
|
136 |
|
137 |
$alert_options['TableNames'] = $table_name;
|
138 |
-
$this->plugin->alerts->
|
139 |
array_push( self::$already_logged, $db_op_key );
|
140 |
}
|
141 |
}
|
@@ -148,36 +149,42 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
148 |
*
|
149 |
* @return bool|string Theme, plugin or false if unknown.
|
150 |
*/
|
151 |
-
private function
|
152 |
-
//
|
153 |
$result = false;
|
154 |
|
155 |
-
//
|
156 |
-
|
157 |
if ( is_null( $this->script_basename ) ) {
|
158 |
$this->script_basename = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ), '.php' ) : false;
|
159 |
}
|
160 |
|
161 |
$result = $this->script_basename;
|
162 |
|
163 |
-
//
|
164 |
-
if ( $this->
|
165 |
-
$result = '
|
166 |
}
|
167 |
|
168 |
return $result;
|
169 |
}
|
170 |
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
if ( ! empty( $tables ) ) {
|
173 |
global $wpdb;
|
174 |
-
$prefix = preg_quote( $wpdb->prefix );
|
175 |
$site_regex = '/\b' . $prefix . '(\d+_)?(commentmeta|comments|links|options|postmeta|posts|terms|termmeta|term_relationships|term_relationships|term_taxonomy|usermeta|users)\b/';
|
176 |
$network_regex = '/\b' . $prefix . '(blogs|blog_versions|registration_log|signups|site|sitemeta|users|usermeta)\b/';
|
177 |
|
178 |
foreach ( $tables as $table ) {
|
179 |
if ( preg_match( $site_regex, $table ) || preg_match( $network_regex, $table ) ) {
|
180 |
-
//
|
181 |
return true;
|
182 |
}
|
183 |
}
|
@@ -192,22 +199,23 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
192 |
* @param string $actor - Plugins, themes, WordPress or unknown.
|
193 |
*
|
194 |
* @return array
|
|
|
|
|
|
|
195 |
*/
|
196 |
-
protected function
|
197 |
-
// Check the actor
|
198 |
$alert_options = array();
|
199 |
switch ( $actor ) {
|
200 |
case 'plugins':
|
201 |
// Action Plugin Component.
|
202 |
$plugin_file = '';
|
203 |
|
204 |
-
// @codingStandardsIgnoreStart
|
205 |
if ( isset( $_GET['plugin'] ) ) {
|
206 |
$plugin_file = sanitize_text_field( wp_unslash( $_GET['plugin'] ) );
|
207 |
} elseif ( isset( $_GET['checked'] ) ) {
|
208 |
$plugin_file = sanitize_text_field( wp_unslash( $_GET['checked'][0] ) );
|
209 |
}
|
210 |
-
// @codingStandardsIgnoreEnd
|
211 |
|
212 |
// Get plugin data.
|
213 |
$plugins = get_plugins();
|
@@ -221,9 +229,9 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
221 |
'Version' => $plugin['Version'],
|
222 |
);
|
223 |
} else {
|
224 |
-
$plugin_name
|
225 |
-
$plugin_name
|
226 |
-
$plugin_name
|
227 |
|
228 |
// If this is still empty at this point, lets check recent events.
|
229 |
if ( empty( $plugin_file ) ) {
|
@@ -236,21 +244,18 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
236 |
case 'themes':
|
237 |
// Action Theme Component.
|
238 |
$theme_name = '';
|
239 |
-
|
240 |
-
// @codingStandardsIgnoreStart
|
241 |
if ( isset( $_GET['theme'] ) ) {
|
242 |
$theme_name = sanitize_text_field( wp_unslash( $_GET['theme'] ) );
|
243 |
} elseif ( isset( $_GET['checked'] ) ) {
|
244 |
$theme_name = sanitize_text_field( wp_unslash( $_GET['checked'][0] ) );
|
245 |
}
|
246 |
-
// @codingStandardsIgnoreEnd
|
247 |
|
248 |
$theme_name = str_replace( array( '_', '-', ' ' ), ' ', $theme_name );
|
249 |
$theme_name = ucwords( $theme_name );
|
250 |
$alert_options['Theme'] = (object) array( 'Name' => $theme_name );
|
251 |
break;
|
252 |
|
253 |
-
case '
|
254 |
$alert_options['Component'] = 'WordPress';
|
255 |
break;
|
256 |
|
@@ -271,7 +276,7 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
271 |
*
|
272 |
* @return int Event code.
|
273 |
*/
|
274 |
-
protected function
|
275 |
switch ( $actor ) {
|
276 |
case 'plugins':
|
277 |
if ( 'create' === $query_type ) {
|
@@ -293,7 +298,7 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
293 |
}
|
294 |
break;
|
295 |
|
296 |
-
case '
|
297 |
if ( 'create' === $query_type ) {
|
298 |
return 5022;
|
299 |
} elseif ( 'update' === $query_type ) {
|
@@ -321,7 +326,7 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
321 |
*
|
322 |
* @return array
|
323 |
*/
|
324 |
-
public function
|
325 |
if ( ! self::$enabled ) {
|
326 |
return $queries;
|
327 |
}
|
@@ -336,9 +341,9 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
336 |
$qry = str_replace( '`', '', $qry );
|
337 |
$str = explode( ' ', $qry );
|
338 |
if ( preg_match( '/CREATE TABLE( IF NOT EXISTS)? ([^ ]*)/i', $qry, $matches ) ) {
|
339 |
-
$table_name = $matches[count($matches) - 1];
|
340 |
-
if ( $this->is_table_operation_check_enabled($table_name, 'create')
|
341 |
-
|
342 |
/**
|
343 |
* Some plugins keep trying to create tables even
|
344 |
* when they already exist- would result in too
|
@@ -350,9 +355,9 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
350 |
array_push( $query_types['update'], $str[2] );
|
351 |
} elseif ( preg_match( '|DROP TABLE( IF EXISTS)? ([^ ]*)|', $qry ) ) {
|
352 |
$table_name = empty( $str[4] ) ? $str[2] : $str[4];
|
353 |
-
//
|
354 |
-
if ( $this->is_table_operation_check_enabled($table_name, 'delete')
|
355 |
-
|
356 |
array_push( $query_types['delete'], $table_name );
|
357 |
}
|
358 |
}
|
@@ -360,7 +365,7 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
360 |
|
361 |
if ( ! empty( $query_types['create'] ) || ! empty( $query_types['update'] ) || ! empty( $query_types['delete'] ) ) {
|
362 |
foreach ( $query_types as $query_type => $table_names ) {
|
363 |
-
$this->
|
364 |
}
|
365 |
}
|
366 |
|
@@ -378,8 +383,8 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
378 |
$latest_events = $this->plugin->alerts->get_latest_events( 25 );
|
379 |
|
380 |
foreach ( $latest_events as $latest_event ) {
|
381 |
-
if (
|
382 |
-
$event_meta
|
383 |
$plugin_name = $event_meta['PluginData']->Name;
|
384 |
}
|
385 |
}
|
@@ -402,13 +407,13 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
402 |
try {
|
403 |
global $wpdb;
|
404 |
|
405 |
-
//
|
406 |
ob_start();
|
407 |
-
$db_result = $wpdb->query( "SELECT COUNT(1) FROM {$table_name};" );
|
408 |
ob_clean();
|
409 |
|
410 |
return ( 1 === $db_result );
|
411 |
-
} catch (Exception $e) {
|
412 |
return false;
|
413 |
}
|
414 |
}
|
@@ -420,16 +425,17 @@ class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
|
420 |
* if a specific alert is not enabled. Unfortunately if the alert is enabled or not is being checked
|
421 |
* too late.
|
422 |
*
|
423 |
-
* @param string $table_name
|
424 |
-
* @param string $query_type
|
425 |
*
|
426 |
* @return bool
|
427 |
-
* @see WSAL_AlertManager::
|
428 |
* @since 4.2.0
|
429 |
*/
|
430 |
private function is_table_operation_check_enabled( $table_name, $query_type ) {
|
431 |
-
$actor
|
432 |
-
$
|
433 |
-
|
|
|
434 |
}
|
435 |
}
|
4 |
*
|
5 |
* Database sensors class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
30 |
* 5023 WordPress modified tables structure
|
31 |
* 5024 WordPress deleted tables
|
32 |
*
|
33 |
+
* @package wsal
|
34 |
* @subpackage sensors
|
35 |
*/
|
36 |
class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
37 |
|
38 |
/**
|
39 |
+
* Local cache for basename of current script. It is used to improve performance
|
40 |
* of determining the actor of current action.
|
41 |
*
|
42 |
* @var string|bool
|
59 |
* @var string[]
|
60 |
* @since 4.1.5
|
61 |
*/
|
62 |
+
private static $already_logged = array();
|
63 |
|
64 |
/**
|
65 |
* Listening to events using WP hooks.
|
66 |
*/
|
67 |
+
public function hook_events() {
|
68 |
+
add_action( 'dbdelta_queries', array( $this, 'event_db_delta_query' ) );
|
69 |
+
add_filter( 'query', array( $this, 'event_drop_query' ) );
|
70 |
}
|
71 |
|
72 |
/**
|
76 |
*
|
77 |
* @return string
|
78 |
*/
|
79 |
+
public function event_drop_query( $query ) {
|
80 |
if ( ! self::$enabled ) {
|
81 |
return $query;
|
82 |
}
|
86 |
$query_type = '';
|
87 |
if ( preg_match( '|DROP TABLE( IF EXISTS)? ([^ ]*)|', $query ) ) {
|
88 |
$table_name = empty( $str[4] ) ? $str[2] : $str[4];
|
89 |
+
// Only log when the table exists as some plugins try to delete tables even if they don't exist.
|
90 |
+
if ( $this->is_table_operation_check_enabled( $table_name, 'delete' )
|
91 |
+
&& $this->check_if_table_exists( $table_name ) ) {
|
92 |
array_push( $table_names, $table_name );
|
93 |
$query_type = 'delete';
|
94 |
}
|
95 |
} elseif ( preg_match( '/CREATE TABLE( IF NOT EXISTS)? ([^ ]*)/i', $query, $matches ) || preg_match( '/CREATE TABLE ([^ ]*)/i', $query, $matches ) ) {
|
96 |
+
$table_name = $matches[ count( $matches ) - 1 ];
|
97 |
+
if ( $this->is_table_operation_check_enabled( $table_name, 'create' )
|
98 |
+
&& ! $this->check_if_table_exists( $table_name ) ) {
|
99 |
/**
|
100 |
* Some plugins keep trying to create tables even
|
101 |
* when they already exist - would result in too
|
106 |
}
|
107 |
}
|
108 |
|
109 |
+
$this->maybe_trigger_event( $query_type, $table_names );
|
110 |
|
111 |
return $query;
|
112 |
}
|
115 |
* Triggers an event if the list of tables is not empty. It also checks if
|
116 |
* the event should be logged for events originated by WordPress.
|
117 |
*
|
118 |
+
* @param string $query_type Query type.
|
119 |
+
* @param string[] $table_names Table names.
|
120 |
*/
|
121 |
+
private function maybe_trigger_event( $query_type, $table_names ) {
|
122 |
if ( ! empty( $table_names ) ) {
|
123 |
+
$actor = $this->get_actor( $table_names );
|
124 |
+
if ( 'WordPress' === $actor && ! $this->plugin->settings()->is_wp_backend() ) {
|
125 |
+
// Event is not fired if the monitoring of background events is disabled.
|
126 |
return;
|
127 |
}
|
128 |
|
129 |
// Loop through each item to report event per table.
|
130 |
foreach ( $table_names as $table_name ) {
|
131 |
+
$alert_options = $this->get_event_options( $actor );
|
132 |
+
$event_code = $this->get_event_code( $actor, $query_type );
|
133 |
+
$db_op_key = $query_type . '_' . $table_name;
|
134 |
+
if ( in_array( $db_op_key, self::$already_logged ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
135 |
continue;
|
136 |
}
|
137 |
|
138 |
$alert_options['TableNames'] = $table_name;
|
139 |
+
$this->plugin->alerts->trigger_event( $event_code, $alert_options );
|
140 |
array_push( self::$already_logged, $db_op_key );
|
141 |
}
|
142 |
}
|
149 |
*
|
150 |
* @return bool|string Theme, plugin or false if unknown.
|
151 |
*/
|
152 |
+
private function get_actor( $table_names ) {
|
153 |
+
// Default actor (treated as an unknown component).
|
154 |
$result = false;
|
155 |
|
156 |
+
// Use current script name to determine if the actor is theme or a plugin.
|
|
|
157 |
if ( is_null( $this->script_basename ) ) {
|
158 |
$this->script_basename = isset( $_SERVER['SCRIPT_NAME'] ) ? basename( sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ) ), '.php' ) : false;
|
159 |
}
|
160 |
|
161 |
$result = $this->script_basename;
|
162 |
|
163 |
+
// Check table names for default WordPress table names (including network tables).
|
164 |
+
if ( $this->contains_wordpress_table( $table_names ) ) {
|
165 |
+
$result = 'WordPress';
|
166 |
}
|
167 |
|
168 |
return $result;
|
169 |
}
|
170 |
|
171 |
+
/**
|
172 |
+
* Checks if the list of tables contains a WordPress table.
|
173 |
+
*
|
174 |
+
* @param string $tables List of table names.
|
175 |
+
*
|
176 |
+
* @return bool True if the list contains a WordPress table.
|
177 |
+
*/
|
178 |
+
private function contains_wordpress_table( $tables ) {
|
179 |
if ( ! empty( $tables ) ) {
|
180 |
global $wpdb;
|
181 |
+
$prefix = preg_quote( $wpdb->prefix ); // phpcs:ignore WordPress.PHP.PregQuoteDelimiter.Missing
|
182 |
$site_regex = '/\b' . $prefix . '(\d+_)?(commentmeta|comments|links|options|postmeta|posts|terms|termmeta|term_relationships|term_relationships|term_taxonomy|usermeta|users)\b/';
|
183 |
$network_regex = '/\b' . $prefix . '(blogs|blog_versions|registration_log|signups|site|sitemeta|users|usermeta)\b/';
|
184 |
|
185 |
foreach ( $tables as $table ) {
|
186 |
if ( preg_match( $site_regex, $table ) || preg_match( $network_regex, $table ) ) {
|
187 |
+
// Stop as soon as the first WordPress table is found.
|
188 |
return true;
|
189 |
}
|
190 |
}
|
199 |
* @param string $actor - Plugins, themes, WordPress or unknown.
|
200 |
*
|
201 |
* @return array
|
202 |
+
*
|
203 |
+
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
204 |
+
* phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
|
205 |
*/
|
206 |
+
protected function get_event_options( $actor ) {
|
207 |
+
// Check the actor.
|
208 |
$alert_options = array();
|
209 |
switch ( $actor ) {
|
210 |
case 'plugins':
|
211 |
// Action Plugin Component.
|
212 |
$plugin_file = '';
|
213 |
|
|
|
214 |
if ( isset( $_GET['plugin'] ) ) {
|
215 |
$plugin_file = sanitize_text_field( wp_unslash( $_GET['plugin'] ) );
|
216 |
} elseif ( isset( $_GET['checked'] ) ) {
|
217 |
$plugin_file = sanitize_text_field( wp_unslash( $_GET['checked'][0] ) );
|
218 |
}
|
|
|
219 |
|
220 |
// Get plugin data.
|
221 |
$plugins = get_plugins();
|
229 |
'Version' => $plugin['Version'],
|
230 |
);
|
231 |
} else {
|
232 |
+
$plugin_name = basename( $plugin_file, '.php' );
|
233 |
+
$plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name );
|
234 |
+
$plugin_name = ucwords( $plugin_name );
|
235 |
|
236 |
// If this is still empty at this point, lets check recent events.
|
237 |
if ( empty( $plugin_file ) ) {
|
244 |
case 'themes':
|
245 |
// Action Theme Component.
|
246 |
$theme_name = '';
|
|
|
|
|
247 |
if ( isset( $_GET['theme'] ) ) {
|
248 |
$theme_name = sanitize_text_field( wp_unslash( $_GET['theme'] ) );
|
249 |
} elseif ( isset( $_GET['checked'] ) ) {
|
250 |
$theme_name = sanitize_text_field( wp_unslash( $_GET['checked'][0] ) );
|
251 |
}
|
|
|
252 |
|
253 |
$theme_name = str_replace( array( '_', '-', ' ' ), ' ', $theme_name );
|
254 |
$theme_name = ucwords( $theme_name );
|
255 |
$alert_options['Theme'] = (object) array( 'Name' => $theme_name );
|
256 |
break;
|
257 |
|
258 |
+
case 'WordPress':
|
259 |
$alert_options['Component'] = 'WordPress';
|
260 |
break;
|
261 |
|
276 |
*
|
277 |
* @return int Event code.
|
278 |
*/
|
279 |
+
protected function get_event_code( $actor, $query_type ) {
|
280 |
switch ( $actor ) {
|
281 |
case 'plugins':
|
282 |
if ( 'create' === $query_type ) {
|
298 |
}
|
299 |
break;
|
300 |
|
301 |
+
case 'WordPress':
|
302 |
if ( 'create' === $query_type ) {
|
303 |
return 5022;
|
304 |
} elseif ( 'update' === $query_type ) {
|
326 |
*
|
327 |
* @return array
|
328 |
*/
|
329 |
+
public function event_db_delta_query( $queries ) {
|
330 |
if ( ! self::$enabled ) {
|
331 |
return $queries;
|
332 |
}
|
341 |
$qry = str_replace( '`', '', $qry );
|
342 |
$str = explode( ' ', $qry );
|
343 |
if ( preg_match( '/CREATE TABLE( IF NOT EXISTS)? ([^ ]*)/i', $qry, $matches ) ) {
|
344 |
+
$table_name = $matches[ count( $matches ) - 1 ];
|
345 |
+
if ( $this->is_table_operation_check_enabled( $table_name, 'create' )
|
346 |
+
&& ! $this->check_if_table_exists( $table_name ) ) {
|
347 |
/**
|
348 |
* Some plugins keep trying to create tables even
|
349 |
* when they already exist- would result in too
|
355 |
array_push( $query_types['update'], $str[2] );
|
356 |
} elseif ( preg_match( '|DROP TABLE( IF EXISTS)? ([^ ]*)|', $qry ) ) {
|
357 |
$table_name = empty( $str[4] ) ? $str[2] : $str[4];
|
358 |
+
// Only log when the table exists as some plugins try to delete tables even if they don't exist.
|
359 |
+
if ( $this->is_table_operation_check_enabled( $table_name, 'delete' )
|
360 |
+
&& $this->check_if_table_exists( $table_name ) ) {
|
361 |
array_push( $query_types['delete'], $table_name );
|
362 |
}
|
363 |
}
|
365 |
|
366 |
if ( ! empty( $query_types['create'] ) || ! empty( $query_types['update'] ) || ! empty( $query_types['delete'] ) ) {
|
367 |
foreach ( $query_types as $query_type => $table_names ) {
|
368 |
+
$this->maybe_trigger_event( $query_type, $table_names );
|
369 |
}
|
370 |
}
|
371 |
|
383 |
$latest_events = $this->plugin->alerts->get_latest_events( 25 );
|
384 |
|
385 |
foreach ( $latest_events as $latest_event ) {
|
386 |
+
if ( intval( $latest_event->alert_id ) === $alert_id ) {
|
387 |
+
$event_meta = $latest_event ? $latest_event->get_meta_array() : false;
|
388 |
$plugin_name = $event_meta['PluginData']->Name;
|
389 |
}
|
390 |
}
|
407 |
try {
|
408 |
global $wpdb;
|
409 |
|
410 |
+
// Output buffering is here to prevent from error log messages that would be fired if the table didn't exist.
|
411 |
ob_start();
|
412 |
+
$db_result = $wpdb->query( "SELECT COUNT(1) FROM {$table_name};" ); // phpcs:ignore
|
413 |
ob_clean();
|
414 |
|
415 |
return ( 1 === $db_result );
|
416 |
+
} catch ( Exception $e ) {
|
417 |
return false;
|
418 |
}
|
419 |
}
|
425 |
* if a specific alert is not enabled. Unfortunately if the alert is enabled or not is being checked
|
426 |
* too late.
|
427 |
*
|
428 |
+
* @param string $table_name Table name.
|
429 |
+
* @param string $query_type Query type.
|
430 |
*
|
431 |
* @return bool
|
432 |
+
* @see WSAL_AlertManager::commit_item()
|
433 |
* @since 4.2.0
|
434 |
*/
|
435 |
private function is_table_operation_check_enabled( $table_name, $query_type ) {
|
436 |
+
$actor = $this->get_actor( array( $table_name ) );
|
437 |
+
$event_code = $this->get_event_code( $actor, $query_type );
|
438 |
+
|
439 |
+
return $this->plugin->alerts->is_enabled( $event_code );
|
440 |
}
|
441 |
}
|
classes/Sensors/Files.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Files sensors class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -21,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
21 |
* 2046 User changed a file using the theme editor
|
22 |
* 2051 User changed a file using the plugin editor
|
23 |
*
|
24 |
-
* @package
|
25 |
* @subpackage sensors
|
26 |
*/
|
27 |
class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
@@ -34,12 +35,12 @@ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
|
34 |
protected $is_file_uploaded = false;
|
35 |
|
36 |
/**
|
37 |
-
*
|
38 |
*/
|
39 |
-
public function
|
40 |
-
add_action( 'add_attachment', array( $this, '
|
41 |
-
add_action( 'delete_attachment', array( $this, '
|
42 |
-
add_action( 'admin_init', array( $this, '
|
43 |
}
|
44 |
|
45 |
/**
|
@@ -47,15 +48,16 @@ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
|
47 |
*
|
48 |
* @param integer $attachment_id - Attachment ID.
|
49 |
*/
|
50 |
-
public function
|
51 |
// Filter $_POST array for security.
|
52 |
$post_array = filter_input_array( INPUT_POST );
|
53 |
|
54 |
$action = isset( $post_array['action'] ) ? $post_array['action'] : '';
|
55 |
-
if ( 'upload-theme' !== $action && 'upload-plugin' !== $action ) {
|
56 |
$file = get_attached_file( $attachment_id );
|
57 |
-
$this->plugin->alerts->
|
58 |
-
2010,
|
|
|
59 |
'AttachmentID' => $attachment_id,
|
60 |
'FileName' => basename( $file ),
|
61 |
'FilePath' => dirname( $file ),
|
@@ -71,13 +73,14 @@ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
|
71 |
*
|
72 |
* @param integer $attachment_id - Attachment ID.
|
73 |
*/
|
74 |
-
public function
|
75 |
if ( $this->is_file_uploaded ) {
|
76 |
return;
|
77 |
}
|
78 |
$file = get_attached_file( $attachment_id );
|
79 |
-
$this->plugin->alerts->
|
80 |
-
2011,
|
|
|
81 |
'AttachmentID' => $attachment_id,
|
82 |
'FileName' => basename( $file ),
|
83 |
'FilePath' => dirname( $file ),
|
@@ -90,7 +93,7 @@ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
|
90 |
*
|
91 |
* Detect file changes in plugins/themes using plugin/theme editor.
|
92 |
*/
|
93 |
-
public function
|
94 |
// @codingStandardsIgnoreStart
|
95 |
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : false;
|
96 |
$file = isset( $_POST['file'] ) ? sanitize_text_field( wp_unslash( $_POST['file'] ) ) : false;
|
@@ -103,8 +106,9 @@ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
|
103 |
if ( 'edit-theme-plugin-file' === $action ) {
|
104 |
if ( 'plugin-editor' === $referer && wp_verify_nonce( $nonce, 'edit-plugin_' . $file ) ) {
|
105 |
$plugin = isset( $_POST['plugin'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) : false;
|
106 |
-
$this->plugin->alerts->
|
107 |
-
2051,
|
|
|
108 |
'File' => $file,
|
109 |
'Plugin' => $plugin,
|
110 |
)
|
@@ -116,8 +120,9 @@ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
|
116 |
return;
|
117 |
}
|
118 |
|
119 |
-
$this->plugin->alerts->
|
120 |
-
2046,
|
|
|
121 |
'File' => $file,
|
122 |
'Theme' => trailingslashit( get_theme_root() ) . $stylesheet,
|
123 |
)
|
4 |
*
|
5 |
* Files sensors class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
22 |
* 2046 User changed a file using the theme editor
|
23 |
* 2051 User changed a file using the plugin editor
|
24 |
*
|
25 |
+
* @package wsal
|
26 |
* @subpackage sensors
|
27 |
*/
|
28 |
class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
35 |
protected $is_file_uploaded = false;
|
36 |
|
37 |
/**
|
38 |
+
* {@inheritDoc}
|
39 |
*/
|
40 |
+
public function hook_events() {
|
41 |
+
add_action( 'add_attachment', array( $this, 'event_file_uploaded' ) );
|
42 |
+
add_action( 'delete_attachment', array( $this, 'event_file_uploaded_deleted' ) );
|
43 |
+
add_action( 'admin_init', array( $this, 'event_admin_init' ) );
|
44 |
}
|
45 |
|
46 |
/**
|
48 |
*
|
49 |
* @param integer $attachment_id - Attachment ID.
|
50 |
*/
|
51 |
+
public function event_file_uploaded( $attachment_id ) {
|
52 |
// Filter $_POST array for security.
|
53 |
$post_array = filter_input_array( INPUT_POST );
|
54 |
|
55 |
$action = isset( $post_array['action'] ) ? $post_array['action'] : '';
|
56 |
+
if ( 'upload-theme' !== $action && 'upload-plugin' !== $action ) {
|
57 |
$file = get_attached_file( $attachment_id );
|
58 |
+
$this->plugin->alerts->trigger_event(
|
59 |
+
2010,
|
60 |
+
array(
|
61 |
'AttachmentID' => $attachment_id,
|
62 |
'FileName' => basename( $file ),
|
63 |
'FilePath' => dirname( $file ),
|
73 |
*
|
74 |
* @param integer $attachment_id - Attachment ID.
|
75 |
*/
|
76 |
+
public function event_file_uploaded_deleted( $attachment_id ) {
|
77 |
if ( $this->is_file_uploaded ) {
|
78 |
return;
|
79 |
}
|
80 |
$file = get_attached_file( $attachment_id );
|
81 |
+
$this->plugin->alerts->trigger_event(
|
82 |
+
2011,
|
83 |
+
array(
|
84 |
'AttachmentID' => $attachment_id,
|
85 |
'FileName' => basename( $file ),
|
86 |
'FilePath' => dirname( $file ),
|
93 |
*
|
94 |
* Detect file changes in plugins/themes using plugin/theme editor.
|
95 |
*/
|
96 |
+
public function event_admin_init() {
|
97 |
// @codingStandardsIgnoreStart
|
98 |
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : false;
|
99 |
$file = isset( $_POST['file'] ) ? sanitize_text_field( wp_unslash( $_POST['file'] ) ) : false;
|
106 |
if ( 'edit-theme-plugin-file' === $action ) {
|
107 |
if ( 'plugin-editor' === $referer && wp_verify_nonce( $nonce, 'edit-plugin_' . $file ) ) {
|
108 |
$plugin = isset( $_POST['plugin'] ) ? sanitize_text_field( wp_unslash( $_POST['plugin'] ) ) : false;
|
109 |
+
$this->plugin->alerts->trigger_event(
|
110 |
+
2051,
|
111 |
+
array(
|
112 |
'File' => $file,
|
113 |
'Plugin' => $plugin,
|
114 |
)
|
120 |
return;
|
121 |
}
|
122 |
|
123 |
+
$this->plugin->alerts->trigger_event(
|
124 |
+
2046,
|
125 |
+
array(
|
126 |
'File' => $file,
|
127 |
'Theme' => trailingslashit( get_theme_root() ) . $stylesheet,
|
128 |
)
|
classes/Sensors/LogInOut.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Log In & Out sensor class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -23,7 +24,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
23 |
* 1004 Login blocked
|
24 |
* 4003 User has changed his or her password
|
25 |
*
|
26 |
-
* @package
|
27 |
* @subpackage sensors
|
28 |
*/
|
29 |
class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
@@ -40,18 +41,17 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
40 |
*
|
41 |
* @var WP_User
|
42 |
*/
|
43 |
-
protected $
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*/
|
48 |
-
public function
|
49 |
-
add_action( 'set_auth_cookie', array( $this, '
|
50 |
-
add_action( 'wp_logout', array( $this, '
|
51 |
-
add_action( 'password_reset', array( $this, '
|
52 |
-
add_action( 'wp_login_failed', array( $this, '
|
53 |
-
add_action( 'clear_auth_cookie', array( $this, '
|
54 |
-
add_filter( 'wp_login_blocked', array( $this, 'EventLoginBlocked' ), 10, 1 );
|
55 |
add_action( 'lostpassword_post', array( $this, 'event_user_requested_pw_reset' ), 10, 2 );
|
56 |
|
57 |
if ( WpSecurityAuditLog::is_twofactor_active() ) {
|
@@ -61,14 +61,13 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
61 |
if ( WpSecurityAuditLog::is_plugin_active( 'user-switching/user-switching.php' ) ) {
|
62 |
add_action( 'switch_to_user', array( $this, 'user_switched_event' ), 10, 2 );
|
63 |
}
|
64 |
-
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
* Sets current user.
|
69 |
*/
|
70 |
-
public function
|
71 |
-
$this->
|
72 |
}
|
73 |
|
74 |
/**
|
@@ -97,13 +96,13 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
97 |
// If provider and user are set and provider is known then log the event.
|
98 |
if ( $provider && $user && in_array( $provider, $providers_2fa, true ) ) {
|
99 |
// Get user roles.
|
100 |
-
$user_roles = $this->plugin->settings()->
|
101 |
|
102 |
-
if ( $this->plugin->settings()->
|
103 |
$user_roles[] = 'superadmin';
|
104 |
}
|
105 |
|
106 |
-
$this->plugin->alerts->
|
107 |
1000,
|
108 |
array(
|
109 |
'Username' => $user->user_login,
|
@@ -128,7 +127,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
128 |
* @param string $scheme Authentication scheme. Values include 'auth' or 'secure_auth'.
|
129 |
* @param string $token User's session token to use for this cookie.
|
130 |
*/
|
131 |
-
public function
|
132 |
// Get global POST array.
|
133 |
$post_array = filter_input_array( INPUT_POST );
|
134 |
|
@@ -158,8 +157,8 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
158 |
|
159 |
// Log user changed password alert.
|
160 |
if ( ! empty( $user ) ) {
|
161 |
-
$user_roles = $this->plugin->settings()->
|
162 |
-
$this->plugin->alerts->
|
163 |
4003,
|
164 |
array(
|
165 |
'Username' => $user->user_login,
|
@@ -178,9 +177,9 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
178 |
return;
|
179 |
}
|
180 |
$user_login = $user->data->user_login;
|
181 |
-
$user_roles = $this->plugin->settings()->
|
182 |
|
183 |
-
if ( $this->plugin->settings()->
|
184 |
$user_roles[] = 'superadmin';
|
185 |
}
|
186 |
|
@@ -192,17 +191,18 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
192 |
$alert_data['SessionID'] = WSAL_UserSessions_Helpers::hash_token( $token );
|
193 |
}
|
194 |
|
195 |
-
$this->plugin->alerts->
|
196 |
1000,
|
197 |
$alert_data,
|
198 |
/**
|
|
|
|
|
199 |
* @param WSAL_AlertManager $manager
|
200 |
*
|
201 |
* @return bool
|
202 |
*/
|
203 |
function ( $manager ) {
|
204 |
-
|
205 |
-
return ! $manager->WillOrHasTriggered( 4003 );
|
206 |
}
|
207 |
);
|
208 |
|
@@ -211,10 +211,10 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
211 |
/**
|
212 |
* Event Logout.
|
213 |
*/
|
214 |
-
public function
|
215 |
-
if ( $this->
|
216 |
// get the list of excluded users.
|
217 |
-
$excluded_users = $this->plugin->settings()->
|
218 |
$excluded_user_ids = array();
|
219 |
// convert excluded usernames into IDs.
|
220 |
if ( ! empty( $excluded_users ) && is_array( $excluded_users ) ) {
|
@@ -224,14 +224,14 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
224 |
}
|
225 |
}
|
226 |
// bail early if this user is in the excluded ids list.
|
227 |
-
if ( in_array( $this->
|
228 |
return;
|
229 |
}
|
230 |
-
$this->plugin->alerts->
|
231 |
1001,
|
232 |
array(
|
233 |
-
'CurrentUserID' => $this->
|
234 |
-
'CurrentUserRoles' => $this->plugin->settings()->
|
235 |
),
|
236 |
true
|
237 |
);
|
@@ -243,7 +243,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
243 |
*
|
244 |
* @return int
|
245 |
*/
|
246 |
-
protected function
|
247 |
return $this->plugin->settings()->get_failed_login_limit();
|
248 |
}
|
249 |
|
@@ -252,7 +252,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
252 |
*
|
253 |
* @return int
|
254 |
*/
|
255 |
-
protected function
|
256 |
return $this->plugin->settings()->get_visitor_failed_login_limit();
|
257 |
}
|
258 |
|
@@ -261,7 +261,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
261 |
*
|
262 |
* @return integer Time until expiration in seconds from now
|
263 |
*/
|
264 |
-
protected function
|
265 |
return 12 * 60 * 60;
|
266 |
}
|
267 |
|
@@ -273,21 +273,21 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
273 |
* @param WP_User $user - User object.
|
274 |
* @return boolean - Passed limit true|false.
|
275 |
*/
|
276 |
-
protected function
|
277 |
-
$get_fn = $this->
|
278 |
if ( $user ) {
|
279 |
-
if ( -1 === (int) $this->
|
280 |
return false;
|
281 |
} else {
|
282 |
$data_known = $get_fn( self::TRANSIENT_FAILEDLOGINS );
|
283 |
-
return ( false !== $data_known ) && isset( $data_known[ $site_id . ':' . $user->ID . ':' . $ip ] ) && ( $data_known[ $site_id . ':' . $user->ID . ':' . $ip ] >= $this->
|
284 |
}
|
285 |
} else {
|
286 |
-
if ( -1 === (int) $this->
|
287 |
return false;
|
288 |
} else {
|
289 |
$data_unknown = $get_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN );
|
290 |
-
return ( false !== $data_unknown ) && isset( $data_unknown[ $site_id . ':' . $ip ] ) && ( $data_unknown[ $site_id . ':' . $ip ] >= $this->
|
291 |
}
|
292 |
}
|
293 |
}
|
@@ -299,9 +299,9 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
299 |
* @param integer $site_id - Blog ID.
|
300 |
* @param WP_User $user - User object.
|
301 |
*/
|
302 |
-
protected function
|
303 |
-
$get_fn = $this->
|
304 |
-
$set_fn = $this->
|
305 |
if ( $user ) {
|
306 |
$data_known = $get_fn( self::TRANSIENT_FAILEDLOGINS );
|
307 |
if ( ! $data_known ) {
|
@@ -311,7 +311,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
311 |
$data_known[ $site_id . ':' . $user->ID . ':' . $ip ] = 1;
|
312 |
}
|
313 |
$data_known[ $site_id . ':' . $user->ID . ':' . $ip ]++;
|
314 |
-
$set_fn( self::TRANSIENT_FAILEDLOGINS, $data_known, $this->
|
315 |
} else {
|
316 |
$data_unknown = $get_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN );
|
317 |
if ( ! $data_unknown ) {
|
@@ -321,7 +321,7 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
321 |
$data_unknown[ $site_id . ':' . $ip ] = 1;
|
322 |
}
|
323 |
$data_unknown[ $site_id . ':' . $ip ]++;
|
324 |
-
$set_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $data_unknown, $this->
|
325 |
}
|
326 |
}
|
327 |
|
@@ -330,10 +330,10 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
330 |
*
|
331 |
* @param string $username Username.
|
332 |
*/
|
333 |
-
public function
|
334 |
-
list($y, $m, $d) = explode( '-', date( 'Y-m-d' ) );
|
335 |
|
336 |
-
$ip = $this->plugin->settings()->
|
337 |
|
338 |
// Filter $_POST global array for security.
|
339 |
$post_array = filter_input_array( INPUT_POST );
|
@@ -346,31 +346,32 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
346 |
if ( empty( $user ) ) {
|
347 |
$user = get_user_by( 'email', $username );
|
348 |
}
|
349 |
-
|
|
|
350 |
if ( $user ) {
|
351 |
$new_alert_code = 1002;
|
352 |
-
$user_roles = $this->plugin->settings()->
|
353 |
-
if ( $this->plugin->settings()->
|
354 |
$user_roles[] = 'superadmin';
|
355 |
}
|
356 |
}
|
357 |
|
358 |
// Check if the alert is disabled from the "Enable/Disable Alerts" section.
|
359 |
-
if ( ! $this->plugin->alerts->
|
360 |
return;
|
361 |
}
|
362 |
|
363 |
-
if ( $this->
|
364 |
return;
|
365 |
}
|
366 |
|
367 |
$obj_occurrence = new WSAL_Models_Occurrence();
|
368 |
|
369 |
if ( 1002 === $new_alert_code ) {
|
370 |
-
if ( ! $this->plugin->alerts->
|
371 |
return;
|
372 |
}
|
373 |
-
$occ = $obj_occurrence->
|
374 |
array(
|
375 |
$ip,
|
376 |
$username,
|
@@ -382,29 +383,28 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
382 |
);
|
383 |
$occ = count( $occ ) ? $occ[0] : null;
|
384 |
|
385 |
-
if ($this->plugin->alerts->
|
386 |
-
//
|
387 |
return;
|
388 |
}
|
389 |
|
390 |
if ( ! empty( $occ ) ) {
|
391 |
// Update existing record exists user.
|
392 |
-
$this->
|
393 |
-
$new = $occ->
|
394 |
|
395 |
-
$login_failure_log_limit = $this->
|
396 |
-
if ( - 1 !== $login_failure_log_limit
|
397 |
-
&& $new > $login_failure_log_limit ) {
|
398 |
$new = $login_failure_log_limit . '+';
|
399 |
}
|
400 |
|
401 |
-
$occ->
|
402 |
-
$occ->username
|
403 |
$occ->created_on = null;
|
404 |
-
$occ->
|
405 |
} else {
|
406 |
// Create a new record exists user.
|
407 |
-
$this->plugin->alerts->
|
408 |
$new_alert_code,
|
409 |
array(
|
410 |
'Attempts' => 1,
|
@@ -413,18 +413,19 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
413 |
'CurrentUserRoles' => $user_roles,
|
414 |
),
|
415 |
/**
|
|
|
|
|
416 |
* @param WSAL_AlertManager $manager
|
417 |
*
|
418 |
* @return bool
|
419 |
*/
|
420 |
function ( $manager ) {
|
421 |
-
|
422 |
-
return !$manager->WillOrHasTriggered(1004);
|
423 |
}
|
424 |
);
|
425 |
}
|
426 |
} else {
|
427 |
-
$occ_unknown = $obj_occurrence->
|
428 |
array(
|
429 |
$ip,
|
430 |
1003,
|
@@ -437,40 +438,40 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
437 |
$occ_unknown = count( $occ_unknown ) ? $occ_unknown[0] : null;
|
438 |
if ( ! empty( $occ_unknown ) ) {
|
439 |
// Update existing record not exists user.
|
440 |
-
$this->
|
441 |
|
442 |
// Increase the number of attempts.
|
443 |
-
$new = $occ_unknown->
|
444 |
|
445 |
// If login attempts pass allowed number of attempts then stop increasing the attempts.
|
446 |
-
$failure_limit = $this->
|
447 |
if ( -1 !== $failure_limit && $new > $failure_limit ) {
|
448 |
$new = $failure_limit . '+';
|
449 |
}
|
450 |
|
451 |
// Update the number of login attempts.
|
452 |
-
$occ_unknown->
|
453 |
|
454 |
// Get users from alert.
|
455 |
-
$users = $occ_unknown->
|
456 |
|
457 |
// Update it if username is not already present in the array.
|
458 |
if ( ! empty( $users ) && is_array( $users ) && ! in_array( $username, $users, true ) ) {
|
459 |
$users[] = $username;
|
460 |
-
$occ_unknown->
|
461 |
} else {
|
462 |
// In this case the value doesn't exist so set the value to array.
|
463 |
-
$users
|
464 |
}
|
465 |
|
466 |
$occ_unknown->created_on = null;
|
467 |
-
$occ_unknown->
|
468 |
} else {
|
469 |
// Make an array of usernames.
|
470 |
$users = array( $username );
|
471 |
|
472 |
// Log an alert for a login attempt with unknown username.
|
473 |
-
$this->plugin->alerts->
|
474 |
$new_alert_code,
|
475 |
array(
|
476 |
'Attempts' => 1,
|
@@ -489,10 +490,10 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
489 |
* @param WP_User $user - User object.
|
490 |
* @param string $new_pass - New Password.
|
491 |
*/
|
492 |
-
public function
|
493 |
if ( ! empty( $user ) ) {
|
494 |
-
$user_roles = $this->plugin->settings()->
|
495 |
-
$this->plugin->alerts->
|
496 |
4003,
|
497 |
array(
|
498 |
'Username' => $user->user_login,
|
@@ -515,12 +516,12 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
515 |
*/
|
516 |
public function user_switched_event( $new_user_id, $old_user_id ) {
|
517 |
$target_user = get_user_by( 'ID', $new_user_id );
|
518 |
-
$target_user_roles = $this->plugin->settings()->
|
519 |
$target_user_roles = implode( ', ', $target_user_roles );
|
520 |
$old_user = get_user_by( 'ID', $old_user_id );
|
521 |
-
$old_user_roles = $this->plugin->settings()->
|
522 |
|
523 |
-
$this->plugin->alerts->
|
524 |
1008,
|
525 |
array(
|
526 |
'TargetUserName' => $target_user->user_login,
|
@@ -534,18 +535,18 @@ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
|
534 |
/**
|
535 |
* User has requested a password reset.
|
536 |
*
|
537 |
-
* @param object $errors Current WP_errors
|
538 |
* @param object $user User making the request.
|
539 |
*/
|
540 |
public function event_user_requested_pw_reset( $errors, $user = null ) {
|
541 |
-
|
542 |
-
// If we
|
543 |
if ( is_null( $user ) || ! isset( $user->roles ) ) {
|
544 |
return;
|
545 |
}
|
546 |
-
|
547 |
-
$user_roles = $this->plugin->settings()->
|
548 |
-
$this->plugin->alerts->
|
549 |
1010,
|
550 |
array(
|
551 |
'Username' => $user->user_login,
|
4 |
*
|
5 |
* Log In & Out sensor class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
24 |
* 1004 Login blocked
|
25 |
* 4003 User has changed his or her password
|
26 |
*
|
27 |
+
* @package wsal
|
28 |
* @subpackage sensors
|
29 |
*/
|
30 |
class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
41 |
*
|
42 |
* @var WP_User
|
43 |
*/
|
44 |
+
protected $current_user = null;
|
45 |
|
46 |
/**
|
47 |
+
* {@inheritDoc}
|
48 |
*/
|
49 |
+
public function hook_events() {
|
50 |
+
add_action( 'set_auth_cookie', array( $this, 'event_login' ), 10, 6 );
|
51 |
+
add_action( 'wp_logout', array( $this, 'event_logout' ), 5 );
|
52 |
+
add_action( 'password_reset', array( $this, 'event_password_reset' ), 10, 2 );
|
53 |
+
add_action( 'wp_login_failed', array( $this, 'event_login_failure' ) );
|
54 |
+
add_action( 'clear_auth_cookie', array( $this, 'get_current_user' ), 10 );
|
|
|
55 |
add_action( 'lostpassword_post', array( $this, 'event_user_requested_pw_reset' ), 10, 2 );
|
56 |
|
57 |
if ( WpSecurityAuditLog::is_twofactor_active() ) {
|
61 |
if ( WpSecurityAuditLog::is_plugin_active( 'user-switching/user-switching.php' ) ) {
|
62 |
add_action( 'switch_to_user', array( $this, 'user_switched_event' ), 10, 2 );
|
63 |
}
|
|
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
* Sets current user.
|
68 |
*/
|
69 |
+
public function get_current_user() {
|
70 |
+
$this->current_user = wp_get_current_user();
|
71 |
}
|
72 |
|
73 |
/**
|
96 |
// If provider and user are set and provider is known then log the event.
|
97 |
if ( $provider && $user && in_array( $provider, $providers_2fa, true ) ) {
|
98 |
// Get user roles.
|
99 |
+
$user_roles = $this->plugin->settings()->get_current_user_roles( $user->roles );
|
100 |
|
101 |
+
if ( $this->plugin->settings()->is_login_super_admin( $user->user_login ) ) {
|
102 |
$user_roles[] = 'superadmin';
|
103 |
}
|
104 |
|
105 |
+
$this->plugin->alerts->trigger_event(
|
106 |
1000,
|
107 |
array(
|
108 |
'Username' => $user->user_login,
|
127 |
* @param string $scheme Authentication scheme. Values include 'auth' or 'secure_auth'.
|
128 |
* @param string $token User's session token to use for this cookie.
|
129 |
*/
|
130 |
+
public function event_login( $auth_cookie, $expire, $expiration, $user_id, $scheme, $token ) {
|
131 |
// Get global POST array.
|
132 |
$post_array = filter_input_array( INPUT_POST );
|
133 |
|
157 |
|
158 |
// Log user changed password alert.
|
159 |
if ( ! empty( $user ) ) {
|
160 |
+
$user_roles = $this->plugin->settings()->get_current_user_roles( $user->roles );
|
161 |
+
$this->plugin->alerts->trigger_event(
|
162 |
4003,
|
163 |
array(
|
164 |
'Username' => $user->user_login,
|
177 |
return;
|
178 |
}
|
179 |
$user_login = $user->data->user_login;
|
180 |
+
$user_roles = $this->plugin->settings()->get_current_user_roles( $user->roles );
|
181 |
|
182 |
+
if ( $this->plugin->settings()->is_login_super_admin( $user_login ) ) {
|
183 |
$user_roles[] = 'superadmin';
|
184 |
}
|
185 |
|
191 |
$alert_data['SessionID'] = WSAL_UserSessions_Helpers::hash_token( $token );
|
192 |
}
|
193 |
|
194 |
+
$this->plugin->alerts->trigger_event_if(
|
195 |
1000,
|
196 |
$alert_data,
|
197 |
/**
|
198 |
+
* Don't fire if the user is changing their password via admin profile page.
|
199 |
+
*
|
200 |
* @param WSAL_AlertManager $manager
|
201 |
*
|
202 |
* @return bool
|
203 |
*/
|
204 |
function ( $manager ) {
|
205 |
+
return ! $manager->will_or_has_triggered( 4003 );
|
|
|
206 |
}
|
207 |
);
|
208 |
|
211 |
/**
|
212 |
* Event Logout.
|
213 |
*/
|
214 |
+
public function event_logout() {
|
215 |
+
if ( $this->current_user->ID ) {
|
216 |
// get the list of excluded users.
|
217 |
+
$excluded_users = $this->plugin->settings()->get_excluded_monitoring_users();
|
218 |
$excluded_user_ids = array();
|
219 |
// convert excluded usernames into IDs.
|
220 |
if ( ! empty( $excluded_users ) && is_array( $excluded_users ) ) {
|
224 |
}
|
225 |
}
|
226 |
// bail early if this user is in the excluded ids list.
|
227 |
+
if ( in_array( $this->current_user->ID, $excluded_user_ids, true ) ) {
|
228 |
return;
|
229 |
}
|
230 |
+
$this->plugin->alerts->trigger_event(
|
231 |
1001,
|
232 |
array(
|
233 |
+
'CurrentUserID' => $this->current_user->ID,
|
234 |
+
'CurrentUserRoles' => $this->plugin->settings()->get_current_user_roles( $this->current_user->roles ),
|
235 |
),
|
236 |
true
|
237 |
);
|
243 |
*
|
244 |
* @return int
|
245 |
*/
|
246 |
+
protected function get_login_failure_log_limit() {
|
247 |
return $this->plugin->settings()->get_failed_login_limit();
|
248 |
}
|
249 |
|
252 |
*
|
253 |
* @return int
|
254 |
*/
|
255 |
+
protected function get_visitor_login_failure_log_limit() {
|
256 |
return $this->plugin->settings()->get_visitor_failed_login_limit();
|
257 |
}
|
258 |
|
261 |
*
|
262 |
* @return integer Time until expiration in seconds from now
|
263 |
*/
|
264 |
+
protected function get_login_failure_expiration() {
|
265 |
return 12 * 60 * 60;
|
266 |
}
|
267 |
|
273 |
* @param WP_User $user - User object.
|
274 |
* @return boolean - Passed limit true|false.
|
275 |
*/
|
276 |
+
protected function is_past_login_failure_limit( $ip, $site_id, $user ) {
|
277 |
+
$get_fn = $this->is_multisite() ? 'get_site_transient' : 'get_transient';
|
278 |
if ( $user ) {
|
279 |
+
if ( -1 === (int) $this->get_login_failure_log_limit() ) {
|
280 |
return false;
|
281 |
} else {
|
282 |
$data_known = $get_fn( self::TRANSIENT_FAILEDLOGINS );
|
283 |
+
return ( false !== $data_known ) && isset( $data_known[ $site_id . ':' . $user->ID . ':' . $ip ] ) && ( $data_known[ $site_id . ':' . $user->ID . ':' . $ip ] >= $this->get_login_failure_log_limit() );
|
284 |
}
|
285 |
} else {
|
286 |
+
if ( -1 === (int) $this->get_visitor_login_failure_log_limit() ) {
|
287 |
return false;
|
288 |
} else {
|
289 |
$data_unknown = $get_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN );
|
290 |
+
return ( false !== $data_unknown ) && isset( $data_unknown[ $site_id . ':' . $ip ] ) && ( $data_unknown[ $site_id . ':' . $ip ] >= $this->get_visitor_login_failure_log_limit() );
|
291 |
}
|
292 |
}
|
293 |
}
|
299 |
* @param integer $site_id - Blog ID.
|
300 |
* @param WP_User $user - User object.
|
301 |
*/
|
302 |
+
protected function increment_login_failure( $ip, $site_id, $user ) {
|
303 |
+
$get_fn = $this->is_multisite() ? 'get_site_transient' : 'get_transient';
|
304 |
+
$set_fn = $this->is_multisite() ? 'set_site_transient' : 'set_transient';
|
305 |
if ( $user ) {
|
306 |
$data_known = $get_fn( self::TRANSIENT_FAILEDLOGINS );
|
307 |
if ( ! $data_known ) {
|
311 |
$data_known[ $site_id . ':' . $user->ID . ':' . $ip ] = 1;
|
312 |
}
|
313 |
$data_known[ $site_id . ':' . $user->ID . ':' . $ip ]++;
|
314 |
+
$set_fn( self::TRANSIENT_FAILEDLOGINS, $data_known, $this->get_login_failure_expiration() );
|
315 |
} else {
|
316 |
$data_unknown = $get_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN );
|
317 |
if ( ! $data_unknown ) {
|
321 |
$data_unknown[ $site_id . ':' . $ip ] = 1;
|
322 |
}
|
323 |
$data_unknown[ $site_id . ':' . $ip ]++;
|
324 |
+
$set_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $data_unknown, $this->get_login_failure_expiration() );
|
325 |
}
|
326 |
}
|
327 |
|
330 |
*
|
331 |
* @param string $username Username.
|
332 |
*/
|
333 |
+
public function event_login_failure( $username ) {
|
334 |
+
list($y, $m, $d) = explode( '-', date( 'Y-m-d' ) ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
335 |
|
336 |
+
$ip = $this->plugin->settings()->get_main_client_ip();
|
337 |
|
338 |
// Filter $_POST global array for security.
|
339 |
$post_array = filter_input_array( INPUT_POST );
|
346 |
if ( empty( $user ) ) {
|
347 |
$user = get_user_by( 'email', $username );
|
348 |
}
|
349 |
+
|
350 |
+
$site_id = ( function_exists( 'get_current_blog_id' ) ? get_current_blog_id() : 0 );
|
351 |
if ( $user ) {
|
352 |
$new_alert_code = 1002;
|
353 |
+
$user_roles = $this->plugin->settings()->get_current_user_roles( $user->roles );
|
354 |
+
if ( $this->plugin->settings()->is_login_super_admin( $username ) ) {
|
355 |
$user_roles[] = 'superadmin';
|
356 |
}
|
357 |
}
|
358 |
|
359 |
// Check if the alert is disabled from the "Enable/Disable Alerts" section.
|
360 |
+
if ( ! $this->plugin->alerts->is_enabled( $new_alert_code ) ) {
|
361 |
return;
|
362 |
}
|
363 |
|
364 |
+
if ( $this->is_past_login_failure_limit( $ip, $site_id, $user ) ) {
|
365 |
return;
|
366 |
}
|
367 |
|
368 |
$obj_occurrence = new WSAL_Models_Occurrence();
|
369 |
|
370 |
if ( 1002 === $new_alert_code ) {
|
371 |
+
if ( ! $this->plugin->alerts->check_enable_user_roles( $username, $user_roles ) ) {
|
372 |
return;
|
373 |
}
|
374 |
+
$occ = $obj_occurrence->check_known_users(
|
375 |
array(
|
376 |
$ip,
|
377 |
$username,
|
383 |
);
|
384 |
$occ = count( $occ ) ? $occ[0] : null;
|
385 |
|
386 |
+
if ( $this->plugin->alerts->will_or_has_triggered( 1004 ) ) {
|
387 |
+
// Skip if 1004 (session block) is already in place.
|
388 |
return;
|
389 |
}
|
390 |
|
391 |
if ( ! empty( $occ ) ) {
|
392 |
// Update existing record exists user.
|
393 |
+
$this->increment_login_failure( $ip, $site_id, $user );
|
394 |
+
$new = $occ->get_meta_value( 'Attempts', 0 ) + 1;
|
395 |
|
396 |
+
$login_failure_log_limit = $this->get_login_failure_log_limit();
|
397 |
+
if ( - 1 !== $login_failure_log_limit && $new > $login_failure_log_limit ) {
|
|
|
398 |
$new = $login_failure_log_limit . '+';
|
399 |
}
|
400 |
|
401 |
+
$occ->update_meta_value( 'Attempts', $new );
|
402 |
+
$occ->username = $username;
|
403 |
$occ->created_on = null;
|
404 |
+
$occ->save();
|
405 |
} else {
|
406 |
// Create a new record exists user.
|
407 |
+
$this->plugin->alerts->trigger_event(
|
408 |
$new_alert_code,
|
409 |
array(
|
410 |
'Attempts' => 1,
|
413 |
'CurrentUserRoles' => $user_roles,
|
414 |
),
|
415 |
/**
|
416 |
+
* Skip if 1004 (session block) is already in place.
|
417 |
+
*
|
418 |
* @param WSAL_AlertManager $manager
|
419 |
*
|
420 |
* @return bool
|
421 |
*/
|
422 |
function ( $manager ) {
|
423 |
+
return ! $manager->will_or_has_triggered( 1004 );
|
|
|
424 |
}
|
425 |
);
|
426 |
}
|
427 |
} else {
|
428 |
+
$occ_unknown = $obj_occurrence->check_unknown_users(
|
429 |
array(
|
430 |
$ip,
|
431 |
1003,
|
438 |
$occ_unknown = count( $occ_unknown ) ? $occ_unknown[0] : null;
|
439 |
if ( ! empty( $occ_unknown ) ) {
|
440 |
// Update existing record not exists user.
|
441 |
+
$this->increment_login_failure( $ip, $site_id, false );
|
442 |
|
443 |
// Increase the number of attempts.
|
444 |
+
$new = $occ_unknown->get_meta_value( 'Attempts', 0 ) + 1;
|
445 |
|
446 |
// If login attempts pass allowed number of attempts then stop increasing the attempts.
|
447 |
+
$failure_limit = $this->get_visitor_login_failure_log_limit();
|
448 |
if ( -1 !== $failure_limit && $new > $failure_limit ) {
|
449 |
$new = $failure_limit . '+';
|
450 |
}
|
451 |
|
452 |
// Update the number of login attempts.
|
453 |
+
$occ_unknown->update_meta_value( 'Attempts', $new );
|
454 |
|
455 |
// Get users from alert.
|
456 |
+
$users = $occ_unknown->get_meta_value( 'Users' );
|
457 |
|
458 |
// Update it if username is not already present in the array.
|
459 |
if ( ! empty( $users ) && is_array( $users ) && ! in_array( $username, $users, true ) ) {
|
460 |
$users[] = $username;
|
461 |
+
$occ_unknown->update_meta_value( 'Users', $users );
|
462 |
} else {
|
463 |
// In this case the value doesn't exist so set the value to array.
|
464 |
+
$users = array( $username );
|
465 |
}
|
466 |
|
467 |
$occ_unknown->created_on = null;
|
468 |
+
$occ_unknown->save();
|
469 |
} else {
|
470 |
// Make an array of usernames.
|
471 |
$users = array( $username );
|
472 |
|
473 |
// Log an alert for a login attempt with unknown username.
|
474 |
+
$this->plugin->alerts->trigger_event(
|
475 |
$new_alert_code,
|
476 |
array(
|
477 |
'Attempts' => 1,
|
490 |
* @param WP_User $user - User object.
|
491 |
* @param string $new_pass - New Password.
|
492 |
*/
|
493 |
+
public function event_password_reset( $user, $new_pass ) {
|
494 |
if ( ! empty( $user ) ) {
|
495 |
+
$user_roles = $this->plugin->settings()->get_current_user_roles( $user->roles );
|
496 |
+
$this->plugin->alerts->trigger_event(
|
497 |
4003,
|
498 |
array(
|
499 |
'Username' => $user->user_login,
|
516 |
*/
|
517 |
public function user_switched_event( $new_user_id, $old_user_id ) {
|
518 |
$target_user = get_user_by( 'ID', $new_user_id );
|
519 |
+
$target_user_roles = $this->plugin->settings()->get_current_user_roles( $target_user->roles );
|
520 |
$target_user_roles = implode( ', ', $target_user_roles );
|
521 |
$old_user = get_user_by( 'ID', $old_user_id );
|
522 |
+
$old_user_roles = $this->plugin->settings()->get_current_user_roles( $old_user->roles );
|
523 |
|
524 |
+
$this->plugin->alerts->trigger_event(
|
525 |
1008,
|
526 |
array(
|
527 |
'TargetUserName' => $target_user->user_login,
|
535 |
/**
|
536 |
* User has requested a password reset.
|
537 |
*
|
538 |
+
* @param object $errors Current WP_errors object.
|
539 |
* @param object $user User making the request.
|
540 |
*/
|
541 |
public function event_user_requested_pw_reset( $errors, $user = null ) {
|
542 |
+
|
543 |
+
// If we don't have the user, do nothing.
|
544 |
if ( is_null( $user ) || ! isset( $user->roles ) ) {
|
545 |
return;
|
546 |
}
|
547 |
+
|
548 |
+
$user_roles = $this->plugin->settings()->get_current_user_roles( $user->roles );
|
549 |
+
$this->plugin->alerts->trigger_event(
|
550 |
1010,
|
551 |
array(
|
552 |
'Username' => $user->user_login,
|
classes/Sensors/MainWP.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* MainWP Plugins & Themes sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -26,7 +27,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
26 |
* 5007 User uninstalled a theme
|
27 |
* 5031 User updated a theme
|
28 |
*
|
29 |
-
* @package
|
30 |
* @subpackage sensors
|
31 |
*/
|
32 |
class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
@@ -39,11 +40,11 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
39 |
protected $old_themes = array();
|
40 |
|
41 |
/**
|
42 |
-
*
|
43 |
*/
|
44 |
-
public function
|
45 |
|
46 |
-
add_action( 'admin_init', array( $this, '
|
47 |
|
48 |
// Check if MainWP Child Plugin exists.
|
49 |
if ( WpSecurityAuditLog::is_mainwp_active() ) {
|
@@ -64,15 +65,14 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
64 |
add_action( 'mainwp_child_theme_action', array( $this, 'mainwp_child_uninstall_theme' ), 10, 1 );
|
65 |
|
66 |
// Update theme/plugin from MainWP dashboard.
|
67 |
-
|
68 |
-
|
69 |
}
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
* Triggered when a user accesses the admin area.
|
74 |
*/
|
75 |
-
public function
|
76 |
$this->old_themes = wp_get_themes();
|
77 |
$this->old_plugins = get_plugins();
|
78 |
}
|
@@ -107,9 +107,9 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
107 |
/**
|
108 |
* Get removed themes.
|
109 |
*
|
110 |
-
* @return
|
111 |
*/
|
112 |
-
protected function
|
113 |
$result = $this->old_themes;
|
114 |
foreach ( $result as $i => $theme ) {
|
115 |
if ( file_exists( $theme->get_template_directory() ) ) {
|
@@ -125,6 +125,8 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
125 |
*
|
126 |
* @param array $args - Array of arguments related to asset installed.
|
127 |
* @since 3.2.2
|
|
|
|
|
128 |
*/
|
129 |
public function mainwp_child_install_assets( $args ) {
|
130 |
if ( empty( $args ) || ! is_array( $args ) ) {
|
@@ -143,7 +145,7 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
143 |
|
144 |
// Check if theme exists.
|
145 |
if ( $theme_obj->exists() ) {
|
146 |
-
$this->plugin->alerts->
|
147 |
5005,
|
148 |
array(
|
149 |
'Theme' => (object) array(
|
@@ -165,7 +167,7 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
165 |
$plugin = $plugins[ $plugin_slug ]; // Take out the plugin being installed.
|
166 |
|
167 |
$plugin_path = plugin_dir_path( WP_PLUGIN_DIR . '/' . $plugin_slug );
|
168 |
-
$this->plugin->alerts->
|
169 |
5000,
|
170 |
array(
|
171 |
'Plugin' => (object) array(
|
@@ -215,7 +217,7 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
215 |
$plugin_filename = WSAL_Sensors_PluginsThemes::get_plugin_file_name( $plugin_name );
|
216 |
|
217 |
if ( ! empty( $plugin_filename ) && in_array( $plugin_filename, $wp_plugins, true ) ) {
|
218 |
-
$this->plugin->alerts->
|
219 |
5003,
|
220 |
array(
|
221 |
'PluginFile' => $plugin_filename,
|
@@ -234,6 +236,8 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
234 |
*
|
235 |
* @param array $args - Array of arguments related to asset uninstalled.
|
236 |
* @since 3.2.2
|
|
|
|
|
237 |
*/
|
238 |
public function mainwp_child_uninstall_theme( $args ) {
|
239 |
if ( empty( $args ) || ! is_array( $args ) ) {
|
@@ -255,12 +259,12 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
255 |
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
256 |
) {
|
257 |
// Get theme object.
|
258 |
-
$themes = $this->
|
259 |
|
260 |
if ( ! empty( $themes ) ) {
|
261 |
foreach ( $themes as $index => $theme ) {
|
262 |
if ( ! empty( $theme ) && $theme instanceof WP_Theme && in_array( $theme->Name, $wp_themes, true ) ) {
|
263 |
-
$this->plugin->alerts->
|
264 |
5007,
|
265 |
array(
|
266 |
'Theme' => (object) array(
|
@@ -315,7 +319,7 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
315 |
|
316 |
$plugin = WP_PLUGIN_DIR . '/' . $plugin;
|
317 |
$plugin_data = get_plugin_data( $plugin, false, true );
|
318 |
-
$this->plugin->alerts->
|
319 |
$event,
|
320 |
array(
|
321 |
'PluginFile' => $plugin,
|
@@ -337,7 +341,7 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
337 |
) {
|
338 |
$plugin = WP_PLUGIN_DIR . '/' . $plugin;
|
339 |
$plugin_data = get_plugin_data( $plugin, false, true );
|
340 |
-
$this->plugin->alerts->
|
341 |
5001,
|
342 |
array(
|
343 |
'PluginFile' => $plugin,
|
@@ -353,14 +357,14 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
353 |
}
|
354 |
}
|
355 |
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
public function mainwp_child_update_assets( $upgrader, $args ) {
|
365 |
if ( empty( $args ) || ! is_array( $args ) ) {
|
366 |
return;
|
@@ -374,32 +378,32 @@ class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
|
374 |
isset( $post_array['function'] ) && 'upgradeplugintheme' === $post_array['function']
|
375 |
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
376 |
&& isset( $post_array['list'] ) && ! empty( $post_array['list'] )
|
377 |
-
|
378 |
-
|
379 |
) {
|
380 |
if ( 'theme' === $args['type'] ) {
|
381 |
// Site themes updated.
|
382 |
$site_themes = array_key_exists( 'themes', $args ) ? $args['themes'] : explode( ',', $post_array['list'] );
|
383 |
|
384 |
if ( empty( $site_themes ) ) {
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
|
389 |
foreach ( $site_themes as $theme_name ) {
|
390 |
-
|
391 |
-
|
392 |
} elseif ( 'plugin' === $args['type'] ) {
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
}
|
404 |
}
|
405 |
}
|
4 |
*
|
5 |
* MainWP Plugins & Themes sensor file.
|
6 |
*
|
7 |
+
* @since 4.1.4
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
27 |
* 5007 User uninstalled a theme
|
28 |
* 5031 User updated a theme
|
29 |
*
|
30 |
+
* @package wsal
|
31 |
* @subpackage sensors
|
32 |
*/
|
33 |
class WSAL_Sensors_MainWP extends WSAL_AbstractSensor {
|
40 |
protected $old_themes = array();
|
41 |
|
42 |
/**
|
43 |
+
* {@inheritDoc}
|
44 |
*/
|
45 |
+
public function hook_events() {
|
46 |
|
47 |
+
add_action( 'admin_init', array( $this, 'event_admin_init' ) );
|
48 |
|
49 |
// Check if MainWP Child Plugin exists.
|
50 |
if ( WpSecurityAuditLog::is_mainwp_active() ) {
|
65 |
add_action( 'mainwp_child_theme_action', array( $this, 'mainwp_child_uninstall_theme' ), 10, 1 );
|
66 |
|
67 |
// Update theme/plugin from MainWP dashboard.
|
68 |
+
add_action( 'upgrader_process_complete', array( $this, 'mainwp_child_update_assets' ), 10, 2 );
|
|
|
69 |
}
|
70 |
}
|
71 |
|
72 |
/**
|
73 |
* Triggered when a user accesses the admin area.
|
74 |
*/
|
75 |
+
public function event_admin_init() {
|
76 |
$this->old_themes = wp_get_themes();
|
77 |
$this->old_plugins = get_plugins();
|
78 |
}
|
107 |
/**
|
108 |
* Get removed themes.
|
109 |
*
|
110 |
+
* @return WP_Theme[] List of WP_Theme objects.
|
111 |
*/
|
112 |
+
protected function get_removed_themes() {
|
113 |
$result = $this->old_themes;
|
114 |
foreach ( $result as $i => $theme ) {
|
115 |
if ( file_exists( $theme->get_template_directory() ) ) {
|
125 |
*
|
126 |
* @param array $args - Array of arguments related to asset installed.
|
127 |
* @since 3.2.2
|
128 |
+
*
|
129 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
130 |
*/
|
131 |
public function mainwp_child_install_assets( $args ) {
|
132 |
if ( empty( $args ) || ! is_array( $args ) ) {
|
145 |
|
146 |
// Check if theme exists.
|
147 |
if ( $theme_obj->exists() ) {
|
148 |
+
$this->plugin->alerts->trigger_event(
|
149 |
5005,
|
150 |
array(
|
151 |
'Theme' => (object) array(
|
167 |
$plugin = $plugins[ $plugin_slug ]; // Take out the plugin being installed.
|
168 |
|
169 |
$plugin_path = plugin_dir_path( WP_PLUGIN_DIR . '/' . $plugin_slug );
|
170 |
+
$this->plugin->alerts->trigger_event(
|
171 |
5000,
|
172 |
array(
|
173 |
'Plugin' => (object) array(
|
217 |
$plugin_filename = WSAL_Sensors_PluginsThemes::get_plugin_file_name( $plugin_name );
|
218 |
|
219 |
if ( ! empty( $plugin_filename ) && in_array( $plugin_filename, $wp_plugins, true ) ) {
|
220 |
+
$this->plugin->alerts->trigger_event(
|
221 |
5003,
|
222 |
array(
|
223 |
'PluginFile' => $plugin_filename,
|
236 |
*
|
237 |
* @param array $args - Array of arguments related to asset uninstalled.
|
238 |
* @since 3.2.2
|
239 |
+
*
|
240 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
241 |
*/
|
242 |
public function mainwp_child_uninstall_theme( $args ) {
|
243 |
if ( empty( $args ) || ! is_array( $args ) ) {
|
259 |
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
260 |
) {
|
261 |
// Get theme object.
|
262 |
+
$themes = $this->get_removed_themes();
|
263 |
|
264 |
if ( ! empty( $themes ) ) {
|
265 |
foreach ( $themes as $index => $theme ) {
|
266 |
if ( ! empty( $theme ) && $theme instanceof WP_Theme && in_array( $theme->Name, $wp_themes, true ) ) {
|
267 |
+
$this->plugin->alerts->trigger_event(
|
268 |
5007,
|
269 |
array(
|
270 |
'Theme' => (object) array(
|
319 |
|
320 |
$plugin = WP_PLUGIN_DIR . '/' . $plugin;
|
321 |
$plugin_data = get_plugin_data( $plugin, false, true );
|
322 |
+
$this->plugin->alerts->trigger_event(
|
323 |
$event,
|
324 |
array(
|
325 |
'PluginFile' => $plugin,
|
341 |
) {
|
342 |
$plugin = WP_PLUGIN_DIR . '/' . $plugin;
|
343 |
$plugin_data = get_plugin_data( $plugin, false, true );
|
344 |
+
$this->plugin->alerts->trigger_event(
|
345 |
5001,
|
346 |
array(
|
347 |
'PluginFile' => $plugin,
|
357 |
}
|
358 |
}
|
359 |
|
360 |
+
/**
|
361 |
+
* Method: Handle plugin/theme update event from MainWP dashboard on child site.
|
362 |
+
*
|
363 |
+
* @param WP_Upgrader $upgrader WordPress upgrader.
|
364 |
+
* @param array $args - Array of arguments related to asset updated.
|
365 |
+
*
|
366 |
+
* @since 3.2.2
|
367 |
+
*/
|
368 |
public function mainwp_child_update_assets( $upgrader, $args ) {
|
369 |
if ( empty( $args ) || ! is_array( $args ) ) {
|
370 |
return;
|
378 |
isset( $post_array['function'] ) && 'upgradeplugintheme' === $post_array['function']
|
379 |
&& isset( $post_array['mainwpsignature'] ) && ! empty( $post_array['mainwpsignature'] )
|
380 |
&& isset( $post_array['list'] ) && ! empty( $post_array['list'] )
|
381 |
+
&& isset( $args['action'] ) && 'update' === $args['action']
|
382 |
+
&& isset( $args['type'] ) && ! empty( $args['type'] )
|
383 |
) {
|
384 |
if ( 'theme' === $args['type'] ) {
|
385 |
// Site themes updated.
|
386 |
$site_themes = array_key_exists( 'themes', $args ) ? $args['themes'] : explode( ',', $post_array['list'] );
|
387 |
|
388 |
if ( empty( $site_themes ) ) {
|
389 |
+
// No themes in any of the lists.
|
390 |
+
return;
|
391 |
+
}
|
392 |
|
393 |
foreach ( $site_themes as $theme_name ) {
|
394 |
+
WSAL_Sensors_PluginsThemes::log_theme_updated_event( $theme_name );
|
395 |
+
}
|
396 |
} elseif ( 'plugin' === $args['type'] ) {
|
397 |
+
// Site plugins updated.
|
398 |
+
if ( ! array_key_exists( 'plugins', $args ) || empty( $args['plugins'] ) ) {
|
399 |
+
// No plugins in the list.
|
400 |
+
return;
|
401 |
+
}
|
402 |
+
|
403 |
+
$plugins = $args['plugins'];
|
404 |
+
foreach ( $plugins as $plugin_file ) {
|
405 |
+
WSAL_Sensors_PluginsThemes::log_plugin_updated_event( $plugin_file );
|
406 |
+
}
|
407 |
}
|
408 |
}
|
409 |
}
|
classes/Sensors/Menus.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Menus sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -26,7 +27,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
26 |
* 2085 User changed order of the objects in a menu
|
27 |
* 2089 User moved objects as a sub-item
|
28 |
*
|
29 |
-
* @package
|
30 |
* @subpackage sensors
|
31 |
*/
|
32 |
class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
@@ -36,28 +37,28 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
36 |
*
|
37 |
* @var object
|
38 |
*/
|
39 |
-
protected $
|
40 |
|
41 |
/**
|
42 |
* Old Menu objects.
|
43 |
*
|
44 |
* @var array
|
45 |
*/
|
46 |
-
protected $
|
47 |
|
48 |
/**
|
49 |
* Old Menu Items.
|
50 |
*
|
51 |
* @var array
|
52 |
*/
|
53 |
-
protected $
|
54 |
|
55 |
/**
|
56 |
* Old Menu Locations.
|
57 |
*
|
58 |
* @var array
|
59 |
*/
|
60 |
-
protected $
|
61 |
|
62 |
/**
|
63 |
* An array of menu IDs for which an order change has already been reported during current request.
|
@@ -65,18 +66,18 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
65 |
* @var array
|
66 |
* @since 4.2.0.1
|
67 |
*/
|
68 |
-
protected $order_changed_menu_ids =
|
69 |
|
70 |
/**
|
71 |
-
*
|
72 |
*/
|
73 |
-
public function
|
74 |
-
add_action( 'wp_create_nav_menu', array( $this, '
|
75 |
-
add_action( 'wp_delete_nav_menu', array( $this, '
|
76 |
-
add_action( 'wp_update_nav_menu', array( $this, '
|
77 |
|
78 |
-
add_action( 'wp_update_nav_menu_item', array( $this, '
|
79 |
-
add_action( 'admin_menu', array( $this, '
|
80 |
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
81 |
|
82 |
// Customizer trigger.
|
@@ -87,13 +88,13 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
87 |
/**
|
88 |
* Menu item updated.
|
89 |
*
|
90 |
-
* @param int
|
91 |
-
* @param int
|
92 |
-
* @param array $args
|
93 |
*
|
94 |
* @return boolean
|
95 |
*/
|
96 |
-
public function
|
97 |
// Filter $_POST global array for security.
|
98 |
$post_array = filter_input_array( INPUT_POST );
|
99 |
|
@@ -102,24 +103,24 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
102 |
$is_changed_order = false;
|
103 |
$is_sub_item = false;
|
104 |
$new_menu_items = array_keys( $post_array['menu-item-title'] );
|
105 |
-
if ( ! empty( $this->
|
106 |
-
foreach ( $this->
|
107 |
-
if ( $old_item['menu_id']
|
108 |
$item_id = $old_item['item_id'];
|
109 |
-
if ( $item_id
|
110 |
-
if ( $old_item['menu_order']
|
111 |
$is_changed_order = true;
|
112 |
}
|
113 |
if ( ! empty( $args['menu-item-parent-id'] ) ) {
|
114 |
$is_sub_item = true;
|
115 |
}
|
116 |
-
if ( ! empty( $args['menu-item-title'] ) && $old_item['title']
|
117 |
// Verify nonce.
|
118 |
if ( ! wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
119 |
return false;
|
120 |
}
|
121 |
|
122 |
-
$this->
|
123 |
}
|
124 |
}
|
125 |
$old_menu_items[ $item_id ] = array(
|
@@ -134,40 +135,40 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
134 |
// Add Items to the menu.
|
135 |
$added_items = array_diff( $new_menu_items, array_keys( $old_menu_items ) );
|
136 |
if ( count( $added_items ) > 0 && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
137 |
-
if ( in_array( $menu_item_db_id, $added_items ) ) {
|
138 |
-
$this->
|
139 |
}
|
140 |
}
|
141 |
|
142 |
// Remove items from the menu.
|
143 |
$removed_items = array_diff( array_keys( $old_menu_items ), $new_menu_items );
|
144 |
if ( count( $removed_items ) > 0 && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
145 |
-
if ( array_search( $menu_item_db_id, $new_menu_items ) == ( count( $new_menu_items ) - 1 ) ) {
|
146 |
foreach ( $removed_items as $removed_item_id ) {
|
147 |
-
$this->
|
148 |
}
|
149 |
}
|
150 |
}
|
151 |
|
152 |
-
//
|
153 |
-
//
|
154 |
$ignore_order_change = ! empty( $removed_items ) || ! empty( $added_items );
|
155 |
|
156 |
-
//
|
157 |
if ( ! $ignore_order_change && $is_changed_order && wp_verify_nonce( $post_array['meta-box-order-nonce'], 'meta-box-order' ) ) {
|
158 |
$old_item = $old_menu_items[ $menu_item_db_id ];
|
159 |
$menu_object = wp_get_nav_menu_object( $menu_id );
|
160 |
if ( $menu_object instanceof WP_Term ) {
|
161 |
-
$this->
|
162 |
}
|
163 |
}
|
164 |
|
165 |
if ( $is_sub_item && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
166 |
$item_parent_id = $args['menu-item-parent-id'];
|
167 |
$item_name = $old_menu_items[ $menu_item_db_id ]['title'];
|
168 |
-
if ( $old_menu_items[ $menu_item_db_id ]['parent']
|
169 |
$parent_name = isset( $old_menu_items[ $item_parent_id ]['title'] ) ? $old_menu_items[ $item_parent_id ]['title'] : false;
|
170 |
-
$this->
|
171 |
}
|
172 |
}
|
173 |
}
|
@@ -179,8 +180,8 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
179 |
* @param int $term_id - Term ID.
|
180 |
* @param array $menu_data - Menu data.
|
181 |
*/
|
182 |
-
public function
|
183 |
-
$this->plugin->alerts->
|
184 |
2078,
|
185 |
array(
|
186 |
'MenuName' => $menu_data['menu-name'],
|
@@ -194,7 +195,7 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
194 |
*
|
195 |
* @global array $_POST Data post.
|
196 |
*/
|
197 |
-
public function
|
198 |
// Filter $_POST global array for security.
|
199 |
$post_array = filter_input_array( INPUT_POST );
|
200 |
|
@@ -207,10 +208,10 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
207 |
if ( isset( $post_array['menu-locations'] ) ) {
|
208 |
$new_locations = $post_array['menu-locations'];
|
209 |
if ( isset( $new_locations['top'] ) ) {
|
210 |
-
$this->
|
211 |
}
|
212 |
if ( isset( $new_locations['social'] ) ) {
|
213 |
-
$this->
|
214 |
}
|
215 |
}
|
216 |
}
|
@@ -221,17 +222,17 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
221 |
* @param integer $new_location - New location.
|
222 |
* @param string $type - Location type.
|
223 |
*/
|
224 |
-
private function
|
225 |
$old_locations = get_nav_menu_locations();
|
226 |
-
if ( 0 != $new_location ) {
|
227 |
$menu = wp_get_nav_menu_object( $new_location );
|
228 |
-
if ( isset( $old_locations[ $type ] ) && $old_locations[ $type ] != $new_location ) {
|
229 |
-
$this->
|
230 |
}
|
231 |
} else {
|
232 |
if ( ! empty( $old_locations[ $type ] ) ) {
|
233 |
$menu = wp_get_nav_menu_object( $old_locations[ $type ] );
|
234 |
-
$this->
|
235 |
}
|
236 |
}
|
237 |
}
|
@@ -241,12 +242,12 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
241 |
*
|
242 |
* @param int $term_id - Term ID.
|
243 |
*/
|
244 |
-
public function
|
245 |
-
if ( $this->
|
246 |
-
$this->plugin->alerts->
|
247 |
2081,
|
248 |
array(
|
249 |
-
'MenuName' => $this->
|
250 |
'MenuID' => $term_id,
|
251 |
)
|
252 |
);
|
@@ -258,8 +259,11 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
258 |
*
|
259 |
* @param int $menu_id - Menu ID.
|
260 |
* @param array $menu_data (Optional) Menu data.
|
|
|
|
|
|
|
261 |
*/
|
262 |
-
public function
|
263 |
if ( ! empty( $menu_data ) ) {
|
264 |
$content_names_old = array();
|
265 |
$content_types_old = array();
|
@@ -278,15 +282,15 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
278 |
$post_array = filter_input_array( INPUT_POST );
|
279 |
|
280 |
// Menu changed name.
|
281 |
-
if ( ! empty( $this->
|
282 |
-
foreach ( $this->
|
283 |
if ( $old_menu_term['term_id'] == $post_array['menu'] && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
284 |
-
if ( $old_menu_term['name']
|
285 |
-
$this->
|
286 |
} else {
|
287 |
-
//Remove the last menu item.
|
288 |
if ( count( $content_names_old ) == 1 && count( $content_types_old ) == 1 ) {
|
289 |
-
$this->
|
290 |
}
|
291 |
}
|
292 |
}
|
@@ -314,49 +318,49 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
314 |
|
315 |
// Alert 2082 Auto add pages.
|
316 |
if ( ! empty( $auto_add ) ) {
|
317 |
-
$this->
|
318 |
}
|
319 |
|
320 |
$nav_menu_locations = get_nav_menu_locations();
|
321 |
|
322 |
$location_top = null;
|
323 |
-
if ( isset( $this->
|
324 |
-
if ( $nav_menu_locations['top'] == $menu_id && $this->
|
325 |
$location_top = 'Enabled';
|
326 |
}
|
327 |
-
} elseif ( empty( $this->
|
328 |
if ( $nav_menu_locations['top'] == $menu_id ) {
|
329 |
$location_top = 'Enabled';
|
330 |
}
|
331 |
-
} elseif ( isset( $this->
|
332 |
-
if ( $this->
|
333 |
$location_top = 'Disabled';
|
334 |
}
|
335 |
}
|
336 |
|
337 |
// Alert 2082 top menu.
|
338 |
if ( ! empty( $location_top ) ) {
|
339 |
-
$this->
|
340 |
}
|
341 |
|
342 |
$location_social = null;
|
343 |
-
if ( isset( $this->
|
344 |
-
if ( $nav_menu_locations['social'] == $menu_id && $this->
|
345 |
$location_social = 'Enabled';
|
346 |
}
|
347 |
-
} elseif ( empty( $this->
|
348 |
if ( $nav_menu_locations['social'] == $menu_id ) {
|
349 |
$location_social = 'Enabled';
|
350 |
}
|
351 |
-
} elseif ( isset( $this->
|
352 |
-
if ( $this->
|
353 |
$location_social = 'Disabled';
|
354 |
}
|
355 |
}
|
356 |
|
357 |
// Alert 2082 Social links menu.
|
358 |
if ( ! empty( $location_social ) ) {
|
359 |
-
$this->
|
360 |
}
|
361 |
}
|
362 |
}
|
@@ -369,7 +373,7 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
369 |
if ( ! empty( $menus ) ) {
|
370 |
foreach ( $menus as $menu ) {
|
371 |
array_push(
|
372 |
-
$this->
|
373 |
array(
|
374 |
'term_id' => $menu->term_id,
|
375 |
'name' => $menu->name,
|
@@ -379,7 +383,7 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
379 |
if ( ! empty( $items ) ) {
|
380 |
foreach ( $items as $item ) {
|
381 |
array_push(
|
382 |
-
$this->
|
383 |
array(
|
384 |
'menu_id' => $menu->term_id,
|
385 |
'item_id' => $item->ID,
|
@@ -415,12 +419,12 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
415 |
if ( $is_nav_menu ) {
|
416 |
if ( isset( $get_array['action'] ) && 'delete' == $get_array['action'] ) {
|
417 |
if ( isset( $get_array['menu'] ) ) {
|
418 |
-
$this->
|
419 |
}
|
420 |
} else {
|
421 |
$this->BuildOldMenuTermsAndItems();
|
422 |
}
|
423 |
-
$this->
|
424 |
}
|
425 |
}
|
426 |
|
@@ -429,7 +433,7 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
429 |
*/
|
430 |
public function CustomizeInit() {
|
431 |
$this->BuildOldMenuTermsAndItems();
|
432 |
-
$this->
|
433 |
}
|
434 |
|
435 |
/**
|
@@ -451,13 +455,13 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
451 |
}
|
452 |
|
453 |
// Deleted Menu.
|
454 |
-
if ( isset( $update_menus ) && isset( $this->
|
455 |
-
$terms = array_diff( array_map( 'serialize', $this->
|
456 |
$terms = array_map( 'unserialize', $terms );
|
457 |
|
458 |
if ( isset( $terms ) && count( $terms ) > 0 ) {
|
459 |
foreach ( $terms as $term ) {
|
460 |
-
$this->plugin->alerts->
|
461 |
2081,
|
462 |
array(
|
463 |
'MenuName' => $term['name'],
|
@@ -479,25 +483,25 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
479 |
$is_occurred_event = false;
|
480 |
$menu = wp_get_nav_menu_object( $value['nav_menu_term_id'] );
|
481 |
$content_name = ! empty( $value['title'] ) ? $value['title'] : 'no title';
|
482 |
-
if ( ! empty( $this->
|
483 |
-
foreach ( $this->
|
484 |
$item_id = substr( trim( $key, ']' ), 14 );
|
485 |
if ( $old_item['item_id'] == $item_id ) {
|
486 |
// Modified Items in the menu.
|
487 |
if ( $old_item['title'] != $content_name ) {
|
488 |
$is_occurred_event = true;
|
489 |
-
$this->
|
490 |
}
|
491 |
// Moved as a sub-item.
|
492 |
if ( $old_item['menu_item_parent'] != $value['menu_item_parent'] && 0 != $value['menu_item_parent'] ) {
|
493 |
$is_occurred_event = true;
|
494 |
-
$parent_name = $this->
|
495 |
-
$this->
|
496 |
}
|
497 |
// Changed order of the objects in a menu.
|
498 |
if ( $old_item['menu_order'] != $value['position'] ) {
|
499 |
$is_occurred_event = true;
|
500 |
-
$this->
|
501 |
}
|
502 |
}
|
503 |
}
|
@@ -505,15 +509,15 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
505 |
// Add Items to the menu.
|
506 |
if ( ! $is_occurred_event ) {
|
507 |
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : $menu->name;
|
508 |
-
$this->
|
509 |
}
|
510 |
} else {
|
511 |
// Menu changed name.
|
512 |
-
if ( isset( $update_menus ) && isset( $this->
|
513 |
-
foreach ( $this->
|
514 |
foreach ( $update_menus as $update_menu ) {
|
515 |
if ( $old_menu['term_id'] == $update_menu['term_id'] && $old_menu['name'] != $update_menu['name'] ) {
|
516 |
-
$this->
|
517 |
}
|
518 |
}
|
519 |
}
|
@@ -521,9 +525,9 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
521 |
// Setting Auto add pages.
|
522 |
if ( ! empty( $value ) && isset( $value['auto_add'] ) ) {
|
523 |
if ( $value['auto_add'] ) {
|
524 |
-
$this->
|
525 |
} else {
|
526 |
-
$this->
|
527 |
}
|
528 |
}
|
529 |
// Setting Location.
|
@@ -532,22 +536,22 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
532 |
if ( ! empty( $value ) ) {
|
533 |
$menu = wp_get_nav_menu_object( $value );
|
534 |
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : ( ! empty( $menu ) ? $menu->name : '' );
|
535 |
-
$this->
|
536 |
} else {
|
537 |
-
if ( ! empty( $this->
|
538 |
-
$menu = wp_get_nav_menu_object( $this->
|
539 |
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : ( ! empty( $menu ) ? $menu->name : '' );
|
540 |
-
$this->
|
541 |
}
|
542 |
}
|
543 |
}
|
544 |
// Remove items from the menu.
|
545 |
if ( false !== strpos( $key, 'nav_menu_item[' ) ) {
|
546 |
$item_id = substr( trim( $key, ']' ), 14 );
|
547 |
-
if ( ! empty( $this->
|
548 |
-
foreach ( $this->
|
549 |
if ( $old_item['item_id'] == $item_id ) {
|
550 |
-
$this->
|
551 |
}
|
552 |
}
|
553 |
}
|
@@ -564,10 +568,11 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
564 |
*
|
565 |
* @param string $content_type - Type of content.
|
566 |
* @param string $content_name - Name of content.
|
567 |
-
* @param string $menu_name
|
|
|
568 |
*/
|
569 |
-
private function
|
570 |
-
$this->plugin->alerts->
|
571 |
2079,
|
572 |
array(
|
573 |
'ContentType' => 'custom' === $content_type ? 'custom link' : $content_type,
|
@@ -583,10 +588,11 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
583 |
*
|
584 |
* @param string $content_type - Type of content.
|
585 |
* @param string $content_name - Name of content.
|
586 |
-
* @param string $menu_name
|
|
|
587 |
*/
|
588 |
-
private function
|
589 |
-
$this->plugin->alerts->
|
590 |
2080,
|
591 |
array(
|
592 |
'ContentType' => 'custom' === $content_type ? 'custom link' : $content_type,
|
@@ -600,13 +606,14 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
600 |
/**
|
601 |
* Changed menu setting.
|
602 |
*
|
603 |
-
* @param string $menu_name
|
604 |
-
* @param string $status
|
605 |
* @param string $menu_setting - Menu setting.
|
|
|
606 |
*/
|
607 |
-
private function
|
608 |
$status = 'Enabled' === $status ? 'enabled' : 'disabled';
|
609 |
-
$this->plugin->alerts->
|
610 |
2082,
|
611 |
array(
|
612 |
'EventType' => $status,
|
@@ -622,10 +629,11 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
622 |
*
|
623 |
* @param string $content_type - Type of content.
|
624 |
* @param string $content_name - Name of content.
|
625 |
-
* @param string $menu_name
|
|
|
626 |
*/
|
627 |
-
private function
|
628 |
-
$this->plugin->alerts->
|
629 |
2083,
|
630 |
array(
|
631 |
'ContentType' => 'custom' === $content_type ? 'custom link' : $content_type,
|
@@ -641,9 +649,10 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
641 |
*
|
642 |
* @param string $old_menu_name - Old Menu Name.
|
643 |
* @param string $new_menu_name - New Menu Name.
|
|
|
644 |
*/
|
645 |
-
private function
|
646 |
-
$this->plugin->alerts->
|
647 |
2084,
|
648 |
array(
|
649 |
'OldMenuName' => $old_menu_name,
|
@@ -658,15 +667,15 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
658 |
*
|
659 |
* @param string $item_name - Item name.
|
660 |
* @param string $menu_name - Menu name.
|
661 |
-
* @param int
|
662 |
*/
|
663 |
-
private function
|
664 |
-
//
|
665 |
-
if ( in_array( $menu_id, $this->order_changed_menu_ids ) ) {
|
666 |
return;
|
667 |
}
|
668 |
|
669 |
-
$this->plugin->alerts->
|
670 |
2085,
|
671 |
array(
|
672 |
'ItemName' => $item_name,
|
@@ -675,20 +684,20 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
675 |
)
|
676 |
);
|
677 |
|
678 |
-
//
|
679 |
array_push( $this->order_changed_menu_ids, $menu_id );
|
680 |
}
|
681 |
|
682 |
/**
|
683 |
* Moved objects as a sub-item.
|
684 |
*
|
685 |
-
* @param string $item_name
|
686 |
* @param string $parent_name - Parent Name.
|
687 |
-
* @param string $menu_name
|
688 |
-
* @param int
|
689 |
*/
|
690 |
-
private function
|
691 |
-
$this->plugin->alerts->
|
692 |
2089,
|
693 |
array(
|
694 |
'ItemName' => $item_name,
|
@@ -707,7 +716,7 @@ class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
|
707 |
*
|
708 |
* @return string
|
709 |
*/
|
710 |
-
private function
|
711 |
$item_name = '';
|
712 |
$menu_items = wp_get_nav_menu_items( $term_id );
|
713 |
foreach ( $menu_items as $menu_item ) {
|
4 |
*
|
5 |
* Menus sensor file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
27 |
* 2085 User changed order of the objects in a menu
|
28 |
* 2089 User moved objects as a sub-item
|
29 |
*
|
30 |
+
* @package wsal
|
31 |
* @subpackage sensors
|
32 |
*/
|
33 |
class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
37 |
*
|
38 |
* @var object
|
39 |
*/
|
40 |
+
protected $old_menu = null;
|
41 |
|
42 |
/**
|
43 |
* Old Menu objects.
|
44 |
*
|
45 |
* @var array
|
46 |
*/
|
47 |
+
protected $old_menu_terms = array();
|
48 |
|
49 |
/**
|
50 |
* Old Menu Items.
|
51 |
*
|
52 |
* @var array
|
53 |
*/
|
54 |
+
protected $old_menu_items = array();
|
55 |
|
56 |
/**
|
57 |
* Old Menu Locations.
|
58 |
*
|
59 |
* @var array
|
60 |
*/
|
61 |
+
protected $old_menu_locations = null;
|
62 |
|
63 |
/**
|
64 |
* An array of menu IDs for which an order change has already been reported during current request.
|
66 |
* @var array
|
67 |
* @since 4.2.0.1
|
68 |
*/
|
69 |
+
protected $order_changed_menu_ids = array();
|
70 |
|
71 |
/**
|
72 |
+
* {@inheritDoc}
|
73 |
*/
|
74 |
+
public function hook_events() {
|
75 |
+
add_action( 'wp_create_nav_menu', array( $this, 'create_menu' ), 10, 2 );
|
76 |
+
add_action( 'wp_delete_nav_menu', array( $this, 'delete_menu' ), 10, 1 );
|
77 |
+
add_action( 'wp_update_nav_menu', array( $this, 'update_menu' ), 10, 2 );
|
78 |
|
79 |
+
add_action( 'wp_update_nav_menu_item', array( $this, 'update_menu_item' ), 10, 3 );
|
80 |
+
add_action( 'admin_menu', array( $this, 'manage_menu_locations' ) );
|
81 |
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
82 |
|
83 |
// Customizer trigger.
|
88 |
/**
|
89 |
* Menu item updated.
|
90 |
*
|
91 |
+
* @param int $menu_id - Menu ID.
|
92 |
+
* @param int $menu_item_db_id - Menu item DB ID.
|
93 |
+
* @param array $args - An array of items used to update menu.
|
94 |
*
|
95 |
* @return boolean
|
96 |
*/
|
97 |
+
public function update_menu_item( $menu_id, $menu_item_db_id, $args ) {
|
98 |
// Filter $_POST global array for security.
|
99 |
$post_array = filter_input_array( INPUT_POST );
|
100 |
|
103 |
$is_changed_order = false;
|
104 |
$is_sub_item = false;
|
105 |
$new_menu_items = array_keys( $post_array['menu-item-title'] );
|
106 |
+
if ( ! empty( $this->old_menu_items ) ) {
|
107 |
+
foreach ( $this->old_menu_items as $old_item ) {
|
108 |
+
if ( $old_item['menu_id'] === $menu_id ) {
|
109 |
$item_id = $old_item['item_id'];
|
110 |
+
if ( $item_id === $menu_item_db_id ) {
|
111 |
+
if ( $old_item['menu_order'] !== $args['menu-item-position'] ) {
|
112 |
$is_changed_order = true;
|
113 |
}
|
114 |
if ( ! empty( $args['menu-item-parent-id'] ) ) {
|
115 |
$is_sub_item = true;
|
116 |
}
|
117 |
+
if ( ! empty( $args['menu-item-title'] ) && $old_item['title'] !== $args['menu-item-title'] ) {
|
118 |
// Verify nonce.
|
119 |
if ( ! wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
120 |
return false;
|
121 |
}
|
122 |
|
123 |
+
$this->event_modified_items( $post_array['menu-item-object'][ $menu_item_db_id ], $post_array['menu-item-title'][ $menu_item_db_id ], $post_array['menu-name'], $menu_id );
|
124 |
}
|
125 |
}
|
126 |
$old_menu_items[ $item_id ] = array(
|
135 |
// Add Items to the menu.
|
136 |
$added_items = array_diff( $new_menu_items, array_keys( $old_menu_items ) );
|
137 |
if ( count( $added_items ) > 0 && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
138 |
+
if ( in_array( $menu_item_db_id, $added_items, true ) ) {
|
139 |
+
$this->event_add_items( $post_array['menu-item-object'][ $menu_item_db_id ], $post_array['menu-item-title'][ $menu_item_db_id ], $post_array['menu-name'], $menu_id );
|
140 |
}
|
141 |
}
|
142 |
|
143 |
// Remove items from the menu.
|
144 |
$removed_items = array_diff( array_keys( $old_menu_items ), $new_menu_items );
|
145 |
if ( count( $removed_items ) > 0 && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
146 |
+
if ( array_search( $menu_item_db_id, $new_menu_items ) == ( count( $new_menu_items ) - 1 ) ) { // phpcs:ignore
|
147 |
foreach ( $removed_items as $removed_item_id ) {
|
148 |
+
$this->event_remove_items( $old_menu_items[ $removed_item_id ]['type'], $old_menu_items[ $removed_item_id ]['title'], $post_array['menu-name'], $menu_id );
|
149 |
}
|
150 |
}
|
151 |
}
|
152 |
|
153 |
+
// We want to ignore order changes when menu items are added, removed or another order change has already
|
154 |
+
// been logged during this request.
|
155 |
$ignore_order_change = ! empty( $removed_items ) || ! empty( $added_items );
|
156 |
|
157 |
+
// Check if an order has changed.
|
158 |
if ( ! $ignore_order_change && $is_changed_order && wp_verify_nonce( $post_array['meta-box-order-nonce'], 'meta-box-order' ) ) {
|
159 |
$old_item = $old_menu_items[ $menu_item_db_id ];
|
160 |
$menu_object = wp_get_nav_menu_object( $menu_id );
|
161 |
if ( $menu_object instanceof WP_Term ) {
|
162 |
+
$this->event_change_order( $old_item['title'], $menu_object->name, $menu_id );
|
163 |
}
|
164 |
}
|
165 |
|
166 |
if ( $is_sub_item && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
167 |
$item_parent_id = $args['menu-item-parent-id'];
|
168 |
$item_name = $old_menu_items[ $menu_item_db_id ]['title'];
|
169 |
+
if ( $old_menu_items[ $menu_item_db_id ]['parent'] !== $item_parent_id ) {
|
170 |
$parent_name = isset( $old_menu_items[ $item_parent_id ]['title'] ) ? $old_menu_items[ $item_parent_id ]['title'] : false;
|
171 |
+
$this->event_change_sub_item( $item_name, $parent_name, $post_array['menu-name'], $menu_id );
|
172 |
}
|
173 |
}
|
174 |
}
|
180 |
* @param int $term_id - Term ID.
|
181 |
* @param array $menu_data - Menu data.
|
182 |
*/
|
183 |
+
public function create_menu( $term_id, $menu_data ) {
|
184 |
+
$this->plugin->alerts->trigger_event(
|
185 |
2078,
|
186 |
array(
|
187 |
'MenuName' => $menu_data['menu-name'],
|
195 |
*
|
196 |
* @global array $_POST Data post.
|
197 |
*/
|
198 |
+
public function manage_menu_locations() {
|
199 |
// Filter $_POST global array for security.
|
200 |
$post_array = filter_input_array( INPUT_POST );
|
201 |
|
208 |
if ( isset( $post_array['menu-locations'] ) ) {
|
209 |
$new_locations = $post_array['menu-locations'];
|
210 |
if ( isset( $new_locations['top'] ) ) {
|
211 |
+
$this->location_setting( $new_locations['top'], 'top' );
|
212 |
}
|
213 |
if ( isset( $new_locations['social'] ) ) {
|
214 |
+
$this->location_setting( $new_locations['social'], 'social' );
|
215 |
}
|
216 |
}
|
217 |
}
|
222 |
* @param integer $new_location - New location.
|
223 |
* @param string $type - Location type.
|
224 |
*/
|
225 |
+
private function location_setting( $new_location, $type ) {
|
226 |
$old_locations = get_nav_menu_locations();
|
227 |
+
if ( 0 != $new_location ) { // phpcs:ignore
|
228 |
$menu = wp_get_nav_menu_object( $new_location );
|
229 |
+
if ( isset( $old_locations[ $type ] ) && $old_locations[ $type ] != $new_location ) { // phpcs:ignore
|
230 |
+
$this->event_menu_setting( $menu->name, 'Enabled', 'Location: ' . $type . ' menu' );
|
231 |
}
|
232 |
} else {
|
233 |
if ( ! empty( $old_locations[ $type ] ) ) {
|
234 |
$menu = wp_get_nav_menu_object( $old_locations[ $type ] );
|
235 |
+
$this->event_menu_setting( $menu->name, 'Disabled', 'Location: ' . $type . ' menu' );
|
236 |
}
|
237 |
}
|
238 |
}
|
242 |
*
|
243 |
* @param int $term_id - Term ID.
|
244 |
*/
|
245 |
+
public function delete_menu( $term_id ) {
|
246 |
+
if ( $this->old_menu ) {
|
247 |
+
$this->plugin->alerts->trigger_event(
|
248 |
2081,
|
249 |
array(
|
250 |
+
'MenuName' => $this->old_menu->name,
|
251 |
'MenuID' => $term_id,
|
252 |
)
|
253 |
);
|
259 |
*
|
260 |
* @param int $menu_id - Menu ID.
|
261 |
* @param array $menu_data (Optional) Menu data.
|
262 |
+
*
|
263 |
+
* phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
|
264 |
+
* phpcs:disable WordPress.PHP.StrictInArray.MissingTrueStrict
|
265 |
*/
|
266 |
+
public function update_menu( $menu_id, $menu_data = null ) {
|
267 |
if ( ! empty( $menu_data ) ) {
|
268 |
$content_names_old = array();
|
269 |
$content_types_old = array();
|
282 |
$post_array = filter_input_array( INPUT_POST );
|
283 |
|
284 |
// Menu changed name.
|
285 |
+
if ( ! empty( $this->old_menu_terms ) && isset( $post_array['menu'] ) && isset( $post_array['menu-name'] ) ) {
|
286 |
+
foreach ( $this->old_menu_terms as $old_menu_term ) {
|
287 |
if ( $old_menu_term['term_id'] == $post_array['menu'] && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
288 |
+
if ( $old_menu_term['name'] !== $post_array['menu-name'] ) {
|
289 |
+
$this->event_change_name( $old_menu_term['name'], $post_array['menu-name'], $menu_id );
|
290 |
} else {
|
291 |
+
// Remove the last menu item.
|
292 |
if ( count( $content_names_old ) == 1 && count( $content_types_old ) == 1 ) {
|
293 |
+
$this->event_remove_items( $content_types_old[0], $content_names_old[0], $post_array['menu-name'], $menu_id );
|
294 |
}
|
295 |
}
|
296 |
}
|
318 |
|
319 |
// Alert 2082 Auto add pages.
|
320 |
if ( ! empty( $auto_add ) ) {
|
321 |
+
$this->event_menu_setting( $menu_data['menu-name'], $auto_add, 'Auto add pages', $menu_id );
|
322 |
}
|
323 |
|
324 |
$nav_menu_locations = get_nav_menu_locations();
|
325 |
|
326 |
$location_top = null;
|
327 |
+
if ( isset( $this->old_menu_locations['top'] ) && isset( $nav_menu_locations['top'] ) ) {
|
328 |
+
if ( $nav_menu_locations['top'] == $menu_id && $this->old_menu_locations['top'] != $nav_menu_locations['top'] ) {
|
329 |
$location_top = 'Enabled';
|
330 |
}
|
331 |
+
} elseif ( empty( $this->old_menu_locations['top'] ) && isset( $nav_menu_locations['top'] ) ) {
|
332 |
if ( $nav_menu_locations['top'] == $menu_id ) {
|
333 |
$location_top = 'Enabled';
|
334 |
}
|
335 |
+
} elseif ( isset( $this->old_menu_locations['top'] ) && empty( $nav_menu_locations['top'] ) ) {
|
336 |
+
if ( $this->old_menu_locations['top'] == $menu_id ) {
|
337 |
$location_top = 'Disabled';
|
338 |
}
|
339 |
}
|
340 |
|
341 |
// Alert 2082 top menu.
|
342 |
if ( ! empty( $location_top ) ) {
|
343 |
+
$this->event_menu_setting( $menu_data['menu-name'], $location_top, 'Location: top menu', $menu_id );
|
344 |
}
|
345 |
|
346 |
$location_social = null;
|
347 |
+
if ( isset( $this->old_menu_locations['social'] ) && isset( $nav_menu_locations['social'] ) ) {
|
348 |
+
if ( $nav_menu_locations['social'] == $menu_id && $this->old_menu_locations['social'] != $nav_menu_locations['social'] ) {
|
349 |
$location_social = 'Enabled';
|
350 |
}
|
351 |
+
} elseif ( empty( $this->old_menu_locations['social'] ) && isset( $nav_menu_locations['social'] ) ) {
|
352 |
if ( $nav_menu_locations['social'] == $menu_id ) {
|
353 |
$location_social = 'Enabled';
|
354 |
}
|
355 |
+
} elseif ( isset( $this->old_menu_locations['social'] ) && empty( $nav_menu_locations['social'] ) ) {
|
356 |
+
if ( $this->old_menu_locations['social'] == $menu_id ) {
|
357 |
$location_social = 'Disabled';
|
358 |
}
|
359 |
}
|
360 |
|
361 |
// Alert 2082 Social links menu.
|
362 |
if ( ! empty( $location_social ) ) {
|
363 |
+
$this->event_menu_setting( $menu_data['menu-name'], $location_social, 'Location: social menu', $menu_id );
|
364 |
}
|
365 |
}
|
366 |
}
|
373 |
if ( ! empty( $menus ) ) {
|
374 |
foreach ( $menus as $menu ) {
|
375 |
array_push(
|
376 |
+
$this->old_menu_terms,
|
377 |
array(
|
378 |
'term_id' => $menu->term_id,
|
379 |
'name' => $menu->name,
|
383 |
if ( ! empty( $items ) ) {
|
384 |
foreach ( $items as $item ) {
|
385 |
array_push(
|
386 |
+
$this->old_menu_items,
|
387 |
array(
|
388 |
'menu_id' => $menu->term_id,
|
389 |
'item_id' => $item->ID,
|
419 |
if ( $is_nav_menu ) {
|
420 |
if ( isset( $get_array['action'] ) && 'delete' == $get_array['action'] ) {
|
421 |
if ( isset( $get_array['menu'] ) ) {
|
422 |
+
$this->old_menu = wp_get_nav_menu_object( $get_array['menu'] );
|
423 |
}
|
424 |
} else {
|
425 |
$this->BuildOldMenuTermsAndItems();
|
426 |
}
|
427 |
+
$this->old_menu_locations = get_nav_menu_locations();
|
428 |
}
|
429 |
}
|
430 |
|
433 |
*/
|
434 |
public function CustomizeInit() {
|
435 |
$this->BuildOldMenuTermsAndItems();
|
436 |
+
$this->old_menu_locations = get_nav_menu_locations();
|
437 |
}
|
438 |
|
439 |
/**
|
455 |
}
|
456 |
|
457 |
// Deleted Menu.
|
458 |
+
if ( isset( $update_menus ) && isset( $this->old_menu_terms ) ) {
|
459 |
+
$terms = array_diff( array_map( 'serialize', $this->old_menu_terms ), array_map( 'serialize', $update_menus ) );
|
460 |
$terms = array_map( 'unserialize', $terms );
|
461 |
|
462 |
if ( isset( $terms ) && count( $terms ) > 0 ) {
|
463 |
foreach ( $terms as $term ) {
|
464 |
+
$this->plugin->alerts->trigger_event(
|
465 |
2081,
|
466 |
array(
|
467 |
'MenuName' => $term['name'],
|
483 |
$is_occurred_event = false;
|
484 |
$menu = wp_get_nav_menu_object( $value['nav_menu_term_id'] );
|
485 |
$content_name = ! empty( $value['title'] ) ? $value['title'] : 'no title';
|
486 |
+
if ( ! empty( $this->old_menu_items ) ) {
|
487 |
+
foreach ( $this->old_menu_items as $old_item ) {
|
488 |
$item_id = substr( trim( $key, ']' ), 14 );
|
489 |
if ( $old_item['item_id'] == $item_id ) {
|
490 |
// Modified Items in the menu.
|
491 |
if ( $old_item['title'] != $content_name ) {
|
492 |
$is_occurred_event = true;
|
493 |
+
$this->event_modified_items( $value['type_label'], $content_name, $menu->name, $menu->term_id );
|
494 |
}
|
495 |
// Moved as a sub-item.
|
496 |
if ( $old_item['menu_item_parent'] != $value['menu_item_parent'] && 0 != $value['menu_item_parent'] ) {
|
497 |
$is_occurred_event = true;
|
498 |
+
$parent_name = $this->get_item_name( $value['nav_menu_term_id'], $value['menu_item_parent'] );
|
499 |
+
$this->event_change_sub_item( $content_name, $parent_name, $menu->name, $menu->term_id );
|
500 |
}
|
501 |
// Changed order of the objects in a menu.
|
502 |
if ( $old_item['menu_order'] != $value['position'] ) {
|
503 |
$is_occurred_event = true;
|
504 |
+
$this->event_change_order( $content_name, $menu->name, $menu->term_id );
|
505 |
}
|
506 |
}
|
507 |
}
|
509 |
// Add Items to the menu.
|
510 |
if ( ! $is_occurred_event ) {
|
511 |
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : $menu->name;
|
512 |
+
$this->event_add_items( $value['type_label'], $content_name, $menu_name, $menu->term_id );
|
513 |
}
|
514 |
} else {
|
515 |
// Menu changed name.
|
516 |
+
if ( isset( $update_menus ) && isset( $this->old_menu_terms ) ) {
|
517 |
+
foreach ( $this->old_menu_terms as $old_menu ) {
|
518 |
foreach ( $update_menus as $update_menu ) {
|
519 |
if ( $old_menu['term_id'] == $update_menu['term_id'] && $old_menu['name'] != $update_menu['name'] ) {
|
520 |
+
$this->event_change_name( $old_menu['name'], $update_menu['name'], $menu->term_id );
|
521 |
}
|
522 |
}
|
523 |
}
|
525 |
// Setting Auto add pages.
|
526 |
if ( ! empty( $value ) && isset( $value['auto_add'] ) ) {
|
527 |
if ( $value['auto_add'] ) {
|
528 |
+
$this->event_menu_setting( $value['name'], 'Enabled', 'Auto add pages', $menu->term_id );
|
529 |
} else {
|
530 |
+
$this->event_menu_setting( $value['name'], 'Disabled', 'Auto add pages', $menu->term_id );
|
531 |
}
|
532 |
}
|
533 |
// Setting Location.
|
536 |
if ( ! empty( $value ) ) {
|
537 |
$menu = wp_get_nav_menu_object( $value );
|
538 |
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : ( ! empty( $menu ) ? $menu->name : '' );
|
539 |
+
$this->event_menu_setting( $menu_name, 'Enabled', 'Location: ' . $loc . ' menu', $menu->term_id );
|
540 |
} else {
|
541 |
+
if ( ! empty( $this->old_menu_locations[ $loc ] ) ) {
|
542 |
+
$menu = wp_get_nav_menu_object( $this->old_menu_locations[ $loc ] );
|
543 |
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : ( ! empty( $menu ) ? $menu->name : '' );
|
544 |
+
$this->event_menu_setting( $menu_name, 'Disabled', 'Location: ' . $loc . ' menu', $menu->term_id );
|
545 |
}
|
546 |
}
|
547 |
}
|
548 |
// Remove items from the menu.
|
549 |
if ( false !== strpos( $key, 'nav_menu_item[' ) ) {
|
550 |
$item_id = substr( trim( $key, ']' ), 14 );
|
551 |
+
if ( ! empty( $this->old_menu_items ) ) {
|
552 |
+
foreach ( $this->old_menu_items as $old_item ) {
|
553 |
if ( $old_item['item_id'] == $item_id ) {
|
554 |
+
$this->event_remove_items( $old_item['object'], $old_item['title'], $old_item['menu_name'], $menu->term_id );
|
555 |
}
|
556 |
}
|
557 |
}
|
568 |
*
|
569 |
* @param string $content_type - Type of content.
|
570 |
* @param string $content_name - Name of content.
|
571 |
+
* @param string $menu_name - Menu name.
|
572 |
+
* @param int $menu_id - Menu ID.
|
573 |
*/
|
574 |
+
private function event_add_items( $content_type, $content_name, $menu_name, $menu_id ) {
|
575 |
+
$this->plugin->alerts->trigger_event(
|
576 |
2079,
|
577 |
array(
|
578 |
'ContentType' => 'custom' === $content_type ? 'custom link' : $content_type,
|
588 |
*
|
589 |
* @param string $content_type - Type of content.
|
590 |
* @param string $content_name - Name of content.
|
591 |
+
* @param string $menu_name - Menu name.
|
592 |
+
* @param int $menu_id - Menu ID.
|
593 |
*/
|
594 |
+
private function event_remove_items( $content_type, $content_name, $menu_name, $menu_id ) {
|
595 |
+
$this->plugin->alerts->trigger_event(
|
596 |
2080,
|
597 |
array(
|
598 |
'ContentType' => 'custom' === $content_type ? 'custom link' : $content_type,
|
606 |
/**
|
607 |
* Changed menu setting.
|
608 |
*
|
609 |
+
* @param string $menu_name - Menu Name.
|
610 |
+
* @param string $status - Status of menu.
|
611 |
* @param string $menu_setting - Menu setting.
|
612 |
+
* @param int $menu_id - Menu ID.
|
613 |
*/
|
614 |
+
private function event_menu_setting( $menu_name, $status, $menu_setting, $menu_id ) {
|
615 |
$status = 'Enabled' === $status ? 'enabled' : 'disabled';
|
616 |
+
$this->plugin->alerts->trigger_event(
|
617 |
2082,
|
618 |
array(
|
619 |
'EventType' => $status,
|
629 |
*
|
630 |
* @param string $content_type - Type of content.
|
631 |
* @param string $content_name - Name of content.
|
632 |
+
* @param string $menu_name - Menu name.
|
633 |
+
* @param int $menu_id - Menu ID.
|
634 |
*/
|
635 |
+
private function event_modified_items( $content_type, $content_name, $menu_name, $menu_id ) {
|
636 |
+
$this->plugin->alerts->trigger_event(
|
637 |
2083,
|
638 |
array(
|
639 |
'ContentType' => 'custom' === $content_type ? 'custom link' : $content_type,
|
649 |
*
|
650 |
* @param string $old_menu_name - Old Menu Name.
|
651 |
* @param string $new_menu_name - New Menu Name.
|
652 |
+
* @param int $menu_id Menu ID.
|
653 |
*/
|
654 |
+
private function event_change_name( $old_menu_name, $new_menu_name, $menu_id ) {
|
655 |
+
$this->plugin->alerts->trigger_event(
|
656 |
2084,
|
657 |
array(
|
658 |
'OldMenuName' => $old_menu_name,
|
667 |
*
|
668 |
* @param string $item_name - Item name.
|
669 |
* @param string $menu_name - Menu name.
|
670 |
+
* @param int $menu_id - Menu ID.
|
671 |
*/
|
672 |
+
private function event_change_order( $item_name, $menu_name, $menu_id ) {
|
673 |
+
// Skip if an order change for this menu has already been reported during the current request.
|
674 |
+
if ( in_array( $menu_id, $this->order_changed_menu_ids ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
675 |
return;
|
676 |
}
|
677 |
|
678 |
+
$this->plugin->alerts->trigger_event(
|
679 |
2085,
|
680 |
array(
|
681 |
'ItemName' => $item_name,
|
684 |
)
|
685 |
);
|
686 |
|
687 |
+
// Keep track of already reported order changes to prevent repetitive events.
|
688 |
array_push( $this->order_changed_menu_ids, $menu_id );
|
689 |
}
|
690 |
|
691 |
/**
|
692 |
* Moved objects as a sub-item.
|
693 |
*
|
694 |
+
* @param string $item_name - Item name.
|
695 |
* @param string $parent_name - Parent Name.
|
696 |
+
* @param string $menu_name - Menu Name.
|
697 |
+
* @param int $menu_id - Menu ID.
|
698 |
*/
|
699 |
+
private function event_change_sub_item( $item_name, $parent_name, $menu_name, $menu_id ) {
|
700 |
+
$this->plugin->alerts->trigger_event(
|
701 |
2089,
|
702 |
array(
|
703 |
'ItemName' => $item_name,
|
716 |
*
|
717 |
* @return string
|
718 |
*/
|
719 |
+
private function get_item_name( $term_id, $item_id ) {
|
720 |
$item_name = '';
|
721 |
$menu_items = wp_get_nav_menu_items( $term_id );
|
722 |
foreach ( $menu_items as $menu_item ) {
|
classes/Sensors/MetaData.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Meta Data sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -27,9 +28,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
27 |
* 4019 User changed nickname for a user
|
28 |
* 4020 User changed the display name for a user
|
29 |
*
|
30 |
-
* @package
|
31 |
* @subpackage sensors
|
32 |
-
* @since
|
33 |
*/
|
34 |
class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
35 |
|
@@ -43,11 +44,11 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
43 |
/**
|
44 |
* Listening to events using WP hooks.
|
45 |
*/
|
46 |
-
public function
|
47 |
-
add_action( 'add_post_meta', array( $this, '
|
48 |
-
add_action( 'update_post_meta', array( $this, '
|
49 |
-
add_action( 'updated_post_meta', array( $this, '
|
50 |
-
add_action( 'deleted_post_meta', array( $this, '
|
51 |
add_action( 'save_post', array( $this, 'reset_null_meta_counter' ), 10 );
|
52 |
add_action( 'add_user_meta', array( $this, 'event_user_meta_created' ), 10, 3 );
|
53 |
add_action( 'update_user_meta', array( $this, 'event_user_meta_updating' ), 10, 3 );
|
@@ -62,8 +63,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
62 |
* @param string $meta_key - Meta key.
|
63 |
* @param mixed $meta_value - Meta value.
|
64 |
*/
|
65 |
-
public function
|
66 |
-
if ( ! $this->
|
67 |
return;
|
68 |
}
|
69 |
|
@@ -82,8 +83,9 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
82 |
}
|
83 |
|
84 |
// Remove WC coupons from ignored array.
|
85 |
-
|
86 |
-
|
|
|
87 |
}
|
88 |
|
89 |
// Ignore post types we are not interested in.
|
@@ -110,8 +112,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
110 |
$log_meta_event = apply_filters( 'wsal_before_post_meta_create_event', true, $meta_key, $meta_value, $post );
|
111 |
|
112 |
if ( $log_meta_event ) {
|
113 |
-
$editor_link = $this->
|
114 |
-
$this->plugin->alerts->
|
115 |
2053,
|
116 |
array(
|
117 |
'PostID' => $object_id,
|
@@ -136,7 +138,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
136 |
* @param int $object_id - Object ID.
|
137 |
* @param string $meta_key - Meta key.
|
138 |
*/
|
139 |
-
public function
|
140 |
static $meta_type = 'post';
|
141 |
$meta = get_metadata_by_mid( $meta_type, $meta_id );
|
142 |
|
@@ -154,8 +156,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
154 |
* @param string $meta_key - Meta key.
|
155 |
* @param mixed $meta_value - Meta value.
|
156 |
*/
|
157 |
-
public function
|
158 |
-
if ( ! $this->
|
159 |
return;
|
160 |
}
|
161 |
|
@@ -178,7 +180,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
178 |
*
|
179 |
* @param int $meta_id - Meta ID.
|
180 |
* @param int $object_id - Post ID.
|
181 |
-
* @param array $this->old_meta - Array of
|
182 |
* @param string $meta_key - Meta key.
|
183 |
* @param mixed $meta_value - Meta value.
|
184 |
* @since 3.2.2
|
@@ -192,21 +194,21 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
192 |
* Runs before logging events for post meta updated i.e. 2054 or 2062.
|
193 |
* This filter can be used as check to whether log these events or not.
|
194 |
*
|
195 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
196 |
*
|
197 |
-
* @
|
198 |
-
* @param string $meta_key - Meta key.
|
199 |
-
* @param mixed $meta_value - Meta value.
|
200 |
-
* @param stdClass $this->old_meta[ $meta_id ] - Old meta value and key object.
|
201 |
-
* @param WP_Post $post - Post object.
|
202 |
-
* @param integer $meta_id - Meta ID.
|
203 |
*/
|
204 |
$log_meta_event = apply_filters( 'wsal_before_post_meta_update_event', true, $meta_key, $meta_value, $this->old_meta[ $meta_id ], $post, $meta_id );
|
205 |
|
206 |
// Check change in meta key.
|
207 |
if ( $log_meta_event && $this->old_meta[ $meta_id ]->key !== $meta_key ) {
|
208 |
-
$editor_link = $this->
|
209 |
-
$this->plugin->alerts->
|
210 |
2062,
|
211 |
array(
|
212 |
'PostID' => $object_id,
|
@@ -224,8 +226,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
224 |
)
|
225 |
);
|
226 |
} elseif ( $log_meta_event && $this->old_meta[ $meta_id ]->val !== $meta_value ) { // Check change in meta value.
|
227 |
-
$editor_link = $this->
|
228 |
-
$this->plugin->alerts->
|
229 |
2054,
|
230 |
array(
|
231 |
'PostID' => $object_id,
|
@@ -242,13 +244,14 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
242 |
$editor_link['name'] => $editor_link['value'],
|
243 |
),
|
244 |
/**
|
245 |
-
*
|
|
|
|
|
246 |
* @return bool
|
247 |
*/
|
248 |
function ( $manager ) {
|
249 |
-
|
250 |
-
|
251 |
-
&& ! $manager->WillOrHasTriggered( 2132 );
|
252 |
}
|
253 |
);
|
254 |
}
|
@@ -265,7 +268,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
265 |
* @param string $meta_key - Meta key.
|
266 |
* @param mixed $meta_value - Meta value.
|
267 |
*/
|
268 |
-
public function
|
269 |
// If meta key starts with "_" then return.
|
270 |
if ( '_' === substr( $meta_key, 0, 1 ) ) {
|
271 |
return;
|
@@ -279,9 +282,9 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
279 |
return;
|
280 |
}
|
281 |
|
282 |
-
$editor_link = $this->
|
283 |
foreach ( $meta_ids as $meta_id ) {
|
284 |
-
if ( ! $this->
|
285 |
continue;
|
286 |
}
|
287 |
|
@@ -311,8 +314,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
311 |
continue;
|
312 |
}
|
313 |
|
314 |
-
if( 'trash' !== $post->post_status ) {
|
315 |
-
$this->plugin->alerts->
|
316 |
2055,
|
317 |
array(
|
318 |
'PostID' => $object_id,
|
@@ -349,7 +352,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
349 |
*/
|
350 |
public function event_user_meta_created( $object_id, $meta_key, $meta_value ) {
|
351 |
// Check to see if we can log the meta key.
|
352 |
-
if ( ! $this->
|
353 |
return;
|
354 |
}
|
355 |
|
@@ -366,7 +369,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
366 |
// Get user.
|
367 |
$user = get_user_by( 'ID', $object_id );
|
368 |
|
369 |
-
$this->plugin->alerts->
|
370 |
4016,
|
371 |
array(
|
372 |
'TargetUsername' => $user->user_login,
|
@@ -409,7 +412,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
409 |
*/
|
410 |
public function event_user_meta_updated( $meta_id, $object_id, $meta_key, $meta_value ) {
|
411 |
// Check to see if we can log the meta key.
|
412 |
-
if ( ! $this->
|
413 |
return;
|
414 |
}
|
415 |
|
@@ -427,7 +430,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
427 |
if ( isset( $this->old_meta[ $meta_id ] ) && ! in_array( $meta_key, $username_meta, true ) ) {
|
428 |
// Check change in meta value.
|
429 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
430 |
-
$this->plugin->alerts->
|
431 |
4015,
|
432 |
array(
|
433 |
'TargetUsername' => $user->user_login,
|
@@ -450,7 +453,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
450 |
switch ( $meta_key ) {
|
451 |
case 'first_name':
|
452 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
453 |
-
$this->plugin->alerts->
|
454 |
4017,
|
455 |
array(
|
456 |
'TargetUsername' => $user->user_login,
|
@@ -468,7 +471,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
468 |
|
469 |
case 'last_name':
|
470 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
471 |
-
$this->plugin->alerts->
|
472 |
4018,
|
473 |
array(
|
474 |
'TargetUsername' => $user->user_login,
|
@@ -485,7 +488,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
485 |
|
486 |
case 'nickname':
|
487 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
488 |
-
$this->plugin->alerts->
|
489 |
4019,
|
490 |
array(
|
491 |
'TargetUsername' => $user->user_login,
|
@@ -514,8 +517,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
514 |
* @return bool
|
515 |
* @since 3.2.3
|
516 |
*/
|
517 |
-
public function must_not_contain_role_changes(
|
518 |
-
return ! $manager->
|
519 |
}
|
520 |
|
521 |
/**
|
@@ -526,8 +529,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
|
526 |
* @return bool
|
527 |
* @since 3.2.3
|
528 |
*/
|
529 |
-
public function must_not_contain_new_user_alert(
|
530 |
-
return ! $manager->
|
531 |
}
|
532 |
|
533 |
/**
|
4 |
*
|
5 |
* Meta Data sensor file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
28 |
* 4019 User changed nickname for a user
|
29 |
* 4020 User changed the display name for a user
|
30 |
*
|
31 |
+
* @package wsal
|
32 |
* @subpackage sensors
|
33 |
+
* @since 1.0.0
|
34 |
*/
|
35 |
class WSAL_Sensors_MetaData extends WSAL_AbstractMetaDataSensor {
|
36 |
|
44 |
/**
|
45 |
* Listening to events using WP hooks.
|
46 |
*/
|
47 |
+
public function hook_events() {
|
48 |
+
add_action( 'add_post_meta', array( $this, 'event_post_meta_created' ), 10, 3 );
|
49 |
+
add_action( 'update_post_meta', array( $this, 'event_post_meta_updating' ), 10, 3 );
|
50 |
+
add_action( 'updated_post_meta', array( $this, 'event_post_meta_updated' ), 10, 4 );
|
51 |
+
add_action( 'deleted_post_meta', array( $this, 'event_post_meta_deleted' ), 10, 4 );
|
52 |
add_action( 'save_post', array( $this, 'reset_null_meta_counter' ), 10 );
|
53 |
add_action( 'add_user_meta', array( $this, 'event_user_meta_created' ), 10, 3 );
|
54 |
add_action( 'update_user_meta', array( $this, 'event_user_meta_updating' ), 10, 3 );
|
63 |
* @param string $meta_key - Meta key.
|
64 |
* @param mixed $meta_value - Meta value.
|
65 |
*/
|
66 |
+
public function event_post_meta_created( $object_id, $meta_key, $meta_value ) {
|
67 |
+
if ( ! $this->can_log_meta_key( 'post', $object_id, $meta_key ) || is_array( $meta_value ) ) {
|
68 |
return;
|
69 |
}
|
70 |
|
83 |
}
|
84 |
|
85 |
// Remove WC coupons from ignored array.
|
86 |
+
$key = array_search( 'shop_coupon', $this->plugin->alerts->ignored_cpts ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
87 |
+
if ( false !== $key ) {
|
88 |
+
unset( $this->plugin->alerts->ignored_cpts[ $key ] );
|
89 |
}
|
90 |
|
91 |
// Ignore post types we are not interested in.
|
112 |
$log_meta_event = apply_filters( 'wsal_before_post_meta_create_event', true, $meta_key, $meta_value, $post );
|
113 |
|
114 |
if ( $log_meta_event ) {
|
115 |
+
$editor_link = $this->get_editor_link( $post );
|
116 |
+
$this->plugin->alerts->trigger_event(
|
117 |
2053,
|
118 |
array(
|
119 |
'PostID' => $object_id,
|
138 |
* @param int $object_id - Object ID.
|
139 |
* @param string $meta_key - Meta key.
|
140 |
*/
|
141 |
+
public function event_post_meta_updating( $meta_id, $object_id, $meta_key ) {
|
142 |
static $meta_type = 'post';
|
143 |
$meta = get_metadata_by_mid( $meta_type, $meta_id );
|
144 |
|
156 |
* @param string $meta_key - Meta key.
|
157 |
* @param mixed $meta_value - Meta value.
|
158 |
*/
|
159 |
+
public function event_post_meta_updated( $meta_id, $object_id, $meta_key, $meta_value ) {
|
160 |
+
if ( ! $this->can_log_meta_key( 'post', $object_id, $meta_key ) || is_array( $meta_value ) ) {
|
161 |
return;
|
162 |
}
|
163 |
|
180 |
*
|
181 |
* @param int $meta_id - Meta ID.
|
182 |
* @param int $object_id - Post ID.
|
183 |
+
* @param array $this->old_meta - Array of metadata holding keys & values of old metadata before updating the current post.
|
184 |
* @param string $meta_key - Meta key.
|
185 |
* @param mixed $meta_value - Meta value.
|
186 |
* @since 3.2.2
|
194 |
* Runs before logging events for post meta updated i.e. 2054 or 2062.
|
195 |
* This filter can be used as check to whether log these events or not.
|
196 |
*
|
197 |
+
* @param bool $log_event - True if log meta event 2054 or 2062, false if not.
|
198 |
+
* @param string $meta_key - Meta key.
|
199 |
+
* @param mixed $meta_value - Meta value.
|
200 |
+
* @param stdClass $old_meta - Old meta value and key object.
|
201 |
+
* @param WP_Post $post - Post object.
|
202 |
+
* @param integer $meta_id - Meta ID.
|
203 |
*
|
204 |
+
* @since 3.3.1
|
|
|
|
|
|
|
|
|
|
|
205 |
*/
|
206 |
$log_meta_event = apply_filters( 'wsal_before_post_meta_update_event', true, $meta_key, $meta_value, $this->old_meta[ $meta_id ], $post, $meta_id );
|
207 |
|
208 |
// Check change in meta key.
|
209 |
if ( $log_meta_event && $this->old_meta[ $meta_id ]->key !== $meta_key ) {
|
210 |
+
$editor_link = $this->get_editor_link( $post );
|
211 |
+
$this->plugin->alerts->trigger_event(
|
212 |
2062,
|
213 |
array(
|
214 |
'PostID' => $object_id,
|
226 |
)
|
227 |
);
|
228 |
} elseif ( $log_meta_event && $this->old_meta[ $meta_id ]->val !== $meta_value ) { // Check change in meta value.
|
229 |
+
$editor_link = $this->get_editor_link( $post );
|
230 |
+
$this->plugin->alerts->trigger_event_if(
|
231 |
2054,
|
232 |
array(
|
233 |
'PostID' => $object_id,
|
244 |
$editor_link['name'] => $editor_link['value'],
|
245 |
),
|
246 |
/**
|
247 |
+
* Don't fire if there's already an event 2131 or 2132 (ACF relationship change).
|
248 |
+
*
|
249 |
+
* @param WSAL_AlertManager $manager
|
250 |
* @return bool
|
251 |
*/
|
252 |
function ( $manager ) {
|
253 |
+
return ! $manager->will_or_has_triggered( 2131 )
|
254 |
+
&& ! $manager->will_or_has_triggered( 2132 );
|
|
|
255 |
}
|
256 |
);
|
257 |
}
|
268 |
* @param string $meta_key - Meta key.
|
269 |
* @param mixed $meta_value - Meta value.
|
270 |
*/
|
271 |
+
public function event_post_meta_deleted( $meta_ids, $object_id, $meta_key, $meta_value ) {
|
272 |
// If meta key starts with "_" then return.
|
273 |
if ( '_' === substr( $meta_key, 0, 1 ) ) {
|
274 |
return;
|
282 |
return;
|
283 |
}
|
284 |
|
285 |
+
$editor_link = $this->get_editor_link( $post );
|
286 |
foreach ( $meta_ids as $meta_id ) {
|
287 |
+
if ( ! $this->can_log_meta_key( 'post', $object_id, $meta_key ) ) {
|
288 |
continue;
|
289 |
}
|
290 |
|
314 |
continue;
|
315 |
}
|
316 |
|
317 |
+
if ( 'trash' !== $post->post_status ) {
|
318 |
+
$this->plugin->alerts->trigger_event(
|
319 |
2055,
|
320 |
array(
|
321 |
'PostID' => $object_id,
|
352 |
*/
|
353 |
public function event_user_meta_created( $object_id, $meta_key, $meta_value ) {
|
354 |
// Check to see if we can log the meta key.
|
355 |
+
if ( ! $this->can_log_meta_key( 'user', $object_id, $meta_key ) || is_array( $meta_value ) ) {
|
356 |
return;
|
357 |
}
|
358 |
|
369 |
// Get user.
|
370 |
$user = get_user_by( 'ID', $object_id );
|
371 |
|
372 |
+
$this->plugin->alerts->trigger_event_if(
|
373 |
4016,
|
374 |
array(
|
375 |
'TargetUsername' => $user->user_login,
|
412 |
*/
|
413 |
public function event_user_meta_updated( $meta_id, $object_id, $meta_key, $meta_value ) {
|
414 |
// Check to see if we can log the meta key.
|
415 |
+
if ( ! $this->can_log_meta_key( 'user', $object_id, $meta_key ) || is_array( $meta_value ) ) {
|
416 |
return;
|
417 |
}
|
418 |
|
430 |
if ( isset( $this->old_meta[ $meta_id ] ) && ! in_array( $meta_key, $username_meta, true ) ) {
|
431 |
// Check change in meta value.
|
432 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
433 |
+
$this->plugin->alerts->trigger_event_if(
|
434 |
4015,
|
435 |
array(
|
436 |
'TargetUsername' => $user->user_login,
|
453 |
switch ( $meta_key ) {
|
454 |
case 'first_name':
|
455 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
456 |
+
$this->plugin->alerts->trigger_event(
|
457 |
4017,
|
458 |
array(
|
459 |
'TargetUsername' => $user->user_login,
|
471 |
|
472 |
case 'last_name':
|
473 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
474 |
+
$this->plugin->alerts->trigger_event(
|
475 |
4018,
|
476 |
array(
|
477 |
'TargetUsername' => $user->user_login,
|
488 |
|
489 |
case 'nickname':
|
490 |
if ( $this->old_meta[ $meta_id ]->val !== $meta_value ) {
|
491 |
+
$this->plugin->alerts->trigger_event(
|
492 |
4019,
|
493 |
array(
|
494 |
'TargetUsername' => $user->user_login,
|
517 |
* @return bool
|
518 |
* @since 3.2.3
|
519 |
*/
|
520 |
+
public function must_not_contain_role_changes( $manager ) {
|
521 |
+
return ! $manager->will_or_has_triggered( 4002 );
|
522 |
}
|
523 |
|
524 |
/**
|
529 |
* @return bool
|
530 |
* @since 3.2.3
|
531 |
*/
|
532 |
+
public function must_not_contain_new_user_alert( $manager ) {
|
533 |
+
return ! $manager->will_or_has_triggered( 4001 ) && ! $manager->will_or_has_triggered( 4012 );
|
534 |
}
|
535 |
|
536 |
/**
|
classes/Sensors/Multisite.php
CHANGED
@@ -4,9 +4,9 @@
|
|
4 |
*
|
5 |
* Multisite sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
*
|
9 |
-
* @package
|
10 |
* @subpackage sensors
|
11 |
*/
|
12 |
|
@@ -30,7 +30,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
30 |
* 7005 Existing site deleted from network
|
31 |
* 7012 Network registration option updated
|
32 |
*
|
33 |
-
* @package
|
34 |
* @subpackage sensors
|
35 |
*/
|
36 |
class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
@@ -43,21 +43,21 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
43 |
protected $old_allowedthemes = null;
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*/
|
48 |
-
public function
|
49 |
-
add_action( 'admin_init', array( $this, '
|
50 |
if ( current_user_can( 'switch_themes' ) ) {
|
51 |
-
add_action( 'shutdown', array( $this, '
|
52 |
}
|
53 |
-
add_action( 'wp_insert_site', array( $this, '
|
54 |
-
add_action( 'archive_blog', array( $this, '
|
55 |
-
add_action( 'unarchive_blog', array( $this, '
|
56 |
-
add_action( 'activate_blog', array( $this, '
|
57 |
-
add_action( 'deactivate_blog', array( $this, '
|
58 |
-
add_action( 'wp_uninitialize_site', array( $this, '
|
59 |
-
add_action( 'add_user_to_blog', array( $this, '
|
60 |
-
add_action( 'remove_user_from_blog', array( $this, '
|
61 |
|
62 |
add_action( 'update_site_option', array( $this, 'on_network_option_change' ), 10, 4 );
|
63 |
}
|
@@ -83,7 +83,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
83 |
'blog' => __( 'users can register new sites', 'wp-security-audit-log' ),
|
84 |
'all' => __( 'sites & users can be registered', 'wp-security-audit-log' ),
|
85 |
);
|
86 |
-
$this->plugin->alerts->
|
87 |
7012,
|
88 |
array(
|
89 |
'previous_setting' => ( isset( $possible_values[ $old_value ] ) ) ? $possible_values[ $old_value ] : $old_value,
|
@@ -93,7 +93,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
93 |
break;
|
94 |
|
95 |
case 'add_new_users':
|
96 |
-
$this->plugin->alerts->
|
97 |
7007,
|
98 |
array(
|
99 |
'EventType' => ( ! $value ) ? 'disabled' : 'enabled',
|
@@ -102,7 +102,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
102 |
break;
|
103 |
|
104 |
case 'upload_space_check_disabled':
|
105 |
-
$this->plugin->alerts->
|
106 |
7008,
|
107 |
array(
|
108 |
'EventType' => ( $value ) ? 'disabled' : 'enabled',
|
@@ -111,7 +111,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
111 |
break;
|
112 |
|
113 |
case 'blog_upload_space':
|
114 |
-
$this->plugin->alerts->
|
115 |
7009,
|
116 |
array(
|
117 |
'old_value' => sanitize_text_field( $old_value ),
|
@@ -121,7 +121,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
121 |
break;
|
122 |
|
123 |
case 'upload_filetypes':
|
124 |
-
$this->plugin->alerts->
|
125 |
7010,
|
126 |
array(
|
127 |
'old_value' => sanitize_text_field( $old_value ),
|
@@ -131,7 +131,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
131 |
break;
|
132 |
|
133 |
case 'fileupload_maxk':
|
134 |
-
$this->plugin->alerts->
|
135 |
7009,
|
136 |
array(
|
137 |
'old_value' => sanitize_text_field( $old_value ),
|
@@ -146,14 +146,16 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
146 |
/**
|
147 |
* Triggered when a user accesses the admin area.
|
148 |
*/
|
149 |
-
public function
|
150 |
$this->old_allowedthemes = array_keys( (array) get_site_option( 'allowedthemes' ) );
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
* Activated/Deactivated theme on network.
|
|
|
|
|
155 |
*/
|
156 |
-
public function
|
157 |
if ( is_null( $this->old_allowedthemes ) ) {
|
158 |
return;
|
159 |
}
|
@@ -161,9 +163,9 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
161 |
|
162 |
// Check for enabled themes.
|
163 |
foreach ( $new_allowedthemes as $theme ) {
|
164 |
-
if ( ! in_array( $theme, (array) $this->old_allowedthemes ) ) {
|
165 |
$theme = wp_get_theme( $theme );
|
166 |
-
$this->plugin->alerts->
|
167 |
5008,
|
168 |
array(
|
169 |
'Theme' => (object) array(
|
@@ -181,9 +183,9 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
181 |
|
182 |
// Check for disabled themes.
|
183 |
foreach ( (array) $this->old_allowedthemes as $theme ) {
|
184 |
-
if ( ! in_array( $theme, $new_allowedthemes ) ) {
|
185 |
$theme = wp_get_theme( $theme );
|
186 |
-
$this->plugin->alerts->
|
187 |
5009,
|
188 |
array(
|
189 |
'Theme' => (object) array(
|
@@ -205,11 +207,11 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
205 |
*
|
206 |
* @param WP_Site $new_blog - New site object.
|
207 |
*/
|
208 |
-
public function
|
209 |
$blog_id = $new_blog->blog_id;
|
210 |
|
211 |
/*
|
212 |
-
* Site
|
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).
|
@@ -222,15 +224,15 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
222 |
|
223 |
$home_scheme = 'http';
|
224 |
if ( ! is_subdomain_install() ) {
|
225 |
-
if ( 'https' === parse_url( get_home_url( $network->site_id ), PHP_URL_SCHEME ) ) {
|
226 |
$home_scheme = 'https';
|
227 |
}
|
228 |
}
|
229 |
|
230 |
-
$blog_title = strip_tags( $_POST['blog']['title'] );
|
231 |
$blog_url = untrailingslashit( $home_scheme . '://' . $new_blog->domain . $new_blog->path );
|
232 |
|
233 |
-
$this->plugin->alerts->
|
234 |
7000,
|
235 |
array(
|
236 |
'BlogID' => $blog_id,
|
@@ -245,8 +247,8 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
245 |
*
|
246 |
* @param int $blog_id - Blog ID.
|
247 |
*/
|
248 |
-
public function
|
249 |
-
$this->plugin->alerts->
|
250 |
7001,
|
251 |
array(
|
252 |
'BlogID' => $blog_id,
|
@@ -261,8 +263,8 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
261 |
*
|
262 |
* @param int $blog_id - Blog ID.
|
263 |
*/
|
264 |
-
public function
|
265 |
-
$this->plugin->alerts->
|
266 |
7002,
|
267 |
array(
|
268 |
'BlogID' => $blog_id,
|
@@ -277,8 +279,8 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
277 |
*
|
278 |
* @param int $blog_id - Blog ID.
|
279 |
*/
|
280 |
-
public function
|
281 |
-
$this->plugin->alerts->
|
282 |
7003,
|
283 |
array(
|
284 |
'BlogID' => $blog_id,
|
@@ -293,8 +295,8 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
293 |
*
|
294 |
* @param int $blog_id - Blog ID.
|
295 |
*/
|
296 |
-
public function
|
297 |
-
$this->plugin->alerts->
|
298 |
7004,
|
299 |
array(
|
300 |
'BlogID' => $blog_id,
|
@@ -309,9 +311,9 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
309 |
*
|
310 |
* @param WP_Site $deleted_blog - Deleted blog object.
|
311 |
*/
|
312 |
-
public function
|
313 |
$blog_id = $deleted_blog->blog_id;
|
314 |
-
$this->plugin->alerts->
|
315 |
7005,
|
316 |
array(
|
317 |
'BlogID' => $blog_id,
|
@@ -328,9 +330,9 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
328 |
* @param string $role - User role.
|
329 |
* @param int $blog_id - Blog ID.
|
330 |
*/
|
331 |
-
public function
|
332 |
$user = get_userdata( $user_id );
|
333 |
-
$this->plugin->alerts->
|
334 |
4010,
|
335 |
array(
|
336 |
'TargetUserID' => $user_id,
|
@@ -342,7 +344,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
342 |
'LastName' => $user ? $user->user_lastname : false,
|
343 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
344 |
),
|
345 |
-
array( $this, '
|
346 |
);
|
347 |
}
|
348 |
|
@@ -352,9 +354,9 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
352 |
* @param int $user_id - User ID.
|
353 |
* @param int $blog_id - Blog ID.
|
354 |
*/
|
355 |
-
public function
|
356 |
$user = get_userdata( $user_id );
|
357 |
-
$this->plugin->alerts->
|
358 |
4011,
|
359 |
array(
|
360 |
'TargetUserID' => $user_id,
|
@@ -366,7 +368,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
366 |
'LastName' => $user ? $user->user_lastname : false,
|
367 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
368 |
),
|
369 |
-
array( $this, '
|
370 |
);
|
371 |
}
|
372 |
|
@@ -376,7 +378,7 @@ class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
|
376 |
* @param WSAL_AlertManager $mgr - Instance of Alert Manager.
|
377 |
* @return bool
|
378 |
*/
|
379 |
-
public function
|
380 |
-
return ! $mgr->
|
381 |
}
|
382 |
}
|
4 |
*
|
5 |
* Multisite sensor file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
*
|
9 |
+
* @package wsal
|
10 |
* @subpackage sensors
|
11 |
*/
|
12 |
|
30 |
* 7005 Existing site deleted from network
|
31 |
* 7012 Network registration option updated
|
32 |
*
|
33 |
+
* @package wsal
|
34 |
* @subpackage sensors
|
35 |
*/
|
36 |
class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
43 |
protected $old_allowedthemes = null;
|
44 |
|
45 |
/**
|
46 |
+
* {@inheritDoc}
|
47 |
*/
|
48 |
+
public function hook_events() {
|
49 |
+
add_action( 'admin_init', array( $this, 'event_admin_init' ) );
|
50 |
if ( current_user_can( 'switch_themes' ) ) {
|
51 |
+
add_action( 'shutdown', array( $this, 'event_admin_shutdown' ) );
|
52 |
}
|
53 |
+
add_action( 'wp_insert_site', array( $this, 'event_new_blog' ), 10, 1 );
|
54 |
+
add_action( 'archive_blog', array( $this, 'event_archive_blog' ) );
|
55 |
+
add_action( 'unarchive_blog', array( $this, 'event_unarchive_blog' ) );
|
56 |
+
add_action( 'activate_blog', array( $this, 'event_activate_blog' ) );
|
57 |
+
add_action( 'deactivate_blog', array( $this, 'event_deactivate_blog' ) );
|
58 |
+
add_action( 'wp_uninitialize_site', array( $this, 'event_delete_blog' ) );
|
59 |
+
add_action( 'add_user_to_blog', array( $this, 'event_user_added_to_blog' ), 10, 3 );
|
60 |
+
add_action( 'remove_user_from_blog', array( $this, 'event_user_removed_from_blog' ), 10, 2 );
|
61 |
|
62 |
add_action( 'update_site_option', array( $this, 'on_network_option_change' ), 10, 4 );
|
63 |
}
|
83 |
'blog' => __( 'users can register new sites', 'wp-security-audit-log' ),
|
84 |
'all' => __( 'sites & users can be registered', 'wp-security-audit-log' ),
|
85 |
);
|
86 |
+
$this->plugin->alerts->trigger_event(
|
87 |
7012,
|
88 |
array(
|
89 |
'previous_setting' => ( isset( $possible_values[ $old_value ] ) ) ? $possible_values[ $old_value ] : $old_value,
|
93 |
break;
|
94 |
|
95 |
case 'add_new_users':
|
96 |
+
$this->plugin->alerts->trigger_event(
|
97 |
7007,
|
98 |
array(
|
99 |
'EventType' => ( ! $value ) ? 'disabled' : 'enabled',
|
102 |
break;
|
103 |
|
104 |
case 'upload_space_check_disabled':
|
105 |
+
$this->plugin->alerts->trigger_event(
|
106 |
7008,
|
107 |
array(
|
108 |
'EventType' => ( $value ) ? 'disabled' : 'enabled',
|
111 |
break;
|
112 |
|
113 |
case 'blog_upload_space':
|
114 |
+
$this->plugin->alerts->trigger_event(
|
115 |
7009,
|
116 |
array(
|
117 |
'old_value' => sanitize_text_field( $old_value ),
|
121 |
break;
|
122 |
|
123 |
case 'upload_filetypes':
|
124 |
+
$this->plugin->alerts->trigger_event(
|
125 |
7010,
|
126 |
array(
|
127 |
'old_value' => sanitize_text_field( $old_value ),
|
131 |
break;
|
132 |
|
133 |
case 'fileupload_maxk':
|
134 |
+
$this->plugin->alerts->trigger_event(
|
135 |
7009,
|
136 |
array(
|
137 |
'old_value' => sanitize_text_field( $old_value ),
|
146 |
/**
|
147 |
* Triggered when a user accesses the admin area.
|
148 |
*/
|
149 |
+
public function event_admin_init() {
|
150 |
$this->old_allowedthemes = array_keys( (array) get_site_option( 'allowedthemes' ) );
|
151 |
}
|
152 |
|
153 |
/**
|
154 |
* Activated/Deactivated theme on network.
|
155 |
+
*
|
156 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
157 |
*/
|
158 |
+
public function event_admin_shutdown() {
|
159 |
if ( is_null( $this->old_allowedthemes ) ) {
|
160 |
return;
|
161 |
}
|
163 |
|
164 |
// Check for enabled themes.
|
165 |
foreach ( $new_allowedthemes as $theme ) {
|
166 |
+
if ( ! in_array( $theme, (array) $this->old_allowedthemes, true ) ) {
|
167 |
$theme = wp_get_theme( $theme );
|
168 |
+
$this->plugin->alerts->trigger_event(
|
169 |
5008,
|
170 |
array(
|
171 |
'Theme' => (object) array(
|
183 |
|
184 |
// Check for disabled themes.
|
185 |
foreach ( (array) $this->old_allowedthemes as $theme ) {
|
186 |
+
if ( ! in_array( $theme, $new_allowedthemes, true ) ) {
|
187 |
$theme = wp_get_theme( $theme );
|
188 |
+
$this->plugin->alerts->trigger_event(
|
189 |
5009,
|
190 |
array(
|
191 |
'Theme' => (object) array(
|
207 |
*
|
208 |
* @param WP_Site $new_blog - New site object.
|
209 |
*/
|
210 |
+
public function event_new_blog( $new_blog ) {
|
211 |
$blog_id = $new_blog->blog_id;
|
212 |
|
213 |
/*
|
214 |
+
* Site metadata nor options are not setup at this point so get_blog_option and get_home_url are not
|
215 |
* returning anything for the new blog.
|
216 |
*
|
217 |
* The following code to work out the correct URL for the new site was taken from ms-site.php (WP 5.7).
|
224 |
|
225 |
$home_scheme = 'http';
|
226 |
if ( ! is_subdomain_install() ) {
|
227 |
+
if ( 'https' === parse_url( get_home_url( $network->site_id ), PHP_URL_SCHEME ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
|
228 |
$home_scheme = 'https';
|
229 |
}
|
230 |
}
|
231 |
|
232 |
+
$blog_title = strip_tags( $_POST['blog']['title'] ); // phpcs:ignore
|
233 |
$blog_url = untrailingslashit( $home_scheme . '://' . $new_blog->domain . $new_blog->path );
|
234 |
|
235 |
+
$this->plugin->alerts->trigger_event(
|
236 |
7000,
|
237 |
array(
|
238 |
'BlogID' => $blog_id,
|
247 |
*
|
248 |
* @param int $blog_id - Blog ID.
|
249 |
*/
|
250 |
+
public function event_archive_blog( $blog_id ) {
|
251 |
+
$this->plugin->alerts->trigger_event(
|
252 |
7001,
|
253 |
array(
|
254 |
'BlogID' => $blog_id,
|
263 |
*
|
264 |
* @param int $blog_id - Blog ID.
|
265 |
*/
|
266 |
+
public function event_unarchive_blog( $blog_id ) {
|
267 |
+
$this->plugin->alerts->trigger_event(
|
268 |
7002,
|
269 |
array(
|
270 |
'BlogID' => $blog_id,
|
279 |
*
|
280 |
* @param int $blog_id - Blog ID.
|
281 |
*/
|
282 |
+
public function event_activate_blog( $blog_id ) {
|
283 |
+
$this->plugin->alerts->trigger_event(
|
284 |
7003,
|
285 |
array(
|
286 |
'BlogID' => $blog_id,
|
295 |
*
|
296 |
* @param int $blog_id - Blog ID.
|
297 |
*/
|
298 |
+
public function event_deactivate_blog( $blog_id ) {
|
299 |
+
$this->plugin->alerts->trigger_event(
|
300 |
7004,
|
301 |
array(
|
302 |
'BlogID' => $blog_id,
|
311 |
*
|
312 |
* @param WP_Site $deleted_blog - Deleted blog object.
|
313 |
*/
|
314 |
+
public function event_delete_blog( $deleted_blog ) {
|
315 |
$blog_id = $deleted_blog->blog_id;
|
316 |
+
$this->plugin->alerts->trigger_event(
|
317 |
7005,
|
318 |
array(
|
319 |
'BlogID' => $blog_id,
|
330 |
* @param string $role - User role.
|
331 |
* @param int $blog_id - Blog ID.
|
332 |
*/
|
333 |
+
public function event_user_added_to_blog( $user_id, $role, $blog_id ) {
|
334 |
$user = get_userdata( $user_id );
|
335 |
+
$this->plugin->alerts->trigger_event_if(
|
336 |
4010,
|
337 |
array(
|
338 |
'TargetUserID' => $user_id,
|
344 |
'LastName' => $user ? $user->user_lastname : false,
|
345 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
346 |
),
|
347 |
+
array( $this, 'must_not_contain_create_user' )
|
348 |
);
|
349 |
}
|
350 |
|
354 |
* @param int $user_id - User ID.
|
355 |
* @param int $blog_id - Blog ID.
|
356 |
*/
|
357 |
+
public function event_user_removed_from_blog( $user_id, $blog_id ) {
|
358 |
$user = get_userdata( $user_id );
|
359 |
+
$this->plugin->alerts->trigger_event_if(
|
360 |
4011,
|
361 |
array(
|
362 |
'TargetUserID' => $user_id,
|
368 |
'LastName' => $user ? $user->user_lastname : false,
|
369 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
370 |
),
|
371 |
+
array( $this, 'must_not_contain_create_user' )
|
372 |
);
|
373 |
}
|
374 |
|
378 |
* @param WSAL_AlertManager $mgr - Instance of Alert Manager.
|
379 |
* @return bool
|
380 |
*/
|
381 |
+
public function must_not_contain_create_user( WSAL_AlertManager $mgr ) {
|
382 |
+
return ! $mgr->will_trigger( 4012 );
|
383 |
}
|
384 |
}
|
classes/Sensors/MultisiteSignUp.php
CHANGED
@@ -28,7 +28,7 @@ class WSAL_Sensors_MultisiteSignUp extends WSAL_AbstractSensor {
|
|
28 |
/**
|
29 |
* {@inheritDoc}
|
30 |
*/
|
31 |
-
public function
|
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 |
}
|
@@ -60,7 +60,7 @@ class WSAL_Sensors_MultisiteSignUp extends WSAL_AbstractSensor {
|
|
60 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
61 |
);
|
62 |
|
63 |
-
$this->plugin->alerts->
|
64 |
}
|
65 |
|
66 |
/**
|
@@ -74,7 +74,7 @@ class WSAL_Sensors_MultisiteSignUp extends WSAL_AbstractSensor {
|
|
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->
|
78 |
4024,
|
79 |
array(
|
80 |
'username' => $user,
|
@@ -90,6 +90,6 @@ class WSAL_Sensors_MultisiteSignUp extends WSAL_AbstractSensor {
|
|
90 |
* @param WSAL_AlertManager $manager - Instance of WSAL_AlertManager.
|
91 |
*/
|
92 |
public function must_not_contain_create_user( WSAL_AlertManager $manager ) {
|
93 |
-
return ! $manager->
|
94 |
}
|
95 |
}
|
28 |
/**
|
29 |
* {@inheritDoc}
|
30 |
*/
|
31 |
+
public function hook_events() {
|
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 |
}
|
60 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
61 |
);
|
62 |
|
63 |
+
$this->plugin->alerts->trigger_event_if( 4013, $event_data, array( $this, 'must_not_contain_create_user' ) );
|
64 |
}
|
65 |
|
66 |
/**
|
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->trigger_event_if(
|
78 |
4024,
|
79 |
array(
|
80 |
'username' => $user,
|
90 |
* @param WSAL_AlertManager $manager - Instance of WSAL_AlertManager.
|
91 |
*/
|
92 |
public function must_not_contain_create_user( WSAL_AlertManager $manager ) {
|
93 |
+
return ! $manager->will_trigger( 4012 );
|
94 |
}
|
95 |
}
|
classes/Sensors/PluginsThemes.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* Plugins & Themes sensor file.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
26 |
* 5007 User uninstalled a theme
|
27 |
* 5031 User updated a theme
|
28 |
*
|
29 |
-
* @package
|
30 |
* @subpackage sensors
|
31 |
*/
|
32 |
class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
@@ -48,30 +48,33 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
48 |
/**
|
49 |
* Listening to events using WP hooks.
|
50 |
*/
|
51 |
-
public function
|
52 |
$has_permission = ( current_user_can( 'install_plugins' ) || current_user_can( 'activate_plugins' ) ||
|
53 |
-
|
54 |
|
55 |
-
add_action( 'admin_init', array( $this, '
|
56 |
if ( $has_permission ) {
|
57 |
-
add_action( 'shutdown', array( $this, '
|
58 |
}
|
59 |
-
add_action( 'switch_theme', array( $this, '
|
60 |
-
add_action( 'upgrader_overwrote_package',
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
* Triggered when a user accesses the admin area.
|
65 |
*/
|
66 |
-
public function
|
67 |
$this->old_themes = wp_get_themes();
|
68 |
$this->old_plugins = get_plugins();
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
* Install, uninstall, activate, deactivate, upgrade and update.
|
|
|
|
|
|
|
73 |
*/
|
74 |
-
public function
|
75 |
// Filter global arrays for security.
|
76 |
$post_array = filter_input_array( INPUT_POST );
|
77 |
$get_array = filter_input_array( INPUT_GET );
|
@@ -98,10 +101,10 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
98 |
$is_plugins = 'plugins' === $actype;
|
99 |
|
100 |
// Install plugin.
|
101 |
-
if ( in_array( $action, array( 'install-plugin', 'upload-plugin', 'run_addon_install' ) ) && current_user_can( 'install_plugins' ) ) {
|
102 |
$plugin = array_values( array_diff( array_keys( get_plugins() ), array_keys( $this->old_plugins ) ) );
|
103 |
if ( count( $plugin ) != 1 ) {
|
104 |
-
$this->
|
105 |
'Expected exactly one new plugin but found ' . count( $plugin ),
|
106 |
array(
|
107 |
'NewPlugin' => $plugin,
|
@@ -116,10 +119,10 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
116 |
$plugin = $plugin[ $plugin_path ];
|
117 |
|
118 |
// Get plugin directory name.
|
119 |
-
$plugin_dir =
|
120 |
|
121 |
$plugin_path = plugin_dir_path( WP_PLUGIN_DIR . '/' . $plugin_path[0] );
|
122 |
-
$this->plugin->alerts->
|
123 |
5000,
|
124 |
array(
|
125 |
'Plugin' => (object) array(
|
@@ -137,7 +140,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
137 |
}
|
138 |
|
139 |
// Activate plugin.
|
140 |
-
if ( $is_plugins && in_array( $action, array( 'activate', 'activate-selected' ) ) && current_user_can( 'activate_plugins' ) ) {
|
141 |
// Check $_GET array case.
|
142 |
if ( isset( $get_array['plugin'] ) ) {
|
143 |
if ( ! isset( $get_array['checked'] ) ) {
|
@@ -157,7 +160,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
157 |
if ( isset( $get_array['checked'] ) && ! empty( $get_array['checked'] ) ) {
|
158 |
$latest_event = $this->plugin->alerts->get_latest_events();
|
159 |
$latest_event = isset( $latest_event[0] ) ? $latest_event[0] : false;
|
160 |
-
$event_meta = $latest_event ? $latest_event->
|
161 |
|
162 |
foreach ( $get_array['checked'] as $plugin_file ) {
|
163 |
if ( $latest_event && 5001 === $latest_event->alert_id && $event_meta && isset( $event_meta['PluginFile'] ) ) {
|
@@ -169,7 +172,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
169 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
170 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
171 |
|
172 |
-
$this->plugin->alerts->
|
173 |
5001,
|
174 |
array(
|
175 |
'PluginFile' => $plugin_file,
|
@@ -190,7 +193,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
190 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
191 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
192 |
|
193 |
-
$this->plugin->alerts->
|
194 |
5001,
|
195 |
array(
|
196 |
'PluginFile' => $plugin_file,
|
@@ -210,7 +213,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
210 |
}
|
211 |
|
212 |
// Deactivate plugin.
|
213 |
-
if ( $is_plugins && in_array( $action, array( 'deactivate', 'deactivate-selected' ) ) && current_user_can( 'activate_plugins' ) ) {
|
214 |
// Check $_GET array case.
|
215 |
if ( isset( $get_array['plugin'] ) ) {
|
216 |
if ( ! isset( $get_array['checked'] ) ) {
|
@@ -231,7 +234,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
231 |
foreach ( $get_array['checked'] as $plugin_file ) {
|
232 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
233 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
234 |
-
$this->plugin->alerts->
|
235 |
5002,
|
236 |
array(
|
237 |
'PluginFile' => $plugin_file,
|
@@ -244,13 +247,13 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
244 |
),
|
245 |
)
|
246 |
);
|
247 |
-
|
248 |
}
|
249 |
} elseif ( isset( $post_array['checked'] ) && ! empty( $post_array['checked'] ) ) {
|
250 |
foreach ( $post_array['checked'] as $plugin_file ) {
|
251 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
252 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
253 |
-
$this->plugin->alerts->
|
254 |
5002,
|
255 |
array(
|
256 |
'PluginFile' => $plugin_file,
|
@@ -263,14 +266,14 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
263 |
),
|
264 |
)
|
265 |
);
|
266 |
-
|
267 |
}
|
268 |
}
|
269 |
}
|
270 |
|
271 |
// Uninstall plugin.
|
272 |
-
if ( $is_plugins && in_array( $action, array( 'delete-selected' ) ) && current_user_can( 'delete_plugins' ) ) {
|
273 |
-
if ( ! isset( $post_array['verify-delete'] ) ) {
|
274 |
// First step, before user approves deletion
|
275 |
// TODO store plugin data in session here.
|
276 |
} else {
|
@@ -282,7 +285,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
282 |
$plugin_name = ucwords( $plugin_name );
|
283 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
284 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
285 |
-
$this->plugin->alerts->
|
286 |
5003,
|
287 |
array(
|
288 |
'PluginFile' => $plugin_file,
|
@@ -292,20 +295,20 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
292 |
),
|
293 |
)
|
294 |
);
|
295 |
-
|
296 |
}
|
297 |
}
|
298 |
}
|
299 |
|
300 |
// Uninstall plugin for WordPress version 4.6.
|
301 |
-
if ( in_array( $action, array( 'delete-plugin' ) ) && current_user_can( 'delete_plugins' ) ) {
|
302 |
if ( isset( $post_array['plugin'] ) ) {
|
303 |
$plugin_file = WP_PLUGIN_DIR . '/' . $post_array['plugin'];
|
304 |
$plugin_name = basename( $plugin_file, '.php' );
|
305 |
$plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name );
|
306 |
$plugin_name = ucwords( $plugin_name );
|
307 |
$plugin_data = $this->old_plugins[ $post_array['plugin'] ];
|
308 |
-
$this->plugin->alerts->
|
309 |
5003,
|
310 |
array(
|
311 |
'PluginFile' => $plugin_file,
|
@@ -316,12 +319,12 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
316 |
)
|
317 |
);
|
318 |
|
319 |
-
|
320 |
}
|
321 |
}
|
322 |
|
323 |
// Upgrade plugin.
|
324 |
-
if ( in_array( $action, array( 'upgrade-plugin', 'update-plugin', 'update-selected' ) ) && current_user_can( 'update_plugins' ) ) {
|
325 |
$plugins = array();
|
326 |
|
327 |
// Check $_GET array cases.
|
@@ -339,13 +342,13 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
339 |
}
|
340 |
if ( isset( $plugins ) ) {
|
341 |
foreach ( $plugins as $plugin_file ) {
|
342 |
-
|
343 |
}
|
344 |
}
|
345 |
}
|
346 |
|
347 |
// Update theme.
|
348 |
-
if ( in_array( $action, array( 'upgrade-theme', 'update-theme', 'update-selected-themes' ) ) && current_user_can( 'install_themes' ) ) {
|
349 |
// Themes.
|
350 |
$themes = array();
|
351 |
|
@@ -362,18 +365,18 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
362 |
} elseif ( isset( $post_array['themes'] ) ) {
|
363 |
$themes = explode( ',', $post_array['themes'] );
|
364 |
}
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
}
|
371 |
|
372 |
// Install theme.
|
373 |
-
if ( in_array( $action, array( 'install-theme', 'upload-theme' ) ) && current_user_can( 'install_themes' ) ) {
|
374 |
$themes = array_diff( wp_get_themes(), $this->old_themes );
|
375 |
-
foreach ( $themes as $
|
376 |
-
$this->plugin->alerts->
|
377 |
5005,
|
378 |
array(
|
379 |
'Theme' => (object) array(
|
@@ -390,9 +393,9 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
390 |
}
|
391 |
|
392 |
// Uninstall theme.
|
393 |
-
if ( in_array( $action, array( 'delete-theme' ) ) && current_user_can( 'install_themes' ) ) {
|
394 |
-
foreach ( $this->
|
395 |
-
$this->plugin->alerts->
|
396 |
5007,
|
397 |
array(
|
398 |
'Theme' => (object) array(
|
@@ -413,17 +416,19 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
413 |
* Activated a theme.
|
414 |
*
|
415 |
* @param string $theme_name - Theme name.
|
|
|
|
|
416 |
*/
|
417 |
-
public function
|
418 |
$theme = null;
|
419 |
foreach ( wp_get_themes() as $item ) {
|
420 |
-
if ( $theme_name
|
421 |
$theme = $item;
|
422 |
break;
|
423 |
}
|
424 |
}
|
425 |
-
if ( null == $theme ) {
|
426 |
-
$this->
|
427 |
'Could not locate theme named "' . $theme . '".',
|
428 |
array(
|
429 |
'ThemeName' => $theme_name,
|
@@ -432,7 +437,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
432 |
);
|
433 |
return;
|
434 |
}
|
435 |
-
$this->plugin->alerts->
|
436 |
5006,
|
437 |
array(
|
438 |
'Theme' => (object) array(
|
@@ -452,7 +457,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
452 |
*
|
453 |
* @return array of WP_Theme objects
|
454 |
*/
|
455 |
-
protected function
|
456 |
$result = $this->old_themes;
|
457 |
foreach ( $result as $i => $theme ) {
|
458 |
if ( file_exists( $theme->get_template_directory() ) ) {
|
@@ -465,14 +470,14 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
465 |
/**
|
466 |
* Get event code by post type.
|
467 |
*
|
468 |
-
* @param object $post
|
469 |
-
* @param int
|
470 |
-
* @param int
|
471 |
-
* @param int
|
472 |
*
|
473 |
* @return false|int
|
474 |
*/
|
475 |
-
protected function
|
476 |
if ( empty( $post ) || ! isset( $post->post_type ) ) {
|
477 |
return false;
|
478 |
}
|
@@ -552,7 +557,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
552 |
$theme = null;
|
553 |
if ( ! empty( $all_themes ) ) {
|
554 |
foreach ( $all_themes as $theme_slug => $theme_obj ) {
|
555 |
-
if ( $theme_name === $theme_slug|| $theme_name === $theme_obj->get('Name') ) {
|
556 |
$theme = $theme_obj;
|
557 |
break;
|
558 |
}
|
@@ -561,6 +566,11 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
561 |
return $theme;
|
562 |
}
|
563 |
|
|
|
|
|
|
|
|
|
|
|
564 |
public function run_addon_check( $plugin_dir ) {
|
565 |
$plugin_filename = basename( preg_replace( '/\\.[^.\\s]{3,4}$/', '', $plugin_dir ) );
|
566 |
|
@@ -578,25 +588,30 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
578 |
|
579 |
// Check if plugin file starts with the same string as our addon_for, or if its equal.
|
580 |
if ( $plugin_filename === $plugin ) {
|
581 |
-
$addon_slug = array( array_search( $plugin, array_column( $predefined_plugins, 'addon_for', 'plugin_slug' ) ) );
|
582 |
$is_addon_installed = array_intersect( $all_plugins, $addon_slug );
|
583 |
if ( empty( $is_addon_installed ) ) {
|
584 |
-
$current_value = $this->plugin->
|
585 |
$plugin_filename = array( $plugin_filename );
|
586 |
if ( isset( $current_value ) && is_array( $current_value ) ) {
|
587 |
$new_plugin_filenames = array_unique( array_merge( $current_value, $plugin_filename ) );
|
588 |
} else {
|
589 |
$new_plugin_filenames = $plugin_filename;
|
590 |
}
|
591 |
-
$this->plugin->
|
592 |
-
$this->plugin->
|
593 |
}
|
594 |
}
|
595 |
}
|
596 |
}
|
597 |
|
|
|
|
|
|
|
|
|
|
|
598 |
public static function run_addon_removal_check( $plugin_dir ) {
|
599 |
-
$wsal
|
600 |
$plugin_filename = basename( preg_replace( '/\\.[^.\\s]{3,4}$/', '', $plugin_dir ) );
|
601 |
|
602 |
if ( is_array( $plugin_filename ) ) {
|
@@ -612,14 +627,15 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
612 |
|
613 |
// Check if plugin file starts with the same string as our addon_for, or if its equal.
|
614 |
if ( $plugin_filename === $plugin ) {
|
615 |
-
$current_installed = $wsal->
|
616 |
-
if ( isset( $current_installed ) && ! empty( $current_installed
|
617 |
-
|
618 |
-
|
|
|
619 |
}
|
620 |
}
|
621 |
|
622 |
-
$wsal->
|
623 |
}
|
624 |
}
|
625 |
}
|
@@ -630,9 +646,9 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
630 |
*
|
631 |
* @since 4.1.4
|
632 |
*
|
633 |
-
* @param string
|
634 |
-
* @param array
|
635 |
-
* @param string
|
636 |
*/
|
637 |
public function OnPackageOverwrite( $package, $new_plugin_data, $package_type ) {
|
638 |
if ( 'plugin' !== $package_type ) {
|
@@ -640,9 +656,9 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
640 |
}
|
641 |
|
642 |
if ( array_key_exists( 'Name', $new_plugin_data ) ) {
|
643 |
-
$plugin_file =
|
644 |
if ( ! empty( $plugin_file ) ) {
|
645 |
-
|
646 |
}
|
647 |
}
|
648 |
}
|
@@ -655,7 +671,7 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
655 |
*
|
656 |
* @since 4.1.4
|
657 |
*/
|
658 |
-
public static function
|
659 |
$plugin_file_full = WP_PLUGIN_DIR . '/' . $plugin_file;
|
660 |
$plugin_data = get_plugin_data( $plugin_file_full, false, true );
|
661 |
|
@@ -663,8 +679,8 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
663 |
$new_version = $plugin_data['Version'];
|
664 |
|
665 |
if ( $old_version !== $new_version ) {
|
666 |
-
$wsal = WpSecurityAuditLog::
|
667 |
-
$wsal->alerts->
|
668 |
5004,
|
669 |
array(
|
670 |
'PluginFile' => $plugin_file,
|
@@ -680,32 +696,34 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
680 |
}
|
681 |
}
|
682 |
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
|
|
|
|
711 |
}
|
4 |
*
|
5 |
* Plugins & Themes sensor file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
26 |
* 5007 User uninstalled a theme
|
27 |
* 5031 User updated a theme
|
28 |
*
|
29 |
+
* @package wsal
|
30 |
* @subpackage sensors
|
31 |
*/
|
32 |
class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
48 |
/**
|
49 |
* Listening to events using WP hooks.
|
50 |
*/
|
51 |
+
public function hook_events() {
|
52 |
$has_permission = ( current_user_can( 'install_plugins' ) || current_user_can( 'activate_plugins' ) ||
|
53 |
+
current_user_can( 'delete_plugins' ) || current_user_can( 'update_plugins' ) || current_user_can( 'install_themes' ) );
|
54 |
|
55 |
+
add_action( 'admin_init', array( $this, 'event_admin_init' ) );
|
56 |
if ( $has_permission ) {
|
57 |
+
add_action( 'shutdown', array( $this, 'event_admin_shutdown' ) );
|
58 |
}
|
59 |
+
add_action( 'switch_theme', array( $this, 'event_theme_activated' ) );
|
60 |
+
add_action( 'upgrader_overwrote_package', array( $this, 'OnPackageOverwrite' ), 10, 3 );
|
61 |
}
|
62 |
|
63 |
/**
|
64 |
* Triggered when a user accesses the admin area.
|
65 |
*/
|
66 |
+
public function event_admin_init() {
|
67 |
$this->old_themes = wp_get_themes();
|
68 |
$this->old_plugins = get_plugins();
|
69 |
}
|
70 |
|
71 |
/**
|
72 |
* Install, uninstall, activate, deactivate, upgrade and update.
|
73 |
+
*
|
74 |
+
* phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
|
75 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
76 |
*/
|
77 |
+
public function event_admin_shutdown() {
|
78 |
// Filter global arrays for security.
|
79 |
$post_array = filter_input_array( INPUT_POST );
|
80 |
$get_array = filter_input_array( INPUT_GET );
|
101 |
$is_plugins = 'plugins' === $actype;
|
102 |
|
103 |
// Install plugin.
|
104 |
+
if ( in_array( $action, array( 'install-plugin', 'upload-plugin', 'run_addon_install' ), true ) && current_user_can( 'install_plugins' ) ) {
|
105 |
$plugin = array_values( array_diff( array_keys( get_plugins() ), array_keys( $this->old_plugins ) ) );
|
106 |
if ( count( $plugin ) != 1 ) {
|
107 |
+
$this->log_error(
|
108 |
'Expected exactly one new plugin but found ' . count( $plugin ),
|
109 |
array(
|
110 |
'NewPlugin' => $plugin,
|
119 |
$plugin = $plugin[ $plugin_path ];
|
120 |
|
121 |
// Get plugin directory name.
|
122 |
+
$plugin_dir = self::get_plugin_dir( $plugin_path );
|
123 |
|
124 |
$plugin_path = plugin_dir_path( WP_PLUGIN_DIR . '/' . $plugin_path[0] );
|
125 |
+
$this->plugin->alerts->trigger_event(
|
126 |
5000,
|
127 |
array(
|
128 |
'Plugin' => (object) array(
|
140 |
}
|
141 |
|
142 |
// Activate plugin.
|
143 |
+
if ( $is_plugins && in_array( $action, array( 'activate', 'activate-selected' ), true ) && current_user_can( 'activate_plugins' ) ) {
|
144 |
// Check $_GET array case.
|
145 |
if ( isset( $get_array['plugin'] ) ) {
|
146 |
if ( ! isset( $get_array['checked'] ) ) {
|
160 |
if ( isset( $get_array['checked'] ) && ! empty( $get_array['checked'] ) ) {
|
161 |
$latest_event = $this->plugin->alerts->get_latest_events();
|
162 |
$latest_event = isset( $latest_event[0] ) ? $latest_event[0] : false;
|
163 |
+
$event_meta = $latest_event ? $latest_event->get_meta_array() : false;
|
164 |
|
165 |
foreach ( $get_array['checked'] as $plugin_file ) {
|
166 |
if ( $latest_event && 5001 === $latest_event->alert_id && $event_meta && isset( $event_meta['PluginFile'] ) ) {
|
172 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
173 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
174 |
|
175 |
+
$this->plugin->alerts->trigger_event(
|
176 |
5001,
|
177 |
array(
|
178 |
'PluginFile' => $plugin_file,
|
193 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
194 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
195 |
|
196 |
+
$this->plugin->alerts->trigger_event(
|
197 |
5001,
|
198 |
array(
|
199 |
'PluginFile' => $plugin_file,
|
213 |
}
|
214 |
|
215 |
// Deactivate plugin.
|
216 |
+
if ( $is_plugins && in_array( $action, array( 'deactivate', 'deactivate-selected' ), true ) && current_user_can( 'activate_plugins' ) ) {
|
217 |
// Check $_GET array case.
|
218 |
if ( isset( $get_array['plugin'] ) ) {
|
219 |
if ( ! isset( $get_array['checked'] ) ) {
|
234 |
foreach ( $get_array['checked'] as $plugin_file ) {
|
235 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
236 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
237 |
+
$this->plugin->alerts->trigger_event(
|
238 |
5002,
|
239 |
array(
|
240 |
'PluginFile' => $plugin_file,
|
247 |
),
|
248 |
)
|
249 |
);
|
250 |
+
self::run_addon_removal_check( $plugin_file );
|
251 |
}
|
252 |
} elseif ( isset( $post_array['checked'] ) && ! empty( $post_array['checked'] ) ) {
|
253 |
foreach ( $post_array['checked'] as $plugin_file ) {
|
254 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
255 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
256 |
+
$this->plugin->alerts->trigger_event(
|
257 |
5002,
|
258 |
array(
|
259 |
'PluginFile' => $plugin_file,
|
266 |
),
|
267 |
)
|
268 |
);
|
269 |
+
self::run_addon_removal_check( $plugin_file );
|
270 |
}
|
271 |
}
|
272 |
}
|
273 |
|
274 |
// Uninstall plugin.
|
275 |
+
if ( $is_plugins && in_array( $action, array( 'delete-selected' ), true ) && current_user_can( 'delete_plugins' ) ) {
|
276 |
+
if ( ! isset( $post_array['verify-delete'] ) ) { // phpcs:ignore
|
277 |
// First step, before user approves deletion
|
278 |
// TODO store plugin data in session here.
|
279 |
} else {
|
285 |
$plugin_name = ucwords( $plugin_name );
|
286 |
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
287 |
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
288 |
+
$this->plugin->alerts->trigger_event(
|
289 |
5003,
|
290 |
array(
|
291 |
'PluginFile' => $plugin_file,
|
295 |
),
|
296 |
)
|
297 |
);
|
298 |
+
self::run_addon_removal_check( $plugin_file );
|
299 |
}
|
300 |
}
|
301 |
}
|
302 |
|
303 |
// Uninstall plugin for WordPress version 4.6.
|
304 |
+
if ( in_array( $action, array( 'delete-plugin' ), true ) && current_user_can( 'delete_plugins' ) ) {
|
305 |
if ( isset( $post_array['plugin'] ) ) {
|
306 |
$plugin_file = WP_PLUGIN_DIR . '/' . $post_array['plugin'];
|
307 |
$plugin_name = basename( $plugin_file, '.php' );
|
308 |
$plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name );
|
309 |
$plugin_name = ucwords( $plugin_name );
|
310 |
$plugin_data = $this->old_plugins[ $post_array['plugin'] ];
|
311 |
+
$this->plugin->alerts->trigger_event(
|
312 |
5003,
|
313 |
array(
|
314 |
'PluginFile' => $plugin_file,
|
319 |
)
|
320 |
);
|
321 |
|
322 |
+
self::run_addon_removal_check( $plugin_file );
|
323 |
}
|
324 |
}
|
325 |
|
326 |
// Upgrade plugin.
|
327 |
+
if ( in_array( $action, array( 'upgrade-plugin', 'update-plugin', 'update-selected' ), true ) && current_user_can( 'update_plugins' ) ) {
|
328 |
$plugins = array();
|
329 |
|
330 |
// Check $_GET array cases.
|
342 |
}
|
343 |
if ( isset( $plugins ) ) {
|
344 |
foreach ( $plugins as $plugin_file ) {
|
345 |
+
self::log_plugin_updated_event( $plugin_file, $this->old_plugins );
|
346 |
}
|
347 |
}
|
348 |
}
|
349 |
|
350 |
// Update theme.
|
351 |
+
if ( in_array( $action, array( 'upgrade-theme', 'update-theme', 'update-selected-themes' ), true ) && current_user_can( 'install_themes' ) ) {
|
352 |
// Themes.
|
353 |
$themes = array();
|
354 |
|
365 |
} elseif ( isset( $post_array['themes'] ) ) {
|
366 |
$themes = explode( ',', $post_array['themes'] );
|
367 |
}
|
368 |
+
if ( isset( $themes ) ) {
|
369 |
+
foreach ( $themes as $theme_name ) {
|
370 |
+
self::log_theme_updated_event( $theme_name );
|
371 |
+
}
|
372 |
+
}
|
373 |
}
|
374 |
|
375 |
// Install theme.
|
376 |
+
if ( in_array( $action, array( 'install-theme', 'upload-theme' ), true ) && current_user_can( 'install_themes' ) ) {
|
377 |
$themes = array_diff( wp_get_themes(), $this->old_themes );
|
378 |
+
foreach ( $themes as $theme ) {
|
379 |
+
$this->plugin->alerts->trigger_event(
|
380 |
5005,
|
381 |
array(
|
382 |
'Theme' => (object) array(
|
393 |
}
|
394 |
|
395 |
// Uninstall theme.
|
396 |
+
if ( in_array( $action, array( 'delete-theme' ), true ) && current_user_can( 'install_themes' ) ) {
|
397 |
+
foreach ( $this->get_removed_themes() as $theme ) {
|
398 |
+
$this->plugin->alerts->trigger_event(
|
399 |
5007,
|
400 |
array(
|
401 |
'Theme' => (object) array(
|
416 |
* Activated a theme.
|
417 |
*
|
418 |
* @param string $theme_name - Theme name.
|
419 |
+
*
|
420 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
421 |
*/
|
422 |
+
public function event_theme_activated( $theme_name ) {
|
423 |
$theme = null;
|
424 |
foreach ( wp_get_themes() as $item ) {
|
425 |
+
if ( $theme_name === $item->Name ) {
|
426 |
$theme = $item;
|
427 |
break;
|
428 |
}
|
429 |
}
|
430 |
+
if ( null == $theme ) { // phpcs:ignore
|
431 |
+
$this->log_error(
|
432 |
'Could not locate theme named "' . $theme . '".',
|
433 |
array(
|
434 |
'ThemeName' => $theme_name,
|
437 |
);
|
438 |
return;
|
439 |
}
|
440 |
+
$this->plugin->alerts->trigger_event(
|
441 |
5006,
|
442 |
array(
|
443 |
'Theme' => (object) array(
|
457 |
*
|
458 |
* @return array of WP_Theme objects
|
459 |
*/
|
460 |
+
protected function get_removed_themes() {
|
461 |
$result = $this->old_themes;
|
462 |
foreach ( $result as $i => $theme ) {
|
463 |
if ( file_exists( $theme->get_template_directory() ) ) {
|
470 |
/**
|
471 |
* Get event code by post type.
|
472 |
*
|
473 |
+
* @param object $post - Post object.
|
474 |
+
* @param int $type_post - Code for post.
|
475 |
+
* @param int $type_page - Code for page.
|
476 |
+
* @param int $type_custom - Code for custom post type.
|
477 |
*
|
478 |
* @return false|int
|
479 |
*/
|
480 |
+
protected function get_event_type_for_post_type( $post, $type_post, $type_page, $type_custom ) {
|
481 |
if ( empty( $post ) || ! isset( $post->post_type ) ) {
|
482 |
return false;
|
483 |
}
|
557 |
$theme = null;
|
558 |
if ( ! empty( $all_themes ) ) {
|
559 |
foreach ( $all_themes as $theme_slug => $theme_obj ) {
|
560 |
+
if ( $theme_name === $theme_slug || $theme_name === $theme_obj->get( 'Name' ) ) {
|
561 |
$theme = $theme_obj;
|
562 |
break;
|
563 |
}
|
566 |
return $theme;
|
567 |
}
|
568 |
|
569 |
+
/**
|
570 |
+
* Runs an add-on check.
|
571 |
+
*
|
572 |
+
* @param string $plugin_dir Plugin directory.
|
573 |
+
*/
|
574 |
public function run_addon_check( $plugin_dir ) {
|
575 |
$plugin_filename = basename( preg_replace( '/\\.[^.\\s]{3,4}$/', '', $plugin_dir ) );
|
576 |
|
588 |
|
589 |
// Check if plugin file starts with the same string as our addon_for, or if its equal.
|
590 |
if ( $plugin_filename === $plugin ) {
|
591 |
+
$addon_slug = array( array_search( $plugin, array_column( $predefined_plugins, 'addon_for', 'plugin_slug' ) ) ); // phpcs:ignore
|
592 |
$is_addon_installed = array_intersect( $all_plugins, $addon_slug );
|
593 |
if ( empty( $is_addon_installed ) ) {
|
594 |
+
$current_value = $this->plugin->get_global_setting( 'installed_plugin_addon_available' );
|
595 |
$plugin_filename = array( $plugin_filename );
|
596 |
if ( isset( $current_value ) && is_array( $current_value ) ) {
|
597 |
$new_plugin_filenames = array_unique( array_merge( $current_value, $plugin_filename ) );
|
598 |
} else {
|
599 |
$new_plugin_filenames = $plugin_filename;
|
600 |
}
|
601 |
+
$this->plugin->set_global_setting( 'installed_plugin_addon_available', $new_plugin_filenames );
|
602 |
+
$this->plugin->delete_global_setting( 'addon_available_notice_dismissed' );
|
603 |
}
|
604 |
}
|
605 |
}
|
606 |
}
|
607 |
|
608 |
+
/**
|
609 |
+
* Checks for an add-on removal.
|
610 |
+
*
|
611 |
+
* @param string $plugin_dir Plugin directory.
|
612 |
+
*/
|
613 |
public static function run_addon_removal_check( $plugin_dir ) {
|
614 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
615 |
$plugin_filename = basename( preg_replace( '/\\.[^.\\s]{3,4}$/', '', $plugin_dir ) );
|
616 |
|
617 |
if ( is_array( $plugin_filename ) ) {
|
627 |
|
628 |
// Check if plugin file starts with the same string as our addon_for, or if its equal.
|
629 |
if ( $plugin_filename === $plugin ) {
|
630 |
+
$current_installed = $wsal->get_global_setting( 'installed_plugin_addon_available' );
|
631 |
+
if ( isset( $current_installed ) && ! empty( $current_installed ) ) {
|
632 |
+
$key = array_search( $plugin, $current_installed ); // phpcs:ignore
|
633 |
+
if ( false !== $key ) {
|
634 |
+
unset( $current_installed[ $key ] );
|
635 |
}
|
636 |
}
|
637 |
|
638 |
+
$wsal->set_global_setting( 'installed_plugin_addon_available', $current_installed );
|
639 |
}
|
640 |
}
|
641 |
}
|
646 |
*
|
647 |
* @since 4.1.4
|
648 |
*
|
649 |
+
* @param string $package The package file.
|
650 |
+
* @param array $new_plugin_data The new plugin data.
|
651 |
+
* @param string $package_type The package type (plugin or theme).
|
652 |
*/
|
653 |
public function OnPackageOverwrite( $package, $new_plugin_data, $package_type ) {
|
654 |
if ( 'plugin' !== $package_type ) {
|
656 |
}
|
657 |
|
658 |
if ( array_key_exists( 'Name', $new_plugin_data ) ) {
|
659 |
+
$plugin_file = self::get_plugin_file_name( $new_plugin_data['Name'] );
|
660 |
if ( ! empty( $plugin_file ) ) {
|
661 |
+
self::log_plugin_updated_event( $plugin_file );
|
662 |
}
|
663 |
}
|
664 |
}
|
671 |
*
|
672 |
* @since 4.1.4
|
673 |
*/
|
674 |
+
public static function log_plugin_updated_event( $plugin_file, $old_plugins = '' ) {
|
675 |
$plugin_file_full = WP_PLUGIN_DIR . '/' . $plugin_file;
|
676 |
$plugin_data = get_plugin_data( $plugin_file_full, false, true );
|
677 |
|
679 |
$new_version = $plugin_data['Version'];
|
680 |
|
681 |
if ( $old_version !== $new_version ) {
|
682 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
683 |
+
$wsal->alerts->trigger_event(
|
684 |
5004,
|
685 |
array(
|
686 |
'PluginFile' => $plugin_file,
|
696 |
}
|
697 |
}
|
698 |
|
699 |
+
/**
|
700 |
+
* Log theme updated event.
|
701 |
+
*
|
702 |
+
* @param string $theme_name Theme name.
|
703 |
+
*
|
704 |
+
* @since 4.1.5
|
705 |
+
*
|
706 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
707 |
+
*/
|
708 |
+
public static function log_theme_updated_event( $theme_name ) {
|
709 |
+
$theme = self::get_theme_by_name( $theme_name );
|
710 |
+
if ( ! $theme instanceof WP_Theme ) {
|
711 |
+
return;
|
712 |
+
}
|
713 |
+
|
714 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
715 |
+
$wsal->alerts->trigger_event(
|
716 |
+
5031,
|
717 |
+
array(
|
718 |
+
'Theme' => (object) array(
|
719 |
+
'Name' => $theme->Name,
|
720 |
+
'ThemeURI' => $theme->ThemeURI,
|
721 |
+
'Description' => $theme->Description,
|
722 |
+
'Author' => $theme->Author,
|
723 |
+
'Version' => $theme->Version,
|
724 |
+
'get_template_directory' => $theme->get_template_directory(),
|
725 |
+
),
|
726 |
+
)
|
727 |
+
);
|
728 |
+
}
|
729 |
}
|
classes/Sensors/Register.php
CHANGED
@@ -22,7 +22,7 @@ class WSAL_Sensors_Register extends WSAL_AbstractSensor {
|
|
22 |
/**
|
23 |
* {@inheritDoc}
|
24 |
*/
|
25 |
-
public function
|
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
|
@@ -60,9 +60,9 @@ class WSAL_Sensors_Register extends WSAL_AbstractSensor {
|
|
60 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
61 |
);
|
62 |
|
63 |
-
if ( $this->
|
64 |
// Registration should not be logged on multisite if event 4024 is fired.
|
65 |
-
$this->plugin->alerts->
|
66 |
4000,
|
67 |
$event_data,
|
68 |
/**
|
@@ -71,11 +71,11 @@ class WSAL_Sensors_Register extends WSAL_AbstractSensor {
|
|
71 |
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
72 |
*/
|
73 |
function ( WSAL_AlertManager $mgr ) {
|
74 |
-
return ! $mgr->
|
75 |
}
|
76 |
);
|
77 |
} else {
|
78 |
-
$this->plugin->alerts->
|
79 |
}
|
80 |
|
81 |
}
|
22 |
/**
|
23 |
* {@inheritDoc}
|
24 |
*/
|
25 |
+
public function hook_events() {
|
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
|
60 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
61 |
);
|
62 |
|
63 |
+
if ( $this->is_multisite() ) {
|
64 |
// Registration should not be logged on multisite if event 4024 is fired.
|
65 |
+
$this->plugin->alerts->trigger_event_if(
|
66 |
4000,
|
67 |
$event_data,
|
68 |
/**
|
71 |
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
72 |
*/
|
73 |
function ( WSAL_AlertManager $mgr ) {
|
74 |
+
return ! $mgr->will_trigger( 4013 );
|
75 |
}
|
76 |
);
|
77 |
} else {
|
78 |
+
$this->plugin->alerts->trigger_event( 4000, $event_data, true );
|
79 |
}
|
80 |
|
81 |
}
|
classes/Sensors/System.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* System activity sensor class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -40,21 +41,21 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
40 |
* 6017 Modified the list of keywords for comments moderation
|
41 |
* 6018 Modified the list of keywords for comments blacklisting
|
42 |
*
|
43 |
-
* @package
|
44 |
* @subpackage sensors
|
45 |
*/
|
46 |
class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
47 |
|
48 |
/**
|
49 |
-
*
|
50 |
*/
|
51 |
-
public function
|
52 |
-
add_action( 'wsal_prune', array( $this, '
|
53 |
-
add_action( 'admin_init', array( $this, '
|
54 |
-
add_action( 'automatic_updates_complete', array( $this, '
|
55 |
|
56 |
// whitelist options.
|
57 |
-
add_action( 'allowed_options', array( $this, '
|
58 |
|
59 |
// Update admin email alert.
|
60 |
add_action( 'update_option_admin_email', array( $this, 'admin_email_changed' ), 10, 3 );
|
@@ -72,8 +73,8 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
72 |
// Check if the option is not empty and is admin_email.
|
73 |
if ( ! empty( $old_value ) && ! empty( $new_value )
|
74 |
&& ! empty( $option ) && 'admin_email' === $option ) {
|
75 |
-
if ( $old_value != $new_value ) {
|
76 |
-
$this->plugin->alerts->
|
77 |
6003,
|
78 |
array(
|
79 |
'OldEmail' => $old_value,
|
@@ -91,8 +92,8 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
91 |
* @param int $count The number of deleted events.
|
92 |
* @param string $query Query that selected events for deletion.
|
93 |
*/
|
94 |
-
public function
|
95 |
-
$this->plugin->alerts->
|
96 |
6000,
|
97 |
array(
|
98 |
'EventCount' => $count,
|
@@ -103,8 +104,11 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
103 |
|
104 |
/**
|
105 |
* Triggered when a user accesses the admin area.
|
|
|
|
|
|
|
106 |
*/
|
107 |
-
public function
|
108 |
// Filter global arrays for security.
|
109 |
$post_array = filter_input_array( INPUT_POST );
|
110 |
$get_array = filter_input_array( INPUT_GET );
|
@@ -112,7 +116,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
112 |
|
113 |
// Destroy all the session of the same user from user profile page.
|
114 |
if ( isset( $post_array['action'] ) && ( 'destroy-sessions' == $post_array['action'] ) && isset( $post_array['user_id'] ) ) {
|
115 |
-
$this->plugin->alerts->
|
116 |
1006,
|
117 |
array(
|
118 |
'TargetUserID' => $post_array['user_id'],
|
@@ -130,22 +134,22 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
130 |
$actype = basename( $server_array['SCRIPT_NAME'], '.php' );
|
131 |
}
|
132 |
|
133 |
-
if ( isset( $post_array['action'] ) && 'toggle-auto-updates' == $post_array['action']
|
134 |
$event_id = ( 'theme' == $post_array['type'] ) ? 5029 : 5028;
|
135 |
|
136 |
if ( 'theme' == $post_array['type'] ) {
|
137 |
$all_themes = wp_get_themes();
|
138 |
-
$our_theme = $all_themes[$post_array['asset']];
|
139 |
$install_location = $our_theme->get_template_directory();
|
140 |
$name = $our_theme->Name;
|
141 |
-
}
|
142 |
$all_plugins = get_plugins();
|
143 |
-
$our_plugin = $all_plugins[$post_array['asset']];
|
144 |
$install_location = plugin_dir_path( WP_PLUGIN_DIR . '/' . $post_array['asset'] );
|
145 |
$name = $our_plugin['Name'];
|
146 |
}
|
147 |
|
148 |
-
$this->plugin->alerts->
|
149 |
$event_id,
|
150 |
array(
|
151 |
'install_directory' => $install_location,
|
@@ -166,7 +170,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
166 |
$old_siteurl = get_option( 'siteurl' );
|
167 |
$new_siteurl = isset( $post_array['siteurl'] ) ? $post_array['siteurl'] : '';
|
168 |
if ( $old_siteurl !== $new_siteurl ) {
|
169 |
-
$this->plugin->alerts->
|
170 |
6024,
|
171 |
array(
|
172 |
'old_url' => $old_siteurl,
|
@@ -184,7 +188,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
184 |
$old_url = get_option( 'home' );
|
185 |
$new_url = isset( $post_array['home'] ) ? $post_array['home'] : '';
|
186 |
if ( $old_url !== $new_url ) {
|
187 |
-
$this->plugin->alerts->
|
188 |
6025,
|
189 |
array(
|
190 |
'old_url' => $old_url,
|
@@ -197,10 +201,10 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
197 |
|
198 |
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] && isset( $post_array['show_on_front'] )
|
199 |
&& wp_verify_nonce( $post_array['_wpnonce'], 'reading-options' ) ) {
|
200 |
-
$old_homepage = ( 'posts' === get_site_option( 'show_on_front' ) ) ? __( 'latest posts', 'wp-security-audit-log' ) :__( 'static page', 'wp-security-audit-log' );
|
201 |
-
$new_homepage = ( 'posts' === $post_array['show_on_front'] ) ? __( 'latest posts', 'wp-security-audit-log' ) :__( 'static page', 'wp-security-audit-log' );
|
202 |
if ( $old_homepage != $new_homepage ) {
|
203 |
-
$this->plugin->alerts->
|
204 |
6035,
|
205 |
array(
|
206 |
'old_homepage' => $old_homepage,
|
@@ -212,10 +216,10 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
212 |
|
213 |
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] && isset( $post_array['page_on_front'] )
|
214 |
&& wp_verify_nonce( $post_array['_wpnonce'], 'reading-options' ) ) {
|
215 |
-
$old_frontpage = get_the_title( get_site_option( 'page_on_front' ) )
|
216 |
-
$new_frontpage = get_the_title( $post_array[
|
217 |
if ( $old_frontpage != $new_frontpage ) {
|
218 |
-
$this->plugin->alerts->
|
219 |
6036,
|
220 |
array(
|
221 |
'old_page' => $old_frontpage,
|
@@ -228,9 +232,9 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
228 |
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] && isset( $post_array['page_for_posts'] )
|
229 |
&& wp_verify_nonce( $post_array['_wpnonce'], 'reading-options' ) ) {
|
230 |
$old_postspage = get_the_title( get_site_option( 'page_for_posts' ) );
|
231 |
-
$new_postspage = get_the_title( $post_array[
|
232 |
if ( $old_postspage != $new_postspage ) {
|
233 |
-
$this->plugin->alerts->
|
234 |
6037,
|
235 |
array(
|
236 |
'old_page' => $old_postspage,
|
@@ -240,17 +244,17 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
240 |
}
|
241 |
}
|
242 |
|
243 |
-
//
|
244 |
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['timezone_string'] ) ) {
|
245 |
$this->check_timezone_change( $post_array );
|
246 |
}
|
247 |
|
248 |
-
//
|
249 |
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['date_format'] ) ) {
|
250 |
$old_date_format = get_option( 'date_format' );
|
251 |
$new_date_format = ( '\c\u\s\t\o\m' === $post_array['date_format'] ) ? $post_array['date_format_custom'] : $post_array['date_format'];
|
252 |
if ( $old_date_format !== $new_date_format ) {
|
253 |
-
$this->plugin->alerts->
|
254 |
6041,
|
255 |
array(
|
256 |
'old_date_format' => $old_date_format,
|
@@ -261,12 +265,12 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
261 |
}
|
262 |
}
|
263 |
|
264 |
-
//
|
265 |
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['time_format'] ) ) {
|
266 |
-
$old_time_format =
|
267 |
$new_time_format = ( '\c\u\s\t\o\m' === $post_array['time_format'] ) ? $post_array['time_format_custom'] : $post_array['time_format'];
|
268 |
if ( $old_time_format !== $new_time_format ) {
|
269 |
-
$this->plugin->alerts->
|
270 |
6042,
|
271 |
array(
|
272 |
'old_time_format' => $old_time_format,
|
@@ -283,7 +287,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
283 |
$new = isset( $post_array['users_can_register'] ) ? 'enabled' : 'disabled';
|
284 |
|
285 |
if ( $old !== $new ) {
|
286 |
-
$this->plugin->alerts->
|
287 |
6001,
|
288 |
array(
|
289 |
'EventType' => $new,
|
@@ -298,7 +302,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
298 |
$old = get_option( 'default_role' );
|
299 |
$new = trim( $post_array['default_role'] );
|
300 |
if ( $old != $new ) {
|
301 |
-
$this->plugin->alerts->
|
302 |
6002,
|
303 |
array(
|
304 |
'OldRole' => $old,
|
@@ -314,7 +318,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
314 |
$old = get_option( 'admin_email' );
|
315 |
$new = trim( $post_array['admin_email'] );
|
316 |
if ( $old != $new ) {
|
317 |
-
$this->plugin->alerts->
|
318 |
6003,
|
319 |
array(
|
320 |
'OldEmail' => $old,
|
@@ -330,7 +334,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
330 |
$old = get_site_option( 'admin_email' );
|
331 |
$new = trim( $post_array['new_admin_email'] );
|
332 |
if ( $old != $new ) {
|
333 |
-
$this->plugin->alerts->
|
334 |
6003,
|
335 |
array(
|
336 |
'OldEmail' => $old,
|
@@ -343,11 +347,11 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
343 |
|
344 |
// Permalinks changed.
|
345 |
if ( $is_permalink_page && ! empty( $post_array['permalink_structure'] )
|
346 |
-
|
347 |
$old = get_option( 'permalink_structure' );
|
348 |
$new = trim( $post_array['permalink_structure'] );
|
349 |
if ( $old != $new ) {
|
350 |
-
$this->plugin->alerts->
|
351 |
6005,
|
352 |
array(
|
353 |
'OldPattern' => $old,
|
@@ -360,11 +364,11 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
360 |
|
361 |
// Core Update.
|
362 |
if ( isset( $get_array['action'] ) && 'do-core-upgrade' === $get_array['action'] && isset( $post_array['version'] )
|
363 |
-
&& wp_verify_nonce( $post_array['_wpnonce'], 'upgrade-core' )) {
|
364 |
$old_version = get_bloginfo( 'version' );
|
365 |
$new_version = $post_array['version'];
|
366 |
if ( $old_version != $new_version ) {
|
367 |
-
$this->plugin->alerts->
|
368 |
6004,
|
369 |
array(
|
370 |
'OldVersion' => $old_version,
|
@@ -377,8 +381,8 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
377 |
// Enable core updates.
|
378 |
if ( isset( $get_array['action'] ) && 'core-major-auto-updates-settings' === $get_array['action'] && isset( $get_array['value'] )
|
379 |
&& wp_verify_nonce( $get_array['_wpnonce'], 'core-major-auto-updates-nonce' ) ) {
|
380 |
-
$status
|
381 |
-
$this->plugin->alerts->
|
382 |
6044,
|
383 |
array(
|
384 |
'updates_status' => $status,
|
@@ -400,11 +404,11 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
400 |
$new_value = ( ! empty( $post_array['WPLANG'] ) ) ? $post_array['WPLANG'] : 'en-US';
|
401 |
|
402 |
// Now lets turn these into a nice, native name - the same as shown to the user when choosing a language.
|
403 |
-
$previous_value = ( isset( $available_translations[$previous_value] ) ) ? $available_translations[$previous_value]['native_name'] : 'English (United States)';
|
404 |
-
$new_value = ( isset( $available_translations[$new_value] ) ) ? $available_translations[$new_value]['native_name'] : 'English (United States)';
|
405 |
|
406 |
if ( $previous_value !== $new_value ) {
|
407 |
-
$this->plugin->alerts->
|
408 |
6045,
|
409 |
array(
|
410 |
'previous_value' => $previous_value,
|
@@ -422,7 +426,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
422 |
$new_value = ( ! empty( $post_array['blogname'] ) ) ? $post_array['blogname'] : '';
|
423 |
|
424 |
if ( $previous_value !== $new_value ) {
|
425 |
-
$this->plugin->alerts->
|
426 |
6059,
|
427 |
array(
|
428 |
'previous_value' => $previous_value,
|
@@ -438,11 +442,11 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
438 |
*
|
439 |
* @param array $automatic - Automatic update array.
|
440 |
*/
|
441 |
-
public function
|
442 |
if ( isset( $automatic['core'][0] ) ) {
|
443 |
$obj = $automatic['core'][0];
|
444 |
$old_version = get_bloginfo( 'version' );
|
445 |
-
$this->plugin->alerts->
|
446 |
6004,
|
447 |
array(
|
448 |
'OldVersion' => $old_version,
|
@@ -459,7 +463,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
459 |
*
|
460 |
* @return array|null
|
461 |
*/
|
462 |
-
public function
|
463 |
// Filter global arrays for security.
|
464 |
$post_array = filter_input_array( INPUT_POST );
|
465 |
|
@@ -468,7 +472,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
468 |
$new_status = isset( $post_array['blog_public'] ) ? 0 : 1;
|
469 |
|
470 |
if ( $old_status !== $new_status ) {
|
471 |
-
$this->plugin->alerts->
|
472 |
6008,
|
473 |
array( 'EventType' => ( 0 === $new_status ) ? 'enabled' : 'disabled' )
|
474 |
);
|
@@ -480,7 +484,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
480 |
$new_status = isset( $post_array['default_comment_status'] ) ? 'open' : 'closed';
|
481 |
|
482 |
if ( $old_status !== $new_status ) {
|
483 |
-
$this->plugin->alerts->
|
484 |
6009,
|
485 |
array( 'EventType' => ( 'open' === $new_status ) ? 'enabled' : 'disabled' )
|
486 |
);
|
@@ -490,7 +494,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
490 |
$new_status = isset( $post_array['require_name_email'] ) ? 1 : 0;
|
491 |
|
492 |
if ( $old_status !== $new_status ) {
|
493 |
-
$this->plugin->alerts->
|
494 |
6010,
|
495 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
496 |
);
|
@@ -500,7 +504,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
500 |
$new_status = isset( $post_array['comment_registration'] ) ? 1 : 0;
|
501 |
|
502 |
if ( $old_status !== $new_status ) {
|
503 |
-
$this->plugin->alerts->
|
504 |
6011,
|
505 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
506 |
);
|
@@ -511,7 +515,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
511 |
|
512 |
if ( $old_status !== $new_status ) {
|
513 |
$value = isset( $post_array['close_comments_days_old'] ) ? $post_array['close_comments_days_old'] : 0;
|
514 |
-
$this->plugin->alerts->
|
515 |
6012,
|
516 |
array(
|
517 |
'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled',
|
@@ -523,7 +527,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
523 |
$old_value = get_option( 'close_comments_days_old', 0 );
|
524 |
$new_value = isset( $post_array['close_comments_days_old'] ) ? $post_array['close_comments_days_old'] : 0;
|
525 |
if ( $old_value !== $new_value ) {
|
526 |
-
$this->plugin->alerts->
|
527 |
6013,
|
528 |
array(
|
529 |
'OldValue' => $old_value,
|
@@ -536,19 +540,19 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
536 |
$new_status = isset( $post_array['comment_moderation'] ) ? 1 : 0;
|
537 |
|
538 |
if ( $old_status !== $new_status ) {
|
539 |
-
$this->plugin->alerts->
|
540 |
6014,
|
541 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
542 |
);
|
543 |
}
|
544 |
|
545 |
-
//
|
546 |
$comment_whitelist_option_name = version_compare( get_bloginfo( 'version' ), '5.5.0', '<' ) ? 'comment_whitelist' : 'comment_previously_approved';
|
547 |
-
$old_status
|
548 |
-
$new_status
|
549 |
|
550 |
if ( $old_status !== $new_status ) {
|
551 |
-
$this->plugin->alerts->
|
552 |
6015,
|
553 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
554 |
);
|
@@ -557,7 +561,7 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
557 |
$old_value = get_option( 'comment_max_links', 0 );
|
558 |
$new_value = isset( $post_array['comment_max_links'] ) ? $post_array['comment_max_links'] : 0;
|
559 |
if ( $old_value !== $new_value ) {
|
560 |
-
$this->plugin->alerts->
|
561 |
6016,
|
562 |
array(
|
563 |
'OldValue' => $old_value,
|
@@ -569,15 +573,15 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
569 |
$old_value = get_option( 'moderation_keys', 0 );
|
570 |
$new_value = isset( $post_array['moderation_keys'] ) ? $post_array['moderation_keys'] : 0;
|
571 |
if ( $old_value !== $new_value ) {
|
572 |
-
$this->plugin->alerts->
|
573 |
}
|
574 |
|
575 |
-
//
|
576 |
$blacklist_keys_option_name = version_compare( get_bloginfo( 'version' ), '5.5.0', '<' ) ? 'blacklist_keys' : 'disallowed_keys';
|
577 |
-
$old_value
|
578 |
-
$new_value
|
579 |
if ( $old_value !== $new_value ) {
|
580 |
-
$this->plugin->alerts->
|
581 |
}
|
582 |
}
|
583 |
return $whitelist;
|
@@ -594,24 +598,24 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
594 |
$old_timezone_string = get_option( 'timezone_string' );
|
595 |
$new_timezone_string = isset( $post_array['timezone_string'] ) ? $post_array['timezone_string'] : '';
|
596 |
|
597 |
-
//
|
598 |
$old_timezone_label = $old_timezone_string;
|
599 |
$new_timezone_label = $new_timezone_string;
|
600 |
if ( strlen( $old_timezone_string ) === 0 ) {
|
601 |
-
//
|
602 |
-
//
|
603 |
-
$old_timezone_string = $old_timezone_label = wp_timezone_string();
|
604 |
if ( 'UTC' === $old_timezone_string ) {
|
605 |
$old_timezone_string = '+00:00';
|
606 |
}
|
607 |
|
608 |
-
//
|
609 |
$old_timezone_label = 'UTC' . $old_timezone_label;
|
610 |
}
|
611 |
|
612 |
-
//
|
613 |
|
614 |
-
//
|
615 |
if ( 'UTC' === $new_timezone_string ) {
|
616 |
$new_timezone_string = 'UTC+0';
|
617 |
}
|
@@ -619,19 +623,19 @@ class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
|
619 |
if ( preg_match( '/UTC([+\-][0-9\.]+)/', $new_timezone_string, $matches ) ) {
|
620 |
$hours_decimal = floatval( $matches[1] );
|
621 |
|
622 |
-
//
|
623 |
-
//
|
624 |
$sign = $hours_decimal < 0 ? '-' : '+';
|
625 |
$abs_hours = abs( $hours_decimal );
|
626 |
$abs_mins = abs( $hours_decimal * 60 % 60 );
|
627 |
$new_timezone_string = sprintf( '%s%02d:%02d', $sign, floor( $abs_hours ), $abs_mins );
|
628 |
|
629 |
-
//
|
630 |
$new_timezone_label = 'UTC' . $new_timezone_string;
|
631 |
}
|
632 |
|
633 |
if ( $old_timezone_string !== $new_timezone_string ) {
|
634 |
-
$this->plugin->alerts->
|
635 |
6040,
|
636 |
array(
|
637 |
'old_timezone' => $old_timezone_label,
|
4 |
*
|
5 |
* System activity sensor class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
41 |
* 6017 Modified the list of keywords for comments moderation
|
42 |
* 6018 Modified the list of keywords for comments blacklisting
|
43 |
*
|
44 |
+
* @package wsal
|
45 |
* @subpackage sensors
|
46 |
*/
|
47 |
class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
48 |
|
49 |
/**
|
50 |
+
* {@inheritDoc}
|
51 |
*/
|
52 |
+
public function hook_events() {
|
53 |
+
add_action( 'wsal_prune', array( $this, 'event_prune_events' ), 10, 2 );
|
54 |
+
add_action( 'admin_init', array( $this, 'event_admin_init' ) );
|
55 |
+
add_action( 'automatic_updates_complete', array( $this, 'wp_update' ), 10, 1 );
|
56 |
|
57 |
// whitelist options.
|
58 |
+
add_action( 'allowed_options', array( $this, 'event_options' ), 10, 1 );
|
59 |
|
60 |
// Update admin email alert.
|
61 |
add_action( 'update_option_admin_email', array( $this, 'admin_email_changed' ), 10, 3 );
|
73 |
// Check if the option is not empty and is admin_email.
|
74 |
if ( ! empty( $old_value ) && ! empty( $new_value )
|
75 |
&& ! empty( $option ) && 'admin_email' === $option ) {
|
76 |
+
if ( $old_value != $new_value ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
77 |
+
$this->plugin->alerts->trigger_event(
|
78 |
6003,
|
79 |
array(
|
80 |
'OldEmail' => $old_value,
|
92 |
* @param int $count The number of deleted events.
|
93 |
* @param string $query Query that selected events for deletion.
|
94 |
*/
|
95 |
+
public function event_prune_events( $count, $query ) {
|
96 |
+
$this->plugin->alerts->trigger_event(
|
97 |
6000,
|
98 |
array(
|
99 |
'EventCount' => $count,
|
104 |
|
105 |
/**
|
106 |
* Triggered when a user accesses the admin area.
|
107 |
+
*
|
108 |
+
* phpcs:disable WordPress.PHP.StrictComparisons.LooseComparison
|
109 |
+
* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
110 |
*/
|
111 |
+
public function event_admin_init() {
|
112 |
// Filter global arrays for security.
|
113 |
$post_array = filter_input_array( INPUT_POST );
|
114 |
$get_array = filter_input_array( INPUT_GET );
|
116 |
|
117 |
// Destroy all the session of the same user from user profile page.
|
118 |
if ( isset( $post_array['action'] ) && ( 'destroy-sessions' == $post_array['action'] ) && isset( $post_array['user_id'] ) ) {
|
119 |
+
$this->plugin->alerts->trigger_event(
|
120 |
1006,
|
121 |
array(
|
122 |
'TargetUserID' => $post_array['user_id'],
|
134 |
$actype = basename( $server_array['SCRIPT_NAME'], '.php' );
|
135 |
}
|
136 |
|
137 |
+
if ( isset( $post_array['action'] ) && 'toggle-auto-updates' == $post_array['action'] ) {
|
138 |
$event_id = ( 'theme' == $post_array['type'] ) ? 5029 : 5028;
|
139 |
|
140 |
if ( 'theme' == $post_array['type'] ) {
|
141 |
$all_themes = wp_get_themes();
|
142 |
+
$our_theme = $all_themes[ $post_array['asset'] ];
|
143 |
$install_location = $our_theme->get_template_directory();
|
144 |
$name = $our_theme->Name;
|
145 |
+
} elseif ( 'plugin' == $post_array['type'] ) {
|
146 |
$all_plugins = get_plugins();
|
147 |
+
$our_plugin = $all_plugins[ $post_array['asset'] ];
|
148 |
$install_location = plugin_dir_path( WP_PLUGIN_DIR . '/' . $post_array['asset'] );
|
149 |
$name = $our_plugin['Name'];
|
150 |
}
|
151 |
|
152 |
+
$this->plugin->alerts->trigger_event(
|
153 |
$event_id,
|
154 |
array(
|
155 |
'install_directory' => $install_location,
|
170 |
$old_siteurl = get_option( 'siteurl' );
|
171 |
$new_siteurl = isset( $post_array['siteurl'] ) ? $post_array['siteurl'] : '';
|
172 |
if ( $old_siteurl !== $new_siteurl ) {
|
173 |
+
$this->plugin->alerts->trigger_event(
|
174 |
6024,
|
175 |
array(
|
176 |
'old_url' => $old_siteurl,
|
188 |
$old_url = get_option( 'home' );
|
189 |
$new_url = isset( $post_array['home'] ) ? $post_array['home'] : '';
|
190 |
if ( $old_url !== $new_url ) {
|
191 |
+
$this->plugin->alerts->trigger_event(
|
192 |
6025,
|
193 |
array(
|
194 |
'old_url' => $old_url,
|
201 |
|
202 |
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] && isset( $post_array['show_on_front'] )
|
203 |
&& wp_verify_nonce( $post_array['_wpnonce'], 'reading-options' ) ) {
|
204 |
+
$old_homepage = ( 'posts' === get_site_option( 'show_on_front' ) ) ? __( 'latest posts', 'wp-security-audit-log' ) : __( 'static page', 'wp-security-audit-log' );
|
205 |
+
$new_homepage = ( 'posts' === $post_array['show_on_front'] ) ? __( 'latest posts', 'wp-security-audit-log' ) : __( 'static page', 'wp-security-audit-log' );
|
206 |
if ( $old_homepage != $new_homepage ) {
|
207 |
+
$this->plugin->alerts->trigger_event(
|
208 |
6035,
|
209 |
array(
|
210 |
'old_homepage' => $old_homepage,
|
216 |
|
217 |
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] && isset( $post_array['page_on_front'] )
|
218 |
&& wp_verify_nonce( $post_array['_wpnonce'], 'reading-options' ) ) {
|
219 |
+
$old_frontpage = get_the_title( get_site_option( 'page_on_front' ) );
|
220 |
+
$new_frontpage = get_the_title( $post_array['page_on_front'] );
|
221 |
if ( $old_frontpage != $new_frontpage ) {
|
222 |
+
$this->plugin->alerts->trigger_event(
|
223 |
6036,
|
224 |
array(
|
225 |
'old_page' => $old_frontpage,
|
232 |
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] && isset( $post_array['page_for_posts'] )
|
233 |
&& wp_verify_nonce( $post_array['_wpnonce'], 'reading-options' ) ) {
|
234 |
$old_postspage = get_the_title( get_site_option( 'page_for_posts' ) );
|
235 |
+
$new_postspage = get_the_title( $post_array['page_for_posts'] );
|
236 |
if ( $old_postspage != $new_postspage ) {
|
237 |
+
$this->plugin->alerts->trigger_event(
|
238 |
6037,
|
239 |
array(
|
240 |
'old_page' => $old_postspage,
|
244 |
}
|
245 |
}
|
246 |
|
247 |
+
// Check timezone change.
|
248 |
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['timezone_string'] ) ) {
|
249 |
$this->check_timezone_change( $post_array );
|
250 |
}
|
251 |
|
252 |
+
// Check date format change.
|
253 |
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['date_format'] ) ) {
|
254 |
$old_date_format = get_option( 'date_format' );
|
255 |
$new_date_format = ( '\c\u\s\t\o\m' === $post_array['date_format'] ) ? $post_array['date_format_custom'] : $post_array['date_format'];
|
256 |
if ( $old_date_format !== $new_date_format ) {
|
257 |
+
$this->plugin->alerts->trigger_event(
|
258 |
6041,
|
259 |
array(
|
260 |
'old_date_format' => $old_date_format,
|
265 |
}
|
266 |
}
|
267 |
|
268 |
+
// Check time format change.
|
269 |
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['time_format'] ) ) {
|
270 |
+
$old_time_format = get_option( 'time_format' );
|
271 |
$new_time_format = ( '\c\u\s\t\o\m' === $post_array['time_format'] ) ? $post_array['time_format_custom'] : $post_array['time_format'];
|
272 |
if ( $old_time_format !== $new_time_format ) {
|
273 |
+
$this->plugin->alerts->trigger_event(
|
274 |
6042,
|
275 |
array(
|
276 |
'old_time_format' => $old_time_format,
|
287 |
$new = isset( $post_array['users_can_register'] ) ? 'enabled' : 'disabled';
|
288 |
|
289 |
if ( $old !== $new ) {
|
290 |
+
$this->plugin->alerts->trigger_event(
|
291 |
6001,
|
292 |
array(
|
293 |
'EventType' => $new,
|
302 |
$old = get_option( 'default_role' );
|
303 |
$new = trim( $post_array['default_role'] );
|
304 |
if ( $old != $new ) {
|
305 |
+
$this->plugin->alerts->trigger_event(
|
306 |
6002,
|
307 |
array(
|
308 |
'OldRole' => $old,
|
318 |
$old = get_option( 'admin_email' );
|
319 |
$new = trim( $post_array['admin_email'] );
|
320 |
if ( $old != $new ) {
|
321 |
+
$this->plugin->alerts->trigger_event(
|
322 |
6003,
|
323 |
array(
|
324 |
'OldEmail' => $old,
|
334 |
$old = get_site_option( 'admin_email' );
|
335 |
$new = trim( $post_array['new_admin_email'] );
|
336 |
if ( $old != $new ) {
|
337 |
+
$this->plugin->alerts->trigger_event(
|
338 |
6003,
|
339 |
array(
|
340 |
'OldEmail' => $old,
|
347 |
|
348 |
// Permalinks changed.
|
349 |
if ( $is_permalink_page && ! empty( $post_array['permalink_structure'] )
|
350 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'update-permalink' ) ) {
|
351 |
$old = get_option( 'permalink_structure' );
|
352 |
$new = trim( $post_array['permalink_structure'] );
|
353 |
if ( $old != $new ) {
|
354 |
+
$this->plugin->alerts->trigger_event(
|
355 |
6005,
|
356 |
array(
|
357 |
'OldPattern' => $old,
|
364 |
|
365 |
// Core Update.
|
366 |
if ( isset( $get_array['action'] ) && 'do-core-upgrade' === $get_array['action'] && isset( $post_array['version'] )
|
367 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'upgrade-core' ) ) {
|
368 |
$old_version = get_bloginfo( 'version' );
|
369 |
$new_version = $post_array['version'];
|
370 |
if ( $old_version != $new_version ) {
|
371 |
+
$this->plugin->alerts->trigger_event(
|
372 |
6004,
|
373 |
array(
|
374 |
'OldVersion' => $old_version,
|
381 |
// Enable core updates.
|
382 |
if ( isset( $get_array['action'] ) && 'core-major-auto-updates-settings' === $get_array['action'] && isset( $get_array['value'] )
|
383 |
&& wp_verify_nonce( $get_array['_wpnonce'], 'core-major-auto-updates-nonce' ) ) {
|
384 |
+
$status = ( 'enable' === $get_array['value'] ) ? esc_html__( 'automatically update to all new versions of WordPress', 'wp-security-audit-log' ) : esc_html__( 'automatically update maintenance and security releases only', 'wp-security-audit-log' );
|
385 |
+
$this->plugin->alerts->trigger_event(
|
386 |
6044,
|
387 |
array(
|
388 |
'updates_status' => $status,
|
404 |
$new_value = ( ! empty( $post_array['WPLANG'] ) ) ? $post_array['WPLANG'] : 'en-US';
|
405 |
|
406 |
// Now lets turn these into a nice, native name - the same as shown to the user when choosing a language.
|
407 |
+
$previous_value = ( isset( $available_translations[ $previous_value ] ) ) ? $available_translations[ $previous_value ]['native_name'] : 'English (United States)';
|
408 |
+
$new_value = ( isset( $available_translations[ $new_value ] ) ) ? $available_translations[ $new_value ]['native_name'] : 'English (United States)';
|
409 |
|
410 |
if ( $previous_value !== $new_value ) {
|
411 |
+
$this->plugin->alerts->trigger_event(
|
412 |
6045,
|
413 |
array(
|
414 |
'previous_value' => $previous_value,
|
426 |
$new_value = ( ! empty( $post_array['blogname'] ) ) ? $post_array['blogname'] : '';
|
427 |
|
428 |
if ( $previous_value !== $new_value ) {
|
429 |
+
$this->plugin->alerts->trigger_event(
|
430 |
6059,
|
431 |
array(
|
432 |
'previous_value' => $previous_value,
|
442 |
*
|
443 |
* @param array $automatic - Automatic update array.
|
444 |
*/
|
445 |
+
public function wp_update( $automatic ) {
|
446 |
if ( isset( $automatic['core'][0] ) ) {
|
447 |
$obj = $automatic['core'][0];
|
448 |
$old_version = get_bloginfo( 'version' );
|
449 |
+
$this->plugin->alerts->trigger_event(
|
450 |
6004,
|
451 |
array(
|
452 |
'OldVersion' => $old_version,
|
463 |
*
|
464 |
* @return array|null
|
465 |
*/
|
466 |
+
public function event_options( $whitelist = null ) {
|
467 |
// Filter global arrays for security.
|
468 |
$post_array = filter_input_array( INPUT_POST );
|
469 |
|
472 |
$new_status = isset( $post_array['blog_public'] ) ? 0 : 1;
|
473 |
|
474 |
if ( $old_status !== $new_status ) {
|
475 |
+
$this->plugin->alerts->trigger_event(
|
476 |
6008,
|
477 |
array( 'EventType' => ( 0 === $new_status ) ? 'enabled' : 'disabled' )
|
478 |
);
|
484 |
$new_status = isset( $post_array['default_comment_status'] ) ? 'open' : 'closed';
|
485 |
|
486 |
if ( $old_status !== $new_status ) {
|
487 |
+
$this->plugin->alerts->trigger_event(
|
488 |
6009,
|
489 |
array( 'EventType' => ( 'open' === $new_status ) ? 'enabled' : 'disabled' )
|
490 |
);
|
494 |
$new_status = isset( $post_array['require_name_email'] ) ? 1 : 0;
|
495 |
|
496 |
if ( $old_status !== $new_status ) {
|
497 |
+
$this->plugin->alerts->trigger_event(
|
498 |
6010,
|
499 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
500 |
);
|
504 |
$new_status = isset( $post_array['comment_registration'] ) ? 1 : 0;
|
505 |
|
506 |
if ( $old_status !== $new_status ) {
|
507 |
+
$this->plugin->alerts->trigger_event(
|
508 |
6011,
|
509 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
510 |
);
|
515 |
|
516 |
if ( $old_status !== $new_status ) {
|
517 |
$value = isset( $post_array['close_comments_days_old'] ) ? $post_array['close_comments_days_old'] : 0;
|
518 |
+
$this->plugin->alerts->trigger_event(
|
519 |
6012,
|
520 |
array(
|
521 |
'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled',
|
527 |
$old_value = get_option( 'close_comments_days_old', 0 );
|
528 |
$new_value = isset( $post_array['close_comments_days_old'] ) ? $post_array['close_comments_days_old'] : 0;
|
529 |
if ( $old_value !== $new_value ) {
|
530 |
+
$this->plugin->alerts->trigger_event(
|
531 |
6013,
|
532 |
array(
|
533 |
'OldValue' => $old_value,
|
540 |
$new_status = isset( $post_array['comment_moderation'] ) ? 1 : 0;
|
541 |
|
542 |
if ( $old_status !== $new_status ) {
|
543 |
+
$this->plugin->alerts->trigger_event(
|
544 |
6014,
|
545 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
546 |
);
|
547 |
}
|
548 |
|
549 |
+
// Comment_whitelist option was renamed to comment_previously_approved in WordPress 5.5.0.
|
550 |
$comment_whitelist_option_name = version_compare( get_bloginfo( 'version' ), '5.5.0', '<' ) ? 'comment_whitelist' : 'comment_previously_approved';
|
551 |
+
$old_status = (int) get_option( $comment_whitelist_option_name, 0 );
|
552 |
+
$new_status = isset( $post_array[ $comment_whitelist_option_name ] ) ? 1 : 0;
|
553 |
|
554 |
if ( $old_status !== $new_status ) {
|
555 |
+
$this->plugin->alerts->trigger_event(
|
556 |
6015,
|
557 |
array( 'EventType' => ( 1 === $new_status ) ? 'enabled' : 'disabled' )
|
558 |
);
|
561 |
$old_value = get_option( 'comment_max_links', 0 );
|
562 |
$new_value = isset( $post_array['comment_max_links'] ) ? $post_array['comment_max_links'] : 0;
|
563 |
if ( $old_value !== $new_value ) {
|
564 |
+
$this->plugin->alerts->trigger_event(
|
565 |
6016,
|
566 |
array(
|
567 |
'OldValue' => $old_value,
|
573 |
$old_value = get_option( 'moderation_keys', 0 );
|
574 |
$new_value = isset( $post_array['moderation_keys'] ) ? $post_array['moderation_keys'] : 0;
|
575 |
if ( $old_value !== $new_value ) {
|
576 |
+
$this->plugin->alerts->trigger_event( 6017, array() );
|
577 |
}
|
578 |
|
579 |
+
// Blacklist_keys option was renamed to disallowed_keys in WordPress 5.5.0.
|
580 |
$blacklist_keys_option_name = version_compare( get_bloginfo( 'version' ), '5.5.0', '<' ) ? 'blacklist_keys' : 'disallowed_keys';
|
581 |
+
$old_value = get_option( $blacklist_keys_option_name, 0 );
|
582 |
+
$new_value = isset( $post_array[ $blacklist_keys_option_name ] ) ? $post_array[ $blacklist_keys_option_name ] : 0;
|
583 |
if ( $old_value !== $new_value ) {
|
584 |
+
$this->plugin->alerts->trigger_event( 6018, array() );
|
585 |
}
|
586 |
}
|
587 |
return $whitelist;
|
598 |
$old_timezone_string = get_option( 'timezone_string' );
|
599 |
$new_timezone_string = isset( $post_array['timezone_string'] ) ? $post_array['timezone_string'] : '';
|
600 |
|
601 |
+
// Backup of the labels as we might change them below when dealing with UTC offset definitions.
|
602 |
$old_timezone_label = $old_timezone_string;
|
603 |
$new_timezone_label = $new_timezone_string;
|
604 |
if ( strlen( $old_timezone_string ) === 0 ) {
|
605 |
+
// The old timezone string can be empty if the time zone was configured using UTC offset selection
|
606 |
+
// rather than using a country/city selection.
|
607 |
+
$old_timezone_string = $old_timezone_label = wp_timezone_string(); // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
|
608 |
if ( 'UTC' === $old_timezone_string ) {
|
609 |
$old_timezone_string = '+00:00';
|
610 |
}
|
611 |
|
612 |
+
// Adjusts label to show UTC offset consistently.
|
613 |
$old_timezone_label = 'UTC' . $old_timezone_label;
|
614 |
}
|
615 |
|
616 |
+
// New timezone can be defined as UTC offset.
|
617 |
|
618 |
+
// There is one UTC option that doesn't contain the offset, we need to tweak the value for further processing.
|
619 |
if ( 'UTC' === $new_timezone_string ) {
|
620 |
$new_timezone_string = 'UTC+0';
|
621 |
}
|
623 |
if ( preg_match( '/UTC([+\-][0-9\.]+)/', $new_timezone_string, $matches ) ) {
|
624 |
$hours_decimal = floatval( $matches[1] );
|
625 |
|
626 |
+
// The new timezone is also set using UTC offset, it needs to be converted to the same format used
|
627 |
+
// by wp_timezone_string.
|
628 |
$sign = $hours_decimal < 0 ? '-' : '+';
|
629 |
$abs_hours = abs( $hours_decimal );
|
630 |
$abs_mins = abs( $hours_decimal * 60 % 60 );
|
631 |
$new_timezone_string = sprintf( '%s%02d:%02d', $sign, floor( $abs_hours ), $abs_mins );
|
632 |
|
633 |
+
// Adjusts label to show UTC offset consistently.
|
634 |
$new_timezone_label = 'UTC' . $new_timezone_string;
|
635 |
}
|
636 |
|
637 |
if ( $old_timezone_string !== $new_timezone_string ) {
|
638 |
+
$this->plugin->alerts->trigger_event(
|
639 |
6040,
|
640 |
array(
|
641 |
'old_timezone' => $old_timezone_label,
|
classes/Sensors/UserProfile.php
CHANGED
@@ -4,10 +4,10 @@
|
|
4 |
*
|
5 |
* User profile sensor file.
|
6 |
*
|
7 |
-
* @package
|
8 |
* @subpackage sensors
|
9 |
*
|
10 |
-
* @since
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly.
|
@@ -29,7 +29,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
29 |
* 4009 User revoked from Super Admin privileges
|
30 |
* 4014 User opened the profile page of another user
|
31 |
*
|
32 |
-
* @package
|
33 |
* @subpackage sensors
|
34 |
*/
|
35 |
class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
@@ -44,7 +44,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
44 |
/**
|
45 |
* {@inheritDoc}
|
46 |
*/
|
47 |
-
public function
|
48 |
add_action( 'profile_update', array( $this, 'event_user_updated' ), 10, 2 );
|
49 |
add_action( 'set_user_role', array( $this, 'event_user_role_changed' ), 10, 3 );
|
50 |
add_action( 'delete_user', array( $this, 'event_user_deleted' ) );
|
@@ -68,6 +68,8 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
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 |
|
@@ -95,15 +97,21 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
95 |
|
96 |
$current_user = get_user_by( 'id', $user_id );
|
97 |
$current_userdata = get_userdata( $user_id );
|
98 |
-
$current_user_roles = implode(
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
$event_id = ( 'user-edit' === $referer_check ) ? 4026 : 4025;
|
103 |
|
104 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
105 |
if ( isset( $_POST['name'] ) ) {
|
106 |
-
$this->plugin->alerts->
|
107 |
$event_id,
|
108 |
array(
|
109 |
'roles' => $current_user_roles,
|
@@ -120,7 +128,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
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->
|
124 |
$event_id,
|
125 |
array(
|
126 |
'roles' => $current_user_roles,
|
@@ -139,7 +147,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
139 |
$event_id = ( 'user-edit' === $referer_check ) ? 4026 : 4025;
|
140 |
|
141 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
142 |
-
$this->plugin->alerts->
|
143 |
$event_id,
|
144 |
array(
|
145 |
'roles' => $current_user_roles,
|
@@ -170,7 +178,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
170 |
if ( $old_userdata->user_pass !== $new_userdata->user_pass ) {
|
171 |
$event = get_current_user_id() === $user_id ? 4003 : 4004;
|
172 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
173 |
-
$this->plugin->alerts->
|
174 |
$event,
|
175 |
array(
|
176 |
'TargetUserID' => $user_id,
|
@@ -189,7 +197,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
189 |
if ( $old_userdata->user_email !== $new_userdata->user_email ) {
|
190 |
$event = get_current_user_id() === $user_id ? 4005 : 4006;
|
191 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
192 |
-
$this->plugin->alerts->
|
193 |
$event,
|
194 |
array(
|
195 |
'TargetUserID' => $user_id,
|
@@ -207,7 +215,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
207 |
// Alert if display name is changed.
|
208 |
if ( $old_userdata->display_name !== $new_userdata->display_name ) {
|
209 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
210 |
-
$this->plugin->alerts->
|
211 |
4020,
|
212 |
array(
|
213 |
'TargetUsername' => $new_userdata->user_login,
|
@@ -224,7 +232,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
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->
|
228 |
4021,
|
229 |
array(
|
230 |
'TargetUsername' => $new_userdata->user_login,
|
@@ -241,7 +249,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
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'] ) {
|
244 |
-
$this->event_user_role_changed( $user_id, $_POST['members_user_roles'], $old_userdata->roles, true );
|
245 |
}
|
246 |
}
|
247 |
}
|
@@ -274,7 +282,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
274 |
|
275 |
// Alert if roles are changed.
|
276 |
if ( $old_roles !== $new_roles ) {
|
277 |
-
$this->plugin->alerts->
|
278 |
4002,
|
279 |
array(
|
280 |
'TargetUserID' => $user_id,
|
@@ -284,9 +292,9 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
284 |
'FirstName' => $user->user_firstname,
|
285 |
'LastName' => $user->user_lastname,
|
286 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
287 |
-
'multisite_text' => $this->plugin->
|
288 |
),
|
289 |
-
array( $this, '
|
290 |
);
|
291 |
}
|
292 |
}
|
@@ -299,7 +307,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
299 |
public function event_user_deleted( $user_id ) {
|
300 |
$user = get_userdata( $user_id );
|
301 |
$role = is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles;
|
302 |
-
$this->plugin->alerts->
|
303 |
4007,
|
304 |
array(
|
305 |
'TargetUserID' => $user_id,
|
@@ -311,7 +319,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
311 |
'Roles' => $role ? $role : 'none',
|
312 |
),
|
313 |
),
|
314 |
-
array( $this, '
|
315 |
);
|
316 |
}
|
317 |
|
@@ -326,10 +334,10 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
326 |
}
|
327 |
|
328 |
$current_user = wp_get_current_user();
|
329 |
-
$updated = isset( $_GET['updated'] ); //
|
330 |
if ( $current_user && ( $user->ID !== $current_user->ID ) && ! $updated ) {
|
331 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $user->roles ) );
|
332 |
-
$this->plugin->alerts->
|
333 |
4014,
|
334 |
array(
|
335 |
'UserChanger' => $current_user->user_login,
|
@@ -347,7 +355,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
347 |
* Triggered when a user accesses the admin area.
|
348 |
*/
|
349 |
public function get_super_admins() {
|
350 |
-
$this->old_superadmins = $this->
|
351 |
}
|
352 |
|
353 |
/**
|
@@ -362,7 +370,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
362 |
public function event_super_access_granted( $user_id ) {
|
363 |
$user = get_userdata( $user_id );
|
364 |
if ( $user && ! in_array( $user->user_login, $this->old_superadmins, true ) ) {
|
365 |
-
$this->plugin->alerts->
|
366 |
4008,
|
367 |
array(
|
368 |
'TargetUserID' => $user_id,
|
@@ -388,7 +396,7 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
388 |
public function event_super_access_revoked( $user_id ) {
|
389 |
$user = get_userdata( $user_id );
|
390 |
if ( $user && in_array( $user->user_login, $this->old_superadmins, true ) ) {
|
391 |
-
$this->plugin->alerts->
|
392 |
4009,
|
393 |
array(
|
394 |
'TargetUserID' => $user_id,
|
@@ -411,12 +419,18 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
411 |
$current_user = get_user_by( 'login', $user_login );
|
412 |
|
413 |
$current_userdata = get_userdata( $current_user->ID );
|
414 |
-
$current_user_roles = implode(
|
415 |
-
|
416 |
-
|
417 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
418 |
|
419 |
-
$this->plugin->alerts->
|
420 |
4029,
|
421 |
array(
|
422 |
'roles' => $current_user_roles,
|
@@ -448,8 +462,8 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
448 |
*
|
449 |
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
450 |
*/
|
451 |
-
public function
|
452 |
-
return ! $mgr->
|
453 |
}
|
454 |
|
455 |
/**
|
@@ -457,13 +471,13 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
457 |
*
|
458 |
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
459 |
*/
|
460 |
-
public function
|
461 |
return ! (
|
462 |
-
$mgr->
|
463 |
-
|| $mgr->
|
464 |
-
|| $mgr->
|
465 |
-
|| $mgr->
|
466 |
-
|| $mgr->
|
467 |
);
|
468 |
}
|
469 |
|
@@ -495,10 +509,10 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
495 |
'LastName' => ! empty( $user->user_lastname ) ? $user->user_lastname : '',
|
496 |
);
|
497 |
|
498 |
-
$event_code = $this->plugin->
|
499 |
if ( 4001 === $event_code ) {
|
500 |
$new_user_data['Roles'] = is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles;
|
501 |
-
}
|
502 |
$new_user_data['Email'] = $user->user_email;
|
503 |
}
|
504 |
|
@@ -508,6 +522,6 @@ class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
|
508 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
509 |
);
|
510 |
|
511 |
-
$this->plugin->alerts->
|
512 |
}
|
513 |
}
|
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.
|
29 |
* 4009 User revoked from Super Admin privileges
|
30 |
* 4014 User opened the profile page of another user
|
31 |
*
|
32 |
+
* @package wsal
|
33 |
* @subpackage sensors
|
34 |
*/
|
35 |
class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
|
44 |
/**
|
45 |
* {@inheritDoc}
|
46 |
*/
|
47 |
+
public function hook_events() {
|
48 |
add_action( 'profile_update', array( $this, 'event_user_updated' ), 10, 2 );
|
49 |
add_action( 'set_user_role', array( $this, 'event_user_role_changed' ), 10, 3 );
|
50 |
add_action( 'delete_user', array( $this, 'event_user_deleted' ) );
|
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 |
+
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
73 |
*/
|
74 |
public function event_application_password_added( $meta_id, $user_id, $meta_key, $_meta_value ) {
|
75 |
|
97 |
|
98 |
$current_user = get_user_by( 'id', $user_id );
|
99 |
$current_userdata = get_userdata( $user_id );
|
100 |
+
$current_user_roles = implode(
|
101 |
+
', ',
|
102 |
+
array_map(
|
103 |
+
array(
|
104 |
+
$this,
|
105 |
+
'filter_role_names',
|
106 |
+
),
|
107 |
+
$current_userdata->roles
|
108 |
+
)
|
109 |
+
);
|
110 |
$event_id = ( 'user-edit' === $referer_check ) ? 4026 : 4025;
|
111 |
|
112 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
113 |
if ( isset( $_POST['name'] ) ) {
|
114 |
+
$this->plugin->alerts->trigger_event(
|
115 |
$event_id,
|
116 |
array(
|
117 |
'roles' => $current_user_roles,
|
128 |
$event_id = ( 'user-edit' === $referer_check ) ? 4028 : 4027;
|
129 |
|
130 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
131 |
+
$this->plugin->alerts->trigger_event(
|
132 |
$event_id,
|
133 |
array(
|
134 |
'roles' => $current_user_roles,
|
147 |
$event_id = ( 'user-edit' === $referer_check ) ? 4026 : 4025;
|
148 |
|
149 |
// Note, firstname and lastname fields are purposefully spaces to avoid NULL.
|
150 |
+
$this->plugin->alerts->trigger_event(
|
151 |
$event_id,
|
152 |
array(
|
153 |
'roles' => $current_user_roles,
|
178 |
if ( $old_userdata->user_pass !== $new_userdata->user_pass ) {
|
179 |
$event = get_current_user_id() === $user_id ? 4003 : 4004;
|
180 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
181 |
+
$this->plugin->alerts->trigger_event(
|
182 |
$event,
|
183 |
array(
|
184 |
'TargetUserID' => $user_id,
|
197 |
if ( $old_userdata->user_email !== $new_userdata->user_email ) {
|
198 |
$event = get_current_user_id() === $user_id ? 4005 : 4006;
|
199 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
200 |
+
$this->plugin->alerts->trigger_event(
|
201 |
$event,
|
202 |
array(
|
203 |
'TargetUserID' => $user_id,
|
215 |
// Alert if display name is changed.
|
216 |
if ( $old_userdata->display_name !== $new_userdata->display_name ) {
|
217 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
218 |
+
$this->plugin->alerts->trigger_event(
|
219 |
4020,
|
220 |
array(
|
221 |
'TargetUsername' => $new_userdata->user_login,
|
232 |
// Alert if website URL is changed.
|
233 |
if ( $old_userdata->user_url !== $new_userdata->user_url ) {
|
234 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $new_userdata->roles ) );
|
235 |
+
$this->plugin->alerts->trigger_event(
|
236 |
4021,
|
237 |
array(
|
238 |
'TargetUsername' => $new_userdata->user_login,
|
249 |
// Alert if role has changed via Members plugin.
|
250 |
if ( isset( $_POST['members_user_roles'] ) && ! empty( $_POST['members_user_roles'] ) ) {
|
251 |
if ( $old_userdata->roles !== $_POST['members_user_roles'] ) {
|
252 |
+
$this->event_user_role_changed( $user_id, $_POST['members_user_roles'], $old_userdata->roles, true ); // phpcs:ignore
|
253 |
}
|
254 |
}
|
255 |
}
|
282 |
|
283 |
// Alert if roles are changed.
|
284 |
if ( $old_roles !== $new_roles ) {
|
285 |
+
$this->plugin->alerts->trigger_event_if(
|
286 |
4002,
|
287 |
array(
|
288 |
'TargetUserID' => $user_id,
|
292 |
'FirstName' => $user->user_firstname,
|
293 |
'LastName' => $user->user_lastname,
|
294 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
295 |
+
'multisite_text' => $this->plugin->is_multisite() ? get_current_blog_id() : false,
|
296 |
),
|
297 |
+
array( $this, 'must_not_contain_user_changes' )
|
298 |
);
|
299 |
}
|
300 |
}
|
307 |
public function event_user_deleted( $user_id ) {
|
308 |
$user = get_userdata( $user_id );
|
309 |
$role = is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles;
|
310 |
+
$this->plugin->alerts->trigger_event_if(
|
311 |
4007,
|
312 |
array(
|
313 |
'TargetUserID' => $user_id,
|
319 |
'Roles' => $role ? $role : 'none',
|
320 |
),
|
321 |
),
|
322 |
+
array( $this, 'must_not_contain_create_user' )
|
323 |
);
|
324 |
}
|
325 |
|
334 |
}
|
335 |
|
336 |
$current_user = wp_get_current_user();
|
337 |
+
$updated = isset( $_GET['updated'] ); // phpcs:ignore
|
338 |
if ( $current_user && ( $user->ID !== $current_user->ID ) && ! $updated ) {
|
339 |
$user_roles = implode( ', ', array_map( array( $this, 'filter_role_names' ), $user->roles ) );
|
340 |
+
$this->plugin->alerts->trigger_event(
|
341 |
4014,
|
342 |
array(
|
343 |
'UserChanger' => $current_user->user_login,
|
355 |
* Triggered when a user accesses the admin area.
|
356 |
*/
|
357 |
public function get_super_admins() {
|
358 |
+
$this->old_superadmins = $this->is_multisite() ? get_super_admins() : null;
|
359 |
}
|
360 |
|
361 |
/**
|
370 |
public function event_super_access_granted( $user_id ) {
|
371 |
$user = get_userdata( $user_id );
|
372 |
if ( $user && ! in_array( $user->user_login, $this->old_superadmins, true ) ) {
|
373 |
+
$this->plugin->alerts->trigger_event(
|
374 |
4008,
|
375 |
array(
|
376 |
'TargetUserID' => $user_id,
|
396 |
public function event_super_access_revoked( $user_id ) {
|
397 |
$user = get_userdata( $user_id );
|
398 |
if ( $user && in_array( $user->user_login, $this->old_superadmins, true ) ) {
|
399 |
+
$this->plugin->alerts->trigger_event(
|
400 |
4009,
|
401 |
array(
|
402 |
'TargetUserID' => $user_id,
|
419 |
$current_user = get_user_by( 'login', $user_login );
|
420 |
|
421 |
$current_userdata = get_userdata( $current_user->ID );
|
422 |
+
$current_user_roles = implode(
|
423 |
+
', ',
|
424 |
+
array_map(
|
425 |
+
array(
|
426 |
+
$this,
|
427 |
+
'filter_role_names',
|
428 |
+
),
|
429 |
+
$current_userdata->roles
|
430 |
+
)
|
431 |
+
);
|
432 |
|
433 |
+
$this->plugin->alerts->trigger_event(
|
434 |
4029,
|
435 |
array(
|
436 |
'roles' => $current_user_roles,
|
462 |
*
|
463 |
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
464 |
*/
|
465 |
+
public function must_not_contain_create_user( WSAL_AlertManager $mgr ) {
|
466 |
+
return ! $mgr->will_trigger( 4012 );
|
467 |
}
|
468 |
|
469 |
/**
|
471 |
*
|
472 |
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
473 |
*/
|
474 |
+
public function must_not_contain_user_changes( WSAL_AlertManager $mgr ) {
|
475 |
return ! (
|
476 |
+
$mgr->will_or_has_triggered( 4010 )
|
477 |
+
|| $mgr->will_or_has_triggered( 4011 )
|
478 |
+
|| $mgr->will_or_has_triggered( 4012 )
|
479 |
+
|| $mgr->will_or_has_triggered( 4000 )
|
480 |
+
|| $mgr->will_or_has_triggered( 4001 )
|
481 |
);
|
482 |
}
|
483 |
|
509 |
'LastName' => ! empty( $user->user_lastname ) ? $user->user_lastname : '',
|
510 |
);
|
511 |
|
512 |
+
$event_code = $this->plugin->is_multisite() ? 4012 : 4001;
|
513 |
if ( 4001 === $event_code ) {
|
514 |
$new_user_data['Roles'] = is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles;
|
515 |
+
} elseif ( 4012 === $event_code ) {
|
516 |
$new_user_data['Email'] = $user->user_email;
|
517 |
}
|
518 |
|
522 |
'EditUserLink' => add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) ),
|
523 |
);
|
524 |
|
525 |
+
$this->plugin->alerts->trigger_event( $event_code, $event_data, $this->plugin->is_multisite() );
|
526 |
}
|
527 |
}
|
classes/Sensors/Widgets.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Widgets sensor class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -22,7 +23,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
22 |
* 2045 User moved widget
|
23 |
* 2071 User changed widget position
|
24 |
*
|
25 |
-
* @package
|
26 |
* @subpackage sensors
|
27 |
*/
|
28 |
class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
@@ -32,24 +33,24 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
32 |
*
|
33 |
* @var array
|
34 |
*/
|
35 |
-
protected $
|
36 |
|
37 |
/**
|
38 |
-
*
|
39 |
*/
|
40 |
-
public function
|
41 |
if ( current_user_can( 'edit_theme_options' ) ) {
|
42 |
-
add_action( 'admin_init', array( $this, '
|
43 |
-
add_action( 'admin_init', array( $this, '
|
44 |
}
|
45 |
-
add_action( 'sidebar_admin_setup', array( $this, '
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
* Triggered when a user accesses the admin area.
|
50 |
* Moved widget.
|
51 |
*/
|
52 |
-
public function
|
53 |
// Filter $_POST array for security.
|
54 |
$post_array = filter_input_array( INPUT_POST );
|
55 |
|
@@ -59,7 +60,7 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
59 |
|
60 |
if ( isset( $post_array ) && ! empty( $post_array['sidebars'] ) ) {
|
61 |
$current_sidebars = $post_array['sidebars'];
|
62 |
-
$sidebars
|
63 |
foreach ( $current_sidebars as $key => $val ) {
|
64 |
$sb = array();
|
65 |
if ( ! empty( $val ) ) {
|
@@ -74,15 +75,15 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
74 |
$sidebars[ $key ] = $sb;
|
75 |
}
|
76 |
$current_sidebars = $sidebars;
|
77 |
-
$db_sidebars
|
78 |
-
$widget_name
|
79 |
foreach ( $current_sidebars as $sidebar_name => $values ) {
|
80 |
if ( is_array( $values ) && ! empty( $values ) && isset( $db_sidebars[ $sidebar_name ] ) ) {
|
81 |
foreach ( $values as $widget_name ) {
|
82 |
-
if ( ! in_array( $widget_name, $db_sidebars[ $sidebar_name ] ) ) {
|
83 |
$to_sidebar = $sidebar_name;
|
84 |
foreach ( $db_sidebars as $name => $v ) {
|
85 |
-
if ( is_array( $v ) && ! empty( $v ) && in_array( $widget_name, $v ) ) {
|
86 |
$from_sidebar = $name;
|
87 |
continue;
|
88 |
}
|
@@ -101,16 +102,18 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
101 |
// as at this moment the $wp_registered_sidebars variable is not yet populated
|
102 |
// so we cannot retrieve the name for sidebar-1 || sidebar-2
|
103 |
// we will then check for this variable in the EventWidgetPostMove() event.
|
104 |
-
$this->
|
105 |
'widget' => $widget_name,
|
106 |
-
'from'
|
107 |
-
'to'
|
108 |
);
|
|
|
109 |
return;
|
110 |
}
|
111 |
|
112 |
-
$this->plugin->alerts->
|
113 |
-
2045,
|
|
|
114 |
'WidgetName' => $widget_name,
|
115 |
'OldSidebar' => $from_sidebar,
|
116 |
'NewSidebar' => $to_sidebar,
|
@@ -123,12 +126,12 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
123 |
* Triggered when a user accesses the admin area.
|
124 |
* Changed widget position or moved widget.
|
125 |
*/
|
126 |
-
public function
|
127 |
// Filter $_POST array for security.
|
128 |
$post_array = filter_input_array( INPUT_POST );
|
129 |
|
130 |
// #!-- generates the event 2071
|
131 |
-
if ( isset( $post_array['action'] ) && ('widgets-order'
|
132 |
if ( isset( $post_array['sidebars'] ) ) {
|
133 |
// Get the sidebars from $post_array.
|
134 |
$request_sidebars = array();
|
@@ -158,20 +161,21 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
158 |
foreach ( $request_sidebars as $sidebar_name => $widgets ) {
|
159 |
if ( isset( $sidebar_widgets[ $sidebar_name ] ) ) {
|
160 |
foreach ( $sidebar_widgets[ $sidebar_name ] as $i => $widget_name ) {
|
161 |
-
$index = array_search( $widget_name, $widgets );
|
162 |
// Check to see whether or not the widget has been moved.
|
163 |
-
if ( $i != $index ) {
|
164 |
$sn = $sidebar_name;
|
165 |
// Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebar_name.
|
166 |
if ( $wp_registered_sidebars && isset( $wp_registered_sidebars[ $sidebar_name ] ) ) {
|
167 |
$sn = $wp_registered_sidebars[ $sidebar_name ]['name'];
|
168 |
}
|
169 |
-
$this->plugin->alerts->
|
170 |
-
2071,
|
171 |
-
|
|
|
172 |
'OldPosition' => $i + 1,
|
173 |
'NewPosition' => $index + 1,
|
174 |
-
'Sidebar'
|
175 |
)
|
176 |
);
|
177 |
}
|
@@ -182,29 +186,28 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
182 |
}
|
183 |
}
|
184 |
// #!--
|
185 |
-
if ( $this->
|
186 |
-
$widget_name
|
187 |
-
$from_sidebar = $this->
|
188 |
-
$to_sidebar
|
189 |
|
190 |
global $wp_registered_sidebars;
|
191 |
|
192 |
if ( preg_match( '/^sidebar-/', $from_sidebar ) ) {
|
193 |
$from_sidebar = isset( $wp_registered_sidebars[ $from_sidebar ] )
|
194 |
-
|
195 |
-
|
196 |
-
;
|
197 |
}
|
198 |
|
199 |
if ( preg_match( '/^sidebar-/', $to_sidebar ) ) {
|
200 |
$to_sidebar = isset( $wp_registered_sidebars[ $to_sidebar ] )
|
201 |
-
|
202 |
-
|
203 |
-
;
|
204 |
}
|
205 |
|
206 |
-
$this->plugin->alerts->
|
207 |
-
2045,
|
|
|
208 |
'WidgetName' => $widget_name,
|
209 |
'OldSidebar' => $from_sidebar,
|
210 |
'NewSidebar' => $to_sidebar,
|
@@ -215,8 +218,10 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
215 |
|
216 |
/**
|
217 |
* Widgets Activity (added, modified, deleted).
|
|
|
|
|
218 |
*/
|
219 |
-
public function
|
220 |
// Filter $_POST array for security.
|
221 |
$post_array = filter_input_array( INPUT_POST );
|
222 |
|
@@ -229,32 +234,34 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
229 |
}
|
230 |
|
231 |
global $wp_registered_sidebars;
|
232 |
-
$can_check_sidebar =
|
233 |
|
234 |
switch ( true ) {
|
235 |
// Added widget.
|
236 |
-
case isset( $post_array['add_new'] ) && 'multi'
|
237 |
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
238 |
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
239 |
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
240 |
}
|
241 |
-
$this->plugin->alerts->
|
242 |
-
2042,
|
|
|
243 |
'WidgetName' => $post_array['id_base'],
|
244 |
-
'Sidebar'
|
245 |
)
|
246 |
);
|
247 |
break;
|
248 |
// Deleted widget.
|
249 |
-
case isset( $post_array['delete_widget'] ) && intval( $post_array['delete_widget'] )
|
250 |
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
251 |
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
252 |
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
253 |
}
|
254 |
-
$this->plugin->alerts->
|
255 |
-
2044,
|
|
|
256 |
'WidgetName' => $post_array['id_base'],
|
257 |
-
'Sidebar'
|
258 |
)
|
259 |
);
|
260 |
break;
|
@@ -271,7 +278,7 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
271 |
}
|
272 |
|
273 |
$widget_name = $post_array['id_base'];
|
274 |
-
$sidebar
|
275 |
$widget_data = isset( $post_array[ "widget-$widget_name" ][ $widget_id ] )
|
276 |
? $post_array[ "widget-$widget_name" ][ $widget_id ]
|
277 |
: null;
|
@@ -287,28 +294,29 @@ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
|
287 |
|
288 |
// Transform 'on' -> 1.
|
289 |
foreach ( $widget_data as $k => $v ) {
|
290 |
-
if ( 'on'
|
291 |
$widget_data[ $k ] = 1;
|
292 |
}
|
293 |
}
|
294 |
|
295 |
// Compare - checks for any changes inside widgets.
|
296 |
-
$diff
|
297 |
$count = count( $diff );
|
298 |
if ( $count > 0 ) {
|
299 |
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
300 |
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
301 |
}
|
302 |
-
$this->plugin->alerts->
|
303 |
-
2043,
|
|
|
304 |
'WidgetName' => $widget_name,
|
305 |
-
'Sidebar'
|
306 |
)
|
307 |
);
|
308 |
}
|
309 |
break;
|
310 |
default:
|
311 |
-
//
|
312 |
break;
|
313 |
}
|
314 |
}
|
4 |
*
|
5 |
* Widgets sensor class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage sensors
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
23 |
* 2045 User moved widget
|
24 |
* 2071 User changed widget position
|
25 |
*
|
26 |
+
* @package wsal
|
27 |
* @subpackage sensors
|
28 |
*/
|
29 |
class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
33 |
*
|
34 |
* @var array
|
35 |
*/
|
36 |
+
protected $widget_move_data = null;
|
37 |
|
38 |
/**
|
39 |
+
* {@inheritDoc}
|
40 |
*/
|
41 |
+
public function hook_events() {
|
42 |
if ( current_user_can( 'edit_theme_options' ) ) {
|
43 |
+
add_action( 'admin_init', array( $this, 'event_widget_move' ) );
|
44 |
+
add_action( 'admin_init', array( $this, 'event_widget_post_move' ) );
|
45 |
}
|
46 |
+
add_action( 'sidebar_admin_setup', array( $this, 'event_widget_activity' ) );
|
47 |
}
|
48 |
|
49 |
/**
|
50 |
* Triggered when a user accesses the admin area.
|
51 |
* Moved widget.
|
52 |
*/
|
53 |
+
public function event_widget_move() {
|
54 |
// Filter $_POST array for security.
|
55 |
$post_array = filter_input_array( INPUT_POST );
|
56 |
|
60 |
|
61 |
if ( isset( $post_array ) && ! empty( $post_array['sidebars'] ) ) {
|
62 |
$current_sidebars = $post_array['sidebars'];
|
63 |
+
$sidebars = array();
|
64 |
foreach ( $current_sidebars as $key => $val ) {
|
65 |
$sb = array();
|
66 |
if ( ! empty( $val ) ) {
|
75 |
$sidebars[ $key ] = $sb;
|
76 |
}
|
77 |
$current_sidebars = $sidebars;
|
78 |
+
$db_sidebars = get_option( 'sidebars_widgets' );
|
79 |
+
$widget_name = $from_sidebar = $to_sidebar = ''; // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
|
80 |
foreach ( $current_sidebars as $sidebar_name => $values ) {
|
81 |
if ( is_array( $values ) && ! empty( $values ) && isset( $db_sidebars[ $sidebar_name ] ) ) {
|
82 |
foreach ( $values as $widget_name ) {
|
83 |
+
if ( ! in_array( $widget_name, $db_sidebars[ $sidebar_name ] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
84 |
$to_sidebar = $sidebar_name;
|
85 |
foreach ( $db_sidebars as $name => $v ) {
|
86 |
+
if ( is_array( $v ) && ! empty( $v ) && in_array( $widget_name, $v ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
|
87 |
$from_sidebar = $name;
|
88 |
continue;
|
89 |
}
|
102 |
// as at this moment the $wp_registered_sidebars variable is not yet populated
|
103 |
// so we cannot retrieve the name for sidebar-1 || sidebar-2
|
104 |
// we will then check for this variable in the EventWidgetPostMove() event.
|
105 |
+
$this->widget_move_data = array(
|
106 |
'widget' => $widget_name,
|
107 |
+
'from' => $from_sidebar,
|
108 |
+
'to' => $to_sidebar,
|
109 |
);
|
110 |
+
|
111 |
return;
|
112 |
}
|
113 |
|
114 |
+
$this->plugin->alerts->trigger_event(
|
115 |
+
2045,
|
116 |
+
array(
|
117 |
'WidgetName' => $widget_name,
|
118 |
'OldSidebar' => $from_sidebar,
|
119 |
'NewSidebar' => $to_sidebar,
|
126 |
* Triggered when a user accesses the admin area.
|
127 |
* Changed widget position or moved widget.
|
128 |
*/
|
129 |
+
public function event_widget_post_move() {
|
130 |
// Filter $_POST array for security.
|
131 |
$post_array = filter_input_array( INPUT_POST );
|
132 |
|
133 |
// #!-- generates the event 2071
|
134 |
+
if ( isset( $post_array['action'] ) && ( 'widgets-order' === $post_array['action'] ) ) {
|
135 |
if ( isset( $post_array['sidebars'] ) ) {
|
136 |
// Get the sidebars from $post_array.
|
137 |
$request_sidebars = array();
|
161 |
foreach ( $request_sidebars as $sidebar_name => $widgets ) {
|
162 |
if ( isset( $sidebar_widgets[ $sidebar_name ] ) ) {
|
163 |
foreach ( $sidebar_widgets[ $sidebar_name ] as $i => $widget_name ) {
|
164 |
+
$index = array_search( $widget_name, $widgets ); // phpcs:ignore
|
165 |
// Check to see whether or not the widget has been moved.
|
166 |
+
if ( $i != $index ) { // phpcs:ignore
|
167 |
$sn = $sidebar_name;
|
168 |
// Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebar_name.
|
169 |
if ( $wp_registered_sidebars && isset( $wp_registered_sidebars[ $sidebar_name ] ) ) {
|
170 |
$sn = $wp_registered_sidebars[ $sidebar_name ]['name'];
|
171 |
}
|
172 |
+
$this->plugin->alerts->trigger_event(
|
173 |
+
2071,
|
174 |
+
array(
|
175 |
+
'WidgetName' => $widget_name,
|
176 |
'OldPosition' => $i + 1,
|
177 |
'NewPosition' => $index + 1,
|
178 |
+
'Sidebar' => $sn,
|
179 |
)
|
180 |
);
|
181 |
}
|
186 |
}
|
187 |
}
|
188 |
// #!--
|
189 |
+
if ( $this->widget_move_data ) {
|
190 |
+
$widget_name = $this->widget_move_data['widget'];
|
191 |
+
$from_sidebar = $this->widget_move_data['from'];
|
192 |
+
$to_sidebar = $this->widget_move_data['to'];
|
193 |
|
194 |
global $wp_registered_sidebars;
|
195 |
|
196 |
if ( preg_match( '/^sidebar-/', $from_sidebar ) ) {
|
197 |
$from_sidebar = isset( $wp_registered_sidebars[ $from_sidebar ] )
|
198 |
+
? $wp_registered_sidebars[ $from_sidebar ]['name']
|
199 |
+
: $from_sidebar;
|
|
|
200 |
}
|
201 |
|
202 |
if ( preg_match( '/^sidebar-/', $to_sidebar ) ) {
|
203 |
$to_sidebar = isset( $wp_registered_sidebars[ $to_sidebar ] )
|
204 |
+
? $wp_registered_sidebars[ $to_sidebar ]['name']
|
205 |
+
: $to_sidebar;
|
|
|
206 |
}
|
207 |
|
208 |
+
$this->plugin->alerts->trigger_event(
|
209 |
+
2045,
|
210 |
+
array(
|
211 |
'WidgetName' => $widget_name,
|
212 |
'OldSidebar' => $from_sidebar,
|
213 |
'NewSidebar' => $to_sidebar,
|
218 |
|
219 |
/**
|
220 |
* Widgets Activity (added, modified, deleted).
|
221 |
+
*
|
222 |
+
* phpcs:disable WordPress.Arrays.ArrayKeySpacingRestrictions.NoSpacesAroundArrayKeys
|
223 |
*/
|
224 |
+
public function event_widget_activity() {
|
225 |
// Filter $_POST array for security.
|
226 |
$post_array = filter_input_array( INPUT_POST );
|
227 |
|
234 |
}
|
235 |
|
236 |
global $wp_registered_sidebars;
|
237 |
+
$can_check_sidebar = ! empty( $wp_registered_sidebars );
|
238 |
|
239 |
switch ( true ) {
|
240 |
// Added widget.
|
241 |
+
case isset( $post_array['add_new'] ) && 'multi' === $post_array['add_new']:
|
242 |
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
243 |
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
244 |
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
245 |
}
|
246 |
+
$this->plugin->alerts->trigger_event(
|
247 |
+
2042,
|
248 |
+
array(
|
249 |
'WidgetName' => $post_array['id_base'],
|
250 |
+
'Sidebar' => $sidebar,
|
251 |
)
|
252 |
);
|
253 |
break;
|
254 |
// Deleted widget.
|
255 |
+
case isset( $post_array['delete_widget'] ) && 1 === intval( $post_array['delete_widget'] ):
|
256 |
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
257 |
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
258 |
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
259 |
}
|
260 |
+
$this->plugin->alerts->trigger_event(
|
261 |
+
2044,
|
262 |
+
array(
|
263 |
'WidgetName' => $post_array['id_base'],
|
264 |
+
'Sidebar' => $sidebar,
|
265 |
)
|
266 |
);
|
267 |
break;
|
278 |
}
|
279 |
|
280 |
$widget_name = $post_array['id_base'];
|
281 |
+
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
282 |
$widget_data = isset( $post_array[ "widget-$widget_name" ][ $widget_id ] )
|
283 |
? $post_array[ "widget-$widget_name" ][ $widget_id ]
|
284 |
: null;
|
294 |
|
295 |
// Transform 'on' -> 1.
|
296 |
foreach ( $widget_data as $k => $v ) {
|
297 |
+
if ( 'on' === $v ) {
|
298 |
$widget_data[ $k ] = 1;
|
299 |
}
|
300 |
}
|
301 |
|
302 |
// Compare - checks for any changes inside widgets.
|
303 |
+
$diff = array_diff_assoc( $widget_data, $widget_db_data[ $widget_id ] );
|
304 |
$count = count( $diff );
|
305 |
if ( $count > 0 ) {
|
306 |
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
307 |
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
308 |
}
|
309 |
+
$this->plugin->alerts->trigger_event(
|
310 |
+
2043,
|
311 |
+
array(
|
312 |
'WidgetName' => $widget_name,
|
313 |
+
'Sidebar' => $sidebar,
|
314 |
)
|
315 |
);
|
316 |
}
|
317 |
break;
|
318 |
default:
|
319 |
+
// Fallback for any other cases would go here.
|
320 |
break;
|
321 |
}
|
322 |
}
|
classes/Settings.php
CHANGED
@@ -31,7 +31,7 @@ class WSAL_Settings {
|
|
31 |
*
|
32 |
* @var WpSecurityAuditLog
|
33 |
*/
|
34 |
-
protected $
|
35 |
|
36 |
const ERROR_CODE_INVALID_IP = 901;
|
37 |
|
@@ -47,70 +47,70 @@ class WSAL_Settings {
|
|
47 |
*
|
48 |
* @var string
|
49 |
*/
|
50 |
-
protected $
|
51 |
|
52 |
/**
|
53 |
* IDs of disabled alerts.
|
54 |
*
|
55 |
* @var array
|
56 |
*/
|
57 |
-
protected $
|
58 |
|
59 |
/**
|
60 |
* Allowed Plugin Viewers.
|
61 |
*
|
62 |
* @var array
|
63 |
*/
|
64 |
-
protected $
|
65 |
|
66 |
/**
|
67 |
* Alerts per page.
|
68 |
*
|
69 |
* @var int
|
70 |
*/
|
71 |
-
protected $
|
72 |
|
73 |
/**
|
74 |
* Users excluded from monitoring.
|
75 |
*
|
76 |
* @var array
|
77 |
*/
|
78 |
-
protected $
|
79 |
|
80 |
/**
|
81 |
* Roles excluded from monitoring.
|
82 |
*
|
83 |
* @var array
|
84 |
*/
|
85 |
-
protected $
|
86 |
|
87 |
/**
|
88 |
* Custom post meta fields excluded from monitoring.
|
89 |
*
|
90 |
* @var array
|
91 |
*/
|
92 |
-
protected $
|
93 |
|
94 |
/**
|
95 |
* Custom user meta fields excluded from monitoring.
|
96 |
*
|
97 |
* @var array
|
98 |
*/
|
99 |
-
protected $
|
100 |
|
101 |
/**
|
102 |
* Custom Post Types excluded from monitoring.
|
103 |
*
|
104 |
* @var array
|
105 |
*/
|
106 |
-
protected $
|
107 |
|
108 |
/**
|
109 |
* IP excluded from monitoring.
|
110 |
*
|
111 |
* @var array
|
112 |
*/
|
113 |
-
protected $
|
114 |
|
115 |
/**
|
116 |
* Alerts enabled in Geek mode.
|
@@ -140,10 +140,10 @@ class WSAL_Settings {
|
|
140 |
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
141 |
*/
|
142 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
143 |
-
$this->
|
144 |
// some settings here may be called before the options helper is setup.
|
145 |
-
if ( ! isset( $this->
|
146 |
-
$this->
|
147 |
}
|
148 |
add_action( 'deactivated_plugin', array( $this, 'reset_stealth_mode' ), 10, 1 );
|
149 |
}
|
@@ -154,14 +154,14 @@ class WSAL_Settings {
|
|
154 |
*/
|
155 |
public function set_basic_mode() {
|
156 |
// Disable alerts of geek mode and alerts to be always disabled.
|
157 |
-
$this->
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
* Enable Geek Mode.
|
162 |
*/
|
163 |
public function set_geek_mode() {
|
164 |
-
$this->
|
165 |
}
|
166 |
|
167 |
|
@@ -170,8 +170,8 @@ class WSAL_Settings {
|
|
170 |
*
|
171 |
* @return boolean
|
172 |
*/
|
173 |
-
public function
|
174 |
-
return ! $this->
|
175 |
}
|
176 |
|
177 |
/**
|
@@ -179,8 +179,8 @@ class WSAL_Settings {
|
|
179 |
*
|
180 |
* @param boolean $newvalue - True if enabled.
|
181 |
*/
|
182 |
-
public function
|
183 |
-
$this->
|
184 |
}
|
185 |
|
186 |
/**
|
@@ -191,7 +191,7 @@ class WSAL_Settings {
|
|
191 |
* @return boolean
|
192 |
*/
|
193 |
public function is_admin_bar_notif() {
|
194 |
-
return ! $this->
|
195 |
}
|
196 |
|
197 |
/**
|
@@ -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->
|
206 |
}
|
207 |
|
208 |
/**
|
@@ -213,7 +213,7 @@ class WSAL_Settings {
|
|
213 |
* @return string
|
214 |
*/
|
215 |
public function get_admin_bar_notif_updates() {
|
216 |
-
return $this->
|
217 |
}
|
218 |
|
219 |
/**
|
@@ -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->
|
228 |
}
|
229 |
|
230 |
/**
|
@@ -232,8 +232,8 @@ class WSAL_Settings {
|
|
232 |
*
|
233 |
* @return boolean
|
234 |
*/
|
235 |
-
public function
|
236 |
-
return ! $this->
|
237 |
}
|
238 |
|
239 |
/**
|
@@ -241,8 +241,8 @@ class WSAL_Settings {
|
|
241 |
*
|
242 |
* @param boolean $newvalue - True if enabled.
|
243 |
*/
|
244 |
-
public function
|
245 |
-
$this->
|
246 |
}
|
247 |
|
248 |
/**
|
@@ -250,7 +250,7 @@ class WSAL_Settings {
|
|
250 |
*
|
251 |
* @return int
|
252 |
*/
|
253 |
-
public function
|
254 |
return 5;
|
255 |
}
|
256 |
|
@@ -259,7 +259,7 @@ class WSAL_Settings {
|
|
259 |
*
|
260 |
* @return int
|
261 |
*/
|
262 |
-
public function
|
263 |
return 5000;
|
264 |
}
|
265 |
|
@@ -268,7 +268,7 @@ class WSAL_Settings {
|
|
268 |
*
|
269 |
* @return string
|
270 |
*/
|
271 |
-
public function
|
272 |
return '6 months';
|
273 |
}
|
274 |
|
@@ -277,14 +277,14 @@ class WSAL_Settings {
|
|
277 |
*
|
278 |
* @return string
|
279 |
*/
|
280 |
-
public function
|
281 |
-
if ( ! $this->
|
282 |
-
$this->
|
283 |
-
if ( ! strtotime( $this->
|
284 |
-
$this->
|
285 |
}
|
286 |
}
|
287 |
-
return $this->
|
288 |
}
|
289 |
|
290 |
/**
|
@@ -292,10 +292,10 @@ class WSAL_Settings {
|
|
292 |
*
|
293 |
* @param string $newvalue - The new pruning date.
|
294 |
*/
|
295 |
-
public function
|
296 |
if ( strtotime( $newvalue ) ) {
|
297 |
-
$this->
|
298 |
-
$this->
|
299 |
}
|
300 |
}
|
301 |
|
@@ -305,7 +305,7 @@ class WSAL_Settings {
|
|
305 |
* @return string
|
306 |
*/
|
307 |
public function get_pruning_unit() {
|
308 |
-
return $this->
|
309 |
}
|
310 |
|
311 |
/**
|
@@ -314,7 +314,7 @@ class WSAL_Settings {
|
|
314 |
* @param string $newvalue – New value of pruning unit.
|
315 |
*/
|
316 |
public function set_pruning_unit( $newvalue ) {
|
317 |
-
$this->
|
318 |
}
|
319 |
|
320 |
/**
|
@@ -322,9 +322,9 @@ class WSAL_Settings {
|
|
322 |
*
|
323 |
* @return integer
|
324 |
*/
|
325 |
-
public function
|
326 |
-
$val = (int) $this->
|
327 |
-
return $val ? $val : $this->
|
328 |
}
|
329 |
|
330 |
/**
|
@@ -332,37 +332,56 @@ class WSAL_Settings {
|
|
332 |
*
|
333 |
* @param integer $newvalue - The new maximum number of alerts.
|
334 |
*/
|
335 |
-
public function
|
336 |
-
$
|
337 |
-
$this->_plugin->SetGlobalSetting( 'pruning-limit', $newvalue );
|
338 |
}
|
339 |
|
340 |
-
|
|
|
|
|
|
|
|
|
|
|
341 |
|
342 |
-
$old_setting = $this->
|
343 |
-
$enable
|
344 |
if ( $old_setting !== $enable ) {
|
345 |
-
$
|
346 |
-
$alert_data
|
347 |
-
'new_setting'
|
348 |
-
'previous_setting' => ( $old_setting ) ? 'Delete events older than ' . $this->
|
349 |
-
|
350 |
-
$this->
|
351 |
}
|
352 |
|
353 |
-
$this->
|
354 |
}
|
355 |
|
356 |
-
|
357 |
-
|
|
|
|
|
|
|
|
|
|
|
358 |
}
|
359 |
|
360 |
-
|
361 |
-
|
|
|
|
|
|
|
|
|
|
|
362 |
}
|
363 |
|
364 |
-
|
365 |
-
|
|
|
|
|
|
|
|
|
|
|
366 |
}
|
367 |
|
368 |
/**
|
@@ -380,17 +399,17 @@ class WSAL_Settings {
|
|
380 |
* @param bool $enable - Enable/Disable.
|
381 |
*/
|
382 |
public function set_login_page_notification( $enable ) {
|
383 |
-
//Only trigger an event if an actual changes is made.
|
384 |
-
$old_setting = $this->
|
385 |
-
$enable
|
386 |
if ( $old_setting !== $enable ) {
|
387 |
-
$event_id
|
388 |
-
$alert_data =
|
389 |
'EventType' => ( $enable ) ? 'enabled' : 'disabled',
|
390 |
-
|
391 |
-
$this->
|
392 |
}
|
393 |
-
$this->
|
394 |
}
|
395 |
|
396 |
/**
|
@@ -399,7 +418,7 @@ class WSAL_Settings {
|
|
399 |
* @return bool - True if set, false if not.
|
400 |
*/
|
401 |
public function is_login_page_notification() {
|
402 |
-
return $this->
|
403 |
}
|
404 |
|
405 |
/**
|
@@ -408,12 +427,12 @@ class WSAL_Settings {
|
|
408 |
* @param string $text - Login Page Notification Text.
|
409 |
*/
|
410 |
public function set_login_page_notification_text( $text ) {
|
411 |
-
$text
|
412 |
-
$old_setting = $this->
|
413 |
if ( ! empty( $old_setting ) && ! empty( $text ) && ! is_null( $old_setting ) && $old_setting !== $text ) {
|
414 |
-
$this->
|
415 |
}
|
416 |
-
$this->
|
417 |
}
|
418 |
|
419 |
/**
|
@@ -422,10 +441,15 @@ class WSAL_Settings {
|
|
422 |
* @return string|bool - Text if set, false if not.
|
423 |
*/
|
424 |
public function get_login_page_notification_text() {
|
425 |
-
return $this->
|
426 |
}
|
427 |
|
428 |
-
|
|
|
|
|
|
|
|
|
|
|
429 |
return array( 0000, 0001, 0002, 0003, 0004, 0005 );
|
430 |
}
|
431 |
|
@@ -434,14 +458,14 @@ class WSAL_Settings {
|
|
434 |
*
|
435 |
* @return array
|
436 |
*/
|
437 |
-
public function
|
438 |
-
if ( ! $this->
|
439 |
-
$this->
|
440 |
-
$this->
|
441 |
-
$this->
|
442 |
-
$this->
|
443 |
}
|
444 |
-
return $this->
|
445 |
}
|
446 |
|
447 |
/**
|
@@ -449,48 +473,52 @@ class WSAL_Settings {
|
|
449 |
*
|
450 |
* @param array $types IDs alerts to disable.
|
451 |
*/
|
452 |
-
public function
|
453 |
-
$this->
|
454 |
-
$this->
|
455 |
}
|
456 |
|
457 |
/**
|
|
|
|
|
458 |
* @return bool
|
459 |
*/
|
460 |
-
public function
|
461 |
-
return $this->
|
462 |
}
|
463 |
|
464 |
/**
|
465 |
-
*
|
|
|
|
|
466 |
*/
|
467 |
-
public function
|
468 |
-
$old_value = $this->
|
469 |
-
$old_value = (
|
470 |
if ( $old_value !== $enabled ) {
|
471 |
-
$alert_data =
|
472 |
'EventType' => ( $enabled ) ? 'enabled' : 'disabled',
|
473 |
-
|
474 |
-
$this->
|
475 |
}
|
476 |
|
477 |
-
$this->
|
478 |
}
|
479 |
|
480 |
/**
|
481 |
* Checking if the data will be removed.
|
482 |
*/
|
483 |
-
public function
|
484 |
-
return $this->
|
485 |
}
|
486 |
|
487 |
/**
|
488 |
* Sets the plugin setting that allows data deletion on plugin uninstall.
|
489 |
*
|
490 |
-
* @param mixed $enabled
|
491 |
*/
|
492 |
-
public function
|
493 |
-
$this->
|
494 |
}
|
495 |
|
496 |
/**
|
@@ -498,14 +526,14 @@ class WSAL_Settings {
|
|
498 |
*
|
499 |
* @param array $users_or_roles – Users/Roles.
|
500 |
*/
|
501 |
-
public function
|
502 |
|
503 |
-
$old_value
|
504 |
-
$changes
|
505 |
|
506 |
-
if ( ! empty( $changes[
|
507 |
-
foreach ( $changes[
|
508 |
-
$this->
|
509 |
6050,
|
510 |
array(
|
511 |
'user' => $user,
|
@@ -516,14 +544,14 @@ class WSAL_Settings {
|
|
516 |
}
|
517 |
}
|
518 |
|
519 |
-
if ( ! empty( $changes[
|
520 |
-
foreach ( $changes[
|
521 |
if ( ! empty( $user ) ) {
|
522 |
-
$this->
|
523 |
6050,
|
524 |
array(
|
525 |
'user' => $user,
|
526 |
-
'previous_users' =>
|
527 |
'EventType' => 'removed',
|
528 |
)
|
529 |
);
|
@@ -531,19 +559,20 @@ class WSAL_Settings {
|
|
531 |
}
|
532 |
}
|
533 |
|
534 |
-
|
535 |
-
$this->
|
536 |
-
$this->_plugin->SetGlobalSetting( 'plugin-viewers', implode( ',', $this->_viewers ), true );
|
537 |
}
|
538 |
|
539 |
/**
|
540 |
* Get Plugin Viewers.
|
|
|
|
|
541 |
*/
|
542 |
-
public function
|
543 |
-
if ( is_null( $this->
|
544 |
-
$this->
|
545 |
}
|
546 |
-
return $this->
|
547 |
}
|
548 |
|
549 |
/**
|
@@ -553,17 +582,17 @@ class WSAL_Settings {
|
|
553 |
* @since 3.2.3
|
554 |
*/
|
555 |
public function set_restrict_plugin_setting( $setting ) {
|
556 |
-
$old_value = $this->
|
557 |
|
558 |
if ( ! is_null( $old_value ) && $old_value !== $setting ) {
|
559 |
-
$alert_data =
|
560 |
-
'new_setting'
|
561 |
-
'previous_setting' => ucfirst( str_replace( '_', ' ', $old_value
|
562 |
-
|
563 |
-
$this->
|
564 |
}
|
565 |
|
566 |
-
$this->
|
567 |
}
|
568 |
|
569 |
/**
|
@@ -572,7 +601,7 @@ class WSAL_Settings {
|
|
572 |
* @since 3.2.3
|
573 |
*/
|
574 |
public function get_restrict_plugin_setting() {
|
575 |
-
return $this->
|
576 |
}
|
577 |
|
578 |
/**
|
@@ -581,7 +610,7 @@ class WSAL_Settings {
|
|
581 |
* @since 4.1.3
|
582 |
*/
|
583 |
public function get_restrict_log_viewer() {
|
584 |
-
return $this->
|
585 |
}
|
586 |
|
587 |
/**
|
@@ -591,19 +620,29 @@ class WSAL_Settings {
|
|
591 |
* @since 4.1.3
|
592 |
*/
|
593 |
public function set_restrict_log_viewer( $setting ) {
|
594 |
-
$this->
|
595 |
}
|
596 |
|
597 |
-
|
598 |
-
|
599 |
-
|
|
|
|
|
|
|
|
|
|
|
600 |
}
|
601 |
|
602 |
-
|
603 |
-
|
604 |
-
|
|
|
|
|
|
|
|
|
|
|
605 |
}
|
606 |
-
return $this->
|
607 |
}
|
608 |
|
609 |
/**
|
@@ -612,8 +651,8 @@ class WSAL_Settings {
|
|
612 |
* @param string $action Type of action, either 'view' or 'edit'.
|
613 |
* @return boolean If user has access or not.
|
614 |
*/
|
615 |
-
public function
|
616 |
-
return $this->
|
617 |
}
|
618 |
|
619 |
/**
|
@@ -621,8 +660,8 @@ class WSAL_Settings {
|
|
621 |
*
|
622 |
* @return array
|
623 |
*/
|
624 |
-
protected function
|
625 |
-
return $this->
|
626 |
}
|
627 |
|
628 |
/**
|
@@ -630,8 +669,8 @@ class WSAL_Settings {
|
|
630 |
*
|
631 |
* @return string[]
|
632 |
*/
|
633 |
-
protected function
|
634 |
-
if ( $this->
|
635 |
if ( empty( $this->site_admins ) ) {
|
636 |
/**
|
637 |
* Get list of admins.
|
@@ -647,7 +686,7 @@ class WSAL_Settings {
|
|
647 |
. " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
|
648 |
|
649 |
// Get admins.
|
650 |
-
$this->site_admins = $wpdb->get_col( $sql );
|
651 |
}
|
652 |
} else {
|
653 |
if ( empty( $this->site_admins ) ) {
|
@@ -667,61 +706,61 @@ class WSAL_Settings {
|
|
667 |
* @param string $action - Type of action, either 'view' or 'edit'.
|
668 |
* @return boolean If user has access or not.
|
669 |
*/
|
670 |
-
public function
|
671 |
if ( is_int( $user ) ) {
|
672 |
$user = get_userdata( $user );
|
673 |
}
|
674 |
|
675 |
-
//
|
676 |
$result = false;
|
677 |
|
678 |
-
$is_multisite = $this->
|
679 |
switch ( $action ) {
|
680 |
case 'view':
|
681 |
if ( ! $is_multisite ) {
|
682 |
-
//
|
683 |
switch ( $this->get_restrict_plugin_setting() ) {
|
684 |
case 'only_admins':
|
685 |
-
//
|
686 |
-
$result = in_array( 'administrator', $user->roles );
|
687 |
break;
|
688 |
case 'only_me':
|
689 |
-
//
|
690 |
-
$result = $user->ID
|
691 |
break;
|
692 |
default:
|
693 |
-
//
|
694 |
$result = false;
|
695 |
}
|
696 |
} else {
|
697 |
-
//
|
698 |
-
// defined in the extra option
|
699 |
switch ( $this->get_restrict_log_viewer() ) {
|
700 |
case 'only_me':
|
701 |
-
//
|
702 |
-
$result = ( $user->ID
|
703 |
break;
|
704 |
case 'only_superadmins':
|
705 |
-
//
|
706 |
if ( function_exists( 'is_super_admin' ) && is_super_admin( $user->ID ) ) {
|
707 |
$result = true;
|
708 |
}
|
709 |
break;
|
710 |
case 'only_admins':
|
711 |
-
//
|
712 |
-
$result = in_array( 'administrator', $user->roles ) || ( function_exists( 'is_super_admin' ) && is_super_admin( $user->ID ) );
|
713 |
break;
|
714 |
default:
|
715 |
-
//
|
716 |
break;
|
717 |
}
|
718 |
}
|
719 |
|
720 |
if ( ! $result ) {
|
721 |
-
//
|
722 |
-
// settings
|
723 |
-
$extra_viewers = $this->
|
724 |
-
if ( in_array( $user->user_login, $extra_viewers ) ) {
|
725 |
$result = true;
|
726 |
} elseif ( ! empty( array_intersect( $extra_viewers, $user->roles ) ) ) {
|
727 |
$result = true;
|
@@ -730,9 +769,9 @@ class WSAL_Settings {
|
|
730 |
break;
|
731 |
case 'edit':
|
732 |
if ( $is_multisite ) {
|
733 |
-
//
|
734 |
if ( wp_doing_ajax() ) {
|
735 |
-
// AJAX calls are an exception
|
736 |
$result = true;
|
737 |
} elseif ( ! is_network_admin() ) {
|
738 |
$result = false;
|
@@ -742,12 +781,12 @@ class WSAL_Settings {
|
|
742 |
|
743 |
$restrict_plugin_setting = $this->get_restrict_plugin_setting();
|
744 |
if ( 'only_me' === $restrict_plugin_setting ) {
|
745 |
-
$result = ( $user->ID
|
746 |
} elseif ( 'only_admins' === $restrict_plugin_setting ) {
|
747 |
if ( $is_multisite ) {
|
748 |
$result = ( function_exists( 'is_super_admin' ) && is_super_admin( $user->ID ) );
|
749 |
} else {
|
750 |
-
$result = in_array( 'administrator', $user->roles );
|
751 |
}
|
752 |
}
|
753 |
break;
|
@@ -768,8 +807,15 @@ class WSAL_Settings {
|
|
768 |
return apply_filters( 'wsal_user_can', $result, $user, $action );
|
769 |
}
|
770 |
|
771 |
-
|
772 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
773 |
$base_roles = wp_get_current_user()->roles;
|
774 |
}
|
775 |
if ( is_multisite() && function_exists( 'is_super_admin' ) && is_super_admin() ) {
|
@@ -778,33 +824,60 @@ class WSAL_Settings {
|
|
778 |
return $base_roles;
|
779 |
}
|
780 |
|
781 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
782 |
$user_id = username_exists( $username );
|
783 |
return function_exists( 'is_super_admin' ) && is_super_admin( $user_id );
|
784 |
}
|
785 |
|
786 |
-
|
787 |
-
|
|
|
|
|
|
|
|
|
|
|
788 |
}
|
789 |
|
790 |
-
|
791 |
-
|
792 |
-
|
|
|
|
|
|
|
|
|
|
|
793 |
if ( $old_value !== $enabled ) {
|
794 |
-
$alert_data =
|
795 |
'EventType' => ( $enabled ) ? 'enabled' : 'disabled',
|
796 |
-
|
797 |
-
$this->
|
798 |
}
|
799 |
-
$this->
|
800 |
}
|
801 |
|
802 |
-
|
803 |
-
|
|
|
|
|
|
|
|
|
|
|
804 |
}
|
805 |
|
806 |
-
|
807 |
-
|
|
|
|
|
|
|
|
|
|
|
808 |
}
|
809 |
|
810 |
/**
|
@@ -812,19 +885,19 @@ class WSAL_Settings {
|
|
812 |
*
|
813 |
* @return string|null
|
814 |
*/
|
815 |
-
public function
|
816 |
$result = null;
|
817 |
|
818 |
-
if ( $this->
|
819 |
// TODO: The algorithm below just gets the first IP in the list...we might want to make this more intelligent somehow.
|
820 |
-
$result = $this->
|
821 |
$result = reset( $result );
|
822 |
$result = isset( $result[0] ) ? $result[0] : null;
|
823 |
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
|
824 |
$ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
|
825 |
-
$result = $this->
|
826 |
|
827 |
-
if ( ! $this->
|
828 |
$result = 'Error ' . self::ERROR_CODE_INVALID_IP . ': Invalid IP Address';
|
829 |
}
|
830 |
}
|
@@ -837,7 +910,7 @@ class WSAL_Settings {
|
|
837 |
*
|
838 |
* @return array
|
839 |
*/
|
840 |
-
public function
|
841 |
$ips = array();
|
842 |
|
843 |
$proxy_headers = array(
|
@@ -849,18 +922,17 @@ class WSAL_Settings {
|
|
849 |
'HTTP_FORWARDED_FOR',
|
850 |
'HTTP_FORWARDED',
|
851 |
'REMOTE_ADDR',
|
852 |
-
//
|
853 |
'HTTP_CF-Connecting-IP',
|
854 |
-
'HTTP_TRUE_CLIENT_IP'
|
855 |
);
|
856 |
foreach ( $proxy_headers as $key ) {
|
857 |
if ( isset( $_SERVER[ $key ] ) ) {
|
858 |
$ips[ $key ] = array();
|
859 |
|
860 |
-
foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) {
|
861 |
-
$ip = $this->
|
862 |
-
|
863 |
-
if ( $this->ValidateIP( $ip ) ) {
|
864 |
$ips[ $key ][] = $ip;
|
865 |
}
|
866 |
}
|
@@ -875,8 +947,10 @@ class WSAL_Settings {
|
|
875 |
*
|
876 |
* @param string $ip - IP address.
|
877 |
* @return string
|
|
|
|
|
878 |
*/
|
879 |
-
protected function
|
880 |
$ip = trim( $ip );
|
881 |
|
882 |
if ( strpos( $ip, ':' ) !== false && substr_count( $ip, '.' ) === 3 && strpos( $ip, '[' ) === false ) {
|
@@ -898,10 +972,10 @@ class WSAL_Settings {
|
|
898 |
* @param string $ip - IP address.
|
899 |
* @return string|bool
|
900 |
*/
|
901 |
-
protected function
|
902 |
$opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
|
903 |
|
904 |
-
if ( $this->
|
905 |
$opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
906 |
}
|
907 |
|
@@ -923,16 +997,18 @@ class WSAL_Settings {
|
|
923 |
}
|
924 |
|
925 |
/**
|
926 |
-
*
|
|
|
|
|
927 |
*/
|
928 |
-
public function
|
929 |
|
930 |
-
$old_value
|
931 |
-
$changes
|
932 |
|
933 |
-
if ( ! empty( $changes[
|
934 |
-
foreach ( $changes[
|
935 |
-
$this->
|
936 |
6053,
|
937 |
array(
|
938 |
'user' => $user,
|
@@ -942,28 +1018,33 @@ class WSAL_Settings {
|
|
942 |
);
|
943 |
}
|
944 |
}
|
945 |
-
if ( ! empty( $changes[
|
946 |
-
foreach ( $changes[
|
947 |
-
$this->
|
948 |
6053,
|
949 |
array(
|
950 |
'user' => $user,
|
951 |
-
'previous_users' =>
|
952 |
'EventType' => 'removed',
|
953 |
)
|
954 |
);
|
955 |
}
|
956 |
}
|
957 |
|
958 |
-
$this->
|
959 |
-
$this->
|
960 |
}
|
961 |
|
962 |
-
|
963 |
-
|
964 |
-
|
|
|
|
|
|
|
|
|
|
|
965 |
}
|
966 |
-
return $this->
|
967 |
}
|
968 |
|
969 |
/**
|
@@ -974,12 +1055,12 @@ class WSAL_Settings {
|
|
974 |
*/
|
975 |
public function set_excluded_post_types( $post_types ) {
|
976 |
|
977 |
-
$old_value
|
978 |
-
$changes
|
979 |
|
980 |
-
if ( ! empty( $changes[
|
981 |
-
foreach ( $changes[
|
982 |
-
$this->
|
983 |
6056,
|
984 |
array(
|
985 |
'post_type' => $post_type,
|
@@ -990,21 +1071,21 @@ class WSAL_Settings {
|
|
990 |
}
|
991 |
}
|
992 |
|
993 |
-
if ( ! empty( $changes[
|
994 |
-
foreach ( $changes[
|
995 |
-
$this->
|
996 |
6056,
|
997 |
array(
|
998 |
'post_type' => $post_type,
|
999 |
-
'previous_types' =>
|
1000 |
'EventType' => 'removed',
|
1001 |
)
|
1002 |
);
|
1003 |
}
|
1004 |
}
|
1005 |
|
1006 |
-
$this->
|
1007 |
-
$this->
|
1008 |
}
|
1009 |
|
1010 |
/**
|
@@ -1013,10 +1094,10 @@ class WSAL_Settings {
|
|
1013 |
* @since 2.6.7
|
1014 |
*/
|
1015 |
public function get_excluded_post_types() {
|
1016 |
-
if ( empty( $this->
|
1017 |
-
$this->
|
1018 |
}
|
1019 |
-
return $this->
|
1020 |
}
|
1021 |
|
1022 |
/**
|
@@ -1024,15 +1105,15 @@ class WSAL_Settings {
|
|
1024 |
*
|
1025 |
* @param array $roles - Array of roles.
|
1026 |
*/
|
1027 |
-
public function
|
1028 |
|
1029 |
// Trigger alert.
|
1030 |
-
$old_value
|
1031 |
-
$changes
|
1032 |
|
1033 |
-
if ( ! empty( $changes[
|
1034 |
-
foreach ( $changes[
|
1035 |
-
$this->
|
1036 |
6054,
|
1037 |
array(
|
1038 |
'role' => $user,
|
@@ -1042,70 +1123,70 @@ class WSAL_Settings {
|
|
1042 |
);
|
1043 |
}
|
1044 |
}
|
1045 |
-
if ( ! empty( $changes[
|
1046 |
-
foreach ( $changes[
|
1047 |
-
$this->
|
1048 |
6054,
|
1049 |
array(
|
1050 |
'role' => $user,
|
1051 |
-
'previous_users' =>
|
1052 |
'EventType' => 'removed',
|
1053 |
)
|
1054 |
);
|
1055 |
}
|
1056 |
}
|
1057 |
|
1058 |
-
$this->
|
1059 |
-
$this->
|
1060 |
}
|
1061 |
|
1062 |
/**
|
1063 |
* Get roles excluded from monitoring.
|
1064 |
*/
|
1065 |
-
public function
|
1066 |
-
if ( empty( $this->
|
1067 |
-
$this->
|
1068 |
}
|
1069 |
-
return $this->
|
1070 |
}
|
1071 |
|
1072 |
/**
|
1073 |
* Updates custom post meta fields excluded from monitoring.
|
1074 |
*
|
1075 |
-
* @param array $custom
|
1076 |
*/
|
1077 |
-
public function
|
1078 |
-
$old_value
|
1079 |
-
$changes
|
1080 |
|
1081 |
-
if ( ! empty( $changes[
|
1082 |
-
foreach ( $changes[
|
1083 |
-
$this->
|
1084 |
6057,
|
1085 |
array(
|
1086 |
'custom_field' => $custom_field,
|
1087 |
'previous_fields' => ( empty( $old_value ) ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1088 |
-
'EventType'
|
1089 |
)
|
1090 |
);
|
1091 |
}
|
1092 |
}
|
1093 |
|
1094 |
-
if ( ! empty( $changes[
|
1095 |
-
foreach ( $changes[
|
1096 |
-
$this->
|
1097 |
6057,
|
1098 |
array(
|
1099 |
'custom_field' => $custom_field,
|
1100 |
-
'previous_fields' =>
|
1101 |
-
'EventType'
|
1102 |
)
|
1103 |
);
|
1104 |
}
|
1105 |
}
|
1106 |
|
1107 |
-
$this->
|
1108 |
-
$this->
|
1109 |
}
|
1110 |
|
1111 |
/**
|
@@ -1113,54 +1194,54 @@ class WSAL_Settings {
|
|
1113 |
*
|
1114 |
* @return array
|
1115 |
*/
|
1116 |
-
public function
|
1117 |
-
if ( empty( $this->
|
1118 |
-
$this->
|
1119 |
-
asort( $this->
|
1120 |
}
|
1121 |
-
return $this->
|
1122 |
}
|
1123 |
|
1124 |
/**
|
1125 |
* Updates custom user meta fields excluded from monitoring.
|
1126 |
*
|
1127 |
-
* @param array $custom
|
1128 |
*
|
1129 |
* @since 4.3.2
|
1130 |
*/
|
1131 |
-
public function
|
1132 |
|
1133 |
-
$old_value
|
1134 |
-
$changes
|
1135 |
|
1136 |
-
if ( ! empty( $changes[
|
1137 |
-
foreach ( $changes[
|
1138 |
-
$this->
|
1139 |
6058,
|
1140 |
array(
|
1141 |
'custom_field' => $custom_field,
|
1142 |
'previous_fields' => ( empty( $old_value ) ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1143 |
-
'EventType'
|
1144 |
)
|
1145 |
);
|
1146 |
}
|
1147 |
}
|
1148 |
|
1149 |
-
if ( ! empty( $changes[
|
1150 |
-
foreach ( $changes[
|
1151 |
-
$this->
|
1152 |
6058,
|
1153 |
array(
|
1154 |
'custom_field' => $custom_field,
|
1155 |
-
'previous_fields' =>
|
1156 |
-
'EventType'
|
1157 |
)
|
1158 |
);
|
1159 |
}
|
1160 |
}
|
1161 |
|
1162 |
-
$this->
|
1163 |
-
$this->
|
1164 |
}
|
1165 |
|
1166 |
/**
|
@@ -1169,25 +1250,27 @@ class WSAL_Settings {
|
|
1169 |
* @return array
|
1170 |
* @since 4.3.2
|
1171 |
*/
|
1172 |
-
public function
|
1173 |
-
if ( empty( $this->
|
1174 |
-
$this->
|
1175 |
-
asort( $this->
|
1176 |
}
|
1177 |
|
1178 |
-
return $this->
|
1179 |
}
|
1180 |
|
1181 |
/**
|
1182 |
* IP excluded from monitoring.
|
|
|
|
|
1183 |
*/
|
1184 |
-
public function
|
1185 |
-
$old_value
|
1186 |
-
$changes
|
1187 |
|
1188 |
-
if ( ! empty( $changes[
|
1189 |
-
foreach ( $changes[
|
1190 |
-
$this->
|
1191 |
6055,
|
1192 |
array(
|
1193 |
'ip' => $user,
|
@@ -1197,28 +1280,33 @@ class WSAL_Settings {
|
|
1197 |
);
|
1198 |
}
|
1199 |
}
|
1200 |
-
if ( ! empty( $changes[
|
1201 |
-
foreach ( $changes[
|
1202 |
-
$this->
|
1203 |
6055,
|
1204 |
array(
|
1205 |
'ip' => $user,
|
1206 |
-
'previous_ips' =>
|
1207 |
'EventType' => 'removed',
|
1208 |
)
|
1209 |
);
|
1210 |
}
|
1211 |
}
|
1212 |
|
1213 |
-
$this->
|
1214 |
-
$this->
|
1215 |
}
|
1216 |
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
|
|
|
|
|
|
|
|
|
|
1220 |
}
|
1221 |
-
return $this->
|
1222 |
}
|
1223 |
|
1224 |
/**
|
@@ -1228,16 +1316,17 @@ class WSAL_Settings {
|
|
1228 |
* Note: Format returned by this function is not compatible with JavaScript date and time picker widgets. Use
|
1229 |
* functions GetTimeFormat and GetDateFormat for those.
|
1230 |
*
|
1231 |
-
* @param boolean $line_break
|
|
|
1232 |
*
|
1233 |
* @return string
|
1234 |
*/
|
1235 |
-
public function
|
1236 |
-
$result = $this->
|
1237 |
|
1238 |
$result .= $line_break ? '<\b\r>' : ' ';
|
1239 |
|
1240 |
-
$time_format = $this->
|
1241 |
$has_am_pm = false;
|
1242 |
$am_pm_fraction = false;
|
1243 |
$am_pm_pattern = '/(?i)(\s+A)/';
|
@@ -1252,11 +1341,10 @@ class WSAL_Settings {
|
|
1252 |
$time_format .= ':s'; // Add seconds to time format.
|
1253 |
}
|
1254 |
|
1255 |
-
if ($this->get_show_milliseconds()) {
|
1256 |
$time_format .= '.$$$'; // Add milliseconds to time format.
|
1257 |
}
|
1258 |
|
1259 |
-
|
1260 |
if ( $has_am_pm ) {
|
1261 |
$time_format .= preg_replace( '/\s/', $use_nb_space_for_am_pm ? '&\n\b\s\p;' : ' ', $am_pm_fraction );
|
1262 |
}
|
@@ -1276,7 +1364,7 @@ class WSAL_Settings {
|
|
1276 |
*
|
1277 |
* @return string
|
1278 |
*/
|
1279 |
-
public function
|
1280 |
if ( $sanitized ) {
|
1281 |
return 'Y-m-d';
|
1282 |
}
|
@@ -1294,7 +1382,7 @@ class WSAL_Settings {
|
|
1294 |
*
|
1295 |
* @return string
|
1296 |
*/
|
1297 |
-
public function
|
1298 |
$result = get_option( 'time_format' );
|
1299 |
if ( $sanitize ) {
|
1300 |
$search = array( 'a', 'A', 'T', ' ' );
|
@@ -1309,12 +1397,19 @@ class WSAL_Settings {
|
|
1309 |
*
|
1310 |
* Server's timezone or WordPress' timezone.
|
1311 |
*/
|
1312 |
-
public function
|
1313 |
-
return $this->
|
1314 |
}
|
1315 |
|
1316 |
-
|
1317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1318 |
}
|
1319 |
|
1320 |
/**
|
@@ -1326,7 +1421,7 @@ class WSAL_Settings {
|
|
1326 |
* @return bool
|
1327 |
*/
|
1328 |
public function get_show_milliseconds() {
|
1329 |
-
return $this->
|
1330 |
}
|
1331 |
|
1332 |
/**
|
@@ -1339,7 +1434,7 @@ class WSAL_Settings {
|
|
1339 |
* @param mixed $newvalue ideally always bool. If not bool then it's cast to true.
|
1340 |
*/
|
1341 |
public function set_show_milliseconds( $newvalue ) {
|
1342 |
-
$this->
|
1343 |
}
|
1344 |
|
1345 |
|
@@ -1347,7 +1442,7 @@ class WSAL_Settings {
|
|
1347 |
* Get type of username to display.
|
1348 |
*/
|
1349 |
public function get_type_username() {
|
1350 |
-
return $this->
|
1351 |
}
|
1352 |
|
1353 |
/**
|
@@ -1357,7 +1452,7 @@ class WSAL_Settings {
|
|
1357 |
* @since 2.6.5
|
1358 |
*/
|
1359 |
public function set_type_username( $newvalue ) {
|
1360 |
-
$this->
|
1361 |
}
|
1362 |
|
1363 |
/**
|
@@ -1365,7 +1460,7 @@ class WSAL_Settings {
|
|
1365 |
*
|
1366 |
* @return array
|
1367 |
*/
|
1368 |
-
public function
|
1369 |
$columns = array(
|
1370 |
'alert_code' => '1',
|
1371 |
'type' => '1',
|
@@ -1379,11 +1474,11 @@ class WSAL_Settings {
|
|
1379 |
'info' => '1',
|
1380 |
);
|
1381 |
|
1382 |
-
if ( $this->
|
1383 |
$columns = array_slice( $columns, 0, 6, true ) + array( 'site' => '1' ) + array_slice( $columns, 6, null, true );
|
1384 |
}
|
1385 |
|
1386 |
-
$selected = $this->
|
1387 |
|
1388 |
if ( ! empty( $selected ) ) {
|
1389 |
$columns = array(
|
@@ -1398,7 +1493,7 @@ class WSAL_Settings {
|
|
1398 |
'message' => '0',
|
1399 |
);
|
1400 |
|
1401 |
-
if ( $this->
|
1402 |
$columns = array_slice( $columns, 0, 6, true ) + array( 'site' => '0' ) + array_slice( $columns, 6, null, true );
|
1403 |
}
|
1404 |
|
@@ -1409,20 +1504,40 @@ class WSAL_Settings {
|
|
1409 |
return $columns;
|
1410 |
}
|
1411 |
|
1412 |
-
|
1413 |
-
|
|
|
|
|
|
|
|
|
|
|
1414 |
}
|
1415 |
|
1416 |
-
|
1417 |
-
|
|
|
|
|
|
|
|
|
|
|
1418 |
}
|
1419 |
|
1420 |
-
|
1421 |
-
|
|
|
|
|
|
|
|
|
|
|
1422 |
}
|
1423 |
|
1424 |
-
|
1425 |
-
|
|
|
|
|
|
|
|
|
|
|
1426 |
}
|
1427 |
|
1428 |
/**
|
@@ -1431,7 +1546,7 @@ class WSAL_Settings {
|
|
1431 |
* @param string $use – Setting value.
|
1432 |
*/
|
1433 |
public function set_use_email( $use ) {
|
1434 |
-
$this->
|
1435 |
}
|
1436 |
|
1437 |
/**
|
@@ -1440,23 +1555,45 @@ class WSAL_Settings {
|
|
1440 |
* @return string
|
1441 |
*/
|
1442 |
public function get_use_email() {
|
1443 |
-
return $this->
|
1444 |
}
|
1445 |
|
1446 |
-
|
1447 |
-
|
|
|
|
|
|
|
|
|
|
|
1448 |
}
|
1449 |
|
1450 |
-
|
1451 |
-
|
|
|
|
|
|
|
|
|
|
|
1452 |
}
|
1453 |
|
1454 |
-
|
1455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1456 |
}
|
1457 |
|
1458 |
-
|
1459 |
-
|
|
|
|
|
|
|
|
|
|
|
1460 |
}
|
1461 |
|
1462 |
/**
|
@@ -1467,9 +1604,9 @@ class WSAL_Settings {
|
|
1467 |
*/
|
1468 |
public function set_failed_login_limit( $value ) {
|
1469 |
if ( ! empty( $value ) ) {
|
1470 |
-
$this->
|
1471 |
} else {
|
1472 |
-
$this->
|
1473 |
}
|
1474 |
}
|
1475 |
|
@@ -1480,7 +1617,7 @@ class WSAL_Settings {
|
|
1480 |
* @since 2.6.3
|
1481 |
*/
|
1482 |
public function get_failed_login_limit() {
|
1483 |
-
return intval($this->
|
1484 |
}
|
1485 |
|
1486 |
/**
|
@@ -1491,9 +1628,9 @@ class WSAL_Settings {
|
|
1491 |
*/
|
1492 |
public function set_visitor_failed_login_limit( $value ) {
|
1493 |
if ( ! empty( $value ) ) {
|
1494 |
-
$this->
|
1495 |
} else {
|
1496 |
-
$this->
|
1497 |
}
|
1498 |
}
|
1499 |
|
@@ -1504,7 +1641,7 @@ class WSAL_Settings {
|
|
1504 |
* @since 2.6.3
|
1505 |
*/
|
1506 |
public function get_visitor_failed_login_limit() {
|
1507 |
-
return intval( $this->
|
1508 |
}
|
1509 |
|
1510 |
|
@@ -1524,7 +1661,7 @@ class WSAL_Settings {
|
|
1524 |
}
|
1525 |
|
1526 |
// Check if the token matched users.
|
1527 |
-
if ( in_array( $token, $users ) ) {
|
1528 |
return 'user';
|
1529 |
}
|
1530 |
|
@@ -1532,7 +1669,7 @@ class WSAL_Settings {
|
|
1532 |
$roles = array_keys( get_editable_roles() );
|
1533 |
|
1534 |
// Check if the token matched user roles.
|
1535 |
-
if ( in_array( $token, $roles ) ) {
|
1536 |
return 'role';
|
1537 |
}
|
1538 |
|
@@ -1548,7 +1685,7 @@ class WSAL_Settings {
|
|
1548 |
}
|
1549 |
|
1550 |
// Check if the token matched post types.
|
1551 |
-
if ( in_array( $token, $post_types ) ) {
|
1552 |
return 'cpts';
|
1553 |
}
|
1554 |
|
@@ -1594,15 +1731,15 @@ class WSAL_Settings {
|
|
1594 |
*/
|
1595 |
public function set_mainwp_child_stealth_mode() {
|
1596 |
if (
|
1597 |
-
! $this->
|
1598 |
&& WpSecurityAuditLog::is_mainwp_active() // And if MainWP Child plugin is installed & active.
|
1599 |
) {
|
1600 |
// Check if freemius state is anonymous.
|
1601 |
-
if ( ! wsal_freemius()->is_premium() && 'anonymous' === $this->
|
1602 |
// Update Freemius state to skipped.
|
1603 |
-
$this->
|
1604 |
|
1605 |
-
if ( ! $this->
|
1606 |
wsal_freemius()->skip_connection(); // Opt out.
|
1607 |
} else {
|
1608 |
wsal_freemius()->skip_connection( null, true ); // Opt out for all websites.
|
@@ -1617,13 +1754,13 @@ class WSAL_Settings {
|
|
1617 |
FS_Admin_Notices::instance( 'wp-security-audit-log' )->remove_sticky( 'trial_promotion' );
|
1618 |
}
|
1619 |
|
1620 |
-
$this->
|
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->
|
1627 |
}
|
1628 |
}
|
1629 |
|
@@ -1633,11 +1770,11 @@ class WSAL_Settings {
|
|
1633 |
* @since 3.2.3.3
|
1634 |
*/
|
1635 |
public function deactivate_mainwp_child_stealth_mode() {
|
1636 |
-
$this->
|
1637 |
$this->set_restrict_plugin_setting( 'only_admins' );
|
1638 |
$this->set_restrict_log_viewer( 'only_admins' );
|
1639 |
$this->set_admin_blocking_plugin_support( false );
|
1640 |
-
$this->
|
1641 |
}
|
1642 |
|
1643 |
/**
|
@@ -1650,7 +1787,7 @@ class WSAL_Settings {
|
|
1650 |
return;
|
1651 |
}
|
1652 |
|
1653 |
-
if ( $this->
|
1654 |
$this->deactivate_mainwp_child_stealth_mode();
|
1655 |
}
|
1656 |
}
|
@@ -1661,7 +1798,7 @@ class WSAL_Settings {
|
|
1661 |
* @return boolean
|
1662 |
*/
|
1663 |
public function is_stealth_mode() {
|
1664 |
-
return $this->
|
1665 |
}
|
1666 |
|
1667 |
/**
|
@@ -1674,7 +1811,7 @@ class WSAL_Settings {
|
|
1674 |
public function get_view_site_id() {
|
1675 |
switch ( true ) {
|
1676 |
// Non-multisite.
|
1677 |
-
case ! $this->
|
1678 |
return 0;
|
1679 |
// Multisite + main site view.
|
1680 |
case $this->is_main_blog() && ! $this->is_specific_view():
|
@@ -1707,7 +1844,7 @@ class WSAL_Settings {
|
|
1707 |
* @return bool
|
1708 |
*/
|
1709 |
protected function is_specific_view() {
|
1710 |
-
return isset( $_REQUEST['wsal-cbid'] ) && 0 !== (int) $_REQUEST['wsal-cbid']; //
|
1711 |
}
|
1712 |
|
1713 |
/**
|
@@ -1718,7 +1855,7 @@ class WSAL_Settings {
|
|
1718 |
* @return int
|
1719 |
*/
|
1720 |
protected function get_specific_view() {
|
1721 |
-
return isset( $_REQUEST['wsal-cbid'] ) ? (int) sanitize_text_field( wp_unslash( $_REQUEST['wsal-cbid'] ) ) : 0; //
|
1722 |
}
|
1723 |
|
1724 |
/**
|
@@ -1736,7 +1873,7 @@ class WSAL_Settings {
|
|
1736 |
if ( ! is_null( $limit ) ) {
|
1737 |
$sql .= ' LIMIT ' . $limit;
|
1738 |
}
|
1739 |
-
$res = $wpdb->get_results( $sql );
|
1740 |
foreach ( $res as $row ) {
|
1741 |
$row->blogname = get_blog_option( $row->blog_id, 'blogname' );
|
1742 |
}
|
@@ -1753,7 +1890,7 @@ class WSAL_Settings {
|
|
1753 |
public function get_site_count() {
|
1754 |
global $wpdb;
|
1755 |
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
1756 |
-
return (int) $wpdb->get_var( $sql );
|
1757 |
}
|
1758 |
|
1759 |
/**
|
@@ -1779,7 +1916,7 @@ class WSAL_Settings {
|
|
1779 |
* @return string
|
1780 |
*/
|
1781 |
public function get_events_type_nav() {
|
1782 |
-
return $this->
|
1783 |
}
|
1784 |
|
1785 |
/**
|
@@ -1792,7 +1929,7 @@ class WSAL_Settings {
|
|
1792 |
* @param string $nav_type - Navigation type.
|
1793 |
*/
|
1794 |
public function set_events_type_nav( $nav_type ) {
|
1795 |
-
$this->
|
1796 |
}
|
1797 |
|
1798 |
/**
|
@@ -1802,7 +1939,7 @@ class WSAL_Settings {
|
|
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 |
/**
|
@@ -2021,7 +2158,7 @@ class WSAL_Settings {
|
|
2021 |
* @since 4.1.3
|
2022 |
*/
|
2023 |
public function set_only_me_user_id( $user_id ) {
|
2024 |
-
$this->
|
2025 |
}
|
2026 |
|
2027 |
/**
|
@@ -2031,16 +2168,16 @@ class WSAL_Settings {
|
|
2031 |
* @since 4.1.3
|
2032 |
*/
|
2033 |
public function get_only_me_user_id() {
|
2034 |
-
return $this->
|
2035 |
}
|
2036 |
|
2037 |
/**
|
2038 |
* Save admin blocking plugin support enabled.
|
2039 |
*
|
2040 |
-
* @param bool $enabled
|
2041 |
*/
|
2042 |
public function set_admin_blocking_plugin_support( $enabled ) {
|
2043 |
-
$this->
|
2044 |
}
|
2045 |
|
2046 |
/**
|
@@ -2053,21 +2190,42 @@ class WSAL_Settings {
|
|
2053 |
* @return bool
|
2054 |
*/
|
2055 |
public function get_admin_blocking_plugin_support() {
|
2056 |
-
return $this->
|
2057 |
}
|
2058 |
|
|
|
|
|
|
|
|
|
|
|
2059 |
public function get_mainwp_enforced_settings() {
|
2060 |
-
return $this->
|
2061 |
}
|
2062 |
|
|
|
|
|
|
|
|
|
|
|
2063 |
public function set_mainwp_enforced_settings( $settings ) {
|
2064 |
-
$this->
|
2065 |
}
|
2066 |
|
|
|
|
|
|
|
2067 |
public function delete_mainwp_enforced_settings() {
|
2068 |
-
$this->
|
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;
|
@@ -2078,6 +2236,13 @@ class WSAL_Settings {
|
|
2078 |
return $return;
|
2079 |
}
|
2080 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2081 |
public function tidy_blank_values( $value ) {
|
2082 |
return ( empty( $value ) ) ? __( 'None provided', 'wp-security-audit-log' ) : $value;
|
2083 |
}
|
@@ -2089,7 +2254,7 @@ class WSAL_Settings {
|
|
2089 |
* @since 4.3.2
|
2090 |
*/
|
2091 |
public function get_database_version() {
|
2092 |
-
return (int) $this->
|
2093 |
}
|
2094 |
|
2095 |
/**
|
@@ -2099,7 +2264,7 @@ class WSAL_Settings {
|
|
2099 |
* @since 4.3.2
|
2100 |
*/
|
2101 |
public function set_database_version( $version ) {
|
2102 |
-
$this->
|
2103 |
}
|
2104 |
|
2105 |
}
|
31 |
*
|
32 |
* @var WpSecurityAuditLog
|
33 |
*/
|
34 |
+
protected $plugin;
|
35 |
|
36 |
const ERROR_CODE_INVALID_IP = 901;
|
37 |
|
47 |
*
|
48 |
* @var string
|
49 |
*/
|
50 |
+
protected $pruning = 0;
|
51 |
|
52 |
/**
|
53 |
* IDs of disabled alerts.
|
54 |
*
|
55 |
* @var array
|
56 |
*/
|
57 |
+
protected $disabled = null;
|
58 |
|
59 |
/**
|
60 |
* Allowed Plugin Viewers.
|
61 |
*
|
62 |
* @var array
|
63 |
*/
|
64 |
+
protected $viewers = null;
|
65 |
|
66 |
/**
|
67 |
* Alerts per page.
|
68 |
*
|
69 |
* @var int
|
70 |
*/
|
71 |
+
protected $per_page = null;
|
72 |
|
73 |
/**
|
74 |
* Users excluded from monitoring.
|
75 |
*
|
76 |
* @var array
|
77 |
*/
|
78 |
+
protected $excluded_users = array();
|
79 |
|
80 |
/**
|
81 |
* Roles excluded from monitoring.
|
82 |
*
|
83 |
* @var array
|
84 |
*/
|
85 |
+
protected $excluded_roles = array();
|
86 |
|
87 |
/**
|
88 |
* Custom post meta fields excluded from monitoring.
|
89 |
*
|
90 |
* @var array
|
91 |
*/
|
92 |
+
protected $excluded_post_meta = array();
|
93 |
|
94 |
/**
|
95 |
* Custom user meta fields excluded from monitoring.
|
96 |
*
|
97 |
* @var array
|
98 |
*/
|
99 |
+
protected $excluded_user_meta = array();
|
100 |
|
101 |
/**
|
102 |
* Custom Post Types excluded from monitoring.
|
103 |
*
|
104 |
* @var array
|
105 |
*/
|
106 |
+
protected $post_types = array();
|
107 |
|
108 |
/**
|
109 |
* IP excluded from monitoring.
|
110 |
*
|
111 |
* @var array
|
112 |
*/
|
113 |
+
protected $excluded_ip = array();
|
114 |
|
115 |
/**
|
116 |
* Alerts enabled in Geek mode.
|
140 |
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
141 |
*/
|
142 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
143 |
+
$this->plugin = $plugin;
|
144 |
// some settings here may be called before the options helper is setup.
|
145 |
+
if ( ! isset( $this->plugin->options_helper ) ) {
|
146 |
+
$this->plugin->include_options_helper();
|
147 |
}
|
148 |
add_action( 'deactivated_plugin', array( $this, 'reset_stealth_mode' ), 10, 1 );
|
149 |
}
|
154 |
*/
|
155 |
public function set_basic_mode() {
|
156 |
// Disable alerts of geek mode and alerts to be always disabled.
|
157 |
+
$this->set_disabled_alerts( array_merge( $this->geek_alerts, $this->always_disabled_alerts ) );
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
* Enable Geek Mode.
|
162 |
*/
|
163 |
public function set_geek_mode() {
|
164 |
+
$this->set_disabled_alerts( $this->always_disabled_alerts ); // Disable alerts to be always disabled.
|
165 |
}
|
166 |
|
167 |
|
170 |
*
|
171 |
* @return boolean
|
172 |
*/
|
173 |
+
public function is_widgets_enabled() {
|
174 |
+
return ! $this->plugin->get_global_boolean_setting( 'disable-widgets' );
|
175 |
}
|
176 |
|
177 |
/**
|
179 |
*
|
180 |
* @param boolean $newvalue - True if enabled.
|
181 |
*/
|
182 |
+
public function set_widgets_enabled( $newvalue ) {
|
183 |
+
$this->plugin->set_global_boolean_setting( 'disable-widgets', ! $newvalue );
|
184 |
}
|
185 |
|
186 |
/**
|
191 |
* @return boolean
|
192 |
*/
|
193 |
public function is_admin_bar_notif() {
|
194 |
+
return ! $this->plugin->get_global_boolean_setting( 'disable-admin-bar-notif', true );
|
195 |
}
|
196 |
|
197 |
/**
|
202 |
* @param boolean $newvalue - True if enabled.
|
203 |
*/
|
204 |
public function set_admin_bar_notif( $newvalue ) {
|
205 |
+
$this->plugin->set_global_boolean_setting( 'disable-admin-bar-notif', ! $newvalue, true );
|
206 |
}
|
207 |
|
208 |
/**
|
213 |
* @return string
|
214 |
*/
|
215 |
public function get_admin_bar_notif_updates() {
|
216 |
+
return $this->plugin->get_global_setting( 'admin-bar-notif-updates', 'page-refresh' );
|
217 |
}
|
218 |
|
219 |
/**
|
224 |
* @param string $newvalue - New option value.
|
225 |
*/
|
226 |
public function set_admin_bar_notif_updates( $newvalue ) {
|
227 |
+
$this->plugin->set_global_setting( 'admin-bar-notif-updates', $newvalue, true );
|
228 |
}
|
229 |
|
230 |
/**
|
232 |
*
|
233 |
* @return boolean
|
234 |
*/
|
235 |
+
public function is_refresh_alerts_enabled() {
|
236 |
+
return ! $this->plugin->get_global_setting( 'disable-refresh' );
|
237 |
}
|
238 |
|
239 |
/**
|
241 |
*
|
242 |
* @param boolean $newvalue - True if enabled.
|
243 |
*/
|
244 |
+
public function set_refresh_alerts_enabled( $newvalue ) {
|
245 |
+
$this->plugin->set_global_setting( 'disable-refresh', ! $newvalue );
|
246 |
}
|
247 |
|
248 |
/**
|
250 |
*
|
251 |
* @return int
|
252 |
*/
|
253 |
+
public function get_dashboard_widget_max_alerts() {
|
254 |
return 5;
|
255 |
}
|
256 |
|
259 |
*
|
260 |
* @return int
|
261 |
*/
|
262 |
+
public function get_max_allowed_alerts() {
|
263 |
return 5000;
|
264 |
}
|
265 |
|
268 |
*
|
269 |
* @return string
|
270 |
*/
|
271 |
+
public function get_default_pruning_date() {
|
272 |
return '6 months';
|
273 |
}
|
274 |
|
277 |
*
|
278 |
* @return string
|
279 |
*/
|
280 |
+
public function get_pruning_date() {
|
281 |
+
if ( ! $this->pruning ) {
|
282 |
+
$this->pruning = $this->plugin->get_global_setting( 'pruning-date' );
|
283 |
+
if ( ! strtotime( $this->pruning ) ) {
|
284 |
+
$this->pruning = $this->get_default_pruning_date();
|
285 |
}
|
286 |
}
|
287 |
+
return $this->pruning;
|
288 |
}
|
289 |
|
290 |
/**
|
292 |
*
|
293 |
* @param string $newvalue - The new pruning date.
|
294 |
*/
|
295 |
+
public function set_pruning_date( $newvalue ) {
|
296 |
if ( strtotime( $newvalue ) ) {
|
297 |
+
$this->plugin->set_global_setting( 'pruning-date', $newvalue );
|
298 |
+
$this->pruning = $newvalue;
|
299 |
}
|
300 |
}
|
301 |
|
305 |
* @return string
|
306 |
*/
|
307 |
public function get_pruning_unit() {
|
308 |
+
return $this->plugin->get_global_setting( 'pruning-unit', 'months' );
|
309 |
}
|
310 |
|
311 |
/**
|
314 |
* @param string $newvalue – New value of pruning unit.
|
315 |
*/
|
316 |
public function set_pruning_unit( $newvalue ) {
|
317 |
+
$this->plugin->set_global_setting( 'pruning-unit', $newvalue );
|
318 |
}
|
319 |
|
320 |
/**
|
322 |
*
|
323 |
* @return integer
|
324 |
*/
|
325 |
+
public function get_pruning_limit() {
|
326 |
+
$val = (int) $this->plugin->get_global_setting( 'pruning-limit' );
|
327 |
+
return $val ? $val : $this->get_max_allowed_alerts();
|
328 |
}
|
329 |
|
330 |
/**
|
332 |
*
|
333 |
* @param integer $newvalue - The new maximum number of alerts.
|
334 |
*/
|
335 |
+
public function set_pruning_limit( $newvalue ) {
|
336 |
+
$this->plugin->set_global_setting( 'pruning-limit', max( (int) $newvalue, 1 ) );
|
|
|
337 |
}
|
338 |
|
339 |
+
/**
|
340 |
+
* Enables or disables time based retention period.
|
341 |
+
*
|
342 |
+
* @param bool $enabled If true, time based retention period is enabled.
|
343 |
+
*/
|
344 |
+
public function set_pruning_date_enabled( $enabled ) {
|
345 |
|
346 |
+
$old_setting = $this->plugin->get_global_boolean_setting( 'pruning-date-e', false );
|
347 |
+
$enable = \WSAL\Helpers\Options::string_to_bool( $enabled );
|
348 |
if ( $old_setting !== $enable ) {
|
349 |
+
$this->pruning = $this->plugin->get_global_setting( 'pruning-date' ) . ' ' . $this->plugin->get_global_setting( 'pruning-unit', 'months' );
|
350 |
+
$alert_data = array(
|
351 |
+
'new_setting' => ( $enable ) ? 'Delete events older than ' . $this->pruning : 'Keep all data',
|
352 |
+
'previous_setting' => ( $old_setting ) ? 'Delete events older than ' . $this->pruning : 'Keep all data',
|
353 |
+
);
|
354 |
+
$this->plugin->alerts->trigger_event( 6052, $alert_data );
|
355 |
}
|
356 |
|
357 |
+
$this->plugin->set_global_boolean_setting( 'pruning-date-e', $enabled );
|
358 |
}
|
359 |
|
360 |
+
/**
|
361 |
+
* Sets the plugin setting that enabled data pruning limit.
|
362 |
+
*
|
363 |
+
* @param bool $enabled If true, the limit is enabled.
|
364 |
+
*/
|
365 |
+
public function set_pruning_limit_enabled( $enabled ) {
|
366 |
+
$this->plugin->set_global_boolean_setting( 'pruning-limit-e', $enabled );
|
367 |
}
|
368 |
|
369 |
+
/**
|
370 |
+
* Checks if the time based retention period is enabled.
|
371 |
+
*
|
372 |
+
* @return bool
|
373 |
+
*/
|
374 |
+
public function is_pruning_date_enabled() {
|
375 |
+
return $this->plugin->get_global_boolean_setting( 'pruning-date-e' );
|
376 |
}
|
377 |
|
378 |
+
/**
|
379 |
+
* Checks if the data pruning limit is enabled.
|
380 |
+
*
|
381 |
+
* @return bool
|
382 |
+
*/
|
383 |
+
public function is_pruning_limit_enabled() {
|
384 |
+
return $this->plugin->get_global_boolean_setting( 'pruning-limit-e' );
|
385 |
}
|
386 |
|
387 |
/**
|
399 |
* @param bool $enable - Enable/Disable.
|
400 |
*/
|
401 |
public function set_login_page_notification( $enable ) {
|
402 |
+
// Only trigger an event if an actual changes is made.
|
403 |
+
$old_setting = $this->plugin->get_global_boolean_setting( 'login_page_notification', false );
|
404 |
+
$enable = \WSAL\Helpers\Options::string_to_bool( $enable );
|
405 |
if ( $old_setting !== $enable ) {
|
406 |
+
$event_id = 6046;
|
407 |
+
$alert_data = array(
|
408 |
'EventType' => ( $enable ) ? 'enabled' : 'disabled',
|
409 |
+
);
|
410 |
+
$this->plugin->alerts->trigger_event( $event_id, $alert_data );
|
411 |
}
|
412 |
+
$this->plugin->set_global_boolean_setting( 'login_page_notification', $enable );
|
413 |
}
|
414 |
|
415 |
/**
|
418 |
* @return bool - True if set, false if not.
|
419 |
*/
|
420 |
public function is_login_page_notification() {
|
421 |
+
return $this->plugin->get_global_boolean_setting( 'login_page_notification', false );
|
422 |
}
|
423 |
|
424 |
/**
|
427 |
* @param string $text - Login Page Notification Text.
|
428 |
*/
|
429 |
public function set_login_page_notification_text( $text ) {
|
430 |
+
$text = wp_kses( $text, $this->plugin->allowed_html_tags );
|
431 |
+
$old_setting = $this->plugin->get_global_setting( 'login_page_notification_text' );
|
432 |
if ( ! empty( $old_setting ) && ! empty( $text ) && ! is_null( $old_setting ) && $old_setting !== $text ) {
|
433 |
+
$this->plugin->alerts->trigger_event( 6047 );
|
434 |
}
|
435 |
+
$this->plugin->set_global_setting( 'login_page_notification_text', $text );
|
436 |
}
|
437 |
|
438 |
/**
|
441 |
* @return string|bool - Text if set, false if not.
|
442 |
*/
|
443 |
public function get_login_page_notification_text() {
|
444 |
+
return $this->plugin->get_global_setting( 'login_page_notification_text', false );
|
445 |
}
|
446 |
|
447 |
+
/**
|
448 |
+
* Retrieves a list of alerts disabled by default.
|
449 |
+
*
|
450 |
+
* @return int[] List of alerts disabled by default.
|
451 |
+
*/
|
452 |
+
public function get_default_disabled_alerts() {
|
453 |
return array( 0000, 0001, 0002, 0003, 0004, 0005 );
|
454 |
}
|
455 |
|
458 |
*
|
459 |
* @return array
|
460 |
*/
|
461 |
+
public function get_disabled_alerts() {
|
462 |
+
if ( ! $this->disabled ) {
|
463 |
+
$this->disabled = implode( ',', $this->get_default_disabled_alerts() );
|
464 |
+
$this->disabled = $this->plugin->get_global_setting( 'disabled-alerts', $this->disabled );
|
465 |
+
$this->disabled = ( '' === $this->disabled ) ? array() : explode( ',', $this->disabled );
|
466 |
+
$this->disabled = array_map( 'intval', $this->disabled );
|
467 |
}
|
468 |
+
return $this->disabled;
|
469 |
}
|
470 |
|
471 |
/**
|
473 |
*
|
474 |
* @param array $types IDs alerts to disable.
|
475 |
*/
|
476 |
+
public function set_disabled_alerts( $types ) {
|
477 |
+
$this->disabled = array_unique( array_map( 'intval', $types ) );
|
478 |
+
$this->plugin->set_global_setting( 'disabled-alerts', implode( ',', $this->disabled ) );
|
479 |
}
|
480 |
|
481 |
/**
|
482 |
+
* Checks if the plugin is in incognito mode.
|
483 |
+
*
|
484 |
* @return bool
|
485 |
*/
|
486 |
+
public function is_incognito() {
|
487 |
+
return $this->plugin->get_global_boolean_setting( 'hide-plugin' );
|
488 |
}
|
489 |
|
490 |
/**
|
491 |
+
* Enables or disables plugin's incognito mode.
|
492 |
+
*
|
493 |
+
* @param bool $enabled If true, the incognito mode gets enabled.
|
494 |
*/
|
495 |
+
public function set_incognito( $enabled ) {
|
496 |
+
$old_value = $this->plugin->get_global_setting( 'hide-plugin' );
|
497 |
+
$old_value = ( 'yes' === $old_value );
|
498 |
if ( $old_value !== $enabled ) {
|
499 |
+
$alert_data = array(
|
500 |
'EventType' => ( $enabled ) ? 'enabled' : 'disabled',
|
501 |
+
);
|
502 |
+
$this->plugin->alerts->trigger_event( 6051, $alert_data );
|
503 |
}
|
504 |
|
505 |
+
$this->plugin->set_global_boolean_setting( 'hide-plugin', $enabled );
|
506 |
}
|
507 |
|
508 |
/**
|
509 |
* Checking if the data will be removed.
|
510 |
*/
|
511 |
+
public function is_delete_data() {
|
512 |
+
return $this->plugin->get_global_boolean_setting( 'delete-data' );
|
513 |
}
|
514 |
|
515 |
/**
|
516 |
* Sets the plugin setting that allows data deletion on plugin uninstall.
|
517 |
*
|
518 |
+
* @param mixed $enabled If true, data deletion on plugin uninstall gets enabled.
|
519 |
*/
|
520 |
+
public function set_delete_data( $enabled ) {
|
521 |
+
$this->plugin->set_global_boolean_setting( 'delete-data', $enabled );
|
522 |
}
|
523 |
|
524 |
/**
|
526 |
*
|
527 |
* @param array $users_or_roles – Users/Roles.
|
528 |
*/
|
529 |
+
public function set_allowed_plugin_viewers( $users_or_roles ) {
|
530 |
|
531 |
+
$old_value = $this->plugin->get_global_setting( 'plugin-viewers' );
|
532 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $users_or_roles ) );
|
533 |
|
534 |
+
if ( ! empty( $changes['added'] ) ) {
|
535 |
+
foreach ( $changes['added'] as $user ) {
|
536 |
+
$this->plugin->alerts->trigger_event(
|
537 |
6050,
|
538 |
array(
|
539 |
'user' => $user,
|
544 |
}
|
545 |
}
|
546 |
|
547 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
548 |
+
foreach ( $changes['removed'] as $user ) {
|
549 |
if ( ! empty( $user ) ) {
|
550 |
+
$this->plugin->alerts->trigger_event(
|
551 |
6050,
|
552 |
array(
|
553 |
'user' => $user,
|
554 |
+
'previous_users' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
555 |
'EventType' => 'removed',
|
556 |
)
|
557 |
);
|
559 |
}
|
560 |
}
|
561 |
|
562 |
+
$this->viewers = $users_or_roles;
|
563 |
+
$this->plugin->set_global_setting( 'plugin-viewers', implode( ',', $this->viewers ), true );
|
|
|
564 |
}
|
565 |
|
566 |
/**
|
567 |
* Get Plugin Viewers.
|
568 |
+
*
|
569 |
+
* @return array List of users allowed to view the plugin.
|
570 |
*/
|
571 |
+
public function get_allowed_plugin_viewers() {
|
572 |
+
if ( is_null( $this->viewers ) ) {
|
573 |
+
$this->viewers = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'plugin-viewers' ) ) ) );
|
574 |
}
|
575 |
+
return $this->viewers;
|
576 |
}
|
577 |
|
578 |
/**
|
582 |
* @since 3.2.3
|
583 |
*/
|
584 |
public function set_restrict_plugin_setting( $setting ) {
|
585 |
+
$old_value = $this->plugin->get_global_setting( 'restrict-plugin-settings', 'only_admins' );
|
586 |
|
587 |
if ( ! is_null( $old_value ) && $old_value !== $setting ) {
|
588 |
+
$alert_data = array(
|
589 |
+
'new_setting' => ucfirst( str_replace( '_', ' ', $setting ) ),
|
590 |
+
'previous_setting' => ucfirst( str_replace( '_', ' ', $old_value ) ),
|
591 |
+
);
|
592 |
+
$this->plugin->alerts->trigger_event( 6049, $alert_data );
|
593 |
}
|
594 |
|
595 |
+
$this->plugin->set_global_setting( 'restrict-plugin-settings', $setting, true );
|
596 |
}
|
597 |
|
598 |
/**
|
601 |
* @since 3.2.3
|
602 |
*/
|
603 |
public function get_restrict_plugin_setting() {
|
604 |
+
return $this->plugin->get_global_setting( 'restrict-plugin-settings', 'only_admins' );
|
605 |
}
|
606 |
|
607 |
/**
|
610 |
* @since 4.1.3
|
611 |
*/
|
612 |
public function get_restrict_log_viewer() {
|
613 |
+
return $this->plugin->get_global_setting( 'restrict-log-viewer', 'only_admins' );
|
614 |
}
|
615 |
|
616 |
/**
|
620 |
* @since 4.1.3
|
621 |
*/
|
622 |
public function set_restrict_log_viewer( $setting ) {
|
623 |
+
$this->plugin->set_global_setting( 'restrict-log-viewer', $setting, true );
|
624 |
}
|
625 |
|
626 |
+
/**
|
627 |
+
* Sets the number of items per page for the audit log viewer.
|
628 |
+
*
|
629 |
+
* @param int $newvalue Number of items per page for the audit log viewer.
|
630 |
+
*/
|
631 |
+
public function set_views_per_page( $newvalue ) {
|
632 |
+
$this->per_page = max( intval( $newvalue ), 1 );
|
633 |
+
$this->plugin->set_global_setting( 'items-per-page', $this->per_page );
|
634 |
}
|
635 |
|
636 |
+
/**
|
637 |
+
* Gets the number of items per page for the audit log viewer.
|
638 |
+
*
|
639 |
+
* @return int Number of items per page for the audit log viewer.
|
640 |
+
*/
|
641 |
+
public function get_views_per_page() {
|
642 |
+
if ( is_null( $this->per_page ) ) {
|
643 |
+
$this->per_page = (int) $this->plugin->get_global_setting( 'items-per-page', 10 );
|
644 |
}
|
645 |
+
return $this->per_page;
|
646 |
}
|
647 |
|
648 |
/**
|
651 |
* @param string $action Type of action, either 'view' or 'edit'.
|
652 |
* @return boolean If user has access or not.
|
653 |
*/
|
654 |
+
public function current_user_can( $action ) {
|
655 |
+
return $this->user_can( wp_get_current_user(), $action );
|
656 |
}
|
657 |
|
658 |
/**
|
660 |
*
|
661 |
* @return array
|
662 |
*/
|
663 |
+
protected function get_super_admins() {
|
664 |
+
return $this->plugin->is_multisite() ? get_super_admins() : array();
|
665 |
}
|
666 |
|
667 |
/**
|
669 |
*
|
670 |
* @return string[]
|
671 |
*/
|
672 |
+
protected function get_admins() {
|
673 |
+
if ( $this->plugin->is_multisite() ) {
|
674 |
if ( empty( $this->site_admins ) ) {
|
675 |
/**
|
676 |
* Get list of admins.
|
686 |
. " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
|
687 |
|
688 |
// Get admins.
|
689 |
+
$this->site_admins = $wpdb->get_col( $sql ); // phpcs:ignore
|
690 |
}
|
691 |
} else {
|
692 |
if ( empty( $this->site_admins ) ) {
|
706 |
* @param string $action - Type of action, either 'view' or 'edit'.
|
707 |
* @return boolean If user has access or not.
|
708 |
*/
|
709 |
+
public function user_can( $user, $action ) {
|
710 |
if ( is_int( $user ) ) {
|
711 |
$user = get_userdata( $user );
|
712 |
}
|
713 |
|
714 |
+
// By default, the user has no privileges.
|
715 |
$result = false;
|
716 |
|
717 |
+
$is_multisite = $this->plugin->is_multisite();
|
718 |
switch ( $action ) {
|
719 |
case 'view':
|
720 |
if ( ! $is_multisite ) {
|
721 |
+
// Non-multisite piggybacks on the plugin settings access.
|
722 |
switch ( $this->get_restrict_plugin_setting() ) {
|
723 |
case 'only_admins':
|
724 |
+
// Allow access only if the user is and admin.
|
725 |
+
$result = in_array( 'administrator', $user->roles, true );
|
726 |
break;
|
727 |
case 'only_me':
|
728 |
+
// Allow access only if the user matches the only user allowed access.
|
729 |
+
$result = $user->ID === $this->get_only_me_user_id();
|
730 |
break;
|
731 |
default:
|
732 |
+
// No other options to allow access here.
|
733 |
$result = false;
|
734 |
}
|
735 |
} else {
|
736 |
+
// Multisite MUST respect the log viewer restriction settings plus also additional users and roles
|
737 |
+
// defined in the extra option.
|
738 |
switch ( $this->get_restrict_log_viewer() ) {
|
739 |
case 'only_me':
|
740 |
+
// Allow access only if the user matches the only user allowed access.
|
741 |
+
$result = ( $user->ID === $this->get_only_me_user_id() );
|
742 |
break;
|
743 |
case 'only_superadmins':
|
744 |
+
// Allow access only for super admins.
|
745 |
if ( function_exists( 'is_super_admin' ) && is_super_admin( $user->ID ) ) {
|
746 |
$result = true;
|
747 |
}
|
748 |
break;
|
749 |
case 'only_admins':
|
750 |
+
// Allow access only for super admins and admins.
|
751 |
+
$result = in_array( 'administrator', $user->roles, true ) || ( function_exists( 'is_super_admin' ) && is_super_admin( $user->ID ) );
|
752 |
break;
|
753 |
default:
|
754 |
+
// Fallback for any other cases would go here.
|
755 |
break;
|
756 |
}
|
757 |
}
|
758 |
|
759 |
if ( ! $result ) {
|
760 |
+
// User is still not allowed to view the logs, let's check the additional users and roles
|
761 |
+
// settings.
|
762 |
+
$extra_viewers = $this->get_allowed_plugin_viewers();
|
763 |
+
if ( in_array( $user->user_login, $extra_viewers ) ) { // phpcs:ignore
|
764 |
$result = true;
|
765 |
} elseif ( ! empty( array_intersect( $extra_viewers, $user->roles ) ) ) {
|
766 |
$result = true;
|
769 |
break;
|
770 |
case 'edit':
|
771 |
if ( $is_multisite ) {
|
772 |
+
// No one has access to settings on sub site inside a network.
|
773 |
if ( wp_doing_ajax() ) {
|
774 |
+
// AJAX calls are an exception.
|
775 |
$result = true;
|
776 |
} elseif ( ! is_network_admin() ) {
|
777 |
$result = false;
|
781 |
|
782 |
$restrict_plugin_setting = $this->get_restrict_plugin_setting();
|
783 |
if ( 'only_me' === $restrict_plugin_setting ) {
|
784 |
+
$result = ( $user->ID === $this->get_only_me_user_id() );
|
785 |
} elseif ( 'only_admins' === $restrict_plugin_setting ) {
|
786 |
if ( $is_multisite ) {
|
787 |
$result = ( function_exists( 'is_super_admin' ) && is_super_admin( $user->ID ) );
|
788 |
} else {
|
789 |
+
$result = in_array( 'administrator', $user->roles, true );
|
790 |
}
|
791 |
}
|
792 |
break;
|
807 |
return apply_filters( 'wsal_user_can', $result, $user, $action );
|
808 |
}
|
809 |
|
810 |
+
/**
|
811 |
+
* Retrieves current user's roles.
|
812 |
+
*
|
813 |
+
* @param string[] $base_roles An array of base roles.
|
814 |
+
*
|
815 |
+
* @return string[]
|
816 |
+
*/
|
817 |
+
public function get_current_user_roles( $base_roles = null ) {
|
818 |
+
if ( null === $base_roles ) {
|
819 |
$base_roles = wp_get_current_user()->roles;
|
820 |
}
|
821 |
if ( is_multisite() && function_exists( 'is_super_admin' ) && is_super_admin() ) {
|
824 |
return $base_roles;
|
825 |
}
|
826 |
|
827 |
+
/**
|
828 |
+
* Checks if given user is a superadmin.
|
829 |
+
*
|
830 |
+
* @param string $username Username.
|
831 |
+
*
|
832 |
+
* @return bool True if the user is a superadmin.
|
833 |
+
*/
|
834 |
+
public function is_login_super_admin( $username ) {
|
835 |
$user_id = username_exists( $username );
|
836 |
return function_exists( 'is_super_admin' ) && is_super_admin( $user_id );
|
837 |
}
|
838 |
|
839 |
+
/**
|
840 |
+
* Checks if IP address is determined based on proxy.
|
841 |
+
*
|
842 |
+
* @return bool True if IP address is determined based on proxy.
|
843 |
+
*/
|
844 |
+
public function is_main_ip_from_proxy() {
|
845 |
+
return $this->plugin->get_global_boolean_setting( 'use-proxy-ip' );
|
846 |
}
|
847 |
|
848 |
+
/**
|
849 |
+
* Sets the setting that decides if IP address should be determined based on proxy.
|
850 |
+
*
|
851 |
+
* @param bool $enabled True if IP address should be determined based on proxy.
|
852 |
+
*/
|
853 |
+
public function set_main_ip_from_proxy( $enabled ) {
|
854 |
+
$old_value = $this->plugin->get_global_boolean_setting( 'use-proxy-ip' );
|
855 |
+
$enabled = \WSAL\Helpers\Options::string_to_bool( $enabled );
|
856 |
if ( $old_value !== $enabled ) {
|
857 |
+
$alert_data = array(
|
858 |
'EventType' => ( $enabled ) ? 'enabled' : 'disabled',
|
859 |
+
);
|
860 |
+
$this->plugin->alerts->trigger_event( 6048, $alert_data );
|
861 |
}
|
862 |
+
$this->plugin->set_global_boolean_setting( 'use-proxy-ip', $enabled );
|
863 |
}
|
864 |
|
865 |
+
/**
|
866 |
+
* Checks if internal IP filtering is enabled.
|
867 |
+
*
|
868 |
+
* @return bool
|
869 |
+
*/
|
870 |
+
public function is_internal_ips_filtered() {
|
871 |
+
return $this->plugin->get_global_boolean_setting( 'filter-internal-ip', false );
|
872 |
}
|
873 |
|
874 |
+
/**
|
875 |
+
* Enables or disables the internal IP filtering.
|
876 |
+
*
|
877 |
+
* @param bool $enabled True if internal IP filtering should be enabled.
|
878 |
+
*/
|
879 |
+
public function set_internal_ips_filtering( $enabled ) {
|
880 |
+
$this->plugin->set_global_boolean_setting( 'filter-internal-ip', $enabled );
|
881 |
}
|
882 |
|
883 |
/**
|
885 |
*
|
886 |
* @return string|null
|
887 |
*/
|
888 |
+
public function get_main_client_ip() {
|
889 |
$result = null;
|
890 |
|
891 |
+
if ( $this->is_main_ip_from_proxy() ) {
|
892 |
// TODO: The algorithm below just gets the first IP in the list...we might want to make this more intelligent somehow.
|
893 |
+
$result = $this->get_client_ips();
|
894 |
$result = reset( $result );
|
895 |
$result = isset( $result[0] ) ? $result[0] : null;
|
896 |
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
|
897 |
$ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) );
|
898 |
+
$result = $this->normalize_ip( $ip );
|
899 |
|
900 |
+
if ( ! $this->validate_ip( $result ) ) {
|
901 |
$result = 'Error ' . self::ERROR_CODE_INVALID_IP . ': Invalid IP Address';
|
902 |
}
|
903 |
}
|
910 |
*
|
911 |
* @return array
|
912 |
*/
|
913 |
+
public function get_client_ips() {
|
914 |
$ips = array();
|
915 |
|
916 |
$proxy_headers = array(
|
922 |
'HTTP_FORWARDED_FOR',
|
923 |
'HTTP_FORWARDED',
|
924 |
'REMOTE_ADDR',
|
925 |
+
// Cloudflare.
|
926 |
'HTTP_CF-Connecting-IP',
|
927 |
+
'HTTP_TRUE_CLIENT_IP',
|
928 |
);
|
929 |
foreach ( $proxy_headers as $key ) {
|
930 |
if ( isset( $_SERVER[ $key ] ) ) {
|
931 |
$ips[ $key ] = array();
|
932 |
|
933 |
+
foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) { // phpcs:ignore
|
934 |
+
$ip = $this->normalize_ip( $ip );
|
935 |
+
if ( $this->validate_ip( $ip ) ) {
|
|
|
936 |
$ips[ $key ][] = $ip;
|
937 |
}
|
938 |
}
|
947 |
*
|
948 |
* @param string $ip - IP address.
|
949 |
* @return string
|
950 |
+
*
|
951 |
+
* phpcs:disable Squiz.PHP.CommentedOutCode.Found
|
952 |
*/
|
953 |
+
protected function normalize_ip( $ip ) {
|
954 |
$ip = trim( $ip );
|
955 |
|
956 |
if ( strpos( $ip, ':' ) !== false && substr_count( $ip, '.' ) === 3 && strpos( $ip, '[' ) === false ) {
|
972 |
* @param string $ip - IP address.
|
973 |
* @return string|bool
|
974 |
*/
|
975 |
+
protected function validate_ip( $ip ) {
|
976 |
$opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
|
977 |
|
978 |
+
if ( $this->is_internal_ips_filtered() ) {
|
979 |
$opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
980 |
}
|
981 |
|
997 |
}
|
998 |
|
999 |
/**
|
1000 |
+
* Sets the users excluded from monitoring.
|
1001 |
+
*
|
1002 |
+
* @param array $users Users to be excluded.
|
1003 |
*/
|
1004 |
+
public function set_excluded_monitoring_users( $users ) {
|
1005 |
|
1006 |
+
$old_value = $this->plugin->get_global_setting( 'excluded-users', array() );
|
1007 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $users ) );
|
1008 |
|
1009 |
+
if ( ! empty( $changes['added'] ) ) {
|
1010 |
+
foreach ( $changes['added'] as $user ) {
|
1011 |
+
$this->plugin->alerts->trigger_event(
|
1012 |
6053,
|
1013 |
array(
|
1014 |
'user' => $user,
|
1018 |
);
|
1019 |
}
|
1020 |
}
|
1021 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
1022 |
+
foreach ( $changes['removed'] as $user ) {
|
1023 |
+
$this->plugin->alerts->trigger_event(
|
1024 |
6053,
|
1025 |
array(
|
1026 |
'user' => $user,
|
1027 |
+
'previous_users' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1028 |
'EventType' => 'removed',
|
1029 |
)
|
1030 |
);
|
1031 |
}
|
1032 |
}
|
1033 |
|
1034 |
+
$this->excluded_users = $users;
|
1035 |
+
$this->plugin->set_global_setting( 'excluded-users', esc_html( implode( ',', $this->excluded_users ) ) );
|
1036 |
}
|
1037 |
|
1038 |
+
/**
|
1039 |
+
* Retrieves the users excluded from monitoring.
|
1040 |
+
*
|
1041 |
+
* @return array Users excluded from monitoring.
|
1042 |
+
*/
|
1043 |
+
public function get_excluded_monitoring_users() {
|
1044 |
+
if ( empty( $this->excluded_users ) ) {
|
1045 |
+
$this->excluded_users = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'excluded-users' ) ) ) );
|
1046 |
}
|
1047 |
+
return $this->excluded_users;
|
1048 |
}
|
1049 |
|
1050 |
/**
|
1055 |
*/
|
1056 |
public function set_excluded_post_types( $post_types ) {
|
1057 |
|
1058 |
+
$old_value = $this->plugin->get_global_setting( 'custom-post-types', array() );
|
1059 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $post_types ) );
|
1060 |
|
1061 |
+
if ( ! empty( $changes['added'] ) ) {
|
1062 |
+
foreach ( $changes['added'] as $post_type ) {
|
1063 |
+
$this->plugin->alerts->trigger_event(
|
1064 |
6056,
|
1065 |
array(
|
1066 |
'post_type' => $post_type,
|
1071 |
}
|
1072 |
}
|
1073 |
|
1074 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
1075 |
+
foreach ( $changes['removed'] as $post_type ) {
|
1076 |
+
$this->plugin->alerts->trigger_event(
|
1077 |
6056,
|
1078 |
array(
|
1079 |
'post_type' => $post_type,
|
1080 |
+
'previous_types' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1081 |
'EventType' => 'removed',
|
1082 |
)
|
1083 |
);
|
1084 |
}
|
1085 |
}
|
1086 |
|
1087 |
+
$this->post_types = $post_types;
|
1088 |
+
$this->plugin->set_global_setting( 'custom-post-types', esc_html( implode( ',', $this->post_types ) ) );
|
1089 |
}
|
1090 |
|
1091 |
/**
|
1094 |
* @since 2.6.7
|
1095 |
*/
|
1096 |
public function get_excluded_post_types() {
|
1097 |
+
if ( empty( $this->post_types ) ) {
|
1098 |
+
$this->post_types = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'custom-post-types' ) ) ) );
|
1099 |
}
|
1100 |
+
return $this->post_types;
|
1101 |
}
|
1102 |
|
1103 |
/**
|
1105 |
*
|
1106 |
* @param array $roles - Array of roles.
|
1107 |
*/
|
1108 |
+
public function set_excluded_monitoring_roles( $roles ) {
|
1109 |
|
1110 |
// Trigger alert.
|
1111 |
+
$old_value = $this->plugin->get_global_setting( 'excluded-roles', array() );
|
1112 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $roles ) );
|
1113 |
|
1114 |
+
if ( ! empty( $changes['added'] ) ) {
|
1115 |
+
foreach ( $changes['added'] as $user ) {
|
1116 |
+
$this->plugin->alerts->trigger_event(
|
1117 |
6054,
|
1118 |
array(
|
1119 |
'role' => $user,
|
1123 |
);
|
1124 |
}
|
1125 |
}
|
1126 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
1127 |
+
foreach ( $changes['removed'] as $user ) {
|
1128 |
+
$this->plugin->alerts->trigger_event(
|
1129 |
6054,
|
1130 |
array(
|
1131 |
'role' => $user,
|
1132 |
+
'previous_users' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1133 |
'EventType' => 'removed',
|
1134 |
)
|
1135 |
);
|
1136 |
}
|
1137 |
}
|
1138 |
|
1139 |
+
$this->excluded_roles = $roles;
|
1140 |
+
$this->plugin->set_global_setting( 'excluded-roles', esc_html( implode( ',', $roles ) ) );
|
1141 |
}
|
1142 |
|
1143 |
/**
|
1144 |
* Get roles excluded from monitoring.
|
1145 |
*/
|
1146 |
+
public function get_excluded_monitoring_roles() {
|
1147 |
+
if ( empty( $this->excluded_roles ) ) {
|
1148 |
+
$this->excluded_roles = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'excluded-roles' ) ) ) );
|
1149 |
}
|
1150 |
+
return $this->excluded_roles;
|
1151 |
}
|
1152 |
|
1153 |
/**
|
1154 |
* Updates custom post meta fields excluded from monitoring.
|
1155 |
*
|
1156 |
+
* @param array $custom Excluded post meta fields.
|
1157 |
*/
|
1158 |
+
public function set_excluded_post_meta_fields( $custom ) {
|
1159 |
+
$old_value = $this->get_excluded_post_meta_fields();
|
1160 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $custom ) );
|
1161 |
|
1162 |
+
if ( ! empty( $changes['added'] ) ) {
|
1163 |
+
foreach ( $changes['added'] as $custom_field ) {
|
1164 |
+
$this->plugin->alerts->trigger_event(
|
1165 |
6057,
|
1166 |
array(
|
1167 |
'custom_field' => $custom_field,
|
1168 |
'previous_fields' => ( empty( $old_value ) ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1169 |
+
'EventType' => 'added',
|
1170 |
)
|
1171 |
);
|
1172 |
}
|
1173 |
}
|
1174 |
|
1175 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
1176 |
+
foreach ( $changes['removed'] as $custom_field ) {
|
1177 |
+
$this->plugin->alerts->trigger_event(
|
1178 |
6057,
|
1179 |
array(
|
1180 |
'custom_field' => $custom_field,
|
1181 |
+
'previous_fields' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1182 |
+
'EventType' => 'removed',
|
1183 |
)
|
1184 |
);
|
1185 |
}
|
1186 |
}
|
1187 |
|
1188 |
+
$this->excluded_post_meta = $custom;
|
1189 |
+
$this->plugin->set_global_setting( 'excluded-post-meta', esc_html( implode( ',', $this->excluded_post_meta ) ) );
|
1190 |
}
|
1191 |
|
1192 |
/**
|
1194 |
*
|
1195 |
* @return array
|
1196 |
*/
|
1197 |
+
public function get_excluded_post_meta_fields() {
|
1198 |
+
if ( empty( $this->excluded_post_meta ) ) {
|
1199 |
+
$this->excluded_post_meta = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'excluded-post-meta' ) ) ) );
|
1200 |
+
asort( $this->excluded_post_meta );
|
1201 |
}
|
1202 |
+
return $this->excluded_post_meta;
|
1203 |
}
|
1204 |
|
1205 |
/**
|
1206 |
* Updates custom user meta fields excluded from monitoring.
|
1207 |
*
|
1208 |
+
* @param array $custom Custom user meta fields excluded from monitoring.
|
1209 |
*
|
1210 |
* @since 4.3.2
|
1211 |
*/
|
1212 |
+
public function set_excluded_user_meta_fields( $custom ) {
|
1213 |
|
1214 |
+
$old_value = $this->get_excluded_user_meta_fields();
|
1215 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $custom ) );
|
1216 |
|
1217 |
+
if ( ! empty( $changes['added'] ) ) {
|
1218 |
+
foreach ( $changes['added'] as $custom_field ) {
|
1219 |
+
$this->plugin->alerts->trigger_event(
|
1220 |
6058,
|
1221 |
array(
|
1222 |
'custom_field' => $custom_field,
|
1223 |
'previous_fields' => ( empty( $old_value ) ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1224 |
+
'EventType' => 'added',
|
1225 |
)
|
1226 |
);
|
1227 |
}
|
1228 |
}
|
1229 |
|
1230 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
1231 |
+
foreach ( $changes['removed'] as $custom_field ) {
|
1232 |
+
$this->plugin->alerts->trigger_event(
|
1233 |
6058,
|
1234 |
array(
|
1235 |
'custom_field' => $custom_field,
|
1236 |
+
'previous_fields' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1237 |
+
'EventType' => 'removed',
|
1238 |
)
|
1239 |
);
|
1240 |
}
|
1241 |
}
|
1242 |
|
1243 |
+
$this->excluded_user_meta = $custom;
|
1244 |
+
$this->plugin->set_global_setting( 'excluded-user-meta', esc_html( implode( ',', $this->excluded_user_meta ) ) );
|
1245 |
}
|
1246 |
|
1247 |
/**
|
1250 |
* @return array
|
1251 |
* @since 4.3.2
|
1252 |
*/
|
1253 |
+
public function get_excluded_user_meta_fields() {
|
1254 |
+
if ( empty( $this->excluded_user_meta ) ) {
|
1255 |
+
$this->excluded_user_meta = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'excluded-user-meta' ) ) ) );
|
1256 |
+
asort( $this->excluded_user_meta );
|
1257 |
}
|
1258 |
|
1259 |
+
return $this->excluded_user_meta;
|
1260 |
}
|
1261 |
|
1262 |
/**
|
1263 |
* IP excluded from monitoring.
|
1264 |
+
*
|
1265 |
+
* @param array $ip IP addresses to exclude from monitoring.
|
1266 |
*/
|
1267 |
+
public function set_excluded_monitoring_ip( $ip ) {
|
1268 |
+
$old_value = $this->plugin->get_global_setting( 'excluded-ip', array() );
|
1269 |
+
$changes = $this->determine_added_and_removed_items( $old_value, implode( ',', $ip ) );
|
1270 |
|
1271 |
+
if ( ! empty( $changes['added'] ) ) {
|
1272 |
+
foreach ( $changes['added'] as $user ) {
|
1273 |
+
$this->plugin->alerts->trigger_event(
|
1274 |
6055,
|
1275 |
array(
|
1276 |
'ip' => $user,
|
1280 |
);
|
1281 |
}
|
1282 |
}
|
1283 |
+
if ( ! empty( $changes['removed'] ) && ! empty( $old_value ) ) {
|
1284 |
+
foreach ( $changes['removed'] as $user ) {
|
1285 |
+
$this->plugin->alerts->trigger_event(
|
1286 |
6055,
|
1287 |
array(
|
1288 |
'ip' => $user,
|
1289 |
+
'previous_ips' => empty( $old_value ) ? $this->tidy_blank_values( $old_value ) : str_replace( ',', ', ', $old_value ),
|
1290 |
'EventType' => 'removed',
|
1291 |
)
|
1292 |
);
|
1293 |
}
|
1294 |
}
|
1295 |
|
1296 |
+
$this->excluded_ip = $ip;
|
1297 |
+
$this->plugin->set_global_setting( 'excluded-ip', esc_html( implode( ',', $this->excluded_ip ) ) );
|
1298 |
}
|
1299 |
|
1300 |
+
/**
|
1301 |
+
* Retrieves a list of IP addresses to exclude from monitoring.
|
1302 |
+
*
|
1303 |
+
* @return array List of IP addresses to exclude from monitoring.
|
1304 |
+
*/
|
1305 |
+
public function get_excluded_monitoring_ip() {
|
1306 |
+
if ( empty( $this->excluded_ip ) ) {
|
1307 |
+
$this->excluded_ip = array_unique( array_filter( explode( ',', $this->plugin->get_global_setting( 'excluded-ip' ) ) ) );
|
1308 |
}
|
1309 |
+
return $this->excluded_ip;
|
1310 |
}
|
1311 |
|
1312 |
/**
|
1316 |
* Note: Format returned by this function is not compatible with JavaScript date and time picker widgets. Use
|
1317 |
* functions GetTimeFormat and GetDateFormat for those.
|
1318 |
*
|
1319 |
+
* @param boolean $line_break - True if line break otherwise false.
|
1320 |
+
* @param boolean $use_nb_space_for_am_pm True if non-breakable space should be placed before the AM/PM chars.
|
1321 |
*
|
1322 |
* @return string
|
1323 |
*/
|
1324 |
+
public function get_datetime_format( $line_break = true, $use_nb_space_for_am_pm = true ) {
|
1325 |
+
$result = $this->get_date_format();
|
1326 |
|
1327 |
$result .= $line_break ? '<\b\r>' : ' ';
|
1328 |
|
1329 |
+
$time_format = $this->get_time_format();
|
1330 |
$has_am_pm = false;
|
1331 |
$am_pm_fraction = false;
|
1332 |
$am_pm_pattern = '/(?i)(\s+A)/';
|
1341 |
$time_format .= ':s'; // Add seconds to time format.
|
1342 |
}
|
1343 |
|
1344 |
+
if ( $this->get_show_milliseconds() ) {
|
1345 |
$time_format .= '.$$$'; // Add milliseconds to time format.
|
1346 |
}
|
1347 |
|
|
|
1348 |
if ( $has_am_pm ) {
|
1349 |
$time_format .= preg_replace( '/\s/', $use_nb_space_for_am_pm ? '&\n\b\s\p;' : ' ', $am_pm_fraction );
|
1350 |
}
|
1364 |
*
|
1365 |
* @return string
|
1366 |
*/
|
1367 |
+
public function get_date_format( $sanitized = false ) {
|
1368 |
if ( $sanitized ) {
|
1369 |
return 'Y-m-d';
|
1370 |
}
|
1382 |
*
|
1383 |
* @return string
|
1384 |
*/
|
1385 |
+
public function get_time_format( $sanitize = false ) {
|
1386 |
$result = get_option( 'time_format' );
|
1387 |
if ( $sanitize ) {
|
1388 |
$search = array( 'a', 'A', 'T', ' ' );
|
1397 |
*
|
1398 |
* Server's timezone or WordPress' timezone.
|
1399 |
*/
|
1400 |
+
public function get_timezone() {
|
1401 |
+
return $this->plugin->get_global_setting( 'timezone', 'wp' );
|
1402 |
}
|
1403 |
|
1404 |
+
/**
|
1405 |
+
* Updates the timezone handling setting.
|
1406 |
+
*
|
1407 |
+
* @param string $newvalue New setting value.
|
1408 |
+
*
|
1409 |
+
* @return void
|
1410 |
+
*/
|
1411 |
+
public function set_timezone( $newvalue ) {
|
1412 |
+
$this->plugin->set_global_setting( 'timezone', $newvalue );
|
1413 |
}
|
1414 |
|
1415 |
/**
|
1421 |
* @return bool
|
1422 |
*/
|
1423 |
public function get_show_milliseconds() {
|
1424 |
+
return $this->plugin->get_global_boolean_setting( 'show_milliseconds', true );
|
1425 |
}
|
1426 |
|
1427 |
/**
|
1434 |
* @param mixed $newvalue ideally always bool. If not bool then it's cast to true.
|
1435 |
*/
|
1436 |
public function set_show_milliseconds( $newvalue ) {
|
1437 |
+
$this->plugin->set_global_boolean_setting( 'show_milliseconds', $newvalue );
|
1438 |
}
|
1439 |
|
1440 |
|
1442 |
* Get type of username to display.
|
1443 |
*/
|
1444 |
public function get_type_username() {
|
1445 |
+
return $this->plugin->get_global_setting( 'type_username', 'display_name' );
|
1446 |
}
|
1447 |
|
1448 |
/**
|
1452 |
* @since 2.6.5
|
1453 |
*/
|
1454 |
public function set_type_username( $newvalue ) {
|
1455 |
+
$this->plugin->set_global_setting( 'type_username', $newvalue );
|
1456 |
}
|
1457 |
|
1458 |
/**
|
1460 |
*
|
1461 |
* @return array
|
1462 |
*/
|
1463 |
+
public function get_columns() {
|
1464 |
$columns = array(
|
1465 |
'alert_code' => '1',
|
1466 |
'type' => '1',
|
1474 |
'info' => '1',
|
1475 |
);
|
1476 |
|
1477 |
+
if ( $this->plugin->is_multisite() ) {
|
1478 |
$columns = array_slice( $columns, 0, 6, true ) + array( 'site' => '1' ) + array_slice( $columns, 6, null, true );
|
1479 |
}
|
1480 |
|
1481 |
+
$selected = $this->get_columns_selected();
|
1482 |
|
1483 |
if ( ! empty( $selected ) ) {
|
1484 |
$columns = array(
|
1493 |
'message' => '0',
|
1494 |
);
|
1495 |
|
1496 |
+
if ( $this->plugin->is_multisite() ) {
|
1497 |
$columns = array_slice( $columns, 0, 6, true ) + array( 'site' => '0' ) + array_slice( $columns, 6, null, true );
|
1498 |
}
|
1499 |
|
1504 |
return $columns;
|
1505 |
}
|
1506 |
|
1507 |
+
/**
|
1508 |
+
* Gets the list of columns selected for display in the audit log viewer.
|
1509 |
+
*
|
1510 |
+
* @return array List of columns selected for display in the audit log viewer
|
1511 |
+
*/
|
1512 |
+
public function get_columns_selected() {
|
1513 |
+
return $this->plugin->get_global_setting( 'columns', array() );
|
1514 |
}
|
1515 |
|
1516 |
+
/**
|
1517 |
+
* Sets the list of columns selected for display in the audit log viewer.
|
1518 |
+
*
|
1519 |
+
* @param array $columns List of columns selected for display in the audit log viewer.
|
1520 |
+
*/
|
1521 |
+
public function set_columns( $columns ) {
|
1522 |
+
$this->plugin->set_global_setting( 'columns', json_encode( $columns ) ); // phpcs:ignore
|
1523 |
}
|
1524 |
|
1525 |
+
/**
|
1526 |
+
* Checks if the monitoring of background events is enabled.
|
1527 |
+
*
|
1528 |
+
* @return bool True if the monitoring of background events is enabled.
|
1529 |
+
*/
|
1530 |
+
public function is_wp_backend() {
|
1531 |
+
return $this->plugin->get_global_boolean_setting( 'wp-backend' );
|
1532 |
}
|
1533 |
|
1534 |
+
/**
|
1535 |
+
* Enables or disables the monitoring of background events.
|
1536 |
+
*
|
1537 |
+
* @param bool $enabled True if the monitoring of background events should be enabled.
|
1538 |
+
*/
|
1539 |
+
public function set_wp_backend( $enabled ) {
|
1540 |
+
$this->plugin->set_global_boolean_setting( 'wp-backend', $enabled );
|
1541 |
}
|
1542 |
|
1543 |
/**
|
1546 |
* @param string $use – Setting value.
|
1547 |
*/
|
1548 |
public function set_use_email( $use ) {
|
1549 |
+
$this->plugin->set_global_setting( 'use-email', $use );
|
1550 |
}
|
1551 |
|
1552 |
/**
|
1555 |
* @return string
|
1556 |
*/
|
1557 |
public function get_use_email() {
|
1558 |
+
return $this->plugin->get_global_setting( 'use-email', 'default_email' );
|
1559 |
}
|
1560 |
|
1561 |
+
/**
|
1562 |
+
* Sets the "From" email address.
|
1563 |
+
*
|
1564 |
+
* @param string $email_address The "From" email address.
|
1565 |
+
*/
|
1566 |
+
public function set_from_email( $email_address ) {
|
1567 |
+
$this->plugin->set_global_setting( 'from-email', trim( $email_address ) );
|
1568 |
}
|
1569 |
|
1570 |
+
/**
|
1571 |
+
* Get the "From" email address.
|
1572 |
+
*
|
1573 |
+
* @return string The "From" email address.
|
1574 |
+
*/
|
1575 |
+
public function get_from_email() {
|
1576 |
+
return $this->plugin->get_global_setting( 'from-email' );
|
1577 |
}
|
1578 |
|
1579 |
+
/**
|
1580 |
+
* Sets the user display name for the event audit log.
|
1581 |
+
*
|
1582 |
+
* @param string $display_name User display name setting.
|
1583 |
+
*
|
1584 |
+
* @return void
|
1585 |
+
*/
|
1586 |
+
public function set_display_name( $display_name ) {
|
1587 |
+
$this->plugin->set_global_setting( 'display-name', trim( $display_name ) );
|
1588 |
}
|
1589 |
|
1590 |
+
/**
|
1591 |
+
* Gets the user display name for the event audit log.
|
1592 |
+
*
|
1593 |
+
* @return string User display name setting.
|
1594 |
+
*/
|
1595 |
+
public function get_display_name() {
|
1596 |
+
return $this->plugin->get_global_setting( 'display-name' );
|
1597 |
}
|
1598 |
|
1599 |
/**
|
1604 |
*/
|
1605 |
public function set_failed_login_limit( $value ) {
|
1606 |
if ( ! empty( $value ) ) {
|
1607 |
+
$this->plugin->set_global_setting( 'log-failed-login-limit', abs( $value ) );
|
1608 |
} else {
|
1609 |
+
$this->plugin->set_global_setting( 'log-failed-login-limit', - 1 );
|
1610 |
}
|
1611 |
}
|
1612 |
|
1617 |
* @since 2.6.3
|
1618 |
*/
|
1619 |
public function get_failed_login_limit() {
|
1620 |
+
return intval( $this->plugin->get_global_setting( 'log-failed-login-limit', 10 ) );
|
1621 |
}
|
1622 |
|
1623 |
/**
|
1628 |
*/
|
1629 |
public function set_visitor_failed_login_limit( $value ) {
|
1630 |
if ( ! empty( $value ) ) {
|
1631 |
+
$this->plugin->set_global_setting( 'log-visitor-failed-login-limit', abs( $value ) );
|
1632 |
} else {
|
1633 |
+
$this->plugin->set_global_setting( 'log-visitor-failed-login-limit', - 1 );
|
1634 |
}
|
1635 |
}
|
1636 |
|
1641 |
* @since 2.6.3
|
1642 |
*/
|
1643 |
public function get_visitor_failed_login_limit() {
|
1644 |
+
return intval( $this->plugin->get_global_setting( 'log-visitor-failed-login-limit', 10 ) );
|
1645 |
}
|
1646 |
|
1647 |
|
1661 |
}
|
1662 |
|
1663 |
// Check if the token matched users.
|
1664 |
+
if ( in_array( $token, $users ) ) { // phpcs:ignore
|
1665 |
return 'user';
|
1666 |
}
|
1667 |
|
1669 |
$roles = array_keys( get_editable_roles() );
|
1670 |
|
1671 |
// Check if the token matched user roles.
|
1672 |
+
if ( in_array( $token, $roles, true ) ) {
|
1673 |
return 'role';
|
1674 |
}
|
1675 |
|
1685 |
}
|
1686 |
|
1687 |
// Check if the token matched post types.
|
1688 |
+
if ( in_array( $token, $post_types, true ) ) {
|
1689 |
return 'cpts';
|
1690 |
}
|
1691 |
|
1731 |
*/
|
1732 |
public function set_mainwp_child_stealth_mode() {
|
1733 |
if (
|
1734 |
+
! $this->plugin->get_global_boolean_setting( 'mwp-child-stealth-mode', false ) // MainWP Child Stealth Mode is not already active.
|
1735 |
&& WpSecurityAuditLog::is_mainwp_active() // And if MainWP Child plugin is installed & active.
|
1736 |
) {
|
1737 |
// Check if freemius state is anonymous.
|
1738 |
+
if ( ! wsal_freemius()->is_premium() && 'anonymous' === $this->plugin->get_global_setting( 'freemius_state', 'anonymous' ) ) {
|
1739 |
// Update Freemius state to skipped.
|
1740 |
+
$this->plugin->set_global_setting( 'wsal_freemius_state', 'skipped', true );
|
1741 |
|
1742 |
+
if ( ! $this->plugin->is_multisite() ) {
|
1743 |
wsal_freemius()->skip_connection(); // Opt out.
|
1744 |
} else {
|
1745 |
wsal_freemius()->skip_connection( null, true ); // Opt out for all websites.
|
1754 |
FS_Admin_Notices::instance( 'wp-security-audit-log' )->remove_sticky( 'trial_promotion' );
|
1755 |
}
|
1756 |
|
1757 |
+
$this->set_incognito( true ); // Incognito mode to hide WSAL on plugins page.
|
1758 |
$this->set_restrict_log_viewer( 'only_me' );
|
1759 |
$this->set_restrict_plugin_setting( 'only_me' );
|
1760 |
// Current user with fallback to default admin (in case this is triggered using WP CLI or something similar).
|
1761 |
$only_me_user_id = is_user_logged_in() ? get_current_user_id() : 1;
|
1762 |
$this->set_only_me_user_id( $only_me_user_id );
|
1763 |
+
$this->plugin->set_global_boolean_setting( 'mwp-child-stealth-mode', true ); // Save stealth mode option.
|
1764 |
}
|
1765 |
}
|
1766 |
|
1770 |
* @since 3.2.3.3
|
1771 |
*/
|
1772 |
public function deactivate_mainwp_child_stealth_mode() {
|
1773 |
+
$this->set_incognito( false ); // Disable incognito mode to hide WSAL on plugins page.
|
1774 |
$this->set_restrict_plugin_setting( 'only_admins' );
|
1775 |
$this->set_restrict_log_viewer( 'only_admins' );
|
1776 |
$this->set_admin_blocking_plugin_support( false );
|
1777 |
+
$this->plugin->set_global_boolean_setting( 'mwp-child-stealth-mode', false ); // Disable stealth mode option.
|
1778 |
}
|
1779 |
|
1780 |
/**
|
1787 |
return;
|
1788 |
}
|
1789 |
|
1790 |
+
if ( $this->plugin->get_global_boolean_setting( 'mwp-child-stealth-mode', false ) ) {
|
1791 |
$this->deactivate_mainwp_child_stealth_mode();
|
1792 |
}
|
1793 |
}
|
1798 |
* @return boolean
|
1799 |
*/
|
1800 |
public function is_stealth_mode() {
|
1801 |
+
return $this->plugin->get_global_boolean_setting( 'mwp-child-stealth-mode', false );
|
1802 |
}
|
1803 |
|
1804 |
/**
|
1811 |
public function get_view_site_id() {
|
1812 |
switch ( true ) {
|
1813 |
// Non-multisite.
|
1814 |
+
case ! $this->plugin->is_multisite():
|
1815 |
return 0;
|
1816 |
// Multisite + main site view.
|
1817 |
case $this->is_main_blog() && ! $this->is_specific_view():
|
1844 |
* @return bool
|
1845 |
*/
|
1846 |
protected function is_specific_view() {
|
1847 |
+
return isset( $_REQUEST['wsal-cbid'] ) && 0 !== (int) $_REQUEST['wsal-cbid']; // phpcs:ignore
|
1848 |
}
|
1849 |
|
1850 |
/**
|
1855 |
* @return int
|
1856 |
*/
|
1857 |
protected function get_specific_view() {
|
1858 |
+
return isset( $_REQUEST['wsal-cbid'] ) ? (int) sanitize_text_field( wp_unslash( $_REQUEST['wsal-cbid'] ) ) : 0; // phpcs:ignore
|
1859 |
}
|
1860 |
|
1861 |
/**
|
1873 |
if ( ! is_null( $limit ) ) {
|
1874 |
$sql .= ' LIMIT ' . $limit;
|
1875 |
}
|
1876 |
+
$res = $wpdb->get_results( $sql ); // phpcs:ignore
|
1877 |
foreach ( $res as $row ) {
|
1878 |
$row->blogname = get_blog_option( $row->blog_id, 'blogname' );
|
1879 |
}
|
1890 |
public function get_site_count() {
|
1891 |
global $wpdb;
|
1892 |
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
1893 |
+
return (int) $wpdb->get_var( $sql ); // phpcs:ignore
|
1894 |
}
|
1895 |
|
1896 |
/**
|
1916 |
* @return string
|
1917 |
*/
|
1918 |
public function get_events_type_nav() {
|
1919 |
+
return $this->plugin->get_global_setting( 'events-nav-type', 'infinite-scroll' );
|
1920 |
}
|
1921 |
|
1922 |
/**
|
1929 |
* @param string $nav_type - Navigation type.
|
1930 |
*/
|
1931 |
public function set_events_type_nav( $nav_type ) {
|
1932 |
+
$this->plugin->set_global_setting( 'events-nav-type', $nav_type );
|
1933 |
}
|
1934 |
|
1935 |
/**
|
1939 |
*/
|
1940 |
public function get_plugin_settings() {
|
1941 |
global $wpdb;
|
1942 |
+
return $wpdb->get_results( "SELECT * FROM $wpdb->options WHERE option_name LIKE 'wsal_%'" ); // phpcs:ignore
|
1943 |
}
|
1944 |
|
1945 |
/**
|
2158 |
* @since 4.1.3
|
2159 |
*/
|
2160 |
public function set_only_me_user_id( $user_id ) {
|
2161 |
+
$this->plugin->set_global_setting( 'only-me-user-id', $user_id, true );
|
2162 |
}
|
2163 |
|
2164 |
/**
|
2168 |
* @since 4.1.3
|
2169 |
*/
|
2170 |
public function get_only_me_user_id() {
|
2171 |
+
return (int) $this->plugin->get_global_setting( 'only-me-user-id' );
|
2172 |
}
|
2173 |
|
2174 |
/**
|
2175 |
* Save admin blocking plugin support enabled.
|
2176 |
*
|
2177 |
+
* @param bool $enabled True, if admin blocking plugin support should be enabled.
|
2178 |
*/
|
2179 |
public function set_admin_blocking_plugin_support( $enabled ) {
|
2180 |
+
$this->plugin->set_global_boolean_setting( 'admin-blocking-plugins-support', $enabled );
|
2181 |
}
|
2182 |
|
2183 |
/**
|
2190 |
* @return bool
|
2191 |
*/
|
2192 |
public function get_admin_blocking_plugin_support() {
|
2193 |
+
return $this->plugin->get_global_boolean_setting( 'admin-blocking-plugins-support', false );
|
2194 |
}
|
2195 |
|
2196 |
+
/**
|
2197 |
+
* Retrieves the settings enforced by MainWP from local database.
|
2198 |
+
*
|
2199 |
+
* @return array Settings enforced by MainWP.
|
2200 |
+
*/
|
2201 |
public function get_mainwp_enforced_settings() {
|
2202 |
+
return $this->plugin->get_global_setting( 'mainwp_enforced_settings', array() );
|
2203 |
}
|
2204 |
|
2205 |
+
/**
|
2206 |
+
* Stores the settings enforced by MainWP in local database.
|
2207 |
+
*
|
2208 |
+
* @param array $settings Enforced settings.
|
2209 |
+
*/
|
2210 |
public function set_mainwp_enforced_settings( $settings ) {
|
2211 |
+
$this->plugin->set_global_setting( 'mainwp_enforced_settings', $settings );
|
2212 |
}
|
2213 |
|
2214 |
+
/**
|
2215 |
+
* Deletes the settings enforced by MainWP from local database.
|
2216 |
+
*/
|
2217 |
public function delete_mainwp_enforced_settings() {
|
2218 |
+
$this->plugin->delete_global_setting( 'mainwp_enforced_settings' );
|
2219 |
}
|
2220 |
|
2221 |
+
/**
|
2222 |
+
* Determines added and removed items between 2 arrays.
|
2223 |
+
*
|
2224 |
+
* @param array|string $old_value Old list. Support comma separated string.
|
2225 |
+
* @param array|string $value New list. Support comma separated string.
|
2226 |
+
*
|
2227 |
+
* @return array
|
2228 |
+
*/
|
2229 |
public function determine_added_and_removed_items( $old_value, $value ) {
|
2230 |
$old_value = ( ! is_array( $old_value ) ) ? explode( ',', $old_value ) : $old_value;
|
2231 |
$value = ( ! is_array( $value ) ) ? explode( ',', $value ) : $value;
|
2236 |
return $return;
|
2237 |
}
|
2238 |
|
2239 |
+
/**
|
2240 |
+
* Tidies-up the blank values.
|
2241 |
+
*
|
2242 |
+
* @param string $value Value.
|
2243 |
+
*
|
2244 |
+
* @return string Tidies up value.
|
2245 |
+
*/
|
2246 |
public function tidy_blank_values( $value ) {
|
2247 |
return ( empty( $value ) ) ? __( 'None provided', 'wp-security-audit-log' ) : $value;
|
2248 |
}
|
2254 |
* @since 4.3.2
|
2255 |
*/
|
2256 |
public function get_database_version() {
|
2257 |
+
return (int) $this->plugin->get_global_setting( 'db_version', 0 );
|
2258 |
}
|
2259 |
|
2260 |
/**
|
2264 |
* @since 4.3.2
|
2265 |
*/
|
2266 |
public function set_database_version( $version ) {
|
2267 |
+
$this->plugin->set_global_setting( 'db_version', $version, true );
|
2268 |
}
|
2269 |
|
2270 |
}
|
classes/ThirdPartyExtensions/AbstractExtension.php
CHANGED
@@ -1,30 +1,48 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_AbstractExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
abstract class WSAL_AbstractExtension {
|
6 |
|
7 |
/**
|
|
|
|
|
8 |
* @var WSAL_AbstractExtension[]
|
9 |
* @since 4.3.2
|
10 |
*/
|
11 |
-
private static $extensions =
|
12 |
|
13 |
/**
|
|
|
|
|
14 |
* @var WSAL_AbstractExtension[]
|
15 |
* @since 4.3.2
|
16 |
*/
|
17 |
private static $post_types_map;
|
18 |
|
19 |
/**
|
20 |
-
*
|
|
|
|
|
21 |
*
|
22 |
* @return WSAL_AbstractExtension|null
|
23 |
* @since 4.3.2
|
24 |
*/
|
25 |
public static function get_extension_for_post_type( $post_type ) {
|
26 |
if ( is_null( self::$post_types_map ) ) {
|
27 |
-
self::$post_types_map =
|
28 |
if ( ! empty( self::$extensions ) ) {
|
29 |
foreach ( self::$extensions as $extension ) {
|
30 |
$post_types = $extension->get_custom_post_types();
|
@@ -46,13 +64,15 @@ if ( ! class_exists( 'WSAL_AbstractExtension' ) ) {
|
|
46 |
|
47 |
/**
|
48 |
* WSAL_AbstractExtension constructor.
|
49 |
-
*
|
50 |
*/
|
51 |
public function __construct() {
|
52 |
array_push( self::$extensions, $this );
|
53 |
$this->add_filters();
|
54 |
}
|
55 |
|
|
|
|
|
|
|
56 |
public function add_filters() {
|
57 |
add_filter( 'wsal_filter_installable_plugins', array( $this, 'filter_installable_plugins' ), 10, 1 );
|
58 |
add_filter( 'wsal_addon_event_codes', array( $this, 'add_event_codes' ), 10, 1 );
|
@@ -95,17 +115,32 @@ if ( ! class_exists( 'WSAL_AbstractExtension' ) ) {
|
|
95 |
* @since 4.3.2
|
96 |
*/
|
97 |
public function get_custom_post_types() {
|
98 |
-
return
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
|
|
101 |
abstract public function get_plugin_name();
|
102 |
|
|
|
|
|
|
|
|
|
|
|
103 |
abstract public function get_plugin_icon_url();
|
104 |
|
|
|
|
|
|
|
|
|
|
|
105 |
abstract public function get_color();
|
106 |
|
107 |
/**
|
108 |
-
* Gets the filename of the plugin this extension is
|
109 |
*
|
110 |
* @return string Filename.
|
111 |
*
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Abstract WSAL extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_AbstractExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Abstract class to provide basic information about a specific WSAL extension.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
abstract class WSAL_AbstractExtension {
|
18 |
|
19 |
/**
|
20 |
+
* List of extensions.
|
21 |
+
*
|
22 |
* @var WSAL_AbstractExtension[]
|
23 |
* @since 4.3.2
|
24 |
*/
|
25 |
+
private static $extensions = array();
|
26 |
|
27 |
/**
|
28 |
+
* A map of custom post types specific to each extension (if any).
|
29 |
+
*
|
30 |
* @var WSAL_AbstractExtension[]
|
31 |
* @since 4.3.2
|
32 |
*/
|
33 |
private static $post_types_map;
|
34 |
|
35 |
/**
|
36 |
+
* Retrieves an extension class associated with given pst type.
|
37 |
+
*
|
38 |
+
* @param string $post_type Post type.
|
39 |
*
|
40 |
* @return WSAL_AbstractExtension|null
|
41 |
* @since 4.3.2
|
42 |
*/
|
43 |
public static function get_extension_for_post_type( $post_type ) {
|
44 |
if ( is_null( self::$post_types_map ) ) {
|
45 |
+
self::$post_types_map = array();
|
46 |
if ( ! empty( self::$extensions ) ) {
|
47 |
foreach ( self::$extensions as $extension ) {
|
48 |
$post_types = $extension->get_custom_post_types();
|
64 |
|
65 |
/**
|
66 |
* WSAL_AbstractExtension constructor.
|
|
|
67 |
*/
|
68 |
public function __construct() {
|
69 |
array_push( self::$extensions, $this );
|
70 |
$this->add_filters();
|
71 |
}
|
72 |
|
73 |
+
/**
|
74 |
+
* Initialises necessary filters.
|
75 |
+
*/
|
76 |
public function add_filters() {
|
77 |
add_filter( 'wsal_filter_installable_plugins', array( $this, 'filter_installable_plugins' ), 10, 1 );
|
78 |
add_filter( 'wsal_addon_event_codes', array( $this, 'add_event_codes' ), 10, 1 );
|
115 |
* @since 4.3.2
|
116 |
*/
|
117 |
public function get_custom_post_types() {
|
118 |
+
return array();
|
119 |
}
|
120 |
|
121 |
+
/**
|
122 |
+
* Retrieves a plugin name.
|
123 |
+
*
|
124 |
+
* @return string Plugin name.
|
125 |
+
*/
|
126 |
abstract public function get_plugin_name();
|
127 |
|
128 |
+
/**
|
129 |
+
* Gets a plugin icon URL.
|
130 |
+
*
|
131 |
+
* @return string Plugin icon URL.
|
132 |
+
*/
|
133 |
abstract public function get_plugin_icon_url();
|
134 |
|
135 |
+
/**
|
136 |
+
* Retrieves the color to use when showing some info about the extension.
|
137 |
+
*
|
138 |
+
* @return string HEX color.
|
139 |
+
*/
|
140 |
abstract public function get_color();
|
141 |
|
142 |
/**
|
143 |
+
* Gets the filename of the plugin this extension is targeting.
|
144 |
*
|
145 |
* @return string Filename.
|
146 |
*
|
classes/ThirdPartyExtensions/BBPressExtension.php
CHANGED
@@ -1,9 +1,24 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class WSAL_BBPressExtension extends WSAL_AbstractExtension {
|
6 |
|
|
|
|
|
|
|
7 |
public function filter_installable_plugins( $plugins ) {
|
8 |
$new_plugin = array(
|
9 |
array(
|
@@ -22,6 +37,9 @@ if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
|
22 |
return array_merge( $plugins, $new_plugin );
|
23 |
}
|
24 |
|
|
|
|
|
|
|
25 |
public function add_event_codes( $addon_event_codes ) {
|
26 |
$new_event_codes = array(
|
27 |
'bbpress' => array(
|
@@ -34,22 +52,37 @@ if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
|
34 |
return array_merge( $addon_event_codes, $new_event_codes );
|
35 |
}
|
36 |
|
|
|
|
|
|
|
37 |
public function get_custom_post_types() {
|
38 |
return array( 'forum', 'topic', 'reply' );
|
39 |
}
|
40 |
|
|
|
|
|
|
|
41 |
public function get_plugin_name() {
|
42 |
-
return '
|
43 |
}
|
44 |
|
|
|
|
|
|
|
45 |
public function get_plugin_icon_url() {
|
46 |
return 'https://ps.w.org/wp-security-audit-log-add-on-for-bbpress/assets/icon-128x128.png?rev=2253395';
|
47 |
}
|
48 |
|
|
|
|
|
|
|
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 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* The bbPress extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_BBPressExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for bbPress.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_BBPressExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
public function filter_installable_plugins( $plugins ) {
|
23 |
$new_plugin = array(
|
24 |
array(
|
37 |
return array_merge( $plugins, $new_plugin );
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* {@inheritDoc}
|
42 |
+
*/
|
43 |
public function add_event_codes( $addon_event_codes ) {
|
44 |
$new_event_codes = array(
|
45 |
'bbpress' => array(
|
52 |
return array_merge( $addon_event_codes, $new_event_codes );
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* {@inheritDoc}
|
57 |
+
*/
|
58 |
public function get_custom_post_types() {
|
59 |
return array( 'forum', 'topic', 'reply' );
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* {@inheritDoc}
|
64 |
+
*/
|
65 |
public function get_plugin_name() {
|
66 |
+
return 'bbPress';
|
67 |
}
|
68 |
|
69 |
+
/**
|
70 |
+
* {@inheritDoc}
|
71 |
+
*/
|
72 |
public function get_plugin_icon_url() {
|
73 |
return 'https://ps.w.org/wp-security-audit-log-add-on-for-bbpress/assets/icon-128x128.png?rev=2253395';
|
74 |
}
|
75 |
|
76 |
+
/**
|
77 |
+
* {@inheritDoc}
|
78 |
+
*/
|
79 |
public function get_color() {
|
80 |
return '#8dc770';
|
81 |
}
|
82 |
|
83 |
+
/**
|
84 |
+
* {@inheritDoc}
|
85 |
+
*/
|
86 |
public function get_plugin_filename() {
|
87 |
return 'wp-security-audit-log-add-on-for-bbpress/wsal-bbpress.php';
|
88 |
}
|
classes/ThirdPartyExtensions/GravityFormsExtension.php
CHANGED
@@ -1,9 +1,24 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_GravityFormsExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class WSAL_GravityFormsExtension extends WSAL_AbstractExtension {
|
6 |
|
|
|
|
|
|
|
7 |
public function filter_installable_plugins( $plugins ) {
|
8 |
$new_plugin = array(
|
9 |
array(
|
@@ -14,13 +29,16 @@ if ( ! class_exists( 'WSAL_GravityFormsExtension' ) ) {
|
|
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 |
);
|
19 |
|
20 |
// combine the two arrays.
|
21 |
return array_merge( $plugins, $new_plugin );
|
22 |
}
|
23 |
|
|
|
|
|
|
|
24 |
public function add_event_codes( $addon_event_codes ) {
|
25 |
$new_event_codes = array(
|
26 |
'gravityforms' => array(
|
@@ -30,21 +48,33 @@ if ( ! class_exists( 'WSAL_GravityFormsExtension' ) ) {
|
|
30 |
);
|
31 |
|
32 |
// combine the two arrays.
|
33 |
-
return
|
34 |
}
|
35 |
|
|
|
|
|
|
|
36 |
public function get_plugin_name() {
|
37 |
return 'Gravity Forms';
|
38 |
}
|
39 |
|
|
|
|
|
|
|
40 |
public function get_plugin_icon_url() {
|
41 |
return 'https://ps.w.org/activity-log-gravity-forms/assets/icon-128x128.png?rev=2465070';
|
42 |
}
|
43 |
|
|
|
|
|
|
|
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 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Gravity Forms extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_GravityFormsExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for Gravity Forms.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_GravityFormsExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
public function filter_installable_plugins( $plugins ) {
|
23 |
$new_plugin = array(
|
24 |
array(
|
29 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-gravity-forms.latest-stable.zip',
|
30 |
'event_tab_id' => '#cat-gravity-forms',
|
31 |
'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' ),
|
32 |
+
),
|
33 |
);
|
34 |
|
35 |
// combine the two arrays.
|
36 |
return array_merge( $plugins, $new_plugin );
|
37 |
}
|
38 |
|
39 |
+
/**
|
40 |
+
* {@inheritDoc}
|
41 |
+
*/
|
42 |
public function add_event_codes( $addon_event_codes ) {
|
43 |
$new_event_codes = array(
|
44 |
'gravityforms' => array(
|
48 |
);
|
49 |
|
50 |
// combine the two arrays.
|
51 |
+
return array_merge( $addon_event_codes, $new_event_codes );
|
52 |
}
|
53 |
|
54 |
+
/**
|
55 |
+
* {@inheritDoc}
|
56 |
+
*/
|
57 |
public function get_plugin_name() {
|
58 |
return 'Gravity Forms';
|
59 |
}
|
60 |
|
61 |
+
/**
|
62 |
+
* {@inheritDoc}
|
63 |
+
*/
|
64 |
public function get_plugin_icon_url() {
|
65 |
return 'https://ps.w.org/activity-log-gravity-forms/assets/icon-128x128.png?rev=2465070';
|
66 |
}
|
67 |
|
68 |
+
/**
|
69 |
+
* {@inheritDoc}
|
70 |
+
*/
|
71 |
public function get_color() {
|
72 |
return '#F15A29';
|
73 |
}
|
74 |
|
75 |
+
/**
|
76 |
+
* {@inheritDoc}
|
77 |
+
*/
|
78 |
public function get_plugin_filename() {
|
79 |
return 'activity-log-gravity-forms/activity-log-gravity-forms.php';
|
80 |
}
|
classes/ThirdPartyExtensions/TablePressExtension.php
CHANGED
@@ -1,9 +1,24 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class WSAL_TablePressExtension extends WSAL_AbstractExtension {
|
6 |
|
|
|
|
|
|
|
7 |
public function filter_installable_plugins( $plugins ) {
|
8 |
$new_plugin = array(
|
9 |
array(
|
@@ -22,6 +37,9 @@ if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
|
22 |
return array_merge( $plugins, $new_plugin );
|
23 |
}
|
24 |
|
|
|
|
|
|
|
25 |
public function add_event_codes( $addon_event_codes ) {
|
26 |
$new_event_codes = array(
|
27 |
'yoast' => array(
|
@@ -34,22 +52,37 @@ if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
|
34 |
return array_merge( $addon_event_codes, $new_event_codes );
|
35 |
}
|
36 |
|
|
|
|
|
|
|
37 |
public function get_custom_post_types() {
|
38 |
return array( 'tablepress_table' );
|
39 |
}
|
40 |
|
|
|
|
|
|
|
41 |
public function get_plugin_name() {
|
42 |
return 'TablePress';
|
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 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* TablePress extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_TablePressExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for TablePress.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_TablePressExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
public function filter_installable_plugins( $plugins ) {
|
23 |
$new_plugin = array(
|
24 |
array(
|
37 |
return array_merge( $plugins, $new_plugin );
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* {@inheritDoc}
|
42 |
+
*/
|
43 |
public function add_event_codes( $addon_event_codes ) {
|
44 |
$new_event_codes = array(
|
45 |
'yoast' => array(
|
52 |
return array_merge( $addon_event_codes, $new_event_codes );
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* {@inheritDoc}
|
57 |
+
*/
|
58 |
public function get_custom_post_types() {
|
59 |
return array( 'tablepress_table' );
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* {@inheritDoc}
|
64 |
+
*/
|
65 |
public function get_plugin_name() {
|
66 |
return 'TablePress';
|
67 |
}
|
68 |
|
69 |
+
/**
|
70 |
+
* {@inheritDoc}
|
71 |
+
*/
|
72 |
public function get_plugin_icon_url() {
|
73 |
return 'https://ps.w.org/activity-log-tablepress/assets/icon-128x128.png?rev=2393849';
|
74 |
}
|
75 |
|
76 |
+
/**
|
77 |
+
* {@inheritDoc}
|
78 |
+
*/
|
79 |
public function get_color() {
|
80 |
return '#a4286a';
|
81 |
}
|
82 |
|
83 |
+
/**
|
84 |
+
* {@inheritDoc}
|
85 |
+
*/
|
86 |
public function get_plugin_filename() {
|
87 |
return 'activity-log-tablepress/wsal-tablepress.php';
|
88 |
}
|
classes/ThirdPartyExtensions/WFCMExtension.php
CHANGED
@@ -1,13 +1,31 @@
|
|
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( '
|
9 |
}
|
10 |
|
|
|
|
|
|
|
11 |
public function filter_installable_plugins( $plugins ) {
|
12 |
$new_plugin = array(
|
13 |
array(
|
@@ -19,13 +37,16 @@ if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
|
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(
|
@@ -38,18 +59,35 @@ if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
|
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 ) ) {
|
@@ -69,7 +107,7 @@ if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
|
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',
|
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>';
|
@@ -88,11 +126,11 @@ if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
|
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',
|
96 |
|
97 |
$body .= '</table></td></tr><!-- Table Border Start --><!-- Desc End --></table></td></tr><!-- Website File Changes End -->';
|
98 |
}
|
@@ -110,6 +148,9 @@ if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
|
110 |
return $body;
|
111 |
}
|
112 |
|
|
|
|
|
|
|
113 |
public function get_plugin_filename() {
|
114 |
return 'website-file-changes-monitor/website-file-changes-monitor.php';
|
115 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WFCM extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_WFCMExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for WFCM.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_WFCMExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
public function __construct() {
|
23 |
+
add_filter( 'append_dailynotification_email_content', array( $this, 'append_dailynotification_email_content' ), 10, 2 );
|
24 |
}
|
25 |
|
26 |
+
/**
|
27 |
+
* {@inheritDoc}
|
28 |
+
*/
|
29 |
public function filter_installable_plugins( $plugins ) {
|
30 |
$new_plugin = array(
|
31 |
array(
|
37 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/website-file-changes-monitor.latest-stable.zip',
|
38 |
'event_tab_id' => '#cat-wfcm',
|
39 |
'plugin_description' => 'To keep a log of file changes please install Website File Changes Monitor, a plugin which is also developed by us.',
|
40 |
+
),
|
41 |
);
|
42 |
|
43 |
// combine the two arrays.
|
44 |
return array_merge( $plugins, $new_plugin );
|
45 |
}
|
46 |
|
47 |
+
/**
|
48 |
+
* {@inheritDoc}
|
49 |
+
*/
|
50 |
public function add_event_codes( $addon_event_codes ) {
|
51 |
$new_event_codes = array(
|
52 |
'wfcm' => array(
|
59 |
return array_merge( $addon_event_codes, $new_event_codes );
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* {@inheritDoc}
|
64 |
+
*/
|
65 |
public function get_plugin_name() {
|
66 |
return 'Website File Changes Monitor';
|
67 |
}
|
68 |
|
69 |
+
/**
|
70 |
+
* {@inheritDoc}
|
71 |
+
*/
|
72 |
public function get_plugin_icon_url() {
|
73 |
return 'https://ps.w.org/website-file-changes-monitor/assets/icon-128x128.png?rev=2393849';
|
74 |
}
|
75 |
|
76 |
+
/**
|
77 |
+
* {@inheritDoc}
|
78 |
+
*/
|
79 |
public function get_color() {
|
80 |
return '#a4286a';
|
81 |
}
|
82 |
|
83 |
+
/**
|
84 |
+
* Appends content to the daily notification email content.
|
85 |
+
*
|
86 |
+
* @param string $body Email body (text).
|
87 |
+
* @param array $events Events.
|
88 |
+
*
|
89 |
+
* @return string
|
90 |
+
*/
|
91 |
public function append_dailynotification_email_content( $body, $events ) {
|
92 |
|
93 |
if ( ! empty( $events ) ) {
|
107 |
if ( ! empty( $files_added ) || ! empty( $files_modified ) || ! empty( $files_deleted ) ) {
|
108 |
$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">';
|
109 |
|
110 |
+
$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>'; // phpcs:disable
|
111 |
|
112 |
if ( ! empty( $files_added ) ) {
|
113 |
$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>';
|
126 |
$body .= '</table></td></tr><!-- Table Border Start --><!-- Desc End --></table></td></tr><!-- Website File Changes End -->';
|
127 |
}
|
128 |
|
129 |
+
// No changes to report.
|
130 |
if ( empty( $files_added ) && empty( $files_modified ) && empty( $files_deleted ) && class_exists( 'Website_File_Changes_Monitor' ) ) {
|
131 |
$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">';
|
132 |
|
133 |
+
$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>';
|
134 |
|
135 |
$body .= '</table></td></tr><!-- Table Border Start --><!-- Desc End --></table></td></tr><!-- Website File Changes End -->';
|
136 |
}
|
148 |
return $body;
|
149 |
}
|
150 |
|
151 |
+
/**
|
152 |
+
* {@inheritDoc}
|
153 |
+
*/
|
154 |
public function get_plugin_filename() {
|
155 |
return 'website-file-changes-monitor/website-file-changes-monitor.php';
|
156 |
}
|
classes/ThirdPartyExtensions/WPFormsExtension.php
CHANGED
@@ -1,9 +1,24 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_WPFormsExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class WSAL_WPFormsExtension extends WSAL_AbstractExtension {
|
6 |
|
|
|
|
|
|
|
7 |
public function filter_installable_plugins( $plugins ) {
|
8 |
$new_plugin = array(
|
9 |
array(
|
@@ -15,13 +30,16 @@ if ( ! class_exists( 'WSAL_WPFormsExtension' ) ) {
|
|
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 |
);
|
20 |
|
21 |
// combine the two arrays.
|
22 |
return array_merge( $plugins, $new_plugin );
|
23 |
}
|
24 |
|
|
|
|
|
|
|
25 |
public function add_event_codes( $addon_event_codes ) {
|
26 |
$new_event_codes = array(
|
27 |
'wpforms' => array(
|
@@ -34,22 +52,37 @@ if ( ! class_exists( 'WSAL_WPFormsExtension' ) ) {
|
|
34 |
return array_merge( $addon_event_codes, $new_event_codes );
|
35 |
}
|
36 |
|
|
|
|
|
|
|
37 |
public function get_custom_post_types() {
|
38 |
-
return
|
39 |
}
|
40 |
|
|
|
|
|
|
|
41 |
public function get_plugin_name() {
|
42 |
return 'WPForms';
|
43 |
}
|
44 |
|
|
|
|
|
|
|
45 |
public function get_plugin_icon_url() {
|
46 |
return 'https://ps.w.org/wp-security-audit-log-add-on-for-wpforms/assets/icon-128x128.png?rev=2241926';
|
47 |
}
|
48 |
|
|
|
|
|
|
|
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 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* WP Forms extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_WPFormsExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for WP Forms.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_WPFormsExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
public function filter_installable_plugins( $plugins ) {
|
23 |
$new_plugin = array(
|
24 |
array(
|
30 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-security-audit-log-add-on-for-wpforms.latest-stable.zip',
|
31 |
'event_tab_id' => '#cat-wpforms',
|
32 |
'plugin_description' => 'Keep a record of when someone adds, modifies or deletes forms, entries and more in the WPForms plugin.',
|
33 |
+
),
|
34 |
);
|
35 |
|
36 |
// combine the two arrays.
|
37 |
return array_merge( $plugins, $new_plugin );
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* {@inheritDoc}
|
42 |
+
*/
|
43 |
public function add_event_codes( $addon_event_codes ) {
|
44 |
$new_event_codes = array(
|
45 |
'wpforms' => array(
|
52 |
return array_merge( $addon_event_codes, $new_event_codes );
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* {@inheritDoc}
|
57 |
+
*/
|
58 |
public function get_custom_post_types() {
|
59 |
+
return array( 'wpforms' );
|
60 |
}
|
61 |
|
62 |
+
/**
|
63 |
+
* {@inheritDoc}
|
64 |
+
*/
|
65 |
public function get_plugin_name() {
|
66 |
return 'WPForms';
|
67 |
}
|
68 |
|
69 |
+
/**
|
70 |
+
* {@inheritDoc}
|
71 |
+
*/
|
72 |
public function get_plugin_icon_url() {
|
73 |
return 'https://ps.w.org/wp-security-audit-log-add-on-for-wpforms/assets/icon-128x128.png?rev=2241926';
|
74 |
}
|
75 |
|
76 |
+
/**
|
77 |
+
* {@inheritDoc}
|
78 |
+
*/
|
79 |
public function get_color() {
|
80 |
return '#e27730';
|
81 |
}
|
82 |
|
83 |
+
/**
|
84 |
+
* {@inheritDoc}
|
85 |
+
*/
|
86 |
public function get_plugin_filename() {
|
87 |
return 'wp-security-audit-log-add-on-for-wpforms/wsal-wpforms.php';
|
88 |
}
|
classes/ThirdPartyExtensions/WooCommerceExtension.php
CHANGED
@@ -1,14 +1,32 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_WooCommerceExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class WSAL_WooCommerceExtension extends WSAL_AbstractExtension {
|
6 |
|
7 |
-
|
|
|
|
|
|
|
8 |
parent::__construct();
|
9 |
add_filter( 'wsal_save_settings_disabled_events', array( $this, 'save_settings_disabled_events' ), 10, 4 );
|
10 |
}
|
11 |
|
|
|
|
|
|
|
12 |
public function filter_installable_plugins( $plugins ) {
|
13 |
$new_plugin = array(
|
14 |
array(
|
@@ -27,6 +45,9 @@ if ( ! class_exists( 'WSAL_WooCommerceExtension' ) ) {
|
|
27 |
return array_merge( $plugins, $new_plugin );
|
28 |
}
|
29 |
|
|
|
|
|
|
|
30 |
public function add_event_codes( $addon_event_codes ) {
|
31 |
$new_event_codes = array(
|
32 |
'woocommerce' => array(
|
@@ -66,29 +87,44 @@ if ( ! class_exists( 'WSAL_WooCommerceExtension' ) ) {
|
|
66 |
return $disabled;
|
67 |
}
|
68 |
|
|
|
|
|
|
|
69 |
public function get_custom_post_types() {
|
70 |
-
return
|
71 |
'product',
|
72 |
'shop_coupon',
|
73 |
'shop_order',
|
74 |
'shop_order_refund',
|
75 |
'product_variation',
|
76 |
-
'wc_product_tab'
|
77 |
-
|
78 |
}
|
79 |
|
|
|
|
|
|
|
80 |
public function get_plugin_name() {
|
81 |
return 'WooCommerce';
|
82 |
}
|
83 |
|
|
|
|
|
|
|
84 |
public function get_plugin_icon_url() {
|
85 |
return 'https://ps.w.org/wp-activity-log-for-woocommerce/assets/icon-128x128.png?rev=2357550';
|
86 |
}
|
87 |
|
|
|
|
|
|
|
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 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Woocommerce extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_WooCommerceExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for WooCommerce.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_WooCommerceExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
+
public function __construct() {
|
23 |
parent::__construct();
|
24 |
add_filter( 'wsal_save_settings_disabled_events', array( $this, 'save_settings_disabled_events' ), 10, 4 );
|
25 |
}
|
26 |
|
27 |
+
/**
|
28 |
+
* {@inheritDoc}
|
29 |
+
*/
|
30 |
public function filter_installable_plugins( $plugins ) {
|
31 |
$new_plugin = array(
|
32 |
array(
|
45 |
return array_merge( $plugins, $new_plugin );
|
46 |
}
|
47 |
|
48 |
+
/**
|
49 |
+
* {@inheritDoc}
|
50 |
+
*/
|
51 |
public function add_event_codes( $addon_event_codes ) {
|
52 |
$new_event_codes = array(
|
53 |
'woocommerce' => array(
|
87 |
return $disabled;
|
88 |
}
|
89 |
|
90 |
+
/**
|
91 |
+
* {@inheritDoc}
|
92 |
+
*/
|
93 |
public function get_custom_post_types() {
|
94 |
+
return array(
|
95 |
'product',
|
96 |
'shop_coupon',
|
97 |
'shop_order',
|
98 |
'shop_order_refund',
|
99 |
'product_variation',
|
100 |
+
'wc_product_tab',
|
101 |
+
);
|
102 |
}
|
103 |
|
104 |
+
/**
|
105 |
+
* {@inheritDoc}
|
106 |
+
*/
|
107 |
public function get_plugin_name() {
|
108 |
return 'WooCommerce';
|
109 |
}
|
110 |
|
111 |
+
/**
|
112 |
+
* {@inheritDoc}
|
113 |
+
*/
|
114 |
public function get_plugin_icon_url() {
|
115 |
return 'https://ps.w.org/wp-activity-log-for-woocommerce/assets/icon-128x128.png?rev=2357550';
|
116 |
}
|
117 |
|
118 |
+
/**
|
119 |
+
* {@inheritDoc}
|
120 |
+
*/
|
121 |
public function get_color() {
|
122 |
return '#7f54b3';
|
123 |
}
|
124 |
|
125 |
+
/**
|
126 |
+
* {@inheritDoc}
|
127 |
+
*/
|
128 |
public function get_plugin_filename() {
|
129 |
return 'wp-activity-log-for-woocommerce/wsal-woocommerce.php';
|
130 |
}
|
classes/ThirdPartyExtensions/YoastSeoExtension.php
CHANGED
@@ -1,9 +1,24 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
class WSAL_YoastSeoExtension extends WSAL_AbstractExtension {
|
6 |
|
|
|
|
|
|
|
7 |
public function filter_installable_plugins( $plugins ) {
|
8 |
$new_plugin = array(
|
9 |
array(
|
@@ -15,13 +30,16 @@ if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
|
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 |
);
|
20 |
|
21 |
// combine the two arrays.
|
22 |
return array_merge( $plugins, $new_plugin );
|
23 |
}
|
24 |
|
|
|
|
|
|
|
25 |
public function add_event_codes( $addon_event_codes ) {
|
26 |
$new_event_codes = array(
|
27 |
'yoast' => array(
|
@@ -34,6 +52,9 @@ if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
|
34 |
return array_merge( $addon_event_codes, $new_event_codes );
|
35 |
}
|
36 |
|
|
|
|
|
|
|
37 |
public function modify_predefined_plugin_slug( $plugin ) {
|
38 |
// Correct yoast addon.
|
39 |
if ( 'yoast' === $plugin ) {
|
@@ -43,18 +64,30 @@ if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
|
43 |
return $plugin;
|
44 |
}
|
45 |
|
|
|
|
|
|
|
46 |
public function get_plugin_name() {
|
47 |
return 'Yoast SEO';
|
48 |
}
|
49 |
|
|
|
|
|
|
|
50 |
public function get_plugin_icon_url() {
|
51 |
return 'https://ps.w.org/activity-log-wp-seo/assets/icon-128x128.png?rev=2393849';
|
52 |
}
|
53 |
|
|
|
|
|
|
|
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 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Yoast SEO extension class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage add-ons
|
7 |
+
*/
|
8 |
|
9 |
if ( ! class_exists( 'WSAL_YoastSeoExtension' ) ) {
|
10 |
|
11 |
+
/**
|
12 |
+
* Class provides basic information about WSAL extension for Yoast SEO.
|
13 |
+
*
|
14 |
+
* @package wsal
|
15 |
+
* @subpackage add-ons
|
16 |
+
*/
|
17 |
class WSAL_YoastSeoExtension extends WSAL_AbstractExtension {
|
18 |
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*/
|
22 |
public function filter_installable_plugins( $plugins ) {
|
23 |
$new_plugin = array(
|
24 |
array(
|
30 |
'plugin_url' => 'https://downloads.wordpress.org/plugin/activity-log-wp-seo.latest-stable.zip',
|
31 |
'event_tab_id' => '#cat-yoast-seo',
|
32 |
'plugin_description' => 'Keep a log of all the changes that you and your team do in the Yoast SEO metabox, plugin settings & much more.',
|
33 |
+
),
|
34 |
);
|
35 |
|
36 |
// combine the two arrays.
|
37 |
return array_merge( $plugins, $new_plugin );
|
38 |
}
|
39 |
|
40 |
+
/**
|
41 |
+
* {@inheritDoc}
|
42 |
+
*/
|
43 |
public function add_event_codes( $addon_event_codes ) {
|
44 |
$new_event_codes = array(
|
45 |
'yoast' => array(
|
52 |
return array_merge( $addon_event_codes, $new_event_codes );
|
53 |
}
|
54 |
|
55 |
+
/**
|
56 |
+
* {@inheritDoc}
|
57 |
+
*/
|
58 |
public function modify_predefined_plugin_slug( $plugin ) {
|
59 |
// Correct yoast addon.
|
60 |
if ( 'yoast' === $plugin ) {
|
64 |
return $plugin;
|
65 |
}
|
66 |
|
67 |
+
/**
|
68 |
+
* {@inheritDoc}
|
69 |
+
*/
|
70 |
public function get_plugin_name() {
|
71 |
return 'Yoast SEO';
|
72 |
}
|
73 |
|
74 |
+
/**
|
75 |
+
* {@inheritDoc}
|
76 |
+
*/
|
77 |
public function get_plugin_icon_url() {
|
78 |
return 'https://ps.w.org/activity-log-wp-seo/assets/icon-128x128.png?rev=2393849';
|
79 |
}
|
80 |
|
81 |
+
/**
|
82 |
+
* {@inheritDoc}
|
83 |
+
*/
|
84 |
public function get_color() {
|
85 |
return '#a4286a';
|
86 |
}
|
87 |
|
88 |
+
/**
|
89 |
+
* {@inheritDoc}
|
90 |
+
*/
|
91 |
public function get_plugin_filename() {
|
92 |
return 'activity-log-wp-seo/activity-log-wp-seo.php';
|
93 |
}
|
classes/Uninstall.php
CHANGED
@@ -47,8 +47,13 @@ class WSAL_Uninstall {
|
|
47 |
return self::should_data_be_deleted();
|
48 |
}
|
49 |
|
|
|
|
|
|
|
|
|
|
|
50 |
private static function should_data_be_deleted() {
|
51 |
-
return in_array( get_option( 'wsal_delete-data' ),
|
52 |
}
|
53 |
|
54 |
/**
|
@@ -70,7 +75,7 @@ class WSAL_Uninstall {
|
|
70 |
private static function drop_table( $name ) {
|
71 |
global $wpdb;
|
72 |
$table_name = self::get_table( $name );
|
73 |
-
$wpdb->query( 'DROP TABLE IF EXISTS ' . $table_name );
|
74 |
}
|
75 |
|
76 |
/**
|
@@ -78,18 +83,18 @@ class WSAL_Uninstall {
|
|
78 |
*/
|
79 |
public static function delete_options_from_wp_options() {
|
80 |
global $wpdb;
|
81 |
-
$plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wsal_%'" );
|
82 |
|
83 |
foreach ( $plugin_options as $option ) {
|
84 |
delete_option( $option->option_name );
|
85 |
}
|
86 |
|
87 |
-
// Remove wsal specific
|
88 |
delete_option( 'fs_wsalp' );
|
89 |
-
|
90 |
// Ensue entry is fully cleared.
|
91 |
-
delete_network_option( 0
|
92 |
|
93 |
-
//
|
94 |
}
|
95 |
}
|
47 |
return self::should_data_be_deleted();
|
48 |
}
|
49 |
|
50 |
+
/**
|
51 |
+
* Checks if data should be deleted.
|
52 |
+
*
|
53 |
+
* @return bool True if data should be deleted.
|
54 |
+
*/
|
55 |
private static function should_data_be_deleted() {
|
56 |
+
return in_array( get_option( 'wsal_delete-data' ), array( 'yes', 1, '1', 'y', 'true', true ), true );
|
57 |
}
|
58 |
|
59 |
/**
|
75 |
private static function drop_table( $name ) {
|
76 |
global $wpdb;
|
77 |
$table_name = self::get_table( $name );
|
78 |
+
$wpdb->query( 'DROP TABLE IF EXISTS ' . $table_name ); // phpcs:ignore
|
79 |
}
|
80 |
|
81 |
/**
|
83 |
*/
|
84 |
public static function delete_options_from_wp_options() {
|
85 |
global $wpdb;
|
86 |
+
$plugin_options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'wsal_%'" ); // phpcs:ignore
|
87 |
|
88 |
foreach ( $plugin_options as $option ) {
|
89 |
delete_option( $option->option_name );
|
90 |
}
|
91 |
|
92 |
+
// Remove wsal specific Freemius entry.
|
93 |
delete_option( 'fs_wsalp' );
|
94 |
+
|
95 |
// Ensue entry is fully cleared.
|
96 |
+
delete_network_option( 0, 'wsal_networkwide_tracker_cpts' );
|
97 |
|
98 |
+
// @todo delete also options from site-level tables in multisite context
|
99 |
}
|
100 |
}
|
classes/Upgrade/MetadataMigration.php
CHANGED
@@ -1,4 +1,11 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
// Exit if accessed directly.
|
4 |
if ( ! defined( 'ABSPATH' ) ) {
|
@@ -12,9 +19,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
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
|
16 |
* @subpackage upgrade
|
17 |
-
* @since
|
18 |
*/
|
19 |
class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
20 |
|
@@ -28,7 +35,9 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
28 |
const OPTION_NAME_MIGRATION_INFO = 'meta_data_migration_info_440';
|
29 |
|
30 |
/**
|
31 |
-
*
|
|
|
|
|
32 |
*/
|
33 |
protected $action = 'wsal_meta_data_migration_440';
|
34 |
|
@@ -53,8 +62,8 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
53 |
return;
|
54 |
}
|
55 |
|
56 |
-
$plugin = WpSecurityAuditLog::
|
57 |
-
$existing_info = $plugin->
|
58 |
if ( empty( $existing_info ) ) {
|
59 |
return;
|
60 |
}
|
@@ -72,17 +81,17 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
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 |
-
//
|
81 |
$items_migrated = $this->process_next_batch( $item['connection'], $item['batch_size'] );
|
82 |
if ( 0 === $items_migrated ) {
|
83 |
-
//
|
84 |
try {
|
85 |
-
//
|
86 |
self::remove_migration_info( $item['connection'] );
|
87 |
|
88 |
} catch ( Exception $exception ) {
|
@@ -92,7 +101,7 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
92 |
return false;
|
93 |
}
|
94 |
|
95 |
-
//
|
96 |
$item['processed_events_count'] += $items_migrated;
|
97 |
self::store_migration_info( $item );
|
98 |
|
@@ -100,13 +109,15 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
100 |
}
|
101 |
|
102 |
/**
|
103 |
-
*
|
104 |
-
*
|
|
|
|
|
105 |
*
|
106 |
* @return int
|
107 |
*/
|
108 |
private function process_next_batch( $connection, $batch_size ) {
|
109 |
-
$plugin = WpSecurityAuditLog::
|
110 |
if ( 'local' !== $connection && ! is_null( $plugin->external_db_util ) ) {
|
111 |
$connection = $plugin->external_db_util->get_connection( $connection );
|
112 |
if ( false === $connection ) {
|
@@ -114,37 +125,37 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
114 |
}
|
115 |
}
|
116 |
|
117 |
-
$connector = $plugin->
|
118 |
/** @var WSAL_Adapters_MySQL_Occurrence $occurrence_adapter */
|
119 |
-
$occurrence_adapter = $connector->
|
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
|
124 |
$lowercase_migrated_meta_keys = array_map( 'strtolower', $migrated_meta_keys );
|
125 |
foreach ( $occurrences_to_migrate as $occurrence ) {
|
126 |
-
$all_metadata = $occurrence_adapter->
|
127 |
if ( ! empty( $all_metadata ) ) {
|
128 |
foreach ( $all_metadata as $meta_model ) {
|
129 |
-
$meta_key
|
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
|
135 |
-
//
|
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->
|
141 |
}
|
142 |
|
143 |
-
$meta_model->
|
144 |
}
|
145 |
}
|
146 |
|
147 |
-
$occurrence->
|
148 |
}
|
149 |
}
|
150 |
}
|
@@ -158,38 +169,40 @@ class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
|
158 |
* @param string $connection_name Connection name.
|
159 |
*/
|
160 |
public static function remove_migration_info( $connection_name ) {
|
161 |
-
$plugin = WpSecurityAuditLog::
|
162 |
-
$existing_info = $plugin->
|
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->
|
170 |
} else {
|
171 |
-
$plugin->
|
172 |
}
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
-
*
|
|
|
|
|
177 |
*/
|
178 |
private function handle_error( $exception ) {
|
179 |
-
//
|
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::
|
189 |
-
$existing_info = $plugin->
|
190 |
$connection_name = $info['connection'];
|
191 |
|
192 |
$existing_info[ $connection_name ] = $info;
|
193 |
-
$plugin->
|
194 |
}
|
195 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Metadata migration class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage upgrade
|
7 |
+
* @since 4.4.0
|
8 |
+
*/
|
9 |
|
10 |
// Exit if accessed directly.
|
11 |
if ( ! defined( 'ABSPATH' ) ) {
|
19 |
* It handles metadata migration for 1 connection defined as part of the process information. This can be either "local"
|
20 |
* to work with the local WP database or a name of connection defined by the Integrations extension.
|
21 |
*
|
22 |
+
* @package wsal
|
23 |
* @subpackage upgrade
|
24 |
+
* @since 4.4.0
|
25 |
*/
|
26 |
class WSAL_Upgrade_MetadataMigration extends WSAL_Vendor\WP_Background_Process {
|
27 |
|
35 |
const OPTION_NAME_MIGRATION_INFO = 'meta_data_migration_info_440';
|
36 |
|
37 |
/**
|
38 |
+
* Action
|
39 |
+
*
|
40 |
+
* @var string
|
41 |
*/
|
42 |
protected $action = 'wsal_meta_data_migration_440';
|
43 |
|
62 |
return;
|
63 |
}
|
64 |
|
65 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
66 |
+
$existing_info = $plugin->get_global_setting( self::OPTION_NAME_MIGRATION_INFO, array() );
|
67 |
if ( empty( $existing_info ) ) {
|
68 |
return;
|
69 |
}
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
+
* {@inheritDoc}
|
85 |
*
|
86 |
+
* @param array{start_time: int, processed_events_count: int, batch_size: int, connection: string} $item Migration process item.
|
87 |
*/
|
88 |
protected function task( $item ) {
|
89 |
+
// Migrate metadata for the next batch of events.
|
90 |
$items_migrated = $this->process_next_batch( $item['connection'], $item['batch_size'] );
|
91 |
if ( 0 === $items_migrated ) {
|
92 |
+
// All metadata has been migrated.
|
93 |
try {
|
94 |
+
// Delete the migration job info to indicate that the migration is done.
|
95 |
self::remove_migration_info( $item['connection'] );
|
96 |
|
97 |
} catch ( Exception $exception ) {
|
101 |
return false;
|
102 |
}
|
103 |
|
104 |
+
// Update and save the migration info.
|
105 |
$item['processed_events_count'] += $items_migrated;
|
106 |
self::store_migration_info( $item );
|
107 |
|
109 |
}
|
110 |
|
111 |
/**
|
112 |
+
* Processes next batch of events that need to be migrated.
|
113 |
+
*
|
114 |
+
* @param string $connection Connection name.
|
115 |
+
* @param int $batch_size Batch size.
|
116 |
*
|
117 |
* @return int
|
118 |
*/
|
119 |
private function process_next_batch( $connection, $batch_size ) {
|
120 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
121 |
if ( 'local' !== $connection && ! is_null( $plugin->external_db_util ) ) {
|
122 |
$connection = $plugin->external_db_util->get_connection( $connection );
|
123 |
if ( false === $connection ) {
|
125 |
}
|
126 |
}
|
127 |
|
128 |
+
$connector = $plugin->get_connector( $connection );
|
129 |
/** @var WSAL_Adapters_MySQL_Occurrence $occurrence_adapter */
|
130 |
+
$occurrence_adapter = $connector->get_adapter( 'Occurrence' );
|
131 |
|
132 |
$occurrences_to_migrate = $occurrence_adapter->get_all_with_meta_to_migrate( $batch_size );
|
133 |
if ( ! empty( $occurrences_to_migrate ) ) {
|
134 |
+
$migrated_meta_keys = array_keys( WSAL_Models_Occurrence::$migrated_meta );
|
135 |
$lowercase_migrated_meta_keys = array_map( 'strtolower', $migrated_meta_keys );
|
136 |
foreach ( $occurrences_to_migrate as $occurrence ) {
|
137 |
+
$all_metadata = $occurrence_adapter->get_multi_meta( $occurrence );
|
138 |
if ( ! empty( $all_metadata ) ) {
|
139 |
foreach ( $all_metadata as $meta_model ) {
|
140 |
+
$meta_key = $meta_model->name;
|
141 |
+
$lowercase_meta_key = strtolower( $meta_key );
|
142 |
|
143 |
// We use lowercase meta keys to make sure we handle even legacy meta keys correctly, for
|
144 |
// example "username" was changed to "Username" at some point.
|
145 |
+
if ( in_array( $lowercase_meta_key, $lowercase_migrated_meta_keys ) ) { // phpcs:ignore
|
146 |
+
// This will store the meta in the occ table if it belongs there.
|
147 |
$is_empty_string = is_string( $meta_model->value ) && 0 === strlen( $meta_model->value );
|
148 |
+
if ( ! $is_empty_string && in_array( $meta_key, $migrated_meta_keys, true ) ) {
|
149 |
// The meta is set in the occurrence object on if it is an exact match, otherwise we
|
150 |
// would end up writing and deleting the same meta key endlessly.
|
151 |
+
$occurrence->set_meta_value( $meta_key, $meta_model->value );
|
152 |
}
|
153 |
|
154 |
+
$meta_model->delete();
|
155 |
}
|
156 |
}
|
157 |
|
158 |
+
$occurrence->save();
|
159 |
}
|
160 |
}
|
161 |
}
|
169 |
* @param string $connection_name Connection name.
|
170 |
*/
|
171 |
public static function remove_migration_info( $connection_name ) {
|
172 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
173 |
+
$existing_info = $plugin->get_global_setting( self::OPTION_NAME_MIGRATION_INFO, array() );
|
174 |
|
175 |
if ( array_key_exists( $connection_name, $existing_info ) ) {
|
176 |
unset( $existing_info[ $connection_name ] );
|
177 |
}
|
178 |
|
179 |
if ( empty( $existing_info ) ) {
|
180 |
+
$plugin->delete_global_setting( self::OPTION_NAME_MIGRATION_INFO );
|
181 |
} else {
|
182 |
+
$plugin->set_global_setting( self::OPTION_NAME_MIGRATION_INFO, $existing_info );
|
183 |
}
|
184 |
}
|
185 |
|
186 |
/**
|
187 |
+
* Handles an error.
|
188 |
+
*
|
189 |
+
* @param Exception $exception Error to handle.
|
190 |
*/
|
191 |
private function handle_error( $exception ) {
|
192 |
+
// @todo handle migration error
|
193 |
}
|
194 |
|
195 |
/**
|
196 |
* Stores or updates migration info for one particular connection.
|
197 |
*
|
198 |
+
* @param array{start_time: int, processed_events_count: int, batch_size: int, connection: string} $info Migration info data.
|
199 |
*/
|
200 |
public static function store_migration_info( $info ) {
|
201 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
202 |
+
$existing_info = $plugin->get_global_setting( self::OPTION_NAME_MIGRATION_INFO, array() );
|
203 |
$connection_name = $info['connection'];
|
204 |
|
205 |
$existing_info[ $connection_name ] = $info;
|
206 |
+
$plugin->set_global_setting( self::OPTION_NAME_MIGRATION_INFO, $existing_info );
|
207 |
}
|
208 |
+
}
|
classes/Upgrade/Upgrade_43000_to_44400.php
CHANGED
@@ -1,4 +1,17 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Class handles upgrade changes from version 43000 to 44400.
|
@@ -8,7 +21,7 @@
|
|
8 |
*
|
9 |
* @since 4.4.0
|
10 |
*/
|
11 |
-
class
|
12 |
|
13 |
/**
|
14 |
* Plugin instance.
|
@@ -31,6 +44,24 @@ class WSAL_Upgrade_43000_to_44400 {
|
|
31 |
*/
|
32 |
public function run() {
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
// Remove some forgotten WFCM settings from the options table.
|
35 |
$this->remove_wfcm_leftover_settings();
|
36 |
|
@@ -60,7 +91,7 @@ class WSAL_Upgrade_43000_to_44400 {
|
|
60 |
'wsal_scanned_dirs',
|
61 |
);
|
62 |
foreach ( $not_found_page_related_settings as $setting_name ) {
|
63 |
-
$this->plugin->
|
64 |
}
|
65 |
}
|
66 |
|
@@ -74,20 +105,20 @@ class WSAL_Upgrade_43000_to_44400 {
|
|
74 |
* @throws Freemius_Exception Freemius exception.
|
75 |
*/
|
76 |
private function upgrade_occurrence_table( $connection ) {
|
77 |
-
$connector = $this->plugin->
|
78 |
/** @var WSAL_Adapters_MySQL_Occurrence $occurrence_adapter */
|
79 |
-
$occurrence_adapter = $connector->
|
80 |
|
81 |
// Skip the upgrade it the table does not exist for some reason.
|
82 |
-
if ( ! $connector->
|
83 |
return;
|
84 |
}
|
85 |
|
86 |
-
$table_name = $occurrence_adapter->
|
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->
|
91 |
// Create a background job to migrate the metadata.
|
92 |
$job_info = array(
|
93 |
'start_time' => current_time( 'timestamp' ), // phpcs:ignore
|
@@ -116,20 +147,20 @@ class WSAL_Upgrade_43000_to_44400 {
|
|
116 |
*/
|
117 |
private function get_occurrence_table_upgrade_query( $table_name ) {
|
118 |
return "ALTER TABLE {$table_name}"
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
}
|
134 |
|
135 |
|
@@ -166,7 +197,7 @@ class WSAL_Upgrade_43000_to_44400 {
|
|
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->
|
170 |
}
|
171 |
}
|
172 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Class WSAL_Upgrade_43000_to_44400.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @subpackage upgrade
|
7 |
+
*
|
8 |
+
* @since 4.4.0
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
|
16 |
/**
|
17 |
* Class handles upgrade changes from version 43000 to 44400.
|
21 |
*
|
22 |
* @since 4.4.0
|
23 |
*/
|
24 |
+
class WSAL_Upgrade_43000_To_44400 {
|
25 |
|
26 |
/**
|
27 |
* Plugin instance.
|
44 |
*/
|
45 |
public function run() {
|
46 |
|
47 |
+
// Delete unwanted usermeta.
|
48 |
+
global $wpdb;
|
49 |
+
$wpdb->query( // phpcs:ignore
|
50 |
+
$wpdb->prepare(
|
51 |
+
"DELETE FROM {$wpdb->usermeta} WHERE meta_key = '%s';", // phpcs:ignore
|
52 |
+
'wsal-notice-update-44-notice'
|
53 |
+
)
|
54 |
+
);
|
55 |
+
|
56 |
+
if ( class_exists( 'WSAL_Extension_Manager' ) ) {
|
57 |
+
WSAL_Extension_Manager::include_extension( 'external-db' );
|
58 |
+
}
|
59 |
+
|
60 |
+
if ( ! did_action( 'wsal_init' ) ) {
|
61 |
+
// We need to call wsal init manually because it does not run as before the upgrade procedure is triggered.
|
62 |
+
do_action( 'wsal_init', $this->plugin );
|
63 |
+
}
|
64 |
+
|
65 |
// Remove some forgotten WFCM settings from the options table.
|
66 |
$this->remove_wfcm_leftover_settings();
|
67 |
|
91 |
'wsal_scanned_dirs',
|
92 |
);
|
93 |
foreach ( $not_found_page_related_settings as $setting_name ) {
|
94 |
+
$this->plugin->delete_global_setting( $setting_name );
|
95 |
}
|
96 |
}
|
97 |
|
105 |
* @throws Freemius_Exception Freemius exception.
|
106 |
*/
|
107 |
private function upgrade_occurrence_table( $connection ) {
|
108 |
+
$connector = $this->plugin->get_connector( $connection );
|
109 |
/** @var WSAL_Adapters_MySQL_Occurrence $occurrence_adapter */
|
110 |
+
$occurrence_adapter = $connector->get_adapter( 'Occurrence' );
|
111 |
|
112 |
// Skip the upgrade it the table does not exist for some reason.
|
113 |
+
if ( ! $connector->is_installed() ) {
|
114 |
return;
|
115 |
}
|
116 |
|
117 |
+
$table_name = $occurrence_adapter->get_table();
|
118 |
$connector->query( $this->get_occurrence_table_upgrade_query( $table_name ) );
|
119 |
|
120 |
// Check if there are any events to process.
|
121 |
+
if ( $occurrence_adapter->count() > 0 ) {
|
122 |
// Create a background job to migrate the metadata.
|
123 |
$job_info = array(
|
124 |
'start_time' => current_time( 'timestamp' ), // phpcs:ignore
|
147 |
*/
|
148 |
private function get_occurrence_table_upgrade_query( $table_name ) {
|
149 |
return "ALTER TABLE {$table_name}"
|
150 |
+
. ' DROP COLUMN is_read, '
|
151 |
+
. ' DROP COLUMN is_migrated, '
|
152 |
+
. " ADD client_ip VARCHAR(255) NOT NULL DEFAULT '',"
|
153 |
+
. ' ADD severity BIGINT NOT NULL DEFAULT 0,'
|
154 |
+
. " ADD object VARCHAR(255) NOT NULL DEFAULT '',"
|
155 |
+
. " ADD event_type VARCHAR(255) NOT NULL DEFAULT '',"
|
156 |
+
. " ADD user_agent VARCHAR(255) NOT NULL DEFAULT '',"
|
157 |
+
. " ADD user_roles VARCHAR(255) NOT NULL DEFAULT '',"
|
158 |
+
. ' ADD username VARCHAR(255) NULL,'
|
159 |
+
. ' ADD user_id BIGINT NULL ,'
|
160 |
+
. " ADD session_id VARCHAR(255) NOT NULL DEFAULT '',"
|
161 |
+
. " ADD post_status VARCHAR(255) NOT NULL DEFAULT '',"
|
162 |
+
. " ADD post_type VARCHAR(255) NOT NULL DEFAULT '',"
|
163 |
+
. ' ADD post_id BIGINT NOT NULL DEFAULT 0;';
|
164 |
}
|
165 |
|
166 |
|
197 |
foreach ( $plugin_options as $option ) {
|
198 |
if ( ! in_array( $option['option_name'], $settings_to_leave_on_autoload ) ) { // phpcs:ignore
|
199 |
$value = maybe_unserialize( $option['option_value'] );
|
200 |
+
$this->plugin->set_global_setting( $option['option_name'], $value, false );
|
201 |
}
|
202 |
}
|
203 |
}
|
classes/Utilities/DateTimeFormatter.php
CHANGED
@@ -23,7 +23,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
23 |
class WSAL_Utilities_DateTimeFormatter {
|
24 |
|
25 |
/**
|
26 |
-
*
|
|
|
|
|
27 |
*/
|
28 |
private static $am_pm_lookup_pattern = '/\.\d+((\ |\ )([AP]M))?/i';
|
29 |
|
@@ -34,14 +36,39 @@ class WSAL_Utilities_DateTimeFormatter {
|
|
34 |
*/
|
35 |
private $gmt_offset_sec = 0;
|
36 |
|
|
|
|
|
|
|
|
|
|
|
37 |
private $date_format;
|
38 |
|
|
|
|
|
|
|
|
|
|
|
39 |
private $time_format;
|
40 |
|
|
|
|
|
|
|
|
|
|
|
41 |
private $datetime_format;
|
42 |
|
|
|
|
|
|
|
|
|
|
|
43 |
private $datetime_format_no_linebreaks;
|
44 |
|
|
|
|
|
|
|
|
|
|
|
45 |
private $show_milliseconds;
|
46 |
|
47 |
/**
|
@@ -55,12 +82,12 @@ class WSAL_Utilities_DateTimeFormatter {
|
|
55 |
*/
|
56 |
public static function instance() {
|
57 |
static $instance = false;
|
58 |
-
if (
|
59 |
-
// Late static binding (PHP 5.3+)
|
60 |
$instance = new static();
|
61 |
|
62 |
-
$plugin = WpSecurityAuditLog::
|
63 |
-
$timezone = $plugin->settings()->
|
64 |
|
65 |
/**
|
66 |
* Transform timezone values.
|
@@ -74,16 +101,16 @@ class WSAL_Utilities_DateTimeFormatter {
|
|
74 |
}
|
75 |
|
76 |
if ( 'utc' === $timezone ) {
|
77 |
-
$instance->gmt_offset_sec = date( 'Z' );
|
78 |
} else {
|
79 |
$instance->gmt_offset_sec = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
|
80 |
}
|
81 |
|
82 |
$instance->show_milliseconds = $plugin->settings()->get_show_milliseconds();
|
83 |
-
$instance->date_format = $plugin->settings()->
|
84 |
-
$instance->time_format = $plugin->settings()->
|
85 |
-
$instance->datetime_format = $plugin->settings()->
|
86 |
-
$instance->datetime_format_no_linebreaks = $plugin->settings()->
|
87 |
|
88 |
}
|
89 |
|
@@ -93,16 +120,28 @@ class WSAL_Utilities_DateTimeFormatter {
|
|
93 |
/**
|
94 |
* Remove milliseconds from formatted datetime string.
|
95 |
*
|
96 |
-
* @param string $
|
97 |
*
|
98 |
* @return string
|
99 |
* @since 4.2.0
|
100 |
*/
|
101 |
-
public static function
|
102 |
-
return preg_replace( self::$am_pm_lookup_pattern, ' $3', $
|
103 |
}
|
104 |
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
$result = '';
|
107 |
$format = null;
|
108 |
switch ( $type ) {
|
@@ -126,19 +165,19 @@ class WSAL_Utilities_DateTimeFormatter {
|
|
126 |
return $result;
|
127 |
}
|
128 |
|
129 |
-
//
|
130 |
$timezone_adjusted_timestamp = $do_timezone_offset ? $timestamp + $this->gmt_offset_sec : $timestamp;
|
131 |
|
132 |
-
//
|
133 |
if ( ! $this->show_milliseconds ) {
|
134 |
-
//
|
135 |
$format = str_replace( '.$$$', '', $format );
|
136 |
}
|
137 |
|
138 |
-
//
|
139 |
-
$result = $translated ? date_i18n( $format, $timezone_adjusted_timestamp ) : date( $format, $timezone_adjusted_timestamp );
|
140 |
|
141 |
-
//
|
142 |
if ( $this->show_milliseconds ) {
|
143 |
$result = str_replace(
|
144 |
'$$$',
|
@@ -148,6 +187,5 @@ class WSAL_Utilities_DateTimeFormatter {
|
|
148 |
}
|
149 |
|
150 |
return $result;
|
151 |
-
|
152 |
}
|
153 |
}
|
23 |
class WSAL_Utilities_DateTimeFormatter {
|
24 |
|
25 |
/**
|
26 |
+
* Regular expression for matching the milliseconds part of datetime string.
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
*/
|
30 |
private static $am_pm_lookup_pattern = '/\.\d+((\ |\ )([AP]M))?/i';
|
31 |
|
36 |
*/
|
37 |
private $gmt_offset_sec = 0;
|
38 |
|
39 |
+
/**
|
40 |
+
* Date format.
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
private $date_format;
|
45 |
|
46 |
+
/**
|
47 |
+
* Time format.
|
48 |
+
*
|
49 |
+
* @var string
|
50 |
+
*/
|
51 |
private $time_format;
|
52 |
|
53 |
+
/**
|
54 |
+
* Datetime format.
|
55 |
+
*
|
56 |
+
* @var string
|
57 |
+
*/
|
58 |
private $datetime_format;
|
59 |
|
60 |
+
/**
|
61 |
+
* Datetime format without linebreaks.
|
62 |
+
*
|
63 |
+
* @var string
|
64 |
+
*/
|
65 |
private $datetime_format_no_linebreaks;
|
66 |
|
67 |
+
/**
|
68 |
+
* If true, show milliseconds.
|
69 |
+
*
|
70 |
+
* @var bool
|
71 |
+
*/
|
72 |
private $show_milliseconds;
|
73 |
|
74 |
/**
|
82 |
*/
|
83 |
public static function instance() {
|
84 |
static $instance = false;
|
85 |
+
if ( false === $instance ) {
|
86 |
+
// Late static binding (PHP 5.3+).
|
87 |
$instance = new static();
|
88 |
|
89 |
+
$plugin = WpSecurityAuditLog::get_instance();
|
90 |
+
$timezone = $plugin->settings()->get_timezone();
|
91 |
|
92 |
/**
|
93 |
* Transform timezone values.
|
101 |
}
|
102 |
|
103 |
if ( 'utc' === $timezone ) {
|
104 |
+
$instance->gmt_offset_sec = date( 'Z' ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
105 |
} else {
|
106 |
$instance->gmt_offset_sec = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
|
107 |
}
|
108 |
|
109 |
$instance->show_milliseconds = $plugin->settings()->get_show_milliseconds();
|
110 |
+
$instance->date_format = $plugin->settings()->get_date_format();
|
111 |
+
$instance->time_format = $plugin->settings()->get_time_format();
|
112 |
+
$instance->datetime_format = $plugin->settings()->get_datetime_format();
|
113 |
+
$instance->datetime_format_no_linebreaks = $plugin->settings()->get_datetime_format( false );
|
114 |
|
115 |
}
|
116 |
|
120 |
/**
|
121 |
* Remove milliseconds from formatted datetime string.
|
122 |
*
|
123 |
+
* @param string $formatted_datetime Formatted datetime string.
|
124 |
*
|
125 |
* @return string
|
126 |
* @since 4.2.0
|
127 |
*/
|
128 |
+
public static function remove_milliseconds( $formatted_datetime ) {
|
129 |
+
return preg_replace( self::$am_pm_lookup_pattern, ' $3', $formatted_datetime );
|
130 |
}
|
131 |
|
132 |
+
/**
|
133 |
+
* Formats date time based on various requirements.
|
134 |
+
*
|
135 |
+
* @param float $timestamp Timestamp.
|
136 |
+
* @param string $type Output type.
|
137 |
+
* @param bool $do_timezone_offset If true, timezone offset is applied to the timestamp.
|
138 |
+
* @param bool $line_break If true, line-break characters are included.
|
139 |
+
* @param bool $use_nb_space_for_am_pm If true, non-breakable space is included before AM/PM part.
|
140 |
+
* @param bool $translated If true, the result is translated.
|
141 |
+
*
|
142 |
+
* @return string
|
143 |
+
*/
|
144 |
+
public function get_formatted_date_time( $timestamp, $type = 'datetime', $do_timezone_offset = true, $line_break = false, $use_nb_space_for_am_pm = true, $translated = true ) {
|
145 |
$result = '';
|
146 |
$format = null;
|
147 |
switch ( $type ) {
|
165 |
return $result;
|
166 |
}
|
167 |
|
168 |
+
// Timezone adjustment.
|
169 |
$timezone_adjusted_timestamp = $do_timezone_offset ? $timestamp + $this->gmt_offset_sec : $timestamp;
|
170 |
|
171 |
+
// Milliseconds in format (this is probably not necessary, but we keep it just to be 100% sure).
|
172 |
if ( ! $this->show_milliseconds ) {
|
173 |
+
// Remove the milliseconds placeholder from format string.
|
174 |
$format = str_replace( '.$$$', '', $format );
|
175 |
}
|
176 |
|
177 |
+
// Date formatting.
|
178 |
+
$result = $translated ? date_i18n( $format, $timezone_adjusted_timestamp ) : date( $format, $timezone_adjusted_timestamp ); // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
179 |
|
180 |
+
// Milliseconds value.
|
181 |
if ( $this->show_milliseconds ) {
|
182 |
$result = str_replace(
|
183 |
'$$$',
|
187 |
}
|
188 |
|
189 |
return $result;
|
|
|
190 |
}
|
191 |
}
|
classes/Utilities/Emailer.php
CHANGED
@@ -25,17 +25,17 @@ class WSAL_Utilities_Emailer {
|
|
25 |
*/
|
26 |
public static function send_deactivation_email() {
|
27 |
// Get the required variables.
|
28 |
-
$wsal = WpSecurityAuditLog::
|
29 |
$home_url = home_url();
|
30 |
$safe_url = str_replace( array( 'http://', 'https://' ), '', $home_url );
|
31 |
$type_name = $wsal->settings()->get_type_username(); // Get the data to display.
|
32 |
$user = _wp_get_current_user();
|
33 |
-
$datetime_format = $wsal->settings()->
|
34 |
-
$now
|
35 |
$date_time = str_replace(
|
36 |
'$$$',
|
37 |
substr( number_format( fmod( $now, 1 ), 3 ), 2 ),
|
38 |
-
date( $datetime_format, $now )
|
39 |
);
|
40 |
|
41 |
// Checks for display name.
|
@@ -83,6 +83,9 @@ class WSAL_Utilities_Emailer {
|
|
83 |
* @param string $email_address - Email Address.
|
84 |
* @param string $subject - Email subject.
|
85 |
* @param string $content - Email content.
|
|
|
|
|
|
|
86 |
* @return bool
|
87 |
*/
|
88 |
public static function send_email( $email_address, $subject, $content, $headers = '', $attachments = array() ) {
|
@@ -151,9 +154,9 @@ class WSAL_Utilities_Emailer {
|
|
151 |
* @return string
|
152 |
*/
|
153 |
public static function custom_wp_mail_from( $original_email_from ) {
|
154 |
-
$wsal = WpSecurityAuditLog::
|
155 |
$use_email = $wsal->settings()->get_use_email();
|
156 |
-
$email_from = $wsal->settings()->
|
157 |
if ( ! empty( $email_from ) && 'custom_email' === $use_email ) {
|
158 |
return $email_from;
|
159 |
} else {
|
@@ -168,9 +171,9 @@ class WSAL_Utilities_Emailer {
|
|
168 |
* @return string
|
169 |
*/
|
170 |
public static function custom_wp_mail_from_name( $original_email_from_name ) {
|
171 |
-
$wsal = WpSecurityAuditLog::
|
172 |
$use_email = $wsal->settings()->get_use_email();
|
173 |
-
$email_from_name = $wsal->settings()->
|
174 |
if ( ! empty( $email_from_name ) && 'custom_email' === $use_email ) {
|
175 |
return $email_from_name;
|
176 |
} else {
|
25 |
*/
|
26 |
public static function send_deactivation_email() {
|
27 |
// Get the required variables.
|
28 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
29 |
$home_url = home_url();
|
30 |
$safe_url = str_replace( array( 'http://', 'https://' ), '', $home_url );
|
31 |
$type_name = $wsal->settings()->get_type_username(); // Get the data to display.
|
32 |
$user = _wp_get_current_user();
|
33 |
+
$datetime_format = $wsal->settings()->get_datetime_format( false );
|
34 |
+
$now = current_time( 'timestamp' ); // phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested
|
35 |
$date_time = str_replace(
|
36 |
'$$$',
|
37 |
substr( number_format( fmod( $now, 1 ), 3 ), 2 ),
|
38 |
+
date( $datetime_format, $now ) // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
|
39 |
);
|
40 |
|
41 |
// Checks for display name.
|
83 |
* @param string $email_address - Email Address.
|
84 |
* @param string $subject - Email subject.
|
85 |
* @param string $content - Email content.
|
86 |
+
* @param string $headers Email headers.
|
87 |
+
* @param array $attachments Email attachments.
|
88 |
+
*
|
89 |
* @return bool
|
90 |
*/
|
91 |
public static function send_email( $email_address, $subject, $content, $headers = '', $attachments = array() ) {
|
154 |
* @return string
|
155 |
*/
|
156 |
public static function custom_wp_mail_from( $original_email_from ) {
|
157 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
158 |
$use_email = $wsal->settings()->get_use_email();
|
159 |
+
$email_from = $wsal->settings()->get_from_email();
|
160 |
if ( ! empty( $email_from ) && 'custom_email' === $use_email ) {
|
161 |
return $email_from;
|
162 |
} else {
|
171 |
* @return string
|
172 |
*/
|
173 |
public static function custom_wp_mail_from_name( $original_email_from_name ) {
|
174 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
175 |
$use_email = $wsal->settings()->get_use_email();
|
176 |
+
$email_from_name = $wsal->settings()->get_display_name();
|
177 |
if ( ! empty( $email_from_name ) && 'custom_email' === $use_email ) {
|
178 |
return $email_from_name;
|
179 |
} else {
|
classes/Utilities/FileSystemUtils.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Utility class for handling certain file system related functionality.
|
@@ -32,7 +38,7 @@ class WSAL_Utilities_FileSystemUtils {
|
|
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 |
}
|
@@ -44,4 +50,4 @@ class WSAL_Utilities_FileSystemUtils {
|
|
44 |
|
45 |
return $result;
|
46 |
}
|
47 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* File system utility class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @since 4.4.0
|
7 |
+
*/
|
8 |
|
9 |
/**
|
10 |
* Utility class for handling certain file system related functionality.
|
38 |
if ( $handle ) {
|
39 |
$ignore_list = array( '.', '..' );
|
40 |
$regexp = '/' . str_replace( array( '.', '*' ), array( '\.', '.*' ), $pattern ) . '/';
|
41 |
+
while ( false !== ( $file_name = readdir( $handle ) ) ) { // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
|
42 |
if ( ! in_array( $file_name, $ignore_list, true ) && preg_match( $regexp, $file_name ) ) {
|
43 |
array_push( $result, $folder_slashed . $file_name );
|
44 |
}
|
50 |
|
51 |
return $result;
|
52 |
}
|
53 |
+
}
|
classes/Utilities/PluginInstallAndActivate.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Handler to install activate plugins.
|
4 |
*
|
5 |
* Provides the allowed plugins data as well as a render method to display the
|
6 |
-
* items inside of a table with install/
|
7 |
*
|
8 |
* @package wsal
|
9 |
* @since 4.0.1
|
@@ -42,7 +42,7 @@ if ( ! class_exists( 'WSAL_PluginInstallAndActivate' ) ) {
|
|
42 |
if ( true === $is_allowed_slug ) {
|
43 |
break;
|
44 |
}
|
45 |
-
$is_allowed_slug =
|
46 |
}
|
47 |
}
|
48 |
|
@@ -99,12 +99,12 @@ if ( ! class_exists( 'WSAL_PluginInstallAndActivate' ) ) {
|
|
99 |
<div class="addon-wrapper">
|
100 |
<img src="<?php echo esc_url( trailingslashit( WSAL_BASE_URL ) . 'img/addons/' . $details['image_filename'] ); ?>">
|
101 |
<h4><?php esc_html_e( 'Extension for ', 'wp-security-audit-log' ); ?><?php echo esc_html( $details['title'] ); ?></h4>
|
102 |
-
<p><?php echo sanitize_text_field( $details['plugin_description'] ); ?></p><br>
|
103 |
<p><button class="install-addon button button-primary <?php echo esc_attr( $disable_button ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>" data-plugin-slug="<?php echo esc_attr( $details['plugin_slug'] ); ?>" data-plugin-download-url="<?php echo esc_url( $details['plugin_url'] ); ?>" data-plugin-event-tab-id="<?php echo esc_attr( $details['event_tab_id'] ); ?>">
|
104 |
<?php
|
105 |
if ( $this->is_plugin_installed( $details['plugin_slug'] ) && ! WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) ) {
|
106 |
esc_html_e( 'Extension installed, activate now?', 'wp-security-audit-log' );
|
107 |
-
} elseif ( $this->is_plugin_installed( $details['plugin_slug'] ) && WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) || 'wsal-wpforms.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_wpforms_add_custom_event_objects' ) || 'wsal-bbpress.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_bbpress_add_custom_event_objects' ) || 'activity-log-yoast-seo.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_yoast_seo_extension_add_custom_event_objects' )
|
108 |
esc_html_e( 'Extension installed', 'wp-security-audit-log' );
|
109 |
} else {
|
110 |
esc_html_e( 'Install Extension', 'wp-security-audit-log' );
|
@@ -112,7 +112,6 @@ if ( ! class_exists( 'WSAL_PluginInstallAndActivate' ) ) {
|
|
112 |
?>
|
113 |
</button><span class="spinner" style="display: none; visibility: visible; float: none; margin: 0 0 0 8px;"></span></p>
|
114 |
</div>
|
115 |
-
|
116 |
<?php
|
117 |
}
|
118 |
?>
|
3 |
* Handler to install activate plugins.
|
4 |
*
|
5 |
* Provides the allowed plugins data as well as a render method to display the
|
6 |
+
* items inside of a table with install/activate buttons.
|
7 |
*
|
8 |
* @package wsal
|
9 |
* @since 4.0.1
|
42 |
if ( true === $is_allowed_slug ) {
|
43 |
break;
|
44 |
}
|
45 |
+
$is_allowed_slug = isset( $allowed_plugin['plugin_slug'] ) && $allowed_plugin['plugin_slug'] === $plugin_slug;
|
46 |
}
|
47 |
}
|
48 |
|
99 |
<div class="addon-wrapper">
|
100 |
<img src="<?php echo esc_url( trailingslashit( WSAL_BASE_URL ) . 'img/addons/' . $details['image_filename'] ); ?>">
|
101 |
<h4><?php esc_html_e( 'Extension for ', 'wp-security-audit-log' ); ?><?php echo esc_html( $details['title'] ); ?></h4>
|
102 |
+
<p><?php echo sanitize_text_field( $details['plugin_description'] ); // phpcs:ignore ?></p><br>
|
103 |
<p><button class="install-addon button button-primary <?php echo esc_attr( $disable_button ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>" data-plugin-slug="<?php echo esc_attr( $details['plugin_slug'] ); ?>" data-plugin-download-url="<?php echo esc_url( $details['plugin_url'] ); ?>" data-plugin-event-tab-id="<?php echo esc_attr( $details['event_tab_id'] ); ?>">
|
104 |
<?php
|
105 |
if ( $this->is_plugin_installed( $details['plugin_slug'] ) && ! WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) ) {
|
106 |
esc_html_e( 'Extension installed, activate now?', 'wp-security-audit-log' );
|
107 |
+
} elseif ( $this->is_plugin_installed( $details['plugin_slug'] ) && WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) || 'wsal-wpforms.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_wpforms_add_custom_event_objects' ) || 'wsal-bbpress.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_bbpress_add_custom_event_objects' ) || 'activity-log-yoast-seo.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_yoast_seo_extension_add_custom_event_objects' ) ) {
|
108 |
esc_html_e( 'Extension installed', 'wp-security-audit-log' );
|
109 |
} else {
|
110 |
esc_html_e( 'Install Extension', 'wp-security-audit-log' );
|
112 |
?>
|
113 |
</button><span class="spinner" style="display: none; visibility: visible; float: none; margin: 0 0 0 8px;"></span></p>
|
114 |
</div>
|
|
|
115 |
<?php
|
116 |
}
|
117 |
?>
|
classes/Utilities/PluginInstallerAction.php
CHANGED
@@ -64,7 +64,7 @@ if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
|
64 |
}
|
65 |
|
66 |
// validate that the plugin is in the allowed list, or it is our helper plugin with external libraries.
|
67 |
-
$valid
|
68 |
$helper_plugin_installation = 'wsal-external-libraries/wsal-external-libraries.php' === $plugin_slug;
|
69 |
if ( $helper_plugin_installation ) {
|
70 |
$valid = true;
|
@@ -106,9 +106,9 @@ if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
|
106 |
$result = 'success';
|
107 |
}
|
108 |
|
109 |
-
//
|
110 |
if ( $helper_plugin_installation ) {
|
111 |
-
WpSecurityAuditLog::
|
112 |
}
|
113 |
|
114 |
wp_send_json( $result );
|
@@ -226,7 +226,6 @@ if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
|
|
226 |
} else {
|
227 |
return false;
|
228 |
}
|
229 |
-
|
230 |
}
|
231 |
}
|
232 |
}
|
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;
|
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::get_instance()->delete_global_setting( 'show-helper-plugin-needed-nudge' );
|
112 |
}
|
113 |
|
114 |
wp_send_json( $result );
|
226 |
} else {
|
227 |
return false;
|
228 |
}
|
|
|
229 |
}
|
230 |
}
|
231 |
}
|
classes/Utilities/RequestUtils.php
CHANGED
@@ -1,4 +1,15 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
/**
|
4 |
* Utility class for handling request inputs.
|
@@ -7,8 +18,14 @@
|
|
7 |
* @since 4.1.4
|
8 |
*/
|
9 |
class WSAL_Utilities_RequestUtils {
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
public static function get_filtered_request_data() {
|
11 |
-
$result =
|
12 |
|
13 |
$get_data = filter_input_array( INPUT_GET );
|
14 |
if ( is_array( $get_data ) ) {
|
@@ -57,4 +74,4 @@ class WSAL_Utilities_RequestUtils {
|
|
57 |
public static function is_ip_address( $ip_address ) {
|
58 |
return filter_var( $ip_address, FILTER_VALIDATE_IP ) !== false;
|
59 |
}
|
60 |
-
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Utility class for handling request inputs.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @since 4.1.4
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Exit if accessed directly.
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
|
14 |
/**
|
15 |
* Utility class for handling request inputs.
|
18 |
* @since 4.1.4
|
19 |
*/
|
20 |
class WSAL_Utilities_RequestUtils {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Filters request data.
|
24 |
+
*
|
25 |
+
* @return array Filtered request data.
|
26 |
+
*/
|
27 |
public static function get_filtered_request_data() {
|
28 |
+
$result = array();
|
29 |
|
30 |
$get_data = filter_input_array( INPUT_GET );
|
31 |
if ( is_array( $get_data ) ) {
|
74 |
public static function is_ip_address( $ip_address ) {
|
75 |
return filter_var( $ip_address, FILTER_VALIDATE_IP ) !== false;
|
76 |
}
|
77 |
+
}
|
classes/Utilities/UserUtils.php
CHANGED
@@ -1,4 +1,10 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
// Exit if accessed directly.
|
4 |
if ( ! defined( 'ABSPATH' ) ) {
|
@@ -13,10 +19,15 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
13 |
*/
|
14 |
class WSAL_Utilities_UsersUtils {
|
15 |
|
|
|
|
|
|
|
|
|
|
|
16 |
private static $cached_users = array();
|
17 |
|
18 |
/**
|
19 |
-
* Local static cache for the value of setting determining the
|
20 |
*
|
21 |
* @var string
|
22 |
*/
|
@@ -64,7 +75,7 @@ class WSAL_Utilities_UsersUtils {
|
|
64 |
*
|
65 |
* @since 4.3.1 Made the meta attribute mandatory, changed to static and moved from occurrence to alert.
|
66 |
*/
|
67 |
-
public static function
|
68 |
if ( ! is_array( $meta ) ) {
|
69 |
return '';
|
70 |
}
|
@@ -121,7 +132,7 @@ class WSAL_Utilities_UsersUtils {
|
|
121 |
/**
|
122 |
* Retrieves user ID using either the username of user ID.
|
123 |
*
|
124 |
-
* @param int|string $user_login
|
125 |
*
|
126 |
* @return int|null
|
127 |
*/
|
@@ -132,7 +143,7 @@ class WSAL_Utilities_UsersUtils {
|
|
132 |
}
|
133 |
|
134 |
global $wpdb;
|
135 |
-
$user_id = $wpdb->get_var(
|
136 |
$wpdb->prepare(
|
137 |
"SELECT ID FROM $wpdb->users WHERE user_login = %s OR ID = %d;",
|
138 |
$user_login,
|
@@ -163,11 +174,10 @@ class WSAL_Utilities_UsersUtils {
|
|
163 |
return esc_html( ucwords( implode( ', ', $roles ) ) );
|
164 |
}
|
165 |
|
166 |
-
if ( is_string( $roles ) && ''
|
167 |
return esc_html( ucwords( str_replace( array( '"', '[', ']' ), ' ', $roles ) ) );
|
168 |
}
|
169 |
|
170 |
return '<i>' . esc_html__( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
171 |
-
|
172 |
}
|
173 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* User utility class.
|
4 |
+
*
|
5 |
+
* @package wsal
|
6 |
+
* @since 4.3.0
|
7 |
+
*/
|
8 |
|
9 |
// Exit if accessed directly.
|
10 |
if ( ! defined( 'ABSPATH' ) ) {
|
19 |
*/
|
20 |
class WSAL_Utilities_UsersUtils {
|
21 |
|
22 |
+
/**
|
23 |
+
* Local user cache. Keys are usernames and values are user IDs.
|
24 |
+
*
|
25 |
+
* @var array
|
26 |
+
*/
|
27 |
private static $cached_users = array();
|
28 |
|
29 |
/**
|
30 |
+
* Local static cache for the value of setting determining the preferred user data to display as label.
|
31 |
*
|
32 |
* @var string
|
33 |
*/
|
75 |
*
|
76 |
* @since 4.3.1 Made the meta attribute mandatory, changed to static and moved from occurrence to alert.
|
77 |
*/
|
78 |
+
public static function get_username( $meta = null ) {
|
79 |
if ( ! is_array( $meta ) ) {
|
80 |
return '';
|
81 |
}
|
132 |
/**
|
133 |
* Retrieves user ID using either the username of user ID.
|
134 |
*
|
135 |
+
* @param int|string $user_login User login or ID.
|
136 |
*
|
137 |
* @return int|null
|
138 |
*/
|
143 |
}
|
144 |
|
145 |
global $wpdb;
|
146 |
+
$user_id = $wpdb->get_var( // phpcs:ignore
|
147 |
$wpdb->prepare(
|
148 |
"SELECT ID FROM $wpdb->users WHERE user_login = %s OR ID = %d;",
|
149 |
$user_login,
|
174 |
return esc_html( ucwords( implode( ', ', $roles ) ) );
|
175 |
}
|
176 |
|
177 |
+
if ( is_string( $roles ) && '' !== $roles ) {
|
178 |
return esc_html( ucwords( str_replace( array( '"', '[', ']' ), ' ', $roles ) ) );
|
179 |
}
|
180 |
|
181 |
return '<i>' . esc_html__( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
|
|
182 |
}
|
183 |
}
|
classes/ViewManager.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* View manager class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -35,25 +35,24 @@ class WSAL_ViewManager {
|
|
35 |
*
|
36 |
* @var object
|
37 |
*/
|
38 |
-
protected $
|
39 |
|
40 |
/**
|
41 |
* Active view.
|
42 |
*
|
43 |
* @var WSAL_AbstractView|null
|
44 |
*/
|
45 |
-
protected $
|
46 |
|
47 |
/**
|
48 |
* Method: Constructor.
|
49 |
*
|
50 |
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
51 |
*
|
52 |
-
* @throws Freemius_Exception
|
53 |
* @since 1.0.0
|
54 |
*/
|
55 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
56 |
-
$this->
|
57 |
|
58 |
// Skipped views array.
|
59 |
$skip_views = array();
|
@@ -65,8 +64,8 @@ class WSAL_ViewManager {
|
|
65 |
*
|
66 |
* @since 3.2.3
|
67 |
*/
|
68 |
-
if ( file_exists( $this->
|
69 |
-
$skip_views[] = $this->
|
70 |
}
|
71 |
|
72 |
/**
|
@@ -76,7 +75,7 @@ class WSAL_ViewManager {
|
|
76 |
*
|
77 |
* @since 4.0.4
|
78 |
*/
|
79 |
-
$skip_views[] = $this->
|
80 |
|
81 |
/**
|
82 |
* Skipped Views.
|
@@ -89,31 +88,37 @@ class WSAL_ViewManager {
|
|
89 |
$skip_views = apply_filters( 'wsal_skip_views', $skip_views );
|
90 |
|
91 |
// Load views.
|
92 |
-
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->
|
93 |
-
if ( empty( $skip_views ) || ! in_array( $file, $skip_views ) ) {
|
94 |
-
$this->
|
95 |
}
|
96 |
}
|
97 |
|
98 |
-
//
|
99 |
-
add_filter(
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
// Add menus.
|
102 |
-
add_action( 'admin_menu', array( $this, '
|
103 |
-
add_action( 'network_admin_menu', array( $this, '
|
104 |
|
105 |
// Add plugin shortcut links.
|
106 |
-
add_filter( 'plugin_action_links_' . $plugin->
|
107 |
|
108 |
// Render header.
|
109 |
-
add_action( 'admin_enqueue_scripts', array( $this, '
|
110 |
|
111 |
// Render footer.
|
112 |
-
add_action( 'admin_footer', array( $this, '
|
113 |
|
114 |
// Initialize setup wizard.
|
115 |
-
if ( ! $this->
|
116 |
-
|
117 |
) {
|
118 |
new WSAL_Views_SetupWizard( $plugin );
|
119 |
}
|
@@ -135,7 +140,7 @@ class WSAL_ViewManager {
|
|
135 |
if ( defined( 'WFCM_VERSION' ) ) {
|
136 |
if ( version_compare( WFCM_VERSION, '1.6.0', '<' ) ) {
|
137 |
echo '<div class="notice notice-success">
|
138 |
-
<p>' .
|
139 |
</div>';
|
140 |
}
|
141 |
}
|
@@ -147,9 +152,9 @@ class WSAL_ViewManager {
|
|
147 |
*
|
148 |
* @param string $file Path to file.
|
149 |
*/
|
150 |
-
public function
|
151 |
$file = basename( $file, '.php' );
|
152 |
-
$this->
|
153 |
}
|
154 |
|
155 |
/**
|
@@ -157,12 +162,12 @@ class WSAL_ViewManager {
|
|
157 |
*
|
158 |
* @param string $class Class name.
|
159 |
*/
|
160 |
-
public function
|
161 |
-
$view = new $class( $this->
|
162 |
-
//
|
163 |
-
// that did not
|
164 |
if ( is_a( $view, '\WSAL_AbstractView' ) ) {
|
165 |
-
$this->
|
166 |
}
|
167 |
}
|
168 |
|
@@ -171,15 +176,15 @@ class WSAL_ViewManager {
|
|
171 |
*
|
172 |
* @param WSAL_AbstractView $view The new view.
|
173 |
*/
|
174 |
-
public function
|
175 |
$this->views[] = $view;
|
176 |
}
|
177 |
|
178 |
/**
|
179 |
* Order views by their declared weight.
|
180 |
*/
|
181 |
-
public function
|
182 |
-
usort( $this->views, array( $this, '
|
183 |
}
|
184 |
|
185 |
/**
|
@@ -190,9 +195,9 @@ class WSAL_ViewManager {
|
|
190 |
* @param WSAL_AbstractView $b - Second view.
|
191 |
* @return int
|
192 |
*/
|
193 |
-
public function
|
194 |
-
$wa = $a->
|
195 |
-
$wb = $b->
|
196 |
switch ( true ) {
|
197 |
case $wa < $wb:
|
198 |
return -1;
|
@@ -206,55 +211,55 @@ class WSAL_ViewManager {
|
|
206 |
/**
|
207 |
* WordPress Action
|
208 |
*/
|
209 |
-
public function
|
210 |
-
$this->
|
211 |
|
212 |
-
if ( $this->
|
213 |
// Add main menu.
|
214 |
-
|
215 |
$this->views[0]->hook_suffix = add_menu_page(
|
216 |
'WP Activity Log',
|
217 |
'WP Activity Log',
|
218 |
'read', // No capability requirement.
|
219 |
$main_view_menu_slug,
|
220 |
-
array( $this, '
|
221 |
-
$this->views[0]->
|
222 |
'2.5' // Right after dashboard.
|
223 |
);
|
224 |
|
225 |
-
//
|
226 |
$protected_views = array(
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
//
|
237 |
-
$has_current_user_edit_priv = $this->
|
238 |
|
239 |
// Add menu items.
|
240 |
foreach ( $this->views as $view ) {
|
241 |
-
if ( $view->
|
242 |
-
|
243 |
-
if ( $this->
|
244 |
continue;
|
245 |
}
|
246 |
|
247 |
-
if ( in_array( $safe_view_name, $protected_views ) && ! $has_current_user_edit_priv ) {
|
248 |
continue;
|
249 |
}
|
250 |
|
251 |
$view->hook_suffix = add_submenu_page(
|
252 |
-
$view->
|
253 |
-
$view->
|
254 |
-
$view->
|
255 |
'read', // No capability requirement.
|
256 |
$safe_view_name,
|
257 |
-
array( $this, '
|
258 |
);
|
259 |
}
|
260 |
}
|
@@ -266,17 +271,17 @@ class WSAL_ViewManager {
|
|
266 |
*
|
267 |
* @param array $old_links - Array of old links.
|
268 |
*/
|
269 |
-
public function
|
270 |
-
$this->
|
271 |
|
272 |
$new_links = array();
|
273 |
foreach ( $this->views as $view ) {
|
274 |
-
if ( $view->
|
275 |
-
$new_links[] = '<a href="' . add_query_arg( 'page', $view->
|
276 |
|
277 |
if ( 1 === count( $new_links ) && ! wsal_freemius()->is__premium_only() ) {
|
278 |
-
// Trial link
|
279 |
-
$trial_link
|
280 |
$new_links[] = '<a style="font-weight:bold" href="' . $trial_link . '" target="_blank">' . __( 'Free Premium Trial', 'wp-security-audit-log' ) . '</a>';
|
281 |
}
|
282 |
}
|
@@ -289,13 +294,13 @@ class WSAL_ViewManager {
|
|
289 |
*
|
290 |
* @return int
|
291 |
*/
|
292 |
-
protected function
|
293 |
// Get current view via $_GET array.
|
294 |
$current_view = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
295 |
|
296 |
if ( isset( $current_view ) ) {
|
297 |
foreach ( $this->views as $i => $view ) {
|
298 |
-
if ( $current_view === $view->
|
299 |
return $i;
|
300 |
}
|
301 |
}
|
@@ -308,69 +313,72 @@ class WSAL_ViewManager {
|
|
308 |
*
|
309 |
* @return WSAL_AbstractView|null
|
310 |
*/
|
311 |
-
public function
|
312 |
-
if ( false === $this->
|
313 |
-
$this->
|
314 |
|
315 |
// Get current view via $_GET array.
|
316 |
$current_view = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
317 |
|
318 |
if ( isset( $current_view ) ) {
|
319 |
foreach ( $this->views as $view ) {
|
320 |
-
if ( $current_view === $view->
|
321 |
-
$this->
|
322 |
}
|
323 |
}
|
324 |
}
|
325 |
|
326 |
-
if ( $this->
|
327 |
-
$this->
|
328 |
}
|
329 |
}
|
330 |
-
return $this->
|
331 |
}
|
332 |
|
333 |
/**
|
334 |
* Render header of the current view.
|
335 |
*/
|
336 |
-
public function
|
337 |
-
|
338 |
-
|
|
|
339 |
}
|
340 |
}
|
341 |
|
342 |
/**
|
343 |
* Render footer of the current view.
|
344 |
*/
|
345 |
-
public function
|
346 |
-
|
347 |
-
|
|
|
348 |
}
|
|
|
349 |
global $pagenow;
|
350 |
-
if ( 'admin.php' === $pagenow && 'wsal-auditlog-pricing' === $_GET['page'] ) {
|
351 |
?>
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
<?php
|
375 |
}
|
376 |
}
|
@@ -378,16 +386,15 @@ class WSAL_ViewManager {
|
|
378 |
/**
|
379 |
* Render content of the current view.
|
380 |
*/
|
381 |
-
public function
|
382 |
-
$view = $this->
|
383 |
-
|
384 |
if ( $view && $view instanceof WSAL_AbstractView ) :
|
385 |
?>
|
386 |
<div class="wrap">
|
387 |
<?php
|
388 |
-
$view->
|
389 |
-
$view->
|
390 |
-
$view->
|
391 |
?>
|
392 |
</div>
|
393 |
<?php
|
@@ -400,7 +407,7 @@ class WSAL_ViewManager {
|
|
400 |
* @param string $class_name View class name.
|
401 |
* @return WSAL_AbstractView|bool The view or false on failure.
|
402 |
*/
|
403 |
-
public function
|
404 |
foreach ( $this->views as $view ) {
|
405 |
if ( $view instanceof $class_name ) {
|
406 |
return $view;
|
@@ -415,7 +422,7 @@ class WSAL_ViewManager {
|
|
415 |
* @param string $view_slug - Slug of view.
|
416 |
* @since 1.0.0
|
417 |
*/
|
418 |
-
private function
|
419 |
$not_show = false;
|
420 |
switch ( $view_slug ) {
|
421 |
case 'wsal-emailnotifications':
|
@@ -463,7 +470,7 @@ class WSAL_ViewManager {
|
|
463 |
}
|
464 |
|
465 |
// Return if multisite but not on the network admin.
|
466 |
-
if (
|
467 |
return;
|
468 |
}
|
469 |
|
@@ -481,27 +488,33 @@ class WSAL_ViewManager {
|
|
481 |
}
|
482 |
|
483 |
/**
|
484 |
-
*
|
|
|
|
|
485 |
*
|
486 |
* @return bool
|
487 |
*/
|
488 |
-
public function bypass_freemius_menu_hiding($should_hide) {
|
489 |
-
|
490 |
}
|
491 |
|
492 |
/**
|
493 |
-
|
494 |
-
|
495 |
-
* @param string $path
|
496 |
-
* @param string $filename
|
497 |
-
* @param string $extension
|
|
|
498 |
*
|
499 |
* @return string
|
500 |
*/
|
501 |
-
public static function get_asset_path($path, $filename, $extension) {
|
502 |
-
$result = $path . $filename;
|
503 |
-
$
|
|
|
|
|
504 |
$result .= $extension;
|
|
|
505 |
return $result;
|
506 |
}
|
507 |
}
|
4 |
*
|
5 |
* View manager class file.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
35 |
*
|
36 |
* @var object
|
37 |
*/
|
38 |
+
protected $plugin;
|
39 |
|
40 |
/**
|
41 |
* Active view.
|
42 |
*
|
43 |
* @var WSAL_AbstractView|null
|
44 |
*/
|
45 |
+
protected $active_view = false;
|
46 |
|
47 |
/**
|
48 |
* Method: Constructor.
|
49 |
*
|
50 |
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
51 |
*
|
|
|
52 |
* @since 1.0.0
|
53 |
*/
|
54 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
55 |
+
$this->plugin = $plugin;
|
56 |
|
57 |
// Skipped views array.
|
58 |
$skip_views = array();
|
64 |
*
|
65 |
* @since 3.2.3
|
66 |
*/
|
67 |
+
if ( file_exists( $this->plugin->get_base_dir() . 'classes/Views/SetupWizard.php' ) ) {
|
68 |
+
$skip_views[] = $this->plugin->get_base_dir() . 'classes/Views/SetupWizard.php';
|
69 |
}
|
70 |
|
71 |
/**
|
75 |
*
|
76 |
* @since 4.0.4
|
77 |
*/
|
78 |
+
$skip_views[] = $this->plugin->get_base_dir() . 'classes/Views/Licensing.php';
|
79 |
|
80 |
/**
|
81 |
* Skipped Views.
|
88 |
$skip_views = apply_filters( 'wsal_skip_views', $skip_views );
|
89 |
|
90 |
// Load views.
|
91 |
+
foreach ( WSAL_Utilities_FileSystemUtils::read_files_in_folder( $this->plugin->get_base_dir() . 'classes/Views', '*.php' ) as $file ) {
|
92 |
+
if ( empty( $skip_views ) || ! in_array( $file, $skip_views ) ) { // phpcs:ignore
|
93 |
+
$this->add_from_file( $file );
|
94 |
}
|
95 |
}
|
96 |
|
97 |
+
// Stop Freemius from hiding the menu on sub sites under certain circumstances.
|
98 |
+
add_filter(
|
99 |
+
'fs_should_hide_site_admin_settings_on_network_activation_mode_wp-security-audit-log',
|
100 |
+
array(
|
101 |
+
$this,
|
102 |
+
'bypass_freemius_menu_hiding',
|
103 |
+
)
|
104 |
+
);
|
105 |
|
106 |
// Add menus.
|
107 |
+
add_action( 'admin_menu', array( $this, 'add_admin_menus' ) );
|
108 |
+
add_action( 'network_admin_menu', array( $this, 'add_admin_menus' ) );
|
109 |
|
110 |
// Add plugin shortcut links.
|
111 |
+
add_filter( 'plugin_action_links_' . $plugin->get_base_name(), array( $this, 'add_plugin_shortcuts' ) );
|
112 |
|
113 |
// Render header.
|
114 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'render_view_header' ) );
|
115 |
|
116 |
// Render footer.
|
117 |
+
add_action( 'admin_footer', array( $this, 'render_view_footer' ) );
|
118 |
|
119 |
// Initialize setup wizard.
|
120 |
+
if ( ! $this->plugin->get_global_boolean_setting( 'setup-complete', false )
|
121 |
+
&& $this->plugin->settings()->current_user_can( 'edit' )
|
122 |
) {
|
123 |
new WSAL_Views_SetupWizard( $plugin );
|
124 |
}
|
140 |
if ( defined( 'WFCM_VERSION' ) ) {
|
141 |
if ( version_compare( WFCM_VERSION, '1.6.0', '<' ) ) {
|
142 |
echo '<div class="notice notice-success">
|
143 |
+
<p>' . esc_html__( 'WP Activity Log requires Website File Changes Monitor 1.6.0. Please upgrade that plugin.', 'wp-security-audit-log' ) . '</p>
|
144 |
</div>';
|
145 |
}
|
146 |
}
|
152 |
*
|
153 |
* @param string $file Path to file.
|
154 |
*/
|
155 |
+
public function add_from_file( $file ) {
|
156 |
$file = basename( $file, '.php' );
|
157 |
+
$this->add_from_class( WSAL_CLASS_PREFIX . 'Views_' . $file );
|
158 |
}
|
159 |
|
160 |
/**
|
162 |
*
|
163 |
* @param string $class Class name.
|
164 |
*/
|
165 |
+
public function add_from_class( $class ) {
|
166 |
+
$view = new $class( $this->plugin );
|
167 |
+
// Only load WSAL_AbstractView instances to prevent lingering classes
|
168 |
+
// that did not implement this from throwing fatals by being autoloaded.
|
169 |
if ( is_a( $view, '\WSAL_AbstractView' ) ) {
|
170 |
+
$this->add_instance( $view );
|
171 |
}
|
172 |
}
|
173 |
|
176 |
*
|
177 |
* @param WSAL_AbstractView $view The new view.
|
178 |
*/
|
179 |
+
public function add_instance( WSAL_AbstractView $view ) {
|
180 |
$this->views[] = $view;
|
181 |
}
|
182 |
|
183 |
/**
|
184 |
* Order views by their declared weight.
|
185 |
*/
|
186 |
+
public function reorder_views() {
|
187 |
+
usort( $this->views, array( $this, 'order_by_weight' ) );
|
188 |
}
|
189 |
|
190 |
/**
|
195 |
* @param WSAL_AbstractView $b - Second view.
|
196 |
* @return int
|
197 |
*/
|
198 |
+
public function order_by_weight( WSAL_AbstractView $a, WSAL_AbstractView $b ) {
|
199 |
+
$wa = $a->get_weight();
|
200 |
+
$wb = $b->get_weight();
|
201 |
switch ( true ) {
|
202 |
case $wa < $wb:
|
203 |
return -1;
|
211 |
/**
|
212 |
* WordPress Action
|
213 |
*/
|
214 |
+
public function add_admin_menus() {
|
215 |
+
$this->reorder_views();
|
216 |
|
217 |
+
if ( $this->plugin->settings()->current_user_can( 'view' ) && count( $this->views ) ) {
|
218 |
// Add main menu.
|
219 |
+
$main_view_menu_slug = $this->views[0]->get_safe_view_name();
|
220 |
$this->views[0]->hook_suffix = add_menu_page(
|
221 |
'WP Activity Log',
|
222 |
'WP Activity Log',
|
223 |
'read', // No capability requirement.
|
224 |
$main_view_menu_slug,
|
225 |
+
array( $this, 'render_view_body' ),
|
226 |
+
$this->views[0]->get_icon(),
|
227 |
'2.5' // Right after dashboard.
|
228 |
);
|
229 |
|
230 |
+
// Protected views to be displayed only to user with full plugin access.
|
231 |
$protected_views = array(
|
232 |
+
'wsal-togglealerts',
|
233 |
+
'wsal-usersessions-views',
|
234 |
+
'wsal-settings',
|
235 |
+
'wsal-ext-settings',
|
236 |
+
'wsal-rep-views-main',
|
237 |
+
'wsal-np-notifications',
|
238 |
+
'wsal-setup',
|
239 |
+
);
|
240 |
+
|
241 |
+
// Check edit privileges of the current user.
|
242 |
+
$has_current_user_edit_priv = $this->plugin->settings()->current_user_can( 'edit' );
|
243 |
|
244 |
// Add menu items.
|
245 |
foreach ( $this->views as $view ) {
|
246 |
+
if ( $view->is_accessible() ) {
|
247 |
+
$safe_view_name = $view->get_safe_view_name();
|
248 |
+
if ( $this->get_class_name_by_view( $safe_view_name ) ) {
|
249 |
continue;
|
250 |
}
|
251 |
|
252 |
+
if ( in_array( $safe_view_name, $protected_views ) && ! $has_current_user_edit_priv ) { // phpcs:ignore
|
253 |
continue;
|
254 |
}
|
255 |
|
256 |
$view->hook_suffix = add_submenu_page(
|
257 |
+
$view->is_visible() ? $main_view_menu_slug : null,
|
258 |
+
$view->get_title(),
|
259 |
+
$view->get_name(),
|
260 |
'read', // No capability requirement.
|
261 |
$safe_view_name,
|
262 |
+
array( $this, 'render_view_body' )
|
263 |
);
|
264 |
}
|
265 |
}
|
271 |
*
|
272 |
* @param array $old_links - Array of old links.
|
273 |
*/
|
274 |
+
public function add_plugin_shortcuts( $old_links ) {
|
275 |
+
$this->reorder_views();
|
276 |
|
277 |
$new_links = array();
|
278 |
foreach ( $this->views as $view ) {
|
279 |
+
if ( $view->has_plugin_shortcut_link() ) {
|
280 |
+
$new_links[] = '<a href="' . add_query_arg( 'page', $view->get_safe_view_name(), admin_url( 'admin.php' ) ) . '">' . $view->get_name() . '</a>';
|
281 |
|
282 |
if ( 1 === count( $new_links ) && ! wsal_freemius()->is__premium_only() ) {
|
283 |
+
// Trial link.
|
284 |
+
$trial_link = 'https://wpactivitylog.com/trial-premium-edition-plugin/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL';
|
285 |
$new_links[] = '<a style="font-weight:bold" href="' . $trial_link . '" target="_blank">' . __( 'Free Premium Trial', 'wp-security-audit-log' ) . '</a>';
|
286 |
}
|
287 |
}
|
294 |
*
|
295 |
* @return int
|
296 |
*/
|
297 |
+
protected function get_backend_page_index() {
|
298 |
// Get current view via $_GET array.
|
299 |
$current_view = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
300 |
|
301 |
if ( isset( $current_view ) ) {
|
302 |
foreach ( $this->views as $i => $view ) {
|
303 |
+
if ( $current_view === $view->get_safe_view_name() ) {
|
304 |
return $i;
|
305 |
}
|
306 |
}
|
313 |
*
|
314 |
* @return WSAL_AbstractView|null
|
315 |
*/
|
316 |
+
public function get_active_view() {
|
317 |
+
if ( false === $this->active_view ) {
|
318 |
+
$this->active_view = null;
|
319 |
|
320 |
// Get current view via $_GET array.
|
321 |
$current_view = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
322 |
|
323 |
if ( isset( $current_view ) ) {
|
324 |
foreach ( $this->views as $view ) {
|
325 |
+
if ( $current_view === $view->get_safe_view_name() ) {
|
326 |
+
$this->active_view = $view;
|
327 |
}
|
328 |
}
|
329 |
}
|
330 |
|
331 |
+
if ( $this->active_view ) {
|
332 |
+
$this->active_view->is_active = true;
|
333 |
}
|
334 |
}
|
335 |
+
return $this->active_view;
|
336 |
}
|
337 |
|
338 |
/**
|
339 |
* Render header of the current view.
|
340 |
*/
|
341 |
+
public function render_view_header() {
|
342 |
+
$view = $this->get_active_view();
|
343 |
+
if ( $view ) {
|
344 |
+
$view->header();
|
345 |
}
|
346 |
}
|
347 |
|
348 |
/**
|
349 |
* Render footer of the current view.
|
350 |
*/
|
351 |
+
public function render_view_footer() {
|
352 |
+
$view = $this->get_active_view();
|
353 |
+
if ( $view ) {
|
354 |
+
$view->footer();
|
355 |
}
|
356 |
+
|
357 |
global $pagenow;
|
358 |
+
if ( 'admin.php' === $pagenow && 'wsal-auditlog-pricing' === $_GET['page'] ) { // phpcs:ignore
|
359 |
?>
|
360 |
+
<style>
|
361 |
+
.fs-full-size-wrapper {
|
362 |
+
margin: 0px 0 -65px -20px !important;
|
363 |
+
}
|
364 |
+
|
365 |
+
#root .fs-app-header .fs-page-title h2, #fs_pricing_wrapper .fs-app-header .fs-page-title h2 {
|
366 |
+
font-size: 23px;
|
367 |
+
font-weight: 400;
|
368 |
+
margin: 0;
|
369 |
+
padding: 9px 0 4px 20px;
|
370 |
+
line-height: 1.3;
|
371 |
+
}
|
372 |
+
|
373 |
+
@media only screen and (max-width: 768px) {
|
374 |
+
#root #fs_pricing_wrapper .fs-app-main .fs-section--plans-and-pricing .fs-section--packages .fs-packages-menu, #fs_pricing_wrapper #fs_pricing_wrapper .fs-app-main .fs-section--plans-and-pricing .fs-section--packages .fs-packages-menu {
|
375 |
+
padding: 5px;
|
376 |
+
display: flex;
|
377 |
+
width: 100%;
|
378 |
+
margin: 0 auto;
|
379 |
+
}
|
380 |
+
}
|
381 |
+
</style>
|
382 |
<?php
|
383 |
}
|
384 |
}
|
386 |
/**
|
387 |
* Render content of the current view.
|
388 |
*/
|
389 |
+
public function render_view_body() {
|
390 |
+
$view = $this->get_active_view();
|
|
|
391 |
if ( $view && $view instanceof WSAL_AbstractView ) :
|
392 |
?>
|
393 |
<div class="wrap">
|
394 |
<?php
|
395 |
+
$view->render_icon();
|
396 |
+
$view->render_title();
|
397 |
+
$view->render_content();
|
398 |
?>
|
399 |
</div>
|
400 |
<?php
|
407 |
* @param string $class_name View class name.
|
408 |
* @return WSAL_AbstractView|bool The view or false on failure.
|
409 |
*/
|
410 |
+
public function find_by_class_name( $class_name ) {
|
411 |
foreach ( $this->views as $view ) {
|
412 |
if ( $view instanceof $class_name ) {
|
413 |
return $view;
|
422 |
* @param string $view_slug - Slug of view.
|
423 |
* @since 1.0.0
|
424 |
*/
|
425 |
+
private function get_class_name_by_view( $view_slug ) {
|
426 |
$not_show = false;
|
427 |
switch ( $view_slug ) {
|
428 |
case 'wsal-emailnotifications':
|
470 |
}
|
471 |
|
472 |
// Return if multisite but not on the network admin.
|
473 |
+
if ( ! is_network_admin() ) {
|
474 |
return;
|
475 |
}
|
476 |
|
488 |
}
|
489 |
|
490 |
/**
|
491 |
+
* Bypasses Freemius hiding menu items.
|
492 |
+
*
|
493 |
+
* @param bool $should_hide Should allow Freemium to hide menu items.
|
494 |
*
|
495 |
* @return bool
|
496 |
*/
|
497 |
+
public function bypass_freemius_menu_hiding( $should_hide ) {
|
498 |
+
return false;
|
499 |
}
|
500 |
|
501 |
/**
|
502 |
+
* Builds a relative asset path that takes SCRIPT_DEBUG constant into account.
|
503 |
+
*
|
504 |
+
* @param string $path Path relative to the plugin folder.
|
505 |
+
* @param string $filename Filename base (.min is optionally appended to this).
|
506 |
+
* @param string $extension File extension.
|
507 |
+
* @param bool $use_minified_version If true, the minified version of the file is used.
|
508 |
*
|
509 |
* @return string
|
510 |
*/
|
511 |
+
public static function get_asset_path( $path, $filename, $extension, $use_minified_version = true ) {
|
512 |
+
$result = $path . $filename . '.';
|
513 |
+
if ( $use_minified_version && SCRIPT_DEBUG ) {
|
514 |
+
$result .= 'min.';
|
515 |
+
}
|
516 |
$result .= $extension;
|
517 |
+
|
518 |
return $result;
|
519 |
}
|
520 |
}
|
classes/Views/AuditLog.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Class file for Audit Log View.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -16,23 +17,24 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
16 |
/**
|
17 |
* Audit Log Viewer Page
|
18 |
*
|
19 |
-
* @package
|
|
|
20 |
*/
|
21 |
class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
22 |
|
23 |
/**
|
24 |
* Listing view object (Instance of WSAL_AuditLogListView).
|
25 |
*
|
26 |
-
* @var
|
27 |
*/
|
28 |
-
protected $
|
29 |
|
30 |
/**
|
31 |
* Plugin version.
|
32 |
*
|
33 |
* @var string
|
34 |
*/
|
35 |
-
protected $
|
36 |
|
37 |
/**
|
38 |
* WSAL Adverts.
|
@@ -62,17 +64,15 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
62 |
public $user_last_view = '';
|
63 |
|
64 |
/**
|
65 |
-
*
|
66 |
-
*
|
67 |
-
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
68 |
*/
|
69 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
70 |
parent::__construct( $plugin );
|
71 |
add_action( 'wp_ajax_AjaxInspector', array( $this, 'AjaxInspector' ) );
|
72 |
-
add_action( 'wp_ajax_AjaxRefresh', array( $this, '
|
73 |
-
add_action( 'wp_ajax_AjaxSetIpp', array( $this, '
|
74 |
-
add_action( 'wp_ajax_AjaxSearchSite', array( $this, '
|
75 |
-
add_action( 'wp_ajax_AjaxSwitchDB', array( $this, '
|
76 |
add_action( 'wp_ajax_wsal_download_failed_login_log', array( $this, 'wsal_download_failed_login_log' ) );
|
77 |
add_action( 'wp_ajax_wsal_freemius_opt_in', array( $this, 'wsal_freemius_opt_in' ) );
|
78 |
add_action( 'wp_ajax_wsal_dismiss_setup_modal', array( $this, 'dismiss_setup_modal' ) );
|
@@ -81,31 +81,31 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
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, '
|
85 |
add_action( 'admin_enqueue_scripts', array( $this, 'load_pointers' ), 1000 );
|
86 |
add_filter( 'wsal_pointers_toplevel_page_wsal-auditlog', array( $this, 'register_privacy_pointer' ), 10, 1 );
|
87 |
add_action( 'admin_init', array( $this, 'handle_form_submission' ) );
|
88 |
|
89 |
-
if ( $this->
|
90 |
add_action( 'wp_ajax_wsal_infinite_scroll_events', array( $this, 'infinite_scroll_events' ) );
|
91 |
}
|
92 |
|
93 |
// Check plugin version for to dismiss the notice only until upgrade.
|
94 |
-
$this->
|
95 |
|
96 |
// Set adverts array.
|
97 |
$this->adverts = array(
|
98 |
0 => array(
|
99 |
-
'head' =>
|
100 |
-
'desc' =>
|
101 |
),
|
102 |
1 => array(
|
103 |
-
'head' =>
|
104 |
-
'desc' =>
|
105 |
),
|
106 |
2 => array(
|
107 |
-
'head' =>
|
108 |
-
'desc' =>
|
109 |
),
|
110 |
);
|
111 |
|
@@ -122,21 +122,21 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
122 |
* 2. DB disconnection notice.
|
123 |
* 3. Freemius opt-in/out notice.
|
124 |
*/
|
125 |
-
public function
|
126 |
-
$is_current_view = $this->
|
127 |
|
128 |
// Check if any of the extensions is activated.
|
129 |
if (
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
) {
|
137 |
-
$get_transient_fn = $this->
|
138 |
$wsal_is_advert_dismissed = $get_transient_fn( 'wsal-is-advert-dismissed' ); // Check if advert has been dismissed.
|
139 |
-
$wsal_premium_advert = $this->
|
140 |
$wsal_premium_advert = false !== $wsal_premium_advert ? (int) $wsal_premium_advert : 0; // Set the default.
|
141 |
|
142 |
$more_info = add_query_arg(
|
@@ -199,13 +199,13 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
199 |
|
200 |
|
201 |
// Check anonymous mode.
|
202 |
-
if ( 'anonymous' === $this->
|
203 |
if (
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
) {
|
210 |
if ( ! is_multisite() || ( is_multisite() && is_network_admin() ) ) :
|
211 |
?>
|
@@ -227,16 +227,16 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
227 |
$screen = get_current_screen();
|
228 |
|
229 |
|
230 |
-
|
231 |
-
|
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();
|
237 |
$plugin_filenames = array();
|
238 |
foreach ( $all_plugins as $plugin => $info ) {
|
239 |
-
$plugin_info
|
240 |
$plugin_filenames[] = $plugin_info['filename'];
|
241 |
}
|
242 |
|
@@ -244,26 +244,26 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
244 |
$predefined_plugins = WSAL_PluginInstallAndActivate::get_installable_plugins();
|
245 |
$predefined_plugins_check = array_column( $predefined_plugins, 'addon_for' );
|
246 |
|
247 |
-
// Loop through plugins and create an array of slugs, we will compare these
|
248 |
$we_have_addon = array_intersect( $plugin_filenames, $predefined_plugins_check );
|
249 |
|
250 |
if ( isset( $we_have_addon ) && is_array( $we_have_addon ) ) {
|
251 |
|
252 |
foreach ( $we_have_addon as $addon ) {
|
253 |
-
$addon_slug = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'plugin_slug' ) );
|
254 |
$is_addon_installed = WpSecurityAuditLog::is_plugin_active( $addon_slug );
|
255 |
if ( $is_addon_installed ) {
|
256 |
continue;
|
257 |
}
|
258 |
|
259 |
-
$is_dismissed = $this->
|
260 |
|
261 |
if ( ! $is_dismissed ) {
|
262 |
-
|
263 |
$image_filename = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'image_filename' ) );
|
264 |
$title = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'title' ) );
|
265 |
$plugin_description = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'plugin_description' ) );
|
266 |
-
|
267 |
?>
|
268 |
<div class="notice notice-information is-dismissible notice-addon-available" id="wsal-notice-addon-available-<?php echo esc_attr( $addon ); ?>" data-addon="<?php echo esc_attr( $addon ); ?>">
|
269 |
<div class="addon-logo-wrapper">
|
@@ -278,7 +278,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
278 |
esc_html__( 'installed.', 'wp-security-audit-log' ),
|
279 |
esc_html( $plugin_description ),
|
280 |
esc_html__( 'Install extension', 'wp-security-audit-log' ),
|
281 |
-
$this->get_third_party_plugins_tab_url()
|
282 |
);
|
283 |
?>
|
284 |
<?php wp_nonce_field( 'wsal_dismiss_notice_addon_available_' . $addon, 'wsal-dismiss-notice-addon-available-' . $addon, false, true ); ?>
|
@@ -303,8 +303,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
303 |
$post_array = filter_input_array( INPUT_POST, $post_array_args );
|
304 |
|
305 |
// Verify nonce.
|
306 |
-
if ( wp_verify_nonce( $post_array['nonce'], 'wsal_dismiss_notice_addon_available_'. $post_array['addon'] ) ) {
|
307 |
-
$this->
|
308 |
die();
|
309 |
}
|
310 |
die( 'Nonce verification failed!' );
|
@@ -312,64 +312,62 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
312 |
|
313 |
|
314 |
/**
|
315 |
-
*
|
316 |
*/
|
317 |
-
public function
|
318 |
return true;
|
319 |
}
|
320 |
|
321 |
/**
|
322 |
-
*
|
323 |
*/
|
324 |
-
public function
|
325 |
-
return
|
326 |
}
|
327 |
|
328 |
/**
|
329 |
-
*
|
330 |
*/
|
331 |
-
public function
|
332 |
-
return $this->
|
333 |
-
? $this->
|
334 |
: $this->get_icon_encoded();
|
335 |
}
|
336 |
|
337 |
/**
|
338 |
-
* Returns an encoded SVG
|
339 |
*
|
340 |
-
* @
|
341 |
-
* @since
|
342 |
-
* @return [type]
|
343 |
*/
|
344 |
private function get_icon_encoded() {
|
345 |
return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTEycHgiIGhlaWdodD0iMTEwcHgiIHZpZXdCb3g9IjAgMCAxMTIgMTEwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IHNrZXRjaHRvb2wgNTIuNiAoNjc0OTEpIC0gaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoIC0tPgogICAgPHRpdGxlPkE2QUQyNDUyLUZERDItNDIwQS05ODMzLTQ3QkJDOTlBQjEzNzwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggc2tldGNodG9vbC48L2Rlc2M+CiAgICA8ZyBpZD0iV1BTQUwtU2NyZWVucyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkN1c3RvbS1pY29ucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMjQuMDAwMDAwLCAtNDYxLjAwMDAwMCkiIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxnIGlkPSJDdXN0b20tSWNvbnMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE1MS4wMDAwMDAsIDIyOC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJMb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4MDcuMDAwMDAwLCAyMDQuNjY2NjY3KSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9IkF0b21zLS8taWNvbnMtLy1jdXN0b20tcmV2ZXJzZWQtYXVkaXQtbG9nIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1Mi4wMDAwMDAsIDE1LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNzAuMDg0ODc0NSw3OC4zNjU1MDAyIEM3Ny44MDAwOTQyLDc4LjM2NTUwMDIgODQuMDU0OTE2MSw3Mi4xMTA2NzgxIDg0LjA1NDkxNjEsNjQuMzk0NTE5MiBDODQuMDU0OTE2MSw1Ni4xMTk1NTg2IDc2Ljg3Njg5NzUsNDkuNTk2MTM2IDY4LjU1MzEwMDYsNTAuNTExODE5NSBDNjkuMDMxMTM0Myw1MS45MjE1MDIzIDY5LjMwMjU1MjIsNTMuNDI2MDQwNiA2OS4zMDI1NTIyLDU0Ljk5NzI1OTQgQzY5LjMwMjU1MjIsNjIuMTk1MDAwNyA2My44NTcyODgzLDY4LjExNzM1OTMgNTYuODYyNDA2Myw2OC44Nzk5NTkyIEM1OC43MzMyMTc5LDc0LjM5Mjg0MjkgNjMuOTM5OTM0Niw3OC4zNjU1MDAyIDcwLjA4NDg3NDUsNzguMzY1NTAwMiBaIE03MC4wNDA3MzIyLDI1LjU3NzA1NTcgTDEwOC4yNzMwOTUsMjkuNjk5MDM5OCBDMTI0LjgyOTU5LDYzLjc3MDkxNTUgMTA2LjA0NTQwMiwxMDIuODE5NDEzIDY5Ljk4ODEzOTEsMTExLjUyNDUxIEM2OS41NDEwOTc4LDExMS40MTU1NjcgNjkuMTE5NDEzOCwxMTEuMjgzMTQ1IDY4LjY3ODAwNzUsMTExLjE2NzYyOCBMNjguNjc2MTI5Miw5My44NzIwMTIyIEM2OC42NzIzNzI1LDkzLjg3MjAxMjIgNjguNjY5NTU1LDkzLjg3MjAxMjIgNjguNjY1Nzk4NCw5My44NzIwMTIyIEM1My4wNzQ3NjI5LDkzLjEyOTEzNDYgNDAuNjE4NjUxNiw4MC4yMTE4OTM5IDQwLjYxODY1MTYsNjQuNDM4NjYgQzQwLjYxODY1MTYsNTQuOTA4MDM5MSA0Ny41ODI1NDEsMzYuMDA5MjcyNSA2OC42NjU3OTg0LDM1LjAwNjI0NyBDNjguNjY5NTU1LDM1LjAwNjI0NyA2OC42NzIzNzI1LDM1LjAwNTMwNzggNjguNjc2MTI5MiwzNS4wMDUzMDc4IEw2OC42ODE3NjQxLDI1LjcyOTIgQzY5LjczMTc0NzcsMjUuNjEwODY1NSA2OS44NTc1OTU1LDI1LjU5NDg5OTggNzAuMDQwNzMyMiwyNS41NzcwNTU3IFogTTExNC40MjkxMTksODEuNTc0NjE1NCBDMTIyLjYxMjA0MSw2My43NjgwOTU4IDEyMi4wNzAxNDUsNDMuMDc0NTkwOCAxMTIuOTg4NDQ0LDI0LjU2NjUxNjggTDcwLjAwMDE2MTEsMTkuODI2NTY0IEwyNy4wMTA5MzkyLDI0LjU2NjUxNjggQzE3LjkyOTIzODQsNDMuMDczNjUxNiAxNy4zODczNDE2LDYzLjc2NzE1NjYgMjUuNTcxMjAzMiw4MS41NzQ2MTU0IEMzMy43ODIzMDA1LDk5LjQ0MjE4MDcgNDkuOTUwOTIxMiwxMTIuNDc0OTM4IDcwLjAwMDE2MTEsMTE3LjQxNzc1IEM5MC4wNDk0MDEsMTEyLjQ3NDkzOCAxMDYuMjE4MDIyLDk5LjQ0MzExOTggMTE0LjQyOTExOSw4MS41NzQ2MTU0IFogTTExNy40NDEwMTQsMjAuNTMwOTM1NyBDMTI4LjAwNzUzLDQwLjk4MDI1OTIgMTI4LjgyODM1OCw2NC4xMTA4OTE0IDExOS42OTIxODYsODMuOTkyOTYwNyBDMTEwLjYzOTU5OSwxMDMuNjkwMDE1IDkyLjc3MTA5NDIsMTE3Ljk4NTk0NiA3MC42NjY5NjY3LDEyMy4yMTUyMDMgTDcwLjAwMDE2MTQsMTIzLjM3MjA0MyBMNjkuMzMzMzU2LDEyMy4yMTUyMDMgQzQ3LjIyOTIyODUsMTE3Ljk4NTk0NiAyOS4zNTk3ODQ1LDEwMy42OTAwMTUgMjAuMzA4MTM2OCw4My45OTI5NjA3IEMxMS4xNzE5NjQ1LDY0LjExMDg5MTQgMTEuOTkxODUzMyw0MC45NzkzMiAyMi41NTkzMDkyLDIwLjUzMDkzNTcgTDIzLjI3MjEzMzUsMTkuMTUyMjQ1MyBMNzAuMDAwMTYxNCwxNCBMMTE2LjcyODE4OSwxOS4xNTIyNDUzIEwxMTcuNDQxMDE0LDIwLjUzMDkzNTcgWiIgaWQ9ImN1c3RvbS1yZXZlcnNlZC1hdWRpdC1sb2ciPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
|
346 |
}
|
347 |
|
348 |
/**
|
349 |
-
*
|
350 |
*/
|
351 |
-
public function
|
352 |
-
return
|
353 |
}
|
354 |
|
355 |
/**
|
356 |
-
*
|
357 |
*/
|
358 |
-
public function
|
359 |
return 1;
|
360 |
}
|
361 |
|
362 |
/**
|
363 |
* Method: Get View.
|
364 |
*/
|
365 |
-
protected function
|
366 |
// Set page arguments.
|
367 |
if ( ! $this->page_args ) {
|
368 |
$this->page_args = new stdClass();
|
369 |
|
370 |
// @codingStandardsIgnoreStart
|
371 |
$this->page_args->page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : false;
|
372 |
-
$this->page_args->site_id = $this->
|
373 |
|
374 |
// Order arguments.
|
375 |
$this->page_args->order_by = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : false;
|
@@ -382,16 +380,16 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
382 |
}
|
383 |
|
384 |
// Set events listing view class.
|
385 |
-
if ( is_null( $this->
|
386 |
// Set the requested view based on POST or GET value. We only care
|
387 |
// if the view is 'grid' specifically.
|
388 |
$requested_view = $this->detect_view_type();
|
389 |
|
390 |
// If 'grid' is requested use it otherwise use list view by default.
|
391 |
if ( 'grid' !== $requested_view ) {
|
392 |
-
$this->
|
393 |
} else {
|
394 |
-
$this->
|
395 |
}
|
396 |
|
397 |
// if the requested view didn't match the view users last viewed
|
@@ -401,7 +399,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
401 |
$this->user_last_view = $requested_view;
|
402 |
}
|
403 |
}
|
404 |
-
return $this->
|
405 |
}
|
406 |
|
407 |
/**
|
@@ -424,6 +422,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
424 |
* @method detect_view_type
|
425 |
* @since 4.0.0
|
426 |
* @return string
|
|
|
|
|
|
|
427 |
*/
|
428 |
public function detect_view_type() {
|
429 |
// First check if there is a GET/POST request for a specific view.
|
@@ -466,12 +467,10 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
466 |
check_admin_referer( 'bulk-logs' );
|
467 |
}
|
468 |
|
469 |
-
//
|
470 |
-
$
|
471 |
-
$
|
472 |
-
$
|
473 |
-
$search_save = ( isset( $_REQUEST['wsal-save-search-name'] ) && ! empty( $_REQUEST['wsal-save-search-name'] ) ) ? trim( sanitize_text_field( $_REQUEST['wsal-save-search-name'] ) ) : false;
|
474 |
-
// @codingStandardsIgnoreEnd
|
475 |
|
476 |
if ( ! empty( $wpnonce ) ) {
|
477 |
// Remove args array.
|
@@ -504,8 +503,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
504 |
*
|
505 |
* @since 1.0.0
|
506 |
*/
|
507 |
-
public function
|
508 |
-
if ( ! $this->
|
509 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
510 |
}
|
511 |
|
@@ -514,13 +513,14 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
514 |
check_admin_referer( 'bulk-logs' );
|
515 |
}
|
516 |
|
517 |
-
$this->
|
|
|
518 |
?>
|
519 |
<form id="audit-log-viewer" method="get">
|
520 |
<div id="audit-log-viewer-content">
|
521 |
<input type="hidden" name="page" value="<?php echo esc_attr( $this->page_args->page ); ?>" />
|
522 |
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr( empty( $this->page_args->site_id ) ? '0' : $this->page_args->site_id ); ?>" />
|
523 |
-
<input type="hidden" id="view" name="view" value="<?php echo (
|
524 |
<?php
|
525 |
/**
|
526 |
* Hook: `wsal_auditlog_before_view`
|
@@ -529,10 +529,10 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
529 |
*
|
530 |
* @param WSAL_AuditLogListView $this->_view - Audit log view object.
|
531 |
*/
|
532 |
-
do_action( 'wsal_auditlog_before_view', $this->
|
533 |
|
534 |
// Display the audit log list.
|
535 |
-
$this->
|
536 |
|
537 |
/**
|
538 |
* Hook: `wsal_auditlog_after_view`
|
@@ -541,16 +541,16 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
541 |
*
|
542 |
* @param WSAL_AuditLogListView $this->_view - Audit log view object.
|
543 |
*/
|
544 |
-
do_action( 'wsal_auditlog_after_view', $this->
|
545 |
?>
|
546 |
</div>
|
547 |
</form>
|
548 |
|
549 |
<?php
|
550 |
if (
|
551 |
-
$this->
|
552 |
-
|
553 |
-
&& ! $this->
|
554 |
) :
|
555 |
?>
|
556 |
<div data-remodal-id="wsal-setup-modal">
|
@@ -572,7 +572,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
572 |
});
|
573 |
|
574 |
jQuery(document).on('closed', wsal_setup_modal, function () {
|
575 |
-
|
576 |
});
|
577 |
});
|
578 |
</script>
|
@@ -594,8 +594,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
594 |
'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
|
595 |
),
|
596 |
'autorefresh' => array(
|
597 |
-
'enabled' => ! $is_search_view
|
598 |
-
'token' => $this->
|
599 |
),
|
600 |
)
|
601 |
);
|
@@ -610,7 +610,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
610 |
* Ajax callback to display meta data inspector.
|
611 |
*/
|
612 |
public function AjaxInspector() {
|
613 |
-
if ( ! $this->
|
614 |
die( 'Access Denied.' );
|
615 |
}
|
616 |
|
@@ -623,13 +623,13 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
623 |
|
624 |
|
625 |
$occ = new WSAL_Models_Occurrence();
|
626 |
-
$occ->
|
627 |
-
$alert_meta = $occ->
|
628 |
unset( $alert_meta['ReportText'] );
|
629 |
|
630 |
// Set WSAL_Ref class scripts and styles.
|
631 |
-
WSAL_Ref::config( 'stylePath', esc_url( $this->
|
632 |
-
WSAL_Ref::config( 'scriptPath', esc_url( $this->
|
633 |
|
634 |
echo '<!DOCTYPE html><html><head>';
|
635 |
echo '<style type="text/css">';
|
@@ -644,8 +644,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
644 |
/**
|
645 |
* Ajax callback to refresh the view.
|
646 |
*/
|
647 |
-
public function
|
648 |
-
if ( ! $this->
|
649 |
die( 'Access Denied.' );
|
650 |
}
|
651 |
|
@@ -663,10 +663,10 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
663 |
|
664 |
// Check for new total number of alerts.
|
665 |
$occ = new WSAL_Models_Occurrence();
|
666 |
-
$new = (int) $occ->
|
667 |
|
668 |
-
|
669 |
-
|
670 |
die;
|
671 |
}
|
672 |
|
@@ -674,8 +674,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
674 |
* Ajax callback to set number of alerts to
|
675 |
* show on a single page.
|
676 |
*/
|
677 |
-
public function
|
678 |
-
if ( ! $this->
|
679 |
die( 'Access Denied.' );
|
680 |
}
|
681 |
|
@@ -685,15 +685,15 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
685 |
if ( ! isset( $post_array['count'] ) ) {
|
686 |
die( 'Count parameter expected.' );
|
687 |
}
|
688 |
-
$this->
|
689 |
die;
|
690 |
}
|
691 |
|
692 |
/**
|
693 |
* Ajax callback to search.
|
694 |
*/
|
695 |
-
public function
|
696 |
-
if ( ! $this->
|
697 |
die( 'Access Denied.' );
|
698 |
}
|
699 |
|
@@ -708,14 +708,14 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
708 |
|
709 |
$search = $post_array['search'];
|
710 |
|
711 |
-
foreach ( $this->
|
712 |
if ( stripos( $site->blogname, $search ) !== false ) {
|
713 |
$grp1[] = $site;
|
714 |
} elseif ( stripos( $site->domain, $search ) !== false ) {
|
715 |
$grp2[] = $site;
|
716 |
}
|
717 |
}
|
718 |
-
die( json_encode( array_slice( $grp1 + $grp2, 0, 7 ) ) );
|
719 |
}
|
720 |
|
721 |
|
@@ -732,32 +732,32 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
732 |
die();
|
733 |
}
|
734 |
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
|
740 |
-
|
741 |
-
|
742 |
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
|
752 |
die();
|
753 |
}
|
754 |
|
755 |
/**
|
756 |
-
* Ajax callback to handle
|
757 |
*/
|
758 |
public function wsal_freemius_opt_in() {
|
759 |
// Die if not have access.
|
760 |
-
if ( ! $this->
|
761 |
die( 'Access Denied.' );
|
762 |
}
|
763 |
|
@@ -795,8 +795,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
795 |
wsal_freemius()->opt_in( false, false, false, false, false, false, false, false, $sites_data );
|
796 |
}
|
797 |
|
798 |
-
// Update
|
799 |
-
$this->
|
800 |
} elseif ( 'no' === $choice ) {
|
801 |
if ( ! is_multisite() ) {
|
802 |
wsal_freemius()->skip_connection(); // Opt out.
|
@@ -804,8 +804,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
804 |
wsal_freemius()->skip_connection( null, true ); // Opt out for all websites.
|
805 |
}
|
806 |
|
807 |
-
// Update
|
808 |
-
$this->
|
809 |
}
|
810 |
|
811 |
echo wp_json_encode(
|
@@ -828,48 +828,48 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
828 |
/**
|
829 |
* Method: Render header of the view.
|
830 |
*/
|
831 |
-
public function
|
832 |
add_thickbox();
|
833 |
|
834 |
// Darktooltip styles.
|
835 |
wp_enqueue_style(
|
836 |
'darktooltip',
|
837 |
-
$this->
|
838 |
array(),
|
839 |
'0.4.0'
|
840 |
);
|
841 |
|
842 |
// Remodal styles.
|
843 |
-
wp_enqueue_style( 'wsal-remodal', $this->
|
844 |
-
wp_enqueue_style( 'wsal-remodal-theme', $this->
|
845 |
|
846 |
// Audit log styles.
|
847 |
wp_enqueue_style(
|
848 |
'auditlog',
|
849 |
-
$this->
|
850 |
array(),
|
851 |
-
filemtime( $this->
|
852 |
);
|
853 |
|
854 |
-
//
|
855 |
wp_enqueue_style(
|
856 |
'wsal_admin_notices',
|
857 |
-
$this->
|
858 |
array(),
|
859 |
-
filemtime( $this->
|
860 |
);
|
861 |
}
|
862 |
|
863 |
/**
|
864 |
-
*
|
865 |
*/
|
866 |
-
public function
|
867 |
wp_enqueue_script( 'jquery' );
|
868 |
|
869 |
// Darktooltip js.
|
870 |
wp_enqueue_script(
|
871 |
'darktooltip', // Identifier.
|
872 |
-
$this->
|
873 |
array( 'jquery' ), // Depends on jQuery.
|
874 |
'0.4.0', // Script version.
|
875 |
true
|
@@ -878,7 +878,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
878 |
// Remodal script.
|
879 |
wp_enqueue_script(
|
880 |
'wsal-remodal-js',
|
881 |
-
$this->
|
882 |
array(),
|
883 |
'1.1.1',
|
884 |
true
|
@@ -890,11 +890,12 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
890 |
// Audit log script.
|
891 |
wp_register_script(
|
892 |
'auditlog',
|
893 |
-
$this->
|
894 |
array(),
|
895 |
-
filemtime( $this->
|
896 |
true
|
897 |
);
|
|
|
898 |
$audit_log_data = array(
|
899 |
'page' => isset( $this->page_args->page ) ? $this->page_args->page : false,
|
900 |
'siteId' => isset( $this->page_args->site_id ) ? $this->page_args->site_id : false,
|
@@ -903,15 +904,15 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
903 |
'searchTerm' => isset( $this->page_args->search_term ) ? $this->page_args->search_term : false,
|
904 |
'searchFilters' => isset( $this->page_args->search_filters ) ? $this->page_args->search_filters : false,
|
905 |
'viewerNonce' => wp_create_nonce( 'wsal_auditlog_viewer_nonce' ),
|
906 |
-
'infiniteScroll' => $this->
|
907 |
'userView' => ( in_array( $this->user_last_view, $this->supported_view_types(), true ) ) ? $this->user_last_view : 'list',
|
908 |
'installAddonStrings' => array(
|
909 |
-
'defaultButton' =>
|
910 |
-
'installingText' =>
|
911 |
-
'otherInstalling' =>
|
912 |
-
'addonInstalled' =>
|
913 |
-
'installedReload' =>
|
914 |
-
'buttonError' =>
|
915 |
'msgError' => sprintf(
|
916 |
/* translators: 1 - an opening link tag, 2 - the closing tag. */
|
917 |
__( '<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.', 'wp-security-audit-log' ),
|
@@ -938,8 +939,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
938 |
|
939 |
// Don't display notice if the wizard notice is showing.
|
940 |
if (
|
941 |
-
! $this->
|
942 |
-
&& ! $this->
|
943 |
) {
|
944 |
return;
|
945 |
}
|
@@ -956,14 +957,14 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
956 |
}
|
957 |
|
958 |
// Get dismissed pointers.
|
959 |
-
$dismissed = explode( ',', (string) $this->
|
960 |
$valid_pointers = array();
|
961 |
|
962 |
// Check pointers and remove dismissed ones.
|
963 |
foreach ( $pointers as $pointer_id => $pointer ) {
|
964 |
// Sanity check.
|
965 |
if (
|
966 |
-
in_array( $pointer_id, $dismissed )
|
967 |
|| empty( $pointer )
|
968 |
|| empty( $pointer_id )
|
969 |
|| empty( $pointer['target'] )
|
@@ -988,9 +989,9 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
988 |
// Add pointers script to queue. Add custom script.
|
989 |
wp_enqueue_script(
|
990 |
'auditlog-pointer',
|
991 |
-
$this->
|
992 |
array( 'wp-pointer' ),
|
993 |
-
filemtime( $this->
|
994 |
true
|
995 |
);
|
996 |
|
@@ -1006,16 +1007,16 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1006 |
* @since 3.2
|
1007 |
*/
|
1008 |
public function register_privacy_pointer( $pointer ) {
|
1009 |
-
$is_current_view = $this->
|
1010 |
if ( current_user_can( 'manage_options' ) && $is_current_view && ! isset( $pointer['wsal_privacy'] ) ) {
|
1011 |
$pointer['wsal_privacy'] = array(
|
1012 |
'target' => '#toplevel_page_wsal-auditlog .wp-first-item',
|
1013 |
'options' => array(
|
1014 |
'content' => sprintf(
|
1015 |
'<h3> %s </h3> <p> %s </p> <p><strong>%s</strong></p>',
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
),
|
1020 |
'position' => array(
|
1021 |
'edge' => 'left',
|
@@ -1034,7 +1035,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1034 |
*/
|
1035 |
public function wsal_dismiss_advert() {
|
1036 |
// Die if user does not have permission to dismiss.
|
1037 |
-
if ( ! $this->
|
1038 |
echo wp_json_encode(
|
1039 |
array(
|
1040 |
'success' => false,
|
@@ -1060,8 +1061,8 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1060 |
// @codingStandardsIgnoreEnd
|
1061 |
|
1062 |
$advert = 2 === $advert ? '0' : $advert + 1;
|
1063 |
-
$this->
|
1064 |
-
$set_transient_fn = $this->
|
1065 |
$set_transient_fn( 'wsal-is-advert-dismissed', true, MONTH_IN_SECONDS );
|
1066 |
echo wp_json_encode(
|
1067 |
array(
|
@@ -1081,31 +1082,31 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1081 |
$pointer = sanitize_text_field( wp_unslash( $_POST['pointer'] ) );
|
1082 |
// @codingStandardsIgnoreEnd
|
1083 |
|
1084 |
-
if ( $pointer != sanitize_key( $pointer ) ) {
|
1085 |
wp_die( 0 );
|
1086 |
}
|
1087 |
|
1088 |
-
$dismissed = array_filter( explode( ',', (string) $this->
|
1089 |
|
1090 |
-
if ( in_array( $pointer, $dismissed ) ) {
|
1091 |
wp_die( 0 );
|
1092 |
}
|
1093 |
|
1094 |
$dismissed[] = $pointer;
|
1095 |
$dismissed = implode( ',', $dismissed );
|
1096 |
|
1097 |
-
$this->
|
1098 |
wp_die( 1 );
|
1099 |
}
|
1100 |
|
1101 |
/**
|
1102 |
-
* Infinite Scroll Events AJAX
|
1103 |
*
|
1104 |
* @since 3.3.1.1
|
1105 |
*/
|
1106 |
public function infinite_scroll_events() {
|
1107 |
// Check user permissions.
|
1108 |
-
if ( ! $this->
|
1109 |
die( esc_html__( 'Access Denied', 'wp-security-audit-log' ) );
|
1110 |
}
|
1111 |
|
@@ -1114,17 +1115,17 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1114 |
die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
1115 |
}
|
1116 |
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
}
|
1129 |
|
1130 |
/**
|
@@ -1134,7 +1135,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1134 |
*/
|
1135 |
public function get_total_events() {
|
1136 |
$occ = new WSAL_Models_Occurrence();
|
1137 |
-
return (int) $occ->
|
1138 |
}
|
1139 |
|
1140 |
/**
|
@@ -1144,7 +1145,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1144 |
*/
|
1145 |
public function dismiss_setup_modal() {
|
1146 |
// Die if user does not have permission to dismiss.
|
1147 |
-
if ( ! $this->
|
1148 |
echo wp_json_encode(
|
1149 |
array(
|
1150 |
'success' => false,
|
@@ -1155,9 +1156,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1155 |
}
|
1156 |
|
1157 |
// Filter $_POST array for security.
|
1158 |
-
//
|
1159 |
-
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : false;
|
1160 |
-
// @codingStandardsIgnoreEnd
|
1161 |
|
1162 |
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wsal_dismiss_setup_modal' ) ) {
|
1163 |
// Nonce verification failed.
|
@@ -1170,18 +1169,20 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1170 |
die();
|
1171 |
}
|
1172 |
|
1173 |
-
$this->
|
1174 |
wp_send_json_success();
|
1175 |
}
|
1176 |
|
1177 |
|
1178 |
/**
|
|
|
|
|
1179 |
* @return string URL of the 3rd party extensions tab.
|
1180 |
-
|
1181 |
*/
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
|
1186 |
/**
|
1187 |
* Builds HTML markup to display 3rd party extension teaser if there is a post type in the event meta data and the
|
@@ -1208,17 +1209,17 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
1208 |
return $result;
|
1209 |
}
|
1210 |
|
1211 |
-
$result
|
1212 |
-
$result
|
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
|
1220 |
-
$result
|
1221 |
-
$result
|
1222 |
|
1223 |
return $result;
|
1224 |
}
|
4 |
*
|
5 |
* Class file for Audit Log View.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
17 |
/**
|
18 |
* Audit Log Viewer Page
|
19 |
*
|
20 |
+
* @package wsal
|
21 |
+
* @subpackage views
|
22 |
*/
|
23 |
class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
24 |
|
25 |
/**
|
26 |
* Listing view object (Instance of WSAL_AuditLogListView).
|
27 |
*
|
28 |
+
* @var WSAL_AuditLogListView
|
29 |
*/
|
30 |
+
protected $view;
|
31 |
|
32 |
/**
|
33 |
* Plugin version.
|
34 |
*
|
35 |
* @var string
|
36 |
*/
|
37 |
+
protected $version;
|
38 |
|
39 |
/**
|
40 |
* WSAL Adverts.
|
64 |
public $user_last_view = '';
|
65 |
|
66 |
/**
|
67 |
+
* {@inheritDoc}
|
|
|
|
|
68 |
*/
|
69 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
70 |
parent::__construct( $plugin );
|
71 |
add_action( 'wp_ajax_AjaxInspector', array( $this, 'AjaxInspector' ) );
|
72 |
+
add_action( 'wp_ajax_AjaxRefresh', array( $this, 'ajax_refresh' ) );
|
73 |
+
add_action( 'wp_ajax_AjaxSetIpp', array( $this, 'ajax_set_items_per_page' ) );
|
74 |
+
add_action( 'wp_ajax_AjaxSearchSite', array( $this, 'ajax_search_site' ) );
|
75 |
+
add_action( 'wp_ajax_AjaxSwitchDB', array( $this, 'ajax_switch_db' ) );
|
76 |
add_action( 'wp_ajax_wsal_download_failed_login_log', array( $this, 'wsal_download_failed_login_log' ) );
|
77 |
add_action( 'wp_ajax_wsal_freemius_opt_in', array( $this, 'wsal_freemius_opt_in' ) );
|
78 |
add_action( 'wp_ajax_wsal_dismiss_setup_modal', array( $this, 'dismiss_setup_modal' ) );
|
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, 'admin_notices' ) );
|
85 |
add_action( 'admin_enqueue_scripts', array( $this, 'load_pointers' ), 1000 );
|
86 |
add_filter( 'wsal_pointers_toplevel_page_wsal-auditlog', array( $this, 'register_privacy_pointer' ), 10, 1 );
|
87 |
add_action( 'admin_init', array( $this, 'handle_form_submission' ) );
|
88 |
|
89 |
+
if ( $this->plugin->settings()->is_infinite_scroll() ) {
|
90 |
add_action( 'wp_ajax_wsal_infinite_scroll_events', array( $this, 'infinite_scroll_events' ) );
|
91 |
}
|
92 |
|
93 |
// Check plugin version for to dismiss the notice only until upgrade.
|
94 |
+
$this->version = WSAL_VERSION;
|
95 |
|
96 |
// Set adverts array.
|
97 |
$this->adverts = array(
|
98 |
0 => array(
|
99 |
+
'head' => esc_html__( 'Get email notifications about website changes, view logged-in users, do granular log searches, create detailed reports, and more.', 'wp-security-audit-log' ),
|
100 |
+
'desc' => esc_html__( 'Upgrade to premium today and get more out of your activity logs!', 'wp-security-audit-log' ),
|
101 |
),
|
102 |
1 => array(
|
103 |
+
'head' => esc_html__( 'Instant SMS & email alerts, search & filters, reports, users sessions management and much more!', 'wp-security-audit-log' ),
|
104 |
+
'desc' => esc_html__( 'Upgrade to premium to get more out of your activity logs!', 'wp-security-audit-log' ),
|
105 |
),
|
106 |
2 => array(
|
107 |
+
'head' => esc_html__( 'See who logged in on your site in real-time, generate reports, get SMS & email alerts of critical changes and more!', 'wp-security-audit-log' ),
|
108 |
+
'desc' => esc_html__( 'Unlock these and other powerful features with WP Activity Log Premium.', 'wp-security-audit-log' ),
|
109 |
),
|
110 |
);
|
111 |
|
122 |
* 2. DB disconnection notice.
|
123 |
* 3. Freemius opt-in/out notice.
|
124 |
*/
|
125 |
+
public function admin_notices() {
|
126 |
+
$is_current_view = $this->plugin->views->get_active_view() == $this; // phpcs:ignore
|
127 |
|
128 |
// Check if any of the extensions is activated.
|
129 |
if (
|
130 |
+
! class_exists( 'WSAL_NP_Plugin' )
|
131 |
+
&& ! class_exists( 'WSAL_Ext_Plugin' )
|
132 |
+
&& ! class_exists( 'WSAL_Rep_Plugin' )
|
133 |
+
&& ! class_exists( 'WSAL_SearchExtension' )
|
134 |
+
&& ! class_exists( 'WSAL_UserSessions_Plugin' )
|
135 |
+
&& 'anonymous' !== $this->plugin->get_global_setting( 'freemius_state', 'anonymous' ) // Anonymous mode option.
|
136 |
) {
|
137 |
+
$get_transient_fn = $this->plugin->is_multisite() ? 'get_site_transient' : 'get_transient'; // Check for multisite.
|
138 |
$wsal_is_advert_dismissed = $get_transient_fn( 'wsal-is-advert-dismissed' ); // Check if advert has been dismissed.
|
139 |
+
$wsal_premium_advert = $this->plugin->get_global_setting( 'premium-advert', false ); // Get the advert to display.
|
140 |
$wsal_premium_advert = false !== $wsal_premium_advert ? (int) $wsal_premium_advert : 0; // Set the default.
|
141 |
|
142 |
$more_info = add_query_arg(
|
199 |
|
200 |
|
201 |
// Check anonymous mode.
|
202 |
+
if ( 'anonymous' === $this->plugin->get_global_setting( 'freemius_state', 'anonymous' ) ) { // If user manually opt-out then don't show the notice.
|
203 |
if (
|
204 |
+
wsal_freemius()->is_anonymous() // Anonymous mode option.
|
205 |
+
&& wsal_freemius()->is_not_paying() // Not paying customer.
|
206 |
+
&& wsal_freemius()->has_api_connectivity() // Check API connectivity.
|
207 |
+
&& $is_current_view
|
208 |
+
&& $this->plugin->settings()->current_user_can( 'edit' ) // Have permission to edit plugin settings.
|
209 |
) {
|
210 |
if ( ! is_multisite() || ( is_multisite() && is_network_admin() ) ) :
|
211 |
?>
|
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' ), true ) ) {
|
235 |
// Grab list of installed plugins.
|
236 |
$all_plugins = get_plugins();
|
237 |
$plugin_filenames = array();
|
238 |
foreach ( $all_plugins as $plugin => $info ) {
|
239 |
+
$plugin_info = pathinfo( $plugin );
|
240 |
$plugin_filenames[] = $plugin_info['filename'];
|
241 |
}
|
242 |
|
244 |
$predefined_plugins = WSAL_PluginInstallAndActivate::get_installable_plugins();
|
245 |
$predefined_plugins_check = array_column( $predefined_plugins, 'addon_for' );
|
246 |
|
247 |
+
// Loop through plugins and create an array of slugs, we will compare these against the plugins we have addons for.
|
248 |
$we_have_addon = array_intersect( $plugin_filenames, $predefined_plugins_check );
|
249 |
|
250 |
if ( isset( $we_have_addon ) && is_array( $we_have_addon ) ) {
|
251 |
|
252 |
foreach ( $we_have_addon as $addon ) {
|
253 |
+
$addon_slug = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'plugin_slug' ) ); // phpcs:ignore
|
254 |
$is_addon_installed = WpSecurityAuditLog::is_plugin_active( $addon_slug );
|
255 |
if ( $is_addon_installed ) {
|
256 |
continue;
|
257 |
}
|
258 |
|
259 |
+
$is_dismissed = $this->plugin->get_global_setting( $addon . '_addon_available_notice_dismissed' );
|
260 |
|
261 |
if ( ! $is_dismissed ) {
|
262 |
+
// @codingStandardsIgnoreStart
|
263 |
$image_filename = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'image_filename' ) );
|
264 |
$title = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'title' ) );
|
265 |
$plugin_description = array_search( $addon, array_column( $predefined_plugins, 'addon_for', 'plugin_description' ) );
|
266 |
+
// @codingStandardsIgnoreEnd
|
267 |
?>
|
268 |
<div class="notice notice-information is-dismissible notice-addon-available" id="wsal-notice-addon-available-<?php echo esc_attr( $addon ); ?>" data-addon="<?php echo esc_attr( $addon ); ?>">
|
269 |
<div class="addon-logo-wrapper">
|
278 |
esc_html__( 'installed.', 'wp-security-audit-log' ),
|
279 |
esc_html( $plugin_description ),
|
280 |
esc_html__( 'Install extension', 'wp-security-audit-log' ),
|
281 |
+
$this->get_third_party_plugins_tab_url() // phpcs:ignore
|
282 |
);
|
283 |
?>
|
284 |
<?php wp_nonce_field( 'wsal_dismiss_notice_addon_available_' . $addon, 'wsal-dismiss-notice-addon-available-' . $addon, false, true ); ?>
|
303 |
$post_array = filter_input_array( INPUT_POST, $post_array_args );
|
304 |
|
305 |
// Verify nonce.
|
306 |
+
if ( wp_verify_nonce( $post_array['nonce'], 'wsal_dismiss_notice_addon_available_' . $post_array['addon'] ) ) {
|
307 |
+
$this->plugin->set_global_setting( $post_array['addon'] . '_addon_available_notice_dismissed', true );
|
308 |
die();
|
309 |
}
|
310 |
die( 'Nonce verification failed!' );
|
312 |
|
313 |
|
314 |
/**
|
315 |
+
* {@inheritDoc}
|
316 |
*/
|
317 |
+
public function has_plugin_shortcut_link() {
|
318 |
return true;
|
319 |
}
|
320 |
|
321 |
/**
|
322 |
+
* {@inheritDoc}
|
323 |
*/
|
324 |
+
public function get_title() {
|
325 |
+
return esc_html__( 'Activity Log Viewer', 'wp-security-audit-log' );
|
326 |
}
|
327 |
|
328 |
/**
|
329 |
+
* {@inheritDoc}
|
330 |
*/
|
331 |
+
public function get_icon() {
|
332 |
+
return $this->wp_version < 3.8
|
333 |
+
? $this->plugin->get_base_url() . '/img/logo-main-menu.png'
|
334 |
: $this->get_icon_encoded();
|
335 |
}
|
336 |
|
337 |
/**
|
338 |
+
* Returns an encoded SVG string for the menu icon.
|
339 |
*
|
340 |
+
* @return string
|
|
|
|
|
341 |
*/
|
342 |
private function get_icon_encoded() {
|
343 |
return 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTEycHgiIGhlaWdodD0iMTEwcHgiIHZpZXdCb3g9IjAgMCAxMTIgMTEwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IHNrZXRjaHRvb2wgNTIuNiAoNjc0OTEpIC0gaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoIC0tPgogICAgPHRpdGxlPkE2QUQyNDUyLUZERDItNDIwQS05ODMzLTQ3QkJDOTlBQjEzNzwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggc2tldGNodG9vbC48L2Rlc2M+CiAgICA8ZyBpZD0iV1BTQUwtU2NyZWVucyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkN1c3RvbS1pY29ucyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMjQuMDAwMDAwLCAtNDYxLjAwMDAwMCkiIGZpbGw9IiNGRkZGRkYiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxnIGlkPSJDdXN0b20tSWNvbnMiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE1MS4wMDAwMDAsIDIyOC4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJMb2dvIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4MDcuMDAwMDAwLCAyMDQuNjY2NjY3KSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9IkF0b21zLS8taWNvbnMtLy1jdXN0b20tcmV2ZXJzZWQtYXVkaXQtbG9nIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg1Mi4wMDAwMDAsIDE1LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNzAuMDg0ODc0NSw3OC4zNjU1MDAyIEM3Ny44MDAwOTQyLDc4LjM2NTUwMDIgODQuMDU0OTE2MSw3Mi4xMTA2NzgxIDg0LjA1NDkxNjEsNjQuMzk0NTE5MiBDODQuMDU0OTE2MSw1Ni4xMTk1NTg2IDc2Ljg3Njg5NzUsNDkuNTk2MTM2IDY4LjU1MzEwMDYsNTAuNTExODE5NSBDNjkuMDMxMTM0Myw1MS45MjE1MDIzIDY5LjMwMjU1MjIsNTMuNDI2MDQwNiA2OS4zMDI1NTIyLDU0Ljk5NzI1OTQgQzY5LjMwMjU1MjIsNjIuMTk1MDAwNyA2My44NTcyODgzLDY4LjExNzM1OTMgNTYuODYyNDA2Myw2OC44Nzk5NTkyIEM1OC43MzMyMTc5LDc0LjM5Mjg0MjkgNjMuOTM5OTM0Niw3OC4zNjU1MDAyIDcwLjA4NDg3NDUsNzguMzY1NTAwMiBaIE03MC4wNDA3MzIyLDI1LjU3NzA1NTcgTDEwOC4yNzMwOTUsMjkuNjk5MDM5OCBDMTI0LjgyOTU5LDYzLjc3MDkxNTUgMTA2LjA0NTQwMiwxMDIuODE5NDEzIDY5Ljk4ODEzOTEsMTExLjUyNDUxIEM2OS41NDEwOTc4LDExMS40MTU1NjcgNjkuMTE5NDEzOCwxMTEuMjgzMTQ1IDY4LjY3ODAwNzUsMTExLjE2NzYyOCBMNjguNjc2MTI5Miw5My44NzIwMTIyIEM2OC42NzIzNzI1LDkzLjg3MjAxMjIgNjguNjY5NTU1LDkzLjg3MjAxMjIgNjguNjY1Nzk4NCw5My44NzIwMTIyIEM1My4wNzQ3NjI5LDkzLjEyOTEzNDYgNDAuNjE4NjUxNiw4MC4yMTE4OTM5IDQwLjYxODY1MTYsNjQuNDM4NjYgQzQwLjYxODY1MTYsNTQuOTA4MDM5MSA0Ny41ODI1NDEsMzYuMDA5MjcyNSA2OC42NjU3OTg0LDM1LjAwNjI0NyBDNjguNjY5NTU1LDM1LjAwNjI0NyA2OC42NzIzNzI1LDM1LjAwNTMwNzggNjguNjc2MTI5MiwzNS4wMDUzMDc4IEw2OC42ODE3NjQxLDI1LjcyOTIgQzY5LjczMTc0NzcsMjUuNjEwODY1NSA2OS44NTc1OTU1LDI1LjU5NDg5OTggNzAuMDQwNzMyMiwyNS41NzcwNTU3IFogTTExNC40MjkxMTksODEuNTc0NjE1NCBDMTIyLjYxMjA0MSw2My43NjgwOTU4IDEyMi4wNzAxNDUsNDMuMDc0NTkwOCAxMTIuOTg4NDQ0LDI0LjU2NjUxNjggTDcwLjAwMDE2MTEsMTkuODI2NTY0IEwyNy4wMTA5MzkyLDI0LjU2NjUxNjggQzE3LjkyOTIzODQsNDMuMDczNjUxNiAxNy4zODczNDE2LDYzLjc2NzE1NjYgMjUuNTcxMjAzMiw4MS41NzQ2MTU0IEMzMy43ODIzMDA1LDk5LjQ0MjE4MDcgNDkuOTUwOTIxMiwxMTIuNDc0OTM4IDcwLjAwMDE2MTEsMTE3LjQxNzc1IEM5MC4wNDk0MDEsMTEyLjQ3NDkzOCAxMDYuMjE4MDIyLDk5LjQ0MzExOTggMTE0LjQyOTExOSw4MS41NzQ2MTU0IFogTTExNy40NDEwMTQsMjAuNTMwOTM1NyBDMTI4LjAwNzUzLDQwLjk4MDI1OTIgMTI4LjgyODM1OCw2NC4xMTA4OTE0IDExOS42OTIxODYsODMuOTkyOTYwNyBDMTEwLjYzOTU5OSwxMDMuNjkwMDE1IDkyLjc3MTA5NDIsMTE3Ljk4NTk0NiA3MC42NjY5NjY3LDEyMy4yMTUyMDMgTDcwLjAwMDE2MTQsMTIzLjM3MjA0MyBMNjkuMzMzMzU2LDEyMy4yMTUyMDMgQzQ3LjIyOTIyODUsMTE3Ljk4NTk0NiAyOS4zNTk3ODQ1LDEwMy42OTAwMTUgMjAuMzA4MTM2OCw4My45OTI5NjA3IEMxMS4xNzE5NjQ1LDY0LjExMDg5MTQgMTEuOTkxODUzMyw0MC45NzkzMiAyMi41NTkzMDkyLDIwLjUzMDkzNTcgTDIzLjI3MjEzMzUsMTkuMTUyMjQ1MyBMNzAuMDAwMTYxNCwxNCBMMTE2LjcyODE4OSwxOS4xNTIyNDUzIEwxMTcuNDQxMDE0LDIwLjUzMDkzNTcgWiIgaWQ9ImN1c3RvbS1yZXZlcnNlZC1hdWRpdC1sb2ciPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==';
|
344 |
}
|
345 |
|
346 |
/**
|
347 |
+
* {@inheritDoc}
|
348 |
*/
|
349 |
+
public function get_name() {
|
350 |
+
return esc_html__( 'Log Viewer', 'wp-security-audit-log' );
|
351 |
}
|
352 |
|
353 |
/**
|
354 |
+
* {@inheritDoc}
|
355 |
*/
|
356 |
+
public function get_weight() {
|
357 |
return 1;
|
358 |
}
|
359 |
|
360 |
/**
|
361 |
* Method: Get View.
|
362 |
*/
|
363 |
+
protected function get_view() {
|
364 |
// Set page arguments.
|
365 |
if ( ! $this->page_args ) {
|
366 |
$this->page_args = new stdClass();
|
367 |
|
368 |
// @codingStandardsIgnoreStart
|
369 |
$this->page_args->page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : false;
|
370 |
+
$this->page_args->site_id = $this->plugin->settings()->get_view_site_id();
|
371 |
|
372 |
// Order arguments.
|
373 |
$this->page_args->order_by = isset( $_REQUEST['orderby'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ) : false;
|
380 |
}
|
381 |
|
382 |
// Set events listing view class.
|
383 |
+
if ( is_null( $this->view ) ) {
|
384 |
// Set the requested view based on POST or GET value. We only care
|
385 |
// if the view is 'grid' specifically.
|
386 |
$requested_view = $this->detect_view_type();
|
387 |
|
388 |
// If 'grid' is requested use it otherwise use list view by default.
|
389 |
if ( 'grid' !== $requested_view ) {
|
390 |
+
$this->view = new WSAL_AuditLogListView( $this->plugin, $this, $this->page_args );
|
391 |
} else {
|
392 |
+
$this->view = new WSAL_AuditLogGridView( $this->plugin, $this, $this->page_args );
|
393 |
}
|
394 |
|
395 |
// if the requested view didn't match the view users last viewed
|
399 |
$this->user_last_view = $requested_view;
|
400 |
}
|
401 |
}
|
402 |
+
return $this->view;
|
403 |
}
|
404 |
|
405 |
/**
|
422 |
* @method detect_view_type
|
423 |
* @since 4.0.0
|
424 |
* @return string
|
425 |
+
*
|
426 |
+
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
427 |
+
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
428 |
*/
|
429 |
public function detect_view_type() {
|
430 |
// First check if there is a GET/POST request for a specific view.
|
467 |
check_admin_referer( 'bulk-logs' );
|
468 |
}
|
469 |
|
470 |
+
$wpnonce = isset( $_GET['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ) : false; // View nonce.
|
471 |
+
$search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : false; // Search.
|
472 |
+
$site_id = isset( $_GET['wsal-cbid'] ) ? (int) sanitize_text_field( wp_unslash( $_GET['wsal-cbid'] ) ) : false; // Site id.
|
473 |
+
$search_save = ( isset( $_REQUEST['wsal-save-search-name'] ) && ! empty( $_REQUEST['wsal-save-search-name'] ) ) ? trim( sanitize_text_field( wp_unslash( $_REQUEST['wsal-save-search-name'] ) ) ) : false;
|
|
|
|
|
474 |
|
475 |
if ( ! empty( $wpnonce ) ) {
|
476 |
// Remove args array.
|
503 |
*
|
504 |
* @since 1.0.0
|
505 |
*/
|
506 |
+
public function render() {
|
507 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
508 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
509 |
}
|
510 |
|
513 |
check_admin_referer( 'bulk-logs' );
|
514 |
}
|
515 |
|
516 |
+
$this->get_view()->prepare_items();
|
517 |
+
$view_input_value = ( isset( $_GET['view'] ) && 'grid' === wp_unslash( $_GET['view'] ) ) ? 'grid' : 'list'; // phpcs:ignore
|
518 |
?>
|
519 |
<form id="audit-log-viewer" method="get">
|
520 |
<div id="audit-log-viewer-content">
|
521 |
<input type="hidden" name="page" value="<?php echo esc_attr( $this->page_args->page ); ?>" />
|
522 |
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr( empty( $this->page_args->site_id ) ? '0' : $this->page_args->site_id ); ?>" />
|
523 |
+
<input type="hidden" id="view" name="view" value="<?php echo esc_attr( $view_input_value ); ?>" />
|
524 |
<?php
|
525 |
/**
|
526 |
* Hook: `wsal_auditlog_before_view`
|
529 |
*
|
530 |
* @param WSAL_AuditLogListView $this->_view - Audit log view object.
|
531 |
*/
|
532 |
+
do_action( 'wsal_auditlog_before_view', $this->get_view() );
|
533 |
|
534 |
// Display the audit log list.
|
535 |
+
$this->get_view()->display();
|
536 |
|
537 |
/**
|
538 |
* Hook: `wsal_auditlog_after_view`
|
541 |
*
|
542 |
* @param WSAL_AuditLogListView $this->_view - Audit log view object.
|
543 |
*/
|
544 |
+
do_action( 'wsal_auditlog_after_view', $this->get_view() );
|
545 |
?>
|
546 |
</div>
|
547 |
</form>
|
548 |
|
549 |
<?php
|
550 |
if (
|
551 |
+
$this->plugin->settings()->current_user_can( 'edit' )
|
552 |
+
&& ! $this->plugin->get_global_boolean_setting( 'setup-complete', false )
|
553 |
+
&& ! $this->plugin->get_global_boolean_setting( 'setup-modal-dismissed', false )
|
554 |
) :
|
555 |
?>
|
556 |
<div data-remodal-id="wsal-setup-modal">
|
572 |
});
|
573 |
|
574 |
jQuery(document).on('closed', wsal_setup_modal, function () {
|
575 |
+
wsal_dismiss_setup_modal();
|
576 |
});
|
577 |
});
|
578 |
</script>
|
594 |
'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
|
595 |
),
|
596 |
'autorefresh' => array(
|
597 |
+
'enabled' => ! $is_search_view && $this->plugin->settings()->is_refresh_alerts_enabled(),
|
598 |
+
'token' => $this->plugin->settings()->is_infinite_scroll() ? $this->get_total_events() : $this->get_view()->get_total_items(),
|
599 |
),
|
600 |
)
|
601 |
);
|
610 |
* Ajax callback to display meta data inspector.
|
611 |
*/
|
612 |
public function AjaxInspector() {
|
613 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
614 |
die( 'Access Denied.' );
|
615 |
}
|
616 |
|
623 |
|
624 |
|
625 |
$occ = new WSAL_Models_Occurrence();
|
626 |
+
$occ->load( 'id = %d', array( (int) $get_array['occurrence'] ) );
|
627 |
+
$alert_meta = $occ->get_meta_array();
|
628 |
unset( $alert_meta['ReportText'] );
|
629 |
|
630 |
// Set WSAL_Ref class scripts and styles.
|
631 |
+
WSAL_Ref::config( 'stylePath', esc_url( $this->plugin->get_base_dir() ) . '/css/wsal-ref.css' );
|
632 |
+
WSAL_Ref::config( 'scriptPath', esc_url( $this->plugin->get_base_dir() ) . '/js/wsal-ref.js' );
|
633 |
|
634 |
echo '<!DOCTYPE html><html><head>';
|
635 |
echo '<style type="text/css">';
|
644 |
/**
|
645 |
* Ajax callback to refresh the view.
|
646 |
*/
|
647 |
+
public function ajax_refresh() {
|
648 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
649 |
die( 'Access Denied.' );
|
650 |
}
|
651 |
|
663 |
|
664 |
// Check for new total number of alerts.
|
665 |
$occ = new WSAL_Models_Occurrence();
|
666 |
+
$new = (int) $occ->count();
|
667 |
|
668 |
+
// If the count is changed, then return the new count.
|
669 |
+
echo $old === $new ? 'false' : esc_html( $new );
|
670 |
die;
|
671 |
}
|
672 |
|
674 |
* Ajax callback to set number of alerts to
|
675 |
* show on a single page.
|
676 |
*/
|
677 |
+
public function ajax_set_items_per_page() {
|
678 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
679 |
die( 'Access Denied.' );
|
680 |
}
|
681 |
|
685 |
if ( ! isset( $post_array['count'] ) ) {
|
686 |
die( 'Count parameter expected.' );
|
687 |
}
|
688 |
+
$this->plugin->settings()->set_views_per_page( (int) $post_array['count'] );
|
689 |
die;
|
690 |
}
|
691 |
|
692 |
/**
|
693 |
* Ajax callback to search.
|
694 |
*/
|
695 |
+
public function ajax_search_site() {
|
696 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
697 |
die( 'Access Denied.' );
|
698 |
}
|
699 |
|
708 |
|
709 |
$search = $post_array['search'];
|
710 |
|
711 |
+
foreach ( $this->get_view()->get_sites() as $site ) {
|
712 |
if ( stripos( $site->blogname, $search ) !== false ) {
|
713 |
$grp1[] = $site;
|
714 |
} elseif ( stripos( $site->domain, $search ) !== false ) {
|
715 |
$grp2[] = $site;
|
716 |
}
|
717 |
}
|
718 |
+
die( json_encode( array_slice( $grp1 + $grp2, 0, 7 ) ) ); // phpcs:ignore
|
719 |
}
|
720 |
|
721 |
|
732 |
die();
|
733 |
}
|
734 |
|
735 |
+
// Get alert by id.
|
736 |
+
$alert_id = filter_input( INPUT_POST, 'alert_id', FILTER_SANITIZE_NUMBER_INT );
|
737 |
+
$alert = new WSAL_Models_Occurrence();
|
738 |
+
$alert->id = (int) $alert_id;
|
739 |
|
740 |
+
// Get users using alert meta.
|
741 |
+
$users = $alert->get_meta_value( 'Users', array() );
|
742 |
|
743 |
+
// Check if there are any users.
|
744 |
+
if ( ! empty( $users ) && is_array( $users ) ) {
|
745 |
+
// Prepare content.
|
746 |
+
$content = implode( ',', $users );
|
747 |
+
echo esc_html( $content );
|
748 |
+
} else {
|
749 |
+
echo esc_html__( 'No users found.', 'wp-security-audit-log' );
|
750 |
+
}
|
751 |
|
752 |
die();
|
753 |
}
|
754 |
|
755 |
/**
|
756 |
+
* Ajax callback to handle Freemius opt in/out.
|
757 |
*/
|
758 |
public function wsal_freemius_opt_in() {
|
759 |
// Die if not have access.
|
760 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
761 |
die( 'Access Denied.' );
|
762 |
}
|
763 |
|
795 |
wsal_freemius()->opt_in( false, false, false, false, false, false, false, false, $sites_data );
|
796 |
}
|
797 |
|
798 |
+
// Update Freemius state.
|
799 |
+
$this->plugin->set_global_setting( 'freemius_state', 'in', true );
|
800 |
} elseif ( 'no' === $choice ) {
|
801 |
if ( ! is_multisite() ) {
|
802 |
wsal_freemius()->skip_connection(); // Opt out.
|
804 |
wsal_freemius()->skip_connection( null, true ); // Opt out for all websites.
|
805 |
}
|
806 |
|
807 |
+
// Update Freemius state.
|
808 |
+
$this->plugin->set_global_setting( 'freemius_state', 'skipped', true );
|
809 |
}
|
810 |
|
811 |
echo wp_json_encode(
|
828 |
/**
|
829 |
* Method: Render header of the view.
|
830 |
*/
|
831 |
+
public function header() {
|
832 |
add_thickbox();
|
833 |
|
834 |
// Darktooltip styles.
|
835 |
wp_enqueue_style(
|
836 |
'darktooltip',
|
837 |
+
$this->plugin->get_base_url() . '/css/darktooltip.css',
|
838 |
array(),
|
839 |
'0.4.0'
|
840 |
);
|
841 |
|
842 |
// Remodal styles.
|
843 |
+
wp_enqueue_style( 'wsal-remodal', $this->plugin->get_base_url() . '/css/remodal.css', array(), '1.1.1' );
|
844 |
+
wp_enqueue_style( 'wsal-remodal-theme', $this->plugin->get_base_url() . '/css/remodal-default-theme.css', array(), '1.1.1.1' );
|
845 |
|
846 |
// Audit log styles.
|
847 |
wp_enqueue_style(
|
848 |
'auditlog',
|
849 |
+
$this->plugin->get_base_url() . '/css/auditlog.css',
|
850 |
array(),
|
851 |
+
filemtime( $this->plugin->get_base_dir() . '/css/auditlog.css' )
|
852 |
);
|
853 |
|
854 |
+
// Admin notices styles.
|
855 |
wp_enqueue_style(
|
856 |
'wsal_admin_notices',
|
857 |
+
$this->plugin->get_base_url() . '/css/admin-notices.css',
|
858 |
array(),
|
859 |
+
filemtime( $this->plugin->get_base_dir() . '/css/admin-notices.css' )
|
860 |
);
|
861 |
}
|
862 |
|
863 |
/**
|
864 |
+
* {@inheritDoc}
|
865 |
*/
|
866 |
+
public function footer() {
|
867 |
wp_enqueue_script( 'jquery' );
|
868 |
|
869 |
// Darktooltip js.
|
870 |
wp_enqueue_script(
|
871 |
'darktooltip', // Identifier.
|
872 |
+
$this->plugin->get_base_url() . '/js/jquery.darktooltip.js', // Script location.
|
873 |
array( 'jquery' ), // Depends on jQuery.
|
874 |
'0.4.0', // Script version.
|
875 |
true
|
878 |
// Remodal script.
|
879 |
wp_enqueue_script(
|
880 |
'wsal-remodal-js',
|
881 |
+
$this->plugin->get_base_url() . '/js/remodal.min.js',
|
882 |
array(),
|
883 |
'1.1.1',
|
884 |
true
|
890 |
// Audit log script.
|
891 |
wp_register_script(
|
892 |
'auditlog',
|
893 |
+
$this->plugin->get_base_url() . '/js/auditlog.js',
|
894 |
array(),
|
895 |
+
filemtime( $this->plugin->get_base_dir() . '/js/auditlog.js' ),
|
896 |
true
|
897 |
);
|
898 |
+
|
899 |
$audit_log_data = array(
|
900 |
'page' => isset( $this->page_args->page ) ? $this->page_args->page : false,
|
901 |
'siteId' => isset( $this->page_args->site_id ) ? $this->page_args->site_id : false,
|
904 |
'searchTerm' => isset( $this->page_args->search_term ) ? $this->page_args->search_term : false,
|
905 |
'searchFilters' => isset( $this->page_args->search_filters ) ? $this->page_args->search_filters : false,
|
906 |
'viewerNonce' => wp_create_nonce( 'wsal_auditlog_viewer_nonce' ),
|
907 |
+
'infiniteScroll' => $this->plugin->settings()->is_infinite_scroll(),
|
908 |
'userView' => ( in_array( $this->user_last_view, $this->supported_view_types(), true ) ) ? $this->user_last_view : 'list',
|
909 |
'installAddonStrings' => array(
|
910 |
+
'defaultButton' => esc_html__( 'Install and activate extension', 'wp-security-audit-log' ),
|
911 |
+
'installingText' => esc_html__( 'Installing extension', 'wp-security-audit-log' ),
|
912 |
+
'otherInstalling' => esc_html__( 'Other extension installing', 'wp-security-audit-log' ),
|
913 |
+
'addonInstalled' => esc_html__( 'Installed', 'wp-security-audit-log' ),
|
914 |
+
'installedReload' => esc_html__( 'Installed... reloading page', 'wp-security-audit-log' ),
|
915 |
+
'buttonError' => esc_html__( 'Problem enabling', 'wp-security-audit-log' ),
|
916 |
'msgError' => sprintf(
|
917 |
/* translators: 1 - an opening link tag, 2 - the closing tag. */
|
918 |
__( '<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.', 'wp-security-audit-log' ),
|
939 |
|
940 |
// Don't display notice if the wizard notice is showing.
|
941 |
if (
|
942 |
+
! $this->plugin->get_global_boolean_setting( 'setup-complete', false )
|
943 |
+
&& ! $this->plugin->get_global_boolean_setting( 'setup-modal-dismissed', false )
|
944 |
) {
|
945 |
return;
|
946 |
}
|
957 |
}
|
958 |
|
959 |
// Get dismissed pointers.
|
960 |
+
$dismissed = explode( ',', (string) $this->plugin->get_global_setting( 'dismissed-privacy-notice', true ) );
|
961 |
$valid_pointers = array();
|
962 |
|
963 |
// Check pointers and remove dismissed ones.
|
964 |
foreach ( $pointers as $pointer_id => $pointer ) {
|
965 |
// Sanity check.
|
966 |
if (
|
967 |
+
in_array( $pointer_id, $dismissed ) // phpcs:ignore
|
968 |
|| empty( $pointer )
|
969 |
|| empty( $pointer_id )
|
970 |
|| empty( $pointer['target'] )
|
989 |
// Add pointers script to queue. Add custom script.
|
990 |
wp_enqueue_script(
|
991 |
'auditlog-pointer',
|
992 |
+
$this->plugin->get_base_url() . '/js/auditlog-pointer.js',
|
993 |
array( 'wp-pointer' ),
|
994 |
+
filemtime( $this->plugin->get_base_dir() . '/js/auditlog-pointer.js' ),
|
995 |
true
|
996 |
);
|
997 |
|
1007 |
* @since 3.2
|
1008 |
*/
|
1009 |
public function register_privacy_pointer( $pointer ) {
|
1010 |
+
$is_current_view = $this->plugin->views->get_active_view() == $this; // phpcs:ignore
|
1011 |
if ( current_user_can( 'manage_options' ) && $is_current_view && ! isset( $pointer['wsal_privacy'] ) ) {
|
1012 |
$pointer['wsal_privacy'] = array(
|
1013 |
'target' => '#toplevel_page_wsal-auditlog .wp-first-item',
|
1014 |
'options' => array(
|
1015 |
'content' => sprintf(
|
1016 |
'<h3> %s </h3> <p> %s </p> <p><strong>%s</strong></p>',
|
1017 |
+
esc_html__( 'WordPress Activity Log', 'wp-security-audit-log' ),
|
1018 |
+
esc_html__( '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.', 'wp-security-audit-log' ),
|
1019 |
+
esc_html__( 'Thank you for using WP Activity Log', 'wp-security-audit-log' )
|
1020 |
),
|
1021 |
'position' => array(
|
1022 |
'edge' => 'left',
|
1035 |
*/
|
1036 |
public function wsal_dismiss_advert() {
|
1037 |
// Die if user does not have permission to dismiss.
|
1038 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
1039 |
echo wp_json_encode(
|
1040 |
array(
|
1041 |
'success' => false,
|
1061 |
// @codingStandardsIgnoreEnd
|
1062 |
|
1063 |
$advert = 2 === $advert ? '0' : $advert + 1;
|
1064 |
+
$this->plugin->set_global_setting( 'premium-advert', $advert );
|
1065 |
+
$set_transient_fn = $this->plugin->is_multisite() ? 'set_site_transient' : 'set_transient';
|
1066 |
$set_transient_fn( 'wsal-is-advert-dismissed', true, MONTH_IN_SECONDS );
|
1067 |
echo wp_json_encode(
|
1068 |
array(
|
1082 |
$pointer = sanitize_text_field( wp_unslash( $_POST['pointer'] ) );
|
1083 |
// @codingStandardsIgnoreEnd
|
1084 |
|
1085 |
+
if ( $pointer != sanitize_key( $pointer ) ) { // phpcs:ignore
|
1086 |
wp_die( 0 );
|
1087 |
}
|
1088 |
|
1089 |
+
$dismissed = array_filter( explode( ',', (string) $this->plugin->get_global_setting( 'dismissed-privacy-notice', true ) ) );
|
1090 |
|
1091 |
+
if ( in_array( $pointer, $dismissed ) ) { // phpcs:ignore
|
1092 |
wp_die( 0 );
|
1093 |
}
|
1094 |
|
1095 |
$dismissed[] = $pointer;
|
1096 |
$dismissed = implode( ',', $dismissed );
|
1097 |
|
1098 |
+
$this->plugin->set_global_setting( 'dismissed-privacy-notice', $dismissed );
|
1099 |
wp_die( 1 );
|
1100 |
}
|
1101 |
|
1102 |
/**
|
1103 |
+
* Infinite Scroll Events AJAX handler.
|
1104 |
*
|
1105 |
* @since 3.3.1.1
|
1106 |
*/
|
1107 |
public function infinite_scroll_events() {
|
1108 |
// Check user permissions.
|
1109 |
+
if ( ! $this->plugin->settings()->current_user_can( 'view' ) ) {
|
1110 |
die( esc_html__( 'Access Denied', 'wp-security-audit-log' ) );
|
1111 |
}
|
1112 |
|
1115 |
die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
1116 |
}
|
1117 |
|
1118 |
+
// Get $_POST arguments.
|
1119 |
+
$paged = isset( $_POST['page_number'] ) ? sanitize_text_field( wp_unslash( $_POST['page_number'] ) ) : 0;
|
1120 |
+
|
1121 |
+
// Query events.
|
1122 |
+
$events_query = $this->get_view()->query_events( $paged );
|
1123 |
+
if ( ! empty( $events_query['items'] ) ) {
|
1124 |
+
foreach ( $events_query['items'] as $event ) {
|
1125 |
+
$this->get_view()->single_row( $event );
|
1126 |
+
}
|
1127 |
+
}
|
1128 |
+
exit();
|
1129 |
}
|
1130 |
|
1131 |
/**
|
1135 |
*/
|
1136 |
public function get_total_events() {
|
1137 |
$occ = new WSAL_Models_Occurrence();
|
1138 |
+
return (int) $occ->count();
|
1139 |
}
|
1140 |
|
1141 |
/**
|
1145 |
*/
|
1146 |
public function dismiss_setup_modal() {
|
1147 |
// Die if user does not have permission to dismiss.
|
1148 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
1149 |
echo wp_json_encode(
|
1150 |
array(
|
1151 |
'success' => false,
|
1156 |
}
|
1157 |
|
1158 |
// Filter $_POST array for security.
|
1159 |
+
$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : false; // phpcs:ignore
|
|
|
|
|
1160 |
|
1161 |
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'wsal_dismiss_setup_modal' ) ) {
|
1162 |
// Nonce verification failed.
|
1169 |
die();
|
1170 |
}
|
1171 |
|
1172 |
+
$this->plugin->set_global_boolean_setting( 'setup-modal-dismissed', true, true );
|
1173 |
wp_send_json_success();
|
1174 |
}
|
1175 |
|
1176 |
|
1177 |
/**
|
1178 |
+
* Gets a URL to the UI tab listing third party plugins.
|
1179 |
+
*
|
1180 |
* @return string URL of the 3rd party extensions tab.
|
1181 |
+
* @since 4.3.2
|
1182 |
*/
|
1183 |
+
public function get_third_party_plugins_tab_url() {
|
1184 |
+
return esc_url( add_query_arg( 'page', 'wsal-togglealerts#tab-third-party-plugins', network_admin_url( 'admin.php' ) ) );
|
1185 |
+
}
|
1186 |
|
1187 |
/**
|
1188 |
* Builds HTML markup to display 3rd party extension teaser if there is a post type in the event meta data and the
|
1209 |
return $result;
|
1210 |
}
|
1211 |
|
1212 |
+
$result .= '<div class="extension-ad" style="border-color: transparent transparent ' . $extension->get_color() . ' transparent;">';
|
1213 |
+
$result .= '</div>';
|
1214 |
$plugin_name = $extension->get_plugin_name();
|
1215 |
$link_title = sprintf(
|
1216 |
+
esc_html__( 'Install the activity log extension for %1$s for more detailed logging of changes done in %2$s.', 'wp-security-audit-log' ), // phpcs:ignore
|
1217 |
$plugin_name,
|
1218 |
$plugin_name
|
1219 |
);
|
1220 |
+
$result .= '<a class="icon" title="' . $link_title . '" href="' . $this->get_third_party_plugins_tab_url() . '">';
|
1221 |
+
$result .= '<img src="' . $extension->get_plugin_icon_url() . '" />';
|
1222 |
+
$result .= '</div>';
|
1223 |
|
1224 |
return $result;
|
1225 |
}
|
classes/Views/EmailNotifications.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* WSAL email notifications page.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -17,63 +18,64 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
* Email Notifications Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
*
|
20 |
-
* @package
|
|
|
21 |
*/
|
22 |
class WSAL_Views_EmailNotifications extends WSAL_ExtensionPlaceholderView {
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
*/
|
27 |
-
public function
|
28 |
-
return
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
*
|
33 |
*/
|
34 |
-
public function
|
35 |
-
return
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
*/
|
41 |
-
public function
|
42 |
return 2;
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*/
|
48 |
-
public function
|
49 |
-
$title =
|
50 |
-
$description =
|
51 |
-
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->
|
52 |
$premium_list = array(
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
);
|
61 |
-
$subtext =
|
62 |
$screenshots = array(
|
63 |
array(
|
64 |
-
'desc' =>
|
65 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_1.png',
|
66 |
),
|
67 |
array(
|
68 |
-
'desc' =>
|
69 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_2.png',
|
70 |
),
|
71 |
array(
|
72 |
-
'desc' =>
|
73 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_3.png',
|
74 |
),
|
75 |
array(
|
76 |
-
'desc' =>
|
77 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_4.png',
|
78 |
),
|
79 |
);
|
4 |
*
|
5 |
* WSAL email notifications page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
18 |
* Email Notifications Add-On promo Page.
|
19 |
* Used only if the plugin is not activated.
|
20 |
*
|
21 |
+
* @package wsal
|
22 |
+
* @subpackage views
|
23 |
*/
|
24 |
class WSAL_Views_EmailNotifications extends WSAL_ExtensionPlaceholderView {
|
25 |
|
26 |
/**
|
27 |
+
* {@inheritDoc}
|
28 |
*/
|
29 |
+
public function get_title() {
|
30 |
+
return esc_html__( 'Notifications Extension', 'wp-security-audit-log' );
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* {@inheritDoc}
|
35 |
*/
|
36 |
+
public function get_name() {
|
37 |
+
return esc_html__( 'Email Notifications ⇪', 'wp-security-audit-log' );
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* {@inheritDoc}
|
42 |
*/
|
43 |
+
public function get_weight() {
|
44 |
return 2;
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* {@inheritDoc}
|
49 |
*/
|
50 |
+
public function render() {
|
51 |
+
$title = esc_html__( 'Email & SMS Notifications', 'wp-security-audit-log' );
|
52 |
+
$description = esc_html__( 'Get instantly alerted of important changes on your site via email notifications & SMS messages. Upgrade to premium and:', 'wp-security-audit-log' );
|
53 |
+
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->get_safe_view_name() . '.jpg';
|
54 |
$premium_list = array(
|
55 |
+
esc_html__( 'Configure any type of email notification', 'wp-security-audit-log' ),
|
56 |
+
esc_html__( 'Configure SMS messages for instant critical alerts', 'wp-security-audit-log' ),
|
57 |
+
esc_html__( 'Receive notifications for when users login, change their password or change content', 'wp-security-audit-log' ),
|
58 |
+
esc_html__( 'Get alerted of site changes like plugin installs, theme changes etc', 'wp-security-audit-log' ),
|
59 |
+
esc_html__( 'Enable built-in security email notifications of suspicious user activity', 'wp-security-audit-log' ),
|
60 |
+
esc_html__( 'Personalize all email and SMS templates', 'wp-security-audit-log' ),
|
61 |
+
esc_html__( 'Use the trigger builder to configure any type of notification criteria!', 'wp-security-audit-log' ),
|
62 |
);
|
63 |
+
$subtext = esc_html__( 'Getting started is really easy. You can use one of the plugin’s built-in notifications or create your own using the easy to use trigger builder.', 'wp-security-audit-log' );
|
64 |
$screenshots = array(
|
65 |
array(
|
66 |
+
'desc' => esc_html__( 'Email and SMS notifications instantly alert you of important changes on your WordPress site.', 'wp-security-audit-log' ),
|
67 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_1.png',
|
68 |
),
|
69 |
array(
|
70 |
+
'desc' => esc_html__( 'Easily enable any of the built-in security and user management notifications.', 'wp-security-audit-log' ),
|
71 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_2.png',
|
72 |
),
|
73 |
array(
|
74 |
+
'desc' => esc_html__( 'Use the trigger builder to configure any type of email and SMS notification to get instantly alerted of site changes that are important to you and your business.', 'wp-security-audit-log' ),
|
75 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_3.png',
|
76 |
),
|
77 |
array(
|
78 |
+
'desc' => esc_html__( 'All email and SMS templates are configurable, allowing you to personalize them.', 'wp-security-audit-log' ),
|
79 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/notifications/notifications_4.png',
|
80 |
),
|
81 |
);
|
classes/Views/ExternalDB.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* WSAL external db page.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -17,56 +18,57 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
* External DB Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
*
|
20 |
-
* @package
|
|
|
21 |
*/
|
22 |
class WSAL_Views_ExternalDB extends WSAL_ExtensionPlaceholderView {
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
*/
|
27 |
-
public function
|
28 |
-
return
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
*
|
33 |
*/
|
34 |
-
public function
|
35 |
-
return
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
*/
|
41 |
-
public function
|
42 |
return 10;
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*/
|
48 |
-
public function
|
49 |
-
$title =
|
50 |
-
$description =
|
51 |
-
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->
|
52 |
$premium_list = array(
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
);
|
58 |
$subtext = false;
|
59 |
$screenshots = array(
|
60 |
array(
|
61 |
-
'desc' =>
|
62 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/external-db/db_integrations_1.png',
|
63 |
),
|
64 |
array(
|
65 |
-
'desc' =>
|
66 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/external-db/db_integrations_2.png',
|
67 |
),
|
68 |
array(
|
69 |
-
'desc' =>
|
70 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/external-db/db_integrations_3.png',
|
71 |
),
|
72 |
);
|
4 |
*
|
5 |
* WSAL external db page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
18 |
* External DB Add-On promo Page.
|
19 |
* Used only if the plugin is not activated.
|
20 |
*
|
21 |
+
* @package wsal
|
22 |
+
* @subpackage views
|
23 |
*/
|
24 |
class WSAL_Views_ExternalDB extends WSAL_ExtensionPlaceholderView {
|
25 |
|
26 |
/**
|
27 |
+
* {@inheritDoc}
|
28 |
*/
|
29 |
+
public function get_title() {
|
30 |
+
return esc_html__( 'External DB Extension', 'wp-security-audit-log' );
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* {@inheritDoc}
|
35 |
*/
|
36 |
+
public function get_name() {
|
37 |
+
return esc_html__( 'Integrations ⇪', 'wp-security-audit-log' );
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* {@inheritDoc}
|
42 |
*/
|
43 |
+
public function get_weight() {
|
44 |
return 10;
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* {@inheritDoc}
|
49 |
*/
|
50 |
+
public function render() {
|
51 |
+
$title = esc_html__( 'Activity log database & integration tools', 'wp-security-audit-log' );
|
52 |
+
$description = esc_html__( 'There are several benefits to segregating the logs from the main site database, and to be able to mirror the logs to third party and centralized business solutions. Upgrade to premium and:', 'wp-security-audit-log' );
|
53 |
+
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->get_safe_view_name() . '.jpg';
|
54 |
$premium_list = array(
|
55 |
+
esc_html__( 'Store the audit logs of your sites on an external database', 'wp-security-audit-log' ),
|
56 |
+
esc_html__( 'Configuring archiving and store older log data in a segregated database', 'wp-security-audit-log' ),
|
57 |
+
esc_html__( 'Mirror the logs to syslog, Slack, Papertrail and central business communication services', 'wp-security-audit-log' ),
|
58 |
+
esc_html__( 'Configure filters to filter what is mirrored and archived in the databases and services', 'wp-security-audit-log' ),
|
59 |
);
|
60 |
$subtext = false;
|
61 |
$screenshots = array(
|
62 |
array(
|
63 |
+
'desc' => esc_html__( 'Easily configure integration and database connections thanks to a user friendly wizard.', 'wp-security-audit-log' ),
|
64 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/external-db/db_integrations_1.png',
|
65 |
),
|
66 |
array(
|
67 |
+
'desc' => esc_html__( 'Configure activity log filters for third party services connections.', 'wp-security-audit-log' ),
|
68 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/external-db/db_integrations_2.png',
|
69 |
),
|
70 |
array(
|
71 |
+
'desc' => esc_html__( 'Configure an unlimited number of connections to different databases and third party services.', 'wp-security-audit-log' ),
|
72 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/external-db/db_integrations_3.png',
|
73 |
),
|
74 |
);
|
classes/Views/Help.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* WSAL help page.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -19,7 +20,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
19 |
* - Plugin Support
|
20 |
* - Plugin Documentation
|
21 |
*
|
22 |
-
* @package
|
|
|
23 |
*/
|
24 |
class WSAL_Views_Help extends WSAL_AbstractView {
|
25 |
|
@@ -39,6 +41,8 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
39 |
|
40 |
/**
|
41 |
* Constructor.
|
|
|
|
|
42 |
*/
|
43 |
public function __construct( $plugin ) {
|
44 |
parent::__construct( $plugin );
|
@@ -52,30 +56,31 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
52 |
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : false; // phpcs:ignore
|
53 |
|
54 |
// Verify that the current page is WSAL settings page.
|
55 |
-
if ( empty( $page ) || $this->
|
56 |
return;
|
57 |
}
|
58 |
|
59 |
// Tab links.
|
60 |
$wsal_help_tabs = array(
|
61 |
-
'help'
|
62 |
-
'name' =>
|
63 |
-
'link' => $this->
|
64 |
'render' => array( $this, 'tab_help' ),
|
65 |
'priority' => 10,
|
66 |
),
|
67 |
);
|
68 |
|
69 |
-
if ( $this->
|
70 |
$wsal_help_tabs['contact'] = array(
|
71 |
-
'name' =>
|
72 |
-
'link' => add_query_arg( 'tab', 'contact', $this->
|
73 |
'render' => array( $this, 'tab_contact_us' ),
|
74 |
'priority' => 15,
|
75 |
);
|
|
|
76 |
$wsal_help_tabs['system-info'] = array(
|
77 |
-
'name' =>
|
78 |
-
'link' => add_query_arg( 'tab', 'system-info', $this->
|
79 |
'render' => array( $this, 'tab_system_info' ),
|
80 |
'priority' => 20,
|
81 |
);
|
@@ -107,50 +112,50 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
107 |
}
|
108 |
|
109 |
/**
|
110 |
-
*
|
111 |
*/
|
112 |
-
public function
|
113 |
-
return
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
-
*
|
118 |
*/
|
119 |
-
public function
|
120 |
return 'dashicons-sos';
|
121 |
}
|
122 |
|
123 |
/**
|
124 |
-
*
|
125 |
*/
|
126 |
-
public function
|
127 |
-
return
|
128 |
}
|
129 |
|
130 |
/**
|
131 |
-
*
|
132 |
*/
|
133 |
-
public function
|
134 |
return 10;
|
135 |
}
|
136 |
|
137 |
/**
|
138 |
-
*
|
139 |
*/
|
140 |
-
public function
|
141 |
wp_enqueue_style(
|
142 |
'extensions',
|
143 |
-
$this->
|
144 |
array(),
|
145 |
-
filemtime( $this->
|
146 |
);
|
147 |
}
|
148 |
|
149 |
/**
|
150 |
-
*
|
151 |
*/
|
152 |
-
public function
|
153 |
-
$can_current_user_edit = $this->
|
154 |
?>
|
155 |
<nav id="wsal-tabs" class="nav-tab-wrapper">
|
156 |
<?php
|
@@ -206,9 +211,7 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
206 |
<?php esc_html_e( 'Refer to the list of WordPress security events for a complete list of Events and IDs that the plugin uses to keep a log of all the changes in the WordPress activity log.', 'wp-security-audit-log' ); ?>
|
207 |
</p><p>
|
208 |
<a class="button" rel="noopener noreferrer" href="https://wpactivitylog.com/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+website" target="_blank"><?php esc_html_e( 'Plugin Website', 'wp-security-audit-log' ); ?></a>
|
209 |
-
|
210 |
<a class="button" rel="noopener noreferrer" href="https://wpactivitylog.com/support/kb/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=knowledge+base" target="_blank"><?php esc_html_e( 'Knowledge Base', 'wp-security-audit-log' ); ?></a>
|
211 |
-
|
212 |
<a class="button" rel="noopener noreferrer" href="https://wpactivitylog.com/support/kb/list-wordpress-activity-log-event-ids/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=list+events" target="_blank"><?php esc_html_e( 'List of activity logs event IDs', 'wp-security-audit-log' ); ?></a>
|
213 |
</p>
|
214 |
</div>
|
@@ -247,13 +250,13 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
247 |
left: 0 !important;
|
248 |
}
|
249 |
.fs-full-size-wrapper {
|
250 |
-
|
251 |
}
|
252 |
</style>
|
253 |
<?php
|
254 |
$freemius_id = wsal_freemius()->get_id();
|
255 |
-
$vars
|
256 |
-
echo fs_get_template( 'contact.php', $vars );
|
257 |
}
|
258 |
|
259 |
/**
|
@@ -279,31 +282,31 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
279 |
$plugins_data = array(
|
280 |
array(
|
281 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/wp-2fa-img.jpg',
|
282 |
-
'desc' =>
|
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' =>
|
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' =>
|
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(
|
299 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/website-file-changes-monitor.jpg',
|
300 |
-
'desc' =>
|
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' =>
|
307 |
'alt' => 'Activity Log for MainWP',
|
308 |
'link' => 'https://wpactivitylog.com/extensions/mainwp-activity-log/?utm_source=plugin&utm_medium=referral&utm_campaign=AL4MWP&utm_content=WSAL+banner',
|
309 |
),
|
@@ -334,7 +337,6 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
334 |
* Method: Get system information.
|
335 |
*
|
336 |
* @return string - System information.
|
337 |
-
* @throws Freemius_Exception
|
338 |
*/
|
339 |
public function get_sysinfo() {
|
340 |
// System info.
|
@@ -359,11 +361,11 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
359 |
|
360 |
// Get theme info.
|
361 |
$theme_data = wp_get_theme();
|
362 |
-
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
363 |
-
$parent_theme = $theme_data->Template;
|
364 |
if ( ! empty( $parent_theme ) ) {
|
365 |
$parent_theme_data = wp_get_theme( $parent_theme );
|
366 |
-
$parent_theme = $parent_theme_data->Name . ' ' . $parent_theme_data->Version;
|
367 |
}
|
368 |
|
369 |
// Language information.
|
@@ -410,18 +412,15 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
410 |
// WordPress active plugins.
|
411 |
$sysinfo .= "\n" . '-- WordPress Active Plugins --' . "\n\n";
|
412 |
|
413 |
-
$plugins
|
414 |
-
$active_plugins
|
415 |
-
|
416 |
foreach ( $plugins as $plugin_path => $plugin ) {
|
417 |
-
if ( ! in_array( $plugin_path, $active_plugins ) ) {
|
418 |
continue;
|
419 |
}
|
420 |
|
421 |
-
if (
|
422 |
-
'WP Activity Log' === $plugin['Name']
|
423 |
-
&& wsal_freemius()->can_use_premium_code()
|
424 |
-
) {
|
425 |
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
|
426 |
$sysinfo .= $plugin['Name'] . ' Premium: ' . $plugin['Version'] . $update . "\n";
|
427 |
} else {
|
@@ -434,14 +433,11 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
434 |
$sysinfo .= "\n" . '-- WordPress Inactive Plugins --' . "\n\n";
|
435 |
|
436 |
foreach ( $plugins as $plugin_path => $plugin ) {
|
437 |
-
if ( in_array( $plugin_path, $active_plugins ) ) {
|
438 |
continue;
|
439 |
}
|
440 |
|
441 |
-
if (
|
442 |
-
'WP Activity Log' === $plugin['Name']
|
443 |
-
&& wsal_freemius()->can_use_premium_code()
|
444 |
-
) {
|
445 |
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
|
446 |
$sysinfo .= $plugin['Name'] . ' Premium: ' . $plugin['Version'] . $update . "\n";
|
447 |
} else {
|
@@ -464,10 +460,7 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
464 |
continue;
|
465 |
}
|
466 |
|
467 |
-
if (
|
468 |
-
'WP Activity Log' === $plugin['Name']
|
469 |
-
&& wsal_freemius()->can_use_premium_code()
|
470 |
-
) {
|
471 |
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
|
472 |
$plugin = get_plugin_data( $plugin_path );
|
473 |
$sysinfo .= $plugin['Name'] . ' Premium: ' . $plugin['Version'] . $update . "\n";
|
@@ -503,7 +496,7 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
503 |
|
504 |
// WSAL options.
|
505 |
$sysinfo .= "\n" . '-- WSAL Options --' . "\n\n";
|
506 |
-
$options = $this->
|
507 |
|
508 |
if ( ! empty( $options ) && is_array( $options ) ) {
|
509 |
foreach ( $options as $option ) {
|
@@ -518,10 +511,10 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
518 |
}
|
519 |
|
520 |
/**
|
521 |
-
*
|
522 |
*/
|
523 |
-
public function
|
524 |
-
if ( 'system-info' === $this->current_tab && $this->
|
525 |
?>
|
526 |
<script>
|
527 |
/**
|
@@ -540,7 +533,7 @@ class WSAL_Views_Help extends WSAL_AbstractView {
|
|
540 |
element.style.display = 'none';
|
541 |
document.body.appendChild(element);
|
542 |
|
543 |
-
//
|
544 |
element.click();
|
545 |
|
546 |
// Remove temporary element.
|
4 |
*
|
5 |
* WSAL help page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
20 |
* - Plugin Support
|
21 |
* - Plugin Documentation
|
22 |
*
|
23 |
+
* @package wsal
|
24 |
+
* @subpackage views
|
25 |
*/
|
26 |
class WSAL_Views_Help extends WSAL_AbstractView {
|
27 |
|
41 |
|
42 |
/**
|
43 |
* Constructor.
|
44 |
+
*
|
45 |
+
* @param WpSecurityAuditLog $plugin Plugin instance.
|
46 |
*/
|
47 |
public function __construct( $plugin ) {
|
48 |
parent::__construct( $plugin );
|
56 |
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : false; // phpcs:ignore
|
57 |
|
58 |
// Verify that the current page is WSAL settings page.
|
59 |
+
if ( empty( $page ) || $this->get_safe_view_name() !== $page ) {
|
60 |
return;
|
61 |
}
|
62 |
|
63 |
// Tab links.
|
64 |
$wsal_help_tabs = array(
|
65 |
+
'help' => array(
|
66 |
+
'name' => esc_html__( 'Help', 'wp-security-audit-log' ),
|
67 |
+
'link' => $this->get_url(),
|
68 |
'render' => array( $this, 'tab_help' ),
|
69 |
'priority' => 10,
|
70 |
),
|
71 |
);
|
72 |
|
73 |
+
if ( $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
74 |
$wsal_help_tabs['contact'] = array(
|
75 |
+
'name' => esc_html__( 'Contact Us', 'wp-security-audit-log' ),
|
76 |
+
'link' => add_query_arg( 'tab', 'contact', $this->get_url() ),
|
77 |
'render' => array( $this, 'tab_contact_us' ),
|
78 |
'priority' => 15,
|
79 |
);
|
80 |
+
|
81 |
$wsal_help_tabs['system-info'] = array(
|
82 |
+
'name' => esc_html__( 'System Info', 'wp-security-audit-log' ),
|
83 |
+
'link' => add_query_arg( 'tab', 'system-info', $this->get_url() ),
|
84 |
'render' => array( $this, 'tab_system_info' ),
|
85 |
'priority' => 20,
|
86 |
);
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
+
* {@inheritDoc}
|
116 |
*/
|
117 |
+
public function get_title() {
|
118 |
+
return esc_html__( 'Help', 'wp-security-audit-log' );
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
+
* {@inheritDoc}
|
123 |
*/
|
124 |
+
public function get_icon() {
|
125 |
return 'dashicons-sos';
|
126 |
}
|
127 |
|
128 |
/**
|
129 |
+
* {@inheritDoc}
|
130 |
*/
|
131 |
+
public function get_name() {
|
132 |
+
return esc_html__( 'Help & Contact Us', 'wp-security-audit-log' );
|
133 |
}
|
134 |
|
135 |
/**
|
136 |
+
* {@inheritDoc}
|
137 |
*/
|
138 |
+
public function get_weight() {
|
139 |
return 10;
|
140 |
}
|
141 |
|
142 |
/**
|
143 |
+
* {@inheritDoc}
|
144 |
*/
|
145 |
+
public function header() {
|
146 |
wp_enqueue_style(
|
147 |
'extensions',
|
148 |
+
$this->plugin->get_base_url() . '/css/extensions.css',
|
149 |
array(),
|
150 |
+
filemtime( $this->plugin->get_base_dir() . '/css/extensions.css' )
|
151 |
);
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
+
* {@inheritDoc}
|
156 |
*/
|
157 |
+
public function render() {
|
158 |
+
$can_current_user_edit = $this->plugin->settings()->current_user_can( 'edit' );
|
159 |
?>
|
160 |
<nav id="wsal-tabs" class="nav-tab-wrapper">
|
161 |
<?php
|
211 |
<?php esc_html_e( 'Refer to the list of WordPress security events for a complete list of Events and IDs that the plugin uses to keep a log of all the changes in the WordPress activity log.', 'wp-security-audit-log' ); ?>
|
212 |
</p><p>
|
213 |
<a class="button" rel="noopener noreferrer" href="https://wpactivitylog.com/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+website" target="_blank"><?php esc_html_e( 'Plugin Website', 'wp-security-audit-log' ); ?></a>
|
|
|
214 |
<a class="button" rel="noopener noreferrer" href="https://wpactivitylog.com/support/kb/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=knowledge+base" target="_blank"><?php esc_html_e( 'Knowledge Base', 'wp-security-audit-log' ); ?></a>
|
|
|
215 |
<a class="button" rel="noopener noreferrer" href="https://wpactivitylog.com/support/kb/list-wordpress-activity-log-event-ids/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=list+events" target="_blank"><?php esc_html_e( 'List of activity logs event IDs', 'wp-security-audit-log' ); ?></a>
|
216 |
</p>
|
217 |
</div>
|
250 |
left: 0 !important;
|
251 |
}
|
252 |
.fs-full-size-wrapper {
|
253 |
+
margin: 10px 20px 0 2px !important;
|
254 |
}
|
255 |
</style>
|
256 |
<?php
|
257 |
$freemius_id = wsal_freemius()->get_id();
|
258 |
+
$vars = array( 'id' => $freemius_id );
|
259 |
+
echo fs_get_template( 'contact.php', $vars ); // phpcs:ignore
|
260 |
}
|
261 |
|
262 |
/**
|
282 |
$plugins_data = array(
|
283 |
array(
|
284 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/wp-2fa-img.jpg',
|
285 |
+
'desc' => esc_html__( 'Add an extra layer of security to your login pages with 2FA & require your users to use it.', 'wp-security-audit-log' ),
|
286 |
'alt' => 'WP 2FA',
|
287 |
'link' => 'https://wp2fa.io/?utm_source=plugin&utm_medium=referral&utm_campaign=WP2FA&utm_content=WSAL+banner',
|
288 |
),
|
289 |
array(
|
290 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/c4wp.jpg',
|
291 |
+
'desc' => esc_html__( 'Protect website forms & login pages from spambots & automated attacks.', 'wp-security-audit-log' ),
|
292 |
'alt' => 'Captcha 4WP',
|
293 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/captcha-plugin-wordpress/?utm_source=plugin&utm_medium=referral&utm_campaign=WP2FA&utm_content=WSAL+banner',
|
294 |
),
|
295 |
array(
|
296 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/password-policy-manager.jpg',
|
297 |
+
'desc' => esc_html__( 'Enforce strong password policies on WordPress', 'wp-security-audit-log' ),
|
298 |
'alt' => 'WPassword',
|
299 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/password-policy-manager-wordpress/?utm_source=plugin&utm_medium=referral&utm_campaign=PPMWP&utm_content=WSAL+banner',
|
300 |
),
|
301 |
array(
|
302 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/website-file-changes-monitor.jpg',
|
303 |
+
'desc' => esc_html__( 'Automatically identify unauthorized file changes on WordPress', 'wp-security-audit-log' ),
|
304 |
'alt' => 'Website File Changes Monitor',
|
305 |
'link' => 'https://www.wpwhitesecurity.com/wordpress-plugins/website-file-changes-monitor/?utm_source=plugin&utm_medium=referral&utm_campaign=WFCM&utm_content=WSAL+banner',
|
306 |
),
|
307 |
array(
|
308 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/help/activity-log-for-mainwp.jpg',
|
309 |
+
'desc' => esc_html__( 'See the child sites activity logs from the central MainWP dashboard', 'wp-security-audit-log' ),
|
310 |
'alt' => 'Activity Log for MainWP',
|
311 |
'link' => 'https://wpactivitylog.com/extensions/mainwp-activity-log/?utm_source=plugin&utm_medium=referral&utm_campaign=AL4MWP&utm_content=WSAL+banner',
|
312 |
),
|
337 |
* Method: Get system information.
|
338 |
*
|
339 |
* @return string - System information.
|
|
|
340 |
*/
|
341 |
public function get_sysinfo() {
|
342 |
// System info.
|
361 |
|
362 |
// Get theme info.
|
363 |
$theme_data = wp_get_theme();
|
364 |
+
$theme = $theme_data->Name . ' ' . $theme_data->Version; // phpcs:ignore
|
365 |
+
$parent_theme = $theme_data->Template; // phpcs:ignore
|
366 |
if ( ! empty( $parent_theme ) ) {
|
367 |
$parent_theme_data = wp_get_theme( $parent_theme );
|
368 |
+
$parent_theme = $parent_theme_data->Name . ' ' . $parent_theme_data->Version; // phpcs:ignore
|
369 |
}
|
370 |
|
371 |
// Language information.
|
412 |
// WordPress active plugins.
|
413 |
$sysinfo .= "\n" . '-- WordPress Active Plugins --' . "\n\n";
|
414 |
|
415 |
+
$plugins = get_plugins();
|
416 |
+
$active_plugins = get_option( 'active_plugins', array() );
|
417 |
+
$can_use_freemius_premium_code = wsal_freemius()->can_use_premium_code();
|
418 |
foreach ( $plugins as $plugin_path => $plugin ) {
|
419 |
+
if ( ! in_array( $plugin_path, $active_plugins ) ) { // phpcs:ignore
|
420 |
continue;
|
421 |
}
|
422 |
|
423 |
+
if ( 'WP Activity Log' === $plugin['Name'] && $can_use_freemius_premium_code ) {
|
|
|
|
|
|
|
424 |
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
|
425 |
$sysinfo .= $plugin['Name'] . ' Premium: ' . $plugin['Version'] . $update . "\n";
|
426 |
} else {
|
433 |
$sysinfo .= "\n" . '-- WordPress Inactive Plugins --' . "\n\n";
|
434 |
|
435 |
foreach ( $plugins as $plugin_path => $plugin ) {
|
436 |
+
if ( in_array( $plugin_path, $active_plugins ) ) { // phpcs:ignore
|
437 |
continue;
|
438 |
}
|
439 |
|
440 |
+
if ( 'WP Activity Log' === $plugin['Name'] && $can_use_freemius_premium_code ) {
|
|
|
|
|
|
|
441 |
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
|
442 |
$sysinfo .= $plugin['Name'] . ' Premium: ' . $plugin['Version'] . $update . "\n";
|
443 |
} else {
|
460 |
continue;
|
461 |
}
|
462 |
|
463 |
+
if ( 'WP Activity Log' === $plugin['Name'] && $can_use_freemius_premium_code ) {
|
|
|
|
|
|
|
464 |
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
|
465 |
$plugin = get_plugin_data( $plugin_path );
|
466 |
$sysinfo .= $plugin['Name'] . ' Premium: ' . $plugin['Version'] . $update . "\n";
|
496 |
|
497 |
// WSAL options.
|
498 |
$sysinfo .= "\n" . '-- WSAL Options --' . "\n\n";
|
499 |
+
$options = $this->plugin->settings()->get_plugin_settings();
|
500 |
|
501 |
if ( ! empty( $options ) && is_array( $options ) ) {
|
502 |
foreach ( $options as $option ) {
|
511 |
}
|
512 |
|
513 |
/**
|
514 |
+
* {@inheritDoc}
|
515 |
*/
|
516 |
+
public function footer() {
|
517 |
+
if ( 'system-info' === $this->current_tab && $this->plugin->settings()->current_user_can( 'edit' ) ) :
|
518 |
?>
|
519 |
<script>
|
520 |
/**
|
533 |
element.style.display = 'none';
|
534 |
document.body.appendChild(element);
|
535 |
|
536 |
+
// Simulate click on the element.
|
537 |
element.click();
|
538 |
|
539 |
// Remove temporary element.
|
classes/Views/LogInUsers.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* WSAL users sessions page.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -17,54 +18,55 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
* User Sessions Management Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
*
|
20 |
-
* @package
|
|
|
21 |
*/
|
22 |
class WSAL_Views_LogInUsers extends WSAL_ExtensionPlaceholderView {
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
*/
|
27 |
-
public function
|
28 |
-
return
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
*
|
33 |
*/
|
34 |
-
public function
|
35 |
-
return
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
*/
|
41 |
-
public function
|
42 |
return 7;
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*/
|
48 |
-
public function
|
49 |
-
$title =
|
50 |
-
$description =
|
51 |
-
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->
|
52 |
$subtext = false;
|
53 |
$premium_list = array(
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
);
|
61 |
$screenshots = array(
|
62 |
array(
|
63 |
-
'desc' =>
|
64 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/users-sessions-management/user_sessions_1.png',
|
65 |
),
|
66 |
array(
|
67 |
-
'desc' =>
|
68 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/users-sessions-management/user_sessions_2.png',
|
69 |
),
|
70 |
);
|
4 |
*
|
5 |
* WSAL users sessions page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
18 |
* User Sessions Management Add-On promo Page.
|
19 |
* Used only if the plugin is not activated.
|
20 |
*
|
21 |
+
* @package wsal
|
22 |
+
* @subpackage views
|
23 |
*/
|
24 |
class WSAL_Views_LogInUsers extends WSAL_ExtensionPlaceholderView {
|
25 |
|
26 |
/**
|
27 |
+
* {@inheritDoc}
|
28 |
*/
|
29 |
+
public function get_title() {
|
30 |
+
return esc_html__( 'User Sessions Management Extension', 'wp-security-audit-log' );
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* {@inheritDoc}
|
35 |
*/
|
36 |
+
public function get_name() {
|
37 |
+
return esc_html__( 'Logged In Users ⇪', 'wp-security-audit-log' );
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* {@inheritDoc}
|
42 |
*/
|
43 |
+
public function get_weight() {
|
44 |
return 7;
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
+
* {@inheritDoc}
|
49 |
*/
|
50 |
+
public function render() {
|
51 |
+
$title = esc_html__( 'Real-Time Users Sessions Management', 'wp-security-audit-log' );
|
52 |
+
$description = esc_html__( 'Better manage your users’ logins and sessions. Upgrade to premium and:', 'wp-security-audit-log' );
|
53 |
+
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->get_safe_view_name() . '.png';
|
54 |
$subtext = false;
|
55 |
$premium_list = array(
|
56 |
+
esc_html__( 'See who is logged in to your site', 'wp-security-audit-log' ),
|
57 |
+
esc_html__( 'When they logged in and from where', 'wp-security-audit-log' ),
|
58 |
+
esc_html__( 'The last change they have done in real-time', 'wp-security-audit-log' ),
|
59 |
+
esc_html__( 'Terminate any users’ session with a click of a button', 'wp-security-audit-log' ),
|
60 |
+
esc_html__( 'Limit or block multiple sessions for the same user', 'wp-security-audit-log' ),
|
61 |
+
esc_html__( 'Get alerted of multiple same user sessions', 'wp-security-audit-log' ),
|
62 |
);
|
63 |
$screenshots = array(
|
64 |
array(
|
65 |
+
'desc' => esc_html__( 'See who is logged in to your WordPress site and multisite network in real-time.', 'wp-security-audit-log' ),
|
66 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/users-sessions-management/user_sessions_1.png',
|
67 |
),
|
68 |
array(
|
69 |
+
'desc' => esc_html__( 'Limit, manage and block multiple same user sessions easily.', 'wp-security-audit-log' ),
|
70 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/users-sessions-management/user_sessions_2.png',
|
71 |
),
|
72 |
);
|
classes/Views/Reports.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* WSAL reports page.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -17,56 +18,57 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
* Reports Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
*
|
20 |
-
* @package
|
|
|
21 |
*/
|
22 |
class WSAL_Views_Reports extends WSAL_ExtensionPlaceholderView {
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
*/
|
27 |
-
public function
|
28 |
-
return
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
*
|
33 |
*/
|
34 |
-
public function
|
35 |
-
return
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
*/
|
41 |
-
public function
|
42 |
return 3;
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
* Page View.
|
47 |
*/
|
48 |
-
public function
|
49 |
-
$title =
|
50 |
-
$description =
|
51 |
-
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->
|
52 |
$premium_list = array(
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
);
|
58 |
-
$subtext =
|
59 |
$screenshots = array(
|
60 |
array(
|
61 |
-
'desc' =>
|
62 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/reports/reports_1.png',
|
63 |
),
|
64 |
array(
|
65 |
-
'desc' =>
|
66 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/reports/reports_2.png',
|
67 |
),
|
68 |
array(
|
69 |
-
'desc' =>
|
70 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/reports/reports_3.png',
|
71 |
),
|
72 |
);
|
4 |
*
|
5 |
* WSAL reports page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
18 |
* Reports Add-On promo Page.
|
19 |
* Used only if the plugin is not activated.
|
20 |
*
|
21 |
+
* @package wsal
|
22 |
+
* @subpackage views
|
23 |
*/
|
24 |
class WSAL_Views_Reports extends WSAL_ExtensionPlaceholderView {
|
25 |
|
26 |
/**
|
27 |
+
* {@inheritDoc}
|
28 |
*/
|
29 |
+
public function get_title() {
|
30 |
+
return esc_html__( 'Reports Extension', 'wp-security-audit-log' );
|
31 |
}
|
32 |
|
33 |
/**
|
34 |
+
* {@inheritDoc}
|
35 |
*/
|
36 |
+
public function get_name() {
|
37 |
+
return esc_html__( 'Create Reports ⇪', 'wp-security-audit-log' );
|
38 |
}
|
39 |
|
40 |
/**
|
41 |
+
* {@inheritDoc}
|
42 |
*/
|
43 |
+
public function get_weight() {
|
44 |
return 3;
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
* Page View.
|
49 |
*/
|
50 |
+
public function render() {
|
51 |
+
$title = esc_html__( 'Individual, Scheduled & Automated Reports', 'wp-security-audit-log' );
|
52 |
+
$description = esc_html__( 'Many are not fans of reports, however reports are vital in business. With them you can make informed decisions that allow you to improve user productivity and the business. Upgrade to Premium so you can:', 'wp-security-audit-log' );
|
53 |
+
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->get_safe_view_name() . '.jpg';
|
54 |
$premium_list = array(
|
55 |
+
esc_html__( 'Generate any type of user and site (in multisite) activity report', 'wp-security-audit-log' ),
|
56 |
+
esc_html__( 'Automate and schedule daily, weekly, monthly and quarterly reports', 'wp-security-audit-log' ),
|
57 |
+
esc_html__( 'Received reports automatically via email', 'wp-security-audit-log' ),
|
58 |
+
esc_html__( 'Create statistics reports about users’ views, logins, activity from IP addresses & more', 'wp-security-audit-log' ),
|
59 |
);
|
60 |
+
$subtext = esc_html__( 'Reports are vital to the success of your business and management of your site.', 'wp-security-audit-log' );
|
61 |
$screenshots = array(
|
62 |
array(
|
63 |
+
'desc' => esc_html__( 'Generate a HTML or CSV report.', 'wp-security-audit-log' ),
|
64 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/reports/reports_1.png',
|
65 |
),
|
66 |
array(
|
67 |
+
'desc' => esc_html__( 'Easily configure a criteria for your reports.', 'wp-security-audit-log' ),
|
68 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/reports/reports_2.png',
|
69 |
),
|
70 |
array(
|
71 |
+
'desc' => esc_html__( 'Schedule reports that are sent to you by email automatically.', 'wp-security-audit-log' ),
|
72 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/reports/reports_3.png',
|
73 |
),
|
74 |
);
|
classes/Views/Search.php
CHANGED
@@ -1,11 +1,10 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* View:
|
4 |
*
|
5 |
-
*
|
6 |
-
*
|
7 |
-
* @
|
8 |
-
* @package wsal
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -17,57 +16,58 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
17 |
* Search Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
*
|
20 |
-
* @package
|
|
|
21 |
*/
|
22 |
class WSAL_Views_Search extends WSAL_ExtensionPlaceholderView {
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
*/
|
27 |
-
public function
|
28 |
-
return
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
-
*
|
33 |
*/
|
34 |
-
public function
|
35 |
-
return
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
*/
|
41 |
-
public function
|
42 |
return 5;
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
*/
|
48 |
-
public function
|
49 |
-
$title =
|
50 |
-
$description =
|
51 |
-
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->
|
52 |
$premium_list = array(
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
);
|
59 |
$subtext = false;
|
60 |
$screenshots = array(
|
61 |
array(
|
62 |
-
'desc' =>
|
63 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/search/search_1.png',
|
64 |
),
|
65 |
array(
|
66 |
-
'desc' =>
|
67 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/search/search_2.png',
|
68 |
),
|
69 |
array(
|
70 |
-
'desc' =>
|
71 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/search/search_3.png',
|
72 |
),
|
73 |
);
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Search Add-On promo Page
|
4 |
*
|
5 |
+
* @since 1.0.0
|
6 |
+
* @package wsal
|
7 |
+
* @subpackage views
|
|
|
8 |
*/
|
9 |
|
10 |
// Exit if accessed directly.
|
16 |
* Search Add-On promo Page.
|
17 |
* Used only if the plugin is not activated.
|
18 |
*
|
19 |
+
* @package wsal
|
20 |
+
* @subpackage views
|
21 |
*/
|
22 |
class WSAL_Views_Search extends WSAL_ExtensionPlaceholderView {
|
23 |
|
24 |
/**
|
25 |
+
* {@inheritDoc}
|
26 |
*/
|
27 |
+
public function get_title() {
|
28 |
+
return esc_html__( 'Search Extension', 'wp-security-audit-log' );
|
29 |
}
|
30 |
|
31 |
/**
|
32 |
+
* {@inheritDoc}
|
33 |
*/
|
34 |
+
public function get_name() {
|
35 |
+
return esc_html__( 'Log Search ⇪', 'wp-security-audit-log' );
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
+
* {@inheritDoc}
|
40 |
*/
|
41 |
+
public function get_weight() {
|
42 |
return 5;
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
+
* {@inheritDoc}
|
47 |
*/
|
48 |
+
public function render() {
|
49 |
+
$title = esc_html__( 'Search & Filters for the Activity Log', 'wp-security-audit-log' );
|
50 |
+
$description = esc_html__( 'You can find all the information you want in the activity log, if you know what you are looking for and have the right tools. Upgrade to premium so you can:', 'wp-security-audit-log' );
|
51 |
+
$addon_img = trailingslashit( WSAL_BASE_URL ) . 'img/' . $this->get_safe_view_name() . '.jpg';
|
52 |
$premium_list = array(
|
53 |
+
esc_html__( 'Do text searches and use filters to fine tune the search results', 'wp-security-audit-log' ),
|
54 |
+
esc_html__( 'Easily find when and who did a specific change on your site', 'wp-security-audit-log' ),
|
55 |
+
esc_html__( 'Easily identify and track back suspicious user behaviour', 'wp-security-audit-log' ),
|
56 |
+
esc_html__( 'Search for the cause of a problem and ease troubleshooting', 'wp-security-audit-log' ),
|
57 |
+
esc_html__( 'Save search terms and filters for future use and improved productivity', 'wp-security-audit-log' ),
|
58 |
);
|
59 |
$subtext = false;
|
60 |
$screenshots = array(
|
61 |
array(
|
62 |
+
'desc' => esc_html__( 'Use the text search to find a specific change.', 'wp-security-audit-log' ),
|
63 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/search/search_1.png',
|
64 |
),
|
65 |
array(
|
66 |
+
'desc' => esc_html__( 'Configure any filter you need to fine tune the search results and find what you are looking for with much less effort.', 'wp-security-audit-log' ),
|
67 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/search/search_2.png',
|
68 |
),
|
69 |
array(
|
70 |
+
'desc' => esc_html__( 'Save search terms and filters to run the searches again in the future with just a single click.', 'wp-security-audit-log' ),
|
71 |
'img' => trailingslashit( WSAL_BASE_URL ) . 'img/search/search_3.png',
|
72 |
),
|
73 |
);
|
classes/Views/Settings.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Settings page of the plugin.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -18,7 +19,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
18 |
*
|
19 |
* Settings view class to handle settings page functions.
|
20 |
*
|
21 |
-
* @since
|
|
|
|
|
|
|
22 |
*/
|
23 |
class WSAL_Views_Settings extends WSAL_AbstractView {
|
24 |
|
@@ -55,11 +59,11 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
55 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
56 |
parent::__construct( $plugin );
|
57 |
add_action( 'admin_init', array( $this, 'setup_settings_tabs' ) );
|
58 |
-
add_action( 'wp_ajax_AjaxCheckSecurityToken', array( $this, '
|
59 |
-
add_action( 'wp_ajax_AjaxRunCleanup', array( $this, '
|
60 |
-
add_action( 'wp_ajax_AjaxGetAllUsers', array( $this, '
|
61 |
-
add_action( 'wp_ajax_AjaxGetAllRoles', array( $this, '
|
62 |
-
add_action( 'wp_ajax_AjaxGetAllCPT', array( $this, '
|
63 |
add_action( 'wp_ajax_wsal_reset_settings', array( $this, 'reset_settings' ) );
|
64 |
add_action( 'wp_ajax_wsal_purge_activity', array( $this, 'purge_activity' ) );
|
65 |
add_action( 'wp_ajax_wsal_ajax_get_all_severities', array( $this, 'ajax_get_all_severities' ) );
|
@@ -74,47 +78,45 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
74 |
* @since 3.4
|
75 |
*/
|
76 |
public function setup_settings_tabs() {
|
77 |
-
// @codingStandardsIgnoreStart
|
78 |
-
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : false;
|
79 |
-
// @codingStandardsIgnoreEnd
|
80 |
|
81 |
// Verify that the current page is WSAL settings page.
|
82 |
-
|
|
|
83 |
return;
|
84 |
}
|
85 |
|
86 |
// Tab links.
|
87 |
$wsal_setting_tabs = array(
|
88 |
'general' => array(
|
89 |
-
'name' =>
|
90 |
-
'link' => add_query_arg( 'tab', 'general', $this->
|
91 |
'render' => array( $this, 'tab_general' ),
|
92 |
'save' => array( $this, 'tab_general_save' ),
|
93 |
'priority' => 10,
|
94 |
),
|
95 |
'audit-log' => array(
|
96 |
-
'name' =>
|
97 |
-
'link' => add_query_arg( 'tab', 'audit-log', $this->
|
98 |
'render' => array( $this, 'tab_audit_log' ),
|
99 |
'save' => array( $this, 'tab_audit_log_save' ),
|
100 |
'priority' => 20,
|
101 |
),
|
102 |
'file-changes' => array(
|
103 |
-
'name' =>
|
104 |
-
'link' => add_query_arg( 'tab', 'file-changes', $this->
|
105 |
'render' => array( $this, 'tab_file_changes' ),
|
106 |
'priority' => 30,
|
107 |
),
|
108 |
'exclude-objects' => array(
|
109 |
-
'name' =>
|
110 |
-
'link' => add_query_arg( 'tab', 'exclude-objects', $this->
|
111 |
'render' => array( $this, 'tab_exclude_objects' ),
|
112 |
'save' => array( $this, 'tab_exclude_objects_save' ),
|
113 |
'priority' => 40,
|
114 |
),
|
115 |
'advanced-settings' => array(
|
116 |
-
'name' =>
|
117 |
-
'link' => add_query_arg( 'tab', 'advanced-settings', $this->
|
118 |
'render' => array( $this, 'tab_advanced_settings' ),
|
119 |
'save' => array( $this, 'tab_advanced_settings_save' ),
|
120 |
'priority' => 100,
|
@@ -152,37 +154,37 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
-
*
|
156 |
*/
|
157 |
-
public function
|
158 |
return true;
|
159 |
}
|
160 |
|
161 |
/**
|
162 |
-
*
|
163 |
*/
|
164 |
-
public function
|
165 |
-
return
|
166 |
}
|
167 |
|
168 |
/**
|
169 |
-
*
|
170 |
*/
|
171 |
-
public function
|
172 |
return 'dashicons-admin-generic';
|
173 |
}
|
174 |
|
175 |
/**
|
176 |
-
*
|
177 |
*/
|
178 |
-
public function
|
179 |
-
return
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
-
*
|
184 |
*/
|
185 |
-
public function
|
186 |
return 8;
|
187 |
}
|
188 |
|
@@ -191,8 +193,8 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
191 |
*
|
192 |
* @param string $token - Token type.
|
193 |
*/
|
194 |
-
protected function
|
195 |
-
return $this->
|
196 |
}
|
197 |
|
198 |
/**
|
@@ -200,9 +202,9 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
200 |
*
|
201 |
* @throws Exception - Unrecognized settings tab error.
|
202 |
*/
|
203 |
-
protected function
|
204 |
// Bail early if user does not have sufficient permissions to save.
|
205 |
-
if ( ! $this->
|
206 |
throw new Exception( esc_html__( 'Current user is not allowed to save settings.', 'wp-security-audit-log' ) );
|
207 |
}
|
208 |
// Call respective tab save functions if they are set. Nonce is already verified at this point.
|
@@ -216,8 +218,8 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
216 |
/**
|
217 |
* Method: Check security token.
|
218 |
*/
|
219 |
-
public function
|
220 |
-
if ( ! $this->
|
221 |
echo wp_json_encode(
|
222 |
array(
|
223 |
'success' => false,
|
@@ -256,7 +258,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
256 |
array(
|
257 |
'success' => true,
|
258 |
'token' => $token,
|
259 |
-
'tokenType' => esc_html( $this->
|
260 |
)
|
261 |
);
|
262 |
die();
|
@@ -265,26 +267,26 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
265 |
/**
|
266 |
* Method: Run cleanup.
|
267 |
*/
|
268 |
-
public function
|
269 |
-
if ( ! $this->
|
270 |
die( 'Access Denied.' );
|
271 |
}
|
272 |
|
273 |
-
$now = current_time( 'timestamp' ); //
|
274 |
-
$max_sdate = $this->
|
275 |
|
276 |
|
277 |
// Calculate limit timestamp.
|
278 |
$max_stamp = $now - ( strtotime( $max_sdate ) - $now );
|
279 |
|
280 |
$query = new WSAL_Models_OccurrenceQuery();
|
281 |
-
$query->
|
282 |
-
$query->
|
283 |
-
$results = $query->
|
284 |
$items = count( $results );
|
285 |
|
286 |
if ( $items ) {
|
287 |
-
$this->
|
288 |
}
|
289 |
|
290 |
if ( $archiving ) {
|
@@ -306,21 +308,21 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
306 |
'pruning' => 0,
|
307 |
);
|
308 |
}
|
309 |
-
wp_safe_redirect( add_query_arg( $redirect_args, $this->
|
310 |
}
|
311 |
exit;
|
312 |
}
|
313 |
|
314 |
/**
|
315 |
-
*
|
316 |
*/
|
317 |
-
public function
|
318 |
// Verify nonce if a form is submitted.
|
319 |
if ( isset( $_POST['_wpnonce'] ) ) {
|
320 |
check_admin_referer( 'wsal-settings' );
|
321 |
}
|
322 |
|
323 |
-
if ( ! $this->
|
324 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
325 |
}
|
326 |
|
@@ -329,21 +331,23 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
329 |
|
330 |
if ( isset( $_POST['submit'] ) ) {
|
331 |
try {
|
332 |
-
$this->
|
333 |
if ( 'sms-provider' === $this->current_tab && $section && 'test' === $section ) :
|
334 |
?>
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
<?php else : ?>
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
endif;
|
344 |
} catch ( Exception $ex ) {
|
345 |
?>
|
346 |
-
|
|
|
|
|
347 |
<?php
|
348 |
}
|
349 |
}
|
@@ -354,34 +358,33 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
354 |
|
355 |
if ( isset( $_GET['pruning'] ) && '1' === $_GET['pruning'] ) {
|
356 |
?>
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
<?php
|
361 |
} elseif ( isset( $_GET['pruning'] ) && '0' === $_GET['pruning'] ) {
|
362 |
?>
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
<?php
|
367 |
}
|
368 |
?>
|
369 |
-
|
370 |
<?php foreach ( $this->wsal_setting_tabs as $tab_id => $tab ) : ?>
|
371 |
-
|
372 |
<?php echo esc_html( $tab['name'] ); ?>
|
373 |
-
|
374 |
<?php endforeach; ?>
|
375 |
-
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
<?php wp_nonce_field( 'wsal-settings' ); ?>
|
381 |
|
382 |
-
|
383 |
-
|
384 |
-
<div class="nav-tabs">
|
385 |
<?php
|
386 |
if ( ! empty( $this->current_tab ) && ! empty( $this->wsal_setting_tabs[ $this->current_tab ]['render'] ) ) {
|
387 |
call_user_func( $this->wsal_setting_tabs[ $this->current_tab ]['render'] );
|
@@ -389,15 +392,16 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
389 |
call_user_func( $this->wsal_setting_tabs['general']['render'] );
|
390 |
}
|
391 |
?>
|
392 |
-
|
393 |
<?php
|
394 |
if ( 'sms-provider' === $this->current_tab && $section && 'test' === $section ) {
|
395 |
-
submit_button(
|
396 |
} else {
|
397 |
submit_button();
|
398 |
}
|
399 |
?>
|
400 |
-
|
|
|
401 |
<script type="text/javascript">
|
402 |
<!--
|
403 |
function delete_confirm(elementRef) {
|
@@ -439,19 +443,20 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
439 |
} );
|
440 |
// --></script>
|
441 |
<?php
|
|
|
442 |
}
|
443 |
|
444 |
/**
|
445 |
* Tab: `General`
|
446 |
*/
|
447 |
private function tab_general() {
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
?>
|
453 |
-
|
454 |
-
|
455 |
<?php
|
456 |
echo sprintf(
|
457 |
/* translators: Learn more link. */
|
@@ -459,156 +464,156 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
459 |
'<a href="https://wpactivitylog.com/features/search-filters-wordpress-activity-log/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . esc_html__( '(Premium feature)', 'wp-security-audit-log' ) . '</a>'
|
460 |
);
|
461 |
?>
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
<?php esc_html_e( 'Infinite Scroll (Recommended)', 'wp-security-audit-log' ); ?>
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
<?php esc_html_e( 'Pagination', 'wp-security-audit-log' ); ?>
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
<?php $are = $this->
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
<?php
|
516 |
echo sprintf(
|
517 |
/* translators: Max number of dashboard widget alerts. */
|
518 |
esc_html__( 'The events widget displays the latest %d security events in the dashboard and the admin bar notification displays the latest event.', 'wp-security-audit-log' ),
|
519 |
-
esc_html( $this->
|
520 |
);
|
521 |
?>
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
<?php $dwe = $this->
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
<?php
|
546 |
$disabled = '';
|
547 |
-
$label =
|
548 |
if ( wsal_freemius()->is_free_plan() ) {
|
549 |
$disabled = 'disabled';
|
550 |
-
$label =
|
551 |
}
|
552 |
?>
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
<?php $abn = $this->
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
<?php
|
573 |
$disabled = '';
|
574 |
-
$label =
|
575 |
if ( wsal_freemius()->is_free_plan() ) {
|
576 |
$disabled = 'disabled';
|
577 |
-
$label =
|
578 |
}
|
579 |
?>
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
<?php $abn_updates = $this->
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
<?php
|
610 |
// Get login page notification checkbox.
|
611 |
-
$wsal_lpn = $this->
|
612 |
if ( $wsal_lpn && 'true' === $wsal_lpn ) {
|
613 |
// If option exists, value is true then set to true.
|
614 |
$wsal_lpn = true;
|
@@ -620,16 +625,17 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
620 |
$wsal_lpn = false;
|
621 |
}
|
622 |
?>
|
623 |
-
|
624 |
-
|
625 |
<?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
|
626 |
-
|
627 |
-
|
628 |
<?php
|
629 |
// Get login page notification text.
|
630 |
-
$wsal_lpn_text
|
631 |
-
|
632 |
-
|
|
|
633 |
// Allowed HTML tags for this setting.
|
634 |
$allowed_tags = array(
|
635 |
'a' => array(
|
@@ -638,32 +644,33 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
638 |
'target' => array(),
|
639 |
),
|
640 |
);
|
|
|
641 |
?>
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
<?php echo ( $wsal_lpn ) ? false : 'disabled'; ?>
|
646 |
-
><?php echo
|
647 |
-
|
648 |
-
|
649 |
-
<?php echo wp_kses( __( '<strong>Note: </strong>', 'wp-security-audit-log' ), $this->
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
<?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
<?php
|
668 |
echo sprintf(
|
669 |
/* translators: Learn more link. */
|
@@ -671,38 +678,38 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
671 |
'<a href="https://wpactivitylog.com/support/kb/support-reverse-proxies-web-application-firewalls/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . esc_html__( 'learn more', 'wp-security-audit-log' ) . '</a>'
|
672 |
);
|
673 |
?>
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
<?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
<?php esc_html_e( 'Filter internal IP addresses from the proxy headers. Enable this option only if you are are still seeing the internal IP addresses of the firewall or proxy.', 'wp-security-audit-log' ); ?>
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
<?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
<?php
|
707 |
$allowed_tags = array(
|
708 |
'a' => array(
|
@@ -712,60 +719,53 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
712 |
);
|
713 |
echo wp_kses(
|
714 |
sprintf(
|
715 |
-
|
716 |
esc_html__( 'By default only users with administrator role (single site) and super administrator role (multisite) can change the settings of the plugin. Though you can restrict the privileges to just your user - %s.', 'wp-security-audit-log' ),
|
717 |
'<a href="https://wpactivitylog.com/support/kb/managing-wordpress-activity-log-plugin-privileges/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . __( 'learn more', 'wp-security-audit-log' ) . '</a>'
|
718 |
),
|
719 |
$allowed_tags
|
720 |
);
|
721 |
-
$restrict_settings = $this->
|
722 |
?>
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
<?php esc_html_e( 'Only me', 'wp-security-audit-log' ); ?>
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
<?php
|
738 |
-
if ( $this->
|
739 |
esc_html_e( 'All superadmins', 'wp-security-audit-log' );
|
740 |
} else {
|
741 |
esc_html_e( 'All administrators', 'wp-security-audit-log' );
|
742 |
}
|
743 |
?>
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
<?php
|
757 |
-
$
|
758 |
-
|
759 |
-
|
760 |
-
'target' => true,
|
761 |
-
),
|
762 |
-
);
|
763 |
-
$is_multisite = $this->_plugin->IsMultisite();
|
764 |
-
$section_label = '';
|
765 |
-
if ($is_multisite) {
|
766 |
-
$section_label = esc_html__('By default only super administrators and the child sites\' administrators can view the WordPress activity log. Though you can change this by using the setting below.', 'wp-security-audit-log');
|
767 |
} else {
|
768 |
-
$section_label = esc_html__('By default only users with administrator role can view the WordPress activity log. To allow someone who does not have an admin role to view the activity log, specify them in the below setting.', 'wp-security-audit-log');
|
769 |
}
|
770 |
|
771 |
echo wp_kses(
|
@@ -773,43 +773,42 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
773 |
$allowed_tags
|
774 |
);
|
775 |
?>
|
776 |
-
|
777 |
-
<?php if ( $is_multisite ): ?>
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
<?php
|
785 |
-
$restrict_settings
|
786 |
$viewer_restriction_options = array(
|
787 |
'only_me' => __( 'Only me', 'wp-security-audit-log' ),
|
788 |
'only_superadmins' => __( 'Super administators only', 'wp-security-audit-log' ),
|
789 |
'only_admins' => __( 'Super administators and site administrators', 'wp-security-audit-log' ),
|
790 |
);
|
791 |
?>
|
792 |
-
<?php foreach ( $viewer_restriction_options as $option => $label ): ?>
|
793 |
-
|
794 |
-
<?php $disabled = ('only_me' === $option && 'only_superadmins' === $restrict_settings); ?>
|
795 |
-
|
796 |
<?php echo esc_html( $label ); ?>
|
797 |
-
|
798 |
-
|
799 |
<?php endforeach; ?>
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
<?php endif; ?>
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
<tr>
|
811 |
-
|
812 |
-
<th><label for="ViewerQueryBox"><?php echo $row_label; ?></label></th>
|
813 |
<td>
|
814 |
<fieldset>
|
815 |
<label>
|
@@ -823,12 +822,12 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
823 |
|
824 |
<div id="ViewerList">
|
825 |
<?php
|
826 |
-
foreach ( $this->
|
827 |
if ( wp_get_current_user()->user_login === $item ) {
|
828 |
continue;
|
829 |
}
|
830 |
?>
|
831 |
-
<span class="sectoken-<?php echo esc_attr( $this->
|
832 |
<input type="hidden" name="Viewers[]" value="<?php echo esc_attr( $item ); ?>"/>
|
833 |
<?php echo esc_html( $item ); ?>
|
834 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
@@ -851,7 +850,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
851 |
<th><label for="FromEmail"><?php esc_html_e( 'From Email & Name', 'wp-security-audit-log' ); ?></label></th>
|
852 |
<td>
|
853 |
<fieldset>
|
854 |
-
<?php $use_email = $this->
|
855 |
<label for="default_email">
|
856 |
<input type="radio" name="use-email" id="default_email" value="default_email" <?php checked( $use_email, 'default_email' ); ?> />
|
857 |
<?php esc_html_e( 'Use the email address from the WordPress general settings', 'wp-security-audit-log' ); ?>
|
@@ -864,12 +863,12 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
864 |
<br>
|
865 |
<label for="FromEmail">
|
866 |
<?php esc_html_e( 'Email Address', 'wp-security-audit-log' ); ?>
|
867 |
-
<input type="email" id="FromEmail" name="FromEmail" value="<?php echo esc_attr( $this->
|
868 |
</label>
|
869 |
<br>
|
870 |
<label for="DisplayName">
|
871 |
<?php esc_html_e( 'Display Name', 'wp-security-audit-log' ); ?>
|
872 |
-
<input type="text" id="DisplayName" name="DisplayName" value="<?php echo esc_attr( $this->
|
873 |
</label>
|
874 |
</fieldset>
|
875 |
</td>
|
@@ -879,6 +878,9 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
879 |
</table>
|
880 |
<!-- From Email & Name -->
|
881 |
|
|
|
|
|
|
|
882 |
<h3><?php esc_html_e( 'Do you want to hide the plugin from the list of installed plugins?', 'wp-security-audit-log' ); ?></h3>
|
883 |
<p class="description"><?php esc_html_e( 'By default all installed plugins are listed in the plugins page. Set this option to Yes remove WP Activity Log from the list of installed plugins for users who are unable to access the WP Activity Log settings.', 'wp-security-audit-log' ); ?></p>
|
884 |
<table class="form-table wsal-tab">
|
@@ -886,14 +888,14 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
886 |
<tr>
|
887 |
<th><label for="incognito_yes"><?php esc_html_e( 'Hide Plugin in Plugins Page', 'wp-security-audit-log' ); ?></label></th>
|
888 |
<td>
|
889 |
-
|
890 |
<label for="incognito_yes">
|
891 |
-
<input type="radio" name="Incognito" value="yes" id="incognito_yes" <?php checked( $
|
892 |
<?php esc_html_e( 'Yes, hide the plugin and any WP Activity Log plugin extensions from the list of installed plugins', 'wp-security-audit-log' ); ?>
|
893 |
</label>
|
894 |
<br/>
|
895 |
<label for="incognito_no">
|
896 |
-
<input type="radio" name="Incognito" value="no" id="incognito_no" <?php checked( $
|
897 |
<?php esc_html_e( 'No, do not hide the plugin', 'wp-security-audit-log' ); ?>
|
898 |
</label>
|
899 |
</fieldset>
|
@@ -913,46 +915,45 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
913 |
// Get $_POST global array.
|
914 |
$post_array = filter_input_array( INPUT_POST );
|
915 |
|
916 |
-
$this->
|
917 |
-
$this->
|
918 |
-
$this->
|
919 |
-
$this->
|
920 |
-
$this->
|
921 |
-
|
922 |
-
$this->_plugin->settings()->SetWidgetsEnabled( sanitize_text_field( $post_array['EnableDashboardWidgets'] ) );
|
923 |
|
924 |
if ( ! wsal_freemius()->is_free_plan() ) {
|
925 |
-
$this->
|
926 |
-
$this->
|
927 |
}
|
928 |
|
929 |
-
//
|
930 |
-
if ($this->
|
931 |
$log_viewer_restrictions = isset( $post_array['restrict-log-viewer'] ) ? sanitize_text_field( $post_array['restrict-log-viewer'] ) : '';
|
932 |
-
$this->
|
933 |
if ( 'only_me' === $log_viewer_restrictions ) {
|
934 |
-
$this->
|
935 |
}
|
936 |
}
|
937 |
|
938 |
// Get plugin viewers.
|
939 |
$viewers = isset( $post_array['Viewers'] ) ? array_map( 'sanitize_text_field', $post_array['Viewers'] ) : array();
|
940 |
-
$this->
|
941 |
|
942 |
-
//
|
943 |
$restrict_settings = isset( $post_array['restrict-plugin-settings'] ) ? sanitize_text_field( $post_array['restrict-plugin-settings'] ) : false;
|
944 |
-
$this->
|
945 |
if ( 'only_me' === $restrict_settings ) {
|
946 |
-
$this->
|
947 |
}
|
948 |
|
949 |
-
$this->
|
950 |
-
$this->
|
951 |
-
$this->
|
952 |
-
$this->
|
953 |
|
954 |
$is_incognito = isset( $post_array['Incognito'] ) ? \WSAL\Helpers\Options::string_to_bool( sanitize_text_field( $post_array['Incognito'] ) ) : false;
|
955 |
-
$this->
|
956 |
}
|
957 |
|
958 |
/**
|
@@ -960,18 +961,18 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
960 |
*/
|
961 |
private function tab_audit_log() {
|
962 |
?>
|
963 |
-
|
964 |
-
|
965 |
<?php
|
966 |
esc_html_e( 'The plugin uses an efficient way to store the activity log data in the WordPress database, though the more data you keep the more disk space will be required. ', 'wp-security-audit-log' );
|
967 |
$retention_help_text = __( '<a href="https://wpactivitylog.com/pricing/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">Upgrade to Premium</a> to store the activity log data in an external database.', 'wp-security-audit-log' );
|
968 |
|
969 |
-
echo wp_kses( $retention_help_text, $this->
|
970 |
?>
|
971 |
-
|
972 |
|
973 |
<?php
|
974 |
-
// Ensure it
|
975 |
if ( ! wsal_freemius()->can_use_premium_code() ) {
|
976 |
$this->render_retention_settings_table();
|
977 |
}
|
@@ -986,7 +987,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
986 |
<td>
|
987 |
<fieldset>
|
988 |
<?php
|
989 |
-
$timezone = $this->
|
990 |
|
991 |
/**
|
992 |
* Transform timezone values.
|
@@ -1018,7 +1019,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1018 |
<th><?php esc_html_e( 'Show Milliseconds', 'wp-security-audit-log' ); ?></th>
|
1019 |
<td>
|
1020 |
<fieldset>
|
1021 |
-
<?php $show_milliseconds = $this->
|
1022 |
<label for="show_milliseconds">
|
1023 |
<input type="checkbox" name="show_milliseconds" id="show_milliseconds" style="margin-top: -2px;"
|
1024 |
<?php checked( $show_milliseconds ); ?> value="yes">
|
@@ -1040,7 +1041,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1040 |
<th><label for="timezone-default"><?php esc_html_e( 'User information in Activity log', 'wp-security-audit-log' ); ?></label></th>
|
1041 |
<td>
|
1042 |
<fieldset>
|
1043 |
-
<?php $type_username = $this->
|
1044 |
<label for="column_username">
|
1045 |
<input type="radio" name="type_username" id="column_username" style="margin-top: -2px;" <?php checked( $type_username, 'username' ); ?> value="username">
|
1046 |
<span><?php esc_html_e( 'WordPress username', 'wp-security-audit-log' ); ?></span>
|
@@ -1071,7 +1072,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1071 |
<th><label for="columns"><?php esc_html_e( 'Activity log columns selection', 'wp-security-audit-log' ); ?></label></th>
|
1072 |
<td>
|
1073 |
<fieldset>
|
1074 |
-
<?php $columns = $this->
|
1075 |
<?php foreach ( $columns as $key => $value ) { ?>
|
1076 |
<label for="columns">
|
1077 |
<input type="checkbox" name="Columns[<?php echo esc_attr( $key ); ?>]" id="<?php echo esc_attr( $key ); ?>" class="sel-columns" style="margin-top: -2px;"
|
@@ -1102,7 +1103,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1102 |
</table>
|
1103 |
<!-- Activity log columns -->
|
1104 |
|
1105 |
-
|
1106 |
<h3><?php esc_html_e( 'Do you want to keep a log of WordPress background activity?', 'wp-security-audit-log' ); ?></h3>
|
1107 |
<p class="description">
|
1108 |
<?php esc_html_e( 'WordPress does a lot of things in the background that you do not necessarily need to know about, such as; deletion of post revisions, deletion of auto saved drafts etc. By default the plugin does not report them since there might be a lot and are irrelevant to the user.', 'wp-security-audit-log' ); ?>
|
@@ -1144,17 +1145,17 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1144 |
$pruning_unit = isset( $post_array['pruning-unit'] ) ? sanitize_text_field( $post_array['pruning-unit'] ) : false;
|
1145 |
$pruning_date = ( ! empty( $pruning_date ) && ! empty( $pruning_unit ) ) ? $pruning_date . ' ' . $pruning_unit : false;
|
1146 |
|
1147 |
-
$this->
|
1148 |
-
$this->
|
1149 |
-
$this->
|
1150 |
-
$this->
|
1151 |
-
$this->
|
1152 |
-
$this->
|
1153 |
if ( ! empty( $post_array['Columns'] ) ) {
|
1154 |
-
$this->
|
1155 |
}
|
1156 |
-
$show_milliseconds =
|
1157 |
-
$this->
|
1158 |
}
|
1159 |
|
1160 |
/**
|
@@ -1168,15 +1169,14 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1168 |
<tr>
|
1169 |
<?php if ( ! defined( 'WFCM_PLUGIN_FILE' ) ) : ?>
|
1170 |
<div class="addon-wrapper" style="max-width: 380px; text-align: center; border: 1px solid #ccc; padding: 25px;">
|
1171 |
-
<img src="<?php echo trailingslashit( WSAL_BASE_URL ) . 'img/help/website-file-changes-monitor.jpg'; ?>">
|
1172 |
<h4><?php echo esc_html__( 'Website File Changes Monitor', 'wp-security-audit-log' ); ?></h4>
|
1173 |
<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>
|
1174 |
-
<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
|
1175 |
</div>
|
1176 |
<?php else : ?>
|
1177 |
<?php
|
1178 |
-
$
|
1179 |
-
$redirect_args = array(
|
1180 |
'page' => 'wfcm-file-changes',
|
1181 |
);
|
1182 |
if ( ! is_multisite() ) {
|
@@ -1210,8 +1210,8 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1210 |
<input type="button" id="ExUserQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1211 |
<br style="clear: both;"/>
|
1212 |
<div id="ExUserList">
|
1213 |
-
<?php foreach ( $this->
|
1214 |
-
<span class="sectoken-<?php echo esc_attr( $this->
|
1215 |
<input type="hidden" name="ExUsers[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1216 |
<?php echo esc_html( $item ); ?>
|
1217 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
@@ -1231,8 +1231,8 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1231 |
<input type="button" id="ExRoleQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1232 |
<br style="clear: both;"/>
|
1233 |
<div id="ExRoleList">
|
1234 |
-
<?php foreach ( $this->
|
1235 |
-
<span class="sectoken-<?php echo esc_attr( $this->
|
1236 |
<input type="hidden" name="ExRoles[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1237 |
<?php echo esc_html( $item ); ?>
|
1238 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
@@ -1252,89 +1252,100 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1252 |
<input type="button" id="IpAddrQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1253 |
<br style="clear: both;"/>
|
1254 |
<div id="IpAddrList">
|
1255 |
-
<?php foreach ( $this->
|
1256 |
-
<span class="sectoken-<?php echo esc_attr( $this->
|
1257 |
<input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1258 |
<?php echo esc_html( $item ); ?>
|
1259 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1260 |
</span>
|
1261 |
<?php endforeach; ?>
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
<?php foreach ( $this->
|
1278 |
-
|
1279 |
<input type="hidden" name="ExCPTss[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1280 |
<?php echo esc_html( $item ); ?>
|
1281 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1282 |
</span>
|
1283 |
<?php endforeach; ?>
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
|
|
1298 |
|
1299 |
<?php
|
1300 |
$this->renderMetaExclusionSection(
|
1301 |
esc_html__( 'Exclude custom user fields:', 'wp-security-audit-log' ),
|
1302 |
-
$this->
|
1303 |
'UserMeta'
|
1304 |
);
|
1305 |
-
|
|
|
1306 |
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
<?php
|
1311 |
}
|
1312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1313 |
private function renderMetaExclusionSection( $title, $values, $type ) {
|
|
|
1314 |
?>
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
<?php foreach ( $values as $item ) : ?>
|
1325 |
-
|
1326 |
<input type="hidden" name="<?php echo $type; ?>s[]"
|
1327 |
-
|
1328 |
<?php echo esc_html( $item ); ?>
|
1329 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1330 |
</span>
|
1331 |
<?php endforeach; ?>
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
<?php
|
|
|
1338 |
}
|
1339 |
|
1340 |
/**
|
@@ -1344,12 +1355,12 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1344 |
// Get $_POST global array.
|
1345 |
$post_array = filter_input_array( INPUT_POST );
|
1346 |
|
1347 |
-
$this->
|
1348 |
-
$this->
|
1349 |
-
$this->
|
1350 |
-
$this->
|
1351 |
-
$this->
|
1352 |
-
$this->
|
1353 |
}
|
1354 |
|
1355 |
/**
|
@@ -1357,23 +1368,23 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1357 |
*/
|
1358 |
private function tab_advanced_settings() {
|
1359 |
?>
|
1360 |
-
|
1361 |
<?php esc_html_e( 'These settings are for advanced users.', 'wp-security-audit-log' ); ?>
|
1362 |
-
<?php echo sprintf( __( 'If you have any questions <a href="https://wpactivitylog.com/contact/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">contact us</a>.', 'wp-security-audit-log' ), $this->
|
1363 |
</p>
|
1364 |
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
|
1378 |
<h3><?php esc_html_e( 'Purge the WordPress activity log', 'wp-security-audit-log' ); ?></h3>
|
1379 |
<p class="description"><?php esc_html_e( 'Click the Purge button below to delete all the data from the WordPress activity log and start afresh.', 'wp-security-audit-log' ); ?></p>
|
@@ -1388,7 +1399,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1388 |
</tbody>
|
1389 |
</table>
|
1390 |
|
1391 |
-
<?php $stealth_mode = $this->
|
1392 |
<h3><?php esc_html_e( 'MainWP Child Site Stealth Mode', 'wp-security-audit-log' ); ?></h3>
|
1393 |
<p class="description"><?php esc_html_e( 'This option is enabled automatically when the plugin detects the MainWP Child plugin on the site. When this setting is enabled plugin access is restricted to the administrator who installs the plugin, the plugin is not shown in the list of installed plugins and no admin notifications are shown. Disable this option to change the plugin to the default setup.', 'wp-security-audit-log' ); ?></p>
|
1394 |
<table class="form-table wsal-tab">
|
@@ -1412,7 +1423,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1412 |
</td>
|
1413 |
</tr>
|
1414 |
<!-- / MainWP Child Site Stealth Mode -->
|
1415 |
-
<?php $admin_blocking_plugins_support = $this->
|
1416 |
<tr>
|
1417 |
<th>
|
1418 |
<label for="mwp_admin_blocking_support"><?php esc_html_e( 'Admin blocking plugins support', 'wp-security-audit-log' ); ?></label>
|
@@ -1431,6 +1442,9 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1431 |
</tbody>
|
1432 |
</table>
|
1433 |
|
|
|
|
|
|
|
1434 |
<h3><?php esc_html_e( 'Do you want to delete the plugin data from the database upon uninstall?', 'wp-security-audit-log' ); ?></h3>
|
1435 |
<p class="description"><?php esc_html_e( '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.', 'wp-security-audit-log' ); ?></p>
|
1436 |
<table class="form-table wsal-tab">
|
@@ -1441,14 +1455,14 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1441 |
<fieldset>
|
1442 |
<label for="delete_data_yes">
|
1443 |
<input type="radio" name="DeleteData" value="1" id="delete_data_yes" onclick="return delete_confirm(this);"
|
1444 |
-
<?php checked( $
|
1445 |
/>
|
1446 |
<?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
|
1447 |
</label>
|
1448 |
<br>
|
1449 |
<label for="delete_data_no">
|
1450 |
<input type="radio" name="DeleteData" value="0" id="delete_data_no"
|
1451 |
-
<?php checked( $
|
1452 |
/>
|
1453 |
<?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
|
1454 |
</label>
|
@@ -1459,15 +1473,15 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1459 |
</tbody>
|
1460 |
</table>
|
1461 |
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
|
1472 |
<div class="remodal" data-remodal-id="wsal_purge_activity">
|
1473 |
<button data-remodal-action="close" class="remodal-close"></button>
|
@@ -1490,33 +1504,33 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1490 |
// Get $_POST global array.
|
1491 |
$post_array = filter_input_array( INPUT_POST );
|
1492 |
|
1493 |
-
$this->
|
1494 |
|
1495 |
$stealth_mode = isset( $post_array['mwp_stealth_mode'] ) ? $post_array['mwp_stealth_mode'] : false;
|
1496 |
if ( 'yes' === $stealth_mode ) {
|
1497 |
if ( ! WpSecurityAuditLog::is_mainwp_active() ) {
|
1498 |
throw new Exception( __( 'MainWP Child plugin is not active on this website.', 'wp-security-audit-log' ) );
|
1499 |
}
|
1500 |
-
$this->
|
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->
|
1505 |
}
|
1506 |
} else {
|
1507 |
-
$this->
|
1508 |
}
|
1509 |
}
|
1510 |
|
1511 |
/**
|
1512 |
-
*
|
1513 |
*/
|
1514 |
-
public function
|
1515 |
wp_enqueue_style(
|
1516 |
'settings',
|
1517 |
-
$this->
|
1518 |
array(),
|
1519 |
-
filemtime( $this->
|
1520 |
);
|
1521 |
|
1522 |
// Check current tab.
|
@@ -1526,24 +1540,24 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1526 |
wp_enqueue_style( 'wsal-remodal-theme', WSAL_BASE_URL . 'css/remodal-default-theme.css', array(), '1.1.1' );
|
1527 |
}
|
1528 |
?>
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
<?php
|
1541 |
}
|
1542 |
|
1543 |
/**
|
1544 |
-
*
|
1545 |
*/
|
1546 |
-
public function
|
1547 |
// Enqueue jQuery UI from core.
|
1548 |
wp_enqueue_script(
|
1549 |
'wsal-jquery-ui',
|
@@ -1568,9 +1582,9 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1568 |
// Register settings script.
|
1569 |
wp_register_script(
|
1570 |
'settings',
|
1571 |
-
$this->
|
1572 |
array(),
|
1573 |
-
filemtime( $this->
|
1574 |
true
|
1575 |
);
|
1576 |
// Passing nonce for security to JS file.
|
@@ -1589,25 +1603,25 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1589 |
wp_localize_script( 'settings', 'wsal_data', $wsal_data );
|
1590 |
wp_enqueue_script( 'settings' );
|
1591 |
?>
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
<?php
|
1605 |
}
|
1606 |
|
1607 |
/**
|
1608 |
* Method: Ajax Request handler for AjaxGetAllUsers.
|
1609 |
*/
|
1610 |
-
public function
|
1611 |
// Filter $_GET array for security.
|
1612 |
$get_array = filter_input_array( INPUT_GET );
|
1613 |
$this->check_ajax_request_is_valid( $get_array );
|
@@ -1626,7 +1640,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1626 |
/**
|
1627 |
* Method: Ajax Request handler for AjaxGetAllRoles.
|
1628 |
*/
|
1629 |
-
public function
|
1630 |
// Filter $_GET array for security.
|
1631 |
$get_array = filter_input_array( INPUT_GET );
|
1632 |
$this->check_ajax_request_is_valid( $get_array );
|
@@ -1653,22 +1667,29 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
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(
|
|
|
|
|
|
|
1657 |
exit;
|
1658 |
}
|
1659 |
|
1660 |
/**
|
1661 |
* Filters values to return ones matching the desired term.
|
1662 |
*
|
1663 |
-
* @param array
|
1664 |
-
* @param string $term
|
1665 |
-
*
|
|
|
1666 |
*/
|
1667 |
public function filter_values_for_searched_term( $items_to_filter, $term ) {
|
1668 |
|
1669 |
-
$result = array_filter(
|
1670 |
-
|
1671 |
-
|
|
|
|
|
|
|
1672 |
|
1673 |
return wp_json_encode( $result );
|
1674 |
}
|
@@ -1684,9 +1705,9 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1684 |
$get_array = filter_input_array( INPUT_GET );
|
1685 |
$this->check_ajax_request_is_valid( $get_array );
|
1686 |
|
1687 |
-
$event_types
|
1688 |
|
1689 |
-
echo $this->filter_values_for_searched_term( array_values( $event_types ), $get_array['term'] );
|
1690 |
exit;
|
1691 |
}
|
1692 |
|
@@ -1701,9 +1722,9 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1701 |
$get_array = filter_input_array( INPUT_GET );
|
1702 |
$this->check_ajax_request_is_valid( $get_array );
|
1703 |
|
1704 |
-
$event_objects
|
1705 |
|
1706 |
-
echo $this->filter_values_for_searched_term( array_values( $event_objects ), $get_array['term'] );
|
1707 |
exit;
|
1708 |
}
|
1709 |
|
@@ -1718,14 +1739,14 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1718 |
$get_array = filter_input_array( INPUT_GET );
|
1719 |
$this->check_ajax_request_is_valid( $get_array );
|
1720 |
|
1721 |
-
$registered_alerts = $this->
|
1722 |
|
1723 |
-
$alerts =
|
1724 |
foreach ( $registered_alerts as $alert => $details ) {
|
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 |
|
@@ -1734,16 +1755,19 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1734 |
*
|
1735 |
* @since 2.6.7
|
1736 |
*/
|
1737 |
-
public function
|
1738 |
// Filter $_GET array for security.
|
1739 |
$get_array = filter_input_array( INPUT_GET );
|
1740 |
$this->check_ajax_request_is_valid( $get_array );
|
1741 |
|
1742 |
// Get custom post types.
|
1743 |
$custom_post_types = array();
|
1744 |
-
$post_types = get_post_types(
|
1745 |
-
|
1746 |
-
|
|
|
|
|
|
|
1747 |
// if we are running multisite and have networkwide cpt tracker get the
|
1748 |
// list from and merge to the post_types array.
|
1749 |
if ( is_multisite() && class_exists( '\WSAL\Multisite\NetworkWide\CPTsTracker' ) ) {
|
@@ -1752,6 +1776,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1752 |
$post_types[ $cpt ] = $cpt;
|
1753 |
}
|
1754 |
}
|
|
|
1755 |
$post_types = array_diff( $post_types, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) );
|
1756 |
foreach ( $post_types as $post_type ) {
|
1757 |
if ( strpos( $post_type, $get_array['term'] ) !== false ) {
|
@@ -1765,14 +1790,14 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1765 |
/**
|
1766 |
* Checks if provided GET array is valid and bails if not.
|
1767 |
*
|
1768 |
-
* @param
|
1769 |
-
* @return void
|
1770 |
*/
|
1771 |
public function check_ajax_request_is_valid( $get_array ) {
|
1772 |
// Die if user does not have permission to edit.
|
1773 |
-
if ( ! $this->
|
1774 |
die( 'Access Denied.' );
|
1775 |
}
|
|
|
1776 |
// Die if nonce verification failed.
|
1777 |
if ( ! wp_verify_nonce( $get_array['wsal_nonce'], 'wsal-exclude-nonce' ) ) {
|
1778 |
die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
@@ -1784,7 +1809,7 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1784 |
*/
|
1785 |
public function reset_settings() {
|
1786 |
// Die if user does not have permission to change settings.
|
1787 |
-
if ( ! $this->
|
1788 |
wp_send_json_error( esc_html__( 'Access Denied.', 'wp-security-audit-log' ) );
|
1789 |
}
|
1790 |
|
@@ -1794,20 +1819,20 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1794 |
wp_send_json_error( esc_html__( 'Nonce Verification Failed.', 'wp-security-audit-log' ) );
|
1795 |
}
|
1796 |
|
1797 |
-
|
1798 |
-
|
1799 |
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
}
|
1804 |
|
1805 |
/**
|
1806 |
* Method: Purge plugin occurrence & meta tables.
|
1807 |
*/
|
1808 |
-
|
1809 |
// Die if user does not have permission to change settings.
|
1810 |
-
if ( ! $this->
|
1811 |
wp_send_json_error( esc_html__( 'Access Denied.', 'wp-security-audit-log' ) );
|
1812 |
}
|
1813 |
|
@@ -1817,103 +1842,110 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
1817 |
wp_send_json_error( esc_html__( 'Nonce Verification Failed.', 'wp-security-audit-log' ) );
|
1818 |
}
|
1819 |
|
1820 |
-
|
1821 |
-
|
1822 |
|
1823 |
-
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
}
|
1831 |
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
|
1856 |
-
|
1857 |
-
|
1858 |
-
$
|
1859 |
-
|
1860 |
-
|
1861 |
-
|
1862 |
-
$
|
|
|
|
|
|
|
|
|
1863 |
'days' => esc_html__( 'Days', 'wp-security-audit-log' ),
|
1864 |
'months' => esc_html__( 'Months', 'wp-security-audit-log' ),
|
1865 |
'years' => esc_html__( 'Years', 'wp-security-audit-log' ),
|
1866 |
-
|
1867 |
-
|
1868 |
-
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
1890 |
-
|
1891 |
-
|
1892 |
-
|
1893 |
-
|
1894 |
-
|
1895 |
-
|
1896 |
-
|
1897 |
-
|
1898 |
-
|
1899 |
-
|
1900 |
-
|
1901 |
-
|
1902 |
-
|
1903 |
-
|
1904 |
-
|
1905 |
-
|
1906 |
-
|
1907 |
-
|
1908 |
-
|
1909 |
-
|
1910 |
-
|
1911 |
-
|
1912 |
-
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
|
|
|
|
|
|
1919 |
}
|
4 |
*
|
5 |
* Settings page of the plugin.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
19 |
*
|
20 |
* Settings view class to handle settings page functions.
|
21 |
*
|
22 |
+
* @since 1.0.0
|
23 |
+
*
|
24 |
+
* @package wsal
|
25 |
+
* @subpackage views
|
26 |
*/
|
27 |
class WSAL_Views_Settings extends WSAL_AbstractView {
|
28 |
|
59 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
60 |
parent::__construct( $plugin );
|
61 |
add_action( 'admin_init', array( $this, 'setup_settings_tabs' ) );
|
62 |
+
add_action( 'wp_ajax_AjaxCheckSecurityToken', array( $this, 'ajax_check_security_token' ) );
|
63 |
+
add_action( 'wp_ajax_AjaxRunCleanup', array( $this, 'ajax_run_cleanup' ) );
|
64 |
+
add_action( 'wp_ajax_AjaxGetAllUsers', array( $this, 'ajax_get_all_users' ) );
|
65 |
+
add_action( 'wp_ajax_AjaxGetAllRoles', array( $this, 'ajax_get_all_roles' ) );
|
66 |
+
add_action( 'wp_ajax_AjaxGetAllCPT', array( $this, 'ajax_get_all_cpts' ) );
|
67 |
add_action( 'wp_ajax_wsal_reset_settings', array( $this, 'reset_settings' ) );
|
68 |
add_action( 'wp_ajax_wsal_purge_activity', array( $this, 'purge_activity' ) );
|
69 |
add_action( 'wp_ajax_wsal_ajax_get_all_severities', array( $this, 'ajax_get_all_severities' ) );
|
78 |
* @since 3.4
|
79 |
*/
|
80 |
public function setup_settings_tabs() {
|
|
|
|
|
|
|
81 |
|
82 |
// Verify that the current page is WSAL settings page.
|
83 |
+
$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : false; // phpcs:ignore
|
84 |
+
if ( empty( $page ) || $this->get_safe_view_name() !== $page ) {
|
85 |
return;
|
86 |
}
|
87 |
|
88 |
// Tab links.
|
89 |
$wsal_setting_tabs = array(
|
90 |
'general' => array(
|
91 |
+
'name' => esc_html__( 'General', 'wp-security-audit-log' ),
|
92 |
+
'link' => add_query_arg( 'tab', 'general', $this->get_url() ),
|
93 |
'render' => array( $this, 'tab_general' ),
|
94 |
'save' => array( $this, 'tab_general_save' ),
|
95 |
'priority' => 10,
|
96 |
),
|
97 |
'audit-log' => array(
|
98 |
+
'name' => esc_html__( 'Activity log viewer', 'wp-security-audit-log' ),
|
99 |
+
'link' => add_query_arg( 'tab', 'audit-log', $this->get_url() ),
|
100 |
'render' => array( $this, 'tab_audit_log' ),
|
101 |
'save' => array( $this, 'tab_audit_log_save' ),
|
102 |
'priority' => 20,
|
103 |
),
|
104 |
'file-changes' => array(
|
105 |
+
'name' => esc_html__( 'File changes', 'wp-security-audit-log' ),
|
106 |
+
'link' => add_query_arg( 'tab', 'file-changes', $this->get_url() ),
|
107 |
'render' => array( $this, 'tab_file_changes' ),
|
108 |
'priority' => 30,
|
109 |
),
|
110 |
'exclude-objects' => array(
|
111 |
+
'name' => esc_html__( 'Exclude objects', 'wp-security-audit-log' ),
|
112 |
+
'link' => add_query_arg( 'tab', 'exclude-objects', $this->get_url() ),
|
113 |
'render' => array( $this, 'tab_exclude_objects' ),
|
114 |
'save' => array( $this, 'tab_exclude_objects_save' ),
|
115 |
'priority' => 40,
|
116 |
),
|
117 |
'advanced-settings' => array(
|
118 |
+
'name' => esc_html__( 'Advanced settings', 'wp-security-audit-log' ),
|
119 |
+
'link' => add_query_arg( 'tab', 'advanced-settings', $this->get_url() ),
|
120 |
'render' => array( $this, 'tab_advanced_settings' ),
|
121 |
'save' => array( $this, 'tab_advanced_settings_save' ),
|
122 |
'priority' => 100,
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
+
* {@inheritDoc}
|
158 |
*/
|
159 |
+
public function has_plugin_shortcut_link() {
|
160 |
return true;
|
161 |
}
|
162 |
|
163 |
/**
|
164 |
+
* {@inheritDoc}
|
165 |
*/
|
166 |
+
public function get_title() {
|
167 |
+
return esc_html__( 'Settings', 'wp-security-audit-log' );
|
168 |
}
|
169 |
|
170 |
/**
|
171 |
+
* {@inheritDoc}
|
172 |
*/
|
173 |
+
public function get_icon() {
|
174 |
return 'dashicons-admin-generic';
|
175 |
}
|
176 |
|
177 |
/**
|
178 |
+
* {@inheritDoc}
|
179 |
*/
|
180 |
+
public function get_name() {
|
181 |
+
return esc_html__( 'Settings', 'wp-security-audit-log' );
|
182 |
}
|
183 |
|
184 |
/**
|
185 |
+
* {@inheritDoc}
|
186 |
*/
|
187 |
+
public function get_weight() {
|
188 |
return 8;
|
189 |
}
|
190 |
|
193 |
*
|
194 |
* @param string $token - Token type.
|
195 |
*/
|
196 |
+
protected function get_token_type( $token ) {
|
197 |
+
return $this->plugin->settings()->get_token_type( $token );
|
198 |
}
|
199 |
|
200 |
/**
|
202 |
*
|
203 |
* @throws Exception - Unrecognized settings tab error.
|
204 |
*/
|
205 |
+
protected function save() {
|
206 |
// Bail early if user does not have sufficient permissions to save.
|
207 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
208 |
throw new Exception( esc_html__( 'Current user is not allowed to save settings.', 'wp-security-audit-log' ) );
|
209 |
}
|
210 |
// Call respective tab save functions if they are set. Nonce is already verified at this point.
|
218 |
/**
|
219 |
* Method: Check security token.
|
220 |
*/
|
221 |
+
public function ajax_check_security_token() {
|
222 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
223 |
echo wp_json_encode(
|
224 |
array(
|
225 |
'success' => false,
|
258 |
array(
|
259 |
'success' => true,
|
260 |
'token' => $token,
|
261 |
+
'tokenType' => esc_html( $this->get_token_type( $token ) ),
|
262 |
)
|
263 |
);
|
264 |
die();
|
267 |
/**
|
268 |
* Method: Run cleanup.
|
269 |
*/
|
270 |
+
public function ajax_run_cleanup() {
|
271 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
272 |
die( 'Access Denied.' );
|
273 |
}
|
274 |
|
275 |
+
$now = current_time( 'timestamp' ); // phpcs:ignore
|
276 |
+
$max_sdate = $this->plugin->settings()->get_pruning_date(); // Pruning date.
|
277 |
|
278 |
|
279 |
// Calculate limit timestamp.
|
280 |
$max_stamp = $now - ( strtotime( $max_sdate ) - $now );
|
281 |
|
282 |
$query = new WSAL_Models_OccurrenceQuery();
|
283 |
+
$query->add_order_by( 'created_on', false ); // Descending order.
|
284 |
+
$query->add_condition( 'created_on <= %s', intval( $max_stamp ) ); // Add limits of timestamp.
|
285 |
+
$results = $query->get_adapter()->execute_query( $query );
|
286 |
$items = count( $results );
|
287 |
|
288 |
if ( $items ) {
|
289 |
+
$this->plugin->clean_up();
|
290 |
}
|
291 |
|
292 |
if ( $archiving ) {
|
308 |
'pruning' => 0,
|
309 |
);
|
310 |
}
|
311 |
+
wp_safe_redirect( add_query_arg( $redirect_args, $this->get_url() ) );
|
312 |
}
|
313 |
exit;
|
314 |
}
|
315 |
|
316 |
/**
|
317 |
+
* {@inheritDoc}
|
318 |
*/
|
319 |
+
public function render() {
|
320 |
// Verify nonce if a form is submitted.
|
321 |
if ( isset( $_POST['_wpnonce'] ) ) {
|
322 |
check_admin_referer( 'wsal-settings' );
|
323 |
}
|
324 |
|
325 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
326 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
327 |
}
|
328 |
|
331 |
|
332 |
if ( isset( $_POST['submit'] ) ) {
|
333 |
try {
|
334 |
+
$this->save(); // Save settings.
|
335 |
if ( 'sms-provider' === $this->current_tab && $section && 'test' === $section ) :
|
336 |
?>
|
337 |
+
<div class="updated">
|
338 |
+
<p><?php esc_html_e( 'Message sent successfully.', 'wp-security-audit-log' ); ?></p>
|
339 |
+
</div>
|
340 |
<?php else : ?>
|
341 |
+
<div class="updated">
|
342 |
+
<p><?php esc_html_e( 'Settings have been saved.', 'wp-security-audit-log' ); ?></p>
|
343 |
+
</div>
|
344 |
+
<?php
|
345 |
endif;
|
346 |
} catch ( Exception $ex ) {
|
347 |
?>
|
348 |
+
<div class="error">
|
349 |
+
<p><?php esc_html_e( 'Error: ', 'wp-security-audit-log' ); ?><?php echo esc_html( $ex->getMessage() ); ?></p>
|
350 |
+
</div>
|
351 |
<?php
|
352 |
}
|
353 |
}
|
358 |
|
359 |
if ( isset( $_GET['pruning'] ) && '1' === $_GET['pruning'] ) {
|
360 |
?>
|
361 |
+
<div class="updated">
|
362 |
+
<p><?php esc_html_e( 'Old data successfully purged.', 'wp-security-audit-log' ); ?></p>
|
363 |
+
</div>
|
364 |
<?php
|
365 |
} elseif ( isset( $_GET['pruning'] ) && '0' === $_GET['pruning'] ) {
|
366 |
?>
|
367 |
+
<div class="error">
|
368 |
+
<p><?php esc_html_e( 'No data is old enough to be purged.', 'wp-security-audit-log' ); ?></p>
|
369 |
+
</div>
|
370 |
<?php
|
371 |
}
|
372 |
?>
|
373 |
+
<nav id="wsal-tabs" class="nav-tab-wrapper">
|
374 |
<?php foreach ( $this->wsal_setting_tabs as $tab_id => $tab ) : ?>
|
375 |
+
<a href="<?php echo esc_url( $tab['link'] ); ?>" class="nav-tab <?php echo ( $tab_id === $this->current_tab ) ? 'nav-tab-active' : false; ?>">
|
376 |
<?php echo esc_html( $tab['name'] ); ?>
|
377 |
+
</a>
|
378 |
<?php endforeach; ?>
|
379 |
+
</nav>
|
380 |
|
381 |
+
<form id="audit-log-settings" method="post">
|
382 |
+
<input type="hidden" name="page" value="<?php echo isset( $_GET['page'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) : false; ?>" />
|
383 |
+
<input type="hidden" id="ajaxurl" value="<?php echo esc_attr( admin_url( 'admin-ajax.php' ) ); ?>" />
|
384 |
<?php wp_nonce_field( 'wsal-settings' ); ?>
|
385 |
|
386 |
+
<div id="audit-log-adverts"></div>
|
387 |
+
<div class="nav-tabs">
|
|
|
388 |
<?php
|
389 |
if ( ! empty( $this->current_tab ) && ! empty( $this->wsal_setting_tabs[ $this->current_tab ]['render'] ) ) {
|
390 |
call_user_func( $this->wsal_setting_tabs[ $this->current_tab ]['render'] );
|
392 |
call_user_func( $this->wsal_setting_tabs['general']['render'] );
|
393 |
}
|
394 |
?>
|
395 |
+
</div>
|
396 |
<?php
|
397 |
if ( 'sms-provider' === $this->current_tab && $section && 'test' === $section ) {
|
398 |
+
submit_button( esc_html__( 'Send Message', 'wp-security-audit-log' ) );
|
399 |
} else {
|
400 |
submit_button();
|
401 |
}
|
402 |
?>
|
403 |
+
</form>
|
404 |
+
<?php // @codingStandardsIgnoreStart ?>
|
405 |
<script type="text/javascript">
|
406 |
<!--
|
407 |
function delete_confirm(elementRef) {
|
443 |
} );
|
444 |
// --></script>
|
445 |
<?php
|
446 |
+
// @codingStandardsIgnoreEnd
|
447 |
}
|
448 |
|
449 |
/**
|
450 |
* Tab: `General`
|
451 |
*/
|
452 |
private function tab_general() {
|
453 |
+
$settings = $this->plugin->settings();
|
454 |
+
$enforced_settings = $settings->get_mainwp_enforced_settings();
|
455 |
+
$login_page_notification_settings_enforced_by_mainwp = array_key_exists( 'login_notification_enabled', $enforced_settings );
|
456 |
+
$incognito_setting_enforced_by_mainwp = array_key_exists( 'incognito_mode_enabled', $enforced_settings );
|
457 |
?>
|
458 |
+
<h3><?php esc_html_e( 'Use infinite scroll or pagination for the event viewer?', 'wp-security-audit-log' ); ?></h3>
|
459 |
+
<p class="description">
|
460 |
<?php
|
461 |
echo sprintf(
|
462 |
/* translators: Learn more link. */
|
464 |
'<a href="https://wpactivitylog.com/features/search-filters-wordpress-activity-log/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . esc_html__( '(Premium feature)', 'wp-security-audit-log' ) . '</a>'
|
465 |
);
|
466 |
?>
|
467 |
+
</p>
|
468 |
+
<table class="form-table wsal-tab">
|
469 |
+
<tbody>
|
470 |
+
<tr>
|
471 |
+
<th><label for="infinite-scroll"><?php esc_html_e( 'Select event viewer view type:', 'wp-security-audit-log' ); ?></label></th>
|
472 |
+
<td>
|
473 |
+
<fieldset>
|
474 |
+
<label for="infinite-scroll">
|
475 |
+
<input type="radio" name="events-type-nav" value="infinite-scroll" id="infinite-scroll" <?php checked( $this->plugin->settings()->get_events_type_nav(), 'infinite-scroll' ); ?> />
|
476 |
<?php esc_html_e( 'Infinite Scroll (Recommended)', 'wp-security-audit-log' ); ?>
|
477 |
+
</label>
|
478 |
+
<br/>
|
479 |
+
<label for="pagination">
|
480 |
+
<input type="radio" name="events-type-nav" value="pagination" id="pagination" <?php checked( $this->plugin->settings()->get_events_type_nav(), 'pagination' ); ?> />
|
481 |
<?php esc_html_e( 'Pagination', 'wp-security-audit-log' ); ?>
|
482 |
+
</label>
|
483 |
+
<br />
|
484 |
+
</fieldset>
|
485 |
+
</td>
|
486 |
+
</tr>
|
487 |
+
<!-- / Reverse Proxy / Firewall Options -->
|
488 |
+
</tbody>
|
489 |
+
</table>
|
490 |
+
<!-- Events Navigation Type -->
|
491 |
+
|
492 |
+
<h3><?php esc_html_e( 'Do you want the activity log viewer to auto refresh?', 'wp-security-audit-log' ); ?></h3>
|
493 |
+
<p class="description"><?php esc_html_e( 'The activity log viewer auto refreshes every 30 seconds when opened so you can see the latest events as they happen almost in real time.', 'wp-security-audit-log' ); ?></p>
|
494 |
+
<table class="form-table wsal-tab">
|
495 |
+
<tbody>
|
496 |
+
<tr>
|
497 |
+
<th><label for="aroption_on"><?php esc_html_e( 'Refresh activity log viewer', 'wp-security-audit-log' ); ?></label></th>
|
498 |
+
<td>
|
499 |
+
<fieldset>
|
500 |
+
<?php $are = $this->plugin->settings()->is_refresh_alerts_enabled(); ?>
|
501 |
+
<label for="aroption_on">
|
502 |
+
<input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: -2px;" <?php checked( $are ); ?> value="1">
|
503 |
+
<span><?php esc_html_e( 'Auto refresh', 'wp-security-audit-log' ); ?></span>
|
504 |
+
</label>
|
505 |
+
<br/>
|
506 |
+
<label for="aroption_off">
|
507 |
+
<input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: -2px;" <?php checked( $are, false ); ?> value="0">
|
508 |
+
<span><?php esc_html_e( 'Do not auto refresh', 'wp-security-audit-log' ); ?></span>
|
509 |
+
</label>
|
510 |
+
</fieldset>
|
511 |
+
</td>
|
512 |
+
</tr>
|
513 |
+
<!-- Refresh activity log viewer -->
|
514 |
+
</tbody>
|
515 |
+
</table>
|
516 |
+
<!-- Refresh activity log -->
|
517 |
+
|
518 |
+
<h3><?php esc_html_e( 'Display latest events widget in Dashboard & Admin bar', 'wp-security-audit-log' ); ?></h3>
|
519 |
+
<p class="description">
|
520 |
<?php
|
521 |
echo sprintf(
|
522 |
/* translators: Max number of dashboard widget alerts. */
|
523 |
esc_html__( 'The events widget displays the latest %d security events in the dashboard and the admin bar notification displays the latest event.', 'wp-security-audit-log' ),
|
524 |
+
esc_html( $this->plugin->settings()->get_dashboard_widget_max_alerts() )
|
525 |
);
|
526 |
?>
|
527 |
+
</p>
|
528 |
+
<table class="form-table wsal-tab">
|
529 |
+
<tbody>
|
530 |
+
<tr>
|
531 |
+
<th><label for="dwoption_on"><?php esc_html_e( 'Dashboard Widget', 'wp-security-audit-log' ); ?></label></th>
|
532 |
+
<td>
|
533 |
+
<fieldset>
|
534 |
+
<?php $dwe = $this->plugin->settings()->is_widgets_enabled(); ?>
|
535 |
+
<label for="dwoption_on">
|
536 |
+
<input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: -2px;" <?php checked( $dwe ); ?> value="1">
|
537 |
+
<span><?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?></span>
|
538 |
+
</label>
|
539 |
+
<br/>
|
540 |
+
<label for="dwoption_off">
|
541 |
+
<input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: -2px;" <?php checked( $dwe, false ); ?> value="0">
|
542 |
+
<span><?php esc_html_e( 'No', 'wp-security-audit-log' ); ?></span>
|
543 |
+
</label>
|
544 |
+
</fieldset>
|
545 |
+
</td>
|
546 |
+
</tr>
|
547 |
+
<!-- / Events Dashboard Widget -->
|
548 |
+
|
549 |
+
<tr>
|
550 |
<?php
|
551 |
$disabled = '';
|
552 |
+
$label = esc_html__( 'Admin Bar Notification', 'wp-security-audit-log' );
|
553 |
if ( wsal_freemius()->is_free_plan() ) {
|
554 |
$disabled = 'disabled';
|
555 |
+
$label = esc_html__( 'Admin Bar Notification (Premium)', 'wp-security-audit-log' );
|
556 |
}
|
557 |
?>
|
558 |
+
<th><label for="admin_bar_notif_on"><?php echo esc_html( $label ); ?></label></th>
|
559 |
+
<td>
|
560 |
+
<fieldset <?php echo esc_attr( $disabled ); ?>>
|
561 |
+
<?php $abn = $this->plugin->settings()->is_admin_bar_notif(); ?>
|
562 |
+
<label for="admin_bar_notif_on">
|
563 |
+
<input type="radio" name="admin_bar_notif" id="admin_bar_notif_on" style="margin-top: -2px;" <?php checked( $abn ); ?> value="1">
|
564 |
+
<span><?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?></span>
|
565 |
+
</label>
|
566 |
+
<br/>
|
567 |
+
<label for="admin_bar_notif_off">
|
568 |
+
<input type="radio" name="admin_bar_notif" id="admin_bar_notif_off" style="margin-top: -2px;" <?php checked( $abn, false ); ?> value="0">
|
569 |
+
<span><?php esc_html_e( 'No', 'wp-security-audit-log' ); ?></span>
|
570 |
+
</label>
|
571 |
+
</fieldset>
|
572 |
+
</td>
|
573 |
+
</tr>
|
574 |
+
<!-- / Admin Bar Notification -->
|
575 |
+
|
576 |
+
<tr>
|
577 |
<?php
|
578 |
$disabled = '';
|
579 |
+
$label = esc_html__( 'Admin Bar Notification Updates', 'wp-security-audit-log' );
|
580 |
if ( wsal_freemius()->is_free_plan() ) {
|
581 |
$disabled = 'disabled';
|
582 |
+
$label = esc_html__( 'Admin Bar Notification Updates (Premium)', 'wp-security-audit-log' );
|
583 |
}
|
584 |
?>
|
585 |
+
<th><label for="admin_bar_notif_refresh"><?php echo esc_html( $label ); ?></label></th>
|
586 |
+
<td>
|
587 |
+
<fieldset <?php echo esc_attr( $disabled ); ?>>
|
588 |
+
<?php $abn_updates = $this->plugin->settings()->get_admin_bar_notif_updates(); ?>
|
589 |
+
<label for="admin_bar_notif_realtime">
|
590 |
+
<input type="radio" name="admin_bar_notif_updates" id="admin_bar_notif_realtime" style="margin-top: -2px;" <?php checked( $abn_updates, 'real-time' ); ?> value="real-time">
|
591 |
+
<span><?php esc_html_e( 'Update in near real time', 'wp-security-audit-log' ); ?></span>
|
592 |
+
</label>
|
593 |
+
<br/>
|
594 |
+
<label for="admin_bar_notif_refresh">
|
595 |
+
<input type="radio" name="admin_bar_notif_updates" id="admin_bar_notif_refresh" style="margin-top: -2px;" <?php checked( $abn_updates, 'page-refresh' ); ?> value="page-refresh">
|
596 |
+
<span><?php esc_html_e( 'Update only on page refreshes', 'wp-security-audit-log' ); ?></span>
|
597 |
+
</label>
|
598 |
+
</fieldset>
|
599 |
+
</td>
|
600 |
+
</tr>
|
601 |
+
<!-- / Admin Bar Notification Updates -->
|
602 |
+
</tbody>
|
603 |
+
</table>
|
604 |
+
<!-- Dashboard Widget -->
|
605 |
+
|
606 |
+
<h3><?php esc_html_e( 'Add user notification on the WordPress login page', 'wp-security-audit-log' ); ?></h3>
|
607 |
+
<p class="description"><?php esc_html_e( 'Many compliance regulations (such as the GDPR) require website administrators to tell the users of their website that all the changes they do when logged in are being logged.', 'wp-security-audit-log' ); ?></p>
|
608 |
+
<table class="form-table wsal-tab">
|
609 |
+
<tbody>
|
610 |
+
<tr>
|
611 |
+
<th><label for="login_page_notification"><?php esc_html_e( 'Login Page Notification', 'wp-security-audit-log' ); ?></label></th>
|
612 |
+
<td>
|
613 |
+
<fieldset <?php echo disabled( $login_page_notification_settings_enforced_by_mainwp ); ?>>
|
614 |
<?php
|
615 |
// Get login page notification checkbox.
|
616 |
+
$wsal_lpn = $this->plugin->settings()->is_login_page_notification();
|
617 |
if ( $wsal_lpn && 'true' === $wsal_lpn ) {
|
618 |
// If option exists, value is true then set to true.
|
619 |
$wsal_lpn = true;
|
625 |
$wsal_lpn = false;
|
626 |
}
|
627 |
?>
|
628 |
+
<label for="wsal_lpn_yes">
|
629 |
+
<input type="radio" name="login_page_notification" id="wsal_lpn_yes" <?php checked( $wsal_lpn ); ?> value="true" />
|
630 |
<?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
|
631 |
+
</label>
|
632 |
+
<br />
|
633 |
<?php
|
634 |
// Get login page notification text.
|
635 |
+
$wsal_lpn_text = $this->plugin->settings()->get_login_page_notification_text();
|
636 |
+
if ( ! $wsal_lpn_text ) {
|
637 |
+
$wsal_lpn_text = __( '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/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">WP Activity Log plugin</a>. The audit log also includes the IP address where you accessed this site from.', 'wp-security-audit-log' );
|
638 |
+
}
|
639 |
// Allowed HTML tags for this setting.
|
640 |
$allowed_tags = array(
|
641 |
'a' => array(
|
644 |
'target' => array(),
|
645 |
),
|
646 |
);
|
647 |
+
|
648 |
?>
|
649 |
+
<textarea name="login_page_notification_text"
|
650 |
+
id="login_page_notification_text"
|
651 |
+
cols="60" rows="6"
|
652 |
<?php echo ( $wsal_lpn ) ? false : 'disabled'; ?>
|
653 |
+
><?php echo wp_kses( $wsal_lpn_text, $allowed_tags ); ?></textarea>
|
654 |
+
<br/>
|
655 |
+
<p class="description">
|
656 |
+
<?php echo wp_kses( __( '<strong>Note: </strong>', 'wp-security-audit-log' ), $this->plugin->allowed_html_tags ) . esc_html__( 'The only HTML code allowed in the login page notification is for links ( < a href >< /a > ).', 'wp-security-audit-log' ); // phpcs:ignore ?>
|
657 |
+
</p>
|
658 |
+
<br />
|
659 |
+
|
660 |
+
<label for="wsal_lpn_no">
|
661 |
+
<input type="radio" name="login_page_notification" id="wsal_lpn_no" <?php checked( $wsal_lpn, false ); ?> value="false" />
|
662 |
<?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
|
663 |
+
</label>
|
664 |
+
</fieldset>
|
665 |
+
</td>
|
666 |
+
</tr>
|
667 |
+
<!-- / Login Page Notification -->
|
668 |
+
</tbody>
|
669 |
+
</table>
|
670 |
+
<!-- Login Page Notification -->
|
671 |
+
|
672 |
+
<h3><?php esc_html_e( 'Is your website running behind a firewall or reverse proxy?', 'wp-security-audit-log' ); ?></h3>
|
673 |
+
<p class="description">
|
674 |
<?php
|
675 |
echo sprintf(
|
676 |
/* translators: Learn more link. */
|
678 |
'<a href="https://wpactivitylog.com/support/kb/support-reverse-proxies-web-application-firewalls/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . esc_html__( 'learn more', 'wp-security-audit-log' ) . '</a>'
|
679 |
);
|
680 |
?>
|
681 |
+
</p>
|
682 |
+
<table class="form-table wsal-tab">
|
683 |
+
<tbody>
|
684 |
+
<tr>
|
685 |
+
<th><label for="pioption_on"><?php esc_html_e( 'Reverse Proxy / Firewall Options', 'wp-security-audit-log' ); ?></label></th>
|
686 |
+
<td>
|
687 |
+
<fieldset>
|
688 |
+
<label for="enable_proxy_ip_capture_yes">
|
689 |
+
<input type="radio" name="EnableProxyIpCapture" value="1" id="enable_proxy_ip_capture_yes" <?php checked( $this->plugin->settings()->is_main_ip_from_proxy() ); ?> />
|
690 |
<?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
|
691 |
+
</label>
|
692 |
+
<br/>
|
693 |
+
<label for="EnableIpFiltering">
|
694 |
+
<input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering" <?php checked( $this->plugin->settings()->is_internal_ips_filtered() ); ?> />
|
695 |
<?php esc_html_e( 'Filter internal IP addresses from the proxy headers. Enable this option only if you are are still seeing the internal IP addresses of the firewall or proxy.', 'wp-security-audit-log' ); ?>
|
696 |
+
</label>
|
697 |
+
<br/>
|
698 |
+
<label for="enable_proxy_ip_capture_no">
|
699 |
+
<input type="radio" name="EnableProxyIpCapture" value="0" id="enable_proxy_ip_capture_no" <?php checked( $this->plugin->settings()->is_main_ip_from_proxy(), false ); ?> />
|
700 |
<?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
|
701 |
+
</label>
|
702 |
+
<br />
|
703 |
+
</fieldset>
|
704 |
+
</td>
|
705 |
+
</tr>
|
706 |
+
<!-- / Reverse Proxy / Firewall Options -->
|
707 |
+
</tbody>
|
708 |
+
</table>
|
709 |
+
<!-- Reverse Proxy -->
|
710 |
+
|
711 |
+
<h3><?php esc_html_e( 'Who can change the plugin settings?', 'wp-security-audit-log' ); ?></h3>
|
712 |
+
<p class="description">
|
713 |
<?php
|
714 |
$allowed_tags = array(
|
715 |
'a' => array(
|
719 |
);
|
720 |
echo wp_kses(
|
721 |
sprintf(
|
722 |
+
/* translators: Learn more link. */
|
723 |
esc_html__( 'By default only users with administrator role (single site) and super administrator role (multisite) can change the settings of the plugin. Though you can restrict the privileges to just your user - %s.', 'wp-security-audit-log' ),
|
724 |
'<a href="https://wpactivitylog.com/support/kb/managing-wordpress-activity-log-plugin-privileges/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">' . __( 'learn more', 'wp-security-audit-log' ) . '</a>'
|
725 |
),
|
726 |
$allowed_tags
|
727 |
);
|
728 |
+
$restrict_settings = $this->plugin->settings()->get_restrict_plugin_setting();
|
729 |
?>
|
730 |
+
</p>
|
731 |
+
<table class="form-table wsal-tab">
|
732 |
+
<tbody>
|
733 |
+
<tr>
|
734 |
+
<th><label for="RestrictAdmins"><?php esc_html_e( 'Restrict plugin access', 'wp-security-audit-log' ); ?></label></th>
|
735 |
+
<td>
|
736 |
+
<fieldset>
|
737 |
+
<label for="only_me">
|
738 |
+
<input type="radio" name="restrict-plugin-settings" id="only_me" value="only_me" <?php checked( $restrict_settings, 'only_me' ); ?> />
|
739 |
<?php esc_html_e( 'Only me', 'wp-security-audit-log' ); ?>
|
740 |
+
</label>
|
741 |
+
<br/>
|
742 |
+
<label for="only_admins">
|
743 |
+
<input type="radio" name="restrict-plugin-settings" id="only_admins" value="only_admins" <?php checked( $restrict_settings, 'only_admins' ); ?> />
|
744 |
<?php
|
745 |
+
if ( $this->plugin->is_multisite() ) {
|
746 |
esc_html_e( 'All superadmins', 'wp-security-audit-log' );
|
747 |
} else {
|
748 |
esc_html_e( 'All administrators', 'wp-security-audit-log' );
|
749 |
}
|
750 |
?>
|
751 |
+
</label>
|
752 |
+
<br/>
|
753 |
+
</fieldset>
|
754 |
+
</td>
|
755 |
+
</tr>
|
756 |
+
<!-- / Restrict Plugin Access -->
|
757 |
+
</tbody>
|
758 |
+
</table>
|
759 |
+
<!-- Restrict Plugin Access -->
|
760 |
+
|
761 |
+
<h3><?php esc_html_e( 'Allow other users to view the activity log', 'wp-security-audit-log' ); ?></h3>
|
762 |
+
<p class="description">
|
763 |
<?php
|
764 |
+
$is_multisite = $this->plugin->is_multisite();
|
765 |
+
if ( $is_multisite ) {
|
766 |
+
$section_label = esc_html__( 'By default only super administrators and the child sites\' administrators can view the WordPress activity log. Though you can change this by using the setting below.', 'wp-security-audit-log' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
767 |
} else {
|
768 |
+
$section_label = esc_html__( 'By default only users with administrator role can view the WordPress activity log. To allow someone who does not have an admin role to view the activity log, specify them in the below setting.', 'wp-security-audit-log' );
|
769 |
}
|
770 |
|
771 |
echo wp_kses(
|
773 |
$allowed_tags
|
774 |
);
|
775 |
?>
|
776 |
+
</p>
|
777 |
+
<?php if ( $is_multisite ) : ?>
|
778 |
+
<table class="form-table wsal-tab">
|
779 |
+
<tbody>
|
780 |
+
<tr>
|
781 |
+
<th><?php esc_html_e( 'Can view events', 'wp-security-audit-log' ); ?></th>
|
782 |
+
<td>
|
783 |
+
<fieldset>
|
784 |
<?php
|
785 |
+
$restrict_settings = $this->plugin->settings()->get_restrict_log_viewer();
|
786 |
$viewer_restriction_options = array(
|
787 |
'only_me' => __( 'Only me', 'wp-security-audit-log' ),
|
788 |
'only_superadmins' => __( 'Super administators only', 'wp-security-audit-log' ),
|
789 |
'only_admins' => __( 'Super administators and site administrators', 'wp-security-audit-log' ),
|
790 |
);
|
791 |
?>
|
792 |
+
<?php foreach ( $viewer_restriction_options as $option => $label ) : ?>
|
793 |
+
<label for="<?php esc_attr( 'log_viewer_' . $option ); ?>">
|
794 |
+
<?php $disabled = ( 'only_me' === $option && 'only_superadmins' === $restrict_settings ); ?>
|
795 |
+
<input type="radio" name="restrict-log-viewer" id="<?php esc_attr( 'log_viewer_' . $option ); ?>" value="<?php echo esc_attr( $option ); ?>" <?php checked( $restrict_settings, $option ); ?> <?php disabled( $disabled ); ?> />
|
796 |
<?php echo esc_html( $label ); ?>
|
797 |
+
</label>
|
798 |
+
<br/>
|
799 |
<?php endforeach; ?>
|
800 |
+
</fieldset>
|
801 |
+
</td>
|
802 |
+
</tr>
|
803 |
+
</tbody>
|
804 |
+
</table>
|
805 |
+
<p class="description"><?php esc_html_e( 'To allow someone who does not have an admin role to view the activity log, specify them in the below setting.', 'wp-security-audit-log' ); ?></p>
|
806 |
<?php endif; ?>
|
807 |
+
<table class="form-table wsal-tab">
|
808 |
+
<tbody>
|
|
|
809 |
<tr>
|
810 |
+
<?php $row_label = $is_multisite ? esc_html__( 'Can also view events', 'wp-security-audit-log' ) : esc_html__( 'Can view events', 'wp-security-audit-log' ); ?>
|
811 |
+
<th><label for="ViewerQueryBox"><?php echo $row_label; // phpcs:ignore ?></label></th>
|
812 |
<td>
|
813 |
<fieldset>
|
814 |
<label>
|
822 |
|
823 |
<div id="ViewerList">
|
824 |
<?php
|
825 |
+
foreach ( $this->plugin->settings()->get_allowed_plugin_viewers() as $item ) :
|
826 |
if ( wp_get_current_user()->user_login === $item ) {
|
827 |
continue;
|
828 |
}
|
829 |
?>
|
830 |
+
<span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
|
831 |
<input type="hidden" name="Viewers[]" value="<?php echo esc_attr( $item ); ?>"/>
|
832 |
<?php echo esc_html( $item ); ?>
|
833 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
850 |
<th><label for="FromEmail"><?php esc_html_e( 'From Email & Name', 'wp-security-audit-log' ); ?></label></th>
|
851 |
<td>
|
852 |
<fieldset>
|
853 |
+
<?php $use_email = $this->plugin->get_global_setting( 'use-email', 'default_email' ); ?>
|
854 |
<label for="default_email">
|
855 |
<input type="radio" name="use-email" id="default_email" value="default_email" <?php checked( $use_email, 'default_email' ); ?> />
|
856 |
<?php esc_html_e( 'Use the email address from the WordPress general settings', 'wp-security-audit-log' ); ?>
|
863 |
<br>
|
864 |
<label for="FromEmail">
|
865 |
<?php esc_html_e( 'Email Address', 'wp-security-audit-log' ); ?>
|
866 |
+
<input type="email" id="FromEmail" name="FromEmail" value="<?php echo esc_attr( $this->plugin->settings()->get_from_email() ); ?>" />
|
867 |
</label>
|
868 |
<br>
|
869 |
<label for="DisplayName">
|
870 |
<?php esc_html_e( 'Display Name', 'wp-security-audit-log' ); ?>
|
871 |
+
<input type="text" id="DisplayName" name="DisplayName" value="<?php echo esc_attr( $this->plugin->settings()->get_display_name() ); ?>" />
|
872 |
</label>
|
873 |
</fieldset>
|
874 |
</td>
|
878 |
</table>
|
879 |
<!-- From Email & Name -->
|
880 |
|
881 |
+
<?php
|
882 |
+
$is_incognito = $this->plugin->settings()->is_incognito();
|
883 |
+
?>
|
884 |
<h3><?php esc_html_e( 'Do you want to hide the plugin from the list of installed plugins?', 'wp-security-audit-log' ); ?></h3>
|
885 |
<p class="description"><?php esc_html_e( 'By default all installed plugins are listed in the plugins page. Set this option to Yes remove WP Activity Log from the list of installed plugins for users who are unable to access the WP Activity Log settings.', 'wp-security-audit-log' ); ?></p>
|
886 |
<table class="form-table wsal-tab">
|
888 |
<tr>
|
889 |
<th><label for="incognito_yes"><?php esc_html_e( 'Hide Plugin in Plugins Page', 'wp-security-audit-log' ); ?></label></th>
|
890 |
<td>
|
891 |
+
<fieldset <?php echo disabled( $incognito_setting_enforced_by_mainwp ); ?>>
|
892 |
<label for="incognito_yes">
|
893 |
+
<input type="radio" name="Incognito" value="yes" id="incognito_yes" <?php checked( $is_incognito ); ?> />
|
894 |
<?php esc_html_e( 'Yes, hide the plugin and any WP Activity Log plugin extensions from the list of installed plugins', 'wp-security-audit-log' ); ?>
|
895 |
</label>
|
896 |
<br/>
|
897 |
<label for="incognito_no">
|
898 |
+
<input type="radio" name="Incognito" value="no" id="incognito_no" <?php checked( $is_incognito, false ); ?> />
|
899 |
<?php esc_html_e( 'No, do not hide the plugin', 'wp-security-audit-log' ); ?>
|
900 |
</label>
|
901 |
</fieldset>
|
915 |
// Get $_POST global array.
|
916 |
$post_array = filter_input_array( INPUT_POST );
|
917 |
|
918 |
+
$this->plugin->settings()->set_refresh_alerts_enabled( $post_array['EnableAuditViewRefresh'] );
|
919 |
+
$this->plugin->settings()->set_events_type_nav( sanitize_text_field( $post_array['events-type-nav'] ) );
|
920 |
+
$this->plugin->settings()->set_use_email( sanitize_text_field( $post_array['use-email'] ) );
|
921 |
+
$this->plugin->settings()->set_from_email( sanitize_email( $post_array['FromEmail'] ) );
|
922 |
+
$this->plugin->settings()->set_display_name( sanitize_text_field( $post_array['DisplayName'] ) );
|
923 |
+
$this->plugin->settings()->set_widgets_enabled( sanitize_text_field( $post_array['EnableDashboardWidgets'] ) );
|
|
|
924 |
|
925 |
if ( ! wsal_freemius()->is_free_plan() ) {
|
926 |
+
$this->plugin->settings()->set_admin_bar_notif( sanitize_text_field( $post_array['admin_bar_notif'] ) );
|
927 |
+
$this->plugin->settings()->set_admin_bar_notif_updates( sanitize_text_field( $post_array['admin_bar_notif_updates'] ) );
|
928 |
}
|
929 |
|
930 |
+
// Handle log viewer settings in multisite context.
|
931 |
+
if ( $this->plugin->is_multisite() ) {
|
932 |
$log_viewer_restrictions = isset( $post_array['restrict-log-viewer'] ) ? sanitize_text_field( $post_array['restrict-log-viewer'] ) : '';
|
933 |
+
$this->plugin->settings()->set_restrict_log_viewer( $log_viewer_restrictions );
|
934 |
if ( 'only_me' === $log_viewer_restrictions ) {
|
935 |
+
$this->plugin->settings()->set_only_me_user_id( get_current_user_id() );
|
936 |
}
|
937 |
}
|
938 |
|
939 |
// Get plugin viewers.
|
940 |
$viewers = isset( $post_array['Viewers'] ) ? array_map( 'sanitize_text_field', $post_array['Viewers'] ) : array();
|
941 |
+
$this->plugin->settings()->set_allowed_plugin_viewers( $viewers );
|
942 |
|
943 |
+
// Handle plugin settings permissions.
|
944 |
$restrict_settings = isset( $post_array['restrict-plugin-settings'] ) ? sanitize_text_field( $post_array['restrict-plugin-settings'] ) : false;
|
945 |
+
$this->plugin->settings()->set_restrict_plugin_setting( $restrict_settings );
|
946 |
if ( 'only_me' === $restrict_settings ) {
|
947 |
+
$this->plugin->settings()->set_only_me_user_id( get_current_user_id() );
|
948 |
}
|
949 |
|
950 |
+
$this->plugin->settings()->set_login_page_notification( isset( $post_array['login_page_notification'] ) ? sanitize_text_field( $post_array['login_page_notification'] ) : false );
|
951 |
+
$this->plugin->settings()->set_login_page_notification_text( isset( $post_array['login_page_notification_text'] ) ? $post_array['login_page_notification_text'] : false );
|
952 |
+
$this->plugin->settings()->set_main_ip_from_proxy( isset( $post_array['EnableProxyIpCapture'] ) ? sanitize_text_field( $post_array['EnableProxyIpCapture'] ) : false );
|
953 |
+
$this->plugin->settings()->set_internal_ips_filtering( isset( $post_array['EnableIpFiltering'] ) ? sanitize_text_field( $post_array['EnableIpFiltering'] ) : false );
|
954 |
|
955 |
$is_incognito = isset( $post_array['Incognito'] ) ? \WSAL\Helpers\Options::string_to_bool( sanitize_text_field( $post_array['Incognito'] ) ) : false;
|
956 |
+
$this->plugin->settings()->set_incognito( $is_incognito );
|
957 |
}
|
958 |
|
959 |
/**
|
961 |
*/
|
962 |
private function tab_audit_log() {
|
963 |
?>
|
964 |
+
<h3><?php esc_html_e( 'For how long do you want to keep the activity log events (Retention settings)?', 'wp-security-audit-log' ); ?></h3>
|
965 |
+
<p class="description">
|
966 |
<?php
|
967 |
esc_html_e( 'The plugin uses an efficient way to store the activity log data in the WordPress database, though the more data you keep the more disk space will be required. ', 'wp-security-audit-log' );
|
968 |
$retention_help_text = __( '<a href="https://wpactivitylog.com/pricing/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">Upgrade to Premium</a> to store the activity log data in an external database.', 'wp-security-audit-log' );
|
969 |
|
970 |
+
echo wp_kses( $retention_help_text, $this->plugin->allowed_html_tags );
|
971 |
?>
|
972 |
+
</p>
|
973 |
|
974 |
<?php
|
975 |
+
// Ensure it doesn't load a 2nd time for premium users.
|
976 |
if ( ! wsal_freemius()->can_use_premium_code() ) {
|
977 |
$this->render_retention_settings_table();
|
978 |
}
|
987 |
<td>
|
988 |
<fieldset>
|
989 |
<?php
|
990 |
+
$timezone = $this->plugin->settings()->get_timezone();
|
991 |
|
992 |
/**
|
993 |
* Transform timezone values.
|
1019 |
<th><?php esc_html_e( 'Show Milliseconds', 'wp-security-audit-log' ); ?></th>
|
1020 |
<td>
|
1021 |
<fieldset>
|
1022 |
+
<?php $show_milliseconds = $this->plugin->settings()->get_show_milliseconds(); ?>
|
1023 |
<label for="show_milliseconds">
|
1024 |
<input type="checkbox" name="show_milliseconds" id="show_milliseconds" style="margin-top: -2px;"
|
1025 |
<?php checked( $show_milliseconds ); ?> value="yes">
|
1041 |
<th><label for="timezone-default"><?php esc_html_e( 'User information in Activity log', 'wp-security-audit-log' ); ?></label></th>
|
1042 |
<td>
|
1043 |
<fieldset>
|
1044 |
+
<?php $type_username = $this->plugin->settings()->get_type_username(); ?>
|
1045 |
<label for="column_username">
|
1046 |
<input type="radio" name="type_username" id="column_username" style="margin-top: -2px;" <?php checked( $type_username, 'username' ); ?> value="username">
|
1047 |
<span><?php esc_html_e( 'WordPress username', 'wp-security-audit-log' ); ?></span>
|
1072 |
<th><label for="columns"><?php esc_html_e( 'Activity log columns selection', 'wp-security-audit-log' ); ?></label></th>
|
1073 |
<td>
|
1074 |
<fieldset>
|
1075 |
+
<?php $columns = $this->plugin->settings()->get_columns(); ?>
|
1076 |
<?php foreach ( $columns as $key => $value ) { ?>
|
1077 |
<label for="columns">
|
1078 |
<input type="checkbox" name="Columns[<?php echo esc_attr( $key ); ?>]" id="<?php echo esc_attr( $key ); ?>" class="sel-columns" style="margin-top: -2px;"
|
1103 |
</table>
|
1104 |
<!-- Activity log columns -->
|
1105 |
|
1106 |
+
<?php $is_wp_backend = $this->plugin->settings()->is_wp_backend(); ?>
|
1107 |
<h3><?php esc_html_e( 'Do you want to keep a log of WordPress background activity?', 'wp-security-audit-log' ); ?></h3>
|
1108 |
<p class="description">
|
1109 |
<?php esc_html_e( 'WordPress does a lot of things in the background that you do not necessarily need to know about, such as; deletion of post revisions, deletion of auto saved drafts etc. By default the plugin does not report them since there might be a lot and are irrelevant to the user.', 'wp-security-audit-log' ); ?>
|
1145 |
$pruning_unit = isset( $post_array['pruning-unit'] ) ? sanitize_text_field( $post_array['pruning-unit'] ) : false;
|
1146 |
$pruning_date = ( ! empty( $pruning_date ) && ! empty( $pruning_unit ) ) ? $pruning_date . ' ' . $pruning_unit : false;
|
1147 |
|
1148 |
+
$this->plugin->settings()->set_pruning_date_enabled( isset( $post_array['PruneBy'] ) ? 'date' === $post_array['PruneBy'] : '' );
|
1149 |
+
$this->plugin->settings()->set_pruning_date( $pruning_date );
|
1150 |
+
$this->plugin->settings()->set_pruning_unit( $pruning_unit );
|
1151 |
+
$this->plugin->settings()->set_timezone( $post_array['Timezone'] );
|
1152 |
+
$this->plugin->settings()->set_type_username( $post_array['type_username'] );
|
1153 |
+
$this->plugin->settings()->set_wp_backend( isset( $post_array['WPBackend'] ) ? sanitize_text_field( $post_array['WPBackend'] ) : false );
|
1154 |
if ( ! empty( $post_array['Columns'] ) ) {
|
1155 |
+
$this->plugin->settings()->set_columns( $post_array['Columns'] );
|
1156 |
}
|
1157 |
+
$show_milliseconds = isset( $post_array['show_milliseconds'] ) && 'yes' === $post_array['show_milliseconds'];
|
1158 |
+
$this->plugin->settings()->set_show_milliseconds( $show_milliseconds );
|
1159 |
}
|
1160 |
|
1161 |
/**
|
1169 |
<tr>
|
1170 |
<?php if ( ! defined( 'WFCM_PLUGIN_FILE' ) ) : ?>
|
1171 |
<div class="addon-wrapper" style="max-width: 380px; text-align: center; border: 1px solid #ccc; padding: 25px;">
|
1172 |
+
<img src="<?php echo esc_html( trailingslashit( WSAL_BASE_URL ) . 'img/help/website-file-changes-monitor.jpg' ); ?>">
|
1173 |
<h4><?php echo esc_html__( 'Website File Changes Monitor', 'wp-security-audit-log' ); ?></h4>
|
1174 |
<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>
|
1175 |
+
<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 esc_html_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 esc_html_e( 'Learn More', 'wp-security-audit-log' ); ?></a></p>
|
1176 |
</div>
|
1177 |
<?php else : ?>
|
1178 |
<?php
|
1179 |
+
$redirect_args = array(
|
|
|
1180 |
'page' => 'wfcm-file-changes',
|
1181 |
);
|
1182 |
if ( ! is_multisite() ) {
|
1210 |
<input type="button" id="ExUserQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1211 |
<br style="clear: both;"/>
|
1212 |
<div id="ExUserList">
|
1213 |
+
<?php foreach ( $this->plugin->settings()->get_excluded_monitoring_users() as $item ) : ?>
|
1214 |
+
<span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
|
1215 |
<input type="hidden" name="ExUsers[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1216 |
<?php echo esc_html( $item ); ?>
|
1217 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1231 |
<input type="button" id="ExRoleQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1232 |
<br style="clear: both;"/>
|
1233 |
<div id="ExRoleList">
|
1234 |
+
<?php foreach ( $this->plugin->settings()->get_excluded_monitoring_roles() as $item ) : ?>
|
1235 |
+
<span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
|
1236 |
<input type="hidden" name="ExRoles[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1237 |
<?php echo esc_html( $item ); ?>
|
1238 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1252 |
<input type="button" id="IpAddrQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1253 |
<br style="clear: both;"/>
|
1254 |
<div id="IpAddrList">
|
1255 |
+
<?php foreach ( $this->plugin->settings()->get_excluded_monitoring_ip() as $item ) : ?>
|
1256 |
+
<span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
|
1257 |
<input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1258 |
<?php echo esc_html( $item ); ?>
|
1259 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1260 |
</span>
|
1261 |
<?php endforeach; ?>
|
1262 |
+
</div>
|
1263 |
+
</fieldset>
|
1264 |
+
<p class="description"><?php esc_html_e( 'You can exclude an individual IP address or a range of IP addresses. To exclude a range use the following format: [first IP]-[last octet of the last IP]. Example: 172.16.180.6-127.', 'wp-security-audit-log' ); ?></p>
|
1265 |
+
</td>
|
1266 |
+
</tr>
|
1267 |
+
<!-- Exclude IP Addresses -->
|
1268 |
+
|
1269 |
+
<tr>
|
1270 |
+
<th><label for="ExCPTsQueryBox"><?php esc_html_e( 'Exclude Post Type:', 'wp-security-audit-log' ); ?></label></th>
|
1271 |
+
<td>
|
1272 |
+
<fieldset>
|
1273 |
+
<input type="text" id="ExCPTsQueryBox" style="width: 250px;">
|
1274 |
+
<input type="button" id="ExCPTsQueryAdd" class="button-primary" value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1275 |
+
<br style="clear: both;"/>
|
1276 |
+
<div id="ExCPTsList">
|
1277 |
+
<?php foreach ( $this->plugin->settings()->get_excluded_post_types() as $item ) : ?>
|
1278 |
+
<span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
|
1279 |
<input type="hidden" name="ExCPTss[]" value="<?php echo esc_attr( $item ); ?>"/>
|
1280 |
<?php echo esc_html( $item ); ?>
|
1281 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1282 |
</span>
|
1283 |
<?php endforeach; ?>
|
1284 |
+
</div>
|
1285 |
+
</fieldset>
|
1286 |
+
<p class="description"><?php esc_html_e( 'WordPress has the post and page post types by default though your website might use more post types (custom post types). You can exclude all post types, including the default WordPress ones.', 'wp-security-audit-log' ); ?></p>
|
1287 |
+
</td>
|
1288 |
+
</tr>
|
1289 |
+
<!-- Exclude Custom Post Types -->
|
1290 |
+
|
1291 |
+
<?php
|
1292 |
+
$this->renderMetaExclusionSection(
|
1293 |
+
esc_html__( 'Exclude custom post fields:', 'wp-security-audit-log' ),
|
1294 |
+
$this->plugin->settings()->get_excluded_post_meta_fields(),
|
1295 |
+
'PostMeta'
|
1296 |
+
);
|
1297 |
+
?>
|
1298 |
+
<!-- Exclude Custom Post Fields -->
|
1299 |
|
1300 |
<?php
|
1301 |
$this->renderMetaExclusionSection(
|
1302 |
esc_html__( 'Exclude custom user fields:', 'wp-security-audit-log' ),
|
1303 |
+
$this->plugin->settings()->get_excluded_user_meta_fields(),
|
1304 |
'UserMeta'
|
1305 |
);
|
1306 |
+
?>
|
1307 |
+
<!-- Exclude Custom User Fields -->
|
1308 |
|
1309 |
+
</tbody>
|
1310 |
+
</table>
|
1311 |
+
<!-- / Exclude Objects Tab -->
|
1312 |
<?php
|
1313 |
}
|
1314 |
|
1315 |
+
/**
|
1316 |
+
* Renders form section for excluding metadata of certain object type.
|
1317 |
+
*
|
1318 |
+
* @param string $title Section title.
|
1319 |
+
* @param array $values Values.
|
1320 |
+
* @param string $type Object type.
|
1321 |
+
*/
|
1322 |
private function renderMetaExclusionSection( $title, $values, $type ) {
|
1323 |
+
// @codingStandardsIgnoreStart
|
1324 |
?>
|
1325 |
+
<tr>
|
1326 |
+
<th><label for="Custom<?php echo $type; ?>QueryBox"><?php echo $title; ?></label></th>
|
1327 |
+
<td>
|
1328 |
+
<fieldset data-type="<?php echo $type; ?>">
|
1329 |
+
<input type="text" id="<?php echo $type; ?>QueryBox" class="js-query-box" style="width: 250px;">
|
1330 |
+
<input type="button" id="<?php echo $type; ?>QueryAdd" class="js-query-add button-primary"
|
1331 |
+
value="<?php esc_attr_e( 'Add', 'wp-security-audit-log' ); ?>">
|
1332 |
+
<br style="clear: both;"/>
|
1333 |
+
<div id="<?php echo $type; ?>List" class="js-list">
|
1334 |
<?php foreach ( $values as $item ) : ?>
|
1335 |
+
<span class="sectoken-<?php echo esc_attr( $this->get_token_type( $item ) ); ?>">
|
1336 |
<input type="hidden" name="<?php echo $type; ?>s[]"
|
1337 |
+
value="<?php echo esc_attr( $item ); ?>"/>
|
1338 |
<?php echo esc_html( $item ); ?>
|
1339 |
<a href="javascript:;" title="<?php esc_attr_e( 'Remove', 'wp-security-audit-log' ); ?>">×</a>
|
1340 |
</span>
|
1341 |
<?php endforeach; ?>
|
1342 |
+
</div>
|
1343 |
+
</fieldset>
|
1344 |
+
<p class="description"><?php esc_html_e( 'You can use the * wildcard to exclude multiple matching custom fields. For example to exclude all custom fields starting with wp123 enter wp123*', 'wp-security-audit-log' ); ?></p>
|
1345 |
+
</td>
|
1346 |
+
</tr>
|
1347 |
<?php
|
1348 |
+
// @codingStandardsIgnoreEnd
|
1349 |
}
|
1350 |
|
1351 |
/**
|
1355 |
// Get $_POST global array.
|
1356 |
$post_array = filter_input_array( INPUT_POST );
|
1357 |
|
1358 |
+
$this->plugin->settings()->set_excluded_monitoring_users( isset( $post_array['ExUsers'] ) ? $post_array['ExUsers'] : array() );
|
1359 |
+
$this->plugin->settings()->set_excluded_monitoring_roles( isset( $post_array['ExRoles'] ) ? $post_array['ExRoles'] : array() );
|
1360 |
+
$this->plugin->settings()->set_excluded_post_meta_fields( isset( $post_array['PostMetas'] ) ? $post_array['PostMetas'] : array() );
|
1361 |
+
$this->plugin->settings()->set_excluded_user_meta_fields( isset( $post_array['UserMetas'] ) ? $post_array['UserMetas'] : array() );
|
1362 |
+
$this->plugin->settings()->set_excluded_monitoring_ip( isset( $post_array['IpAddrs'] ) ? $post_array['IpAddrs'] : array() );
|
1363 |
+
$this->plugin->settings()->set_excluded_post_types( isset( $post_array['ExCPTss'] ) ? $post_array['ExCPTss'] : array() );
|
1364 |
}
|
1365 |
|
1366 |
/**
|
1368 |
*/
|
1369 |
private function tab_advanced_settings() {
|
1370 |
?>
|
1371 |
+
<p class="description">
|
1372 |
<?php esc_html_e( 'These settings are for advanced users.', 'wp-security-audit-log' ); ?>
|
1373 |
+
<?php echo sprintf( __( 'If you have any questions <a href="https://wpactivitylog.com/contact/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages" target="_blank">contact us</a>.', 'wp-security-audit-log' ), $this->plugin->allowed_html_tags ); // phpcs:ignore ?>
|
1374 |
</p>
|
1375 |
|
1376 |
+
<h3><?php esc_html_e( 'Reset plugin settings to default', 'wp-security-audit-log' ); ?></h3>
|
1377 |
+
<p class="description"><?php _e( 'Use this button to <em>factory reset</em> the plugin. This means that all the configured settings will be reset to default and all email notifications, scheduled reports, external database / third party services connections, archiving and mirroring rule will be deleted. NOTE: the activity log data will not be purged. Use the setting below to purge the activity log.', 'wp-security-audit-log' ); // phpcs:ignore ?></p>
|
1378 |
+
<table class="form-table wsal-tab">
|
1379 |
+
<tbody>
|
1380 |
+
<tr>
|
1381 |
+
<th><?php esc_html_e( 'Reset Settings', 'wp-security-audit-log' ); ?></th>
|
1382 |
+
<td>
|
1383 |
+
<a href="#wsal_reset_settings" class="button-primary js-settings-reset"><?php esc_html_e( 'RESET', 'wp-security-audit-log' ); ?></a>
|
1384 |
+
</td>
|
1385 |
+
</tr>
|
1386 |
+
</tbody>
|
1387 |
+
</table>
|
1388 |
|
1389 |
<h3><?php esc_html_e( 'Purge the WordPress activity log', 'wp-security-audit-log' ); ?></h3>
|
1390 |
<p class="description"><?php esc_html_e( 'Click the Purge button below to delete all the data from the WordPress activity log and start afresh.', 'wp-security-audit-log' ); ?></p>
|
1399 |
</tbody>
|
1400 |
</table>
|
1401 |
|
1402 |
+
<?php $stealth_mode = $this->plugin->settings()->is_stealth_mode(); ?>
|
1403 |
<h3><?php esc_html_e( 'MainWP Child Site Stealth Mode', 'wp-security-audit-log' ); ?></h3>
|
1404 |
<p class="description"><?php esc_html_e( 'This option is enabled automatically when the plugin detects the MainWP Child plugin on the site. When this setting is enabled plugin access is restricted to the administrator who installs the plugin, the plugin is not shown in the list of installed plugins and no admin notifications are shown. Disable this option to change the plugin to the default setup.', 'wp-security-audit-log' ); ?></p>
|
1405 |
<table class="form-table wsal-tab">
|
1423 |
</td>
|
1424 |
</tr>
|
1425 |
<!-- / MainWP Child Site Stealth Mode -->
|
1426 |
+
<?php $admin_blocking_plugins_support = $this->plugin->settings()->get_admin_blocking_plugin_support(); ?>
|
1427 |
<tr>
|
1428 |
<th>
|
1429 |
<label for="mwp_admin_blocking_support"><?php esc_html_e( 'Admin blocking plugins support', 'wp-security-audit-log' ); ?></label>
|
1442 |
</tbody>
|
1443 |
</table>
|
1444 |
|
1445 |
+
<?php
|
1446 |
+
$data_deletion_enabled = $this->plugin->settings()->is_delete_data();
|
1447 |
+
?>
|
1448 |
<h3><?php esc_html_e( 'Do you want to delete the plugin data from the database upon uninstall?', 'wp-security-audit-log' ); ?></h3>
|
1449 |
<p class="description"><?php esc_html_e( '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.', 'wp-security-audit-log' ); ?></p>
|
1450 |
<table class="form-table wsal-tab">
|
1455 |
<fieldset>
|
1456 |
<label for="delete_data_yes">
|
1457 |
<input type="radio" name="DeleteData" value="1" id="delete_data_yes" onclick="return delete_confirm(this);"
|
1458 |
+
<?php checked( $data_deletion_enabled ); ?>
|
1459 |
/>
|
1460 |
<?php esc_html_e( 'Yes', 'wp-security-audit-log' ); ?>
|
1461 |
</label>
|
1462 |
<br>
|
1463 |
<label for="delete_data_no">
|
1464 |
<input type="radio" name="DeleteData" value="0" id="delete_data_no"
|
1465 |
+
<?php checked( $data_deletion_enabled, false ); ?>
|
1466 |
/>
|
1467 |
<?php esc_html_e( 'No', 'wp-security-audit-log' ); ?>
|
1468 |
</label>
|
1473 |
</tbody>
|
1474 |
</table>
|
1475 |
|
1476 |
+
<div class="remodal" data-remodal-id="wsal_reset_settings">
|
1477 |
+
<button data-remodal-action="close" class="remodal-close"></button>
|
1478 |
+
<h3><?php esc_html_e( 'Are you sure you want to reset all the plugin settings to default? This action cannot be undone.', 'wp-security-audit-log' ); ?></h3>
|
1479 |
+
<br>
|
1480 |
+
<input type="hidden" id="wsal-reset-settings-nonce" value="<?php echo esc_attr( wp_create_nonce( 'wsal-reset-settings' ) ); ?>">
|
1481 |
+
<button data-remodal-action="confirm" class="remodal-confirm"><?php esc_html_e( 'Yes' ); ?></button>
|
1482 |
+
<button data-remodal-action="cancel" class="remodal-cancel"><?php esc_html_e( 'No' ); ?></button>
|
1483 |
+
</div>
|
1484 |
+
<!-- Reset Settings Modal -->
|
1485 |
|
1486 |
<div class="remodal" data-remodal-id="wsal_purge_activity">
|
1487 |
<button data-remodal-action="close" class="remodal-close"></button>
|
1504 |
// Get $_POST global array.
|
1505 |
$post_array = filter_input_array( INPUT_POST );
|
1506 |
|
1507 |
+
$this->plugin->settings()->set_delete_data( isset( $post_array['DeleteData'] ) ? sanitize_text_field( $post_array['DeleteData'] ) : false );
|
1508 |
|
1509 |
$stealth_mode = isset( $post_array['mwp_stealth_mode'] ) ? $post_array['mwp_stealth_mode'] : false;
|
1510 |
if ( 'yes' === $stealth_mode ) {
|
1511 |
if ( ! WpSecurityAuditLog::is_mainwp_active() ) {
|
1512 |
throw new Exception( __( 'MainWP Child plugin is not active on this website.', 'wp-security-audit-log' ) );
|
1513 |
}
|
1514 |
+
$this->plugin->settings()->set_mainwp_child_stealth_mode();
|
1515 |
|
1516 |
$admin_blocking_plugins_support = isset( $post_array['mwp_admin_blocking_support'] ) ? $post_array['mwp_admin_blocking_support'] : false;
|
1517 |
if ( 'yes' === $admin_blocking_plugins_support ) {
|
1518 |
+
$this->plugin->settings()->set_admin_blocking_plugin_support( true );
|
1519 |
}
|
1520 |
} else {
|
1521 |
+
$this->plugin->settings()->deactivate_mainwp_child_stealth_mode();
|
1522 |
}
|
1523 |
}
|
1524 |
|
1525 |
/**
|
1526 |
+
* {@inheritDoc}
|
1527 |
*/
|
1528 |
+
public function header() {
|
1529 |
wp_enqueue_style(
|
1530 |
'settings',
|
1531 |
+
$this->plugin->get_base_url() . '/css/settings.css',
|
1532 |
array(),
|
1533 |
+
filemtime( $this->plugin->get_base_dir() . '/css/settings.css' )
|
1534 |
);
|
1535 |
|
1536 |
// Check current tab.
|
1540 |
wp_enqueue_style( 'wsal-remodal-theme', WSAL_BASE_URL . 'css/remodal-default-theme.css', array(), '1.1.1' );
|
1541 |
}
|
1542 |
?>
|
1543 |
+
<style type="text/css">
|
1544 |
+
.wsal-tab {
|
1545 |
+
/* display: none; */
|
1546 |
+
}
|
1547 |
+
.wsal-tab tr.alert-incomplete td {
|
1548 |
+
color: #9BE;
|
1549 |
+
}
|
1550 |
+
.wsal-tab tr.alert-unavailable td {
|
1551 |
+
color: #CCC;
|
1552 |
+
}
|
1553 |
+
</style>
|
1554 |
<?php
|
1555 |
}
|
1556 |
|
1557 |
/**
|
1558 |
+
* {@inheritDoc}
|
1559 |
*/
|
1560 |
+
public function footer() {
|
1561 |
// Enqueue jQuery UI from core.
|
1562 |
wp_enqueue_script(
|
1563 |
'wsal-jquery-ui',
|
1582 |
// Register settings script.
|
1583 |
wp_register_script(
|
1584 |
'settings',
|
1585 |
+
$this->plugin->get_base_url() . '/js/settings.js',
|
1586 |
array(),
|
1587 |
+
filemtime( $this->plugin->get_base_dir() . '/js/settings.js' ),
|
1588 |
true
|
1589 |
);
|
1590 |
// Passing nonce for security to JS file.
|
1603 |
wp_localize_script( 'settings', 'wsal_data', $wsal_data );
|
1604 |
wp_enqueue_script( 'settings' );
|
1605 |
?>
|
1606 |
+
<script type="text/javascript">
|
1607 |
+
jQuery( document ).ready( function() {
|
1608 |
+
jQuery( '.sel-columns' ).change( function() {
|
1609 |
+
var notChecked = 1;
|
1610 |
+
jQuery( '.sel-columns' ).each( function() {
|
1611 |
+
if ( this.checked ) notChecked = 0;
|
1612 |
+
})
|
1613 |
+
if ( notChecked == 1 ) {
|
1614 |
+
alert( "<?php esc_html_e( 'You have to select at least one column!', 'wp-security-audit-log' ); ?>" );
|
1615 |
+
}
|
1616 |
+
});
|
1617 |
+
});</script>
|
1618 |
<?php
|
1619 |
}
|
1620 |
|
1621 |
/**
|
1622 |
* Method: Ajax Request handler for AjaxGetAllUsers.
|
1623 |
*/
|
1624 |
+
public function ajax_get_all_users() {
|
1625 |
// Filter $_GET array for security.
|
1626 |
$get_array = filter_input_array( INPUT_GET );
|
1627 |
$this->check_ajax_request_is_valid( $get_array );
|
1640 |
/**
|
1641 |
* Method: Ajax Request handler for AjaxGetAllRoles.
|
1642 |
*/
|
1643 |
+
public function ajax_get_all_roles() {
|
1644 |
// Filter $_GET array for security.
|
1645 |
$get_array = filter_input_array( INPUT_GET );
|
1646 |
$this->check_ajax_request_is_valid( $get_array );
|
1667 |
$get_array = filter_input_array( INPUT_GET );
|
1668 |
$this->check_ajax_request_is_valid( $get_array );
|
1669 |
|
1670 |
+
echo $this->filter_values_for_searched_term( // phpcs:ignore
|
1671 |
+
array_values( WSAL_ConstantManager::get_severities() ),
|
1672 |
+
$get_array['term'] // phpcs:ignore
|
1673 |
+
);
|
1674 |
exit;
|
1675 |
}
|
1676 |
|
1677 |
/**
|
1678 |
* Filters values to return ones matching the desired term.
|
1679 |
*
|
1680 |
+
* @param array $items_to_filter List of items to filter.
|
1681 |
+
* @param string $term Search term.
|
1682 |
+
*
|
1683 |
+
* @return string JSON encoded filtered list.
|
1684 |
*/
|
1685 |
public function filter_values_for_searched_term( $items_to_filter, $term ) {
|
1686 |
|
1687 |
+
$result = array_filter(
|
1688 |
+
$items_to_filter,
|
1689 |
+
function( $value ) use ( $term ) {
|
1690 |
+
return strpos( strtolower( $value ), strtolower( $term ) ) !== false;
|
1691 |
+
}
|
1692 |
+
);
|
1693 |
|
1694 |
return wp_json_encode( $result );
|
1695 |
}
|
1705 |
$get_array = filter_input_array( INPUT_GET );
|
1706 |
$this->check_ajax_request_is_valid( $get_array );
|
1707 |
|
1708 |
+
$event_types = $this->plugin->alerts->get_event_type_data();
|
1709 |
|
1710 |
+
echo $this->filter_values_for_searched_term( array_values( $event_types ), $get_array['term'] ); // phpcs:ignore
|
1711 |
exit;
|
1712 |
}
|
1713 |
|
1722 |
$get_array = filter_input_array( INPUT_GET );
|
1723 |
$this->check_ajax_request_is_valid( $get_array );
|
1724 |
|
1725 |
+
$event_objects = $this->plugin->alerts->get_event_objects_data();
|
1726 |
|
1727 |
+
echo $this->filter_values_for_searched_term( array_values( $event_objects ), $get_array['term'] ); // phpcs:ignore
|
1728 |
exit;
|
1729 |
}
|
1730 |
|
1739 |
$get_array = filter_input_array( INPUT_GET );
|
1740 |
$this->check_ajax_request_is_valid( $get_array );
|
1741 |
|
1742 |
+
$registered_alerts = $this->plugin->alerts->get_alerts();
|
1743 |
|
1744 |
+
$alerts = array();
|
1745 |
foreach ( $registered_alerts as $alert => $details ) {
|
1746 |
$alerts[] = (string) $details->code;
|
1747 |
}
|
1748 |
|
1749 |
+
echo $this->filter_values_for_searched_term( array_values( $alerts ), $get_array['term'] ); // phpcs:ignore
|
1750 |
exit;
|
1751 |
}
|
1752 |
|
1755 |
*
|
1756 |
* @since 2.6.7
|
1757 |
*/
|
1758 |
+
public function ajax_get_all_cpts() {
|
1759 |
// Filter $_GET array for security.
|
1760 |
$get_array = filter_input_array( INPUT_GET );
|
1761 |
$this->check_ajax_request_is_valid( $get_array );
|
1762 |
|
1763 |
// Get custom post types.
|
1764 |
$custom_post_types = array();
|
1765 |
+
$post_types = get_post_types(
|
1766 |
+
array(
|
1767 |
+
'public' => false,
|
1768 |
+
),
|
1769 |
+
'names'
|
1770 |
+
);
|
1771 |
// if we are running multisite and have networkwide cpt tracker get the
|
1772 |
// list from and merge to the post_types array.
|
1773 |
if ( is_multisite() && class_exists( '\WSAL\Multisite\NetworkWide\CPTsTracker' ) ) {
|
1776 |
$post_types[ $cpt ] = $cpt;
|
1777 |
}
|
1778 |
}
|
1779 |
+
|
1780 |
$post_types = array_diff( $post_types, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) );
|
1781 |
foreach ( $post_types as $post_type ) {
|
1782 |
if ( strpos( $post_type, $get_array['term'] ) !== false ) {
|
1790 |
/**
|
1791 |
* Checks if provided GET array is valid and bails if not.
|
1792 |
*
|
1793 |
+
* @param array $get_array Get data.
|
|
|
1794 |
*/
|
1795 |
public function check_ajax_request_is_valid( $get_array ) {
|
1796 |
// Die if user does not have permission to edit.
|
1797 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
1798 |
die( 'Access Denied.' );
|
1799 |
}
|
1800 |
+
|
1801 |
// Die if nonce verification failed.
|
1802 |
if ( ! wp_verify_nonce( $get_array['wsal_nonce'], 'wsal-exclude-nonce' ) ) {
|
1803 |
die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
1809 |
*/
|
1810 |
public function reset_settings() {
|
1811 |
// Die if user does not have permission to change settings.
|
1812 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
1813 |
wp_send_json_error( esc_html__( 'Access Denied.', 'wp-security-audit-log' ) );
|
1814 |
}
|
1815 |
|
1819 |
wp_send_json_error( esc_html__( 'Nonce Verification Failed.', 'wp-security-audit-log' ) );
|
1820 |
}
|
1821 |
|
1822 |
+
// Delete all settings.
|
1823 |
+
WSAL_Uninstall::delete_options_from_wp_options();
|
1824 |
|
1825 |
+
// Log settings reset event.
|
1826 |
+
$this->plugin->alerts->trigger_event( 6006 );
|
1827 |
+
wp_send_json_success( esc_html__( 'Plugin settings have been reset.', 'wp-security-audit-log' ) );
|
1828 |
}
|
1829 |
|
1830 |
/**
|
1831 |
* Method: Purge plugin occurrence & meta tables.
|
1832 |
*/
|
1833 |
+
public function purge_activity() {
|
1834 |
// Die if user does not have permission to change settings.
|
1835 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
1836 |
wp_send_json_error( esc_html__( 'Access Denied.', 'wp-security-audit-log' ) );
|
1837 |
}
|
1838 |
|
1842 |
wp_send_json_error( esc_html__( 'Nonce Verification Failed.', 'wp-security-audit-log' ) );
|
1843 |
}
|
1844 |
|
1845 |
+
$connector = WpSecurityAuditLog::get_connector();
|
1846 |
+
$result = $connector->purge_activity();
|
1847 |
|
1848 |
+
if ( $result ) {
|
1849 |
+
// Log purge activity event.
|
1850 |
+
$this->plugin->alerts->trigger_event( 6034 );
|
1851 |
+
wp_send_json_success( esc_html__( 'Tables has been reset.', 'wp-security-audit-log' ) );
|
1852 |
+
} else {
|
1853 |
+
wp_send_json_error( esc_html__( 'Reset query failed.', 'wp-security-audit-log' ) );
|
1854 |
+
}
|
1855 |
}
|
1856 |
|
1857 |
+
/**
|
1858 |
+
* Renders table with retention related settings.
|
1859 |
+
*/
|
1860 |
+
public function render_retention_settings_table() {
|
1861 |
+
// Check if the retention settings are enforced from the MainWP master site.
|
1862 |
+
$settings = $this->plugin->settings();
|
1863 |
+
$enforced_settings = $settings->get_mainwp_enforced_settings();
|
1864 |
+
$retention_settings_enforced_by_mainwp = array_key_exists( 'pruning_enabled', $enforced_settings );
|
1865 |
+
?>
|
1866 |
+
<table class="form-table wsal-tab">
|
1867 |
+
<tbody>
|
1868 |
+
<tr>
|
1869 |
+
<th><label for="delete1"><?php esc_html_e( 'Activity log retention', 'wp-security-audit-log' ); ?></label></th>
|
1870 |
+
<td>
|
1871 |
+
<fieldset>
|
1872 |
+
<?php $nbld = ! $this->plugin->settings()->is_pruning_date_enabled(); ?>
|
1873 |
+
<label for="delete0">
|
1874 |
+
<input type="radio" id="delete0" name="PruneBy" value="" <?php checked( $nbld ); ?>
|
1875 |
+
<?php disabled( $retention_settings_enforced_by_mainwp ); ?> />
|
1876 |
+
<?php esc_html_e( 'Keep all data', 'wp-security-audit-log' ); ?>
|
1877 |
+
</label>
|
1878 |
+
</fieldset>
|
1879 |
+
|
1880 |
+
<fieldset>
|
1881 |
+
<?php
|
1882 |
+
// Check pruning date option.
|
1883 |
+
$nbld = $this->plugin->settings()->is_pruning_date_enabled();
|
1884 |
+
|
1885 |
+
// Find and replace ` months` in the string.
|
1886 |
+
$pruning_date = $this->plugin->settings()->get_pruning_date();
|
1887 |
+
$pruning_date = preg_replace( '/[^0-9]/', '', $pruning_date );
|
1888 |
+
|
1889 |
+
$pruning_unit = $this->plugin->settings()->get_pruning_unit();
|
1890 |
+
|
1891 |
+
$pruning_unit_options = array(
|
1892 |
'days' => esc_html__( 'Days', 'wp-security-audit-log' ),
|
1893 |
'months' => esc_html__( 'Months', 'wp-security-audit-log' ),
|
1894 |
'years' => esc_html__( 'Years', 'wp-security-audit-log' ),
|
1895 |
+
);
|
1896 |
+
|
1897 |
+
// Check if pruning limit was enabled for backwards compatibility.
|
1898 |
+
if ( $this->plugin->settings()->is_pruning_limit_enabled() ) {
|
1899 |
+
$nbld = true;
|
1900 |
+
$pruning_date = '6';
|
1901 |
+
$pruning_unit = 'months';
|
1902 |
+
$this->plugin->settings()->set_pruning_date( $pruning_date . ' ' . $pruning_unit );
|
1903 |
+
$this->plugin->settings()->set_pruning_date_enabled( true );
|
1904 |
+
$this->plugin->settings()->set_pruning_limit_enabled( false );
|
1905 |
+
}
|
1906 |
+
?>
|
1907 |
+
<label for="delete1">
|
1908 |
+
<input type="radio" id="delete1" name="PruneBy" value="date" <?php checked( $nbld ); ?>
|
1909 |
+
<?php disabled( $retention_settings_enforced_by_mainwp ); ?> />
|
1910 |
+
<?php esc_html_e( 'Delete events older than', 'wp-security-audit-log' ); ?>
|
1911 |
+
</label>
|
1912 |
+
<input type="text" id="PruningDate" name="PruningDate"
|
1913 |
+
value="<?php echo esc_attr( $pruning_date ); ?>"
|
1914 |
+
onfocus="jQuery('#delete1').attr('checked', true);"
|
1915 |
+
<?php disabled( $retention_settings_enforced_by_mainwp ); ?>
|
1916 |
+
/>
|
1917 |
+
<select name="pruning-unit" id="pruning-unit" <?php disabled( $retention_settings_enforced_by_mainwp ); ?>>
|
1918 |
+
<?php
|
1919 |
+
foreach ( $pruning_unit_options as $option => $label ) {
|
1920 |
+
echo '<option value="' . esc_attr( $option ) . '" ' . selected( $pruning_unit, $option, true ) . '>' . ucwords( $label ) . '</option>'; // phpcs:disable
|
1921 |
+
}
|
1922 |
+
?>
|
1923 |
+
</select>
|
1924 |
+
</fieldset>
|
1925 |
+
|
1926 |
+
<?php if ( $this->plugin->settings()->is_pruning_date_enabled() ) : ?>
|
1927 |
+
<p class="description">
|
1928 |
+
<?php
|
1929 |
+
$next = wp_next_scheduled( 'wsal_cleanup' );
|
1930 |
+
echo esc_html__( 'The next scheduled purging of activity log data that is older than ', 'wp-security-audit-log' );
|
1931 |
+
echo esc_html( $pruning_date . ' ' . $pruning_unit );
|
1932 |
+
echo sprintf(
|
1933 |
+
' is in %s.',
|
1934 |
+
esc_html( human_time_diff( current_time( 'timestamp' ), $next ) )
|
1935 |
+
);
|
1936 |
+
echo '<!-- ' . esc_html( date( 'dMy H:i:s', $next ) ) . ' --> ';
|
1937 |
+
echo esc_html__( 'You can run the purging process now by clicking the button below.', 'wp-security-audit-log' );
|
1938 |
+
?>
|
1939 |
+
</p>
|
1940 |
+
<p>
|
1941 |
+
<a class="button-primary" href="<?php echo esc_url( add_query_arg( 'action', 'AjaxRunCleanup', admin_url( 'admin-ajax.php' ) ) ); ?>"><?php esc_html_e( 'Purge Old Data', 'wp-security-audit-log' ); ?></a>
|
1942 |
+
</p>
|
1943 |
+
<?php endif; ?>
|
1944 |
+
</td>
|
1945 |
+
</tr>
|
1946 |
+
<!-- Activity log retention -->
|
1947 |
+
</tbody>
|
1948 |
+
</table>
|
1949 |
+
<?php
|
1950 |
+
}
|
1951 |
}
|
classes/Views/SetupWizard.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* WSAL setup class file.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -18,6 +19,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
18 |
*
|
19 |
* WSAL setup wizard class which manages the functionality
|
20 |
* related to setup.
|
|
|
|
|
|
|
21 |
*/
|
22 |
final class WSAL_Views_SetupWizard {
|
23 |
|
@@ -26,7 +30,7 @@ final class WSAL_Views_SetupWizard {
|
|
26 |
*
|
27 |
* @var WpSecurityAuditLog
|
28 |
*/
|
29 |
-
private $
|
30 |
|
31 |
/**
|
32 |
* Wizard Steps
|
@@ -62,9 +66,9 @@ final class WSAL_Views_SetupWizard {
|
|
62 |
* @param WpSecurityAuditLog $wsal – Instance of main plugin.
|
63 |
*/
|
64 |
public function __construct( WpSecurityAuditLog $wsal ) {
|
65 |
-
$this->
|
66 |
|
67 |
-
if ( $wsal->settings()->
|
68 |
add_action( 'admin_init', array( $this, 'setup_page' ), 10 );
|
69 |
add_action( 'admin_menu', array( $this, 'admin_menus' ), 10 );
|
70 |
add_action( 'network_admin_menu', array( $this, 'admin_menus' ), 10 );
|
@@ -76,7 +80,7 @@ final class WSAL_Views_SetupWizard {
|
|
76 |
* Ajax handler to verify setting token.
|
77 |
*/
|
78 |
public function setup_check_security_token() {
|
79 |
-
if ( ! $this->
|
80 |
echo wp_json_encode(
|
81 |
array(
|
82 |
'success' => false,
|
@@ -154,7 +158,7 @@ final class WSAL_Views_SetupWizard {
|
|
154 |
$all_plugins = get_plugins();
|
155 |
$plugin_filenames = array();
|
156 |
foreach ( $all_plugins as $plugin => $info ) {
|
157 |
-
$plugin_info
|
158 |
$plugin_filenames[] = $plugin_info['filename'];
|
159 |
}
|
160 |
|
@@ -174,31 +178,31 @@ final class WSAL_Views_SetupWizard {
|
|
174 |
* Wizard Steps.
|
175 |
*/
|
176 |
$wizard_steps = array(
|
177 |
-
'welcome'
|
178 |
'name' => __( 'Welcome', 'wp-security-audit-log' ),
|
179 |
'content' => array( $this, 'wsal_step_welcome' ),
|
180 |
),
|
181 |
-
'log_details'
|
182 |
'name' => __( 'Log Details', 'wp-security-audit-log' ),
|
183 |
'content' => array( $this, 'wsal_step_log_details' ),
|
184 |
'save' => array( $this, 'wsal_step_log_details_save' ),
|
185 |
),
|
186 |
-
'login'
|
187 |
'name' => __( 'Log In', 'wp-security-audit-log' ),
|
188 |
'content' => array( $this, 'wsal_step_login' ),
|
189 |
'save' => array( $this, 'wsal_step_login_save' ),
|
190 |
),
|
191 |
-
'register'
|
192 |
'name' => __( 'User Registrations', 'wp-security-audit-log' ),
|
193 |
'content' => array( $this, 'wsal_step_register' ),
|
194 |
'save' => array( $this, 'wsal_step_register_save' ),
|
195 |
),
|
196 |
-
'log_retention'
|
197 |
'name' => __( 'Log Retention', 'wp-security-audit-log' ),
|
198 |
'content' => array( $this, 'wsal_step_log_retention' ),
|
199 |
'save' => array( $this, 'wsal_step_log_retention_save' ),
|
200 |
),
|
201 |
-
'finish'
|
202 |
'name' => __( 'Finish', 'wp-security-audit-log' ),
|
203 |
'content' => array( $this, 'wsal_step_finish' ),
|
204 |
'save' => array( $this, 'wsal_step_finish_save' ),
|
@@ -226,39 +230,39 @@ final class WSAL_Views_SetupWizard {
|
|
226 |
/**
|
227 |
* Enqueue Styles.
|
228 |
*/
|
229 |
-
$wizard_css = WSAL_ViewManager::get_asset_path('
|
230 |
wp_enqueue_style(
|
231 |
'wsal-wizard-css',
|
232 |
-
$this->
|
233 |
array( 'dashicons', 'install', 'forms' ),
|
234 |
-
filemtime( $this->
|
235 |
);
|
236 |
|
237 |
/**
|
238 |
* Enqueue Scripts.
|
239 |
*/
|
240 |
-
$wizard_js = WSAL_ViewManager::get_asset_path( '
|
241 |
wp_register_script(
|
242 |
-
|
243 |
-
$this->
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
wp_register_script(
|
251 |
'wsal-common',
|
252 |
-
$this->
|
253 |
array( 'jquery' ),
|
254 |
-
filemtime( $this->
|
255 |
true
|
256 |
-
|
257 |
|
258 |
// Data array.
|
259 |
$data_array = array(
|
260 |
'ajaxURL' => admin_url( 'admin-ajax.php' ),
|
261 |
-
'nonce' => ( ( ! $this->
|
262 |
'usersError' => esc_html__( 'Specified value in not a user.', 'wp-security-audit-log' ),
|
263 |
'rolesError' => esc_html__( 'Specified value in not a role.', 'wp-security-audit-log' ),
|
264 |
'ipError' => esc_html__( 'Specified value in not an IP address.', 'wp-security-audit-log' ),
|
@@ -272,11 +276,10 @@ final class WSAL_Views_SetupWizard {
|
|
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 |
-
|
276 |
);
|
277 |
wp_localize_script( 'wsal-common', 'wsalCommonData', $installer_script_data );
|
278 |
|
279 |
-
|
280 |
/**
|
281 |
* Save Wizard Settings.
|
282 |
*/
|
@@ -309,7 +312,7 @@ final class WSAL_Views_SetupWizard {
|
|
309 |
<?php do_action( 'admin_print_styles' ); ?>
|
310 |
</head>
|
311 |
<body class="wsal-setup wp-core-ui">
|
312 |
-
<h1 id="wsal-logo"><a href="https://wpactivitylog.com/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=wizard+configuration" rel="noopener noreferrer" target="_blank"><img src="<?php echo esc_url( $this->
|
313 |
<?php
|
314 |
}
|
315 |
|
@@ -409,25 +412,23 @@ final class WSAL_Views_SetupWizard {
|
|
409 |
* @since 4.0.2
|
410 |
*/
|
411 |
private function render_invalid_step() {
|
412 |
-
|
413 |
-
<p><?php
|
414 |
printf(
|
415 |
/* translators: 1 - an opening link tag, 2 - a closing link tag. */
|
416 |
esc_html__( 'You have reached an invaild step - %1$sreturn to the start of the wizard%2$s.', 'wp-security-audit-log' ),
|
417 |
'<a href="' . esc_url( $this->get_welcome_step() ) . '">',
|
418 |
'</a>'
|
419 |
);
|
420 |
-
|
421 |
-
<?php
|
422 |
}
|
423 |
|
424 |
/**
|
425 |
* Step View: `Welcome`
|
426 |
*/
|
427 |
private function wsal_step_welcome() {
|
428 |
-
//
|
429 |
-
if ( ! $this->
|
430 |
-
$this->
|
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>
|
@@ -489,11 +490,11 @@ final class WSAL_Views_SetupWizard {
|
|
489 |
}
|
490 |
|
491 |
// Save log details option.
|
492 |
-
$this->
|
493 |
if ( ! empty( $log_details ) && 'basic' === $log_details ) {
|
494 |
-
$this->
|
495 |
} elseif ( ! empty( $log_details ) && 'geek' === $log_details ) {
|
496 |
-
$this->
|
497 |
}
|
498 |
|
499 |
wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
|
@@ -539,7 +540,7 @@ final class WSAL_Views_SetupWizard {
|
|
539 |
if ( isset( $_POST['wsal-frontend-login'] ) ) {
|
540 |
$frontend_sensors = WSAL_Settings::get_frontend_events(); // Get the frontend sensors setting.
|
541 |
$login_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-login'] ) );
|
542 |
-
$login_sensor = '1' === $login_sensor
|
543 |
|
544 |
$frontend_sensors['login'] = $login_sensor;
|
545 |
WSAL_Settings::set_frontend_events( $frontend_sensors );
|
@@ -588,7 +589,7 @@ final class WSAL_Views_SetupWizard {
|
|
588 |
if ( isset( $_POST['wsal-frontend-register'] ) ) {
|
589 |
$frontend_sensors = WSAL_Settings::get_frontend_events(); // Get the frontend sensors setting.
|
590 |
$register_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-register'] ) );
|
591 |
-
$register_sensor = '1' === $register_sensor
|
592 |
|
593 |
$frontend_sensors['register'] = $register_sensor;
|
594 |
WSAL_Settings::set_frontend_events( $frontend_sensors );
|
@@ -644,7 +645,7 @@ final class WSAL_Views_SetupWizard {
|
|
644 |
// Step help text.
|
645 |
$step_help = __( '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.', 'wp-security-audit-log' );
|
646 |
|
647 |
-
echo wp_kses( $step_help, $this->
|
648 |
?>
|
649 |
</em>
|
650 |
</p>
|
@@ -673,13 +674,13 @@ final class WSAL_Views_SetupWizard {
|
|
673 |
case '6':
|
674 |
case '12':
|
675 |
// 6 or 12 months.
|
676 |
-
$this->
|
677 |
-
$this->
|
678 |
break;
|
679 |
|
680 |
case 'none':
|
681 |
// None.
|
682 |
-
$this->
|
683 |
break;
|
684 |
|
685 |
default:
|
@@ -697,7 +698,7 @@ final class WSAL_Views_SetupWizard {
|
|
697 |
* @param string $token - Token type.
|
698 |
*/
|
699 |
protected function get_token_type( $token ) {
|
700 |
-
return $this->
|
701 |
}
|
702 |
|
703 |
/**
|
@@ -731,7 +732,7 @@ final class WSAL_Views_SetupWizard {
|
|
731 |
$help_page = 'https://wpactivitylog.com/contact/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages';
|
732 |
?>
|
733 |
|
734 |
-
<p><?php echo wp_kses( __( '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', 'wp-security-audit-log' ), $this->
|
735 |
|
736 |
<form method="post" class="wsal-setup-form">
|
737 |
<?php wp_nonce_field( 'wsal-step-finish' ); ?>
|
@@ -755,18 +756,20 @@ final class WSAL_Views_SetupWizard {
|
|
755 |
check_admin_referer( 'wsal-step-finish' );
|
756 |
|
757 |
// Mark the finish of the setup.
|
758 |
-
$this->
|
759 |
|
760 |
wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
|
761 |
exit();
|
762 |
}
|
763 |
|
764 |
/**
|
765 |
-
* 3rd Party plugins
|
|
|
|
|
766 |
*/
|
767 |
-
function wsal_add_wizard_step( $wizard_steps ) {
|
768 |
$new_wizard_steps = array(
|
769 |
-
'test'
|
770 |
'name' => __( 'Third Party Extensions', 'wp-security-audit-log' ),
|
771 |
'content' => array( $this, 'addons_step' ),
|
772 |
'save' => array( $this, 'addons_step_save' ),
|
@@ -776,11 +779,11 @@ final class WSAL_Views_SetupWizard {
|
|
776 |
// Count number of items in the array.
|
777 |
$number_of_steps = count( $wizard_steps );
|
778 |
// Subtract 1, as we want to insert our step one before the last item.
|
779 |
-
$number_of_steps
|
780 |
|
781 |
// Slice the steps up, so we have 2 parts we can insert our slide between.
|
782 |
$first_part = array_slice( $wizard_steps, 0, $number_of_steps, true );
|
783 |
-
$last_part
|
784 |
|
785 |
// combine the two arrays.
|
786 |
$wizard_steps = $first_part + $new_wizard_steps + $last_part;
|
@@ -788,6 +791,9 @@ final class WSAL_Views_SetupWizard {
|
|
788 |
return $wizard_steps;
|
789 |
}
|
790 |
|
|
|
|
|
|
|
791 |
private function addons_step() {
|
792 |
$our_plugins = WSAL_PluginInstallAndActivate::get_installable_plugins();
|
793 |
|
@@ -795,7 +801,7 @@ final class WSAL_Views_SetupWizard {
|
|
795 |
$all_plugins = get_plugins();
|
796 |
$plugin_filenames = array();
|
797 |
foreach ( $all_plugins as $plugin => $info ) {
|
798 |
-
$plugin_info
|
799 |
$plugin_filenames[] = $plugin_info['filename'];
|
800 |
}
|
801 |
|
@@ -812,7 +818,7 @@ final class WSAL_Views_SetupWizard {
|
|
812 |
<p><?php esc_html_e( '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.', 'wp-security-audit-log' ); ?></p>
|
813 |
<?php
|
814 |
// Create a nonce to pass through via data attr.
|
815 |
-
$nonce
|
816 |
|
817 |
// Loop through plugins and output.
|
818 |
foreach ( $our_plugins as $details ) {
|
@@ -820,7 +826,7 @@ final class WSAL_Views_SetupWizard {
|
|
820 |
if ( WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) || 'wsal-wpforms.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_wpforms_init_actions' ) || 'wsal-bbpress.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_bbpress_init_actions' ) ) {
|
821 |
$disable_button = 'disabled';
|
822 |
}
|
823 |
-
if ( ! in_array( $details['addon_for'], $we_have_addon ) ) {
|
824 |
continue;
|
825 |
}
|
826 |
// Check if this is actually an addon for something, otherwise bail.
|
@@ -833,7 +839,7 @@ final class WSAL_Views_SetupWizard {
|
|
833 |
<img src="<?php echo esc_url( trailingslashit( WSAL_BASE_URL ) . 'img/addons/' . $details['image_filename'] ); ?>">
|
834 |
<div class="addon-content">
|
835 |
<h5><?php esc_html_e( 'Extension for ', 'wp-security-audit-log' ); ?><?php echo esc_html( $details['title'] ); ?></h5>
|
836 |
-
<p><?php echo sanitize_text_field( $details['plugin_description'] ); ?></p>
|
837 |
<p><button class="install-addon button button-primary <?php echo esc_attr( $disable_button ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>" data-plugin-slug="<?php echo esc_attr( $details['plugin_slug'] ); ?>" data-plugin-download-url="<?php echo esc_url( $details['plugin_url'] ); ?>" data-plugin-event-tab-id="<?php echo esc_attr( $details['event_tab_id'] ); ?>">
|
838 |
<?php
|
839 |
if ( WSAL_PluginInstallAndActivate::is_plugin_installed( $details['plugin_slug'] ) && ! WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) ) {
|
@@ -848,8 +854,8 @@ final class WSAL_Views_SetupWizard {
|
|
848 |
</div>
|
849 |
</div>
|
850 |
<?php
|
851 |
-
|
852 |
-
|
853 |
<div class="wsal-setup-actions">
|
854 |
<button class="button button-primary"
|
855 |
type="submit"
|
@@ -872,5 +878,4 @@ final class WSAL_Views_SetupWizard {
|
|
872 |
wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
|
873 |
exit();
|
874 |
}
|
875 |
-
|
876 |
}
|
4 |
*
|
5 |
* WSAL setup class file.
|
6 |
*
|
7 |
+
* @since 3.2.3
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
19 |
*
|
20 |
* WSAL setup wizard class which manages the functionality
|
21 |
* related to setup.
|
22 |
+
*
|
23 |
+
* @package wsal
|
24 |
+
* @subpackage views
|
25 |
*/
|
26 |
final class WSAL_Views_SetupWizard {
|
27 |
|
30 |
*
|
31 |
* @var WpSecurityAuditLog
|
32 |
*/
|
33 |
+
private $plugin;
|
34 |
|
35 |
/**
|
36 |
* Wizard Steps
|
66 |
* @param WpSecurityAuditLog $wsal – Instance of main plugin.
|
67 |
*/
|
68 |
public function __construct( WpSecurityAuditLog $wsal ) {
|
69 |
+
$this->plugin = $wsal;
|
70 |
|
71 |
+
if ( $wsal->settings()->current_user_can( 'edit' ) ) {
|
72 |
add_action( 'admin_init', array( $this, 'setup_page' ), 10 );
|
73 |
add_action( 'admin_menu', array( $this, 'admin_menus' ), 10 );
|
74 |
add_action( 'network_admin_menu', array( $this, 'admin_menus' ), 10 );
|
80 |
* Ajax handler to verify setting token.
|
81 |
*/
|
82 |
public function setup_check_security_token() {
|
83 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
84 |
echo wp_json_encode(
|
85 |
array(
|
86 |
'success' => false,
|
158 |
$all_plugins = get_plugins();
|
159 |
$plugin_filenames = array();
|
160 |
foreach ( $all_plugins as $plugin => $info ) {
|
161 |
+
$plugin_info = pathinfo( $plugin );
|
162 |
$plugin_filenames[] = $plugin_info['filename'];
|
163 |
}
|
164 |
|
178 |
* Wizard Steps.
|
179 |
*/
|
180 |
$wizard_steps = array(
|
181 |
+
'welcome' => array(
|
182 |
'name' => __( 'Welcome', 'wp-security-audit-log' ),
|
183 |
'content' => array( $this, 'wsal_step_welcome' ),
|
184 |
),
|
185 |
+
'log_details' => array(
|
186 |
'name' => __( 'Log Details', 'wp-security-audit-log' ),
|
187 |
'content' => array( $this, 'wsal_step_log_details' ),
|
188 |
'save' => array( $this, 'wsal_step_log_details_save' ),
|
189 |
),
|
190 |
+
'login' => array(
|
191 |
'name' => __( 'Log In', 'wp-security-audit-log' ),
|
192 |
'content' => array( $this, 'wsal_step_login' ),
|
193 |
'save' => array( $this, 'wsal_step_login_save' ),
|
194 |
),
|
195 |
+
'register' => array(
|
196 |
'name' => __( 'User Registrations', 'wp-security-audit-log' ),
|
197 |
'content' => array( $this, 'wsal_step_register' ),
|
198 |
'save' => array( $this, 'wsal_step_register_save' ),
|
199 |
),
|
200 |
+
'log_retention' => array(
|
201 |
'name' => __( 'Log Retention', 'wp-security-audit-log' ),
|
202 |
'content' => array( $this, 'wsal_step_log_retention' ),
|
203 |
'save' => array( $this, 'wsal_step_log_retention_save' ),
|
204 |
),
|
205 |
+
'finish' => array(
|
206 |
'name' => __( 'Finish', 'wp-security-audit-log' ),
|
207 |
'content' => array( $this, 'wsal_step_finish' ),
|
208 |
'save' => array( $this, 'wsal_step_finish_save' ),
|
230 |
/**
|
231 |
* Enqueue Styles.
|
232 |
*/
|
233 |
+
$wizard_css = WSAL_ViewManager::get_asset_path( 'css/dist/', 'wsal-wizard', 'css', false );
|
234 |
wp_enqueue_style(
|
235 |
'wsal-wizard-css',
|
236 |
+
$this->plugin->get_base_url() . '/' . $wizard_css,
|
237 |
array( 'dashicons', 'install', 'forms' ),
|
238 |
+
filemtime( $this->plugin->get_base_dir() . $wizard_css )
|
239 |
);
|
240 |
|
241 |
/**
|
242 |
* Enqueue Scripts.
|
243 |
*/
|
244 |
+
$wizard_js = WSAL_ViewManager::get_asset_path( 'js/dist/', 'wsal-wizard', 'js', false );
|
245 |
wp_register_script(
|
246 |
+
'wsal-wizard-js',
|
247 |
+
$this->plugin->get_base_url() . '/' . $wizard_js,
|
248 |
+
array( 'jquery' ),
|
249 |
+
filemtime( $this->plugin->get_base_dir() . $wizard_js ),
|
250 |
+
false
|
251 |
+
);
|
252 |
+
|
253 |
+
$common_js = '/js/common.js';
|
254 |
wp_register_script(
|
255 |
'wsal-common',
|
256 |
+
$this->plugin->get_base_url() . $common_js,
|
257 |
array( 'jquery' ),
|
258 |
+
filemtime( $this->plugin->get_base_dir() . $common_js ),
|
259 |
true
|
260 |
+
);
|
261 |
|
262 |
// Data array.
|
263 |
$data_array = array(
|
264 |
'ajaxURL' => admin_url( 'admin-ajax.php' ),
|
265 |
+
'nonce' => ( ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) && ! 'invalid-step' === $this->current_step ) ? wp_create_nonce( 'wsal-verify-wizard-page' ) : '',
|
266 |
'usersError' => esc_html__( 'Specified value in not a user.', 'wp-security-audit-log' ),
|
267 |
'rolesError' => esc_html__( 'Specified value in not a role.', 'wp-security-audit-log' ),
|
268 |
'ipError' => esc_html__( 'Specified value in not an IP address.', 'wp-security-audit-log' ),
|
276 |
'installed' => esc_html__( 'Extension installed', 'wp-security-audit-log' ),
|
277 |
'activated' => esc_html__( 'Extension activated', 'wp-security-audit-log' ),
|
278 |
'failed' => esc_html__( 'Install failed', 'wp-security-audit-log' ),
|
279 |
+
'reloading_page' => esc_html__( 'Reloading page', 'wp-security-audit-log' ),
|
280 |
);
|
281 |
wp_localize_script( 'wsal-common', 'wsalCommonData', $installer_script_data );
|
282 |
|
|
|
283 |
/**
|
284 |
* Save Wizard Settings.
|
285 |
*/
|
312 |
<?php do_action( 'admin_print_styles' ); ?>
|
313 |
</head>
|
314 |
<body class="wsal-setup wp-core-ui">
|
315 |
+
<h1 id="wsal-logo"><a href="https://wpactivitylog.com/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=wizard+configuration" rel="noopener noreferrer" target="_blank"><img src="<?php echo esc_url( $this->plugin->get_base_url() ); ?>/img/wsal-logo-full.png" alt="WP Activity Log" /></a></h1>
|
316 |
<?php
|
317 |
}
|
318 |
|
412 |
* @since 4.0.2
|
413 |
*/
|
414 |
private function render_invalid_step() {
|
415 |
+
echo '<p>';
|
|
|
416 |
printf(
|
417 |
/* translators: 1 - an opening link tag, 2 - a closing link tag. */
|
418 |
esc_html__( 'You have reached an invaild step - %1$sreturn to the start of the wizard%2$s.', 'wp-security-audit-log' ),
|
419 |
'<a href="' . esc_url( $this->get_welcome_step() ) . '">',
|
420 |
'</a>'
|
421 |
);
|
422 |
+
echo '</p>';
|
|
|
423 |
}
|
424 |
|
425 |
/**
|
426 |
* Step View: `Welcome`
|
427 |
*/
|
428 |
private function wsal_step_welcome() {
|
429 |
+
// Dismiss the setup modal in case if not already done.
|
430 |
+
if ( ! $this->plugin->get_global_boolean_setting( 'setup-modal-dismissed', false ) ) {
|
431 |
+
$this->plugin->set_global_boolean_setting( 'setup-modal-dismissed', true, true );
|
432 |
}
|
433 |
?>
|
434 |
<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>
|
490 |
}
|
491 |
|
492 |
// Save log details option.
|
493 |
+
$this->plugin->set_global_setting( 'details-level', $log_details );
|
494 |
if ( ! empty( $log_details ) && 'basic' === $log_details ) {
|
495 |
+
$this->plugin->settings()->set_basic_mode();
|
496 |
} elseif ( ! empty( $log_details ) && 'geek' === $log_details ) {
|
497 |
+
$this->plugin->settings()->set_geek_mode();
|
498 |
}
|
499 |
|
500 |
wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
|
540 |
if ( isset( $_POST['wsal-frontend-login'] ) ) {
|
541 |
$frontend_sensors = WSAL_Settings::get_frontend_events(); // Get the frontend sensors setting.
|
542 |
$login_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-login'] ) );
|
543 |
+
$login_sensor = '1' === $login_sensor; // Update the sensor option.
|
544 |
|
545 |
$frontend_sensors['login'] = $login_sensor;
|
546 |
WSAL_Settings::set_frontend_events( $frontend_sensors );
|
589 |
if ( isset( $_POST['wsal-frontend-register'] ) ) {
|
590 |
$frontend_sensors = WSAL_Settings::get_frontend_events(); // Get the frontend sensors setting.
|
591 |
$register_sensor = sanitize_text_field( wp_unslash( $_POST['wsal-frontend-register'] ) );
|
592 |
+
$register_sensor = '1' === $register_sensor; // Update the sensor option.
|
593 |
|
594 |
$frontend_sensors['register'] = $register_sensor;
|
595 |
WSAL_Settings::set_frontend_events( $frontend_sensors );
|
645 |
// Step help text.
|
646 |
$step_help = __( '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.', 'wp-security-audit-log' );
|
647 |
|
648 |
+
echo wp_kses( $step_help, $this->plugin->allowed_html_tags );
|
649 |
?>
|
650 |
</em>
|
651 |
</p>
|
674 |
case '6':
|
675 |
case '12':
|
676 |
// 6 or 12 months.
|
677 |
+
$this->plugin->set_global_boolean_setting( 'pruning-date-e', true );
|
678 |
+
$this->plugin->set_global_setting( 'pruning-date', $pruning_limit . ' months' );
|
679 |
break;
|
680 |
|
681 |
case 'none':
|
682 |
// None.
|
683 |
+
$this->plugin->set_global_boolean_setting( 'pruning-date-e', false );
|
684 |
break;
|
685 |
|
686 |
default:
|
698 |
* @param string $token - Token type.
|
699 |
*/
|
700 |
protected function get_token_type( $token ) {
|
701 |
+
return $this->plugin->settings()->get_token_type( $token );
|
702 |
}
|
703 |
|
704 |
/**
|
732 |
$help_page = 'https://wpactivitylog.com/contact/?utm_source=plugin&utm_medium=referral&utm_campaign=WSAL&utm_content=settings+pages';
|
733 |
?>
|
734 |
|
735 |
+
<p><?php echo wp_kses( __( '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', 'wp-security-audit-log' ), $this->plugin->allowed_html_tags ); ?> <a href="<?php echo esc_url( $help_page ); ?>" rel="noopener noreferrer" target="_blank"><?php esc_html_e( 'please get in touch!', 'wp-security-audit-log' ); ?></a></p>
|
736 |
|
737 |
<form method="post" class="wsal-setup-form">
|
738 |
<?php wp_nonce_field( 'wsal-step-finish' ); ?>
|
756 |
check_admin_referer( 'wsal-step-finish' );
|
757 |
|
758 |
// Mark the finish of the setup.
|
759 |
+
$this->plugin->set_global_boolean_setting( 'setup-complete', true );
|
760 |
|
761 |
wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
|
762 |
exit();
|
763 |
}
|
764 |
|
765 |
/**
|
766 |
+
* 3rd Party plugins.
|
767 |
+
*
|
768 |
+
* @param array $wizard_steps Wizard steps data.
|
769 |
*/
|
770 |
+
public function wsal_add_wizard_step( $wizard_steps ) {
|
771 |
$new_wizard_steps = array(
|
772 |
+
'test' => array(
|
773 |
'name' => __( 'Third Party Extensions', 'wp-security-audit-log' ),
|
774 |
'content' => array( $this, 'addons_step' ),
|
775 |
'save' => array( $this, 'addons_step_save' ),
|
779 |
// Count number of items in the array.
|
780 |
$number_of_steps = count( $wizard_steps );
|
781 |
// Subtract 1, as we want to insert our step one before the last item.
|
782 |
+
$number_of_steps--;
|
783 |
|
784 |
// Slice the steps up, so we have 2 parts we can insert our slide between.
|
785 |
$first_part = array_slice( $wizard_steps, 0, $number_of_steps, true );
|
786 |
+
$last_part = array_slice( $wizard_steps, -1, 1, true );
|
787 |
|
788 |
// combine the two arrays.
|
789 |
$wizard_steps = $first_part + $new_wizard_steps + $last_part;
|
791 |
return $wizard_steps;
|
792 |
}
|
793 |
|
794 |
+
/**
|
795 |
+
* Renders wizard step showing available add-ons.
|
796 |
+
*/
|
797 |
private function addons_step() {
|
798 |
$our_plugins = WSAL_PluginInstallAndActivate::get_installable_plugins();
|
799 |
|
801 |
$all_plugins = get_plugins();
|
802 |
$plugin_filenames = array();
|
803 |
foreach ( $all_plugins as $plugin => $info ) {
|
804 |
+
$plugin_info = pathinfo( $plugin );
|
805 |
$plugin_filenames[] = $plugin_info['filename'];
|
806 |
}
|
807 |
|
818 |
<p><?php esc_html_e( '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.', 'wp-security-audit-log' ); ?></p>
|
819 |
<?php
|
820 |
// Create a nonce to pass through via data attr.
|
821 |
+
$nonce = wp_create_nonce( 'wsal-install-addon' );
|
822 |
|
823 |
// Loop through plugins and output.
|
824 |
foreach ( $our_plugins as $details ) {
|
826 |
if ( WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) || 'wsal-wpforms.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_wpforms_init_actions' ) || 'wsal-bbpress.php' === basename( $details['plugin_slug'] ) && function_exists( 'wsal_bbpress_init_actions' ) ) {
|
827 |
$disable_button = 'disabled';
|
828 |
}
|
829 |
+
if ( ! in_array( $details['addon_for'], $we_have_addon, true ) ) {
|
830 |
continue;
|
831 |
}
|
832 |
// Check if this is actually an addon for something, otherwise bail.
|
839 |
<img src="<?php echo esc_url( trailingslashit( WSAL_BASE_URL ) . 'img/addons/' . $details['image_filename'] ); ?>">
|
840 |
<div class="addon-content">
|
841 |
<h5><?php esc_html_e( 'Extension for ', 'wp-security-audit-log' ); ?><?php echo esc_html( $details['title'] ); ?></h5>
|
842 |
+
<p><?php echo sanitize_text_field( $details['plugin_description'] ); // phpcs:ignore ?></p>
|
843 |
<p><button class="install-addon button button-primary <?php echo esc_attr( $disable_button ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>" data-plugin-slug="<?php echo esc_attr( $details['plugin_slug'] ); ?>" data-plugin-download-url="<?php echo esc_url( $details['plugin_url'] ); ?>" data-plugin-event-tab-id="<?php echo esc_attr( $details['event_tab_id'] ); ?>">
|
844 |
<?php
|
845 |
if ( WSAL_PluginInstallAndActivate::is_plugin_installed( $details['plugin_slug'] ) && ! WpSecurityAuditLog::is_plugin_active( $details['plugin_slug'] ) ) {
|
854 |
</div>
|
855 |
</div>
|
856 |
<?php
|
857 |
+
}
|
858 |
+
?>
|
859 |
<div class="wsal-setup-actions">
|
860 |
<button class="button button-primary"
|
861 |
type="submit"
|
878 |
wp_safe_redirect( esc_url_raw( $this->get_next_step() ) );
|
879 |
exit();
|
880 |
}
|
|
|
881 |
}
|
classes/Views/ToggleAlerts.php
CHANGED
@@ -4,8 +4,9 @@
|
|
4 |
*
|
5 |
* Settings page of the plugin.
|
6 |
*
|
7 |
-
* @since
|
8 |
-
* @package
|
|
|
9 |
*/
|
10 |
|
11 |
// Exit if accessed directly.
|
@@ -16,35 +17,36 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
16 |
/**
|
17 |
* Enable/Disable Alerts Page.
|
18 |
*
|
19 |
-
* @package
|
|
|
20 |
*/
|
21 |
class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
22 |
|
23 |
/**
|
24 |
-
*
|
25 |
*/
|
26 |
-
public function
|
27 |
-
return
|
28 |
}
|
29 |
|
30 |
/**
|
31 |
-
*
|
32 |
*/
|
33 |
-
public function
|
34 |
return 'dashicons-forms';
|
35 |
}
|
36 |
|
37 |
/**
|
38 |
-
*
|
39 |
*/
|
40 |
-
public function
|
41 |
-
return
|
42 |
}
|
43 |
|
44 |
/**
|
45 |
-
*
|
46 |
*/
|
47 |
-
public function
|
48 |
return 9;
|
49 |
}
|
50 |
|
@@ -53,7 +55,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
53 |
*
|
54 |
* @param string $name - Name of the category.
|
55 |
*/
|
56 |
-
protected function
|
57 |
return strtolower(
|
58 |
preg_replace( '/[^A-Za-z0-9\-]/', '-', $name )
|
59 |
);
|
@@ -84,19 +86,19 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
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->
|
92 |
$disabled = apply_filters( 'wsal_save_settings_disabled_events', $disabled, $registered_alerts, $frontend_events, $enabled );
|
93 |
|
94 |
// Save the disabled events.
|
95 |
-
$this->
|
96 |
|
97 |
// Update failed login limits.
|
98 |
-
$this->
|
99 |
-
$this->
|
100 |
|
101 |
// Allow 3rd parties to process and save more of the posted data.
|
102 |
do_action( 'wsal_togglealerts_process_save_settings', $post_array );
|
@@ -106,9 +108,9 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
106 |
/**
|
107 |
* Method: Get View.
|
108 |
*/
|
109 |
-
public function
|
110 |
// Die if user does not have permission to view.
|
111 |
-
if ( ! $this->
|
112 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
113 |
}
|
114 |
|
@@ -134,36 +136,36 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
134 |
}
|
135 |
|
136 |
// Log level form submission.
|
137 |
-
$log_level_to_set
|
138 |
-
$log_level_nonce
|
139 |
|
140 |
if ( wp_verify_nonce( $log_level_nonce, 'wsal-log-level' ) ) {
|
141 |
-
$this->
|
142 |
|
143 |
if ( 'basic' === $log_level_to_set ) {
|
144 |
-
$this->
|
145 |
} elseif ( 'geek' === $log_level_to_set ) {
|
146 |
-
$this->
|
147 |
}
|
148 |
}
|
149 |
|
150 |
$alert = new WSAL_Alert(); // IDE type hinting.
|
151 |
-
$grouped_alerts = $this->
|
152 |
-
$safe_names = array_map( array( $this, '
|
153 |
$safe_names = array_combine( array_keys( $grouped_alerts ), $safe_names );
|
154 |
|
155 |
-
$disabled_events = $this->
|
156 |
$disabled_events = explode( ',', $disabled_events );
|
157 |
|
158 |
-
//
|
159 |
-
$log_level
|
160 |
-
$log_level_options =
|
161 |
'basic' => esc_html__( 'Basic', 'wp-security-audit-log' ),
|
162 |
'geek' => esc_html__( 'Geek', 'wp-security-audit-log' ),
|
163 |
'custom' => esc_html__( 'Custom', 'wp-security-audit-log' ),
|
164 |
-
|
165 |
|
166 |
-
$subcat_alerts
|
167 |
|
168 |
// Allow further items to be added externally.
|
169 |
$subcat_alerts = apply_filters( 'wsal_togglealerts_sub_category_events', $subcat_alerts );
|
@@ -171,12 +173,12 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
171 |
$obsolete_events = array( 9999, 2126, 99999 );
|
172 |
$obsolete_events = apply_filters( 'wsal_togglealerts_obsolete_events', $obsolete_events );
|
173 |
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
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">
|
@@ -185,20 +187,21 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
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()"
|
196 |
-
|
197 |
-
|
|
|
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->
|
202 |
</p>
|
203 |
</fieldset>
|
204 |
</form>
|
@@ -243,14 +246,14 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
243 |
if ( in_array( $alert->code, $obsolete_events, true ) ) {
|
244 |
continue; // <- Ignore promo alerts.
|
245 |
}
|
246 |
-
$active[ $alert->code ] = $this->
|
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>
|
@@ -268,14 +271,14 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
268 |
$allactive = true;
|
269 |
/** @var WSAL_Alert $alert */
|
270 |
foreach ( $alerts as $alert ) {
|
271 |
-
$active[ $alert->code ] = $this->
|
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.
|
@@ -302,7 +305,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
302 |
case 'WooCommerce Products':
|
303 |
// Check if WooCommerce plugin exists.
|
304 |
if ( ! WpSecurityAuditLog::is_woocommerce_active() ) {
|
305 |
-
$disable_inputs
|
306 |
$disabled_message = esc_html__( 'Please activate WooCommerce to enable this alert', 'wp-security-audit-log' );
|
307 |
}
|
308 |
break;
|
@@ -310,7 +313,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
310 |
case 'Yoast SEO':
|
311 |
// Check if Yoast SEO plugin exists.
|
312 |
if ( ! WpSecurityAuditLog::is_wpseo_active() ) {
|
313 |
-
$disable_inputs
|
314 |
$disabled_message = esc_html__( 'Please activate the Yoast SEO Plugin', 'wp-security-audit-log' );
|
315 |
}
|
316 |
break;
|
@@ -318,7 +321,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
318 |
case 'Multisite Network Sites':
|
319 |
// Disable if not multisite.
|
320 |
if ( ! is_multisite() ) {
|
321 |
-
$disable_inputs
|
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;
|
@@ -343,9 +346,9 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
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->
|
347 |
$severity = '';
|
348 |
-
$severity_obj
|
349 |
|
350 |
if ( is_object( $severity_obj ) ) {
|
351 |
if ( 'E_CRITICAL' === $severity_obj->name ) {
|
@@ -367,19 +370,21 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
367 |
} else {
|
368 |
$severity = esc_html__( 'Notification', 'wp-security-audit-log' );
|
369 |
}
|
370 |
-
}
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
|
|
379 |
echo '</tr>';
|
|
|
380 |
|
381 |
if ( 4000 === $alert->code ) {
|
382 |
-
$frontend_events
|
383 |
?>
|
384 |
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
385 |
<td></td>
|
@@ -392,7 +397,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
392 |
}
|
393 |
|
394 |
if ( 1002 === $alert->code ) {
|
395 |
-
$log_failed_login_limit = (int) $this->
|
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">
|
@@ -405,7 +410,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
405 |
<?php
|
406 |
}
|
407 |
if ( 1003 === $alert->code ) {
|
408 |
-
$log_visitor_failed_login_limit = (int) $this->
|
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">
|
@@ -419,7 +424,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
419 |
}
|
420 |
|
421 |
if ( 1000 === $alert->code ) {
|
422 |
-
$frontend_events
|
423 |
?>
|
424 |
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
425 |
<td></td>
|
@@ -447,7 +452,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
447 |
<?php
|
448 |
$addons = new WSAL_PluginInstallAndActivate();
|
449 |
$addons->render();
|
450 |
-
?>
|
451 |
</div>
|
452 |
|
453 |
|
@@ -459,7 +464,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
459 |
<p>
|
460 |
<?php
|
461 |
/* translators: Alerts log level. */
|
462 |
-
echo sprintf( esc_html__( 'The %s log level has been successfully loaded and applied.', 'wp-security-audit-log' ), $log_level_to_set );
|
463 |
?>
|
464 |
</p>
|
465 |
<br>
|
@@ -493,12 +498,11 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
493 |
/**
|
494 |
* Method: Get View Header.
|
495 |
*/
|
496 |
-
public function
|
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',
|
@@ -685,7 +689,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
685 |
margin-top: 10px;
|
686 |
padding: 10px;
|
687 |
border: 1px solid #c3c4c7;
|
688 |
-
|
689 |
}
|
690 |
</style>
|
691 |
<?php
|
@@ -694,7 +698,7 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
694 |
/**
|
695 |
* Method: Get View Footer.
|
696 |
*/
|
697 |
-
public function
|
698 |
// Remodal script.
|
699 |
wp_enqueue_script(
|
700 |
'wsal-remodal-js',
|
@@ -870,14 +874,14 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
|
870 |
* @since 4.2.0
|
871 |
*/
|
872 |
private function get_log_level_based_on_events( $disabled_events ) {
|
873 |
-
$events_to_cross_check = $this->
|
874 |
$events_diff = array_diff( $disabled_events, $events_to_cross_check );
|
875 |
$events_diff = array_filter( $events_diff ); // Remove empty values.
|
876 |
if ( empty( $events_diff ) ) {
|
877 |
return 'geek';
|
878 |
}
|
879 |
|
880 |
-
$events_to_cross_check = array_merge( $events_to_cross_check, $this->
|
881 |
$events_diff = array_diff( $disabled_events, $events_to_cross_check );
|
882 |
$events_diff = array_filter( $events_diff ); // Remove empty values.
|
883 |
if ( empty( $events_diff ) ) {
|
4 |
*
|
5 |
* Settings page of the plugin.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package wsal
|
9 |
+
* @subpackage views
|
10 |
*/
|
11 |
|
12 |
// Exit if accessed directly.
|
17 |
/**
|
18 |
* Enable/Disable Alerts Page.
|
19 |
*
|
20 |
+
* @package wsal
|
21 |
+
* @subpackage views
|
22 |
*/
|
23 |
class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
|
24 |
|
25 |
/**
|
26 |
+
* {@inheritDoc}
|
27 |
*/
|
28 |
+
public function get_title() {
|
29 |
+
return esc_html__( 'Enable/Disable Events', 'wp-security-audit-log' );
|
30 |
}
|
31 |
|
32 |
/**
|
33 |
+
* {@inheritDoc}
|
34 |
*/
|
35 |
+
public function get_icon() {
|
36 |
return 'dashicons-forms';
|
37 |
}
|
38 |
|
39 |
/**
|
40 |
+
* {@inheritDoc}
|
41 |
*/
|
42 |
+
public function get_name() {
|
43 |
+
return esc_html__( 'Enable/Disable Events', 'wp-security-audit-log' );
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
+
* {@inheritDoc}
|
48 |
*/
|
49 |
+
public function get_weight() {
|
50 |
return 9;
|
51 |
}
|
52 |
|
55 |
*
|
56 |
* @param string $name - Name of the category.
|
57 |
*/
|
58 |
+
protected function get_safe_category_name( $name ) {
|
59 |
return strtolower(
|
60 |
preg_replace( '/[^A-Za-z0-9\-]/', '-', $name )
|
61 |
);
|
86 |
WSAL_Settings::set_frontend_events( $frontend_events );
|
87 |
|
88 |
// Ensure we attempt to save even if eveything is disabled.
|
89 |
+
$post_array['alert'] = ( isset( $post_array['alert'] ) ) ? $post_array['alert'] : array();
|
90 |
|
91 |
$enabled = array_map( 'intval', $post_array['alert'] );
|
92 |
$disabled = array();
|
93 |
+
$registered_alerts = $this->plugin->alerts->get_alerts();
|
94 |
$disabled = apply_filters( 'wsal_save_settings_disabled_events', $disabled, $registered_alerts, $frontend_events, $enabled );
|
95 |
|
96 |
// Save the disabled events.
|
97 |
+
$this->plugin->settings()->set_disabled_alerts( $disabled ); // Save the disabled events.
|
98 |
|
99 |
// Update failed login limits.
|
100 |
+
$this->plugin->settings()->set_failed_login_limit( $post_array['log_failed_login_limit'] );
|
101 |
+
$this->plugin->settings()->set_visitor_failed_login_limit( $post_array['log_visitor_failed_login_limit'] );
|
102 |
|
103 |
// Allow 3rd parties to process and save more of the posted data.
|
104 |
do_action( 'wsal_togglealerts_process_save_settings', $post_array );
|
108 |
/**
|
109 |
* Method: Get View.
|
110 |
*/
|
111 |
+
public function render() {
|
112 |
// Die if user does not have permission to view.
|
113 |
+
if ( ! $this->plugin->settings()->current_user_can( 'edit' ) ) {
|
114 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
115 |
}
|
116 |
|
136 |
}
|
137 |
|
138 |
// Log level form submission.
|
139 |
+
$log_level_to_set = isset( $post_array['wsal-log-level'] ) ? sanitize_text_field( $post_array['wsal-log-level'] ) : false;
|
140 |
+
$log_level_nonce = isset( $post_array['wsal-log-level-nonce'] ) ? sanitize_text_field( $post_array['wsal-log-level-nonce'] ) : false;
|
141 |
|
142 |
if ( wp_verify_nonce( $log_level_nonce, 'wsal-log-level' ) ) {
|
143 |
+
$this->plugin->set_global_setting( 'details-level', $log_level_to_set );
|
144 |
|
145 |
if ( 'basic' === $log_level_to_set ) {
|
146 |
+
$this->plugin->settings()->set_basic_mode();
|
147 |
} elseif ( 'geek' === $log_level_to_set ) {
|
148 |
+
$this->plugin->settings()->set_geek_mode();
|
149 |
}
|
150 |
}
|
151 |
|
152 |
$alert = new WSAL_Alert(); // IDE type hinting.
|
153 |
+
$grouped_alerts = $this->plugin->alerts->get_categorized_alerts( false );
|
154 |
+
$safe_names = array_map( array( $this, 'get_safe_category_name' ), array_keys( $grouped_alerts ) );
|
155 |
$safe_names = array_combine( array_keys( $grouped_alerts ), $safe_names );
|
156 |
|
157 |
+
$disabled_events = $this->plugin->get_global_setting( 'disabled-alerts' ); // Get disabled events.
|
158 |
$disabled_events = explode( ',', $disabled_events );
|
159 |
|
160 |
+
// Check if the log level is custom.
|
161 |
+
$log_level = $this->get_log_level_based_on_events( $disabled_events );
|
162 |
+
$log_level_options = array(
|
163 |
'basic' => esc_html__( 'Basic', 'wp-security-audit-log' ),
|
164 |
'geek' => esc_html__( 'Geek', 'wp-security-audit-log' ),
|
165 |
'custom' => esc_html__( 'Custom', 'wp-security-audit-log' ),
|
166 |
+
);
|
167 |
|
168 |
+
$subcat_alerts = array( 1000, 1004, 2010, 2111 );
|
169 |
|
170 |
// Allow further items to be added externally.
|
171 |
$subcat_alerts = apply_filters( 'wsal_togglealerts_sub_category_events', $subcat_alerts );
|
173 |
$obsolete_events = array( 9999, 2126, 99999 );
|
174 |
$obsolete_events = apply_filters( 'wsal_togglealerts_obsolete_events', $obsolete_events );
|
175 |
|
176 |
+
// Check if the disabled events are enforced from the MainWP master site.
|
177 |
+
$settings = $this->plugin->settings();
|
178 |
+
$enforced_settings = $settings->get_mainwp_enforced_settings();
|
179 |
+
$disabled_events_enforced_by_mainwp = array_key_exists( 'disabled_events', $enforced_settings ) && ! empty( $enforced_settings['disabled_events'] );
|
180 |
?>
|
181 |
+
|
182 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
183 |
<a href="#tab-all" class="nav-tab"><?php esc_html_e( 'Enable/Disable alerts', 'wp-security-audit-log' ); ?></a>
|
184 |
<a href="#tab-third-party-plugins" class="nav-tab">
|
187 |
</h2>
|
188 |
|
189 |
<div class="nav-tabs">
|
190 |
+
|
191 |
<div id="tab-all" class="wsal-tab widefat fixed">
|
192 |
|
193 |
<form method="post" id="wsal-alerts-level">
|
194 |
<?php wp_nonce_field( 'wsal-log-level', 'wsal-log-level-nonce' ); ?>
|
195 |
<fieldset>
|
196 |
<label for="wsal-log-level"><?php esc_html_e( 'Log Level: ', 'wp-security-audit-log' ); ?></label>
|
197 |
+
<select name="wsal-log-level" id="wsal-log-level" onchange="this.form.submit()"
|
198 |
+
<?php disabled( $disabled_events_enforced_by_mainwp ); ?>>
|
199 |
+
<?php foreach ( $log_level_options as $log_level_id => $log_level_label ) : ?>
|
200 |
+
<option value="<?php echo $log_level_id; ?>" <?php echo selected( $log_level, $log_level_id ); ?>><?php echo $log_level_label; // phpcs:ignore ?></option>
|
201 |
<?php endforeach; ?>
|
202 |
</select>
|
203 |
<p class="description">
|
204 |
+
<?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 ); ?>
|
205 |
</p>
|
206 |
</fieldset>
|
207 |
</form>
|
246 |
if ( in_array( $alert->code, $obsolete_events, true ) ) {
|
247 |
continue; // <- Ignore promo alerts.
|
248 |
}
|
249 |
+
$active[ $alert->code ] = $this->plugin->alerts->is_enabled( $alert->code );
|
250 |
if ( ! $active[ $alert->code ] ) {
|
251 |
$allactive = false;
|
252 |
}
|
253 |
}
|
254 |
}
|
255 |
}
|
256 |
+
?>
|
257 |
<th width="48"><input type="checkbox" <?php checked( $allactive ); ?> /></th>
|
258 |
<th width="80"><?php esc_html_e( 'Code', 'wp-security-audit-log' ); ?></th>
|
259 |
<th width="100"><?php esc_html_e( 'Severity', 'wp-security-audit-log' ); ?></th>
|
271 |
$allactive = true;
|
272 |
/** @var WSAL_Alert $alert */
|
273 |
foreach ( $alerts as $alert ) {
|
274 |
+
$active[ $alert->code ] = $this->plugin->alerts->is_enabled( $alert->code );
|
275 |
if ( ! $active[ $alert->code ] ) {
|
276 |
$allactive = false;
|
277 |
}
|
278 |
}
|
279 |
|
280 |
// Disabled alerts.
|
281 |
+
$disable_inputs = '';
|
282 |
$disabled_message = '';
|
283 |
|
284 |
// Skip Pages and CPTs section.
|
305 |
case 'WooCommerce Products':
|
306 |
// Check if WooCommerce plugin exists.
|
307 |
if ( ! WpSecurityAuditLog::is_woocommerce_active() ) {
|
308 |
+
$disable_inputs = 'disabled';
|
309 |
$disabled_message = esc_html__( 'Please activate WooCommerce to enable this alert', 'wp-security-audit-log' );
|
310 |
}
|
311 |
break;
|
313 |
case 'Yoast SEO':
|
314 |
// Check if Yoast SEO plugin exists.
|
315 |
if ( ! WpSecurityAuditLog::is_wpseo_active() ) {
|
316 |
+
$disable_inputs = 'disabled';
|
317 |
$disabled_message = esc_html__( 'Please activate the Yoast SEO Plugin', 'wp-security-audit-log' );
|
318 |
}
|
319 |
break;
|
321 |
case 'Multisite Network Sites':
|
322 |
// Disable if not multisite.
|
323 |
if ( ! is_multisite() ) {
|
324 |
+
$disable_inputs = 'disabled';
|
325 |
$disabled_message = esc_html__( 'Your website is a single site so the multisite events have been disabled.', 'wp-security-audit-log' );
|
326 |
}
|
327 |
break;
|
346 |
|
347 |
$disable_inputs_needed = ( ! empty( $disable_inputs ) ) ? esc_attr( $disable_inputs ) : '';
|
348 |
$disabled_tooltip = ( $disabled_message ) ? 'data-tooltip="' . $disabled_message . '"' : '';
|
349 |
+
$checkbox_markup = '<input name="alert[]" type="checkbox" class="alert"' . checked( $this->plugin->alerts->is_enabled( $alert->code ), true, false ) . ' value="' . esc_attr( (int) $alert->code ) . '" ' . $disable_inputs_needed . ' />';
|
350 |
$severity = '';
|
351 |
+
$severity_obj = $this->plugin->constants->get_constant_by( 'value', $alert->severity );
|
352 |
|
353 |
if ( is_object( $severity_obj ) ) {
|
354 |
if ( 'E_CRITICAL' === $severity_obj->name ) {
|
370 |
} else {
|
371 |
$severity = esc_html__( 'Notification', 'wp-security-audit-log' );
|
372 |
}
|
373 |
+
}
|
374 |
+
|
375 |
+
// @codingStandardsIgnoreStart
|
376 |
+
echo '<tr class="alert-wrapper ' . $disable_inputs_needed . '" data-alert-cat="' . $alert->catg . '" data-alert-subcat="' . $alert->subcatg . '" ' . $disabled_tooltip . '>';
|
377 |
+
echo '<th>' . $checkbox_markup . '</th>';
|
378 |
+
echo '<td>' . $alert->code . '</td>';
|
379 |
+
echo '<td>' . $severity . '</td>';
|
380 |
+
echo '<td>' . $alert->desc . '</td>';
|
381 |
+
echo '<td style="display: none;">' . $alert->catg . '</td>';
|
382 |
+
echo '<td style="display: none;">' . $alert->subcatg . '</td>';
|
383 |
echo '</tr>';
|
384 |
+
// @codingStandardsIgnoreEnd
|
385 |
|
386 |
if ( 4000 === $alert->code ) {
|
387 |
+
$frontend_events = WSAL_Settings::get_frontend_events();
|
388 |
?>
|
389 |
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
390 |
<td></td>
|
397 |
}
|
398 |
|
399 |
if ( 1002 === $alert->code ) {
|
400 |
+
$log_failed_login_limit = (int) $this->plugin->get_global_setting( 'log-failed-login-limit', 10 );
|
401 |
$log_failed_login_limit = ( -1 === $log_failed_login_limit ) ? '0' : $log_failed_login_limit;
|
402 |
?>
|
403 |
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
410 |
<?php
|
411 |
}
|
412 |
if ( 1003 === $alert->code ) {
|
413 |
+
$log_visitor_failed_login_limit = (int) $this->plugin->get_global_setting( 'log-visitor-failed-login-limit', 10 );
|
414 |
$log_visitor_failed_login_limit = ( -1 === $log_visitor_failed_login_limit ) ? '0' : $log_visitor_failed_login_limit;
|
415 |
?>
|
416 |
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
424 |
}
|
425 |
|
426 |
if ( 1000 === $alert->code ) {
|
427 |
+
$frontend_events = WSAL_Settings::get_frontend_events();
|
428 |
?>
|
429 |
<tr class="alert-wrapper" data-alert-cat="Users Logins & Sessions Events" data-alert-subcat="User Activity">
|
430 |
<td></td>
|
452 |
<?php
|
453 |
$addons = new WSAL_PluginInstallAndActivate();
|
454 |
$addons->render();
|
455 |
+
?>
|
456 |
</div>
|
457 |
|
458 |
|
464 |
<p>
|
465 |
<?php
|
466 |
/* translators: Alerts log level. */
|
467 |
+
echo sprintf( esc_html__( 'The %s log level has been successfully loaded and applied.', 'wp-security-audit-log' ), $log_level_to_set ); // phpcs:ignore
|
468 |
?>
|
469 |
</p>
|
470 |
<br>
|
498 |
/**
|
499 |
* Method: Get View Header.
|
500 |
*/
|
501 |
+
public function header() {
|
502 |
// Remodal styles.
|
503 |
wp_enqueue_style( 'wsal-remodal', WSAL_BASE_URL . 'css/remodal.css', array(), '1.1.1' );
|
504 |
wp_enqueue_style( 'wsal-remodal-theme', WSAL_BASE_URL . 'css/remodal-default-theme.css', array(), '1.1.1' );
|
505 |
|
|
|
506 |
// Darktooltip styles.
|
507 |
wp_enqueue_style(
|
508 |
'darktooltip',
|
689 |
margin-top: 10px;
|
690 |
padding: 10px;
|
691 |
border: 1px solid #c3c4c7;
|
692 |
+
box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
|
693 |
}
|
694 |
</style>
|
695 |
<?php
|
698 |
/**
|
699 |
* Method: Get View Footer.
|
700 |
*/
|
701 |
+
public function footer() {
|
702 |
// Remodal script.
|
703 |
wp_enqueue_script(
|
704 |
'wsal-remodal-js',
|
874 |
* @since 4.2.0
|
875 |
*/
|
876 |
private function get_log_level_based_on_events( $disabled_events ) {
|
877 |
+
$events_to_cross_check = $this->plugin->settings()->always_disabled_alerts;
|
878 |
$events_diff = array_diff( $disabled_events, $events_to_cross_check );
|
879 |
$events_diff = array_filter( $events_diff ); // Remove empty values.
|
880 |
if ( empty( $events_diff ) ) {
|
881 |
return 'geek';
|
882 |
}
|
883 |
|
884 |
+
$events_to_cross_check = array_merge( $events_to_cross_check, $this->plugin->settings()->geek_alerts );
|
885 |
$events_diff = array_diff( $disabled_events, $events_to_cross_check );
|
886 |
$events_diff = array_filter( $events_diff ); // Remove empty values.
|
887 |
if ( empty( $events_diff ) ) {
|
classes/Views/addons/html-view.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
* Addons HTML View in Admin.
|
4 |
*
|
5 |
* @package wsal
|
|
|
6 |
*/
|
7 |
|
8 |
if ( ! defined( 'ABSPATH' ) ) {
|
@@ -32,9 +33,9 @@ switch ( $this->hook_suffix ) {
|
|
32 |
case 'wp-activity-log_page_wsal-search':
|
33 |
$utm_params['utm_content'] = 'search';
|
34 |
break;
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
}
|
39 |
// Links.
|
40 |
$more_info = add_query_arg(
|
@@ -46,7 +47,7 @@ $more_info = add_query_arg(
|
|
46 |
$trial_args = array(
|
47 |
'page' => 'wsal-auditlog-pricing',
|
48 |
'billing_cycle' => 'annual',
|
49 |
-
'trial' => 'true'
|
50 |
);
|
51 |
|
52 |
// Buy Now button link.
|
@@ -55,14 +56,14 @@ $buy_now_target = '';
|
|
55 |
$trial_link = add_query_arg( $trial_args, admin_url( 'admin.php' ) );
|
56 |
|
57 |
// If user is not super admin and website is multisite then change the URL.
|
58 |
-
if ( $this->
|
59 |
$buy_now = 'https://wpactivitylog.com/pricing/';
|
60 |
$trial_link = 'https://wpactivitylog.com/pricing/';
|
61 |
$buy_now_target = ' target="_blank"';
|
62 |
-
} elseif ( $this->
|
63 |
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', network_admin_url( 'admin.php' ) );
|
64 |
$trial_link = add_query_arg( $trial_args, network_admin_url( 'admin.php' ) );
|
65 |
-
} elseif (
|
66 |
$buy_now = 'https://wpactivitylog.com/pricing/';
|
67 |
$trial_link = 'https://wpactivitylog.com/pricing/';
|
68 |
$buy_now_target = ' target="_blank"';
|
3 |
* Addons HTML View in Admin.
|
4 |
*
|
5 |
* @package wsal
|
6 |
+
* @subpackage views
|
7 |
*/
|
8 |
|
9 |
if ( ! defined( 'ABSPATH' ) ) {
|
33 |
case 'wp-activity-log_page_wsal-search':
|
34 |
$utm_params['utm_content'] = 'search';
|
35 |
break;
|
36 |
+
default:
|
37 |
+
// Fallback for any other hook suffix would go here.
|
38 |
+
break;
|
39 |
}
|
40 |
// Links.
|
41 |
$more_info = add_query_arg(
|
47 |
$trial_args = array(
|
48 |
'page' => 'wsal-auditlog-pricing',
|
49 |
'billing_cycle' => 'annual',
|
50 |
+
'trial' => 'true',
|
51 |
);
|
52 |
|
53 |
// Buy Now button link.
|
56 |
$trial_link = add_query_arg( $trial_args, admin_url( 'admin.php' ) );
|
57 |
|
58 |
// If user is not super admin and website is multisite then change the URL.
|
59 |
+
if ( $this->plugin->is_multisite() && ! is_super_admin() ) {
|
60 |
$buy_now = 'https://wpactivitylog.com/pricing/';
|
61 |
$trial_link = 'https://wpactivitylog.com/pricing/';
|
62 |
$buy_now_target = ' target="_blank"';
|
63 |
+
} elseif ( $this->plugin->is_multisite() && is_super_admin() ) {
|
64 |
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', network_admin_url( 'admin.php' ) );
|
65 |
$trial_link = add_query_arg( $trial_args, network_admin_url( 'admin.php' ) );
|
66 |
+
} elseif ( $this->plugin->is_multisite() && ! current_user_can( 'manage_options' ) ) {
|
67 |
$buy_now = 'https://wpactivitylog.com/pricing/';
|
68 |
$trial_link = 'https://wpactivitylog.com/pricing/';
|
69 |
$buy_now_target = ' target="_blank"';
|
classes/WidgetManager.php
CHANGED
@@ -27,7 +27,7 @@ class WSAL_WidgetManager {
|
|
27 |
*
|
28 |
* @var WpSecurityAuditLog
|
29 |
*/
|
30 |
-
protected $
|
31 |
|
32 |
/**
|
33 |
* Method: Constructor.
|
@@ -35,7 +35,7 @@ class WSAL_WidgetManager {
|
|
35 |
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
36 |
*/
|
37 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
38 |
-
$this->
|
39 |
add_action( 'wp_dashboard_setup', array( $this, 'add_widgets' ) );
|
40 |
}
|
41 |
|
@@ -46,13 +46,13 @@ class WSAL_WidgetManager {
|
|
46 |
global $pagenow;
|
47 |
|
48 |
if (
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
) {
|
53 |
wp_add_dashboard_widget(
|
54 |
'wsal',
|
55 |
-
|
56 |
array( $this, 'render_widget' )
|
57 |
);
|
58 |
}
|
@@ -64,7 +64,7 @@ class WSAL_WidgetManager {
|
|
64 |
public function render_widget() {
|
65 |
// get the events for the dashboard widget.
|
66 |
$query = $this->get_dashboard_widget_query();
|
67 |
-
$results = $query->
|
68 |
|
69 |
?><div>
|
70 |
<?php if ( ! count( $results ) ) : ?>
|
@@ -80,21 +80,21 @@ class WSAL_WidgetManager {
|
|
80 |
</thead>
|
81 |
<tbody>
|
82 |
<?php
|
83 |
-
$url = 'admin.php?page=' . $this->
|
84 |
foreach ( $results as $entry ) :
|
85 |
-
$event_meta = $entry->
|
86 |
-
$username = WSAL_Utilities_UsersUtils::
|
87 |
?>
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
<?php echo wp_kses( $entry->
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
<?php endforeach; ?>
|
99 |
</tbody>
|
100 |
</table>
|
@@ -115,12 +115,12 @@ class WSAL_WidgetManager {
|
|
115 |
// get the site we are on (of multisite).
|
116 |
$bid = (int) $this->get_view_site_id();
|
117 |
if ( $bid ) {
|
118 |
-
$query->
|
119 |
}
|
120 |
// order by date of creation.
|
121 |
-
$query->
|
122 |
// set the limit based on the limit option for dashboard alerts.
|
123 |
-
$query->
|
124 |
return $query;
|
125 |
}
|
126 |
|
27 |
*
|
28 |
* @var WpSecurityAuditLog
|
29 |
*/
|
30 |
+
protected $plugin;
|
31 |
|
32 |
/**
|
33 |
* Method: Constructor.
|
35 |
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
36 |
*/
|
37 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
38 |
+
$this->plugin = $plugin;
|
39 |
add_action( 'wp_dashboard_setup', array( $this, 'add_widgets' ) );
|
40 |
}
|
41 |
|
46 |
global $pagenow;
|
47 |
|
48 |
if (
|
49 |
+
$this->plugin->settings()->is_widgets_enabled() // If widget is enabled.
|
50 |
+
&& $this->plugin->settings()->current_user_can( 'view' ) // If user has permission to view.
|
51 |
+
&& 'index.php' === $pagenow // If the current page is dashboard.
|
52 |
) {
|
53 |
wp_add_dashboard_widget(
|
54 |
'wsal',
|
55 |
+
esc_html__( 'Latest Events', 'wp-security-audit-log' ) . ' | WP Activity Log',
|
56 |
array( $this, 'render_widget' )
|
57 |
);
|
58 |
}
|
64 |
public function render_widget() {
|
65 |
// get the events for the dashboard widget.
|
66 |
$query = $this->get_dashboard_widget_query();
|
67 |
+
$results = $query->get_adapter()->execute_query( $query );
|
68 |
|
69 |
?><div>
|
70 |
<?php if ( ! count( $results ) ) : ?>
|
80 |
</thead>
|
81 |
<tbody>
|
82 |
<?php
|
83 |
+
$url = 'admin.php?page=' . $this->plugin->views->views[0]->get_safe_view_name();
|
84 |
foreach ( $results as $entry ) :
|
85 |
+
$event_meta = $entry->get_meta_array();
|
86 |
+
$username = WSAL_Utilities_UsersUtils::get_username( $event_meta );
|
87 |
?>
|
88 |
+
<tr>
|
89 |
+
<td><?php echo ( $username ) ? esc_html( $username ) : '<i>unknown</i>'; ?></td>
|
90 |
+
<td><?php echo ( $event_meta['Object'] ) ? esc_html( $event_meta['Object'] ) : '<i>unknown</i>'; ?></td>
|
91 |
+
<td><?php echo ( $event_meta['EventType'] ) ? esc_html( $event_meta['EventType'] ) : '<i>unknown</i>'; ?></td>
|
92 |
+
<td>
|
93 |
+
<a href="<?php echo esc_url( $url ) . '#Event' . esc_attr( $entry->get_id() ); ?>">
|
94 |
+
<?php echo wp_kses( $entry->get_message( $event_meta, 'dashboard-widget' ), $this->plugin->allowed_html_tags ); ?>
|
95 |
+
</a>
|
96 |
+
</td>
|
97 |
+
</tr>
|
98 |
<?php endforeach; ?>
|
99 |
</tbody>
|
100 |
</table>
|
115 |
// get the site we are on (of multisite).
|
116 |
$bid = (int) $this->get_view_site_id();
|
117 |
if ( $bid ) {
|
118 |
+
$query->add_condition( 'site_id = %s ', $bid );
|
119 |
}
|
120 |
// order by date of creation.
|
121 |
+
$query->add_order_by( 'created_on', true );
|
122 |
// set the limit based on the limit option for dashboard alerts.
|
123 |
+
$query->set_limit( $this->plugin->settings()->get_dashboard_widget_max_alerts() );
|
124 |
return $query;
|
125 |
}
|
126 |
|
css/dist/wsal-wizard.css
CHANGED
@@ -1,177 +1 @@
|
|
1 |
-
|
2 |
-
* WSAL Wizard Styles
|
3 |
-
*/
|
4 |
-
body {
|
5 |
-
margin: 65px auto 24px;
|
6 |
-
-webkit-box-shadow: none;
|
7 |
-
box-shadow: none;
|
8 |
-
background: #f1f1f1;
|
9 |
-
padding: 0;
|
10 |
-
border: none; }
|
11 |
-
|
12 |
-
#wsal-logo {
|
13 |
-
border: 0;
|
14 |
-
margin: 0 0 24px;
|
15 |
-
padding: 0;
|
16 |
-
text-align: center; }
|
17 |
-
#wsal-logo img {
|
18 |
-
width: 400px; }
|
19 |
-
|
20 |
-
.steps {
|
21 |
-
display: flex;
|
22 |
-
list-style-type: none;
|
23 |
-
margin: 0;
|
24 |
-
padding: 0 0 25px;
|
25 |
-
text-align: center; }
|
26 |
-
.steps li {
|
27 |
-
flex: 1 0 auto;
|
28 |
-
font-weight: 700;
|
29 |
-
margin: 0 0 5px;
|
30 |
-
color: #b4b9be;
|
31 |
-
padding-bottom: 15px;
|
32 |
-
position: relative; }
|
33 |
-
.steps li.is-active {
|
34 |
-
color: #009344; }
|
35 |
-
.steps li.is-active::before {
|
36 |
-
border: 4px solid #009344;
|
37 |
-
background: #009344; }
|
38 |
-
.steps li::before {
|
39 |
-
content: '';
|
40 |
-
border: 4px solid #b4b9be;
|
41 |
-
border-radius: 100%;
|
42 |
-
width: 4px;
|
43 |
-
height: 4px;
|
44 |
-
position: absolute;
|
45 |
-
bottom: 0;
|
46 |
-
left: 50%;
|
47 |
-
margin-left: -6px;
|
48 |
-
margin-bottom: -8px;
|
49 |
-
background: #b4b9be; }
|
50 |
-
|
51 |
-
.wsal-setup-content {
|
52 |
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.13);
|
53 |
-
padding: 2em;
|
54 |
-
margin: 0 0 20px;
|
55 |
-
background: #fff;
|
56 |
-
overflow: hidden;
|
57 |
-
zoom: 1;
|
58 |
-
text-align: left; }
|
59 |
-
.wsal-setup-content h4,
|
60 |
-
.wsal-setup-content fieldset {
|
61 |
-
line-height: 1.5; }
|
62 |
-
.wsal-setup-content .addon-wrapper {
|
63 |
-
border: 1px solid #eee;
|
64 |
-
padding: 15px;
|
65 |
-
display: flex;
|
66 |
-
margin-bottom: 15px; }
|
67 |
-
.wsal-setup-content .addon-wrapper:hover {
|
68 |
-
border-color: #ccc; }
|
69 |
-
.wsal-setup-content .addon-wrapper img {
|
70 |
-
align-self: center;
|
71 |
-
max-width: 200px;
|
72 |
-
margin-right: 15px; }
|
73 |
-
|
74 |
-
.wsal-setup-actions {
|
75 |
-
text-align: center; }
|
76 |
-
.wsal-setup-actions .button {
|
77 |
-
box-shadow: none;
|
78 |
-
font-size: 14px;
|
79 |
-
height: auto;
|
80 |
-
padding: 8px 20px;
|
81 |
-
min-width: 12em;
|
82 |
-
min-width: auto;
|
83 |
-
transition: 0.1s all linear; }
|
84 |
-
.wsal-setup-actions .button-primary {
|
85 |
-
background-color: #009344;
|
86 |
-
border-color: #009344;
|
87 |
-
box-shadow: none;
|
88 |
-
text-shadow: none;
|
89 |
-
margin: 0;
|
90 |
-
opacity: 1; }
|
91 |
-
.wsal-setup-actions .button-primary:hover, .wsal-setup-actions .button-primary:focus {
|
92 |
-
background: #00ad50;
|
93 |
-
border-color: #00ad50;
|
94 |
-
box-shadow: none;
|
95 |
-
color: #fff; }
|
96 |
-
|
97 |
-
.wsal-setup-footer {
|
98 |
-
text-align: center; }
|
99 |
-
.wsal-setup-footer a {
|
100 |
-
color: #009344;
|
101 |
-
font-size: 14px;
|
102 |
-
text-decoration: none; }
|
103 |
-
|
104 |
-
.wsal-setup-form label[for="editor-users-box"],
|
105 |
-
.wsal-setup-form label[for="editor-roles-box"],
|
106 |
-
.wsal-setup-form label[for="exuser-query-box"],
|
107 |
-
.wsal-setup-form label[for="exrole-query-box"],
|
108 |
-
.wsal-setup-form label[for="ipaddr-query-box"] {
|
109 |
-
display: inline-block;
|
110 |
-
margin: 5px 0; }
|
111 |
-
.wsal-setup-form label[for="editor-users-box"] span,
|
112 |
-
.wsal-setup-form label[for="editor-roles-box"] span,
|
113 |
-
.wsal-setup-form label[for="exuser-query-box"] span,
|
114 |
-
.wsal-setup-form label[for="exrole-query-box"] span,
|
115 |
-
.wsal-setup-form label[for="ipaddr-query-box"] span {
|
116 |
-
display: inline-block;
|
117 |
-
min-width: 100px; }
|
118 |
-
|
119 |
-
.sectoken-user,
|
120 |
-
.sectoken-role,
|
121 |
-
.sectoken-ip,
|
122 |
-
.sectoken-other {
|
123 |
-
display: inline-block;
|
124 |
-
border-width: 1px;
|
125 |
-
border-style: solid;
|
126 |
-
padding: 2px 4px;
|
127 |
-
margin: 2px 0 0 2px;
|
128 |
-
border-radius: 3px;
|
129 |
-
cursor: default;
|
130 |
-
line-height: 1.3;
|
131 |
-
font-size: 14px; }
|
132 |
-
.sectoken-user a,
|
133 |
-
.sectoken-role a,
|
134 |
-
.sectoken-ip a,
|
135 |
-
.sectoken-other a {
|
136 |
-
text-decoration: none;
|
137 |
-
font-size: 12px;
|
138 |
-
font-weight: bold;
|
139 |
-
color: #FFF;
|
140 |
-
margin-left: 2px;
|
141 |
-
background: #BBB;
|
142 |
-
border-radius: 25px;
|
143 |
-
height: 14px;
|
144 |
-
display: inline-block;
|
145 |
-
vertical-align: middle;
|
146 |
-
width: 14px;
|
147 |
-
text-align: center;
|
148 |
-
line-height: 12px; }
|
149 |
-
.sectoken-user a:hover,
|
150 |
-
.sectoken-role a:hover,
|
151 |
-
.sectoken-ip a:hover,
|
152 |
-
.sectoken-other a:hover {
|
153 |
-
background: #FB9; }
|
154 |
-
|
155 |
-
.sectoken-other {
|
156 |
-
display: table;
|
157 |
-
border-collapse: separate; }
|
158 |
-
|
159 |
-
.sectoken-role {
|
160 |
-
background: #EFE;
|
161 |
-
border-color: #5B5; }
|
162 |
-
|
163 |
-
.sectoken-user {
|
164 |
-
background: #EFF;
|
165 |
-
border-color: #5BE; }
|
166 |
-
|
167 |
-
.sectoken-ip {
|
168 |
-
background: #FFE;
|
169 |
-
border-color: #ED5; }
|
170 |
-
|
171 |
-
.sectoken-other {
|
172 |
-
background: #FFE;
|
173 |
-
border-color: #ED5; }
|
174 |
-
|
175 |
-
p.description {
|
176 |
-
font-size: 13px;
|
177 |
-
font-style: italic; }
|
1 |
+
body{background:#f1f1f1;border:none;box-shadow:none;margin:65px auto 24px;padding:0}#wsal-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wsal-logo img{width:400px}.steps{display:flex;list-style-type:none;margin:0;padding:0 0 25px;text-align:center}.steps li{color:#b4b9be;flex:1 0 auto;font-weight:700;margin:0 0 5px;padding-bottom:15px;position:relative}.steps li.is-active{color:#009344}.steps li.is-active:before{background:#009344;border:4px solid #009344}.steps li:before{background:#b4b9be;border:4px solid #b4b9be;border-radius:100%;bottom:0;content:"";height:4px;left:50%;margin-bottom:-8px;margin-left:-6px;position:absolute;width:4px}.wsal-setup-content{zoom:1;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.13);margin:0 0 20px;overflow:hidden;padding:2em;text-align:left}.wsal-setup-content fieldset,.wsal-setup-content h4{line-height:1.5}.wsal-setup-content .addon-wrapper{border:1px solid #eee;display:flex;margin-bottom:15px;padding:15px}.wsal-setup-content .addon-wrapper:hover{border-color:#ccc}.wsal-setup-content .addon-wrapper img{align-self:center;margin-right:15px;max-width:200px}.wsal-setup-actions{text-align:center}.wsal-setup-actions .button{box-shadow:none;font-size:14px;height:auto;min-width:12em;min-width:auto;padding:8px 20px;transition:all .1s linear}.wsal-setup-actions .button-primary{background-color:#009344;border-color:#009344;box-shadow:none;margin:0;opacity:1;text-shadow:none}.wsal-setup-actions .button-primary:focus,.wsal-setup-actions .button-primary:hover{background:#00ad50;border-color:#00ad50;box-shadow:none;color:#fff}.wsal-setup-footer{text-align:center}.wsal-setup-footer a{color:#009344;font-size:14px;text-decoration:none}.wsal-setup-form label[for=editor-roles-box],.wsal-setup-form label[for=editor-users-box],.wsal-setup-form label[for=exrole-query-box],.wsal-setup-form label[for=exuser-query-box],.wsal-setup-form label[for=ipaddr-query-box]{display:inline-block;margin:5px 0}.wsal-setup-form label[for=editor-roles-box] span,.wsal-setup-form label[for=editor-users-box] span,.wsal-setup-form label[for=exrole-query-box] span,.wsal-setup-form label[for=exuser-query-box] span,.wsal-setup-form label[for=ipaddr-query-box] span{display:inline-block;min-width:100px}.sectoken-ip,.sectoken-other,.sectoken-role,.sectoken-user{border-radius:3px;border-style:solid;border-width:1px;cursor:default;display:inline-block;font-size:14px;line-height:1.3;margin:2px 0 0 2px;padding:2px 4px}.sectoken-ip a,.sectoken-other a,.sectoken-role a,.sectoken-user a{background:#bbb;border-radius:25px;color:#fff;display:inline-block;font-size:12px;font-weight:700;height:14px;line-height:12px;margin-left:2px;text-align:center;text-decoration:none;vertical-align:middle;width:14px}.sectoken-ip a:hover,.sectoken-other a:hover,.sectoken-role a:hover,.sectoken-user a:hover{background:#fb9}.sectoken-other{border-collapse:separate;display:table}.sectoken-role{background:#efe;border-color:#5b5}.sectoken-user{background:#eff;border-color:#5be}.sectoken-ip,.sectoken-other{background:#ffe;border-color:#ed5}p.description{font-size:13px;font-style:italic}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
css/dist/wsal-wizard.min.css
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
body{margin:65px auto 24px;-webkit-box-shadow:none;box-shadow:none;background:#f1f1f1;padding:0;border:none}#wsal-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wsal-logo img{width:400px}.steps{display:flex;list-style-type:none;margin:0;padding:0 0 25px;text-align:center}.steps li{flex:1 0 auto;font-weight:700;margin:0 0 5px;color:#b4b9be;padding-bottom:15px;position:relative}.steps li.is-active{color:#009344}.steps li.is-active::before{border:4px solid #009344;background:#009344}.steps li::before{content:'';border:4px solid #b4b9be;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#b4b9be}.wsal-setup-content{box-shadow:0 1px 3px rgba(0,0,0,.13);padding:2em;margin:0 0 20px;background:#fff;overflow:hidden;zoom:1;text-align:left}.wsal-setup-content fieldset,.wsal-setup-content h4{line-height:1.5}.wsal-setup-content .addon-wrapper{border:1px solid #eee;padding:15px;display:flex;margin-bottom:15px}.wsal-setup-content .addon-wrapper:hover{border-color:#ccc}.wsal-setup-content .addon-wrapper img{align-self:center;max-width:200px;margin-right:15px}.wsal-setup-actions{text-align:center}.wsal-setup-actions .button{box-shadow:none;font-size:14px;height:auto;padding:8px 20px;min-width:12em;min-width:auto;transition:.1s all linear}.wsal-setup-actions .button-primary{background-color:#009344;border-color:#009344;box-shadow:none;text-shadow:none;margin:0;opacity:1}.wsal-setup-actions .button-primary:focus,.wsal-setup-actions .button-primary:hover{background:#00ad50;border-color:#00ad50;box-shadow:none;color:#fff}.wsal-setup-footer{text-align:center}.wsal-setup-footer a{color:#009344;font-size:14px;text-decoration:none}.wsal-setup-form label[for=editor-roles-box],.wsal-setup-form label[for=editor-users-box],.wsal-setup-form label[for=exrole-query-box],.wsal-setup-form label[for=exuser-query-box],.wsal-setup-form label[for=ipaddr-query-box]{display:inline-block;margin:5px 0}.wsal-setup-form label[for=editor-roles-box] span,.wsal-setup-form label[for=editor-users-box] span,.wsal-setup-form label[for=exrole-query-box] span,.wsal-setup-form label[for=exuser-query-box] span,.wsal-setup-form label[for=ipaddr-query-box] span{display:inline-block;min-width:100px}.sectoken-ip,.sectoken-other,.sectoken-role,.sectoken-user{display:inline-block;border-width:1px;border-style:solid;padding:2px 4px;margin:2px 0 0 2px;border-radius:3px;cursor:default;line-height:1.3;font-size:14px}.sectoken-ip a,.sectoken-other a,.sectoken-role a,.sectoken-user a{text-decoration:none;font-size:12px;font-weight:700;color:#fff;margin-left:2px;background:#bbb;border-radius:25px;height:14px;display:inline-block;vertical-align:middle;width:14px;text-align:center;line-height:12px}.sectoken-ip a:hover,.sectoken-other a:hover,.sectoken-role a:hover,.sectoken-user a:hover{background:#fb9}.sectoken-other{display:table;border-collapse:separate}.sectoken-role{background:#efe;border-color:#5b5}.sectoken-user{background:#eff;border-color:#5be}.sectoken-ip{background:#ffe;border-color:#ed5}.sectoken-other{background:#ffe;border-color:#ed5}p.description{font-size:13px;font-style:italic}
|
|
defaults.php
CHANGED
@@ -7,6 +7,8 @@
|
|
7 |
* @package wsal
|
8 |
*/
|
9 |
|
|
|
|
|
10 |
// Exit if accessed directly.
|
11 |
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
exit;
|
@@ -29,7 +31,6 @@ defined( 'E_CRITICAL' ) || define( 'E_CRITICAL', 'E_CRITICAL' );
|
|
29 |
* @param WpSecurityAuditLog $wsal - Instance of main plugin.
|
30 |
*
|
31 |
* @since 3.5.1 - Added the `wsal_custom_alerts_dirs` filter.
|
32 |
-
*
|
33 |
*/
|
34 |
function wsal_load_include_custom_files( $wsal ) {
|
35 |
$paths = apply_filters( 'wsal_custom_alerts_dirs', array() );
|
@@ -42,7 +43,7 @@ function wsal_load_include_custom_files( $wsal ) {
|
|
42 |
require_once $file;
|
43 |
if ( ! empty( $custom_alerts ) && is_array( $custom_alerts ) ) {
|
44 |
try {
|
45 |
-
$wsal->alerts->
|
46 |
} catch ( Exception $ex ) {
|
47 |
$wsal->wsal_log( $ex->getMessage() );
|
48 |
}
|
@@ -53,14 +54,14 @@ function wsal_load_include_custom_files( $wsal ) {
|
|
53 |
}
|
54 |
|
55 |
/**
|
56 |
-
* Builds a configuration object of links suitable for the
|
57 |
*
|
58 |
-
* @param string[] $link_aliases
|
59 |
*
|
60 |
* @return array
|
61 |
*/
|
62 |
-
function wsaldefaults_build_links( $link_aliases =
|
63 |
-
$result =
|
64 |
|
65 |
if ( ! empty( $link_aliases ) ) {
|
66 |
foreach ( $link_aliases as $link_alias ) {
|
@@ -68,70 +69,70 @@ function wsaldefaults_build_links( $link_aliases = [] ) {
|
|
68 |
case 'CategoryLink':
|
69 |
case 'cat_link':
|
70 |
case 'ProductCatLink':
|
71 |
-
$result[
|
72 |
break;
|
73 |
|
74 |
case 'ContactSupport':
|
75 |
-
$result[
|
76 |
break;
|
77 |
|
78 |
case 'CommentLink':
|
79 |
-
$result[
|
80 |
-
//
|
81 |
-
//
|
82 |
'url' => '%CommentLink%',
|
83 |
-
'label' => '%CommentDate%'
|
84 |
-
|
85 |
break;
|
86 |
|
87 |
case 'EditorLinkPage':
|
88 |
-
$result[
|
89 |
break;
|
90 |
|
91 |
case 'EditorLinkPost':
|
92 |
-
$result[
|
93 |
break;
|
94 |
|
95 |
case 'EditorLinkOrder':
|
96 |
-
//
|
97 |
-
$result[
|
98 |
break;
|
99 |
|
100 |
case 'EditUserLink':
|
101 |
-
$result[
|
102 |
break;
|
103 |
|
104 |
case 'LinkFile':
|
105 |
-
$result[
|
106 |
break;
|
107 |
|
108 |
case 'LogFileLink':
|
109 |
-
//
|
110 |
break;
|
111 |
|
112 |
case 'MenuUrl':
|
113 |
-
$result[
|
114 |
break;
|
115 |
|
116 |
case 'PostUrl':
|
117 |
-
$result[
|
118 |
break;
|
119 |
|
120 |
case 'AttachmentUrl':
|
121 |
-
$result[
|
122 |
break;
|
123 |
|
124 |
case 'PostUrlIfPlublished':
|
125 |
case 'PostUrlIfPublished':
|
126 |
-
$result[
|
127 |
break;
|
128 |
|
129 |
case 'RevisionLink':
|
130 |
-
$result[
|
131 |
break;
|
132 |
|
133 |
case 'TagLink':
|
134 |
-
$result[
|
135 |
break;
|
136 |
|
137 |
case 'LogFileText':
|
@@ -145,7 +146,7 @@ function wsaldefaults_build_links( $link_aliases = [] ) {
|
|
145 |
break;
|
146 |
|
147 |
default:
|
148 |
-
//
|
149 |
}
|
150 |
}
|
151 |
}
|
@@ -159,7 +160,7 @@ function wsaldefaults_build_links( $link_aliases = [] ) {
|
|
159 |
* Define default alerts for the plugin.
|
160 |
*/
|
161 |
function wsaldefaults_wsal_init() {
|
162 |
-
$wsal = WpSecurityAuditLog::
|
163 |
|
164 |
if ( ! isset( $wsal->constants ) ) {
|
165 |
$wsal->constants = new WSAL_ConstantManager();
|
@@ -173,959 +174,959 @@ function wsaldefaults_wsal_init() {
|
|
173 |
* severity is based on monolog log levels
|
174 |
* @see https://github.com/Seldaek/monolog/blob/main/doc/01-usage.md#log-levels
|
175 |
*/
|
176 |
-
//
|
177 |
-
$wsal->constants->
|
178 |
-
//
|
179 |
-
$wsal->constants->
|
180 |
-
//
|
181 |
-
$wsal->constants->
|
182 |
-
//
|
183 |
-
$wsal->constants->
|
184 |
-
//
|
185 |
-
$wsal->constants->
|
186 |
|
187 |
// Create list of default alerts.
|
188 |
-
$wsal->alerts->
|
189 |
array(
|
190 |
-
|
191 |
-
|
192 |
array(
|
193 |
1000,
|
194 |
WSAL_LOW,
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
'user',
|
200 |
-
'login'
|
201 |
),
|
202 |
array(
|
203 |
1001,
|
204 |
WSAL_LOW,
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
'user',
|
210 |
-
'logout'
|
211 |
),
|
212 |
array(
|
213 |
1002,
|
214 |
WSAL_MEDIUM,
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
'user',
|
220 |
-
'failed-login'
|
221 |
),
|
222 |
array(
|
223 |
1003,
|
224 |
WSAL_LOW,
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
wsaldefaults_build_links(
|
229 |
'system',
|
230 |
-
'failed-login'
|
231 |
),
|
232 |
array(
|
233 |
1004,
|
234 |
WSAL_MEDIUM,
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
'user',
|
242 |
-
'blocked'
|
243 |
),
|
244 |
array(
|
245 |
1005,
|
246 |
WSAL_LOW,
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
'user',
|
254 |
-
'login'
|
255 |
),
|
256 |
array(
|
257 |
1006,
|
258 |
WSAL_MEDIUM,
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
'user',
|
264 |
-
'logout'
|
265 |
),
|
266 |
array(
|
267 |
1007,
|
268 |
WSAL_MEDIUM,
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
'user',
|
277 |
-
'logout'
|
278 |
),
|
279 |
array(
|
280 |
1008,
|
281 |
WSAL_MEDIUM,
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
'user',
|
289 |
-
'login'
|
290 |
),
|
291 |
array(
|
292 |
1009,
|
293 |
WSAL_LOW,
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
'user',
|
302 |
-
'logout'
|
303 |
),
|
304 |
array(
|
305 |
2010,
|
306 |
WSAL_MEDIUM,
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
wsaldefaults_build_links(
|
313 |
'file',
|
314 |
-
'uploaded'
|
315 |
),
|
316 |
array(
|
317 |
2011,
|
318 |
WSAL_LOW,
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
'file',
|
326 |
-
'deleted'
|
327 |
),
|
328 |
array(
|
329 |
1010,
|
330 |
WSAL_INFORMATIONAL,
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
'user',
|
336 |
-
'submitted'
|
337 |
),
|
338 |
),
|
339 |
),
|
340 |
|
341 |
-
|
342 |
-
|
343 |
array(
|
344 |
2000,
|
345 |
WSAL_INFORMATIONAL,
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
wsaldefaults_build_links(
|
354 |
'post',
|
355 |
-
'created'
|
356 |
),
|
357 |
array(
|
358 |
2001,
|
359 |
WSAL_LOW,
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
wsaldefaults_build_links(
|
368 |
'post',
|
369 |
-
'published'
|
370 |
),
|
371 |
array(
|
372 |
2002,
|
373 |
WSAL_LOW,
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
wsaldefaults_build_links(
|
382 |
'post',
|
383 |
-
'modified'
|
384 |
),
|
385 |
array(
|
386 |
2008,
|
387 |
WSAL_MEDIUM,
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
'post',
|
397 |
-
'deleted'
|
398 |
),
|
399 |
array(
|
400 |
2012,
|
401 |
WSAL_MEDIUM,
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
wsaldefaults_build_links(
|
410 |
'post',
|
411 |
-
'deleted'
|
412 |
),
|
413 |
array(
|
414 |
2014,
|
415 |
WSAL_LOW,
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
wsaldefaults_build_links(
|
424 |
'post',
|
425 |
-
'restored'
|
426 |
),
|
427 |
array(
|
428 |
2017,
|
429 |
WSAL_INFORMATIONAL,
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
wsaldefaults_build_links(
|
440 |
'post',
|
441 |
-
'modified'
|
442 |
),
|
443 |
array(
|
444 |
2019,
|
445 |
WSAL_INFORMATIONAL,
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
wsaldefaults_build_links(
|
455 |
'post',
|
456 |
-
'modified'
|
457 |
),
|
458 |
array(
|
459 |
2021,
|
460 |
WSAL_MEDIUM,
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
wsaldefaults_build_links(
|
469 |
'post',
|
470 |
-
'modified'
|
471 |
),
|
472 |
array(
|
473 |
2025,
|
474 |
WSAL_LOW,
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
wsaldefaults_build_links(
|
484 |
'post',
|
485 |
-
'modified'
|
486 |
),
|
487 |
array(
|
488 |
2027,
|
489 |
WSAL_INFORMATIONAL,
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
wsaldefaults_build_links(
|
499 |
'post',
|
500 |
-
'modified'
|
501 |
),
|
502 |
array(
|
503 |
2047,
|
504 |
WSAL_LOW,
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
wsaldefaults_build_links(
|
514 |
'post',
|
515 |
-
'modified'
|
516 |
),
|
517 |
array(
|
518 |
2048,
|
519 |
WSAL_LOW,
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
wsaldefaults_build_links(
|
529 |
'post',
|
530 |
-
'modified'
|
531 |
),
|
532 |
array(
|
533 |
2049,
|
534 |
WSAL_INFORMATIONAL,
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
wsaldefaults_build_links(
|
543 |
'post',
|
544 |
-
'modified'
|
545 |
),
|
546 |
array(
|
547 |
2050,
|
548 |
WSAL_INFORMATIONAL,
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
wsaldefaults_build_links(
|
557 |
'post',
|
558 |
-
'modified'
|
559 |
),
|
560 |
array(
|
561 |
2065,
|
562 |
WSAL_LOW,
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
wsaldefaults_build_links(
|
571 |
'post',
|
572 |
-
'modified'
|
573 |
),
|
574 |
array(
|
575 |
2073,
|
576 |
WSAL_INFORMATIONAL,
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
wsaldefaults_build_links(
|
585 |
'post',
|
586 |
-
'modified'
|
587 |
),
|
588 |
array(
|
589 |
2074,
|
590 |
WSAL_LOW,
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
wsaldefaults_build_links(
|
599 |
'post',
|
600 |
-
'modified'
|
601 |
),
|
602 |
array(
|
603 |
2086,
|
604 |
WSAL_INFORMATIONAL,
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
wsaldefaults_build_links(
|
613 |
'post',
|
614 |
-
'modified'
|
615 |
),
|
616 |
array(
|
617 |
2100,
|
618 |
WSAL_INFORMATIONAL,
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
wsaldefaults_build_links(
|
627 |
'post',
|
628 |
-
'opened'
|
629 |
),
|
630 |
array(
|
631 |
2101,
|
632 |
WSAL_INFORMATIONAL,
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
wsaldefaults_build_links(
|
641 |
'post',
|
642 |
-
'viewed'
|
643 |
),
|
644 |
array(
|
645 |
2111,
|
646 |
WSAL_LOW,
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
wsaldefaults_build_links(
|
655 |
'post',
|
656 |
-
'enabled'
|
657 |
),
|
658 |
array(
|
659 |
2112,
|
660 |
WSAL_LOW,
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
wsaldefaults_build_links(
|
669 |
'post',
|
670 |
-
'enabled'
|
671 |
),
|
672 |
array(
|
673 |
2129,
|
674 |
WSAL_INFORMATIONAL,
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
wsaldefaults_build_links(
|
685 |
'post',
|
686 |
-
'modified'
|
687 |
),
|
688 |
array(
|
689 |
2130,
|
690 |
WSAL_INFORMATIONAL,
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
wsaldefaults_build_links(
|
701 |
'post',
|
702 |
-
'modified'
|
703 |
),
|
704 |
),
|
705 |
|
706 |
-
|
707 |
array(
|
708 |
2119,
|
709 |
WSAL_INFORMATIONAL,
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
wsaldefaults_build_links(
|
719 |
'post',
|
720 |
-
'modified'
|
721 |
),
|
722 |
array(
|
723 |
2120,
|
724 |
WSAL_INFORMATIONAL,
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
wsaldefaults_build_links(
|
734 |
'post',
|
735 |
-
'modified'
|
736 |
),
|
737 |
array(
|
738 |
2121,
|
739 |
WSAL_INFORMATIONAL,
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
wsaldefaults_build_links(
|
746 |
'tag',
|
747 |
-
'created'
|
748 |
),
|
749 |
array(
|
750 |
2122,
|
751 |
WSAL_LOW,
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
'tag',
|
759 |
-
'deleted'
|
760 |
),
|
761 |
array(
|
762 |
2123,
|
763 |
WSAL_INFORMATIONAL,
|
764 |
-
|
765 |
'',
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
wsaldefaults_build_links(
|
770 |
'tag',
|
771 |
-
'renamed'
|
772 |
),
|
773 |
array(
|
774 |
2124,
|
775 |
WSAL_INFORMATIONAL,
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
wsaldefaults_build_links(
|
782 |
'tag',
|
783 |
-
'modified'
|
784 |
),
|
785 |
array(
|
786 |
2125,
|
787 |
WSAL_INFORMATIONAL,
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
wsaldefaults_build_links(
|
796 |
'tag',
|
797 |
-
'modified'
|
798 |
),
|
799 |
),
|
800 |
|
801 |
-
|
802 |
array(
|
803 |
2016,
|
804 |
WSAL_LOW,
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
wsaldefaults_build_links(
|
814 |
'post',
|
815 |
-
'modified'
|
816 |
),
|
817 |
array(
|
818 |
2023,
|
819 |
WSAL_MEDIUM,
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
wsaldefaults_build_links(
|
826 |
'category',
|
827 |
-
'created'
|
828 |
),
|
829 |
array(
|
830 |
2024,
|
831 |
WSAL_MEDIUM,
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
'category',
|
839 |
-
'deleted'
|
840 |
),
|
841 |
array(
|
842 |
2052,
|
843 |
WSAL_LOW,
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
wsaldefaults_build_links(
|
851 |
'category',
|
852 |
-
'modified'
|
853 |
),
|
854 |
array(
|
855 |
2127,
|
856 |
WSAL_LOW,
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
wsaldefaults_build_links(
|
863 |
'category',
|
864 |
-
'renamed'
|
865 |
),
|
866 |
array(
|
867 |
2128,
|
868 |
WSAL_LOW,
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
wsaldefaults_build_links(
|
875 |
'category',
|
876 |
-
'modified'
|
877 |
),
|
878 |
),
|
879 |
|
880 |
-
|
881 |
array(
|
882 |
2053,
|
883 |
WSAL_LOW,
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
wsaldefaults_build_links(
|
893 |
'post',
|
894 |
-
'modified'
|
895 |
),
|
896 |
array(
|
897 |
2054,
|
898 |
WSAL_LOW,
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
wsaldefaults_build_links(
|
909 |
'custom-field',
|
910 |
-
'modified'
|
911 |
),
|
912 |
array(
|
913 |
2055,
|
914 |
WSAL_MEDIUM,
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
wsaldefaults_build_links(
|
923 |
'custom-field',
|
924 |
-
'deleted'
|
925 |
),
|
926 |
array(
|
927 |
2062,
|
928 |
WSAL_LOW,
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
wsaldefaults_build_links(
|
938 |
'custom-field',
|
939 |
-
'renamed'
|
940 |
),
|
941 |
),
|
942 |
|
943 |
-
|
944 |
array(
|
945 |
2131,
|
946 |
WSAL_LOW,
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
wsaldefaults_build_links(
|
956 |
'custom-field',
|
957 |
-
'modified'
|
958 |
),
|
959 |
array(
|
960 |
2132,
|
961 |
WSAL_LOW,
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
wsaldefaults_build_links(
|
971 |
'custom-field',
|
972 |
-
'modified'
|
973 |
),
|
974 |
),
|
975 |
|
976 |
/**
|
977 |
* Alerts: Comments
|
978 |
*/
|
979 |
-
|
980 |
array(
|
981 |
2090,
|
982 |
WSAL_INFORMATIONAL,
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
wsaldefaults_build_links(
|
992 |
'comment',
|
993 |
-
'approved'
|
994 |
),
|
995 |
array(
|
996 |
2091,
|
997 |
WSAL_INFORMATIONAL,
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
wsaldefaults_build_links(
|
1007 |
'comment',
|
1008 |
-
'unapproved'
|
1009 |
),
|
1010 |
array(
|
1011 |
2092,
|
1012 |
WSAL_INFORMATIONAL,
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
wsaldefaults_build_links(
|
1022 |
'comment',
|
1023 |
-
'created'
|
1024 |
),
|
1025 |
array(
|
1026 |
2093,
|
1027 |
WSAL_LOW,
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
wsaldefaults_build_links(
|
1037 |
'comment',
|
1038 |
-
'modified'
|
1039 |
),
|
1040 |
array(
|
1041 |
2094,
|
1042 |
WSAL_INFORMATIONAL,
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
wsaldefaults_build_links(
|
1052 |
'comment',
|
1053 |
-
'unapproved'
|
1054 |
),
|
1055 |
array(
|
1056 |
2095,
|
1057 |
WSAL_LOW,
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
wsaldefaults_build_links(
|
1067 |
'comment',
|
1068 |
-
'approved'
|
1069 |
),
|
1070 |
array(
|
1071 |
2096,
|
1072 |
WSAL_LOW,
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
wsaldefaults_build_links(
|
1082 |
'comment',
|
1083 |
-
'deleted'
|
1084 |
),
|
1085 |
array(
|
1086 |
2097,
|
1087 |
WSAL_INFORMATIONAL,
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
wsaldefaults_build_links(
|
1097 |
'comment',
|
1098 |
-
'restored'
|
1099 |
),
|
1100 |
array(
|
1101 |
2098,
|
1102 |
WSAL_LOW,
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
wsaldefaults_build_links(
|
1112 |
'comment',
|
1113 |
-
'deleted'
|
1114 |
),
|
1115 |
array(
|
1116 |
2099,
|
1117 |
WSAL_INFORMATIONAL,
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
wsaldefaults_build_links(
|
1127 |
'comment',
|
1128 |
-
'created'
|
1129 |
),
|
1130 |
/**
|
1131 |
* IMPORTANT: This alert is deprecated but should not be
|
@@ -1134,181 +1135,181 @@ function wsaldefaults_wsal_init() {
|
|
1134 |
array(
|
1135 |
2126,
|
1136 |
WSAL_INFORMATIONAL,
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
wsaldefaults_build_links(
|
1146 |
'comment',
|
1147 |
-
'created'
|
1148 |
),
|
1149 |
),
|
1150 |
|
1151 |
/**
|
1152 |
* Alerts: Widgets
|
1153 |
*/
|
1154 |
-
|
1155 |
array(
|
1156 |
2042,
|
1157 |
WSAL_MEDIUM,
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
'widget',
|
1163 |
-
'added'
|
1164 |
),
|
1165 |
array(
|
1166 |
2043,
|
1167 |
WSAL_HIGH,
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
'widget',
|
1173 |
-
'modified'
|
1174 |
),
|
1175 |
array(
|
1176 |
2044,
|
1177 |
WSAL_MEDIUM,
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
'widget',
|
1183 |
-
'deleted'
|
1184 |
),
|
1185 |
array(
|
1186 |
2045,
|
1187 |
WSAL_LOW,
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
'widget',
|
1196 |
-
'modified'
|
1197 |
),
|
1198 |
array(
|
1199 |
2071,
|
1200 |
WSAL_LOW,
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
'widget',
|
1206 |
-
'modified'
|
1207 |
),
|
1208 |
),
|
1209 |
|
1210 |
/**
|
1211 |
* Alerts: Menus
|
1212 |
*/
|
1213 |
-
|
1214 |
array(
|
1215 |
2078,
|
1216 |
WSAL_LOW,
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
wsaldefaults_build_links(
|
1221 |
'menu',
|
1222 |
-
'created'
|
1223 |
),
|
1224 |
array(
|
1225 |
2079,
|
1226 |
WSAL_LOW,
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
wsaldefaults_build_links(
|
1233 |
'menu',
|
1234 |
-
'modified'
|
1235 |
),
|
1236 |
array(
|
1237 |
2080,
|
1238 |
WSAL_LOW,
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
wsaldefaults_build_links(
|
1245 |
'menu',
|
1246 |
-
'modified'
|
1247 |
),
|
1248 |
array(
|
1249 |
2081,
|
1250 |
WSAL_MEDIUM,
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
'menu',
|
1256 |
-
'deleted'
|
1257 |
),
|
1258 |
array(
|
1259 |
2082,
|
1260 |
WSAL_LOW,
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
wsaldefaults_build_links(
|
1265 |
'menu',
|
1266 |
-
'enabled'
|
1267 |
),
|
1268 |
array(
|
1269 |
2083,
|
1270 |
WSAL_LOW,
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
wsaldefaults_build_links(
|
1277 |
'menu',
|
1278 |
-
'modified'
|
1279 |
),
|
1280 |
array(
|
1281 |
2084,
|
1282 |
WSAL_LOW,
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
wsaldefaults_build_links(
|
1287 |
'menu',
|
1288 |
-
'renamed'
|
1289 |
),
|
1290 |
array(
|
1291 |
2085,
|
1292 |
WSAL_LOW,
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
wsaldefaults_build_links(
|
1297 |
'menu',
|
1298 |
-
'modified'
|
1299 |
),
|
1300 |
array(
|
1301 |
2089,
|
1302 |
WSAL_LOW,
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
wsaldefaults_build_links(
|
1310 |
'menu',
|
1311 |
-
'modified'
|
1312 |
),
|
1313 |
),
|
1314 |
|
@@ -1320,180 +1321,180 @@ function wsaldefaults_wsal_init() {
|
|
1320 |
*
|
1321 |
* @deprecated 3.1.0
|
1322 |
*/
|
1323 |
-
|
1324 |
array(
|
1325 |
2003,
|
1326 |
E_NOTICE,
|
1327 |
-
|
1328 |
-
|
1329 |
),
|
1330 |
array(
|
1331 |
2029,
|
1332 |
E_NOTICE,
|
1333 |
-
|
1334 |
-
|
1335 |
),
|
1336 |
array(
|
1337 |
2030,
|
1338 |
E_NOTICE,
|
1339 |
-
|
1340 |
-
|
1341 |
),
|
1342 |
array(
|
1343 |
2031,
|
1344 |
E_NOTICE,
|
1345 |
-
|
1346 |
-
|
1347 |
),
|
1348 |
array(
|
1349 |
2032,
|
1350 |
E_NOTICE,
|
1351 |
-
|
1352 |
-
|
1353 |
),
|
1354 |
array(
|
1355 |
2033,
|
1356 |
E_WARNING,
|
1357 |
-
|
1358 |
-
|
1359 |
),
|
1360 |
array(
|
1361 |
2034,
|
1362 |
E_WARNING,
|
1363 |
-
|
1364 |
-
|
1365 |
),
|
1366 |
array(
|
1367 |
2035,
|
1368 |
E_CRITICAL,
|
1369 |
-
|
1370 |
-
|
1371 |
),
|
1372 |
array(
|
1373 |
2036,
|
1374 |
E_NOTICE,
|
1375 |
-
|
1376 |
-
|
1377 |
),
|
1378 |
array(
|
1379 |
2037,
|
1380 |
E_NOTICE,
|
1381 |
-
|
1382 |
-
|
1383 |
),
|
1384 |
array(
|
1385 |
2038,
|
1386 |
E_NOTICE,
|
1387 |
-
|
1388 |
-
|
1389 |
),
|
1390 |
array(
|
1391 |
2039,
|
1392 |
E_NOTICE,
|
1393 |
-
|
1394 |
-
|
1395 |
),
|
1396 |
array(
|
1397 |
2040,
|
1398 |
E_WARNING,
|
1399 |
-
|
1400 |
-
|
1401 |
),
|
1402 |
array(
|
1403 |
2041,
|
1404 |
E_NOTICE,
|
1405 |
-
|
1406 |
-
|
1407 |
),
|
1408 |
array(
|
1409 |
2056,
|
1410 |
E_CRITICAL,
|
1411 |
-
|
1412 |
-
|
1413 |
),
|
1414 |
array(
|
1415 |
2057,
|
1416 |
E_CRITICAL,
|
1417 |
-
|
1418 |
-
|
1419 |
),
|
1420 |
array(
|
1421 |
2058,
|
1422 |
E_CRITICAL,
|
1423 |
-
|
1424 |
-
|
1425 |
),
|
1426 |
array(
|
1427 |
2063,
|
1428 |
E_CRITICAL,
|
1429 |
-
|
1430 |
-
|
1431 |
),
|
1432 |
array(
|
1433 |
2067,
|
1434 |
E_WARNING,
|
1435 |
-
|
1436 |
-
|
1437 |
),
|
1438 |
array(
|
1439 |
2068,
|
1440 |
E_NOTICE,
|
1441 |
-
|
1442 |
-
|
1443 |
),
|
1444 |
array(
|
1445 |
2070,
|
1446 |
E_NOTICE,
|
1447 |
-
|
1448 |
-
|
1449 |
),
|
1450 |
array(
|
1451 |
2072,
|
1452 |
E_NOTICE,
|
1453 |
-
|
1454 |
-
|
1455 |
),
|
1456 |
array(
|
1457 |
2076,
|
1458 |
E_NOTICE,
|
1459 |
-
|
1460 |
-
|
1461 |
),
|
1462 |
array(
|
1463 |
2088,
|
1464 |
E_NOTICE,
|
1465 |
-
|
1466 |
-
|
1467 |
),
|
1468 |
array(
|
1469 |
2104,
|
1470 |
E_NOTICE,
|
1471 |
-
|
1472 |
-
|
1473 |
),
|
1474 |
array(
|
1475 |
2105,
|
1476 |
E_NOTICE,
|
1477 |
-
|
1478 |
-
|
1479 |
),
|
1480 |
array(
|
1481 |
5021,
|
1482 |
E_CRITICAL,
|
1483 |
-
|
1484 |
-
|
1485 |
),
|
1486 |
array(
|
1487 |
5027,
|
1488 |
E_CRITICAL,
|
1489 |
-
|
1490 |
-
|
1491 |
),
|
1492 |
array(
|
1493 |
2108,
|
1494 |
E_NOTICE,
|
1495 |
-
|
1496 |
-
|
1497 |
),
|
1498 |
),
|
1499 |
|
@@ -1505,883 +1506,883 @@ function wsaldefaults_wsal_init() {
|
|
1505 |
*
|
1506 |
* @deprecated 3.1.0
|
1507 |
*/
|
1508 |
-
|
1509 |
array(
|
1510 |
2004,
|
1511 |
E_NOTICE,
|
1512 |
-
|
1513 |
-
|
1514 |
),
|
1515 |
array(
|
1516 |
2005,
|
1517 |
E_NOTICE,
|
1518 |
-
|
1519 |
-
|
1520 |
),
|
1521 |
array(
|
1522 |
2006,
|
1523 |
E_NOTICE,
|
1524 |
-
|
1525 |
-
|
1526 |
),
|
1527 |
array(
|
1528 |
2007,
|
1529 |
E_NOTICE,
|
1530 |
-
|
1531 |
-
|
1532 |
),
|
1533 |
array(
|
1534 |
2009,
|
1535 |
E_WARNING,
|
1536 |
-
|
1537 |
-
|
1538 |
),
|
1539 |
array(
|
1540 |
2013,
|
1541 |
E_WARNING,
|
1542 |
-
|
1543 |
-
|
1544 |
),
|
1545 |
array(
|
1546 |
2015,
|
1547 |
E_CRITICAL,
|
1548 |
-
|
1549 |
-
|
1550 |
),
|
1551 |
array(
|
1552 |
2018,
|
1553 |
E_NOTICE,
|
1554 |
-
|
1555 |
-
|
1556 |
),
|
1557 |
array(
|
1558 |
2020,
|
1559 |
E_NOTICE,
|
1560 |
-
|
1561 |
-
|
1562 |
),
|
1563 |
array(
|
1564 |
2022,
|
1565 |
E_NOTICE,
|
1566 |
-
|
1567 |
-
|
1568 |
),
|
1569 |
array(
|
1570 |
2026,
|
1571 |
E_WARNING,
|
1572 |
-
|
1573 |
-
|
1574 |
),
|
1575 |
array(
|
1576 |
2028,
|
1577 |
E_NOTICE,
|
1578 |
-
|
1579 |
-
|
1580 |
),
|
1581 |
array(
|
1582 |
2059,
|
1583 |
E_CRITICAL,
|
1584 |
-
|
1585 |
-
|
1586 |
),
|
1587 |
array(
|
1588 |
2060,
|
1589 |
E_CRITICAL,
|
1590 |
-
|
1591 |
-
|
1592 |
),
|
1593 |
array(
|
1594 |
2061,
|
1595 |
E_CRITICAL,
|
1596 |
-
|
1597 |
-
|
1598 |
),
|
1599 |
array(
|
1600 |
2064,
|
1601 |
E_CRITICAL,
|
1602 |
-
|
1603 |
-
|
1604 |
),
|
1605 |
array(
|
1606 |
2066,
|
1607 |
E_WARNING,
|
1608 |
-
|
1609 |
-
|
1610 |
),
|
1611 |
array(
|
1612 |
2069,
|
1613 |
E_NOTICE,
|
1614 |
-
|
1615 |
-
|
1616 |
),
|
1617 |
array(
|
1618 |
2075,
|
1619 |
E_NOTICE,
|
1620 |
-
|
1621 |
-
__( 'Scheduled the page %PostTitle% to be published %PublishingDate%. %EditorLinkPage%.', 'wp-security-audit-log' )
|
7 |
* @package wsal
|
8 |
*/
|
9 |
|
10 |
+
// phpcs:disable WordPress.WP.I18n.MissingTranslatorsComment
|
11 |
+
|
12 |
// Exit if accessed directly.
|
13 |
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
exit;
|
31 |
* @param WpSecurityAuditLog $wsal - Instance of main plugin.
|
32 |
*
|
33 |
* @since 3.5.1 - Added the `wsal_custom_alerts_dirs` filter.
|
|
|
34 |
*/
|
35 |
function wsal_load_include_custom_files( $wsal ) {
|
36 |
$paths = apply_filters( 'wsal_custom_alerts_dirs', array() );
|
43 |
require_once $file;
|
44 |
if ( ! empty( $custom_alerts ) && is_array( $custom_alerts ) ) {
|
45 |
try {
|
46 |
+
$wsal->alerts->register_group( $custom_alerts );
|
47 |
} catch ( Exception $ex ) {
|
48 |
$wsal->wsal_log( $ex->getMessage() );
|
49 |
}
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
+
* Builds a configuration object of links suitable for the events definition.
|
58 |
*
|
59 |
+
* @param string[] $link_aliases Link aliases.
|
60 |
*
|
61 |
* @return array
|
62 |
*/
|
63 |
+
function wsaldefaults_build_links( $link_aliases = array() ) {
|
64 |
+
$result = array();
|
65 |
|
66 |
if ( ! empty( $link_aliases ) ) {
|
67 |
foreach ( $link_aliases as $link_alias ) {
|
69 |
case 'CategoryLink':
|
70 |
case 'cat_link':
|
71 |
case 'ProductCatLink':
|
72 |
+
$result[ esc_html__( 'View category', 'wp-security-audit-log' ) ] = '%' . $link_alias . '%';
|
73 |
break;
|
74 |
|
75 |
case 'ContactSupport':
|
76 |
+
$result[ esc_html__( 'Contact Support', 'wp-security-audit-log' ) ] = 'https://wpactivitylog.com/contact/';
|
77 |
break;
|
78 |
|
79 |
case 'CommentLink':
|
80 |
+
$result[ esc_html__( 'Comment', 'wp-security-audit-log' ) ] = array(
|
81 |
+
// Before 4.2.1 the CommentLink meta would contain the full HTML markup for the link, now it
|
82 |
+
// contains only the URL.
|
83 |
'url' => '%CommentLink%',
|
84 |
+
'label' => '%CommentDate%',
|
85 |
+
);
|
86 |
break;
|
87 |
|
88 |
case 'EditorLinkPage':
|
89 |
+
$result[ esc_html__( 'View page in the editor', 'wp-security-audit-log' ) ] = '%EditorLinkPage%';
|
90 |
break;
|
91 |
|
92 |
case 'EditorLinkPost':
|
93 |
+
$result[ esc_html__( 'View the post in editor', 'wp-security-audit-log' ) ] = '%EditorLinkPost%';
|
94 |
break;
|
95 |
|
96 |
case 'EditorLinkOrder':
|
97 |
+
// @todo move to the WooCommerce extension
|
98 |
+
$result[ esc_html__( 'View the order', 'wp-security-audit-log' ) ] = '%EditorLinkOrder%';
|
99 |
break;
|
100 |
|
101 |
case 'EditUserLink':
|
102 |
+
$result[ esc_html__( 'User profile page', 'wp-security-audit-log' ) ] = '%EditUserLink%';
|
103 |
break;
|
104 |
|
105 |
case 'LinkFile':
|
106 |
+
$result[ esc_html__( 'Open the log file', 'wp-security-audit-log' ) ] = '%LinkFile%';
|
107 |
break;
|
108 |
|
109 |
case 'LogFileLink':
|
110 |
+
// We don't show the link anymore.
|
111 |
break;
|
112 |
|
113 |
case 'MenuUrl':
|
114 |
+
$result[ esc_html__( 'View menu', 'wp-security-audit-log' ) ] = '%MenuUrl%';
|
115 |
break;
|
116 |
|
117 |
case 'PostUrl':
|
118 |
+
$result[ esc_html__( 'URL', 'wp-security-audit-log' ) ] = '%PostUrl%';
|
119 |
break;
|
120 |
|
121 |
case 'AttachmentUrl':
|
122 |
+
$result[ esc_html__( 'View attachment page', 'wp-security-audit-log' ) ] = '%AttachmentUrl%';
|
123 |
break;
|
124 |
|
125 |
case 'PostUrlIfPlublished':
|
126 |
case 'PostUrlIfPublished':
|
127 |
+
$result[ esc_html__( 'URL', 'wp-security-audit-log' ) ] = '%PostUrlIfPlublished%';
|
128 |
break;
|
129 |
|
130 |
case 'RevisionLink':
|
131 |
+
$result[ esc_html__( 'View the content changes', 'wp-security-audit-log' ) ] = '%RevisionLink%';
|
132 |
break;
|
133 |
|
134 |
case 'TagLink':
|
135 |
+
$result[ esc_html__( 'View tag', 'wp-security-audit-log' ) ] = '%RevisionLink%';
|
136 |
break;
|
137 |
|
138 |
case 'LogFileText':
|
146 |
break;
|
147 |
|
148 |
default:
|
149 |
+
// Unsupported link alias.
|
150 |
}
|
151 |
}
|
152 |
}
|
160 |
* Define default alerts for the plugin.
|
161 |
*/
|
162 |
function wsaldefaults_wsal_init() {
|
163 |
+
$wsal = WpSecurityAuditLog::get_instance();
|
164 |
|
165 |
if ( ! isset( $wsal->constants ) ) {
|
166 |
$wsal->constants = new WSAL_ConstantManager();
|
174 |
* severity is based on monolog log levels
|
175 |
* @see https://github.com/Seldaek/monolog/blob/main/doc/01-usage.md#log-levels
|
176 |
*/
|
177 |
+
// ALERT (550): Action must be taken immediately.
|
178 |
+
$wsal->constants->add_constant( 'WSAL_CRITICAL', 500, esc_html__( 'Critical severity events.', 'wp-security-audit-log' ) );
|
179 |
+
// ERROR (400): Runtime errors that do not require immediate action but should typically be logged and monitored.
|
180 |
+
$wsal->constants->add_constant( 'WSAL_HIGH', 400, esc_html__( 'High severity events.', 'wp-security-audit-log' ) );
|
181 |
+
// WARNING (300): Exceptional occurrences that are not errors.
|
182 |
+
$wsal->constants->add_constant( 'WSAL_MEDIUM', 300, esc_html__( 'Medium severity events.', 'wp-security-audit-log' ) );
|
183 |
+
// NOTICE (250): Normal but significant events.
|
184 |
+
$wsal->constants->add_constant( 'WSAL_LOW', 250, esc_html__( 'Low severity events.', 'wp-security-audit-log' ) );
|
185 |
+
// INFO (200): Interesting events.
|
186 |
+
$wsal->constants->add_constant( 'WSAL_INFORMATIONAL', 200, esc_html__( 'Informational events.', 'wp-security-audit-log' ) );
|
187 |
|
188 |
// Create list of default alerts.
|
189 |
+
$wsal->alerts->register_group(
|
190 |
array(
|
191 |
+
esc_html__( 'Users Logins & Sessions Events', 'wp-security-audit-log' ) => array(
|
192 |
+
esc_html__( 'User Activity', 'wp-security-audit-log' ) => array(
|
193 |
array(
|
194 |
1000,
|
195 |
WSAL_LOW,
|
196 |
+
esc_html__( 'User logged in', 'wp-security-audit-log' ),
|
197 |
+
esc_html__( 'User logged in.', 'wp-security-audit-log' ),
|
198 |
+
array(),
|
199 |
+
array(),
|
200 |
'user',
|
201 |
+
'login',
|
202 |
),
|
203 |
array(
|
204 |
1001,
|
205 |
WSAL_LOW,
|
206 |
+
esc_html__( 'User logged out', 'wp-security-audit-log' ),
|
207 |
+
esc_html__( 'User logged out.', 'wp-security-audit-log' ),
|
208 |
+
array(),
|
209 |
+
array(),
|
210 |
'user',
|
211 |
+
'logout',
|
212 |
),
|
213 |
array(
|
214 |
1002,
|
215 |
WSAL_MEDIUM,
|
216 |
+
esc_html__( 'Login failed', 'wp-security-audit-log' ),
|
217 |
+
esc_html__( '%Attempts% failed login(s).', 'wp-security-audit-log' ),
|
218 |
+
array(),
|
219 |
+
array(),
|
220 |
'user',
|
221 |
+
'failed-login',
|
222 |
),
|
223 |
array(
|
224 |
1003,
|
225 |
WSAL_LOW,
|
226 |
+
esc_html__( 'Login failed / non existing user', 'wp-security-audit-log' ),
|
227 |
+
esc_html__( '%Attempts% failed login(s).', 'wp-security-audit-log' ),
|
228 |
+
array(),
|
229 |
+
wsaldefaults_build_links( array( 'LogFileText' ) ),
|
230 |
'system',
|
231 |
+
'failed-login',
|
232 |
),
|
233 |
array(
|
234 |
1004,
|
235 |
WSAL_MEDIUM,
|
236 |
+
esc_html__( 'Login blocked', 'wp-security-audit-log' ),
|
237 |
+
esc_html__( 'Login blocked because other session(s) already exist for this user.', 'wp-security-audit-log' ),
|
238 |
+
array(
|
239 |
+
esc_html__( 'IP address', 'wp-security-audit-log' ) => '%ClientIP%',
|
240 |
+
),
|
241 |
+
array(),
|
242 |
'user',
|
243 |
+
'blocked',
|
244 |
),
|
245 |
array(
|
246 |
1005,
|
247 |
WSAL_LOW,
|
248 |
+
esc_html__( 'User logged in with existing session(s)', 'wp-security-audit-log' ),
|
249 |
+
esc_html__( 'User logged in however there are other session(s) already for this user.', 'wp-security-audit-log' ),
|
250 |
+
array(
|
251 |
+
esc_html__( 'IP address(es)', 'wp-security-audit-log' ) => '%IPAddress%',
|
252 |
+
),
|
253 |
+
array(),
|
254 |
'user',
|
255 |
+
'login',
|
256 |
),
|
257 |
array(
|
258 |
1006,
|
259 |
WSAL_MEDIUM,
|
260 |
+
esc_html__( 'User logged out all other sessions with the same username', 'wp-security-audit-log' ),
|
261 |
+
esc_html__( 'Logged out all other sessions with the same user.', 'wp-security-audit-log' ),
|
262 |
+
array(),
|
263 |
+
array(),
|
264 |
'user',
|
265 |
+
'logout',
|
266 |
),
|
267 |
array(
|
268 |
1007,
|
269 |
WSAL_MEDIUM,
|
270 |
+
esc_html__( 'User session destroyed and logged out', 'wp-security-audit-log' ),
|
271 |
+
esc_html__( 'Terminated the session of the user %TargetUserName%.', 'wp-security-audit-log' ),
|
272 |
+
array(
|
273 |
+
esc_html__( 'Role', 'wp-security-audit-log' ) => '%TargetUserRole%',
|
274 |
+
esc_html__( 'Session ID', 'wp-security-audit-log' ) => '%TargetSessionID%',
|
275 |
+
),
|
276 |
+
array(),
|
277 |
'user',
|
278 |
+
'logout',
|
279 |
),
|
280 |
array(
|
281 |
1008,
|
282 |
WSAL_MEDIUM,
|
283 |
+
esc_html__( 'Switched to another user', 'wp-security-audit-log' ),
|
284 |
+
esc_html__( 'Switched the session to being logged in as %TargetUserName%.', 'wp-security-audit-log' ),
|
285 |
+
array(
|
286 |
+
esc_html__( 'Role', 'wp-security-audit-log' ) => '%TargetUserRole%',
|
287 |
+
),
|
288 |
+
array(),
|
289 |
'user',
|
290 |
+
'login',
|
291 |
),
|
292 |
array(
|
293 |
1009,
|
294 |
WSAL_LOW,
|
295 |
+
esc_html__( 'The plugin terminated an idle session for a user', 'wp-security-audit-log' ),
|
296 |
+
esc_html__( 'The plugin terminated an idle session for the user %username%.', 'wp-security-audit-log' ),
|
297 |
+
array(
|
298 |
+
esc_html__( 'Role', 'wp-security-audit-log' ) => '%TargetUserRole%',
|
299 |
+
esc_html__( 'Session ID', 'wp-security-audit-log' ) => '%SessionID%',
|
300 |
+
),
|
301 |
+
array(),
|
302 |
'user',
|
303 |
+
'logout',
|
304 |
),
|
305 |
array(
|
306 |
2010,
|
307 |
WSAL_MEDIUM,
|
308 |
+
esc_html__( 'User uploaded file to the Uploads directory', 'wp-security-audit-log' ),
|
309 |
+
esc_html__( 'Uploaded a file called %FileName%.', 'wp-security-audit-log' ),
|
310 |
+
array(
|
311 |
+
esc_html__( 'Directory', 'wp-security-audit-log' ) => '%FilePath%',
|
312 |
+
),
|
313 |
+
wsaldefaults_build_links( array( 'AttachmentUrl' ) ),
|
314 |
'file',
|
315 |
+
'uploaded',
|
316 |
),
|
317 |
array(
|
318 |
2011,
|
319 |
WSAL_LOW,
|
320 |
+
esc_html__( 'User deleted file from Uploads directory', 'wp-security-audit-log' ),
|
321 |
+
esc_html__( 'Deleted the file %FileName%.', 'wp-security-audit-log' ),
|
322 |
+
array(
|
323 |
+
esc_html__( 'Directory', 'wp-security-audit-log' ) => '%FilePath%',
|
324 |
+
),
|
325 |
+
array(),
|
326 |
'file',
|
327 |
+
'deleted',
|
328 |
),
|
329 |
array(
|
330 |
1010,
|
331 |
WSAL_INFORMATIONAL,
|
332 |
+
esc_html__( 'User requested a password reset', 'wp-security-audit-log' ),
|
333 |
+
esc_html__( 'User requested a password reset. This does not mean that the password was changed.', 'wp-security-audit-log' ),
|
334 |
+
array(),
|
335 |
+
array(),
|
336 |
'user',
|
337 |
+
'submitted',
|
338 |
),
|
339 |
),
|
340 |
),
|
341 |
|
342 |
+
esc_html__( 'Content & Comments', 'wp-security-audit-log' ) => array(
|
343 |
+
esc_html__( 'Content', 'wp-security-audit-log' ) => array(
|
344 |
array(
|
345 |
2000,
|
346 |
WSAL_INFORMATIONAL,
|
347 |
+
esc_html__( 'User created a new post and saved it as draft', 'wp-security-audit-log' ),
|
348 |
+
esc_html__( 'Created the post %PostTitle%.', 'wp-security-audit-log' ),
|
349 |
+
array(
|
350 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
351 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
352 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
353 |
+
),
|
354 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
355 |
'post',
|
356 |
+
'created',
|
357 |
),
|
358 |
array(
|
359 |
2001,
|
360 |
WSAL_LOW,
|
361 |
+
esc_html__( 'User published a post', 'wp-security-audit-log' ),
|
362 |
+
esc_html__( 'Published the post %PostTitle%.', 'wp-security-audit-log' ),
|
363 |
+
array(
|
364 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
365 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
366 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
367 |
+
),
|
368 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
369 |
'post',
|
370 |
+
'published',
|
371 |
),
|
372 |
array(
|
373 |
2002,
|
374 |
WSAL_LOW,
|
375 |
+
esc_html__( 'User modified a post', 'wp-security-audit-log' ),
|
376 |
+
esc_html__( 'Modified the post %PostTitle%.', 'wp-security-audit-log' ),
|
377 |
+
array(
|
378 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
379 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
380 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
381 |
+
),
|
382 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
383 |
'post',
|
384 |
+
'modified',
|
385 |
),
|
386 |
array(
|
387 |
2008,
|
388 |
WSAL_MEDIUM,
|
389 |
+
esc_html__( 'User permanently deleted a post from the trash', 'wp-security-audit-log' ),
|
390 |
+
esc_html__( 'Permanently deleted the post %PostTitle%.', 'wp-security-audit-log' ),
|
391 |
+
array(
|
392 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
393 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
394 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
395 |
+
),
|
396 |
+
array(),
|
397 |
'post',
|
398 |
+
'deleted',
|
399 |
),
|
400 |
array(
|
401 |
2012,
|
402 |
WSAL_MEDIUM,
|
403 |
+
esc_html__( 'User moved a post to the trash', 'wp-security-audit-log' ),
|
404 |
+
esc_html__( 'Moved the post %PostTitle% to trash.', 'wp-security-audit-log' ),
|
405 |
+
array(
|
406 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
407 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
408 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
409 |
+
),
|
410 |
+
wsaldefaults_build_links( array( 'PostUrlIfPublished' ) ),
|
411 |
'post',
|
412 |
+
'deleted',
|
413 |
),
|
414 |
array(
|
415 |
2014,
|
416 |
WSAL_LOW,
|
417 |
+
esc_html__( 'User restored a post from trash', 'wp-security-audit-log' ),
|
418 |
+
esc_html__( 'Restored the post %PostTitle% from trash.', 'wp-security-audit-log' ),
|
419 |
+
array(
|
420 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
421 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
422 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
423 |
+
),
|
424 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
425 |
'post',
|
426 |
+
'restored',
|
427 |
),
|
428 |
array(
|
429 |
2017,
|
430 |
WSAL_INFORMATIONAL,
|
431 |
+
esc_html__( 'User changed post URL', 'wp-security-audit-log' ),
|
432 |
+
esc_html__( 'Changed the URL of the post %PostTitle%.', 'wp-security-audit-log' ),
|
433 |
+
array(
|
434 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
435 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
436 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
437 |
+
esc_html__( 'Previous URL', 'wp-security-audit-log' ) => '%OldUrl%',
|
438 |
+
esc_html__( 'New URL', 'wp-security-audit-log' ) => '%NewUrl%',
|
439 |
+
),
|
440 |
+
wsaldefaults_build_links( array( 'EditorLinkPost' ) ),
|
441 |
'post',
|
442 |
+
'modified',
|
443 |
),
|
444 |
array(
|
445 |
2019,
|
446 |
WSAL_INFORMATIONAL,
|
447 |
+
esc_html__( 'User changed post author', 'wp-security-audit-log' ),
|
448 |
+
esc_html__( 'Changed the author of the post %PostTitle% to %NewAuthor%.', 'wp-security-audit-log' ),
|
449 |
+
array(
|
450 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
451 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
452 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
453 |
+
esc_html__( 'Previous author', 'wp-security-audit-log' ) => '%OldAuthor%',
|
454 |
+
),
|
455 |
+
wsaldefaults_build_links( array( 'PostUrlIfPublished' ) ),
|
456 |
'post',
|
457 |
+
'modified',
|
458 |
),
|
459 |
array(
|
460 |
2021,
|
461 |
WSAL_MEDIUM,
|
462 |
+
esc_html__( 'User changed post status', 'wp-security-audit-log' ),
|
463 |
+
esc_html__( 'Changed the status of the post %PostTitle% to %NewStatus%.', 'wp-security-audit-log' ),
|
464 |
+
array(
|
465 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
466 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
467 |
+
esc_html__( 'Previous status', 'wp-security-audit-log' ) => '%OldStatus%',
|
468 |
+
),
|
469 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
470 |
'post',
|
471 |
+
'modified',
|
472 |
),
|
473 |
array(
|
474 |
2025,
|
475 |
WSAL_LOW,
|
476 |
+
esc_html__( 'User changed the visibility of a post', 'wp-security-audit-log' ),
|
477 |
+
esc_html__( 'Changed the visibility of the post %PostTitle% to %NewVisibility%.', 'wp-security-audit-log' ),
|
478 |
+
array(
|
479 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
480 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
481 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
482 |
+
esc_html__( 'Previous visibility status', 'wp-security-audit-log' ) => '%OldVisibility%',
|
483 |
+
),
|
484 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
485 |
'post',
|
486 |
+
'modified',
|
487 |
),
|
488 |
array(
|
489 |
2027,
|
490 |
WSAL_INFORMATIONAL,
|
491 |
+
esc_html__( 'User changed the date of a post', 'wp-security-audit-log' ),
|
492 |
+
esc_html__( 'Changed the date of the post %PostTitle% to %NewDate%.', 'wp-security-audit-log' ),
|
493 |
+
array(
|
494 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
495 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
496 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
497 |
+
esc_html__( 'Previous date', 'wp-security-audit-log' ) => '%OldDate%',
|
498 |
+
),
|
499 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
500 |
'post',
|
501 |
+
'modified',
|
502 |
),
|
503 |
array(
|
504 |
2047,
|
505 |
WSAL_LOW,
|
506 |
+
esc_html__( 'User changed the parent of a page', 'wp-security-audit-log' ),
|
507 |
+
esc_html__( 'Changed the parent of the post %PostTitle% to %NewParentName%.', 'wp-security-audit-log' ),
|
508 |
+
array(
|
509 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
510 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
511 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
512 |
+
esc_html__( 'Previous parent', 'wp-security-audit-log' ) => '%OldParentName%',
|
513 |
+
),
|
514 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
515 |
'post',
|
516 |
+
'modified',
|
517 |
),
|
518 |
array(
|
519 |
2048,
|
520 |
WSAL_LOW,
|
521 |
+
esc_html__( 'User changed the template of a page', 'wp-security-audit-log' ),
|
522 |
+
esc_html__( 'Changed the template of the post %PostTitle% to %NewTemplate%.', 'wp-security-audit-log' ),
|
523 |
+
array(
|
524 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
525 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
526 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
527 |
+
esc_html__( 'Previous template', 'wp-security-audit-log' ) => '%OldTemplate%',
|
528 |
+
),
|
529 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
530 |
'post',
|
531 |
+
'modified',
|
532 |
),
|
533 |
array(
|
534 |
2049,
|
535 |
WSAL_INFORMATIONAL,
|
536 |
+
esc_html__( 'User set a post as sticky', 'wp-security-audit-log' ),
|
537 |
+
esc_html__( 'Set the post %PostTitle% as sticky.', 'wp-security-audit-log' ),
|
538 |
+
array(
|
539 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
540 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
541 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
542 |
+
),
|
543 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
544 |
'post',
|
545 |
+
'modified',
|
546 |
),
|
547 |
array(
|
548 |
2050,
|
549 |
WSAL_INFORMATIONAL,
|
550 |
+
esc_html__( 'User removed post from sticky', 'wp-security-audit-log' ),
|
551 |
+
esc_html__( 'Removed the post %PostTitle% from sticky.', 'wp-security-audit-log' ),
|
552 |
+
array(
|
553 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
554 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
555 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
556 |
+
),
|
557 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
558 |
'post',
|
559 |
+
'modified',
|
560 |
),
|
561 |
array(
|
562 |
2065,
|
563 |
WSAL_LOW,
|
564 |
+
esc_html__( 'User modified the content of a post', 'wp-security-audit-log' ),
|
565 |
+
esc_html__( 'Modified the content of the post %PostTitle%.', 'wp-security-audit-log' ),
|
566 |
+
array(
|
567 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
568 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
569 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
570 |
+
),
|
571 |
+
wsaldefaults_build_links( array( 'RevisionLink', 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
572 |
'post',
|
573 |
+
'modified',
|
574 |
),
|
575 |
array(
|
576 |
2073,
|
577 |
WSAL_INFORMATIONAL,
|
578 |
+
esc_html__( 'User submitted a post for review', 'wp-security-audit-log' ),
|
579 |
+
esc_html__( 'Submitted the post %PostTitle% for review.', 'wp-security-audit-log' ),
|
580 |
+
array(
|
581 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
582 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
583 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
584 |
+
),
|
585 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
586 |
'post',
|
587 |
+
'modified',
|
588 |
),
|
589 |
array(
|
590 |
2074,
|
591 |
WSAL_LOW,
|
592 |
+
esc_html__( 'User scheduled a post', 'wp-security-audit-log' ),
|
593 |
+
esc_html__( 'Scheduled the post %PostTitle% to be published on %PublishingDate%.', 'wp-security-audit-log' ),
|
594 |
+
array(
|
595 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
596 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
597 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
598 |
+
),
|
599 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
600 |
'post',
|
601 |
+
'modified',
|
602 |
),
|
603 |
array(
|
604 |
2086,
|
605 |
WSAL_INFORMATIONAL,
|
606 |
+
esc_html__( 'User changed title of a post', 'wp-security-audit-log' ),
|
607 |
+
esc_html__( 'Changed the title of the post %OldTitle% to %NewTitle%.', 'wp-security-audit-log' ),
|
608 |
+
array(
|
609 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
610 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
611 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
612 |
+
),
|
613 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
614 |
'post',
|
615 |
+
'modified',
|
616 |
),
|
617 |
array(
|
618 |
2100,
|
619 |
WSAL_INFORMATIONAL,
|
620 |
+
esc_html__( 'User opened a post in the editor', 'wp-security-audit-log' ),
|
621 |
+
esc_html__( 'Opened the post %PostTitle% in the editor.', 'wp-security-audit-log' ),
|
622 |
+
array(
|
623 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
624 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
625 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
626 |
+
),
|
627 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
628 |
'post',
|
629 |
+
'opened',
|
630 |
),
|
631 |
array(
|
632 |
2101,
|
633 |
WSAL_INFORMATIONAL,
|
634 |
+
esc_html__( 'User viewed a post', 'wp-security-audit-log' ),
|
635 |
+
esc_html__( 'Viewed the post %PostTitle%.', 'wp-security-audit-log' ),
|
636 |
+
array(
|
637 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
638 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
639 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
640 |
+
),
|
641 |
+
wsaldefaults_build_links( array( 'PostUrl', 'EditorLinkPost' ) ),
|
642 |
'post',
|
643 |
+
'viewed',
|
644 |
),
|
645 |
array(
|
646 |
2111,
|
647 |
WSAL_LOW,
|
648 |
+
esc_html__( 'User enabled/disabled comments in a post', 'wp-security-audit-log' ),
|
649 |
+
esc_html__( 'Comments in the post %PostTitle%.', 'wp-security-audit-log' ),
|
650 |
+
array(
|
651 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
652 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
653 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
654 |
+
),
|
655 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
656 |
'post',
|
657 |
+
'enabled',
|
658 |
),
|
659 |
array(
|
660 |
2112,
|
661 |
WSAL_LOW,
|
662 |
+
esc_html__( 'User enabled/disabled trackbacks and pingbacks in a post', 'wp-security-audit-log' ),
|
663 |
+
esc_html__( 'Pingbacks and Trackbacks in the post %PostTitle%.', 'wp-security-audit-log' ),
|
664 |
+
array(
|
665 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
666 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
667 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
668 |
+
),
|
669 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
670 |
'post',
|
671 |
+
'enabled',
|
672 |
),
|
673 |
array(
|
674 |
2129,
|
675 |
WSAL_INFORMATIONAL,
|
676 |
+
esc_html__( 'User updated the excerpt in a post', 'wp-security-audit-log' ),
|
677 |
+
esc_html__( 'The excerpt of the post %PostTitle%.', 'wp-security-audit-log' ),
|
678 |
+
array(
|
679 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
680 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
681 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
682 |
+
esc_html__( 'Previous excerpt entry', 'wp-security-audit-log' ) => '%old_post_excerpt%',
|
683 |
+
esc_html__( 'New excerpt entry', 'wp-security-audit-log' ) => '%post_excerpt%',
|
684 |
+
),
|
685 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
686 |
'post',
|
687 |
+
'modified',
|
688 |
),
|
689 |
array(
|
690 |
2130,
|
691 |
WSAL_INFORMATIONAL,
|
692 |
+
esc_html__( 'User updated the featured image in a post', 'wp-security-audit-log' ),
|
693 |
+
esc_html__( 'The featured image of the post %PostTitle%.', 'wp-security-audit-log' ),
|
694 |
+
array(
|
695 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
696 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
697 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
698 |
+
esc_html__( 'Previous image', 'wp-security-audit-log' ) => '%previous_image%',
|
699 |
+
esc_html__( 'New image', 'wp-security-audit-log' ) => '%new_image%',
|
700 |
+
),
|
701 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
702 |
'post',
|
703 |
+
'modified',
|
704 |
),
|
705 |
),
|
706 |
|
707 |
+
esc_html__( 'Tags', 'wp-security-audit-log' ) => array(
|
708 |
array(
|
709 |
2119,
|
710 |
WSAL_INFORMATIONAL,
|
711 |
+
esc_html__( 'User added post tag', 'wp-security-audit-log' ),
|
712 |
+
esc_html__( 'Added tag(s) to the post %PostTitle%.', 'wp-security-audit-log' ),
|
713 |
+
array(
|
714 |
+
esc_html__( 'ID', 'wp-security-audit-log' ) => '%PostID%',
|
715 |
+
esc_html__( 'Type', 'wp-security-audit-log' ) => '%PostType%',
|
716 |
+
esc_html__( 'Status', 'wp-security-audit-log' ) => '%PostStatus%',
|
717 |
+
esc_html__( 'Added tag(s)', 'wp-security-audit-log' ) => '%tag%',
|
718 |
+
),
|
719 |
+
wsaldefaults_build_links( array( 'EditorLinkPost' ) ),
|
720 |
'post',
|
721 |
+
'modified',
|
722 |
),
|
723 |
array(
|
724 |
2120,
|
725 |
WSAL_INFORMATIONAL,
|
726 |
+
esc_html__( 'User removed post tag', 'wp-security-audit-log' ),
|
727 |
+
esc_html__( 'Removed tag(s) from the post %PostTitle%.', 'wp-security-audit-log' ),
|
728 |
+
array(
|
729 |
+
esc_html__( 'ID', 'wp-security-audit-log' ) => '%PostID%',
|
730 |
+
esc_html__( 'Type', 'wp-security-audit-log' ) => '%PostType%',
|
731 |
+
esc_html__( 'Status', 'wp-security-audit-log' ) => '%PostStatus%',
|
732 |
+
esc_html__( 'Removed tag(s)', 'wp-security-audit-log' ) => '%tag%',
|
733 |
+
),
|
734 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
735 |
'post',
|
736 |
+
'modified',
|
737 |
),
|
738 |
array(
|
739 |
2121,
|
740 |
WSAL_INFORMATIONAL,
|
741 |
+
esc_html__( 'User created new tag', 'wp-security-audit-log' ),
|
742 |
+
esc_html__( 'Created the tag %TagName%.', 'wp-security-audit-log' ),
|
743 |
+
array(
|
744 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => 'Slug',
|
745 |
+
),
|
746 |
+
wsaldefaults_build_links( array( 'TagLink' ) ),
|
747 |
'tag',
|
748 |
+
'created',
|
749 |
),
|
750 |
array(
|
751 |
2122,
|
752 |
WSAL_LOW,
|
753 |
+
esc_html__( 'User deleted tag', 'wp-security-audit-log' ),
|
754 |
+
esc_html__( 'Deleted the tag %TagName%.', 'wp-security-audit-log' ),
|
755 |
+
array(
|
756 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => 'Slug',
|
757 |
+
),
|
758 |
+
array(),
|
759 |
'tag',
|
760 |
+
'deleted',
|
761 |
),
|
762 |
array(
|
763 |
2123,
|
764 |
WSAL_INFORMATIONAL,
|
765 |
+
esc_html__( 'Renamed the tag %old_name% to %new_name%.', 'wp-security-audit-log' ),
|
766 |
'',
|
767 |
+
array(
|
768 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => '%Slug%',
|
769 |
+
),
|
770 |
+
wsaldefaults_build_links( array( 'TagLink' ) ),
|
771 |
'tag',
|
772 |
+
'renamed',
|
773 |
),
|
774 |
array(
|
775 |
2124,
|
776 |
WSAL_INFORMATIONAL,
|
777 |
+
esc_html__( 'User changed tag slug', 'wp-security-audit-log' ),
|
778 |
+
esc_html__( 'Changed the slug of the tag %tag% to %new_slug%.', 'wp-security-audit-log' ),
|
779 |
+
array(
|
780 |
+
esc_html__( 'Previous slug', 'wp-security-audit-log' ) => '%old_slug%',
|
781 |
+
),
|
782 |
+
wsaldefaults_build_links( array( 'TagLink' ) ),
|
783 |
'tag',
|
784 |
+
'modified',
|
785 |
),
|
786 |
array(
|
787 |
2125,
|
788 |
WSAL_INFORMATIONAL,
|
789 |
+
esc_html__( 'User changed tag description', 'wp-security-audit-log' ),
|
790 |
+
esc_html__( 'Changed the description of the tag %tag%.', 'wp-security-audit-log' ),
|
791 |
+
array(
|
792 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => '%Slug%',
|
793 |
+
esc_html__( 'Previous description', 'wp-security-audit-log' ) => '%old_desc%',
|
794 |
+
esc_html__( 'New description', 'wp-security-audit-log' ) => '%new_desc%',
|
795 |
+
),
|
796 |
+
wsaldefaults_build_links( array( 'TagLink' ) ),
|
797 |
'tag',
|
798 |
+
'modified',
|
799 |
),
|
800 |
),
|
801 |
|
802 |
+
esc_html__( 'Categories', 'wp-security-audit-log' ) => array(
|
803 |
array(
|
804 |
2016,
|
805 |
WSAL_LOW,
|
806 |
+
esc_html__( 'User changed post category', 'wp-security-audit-log' ),
|
807 |
+
esc_html__( 'Changed the category(ies) of the post %PostTitle% to %NewCategories%.', 'wp-security-audit-log' ),
|
808 |
+
array(
|
809 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
810 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
811 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
812 |
+
esc_html__( 'Previous category(ies)', 'wp-security-audit-log' ) => '%OldCategories%',
|
813 |
+
),
|
814 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
815 |
'post',
|
816 |
+
'modified',
|
817 |
),
|
818 |
array(
|
819 |
2023,
|
820 |
WSAL_MEDIUM,
|
821 |
+
esc_html__( 'User created new category', 'wp-security-audit-log' ),
|
822 |
+
esc_html__( 'Created the category %CategoryName%.', 'wp-security-audit-log' ),
|
823 |
+
array(
|
824 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => 'Slug',
|
825 |
+
),
|
826 |
+
wsaldefaults_build_links( array( 'CategoryLink' ) ),
|
827 |
'category',
|
828 |
+
'created',
|
829 |
),
|
830 |
array(
|
831 |
2024,
|
832 |
WSAL_MEDIUM,
|
833 |
+
esc_html__( 'User deleted category', 'wp-security-audit-log' ),
|
834 |
+
esc_html__( 'Deleted the category %CategoryName%.', 'wp-security-audit-log' ),
|
835 |
+
array(
|
836 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => 'Slug',
|
837 |
+
),
|
838 |
+
array(),
|
839 |
'category',
|
840 |
+
'deleted',
|
841 |
),
|
842 |
array(
|
843 |
2052,
|
844 |
WSAL_LOW,
|
845 |
+
esc_html__( 'Changed the parent of a category', 'wp-security-audit-log' ),
|
846 |
+
esc_html__( 'Changed the parent of the category %CategoryName% to %NewParent%.', 'wp-security-audit-log' ),
|
847 |
+
array(
|
848 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => '%Slug%',
|
849 |
+
esc_html__( 'Previous parent', 'wp-security-audit-log' ) => '%OldParent%',
|
850 |
+
),
|
851 |
+
wsaldefaults_build_links( array( 'CategoryLink' ) ),
|
852 |
'category',
|
853 |
+
'modified',
|
854 |
),
|
855 |
array(
|
856 |
2127,
|
857 |
WSAL_LOW,
|
858 |
+
esc_html__( 'User changed category name', 'wp-security-audit-log' ),
|
859 |
+
esc_html__( 'Renamed the category %old_name% to %new_name%.', 'wp-security-audit-log' ),
|
860 |
+
array(
|
861 |
+
esc_html__( 'Slug', 'wp-security-audit-log' ) => '%slug%',
|
862 |
+
),
|
863 |
+
wsaldefaults_build_links( array( 'cat_link' ) ),
|
864 |
'category',
|
865 |
+
'renamed',
|
866 |
),
|
867 |
array(
|
868 |
2128,
|
869 |
WSAL_LOW,
|
870 |
+
esc_html__( 'User changed category slug', 'wp-security-audit-log' ),
|
871 |
+
esc_html__( 'Changed the slug of the category %CategoryName% to %new_slug%.', 'wp-security-audit-log' ),
|
872 |
+
array(
|
873 |
+
esc_html__( 'Previous slug', 'wp-security-audit-log' ) => '%old_slug%',
|
874 |
+
),
|
875 |
+
wsaldefaults_build_links( array( 'cat_link' ) ),
|
876 |
'category',
|
877 |
+
'modified',
|
878 |
),
|
879 |
),
|
880 |
|
881 |
+
esc_html__( 'Custom Fields', 'wp-security-audit-log' ) => array(
|
882 |
array(
|
883 |
2053,
|
884 |
WSAL_LOW,
|
885 |
+
esc_html__( 'User created a custom field for a post', 'wp-security-audit-log' ),
|
886 |
+
esc_html__( 'Created the new custom field %MetaKey% in the post %PostTitle%.', 'wp-security-audit-log' ),
|
887 |
+
array(
|
888 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
889 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
890 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
891 |
+
esc_html__( 'Custom field value', 'wp-security-audit-log' ) => '%MetaValue%',
|
892 |
+
),
|
893 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'MetaLink', 'PostUrlIfPublished' ) ),
|
894 |
'post',
|
895 |
+
'modified',
|
896 |
),
|
897 |
array(
|
898 |
2054,
|
899 |
WSAL_LOW,
|
900 |
+
esc_html__( 'User updated a custom field value for a post', 'wp-security-audit-log' ),
|
901 |
+
esc_html__( 'Modified the value of the custom field %MetaKey% in the post %PostTitle%.', 'wp-security-audit-log' ),
|
902 |
+
array(
|
903 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
904 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
905 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
906 |
+
esc_html__( 'Previous custom field value', 'wp-security-audit-log' ) => '%MetaValueOld%',
|
907 |
+
esc_html__( 'New custom field value', 'wp-security-audit-log' ) => '%MetaValueNew%',
|
908 |
+
),
|
909 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'MetaLink', 'PostUrlIfPublished' ) ),
|
910 |
'custom-field',
|
911 |
+
'modified',
|
912 |
),
|
913 |
array(
|
914 |
2055,
|
915 |
WSAL_MEDIUM,
|
916 |
+
esc_html__( 'User deleted a custom field from a post', 'wp-security-audit-log' ),
|
917 |
+
esc_html__( 'Deleted the custom field %MetaKey% from the post %PostTitle%.', 'wp-security-audit-log' ),
|
918 |
+
array(
|
919 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
920 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
921 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
922 |
+
),
|
923 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
924 |
'custom-field',
|
925 |
+
'deleted',
|
926 |
),
|
927 |
array(
|
928 |
2062,
|
929 |
WSAL_LOW,
|
930 |
+
esc_html__( 'User updated a custom field name for a post', 'wp-security-audit-log' ),
|
931 |
+
esc_html__( 'Renamed the custom field %MetaKeyOld% on post %PostTitle% to %MetaKeNew%.', 'wp-security-audit-log' ),
|
932 |
+
array(
|
933 |
+
esc_html__( 'Post', 'wp-security-audit-log' ) => '%PostTitle%',
|
934 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
935 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
936 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
937 |
+
),
|
938 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'PostUrlIfPublished' ) ),
|
939 |
'custom-field',
|
940 |
+
'renamed',
|
941 |
),
|
942 |
),
|
943 |
|
944 |
+
esc_html__( 'Custom Fields (ACF)', 'wp-security-audit-log' ) => array(
|
945 |
array(
|
946 |
2131,
|
947 |
WSAL_LOW,
|
948 |
+
esc_html__( 'User added relationship to a custom field value for a post', 'wp-security-audit-log' ),
|
949 |
+
esc_html__( 'Added relationships to the custom field %MetaKey% in the post %PostTitle%.', 'wp-security-audit-log' ),
|
950 |
+
array(
|
951 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
952 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
953 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
954 |
+
esc_html__( 'New relationships', 'wp-security-audit-log' ) => '%Relationships%',
|
955 |
+
),
|
956 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'MetaLink' ) ),
|
957 |
'custom-field',
|
958 |
+
'modified',
|
959 |
),
|
960 |
array(
|
961 |
2132,
|
962 |
WSAL_LOW,
|
963 |
+
esc_html__( 'User removed relationship from a custom field value for a post', 'wp-security-audit-log' ),
|
964 |
+
esc_html__( 'Removed relationships from the custom field %MetaKey% in the post %PostTitle%.', 'wp-security-audit-log' ),
|
965 |
+
array(
|
966 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
967 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
968 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
969 |
+
esc_html__( 'Removed relationships', 'wp-security-audit-log' ) => '%Relationships%',
|
970 |
+
),
|
971 |
+
wsaldefaults_build_links( array( 'EditorLinkPost', 'MetaLink' ) ),
|
972 |
'custom-field',
|
973 |
+
'modified',
|
974 |
),
|
975 |
),
|
976 |
|
977 |
/**
|
978 |
* Alerts: Comments
|
979 |
*/
|
980 |
+
esc_html__( 'Comments', 'wp-security-audit-log' ) => array(
|
981 |
array(
|
982 |
2090,
|
983 |
WSAL_INFORMATIONAL,
|
984 |
+
esc_html__( 'User approved a comment', 'wp-security-audit-log' ),
|
985 |
+
esc_html__( 'Approved the comment posted by %Author% on the post %PostTitle%.', 'wp-security-audit-log' ),
|
986 |
+
array(
|
987 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
988 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
989 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
990 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
991 |
+
),
|
992 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
993 |
'comment',
|
994 |
+
'approved',
|
995 |
),
|
996 |
array(
|
997 |
2091,
|
998 |
WSAL_INFORMATIONAL,
|
999 |
+
esc_html__( 'User unapproved a comment', 'wp-security-audit-log' ),
|
1000 |
+
esc_html__( 'Unapproved the comment posted by %Author% on the post %PostTitle%.', 'wp-security-audit-log' ),
|
1001 |
+
array(
|
1002 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1003 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1004 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1005 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1006 |
+
),
|
1007 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1008 |
'comment',
|
1009 |
+
'unapproved',
|
1010 |
),
|
1011 |
array(
|
1012 |
2092,
|
1013 |
WSAL_INFORMATIONAL,
|
1014 |
+
esc_html__( 'User replied to a comment', 'wp-security-audit-log' ),
|
1015 |
+
esc_html__( 'Replied to the comment posted by %Author% on the post %PostTitle%.', 'wp-security-audit-log' ),
|
1016 |
+
array(
|
1017 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1018 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1019 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1020 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1021 |
+
),
|
1022 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1023 |
'comment',
|
1024 |
+
'created',
|
1025 |
),
|
1026 |
array(
|
1027 |
2093,
|
1028 |
WSAL_LOW,
|
1029 |
+
esc_html__( 'User edited a comment', 'wp-security-audit-log' ),
|
1030 |
+
esc_html__( 'Edited the comment posted by %Author% on the post %PostTitle%.', 'wp-security-audit-log' ),
|
1031 |
+
array(
|
1032 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1033 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1034 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1035 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1036 |
+
),
|
1037 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1038 |
'comment',
|
1039 |
+
'modified',
|
1040 |
),
|
1041 |
array(
|
1042 |
2094,
|
1043 |
WSAL_INFORMATIONAL,
|
1044 |
+
esc_html__( 'User marked a comment as Spam', 'wp-security-audit-log' ),
|
1045 |
+
esc_html__( 'Marked the comment posted by %Author% on the post %PostTitle% as spam.', 'wp-security-audit-log' ),
|
1046 |
+
array(
|
1047 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1048 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1049 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1050 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1051 |
+
),
|
1052 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1053 |
'comment',
|
1054 |
+
'unapproved',
|
1055 |
),
|
1056 |
array(
|
1057 |
2095,
|
1058 |
WSAL_LOW,
|
1059 |
+
esc_html__( 'User marked a comment as Not Spam', 'wp-security-audit-log' ),
|
1060 |
+
esc_html__( 'Marked the comment posted by %Author% on the post %PostTitle% as not spam.', 'wp-security-audit-log' ),
|
1061 |
+
array(
|
1062 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1063 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1064 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1065 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1066 |
+
),
|
1067 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1068 |
'comment',
|
1069 |
+
'approved',
|
1070 |
),
|
1071 |
array(
|
1072 |
2096,
|
1073 |
WSAL_LOW,
|
1074 |
+
esc_html__( 'User moved a comment to trash', 'wp-security-audit-log' ),
|
1075 |
+
esc_html__( 'Moved the comment posted by %Author% on the post %PostTitle% to trash.', 'wp-security-audit-log' ),
|
1076 |
+
array(
|
1077 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1078 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1079 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1080 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1081 |
+
),
|
1082 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1083 |
'comment',
|
1084 |
+
'deleted',
|
1085 |
),
|
1086 |
array(
|
1087 |
2097,
|
1088 |
WSAL_INFORMATIONAL,
|
1089 |
+
esc_html__( 'User restored a comment from the trash', 'wp-security-audit-log' ),
|
1090 |
+
esc_html__( 'Restored the comment posted by %Author% on the post %PostTitle% from trash.', 'wp-security-audit-log' ),
|
1091 |
+
array(
|
1092 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1093 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1094 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1095 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1096 |
+
),
|
1097 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1098 |
'comment',
|
1099 |
+
'restored',
|
1100 |
),
|
1101 |
array(
|
1102 |
2098,
|
1103 |
WSAL_LOW,
|
1104 |
+
esc_html__( 'User permanently deleted a comment', 'wp-security-audit-log' ),
|
1105 |
+
esc_html__( 'Permanently deleted the comment posted by %Author% on the post %PostTitle%.', 'wp-security-audit-log' ),
|
1106 |
+
array(
|
1107 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1108 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1109 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1110 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1111 |
+
),
|
1112 |
+
wsaldefaults_build_links( array( 'PostUrlIfPublished' ) ),
|
1113 |
'comment',
|
1114 |
+
'deleted',
|
1115 |
),
|
1116 |
array(
|
1117 |
2099,
|
1118 |
WSAL_INFORMATIONAL,
|
1119 |
+
esc_html__( 'User posted a comment', 'wp-security-audit-log' ),
|
1120 |
+
esc_html__( 'Posted a comment on the post %PostTitle%.', 'wp-security-audit-log' ),
|
1121 |
+
array(
|
1122 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1123 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1124 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1125 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1126 |
+
),
|
1127 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1128 |
'comment',
|
1129 |
+
'created',
|
1130 |
),
|
1131 |
/**
|
1132 |
* IMPORTANT: This alert is deprecated but should not be
|
1135 |
array(
|
1136 |
2126,
|
1137 |
WSAL_INFORMATIONAL,
|
1138 |
+
esc_html__( 'Visitor posted a comment', 'wp-security-audit-log' ),
|
1139 |
+
esc_html__( 'Posted a comment on the post %PostTitle%.', 'wp-security-audit-log' ),
|
1140 |
+
array(
|
1141 |
+
esc_html__( 'Post ID', 'wp-security-audit-log' ) => '%PostID%',
|
1142 |
+
esc_html__( 'Post type', 'wp-security-audit-log' ) => '%PostType%',
|
1143 |
+
esc_html__( 'Post status', 'wp-security-audit-log' ) => '%PostStatus%',
|
1144 |
+
esc_html__( 'Comment ID', 'wp-security-audit-log' ) => '%CommentID%',
|
1145 |
+
),
|
1146 |
+
wsaldefaults_build_links( array( 'CommentLink', 'PostUrlIfPublished' ) ),
|
1147 |
'comment',
|
1148 |
+
'created',
|
1149 |
),
|
1150 |
),
|
1151 |
|
1152 |
/**
|
1153 |
* Alerts: Widgets
|
1154 |
*/
|
1155 |
+
esc_html__( 'Widgets', 'wp-security-audit-log' ) => array(
|
1156 |
array(
|
1157 |
2042,
|
1158 |
WSAL_MEDIUM,
|
1159 |
+
esc_html__( 'User added a new widget', 'wp-security-audit-log' ),
|
1160 |
+
esc_html__( 'Added a new %WidgetName% widget in %Sidebar%.', 'wp-security-audit-log' ),
|
1161 |
+
array(),
|
1162 |
+
array(),
|
1163 |
'widget',
|
1164 |
+
'added',
|
1165 |
),
|
1166 |
array(
|
1167 |
2043,
|
1168 |
WSAL_HIGH,
|
1169 |
+
esc_html__( 'User modified a widget', 'wp-security-audit-log' ),
|
1170 |
+
esc_html__( 'Modified the %WidgetName% widget in %Sidebar%.', 'wp-security-audit-log' ),
|
1171 |
+
array(),
|
1172 |
+
array(),
|
1173 |
'widget',
|
1174 |
+
'modified',
|
1175 |
),
|
1176 |
array(
|
1177 |
2044,
|
1178 |
WSAL_MEDIUM,
|
1179 |
+
esc_html__( 'User deleted widget', 'wp-security-audit-log' ),
|
1180 |
+
esc_html__( 'Deleted the %WidgetName% widget from %Sidebar%.', 'wp-security-audit-log' ),
|
1181 |
+
array(),
|
1182 |
+
array(),
|
1183 |
'widget',
|
1184 |
+
'deleted',
|
1185 |
),
|
1186 |
array(
|
1187 |
2045,
|
1188 |
WSAL_LOW,
|
1189 |
+
esc_html__( 'User moved widget', 'wp-security-audit-log' ),
|
1190 |
+
esc_html__( 'Moved the %WidgetName% widget.', 'wp-security-audit-log' ),
|
1191 |
+
array(
|
1192 |
+
esc_html__( 'From', 'wp-security-audit-log' ) => '%OldSidebar%',
|
1193 |
+
esc_html__( 'To', 'wp-security-audit-log' ) => '%NewSidebar%',
|
1194 |
+
),
|
1195 |
+
array(),
|
1196 |
'widget',
|
1197 |
+
'modified',
|
1198 |
),
|
1199 |
array(
|
1200 |
2071,
|
1201 |
WSAL_LOW,
|
1202 |
+
esc_html__( 'User changed widget position', 'wp-security-audit-log' ),
|
1203 |
+
esc_html__( 'Changed the position of the %WidgetName% widget in %Sidebar%.', 'wp-security-audit-log' ),
|
1204 |
+
array(),
|
1205 |
+
array(),
|
1206 |
'widget',
|
1207 |
+
'modified',
|
1208 |
),
|
1209 |
),
|
1210 |
|
1211 |
/**
|
1212 |
* Alerts: Menus
|
1213 |
*/
|
1214 |
+
esc_html__( 'Menus', 'wp-security-audit-log' ) => array(
|
1215 |
array(
|
1216 |
2078,
|
1217 |
WSAL_LOW,
|
1218 |
+
esc_html__( 'User created new menu', 'wp-security-audit-log' ),
|
1219 |
+
esc_html__( 'New menu called %MenuName%.', 'wp-security-audit-log' ),
|
1220 |
+
array(),
|
1221 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1222 |
'menu',
|
1223 |
+
'created',
|
1224 |
),
|
1225 |
array(
|
1226 |
2079,
|
1227 |
WSAL_LOW,
|
1228 |
+
esc_html__( 'User added content to a menu', 'wp-security-audit-log' ),
|
1229 |
+
esc_html__( 'Added the item %ContentName% to the menu %MenuName%.', 'wp-security-audit-log' ),
|
1230 |
+
array(
|
1231 |
+
esc_html__( 'Item type', 'wp-security-audit-log' ) => '%ContentType%',
|
1232 |
+
),
|
1233 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1234 |
'menu',
|
1235 |
+
'modified',
|
1236 |
),
|
1237 |
array(
|
1238 |
2080,
|
1239 |
WSAL_LOW,
|
1240 |
+
esc_html__( 'User removed content from a menu', 'wp-security-audit-log' ),
|
1241 |
+
esc_html__( 'Removed the item %ContentName% from the menu %MenuName%.', 'wp-security-audit-log' ),
|
1242 |
+
array(
|
1243 |
+
esc_html__( 'Item type', 'wp-security-audit-log' ) => '%ContentType%',
|
1244 |
+
),
|
1245 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1246 |
'menu',
|
1247 |
+
'modified',
|
1248 |
),
|
1249 |
array(
|
1250 |
2081,
|
1251 |
WSAL_MEDIUM,
|
1252 |
+
esc_html__( 'User deleted menu', 'wp-security-audit-log' ),
|
1253 |
+
esc_html__( 'Deleted the menu %MenuName%.', 'wp-security-audit-log' ),
|
1254 |
+
array(),
|
1255 |
+
array(),
|
1256 |
'menu',
|
1257 |
+
'deleted',
|
1258 |
),
|
1259 |
array(
|
1260 |
2082,
|
1261 |
WSAL_LOW,
|
1262 |
+
esc_html__( 'User changed menu setting', 'wp-security-audit-log' ),
|
1263 |
+
esc_html__( 'The setting %MenuSetting% in the menu %MenuName%.', 'wp-security-audit-log' ),
|
1264 |
+
array(),
|
1265 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1266 |
'menu',
|
1267 |
+
'enabled',
|
1268 |
),
|
1269 |
array(
|
1270 |
2083,
|
1271 |
WSAL_LOW,
|
1272 |
+
esc_html__( 'User modified content in a menu', 'wp-security-audit-log' ),
|
1273 |
+
esc_html__( 'Modified the item %ContentName% in the menu %MenuName%.', 'wp-security-audit-log' ),
|
1274 |
+
array(
|
1275 |
+
esc_html__( 'Item type', 'wp-security-audit-log' ) => '%ContentType%',
|
1276 |
+
),
|
1277 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1278 |
'menu',
|
1279 |
+
'modified',
|
1280 |
),
|
1281 |
array(
|
1282 |
2084,
|
1283 |
WSAL_LOW,
|
1284 |
+
esc_html__( 'User changed name of a menu', 'wp-security-audit-log' ),
|
1285 |
+
esc_html__( 'Renamed the menu %OldMenuName% to %MenuName%.', 'wp-security-audit-log' ),
|
1286 |
+
array(),
|
1287 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1288 |
'menu',
|
1289 |
+
'renamed',
|
1290 |
),
|
1291 |
array(
|
1292 |
2085,
|
1293 |
WSAL_LOW,
|
1294 |
+
esc_html__( 'User changed order of the objects in a menu', 'wp-security-audit-log' ),
|
1295 |
+
esc_html__( 'Changed the order of the items in the menu %MenuName%.', 'wp-security-audit-log' ),
|
1296 |
+
array(),
|
1297 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1298 |
'menu',
|
1299 |
+
'modified',
|
1300 |
),
|
1301 |
array(
|
1302 |
2089,
|
1303 |
WSAL_LOW,
|
1304 |
+
esc_html__( 'User moved objects as a sub-item', 'wp-security-audit-log' ),
|
1305 |
+
esc_html__( 'Moved items as sub-items in the menu %MenuName%.', 'wp-security-audit-log' ),
|
1306 |
+
array(
|
1307 |
+
esc_html__( 'Moved item', 'wp-security-audit-log' ) => '%ItemName%',
|
1308 |
+
esc_html__( 'as a sub-item of', 'wp-security-audit-log' ) => '%ParentName%',
|
1309 |
+
),
|
1310 |
+
wsaldefaults_build_links( array( 'MenuUrl' ) ),
|
1311 |
'menu',
|
1312 |
+
'modified',
|
1313 |
),
|
1314 |
),
|
1315 |
|
1321 |
*
|
1322 |
* @deprecated 3.1.0
|
1323 |
*/
|
1324 |
+
esc_html__( 'Custom Post Types', 'wp-security-audit-log' ) => array(
|
1325 |
array(
|
1326 |
2003,
|
1327 |
E_NOTICE,
|
1328 |
+
esc_html__( 'User modified a draft blog post', 'wp-security-audit-log' ),
|
1329 |
+
esc_html__( 'Modified the draft post with the %PostTitle%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1330 |
),
|
1331 |
array(
|
1332 |
2029,
|
1333 |
E_NOTICE,
|
1334 |
+
esc_html__( 'User created a new post with custom post type and saved it as draft', 'wp-security-audit-log' ),
|
1335 |
+
esc_html__( 'Created a new custom post called %PostTitle% of type %PostType%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1336 |
),
|
1337 |
array(
|
1338 |
2030,
|
1339 |
E_NOTICE,
|
1340 |
+
esc_html__( 'User published a post with custom post type', 'wp-security-audit-log' ),
|
1341 |
+
esc_html__( 'Published a custom post %PostTitle% of type %PostType%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1342 |
),
|
1343 |
array(
|
1344 |
2031,
|
1345 |
E_NOTICE,
|
1346 |
+
esc_html__( 'User modified a post with custom post type', 'wp-security-audit-log' ),
|
1347 |
+
esc_html__( 'Modified the custom post %PostTitle% of type %PostType%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1348 |
),
|
1349 |
array(
|
1350 |
2032,
|
1351 |
E_NOTICE,
|
1352 |
+
esc_html__( 'User modified a draft post with custom post type', 'wp-security-audit-log' ),
|
1353 |
+
esc_html__( 'Modified the draft custom post %PostTitle% of type is %PostType%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1354 |
),
|
1355 |
array(
|
1356 |
2033,
|
1357 |
E_WARNING,
|
1358 |
+
esc_html__( 'User permanently deleted post with custom post type', 'wp-security-audit-log' ),
|
1359 |
+
esc_html__( 'Permanently Deleted the custom post %PostTitle% of type %PostType%.', 'wp-security-audit-log' ),
|
1360 |
),
|
1361 |
array(
|
1362 |
2034,
|
1363 |
E_WARNING,
|
1364 |
+
esc_html__( 'User moved post with custom post type to trash', 'wp-security-audit-log' ),
|
1365 |
+
esc_html__( 'Moved the custom post %PostTitle% of type %PostType% to trash. Post URL was %PostUrl%.', 'wp-security-audit-log' ),
|
1366 |
),
|
1367 |
array(
|
1368 |
2035,
|
1369 |
E_CRITICAL,
|
1370 |
+
esc_html__( 'User restored post with custom post type from trash', 'wp-security-audit-log' ),
|
1371 |
+
esc_html__( 'The custom post %PostTitle% of type %PostType% has been restored from trash. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1372 |
),
|
1373 |
array(
|
1374 |
2036,
|
1375 |
E_NOTICE,
|
1376 |
+
esc_html__( 'User changed the category of a post with custom post type', 'wp-security-audit-log' ),
|
1377 |
+
esc_html__( 'Changed the category(ies) of the custom post %PostTitle% of type %PostType% from %OldCategories% to %NewCategories%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1378 |
),
|
1379 |
array(
|
1380 |
2037,
|
1381 |
E_NOTICE,
|
1382 |
+
esc_html__( 'User changed the URL of a post with custom post type', 'wp-security-audit-log' ),
|
1383 |
+
esc_html__( 'Changed the URL of the custom post %PostTitle% of type %PostType% from %OldUrl% to %NewUrl%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1384 |
),
|
1385 |
array(
|
1386 |
2038,
|
1387 |
E_NOTICE,
|
1388 |
+
esc_html__( 'User changed the author or post with custom post type', 'wp-security-audit-log' ),
|
1389 |
+
esc_html__( 'Changed the author of custom post %PostTitle% of type %PostType% from %OldAuthor% to %NewAuthor%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1390 |
),
|
1391 |
array(
|
1392 |
2039,
|
1393 |
E_NOTICE,
|
1394 |
+
esc_html__( 'User changed the status of post with custom post type', 'wp-security-audit-log' ),
|
1395 |
+
esc_html__( 'Changed the status of custom post %PostTitle% of type %PostType% from %OldStatus% to %NewStatus%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1396 |
),
|
1397 |
array(
|
1398 |
2040,
|
1399 |
E_WARNING,
|
1400 |
+
esc_html__( 'User changed the visibility of a post with custom post type', 'wp-security-audit-log' ),
|
1401 |
+
esc_html__( 'Changed the visibility of the custom post %PostTitle% of type %PostType% from %OldVisibility% to %NewVisibility%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1402 |
),
|
1403 |
array(
|
1404 |
2041,
|
1405 |
E_NOTICE,
|
1406 |
+
esc_html__( 'User changed the date of post with custom post type', 'wp-security-audit-log' ),
|
1407 |
+
esc_html__( 'Changed the date of the custom post %PostTitle% of type %PostType% from %OldDate% to %NewDate%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1408 |
),
|
1409 |
array(
|
1410 |
2056,
|
1411 |
E_CRITICAL,
|
1412 |
+
esc_html__( 'User created a custom field for a custom post type', 'wp-security-audit-log' ),
|
1413 |
+
esc_html__( 'Created a new custom field %MetaKey% with value %MetaValue% in custom post %PostTitle% of type %PostType%. %EditorLinkPost%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1414 |
),
|
1415 |
array(
|
1416 |
2057,
|
1417 |
E_CRITICAL,
|
1418 |
+
esc_html__( 'User updated a custom field for a custom post type', 'wp-security-audit-log' ),
|
1419 |
+
esc_html__( 'Modified the value of the custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in custom post %PostTitle% of type %PostType% %EditorLinkPost%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1420 |
),
|
1421 |
array(
|
1422 |
2058,
|
1423 |
E_CRITICAL,
|
1424 |
+
esc_html__( 'User deleted a custom field from a custom post type', 'wp-security-audit-log' ),
|
1425 |
+
esc_html__( 'Deleted the custom field %MetaKey% with id %MetaID% from custom post %PostTitle% of type %PostType% %EditorLinkPost%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1426 |
),
|
1427 |
array(
|
1428 |
2063,
|
1429 |
E_CRITICAL,
|
1430 |
+
esc_html__( 'User updated a custom field name for a custom post type', 'wp-security-audit-log' ),
|
1431 |
+
esc_html__( 'Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in custom post %PostTitle% of type %PostType% %EditorLinkPost%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1432 |
),
|
1433 |
array(
|
1434 |
2067,
|
1435 |
E_WARNING,
|
1436 |
+
esc_html__( 'User modified content for a published custom post type', 'wp-security-audit-log' ),
|
1437 |
+
esc_html__( 'Modified the content of the published custom post type %PostTitle%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1438 |
),
|
1439 |
array(
|
1440 |
2068,
|
1441 |
E_NOTICE,
|
1442 |
+
esc_html__( 'User modified content for a draft post', 'wp-security-audit-log' ),
|
1443 |
+
esc_html__( 'Modified the content of the draft post %PostTitle%.%RevisionLink% %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1444 |
),
|
1445 |
array(
|
1446 |
2070,
|
1447 |
E_NOTICE,
|
1448 |
+
esc_html__( 'User modified content for a draft custom post type', 'wp-security-audit-log' ),
|
1449 |
+
esc_html__( 'Modified the content of the draft custom post type %PostTitle%.%EditorLinkPost%.', 'wp-security-audit-log' ),
|
1450 |
),
|
1451 |
array(
|
1452 |
2072,
|
1453 |
E_NOTICE,
|
1454 |
+
esc_html__( 'User modified content of a post', 'wp-security-audit-log' ),
|
1455 |
+
esc_html__( 'Modified the content of post %PostTitle% which is submitted for review.%RevisionLink% %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1456 |
),
|
1457 |
array(
|
1458 |
2076,
|
1459 |
E_NOTICE,
|
1460 |
+
esc_html__( 'User scheduled a custom post type', 'wp-security-audit-log' ),
|
1461 |
+
esc_html__( 'Scheduled the custom post type %PostTitle% to be published %PublishingDate%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1462 |
),
|
1463 |
array(
|
1464 |
2088,
|
1465 |
E_NOTICE,
|
1466 |
+
esc_html__( 'User changed title of a custom post type', 'wp-security-audit-log' ),
|
1467 |
+
esc_html__( 'Changed the title of the custom post %OldTitle% to %NewTitle%. %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1468 |
),
|
1469 |
array(
|
1470 |
2104,
|
1471 |
E_NOTICE,
|
1472 |
+
esc_html__( 'User opened a custom post type in the editor', 'wp-security-audit-log' ),
|
1473 |
+
esc_html__( 'Opened the custom post %PostTitle% of type %PostType% in the editor. View the post: %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1474 |
),
|
1475 |
array(
|
1476 |
2105,
|
1477 |
E_NOTICE,
|
1478 |
+
esc_html__( 'User viewed a custom post type', 'wp-security-audit-log' ),
|
1479 |
+
esc_html__( 'Viewed the custom post %PostTitle% of type %PostType%. View the post: %PostUrl%.', 'wp-security-audit-log' ),
|
1480 |
),
|
1481 |
array(
|
1482 |
5021,
|
1483 |
E_CRITICAL,
|
1484 |
+
esc_html__( 'A plugin created a custom post', 'wp-security-audit-log' ),
|
1485 |
+
esc_html__( 'A plugin automatically created the following custom post: %PostTitle%.', 'wp-security-audit-log' ),
|
1486 |
),
|
1487 |
array(
|
1488 |
5027,
|
1489 |
E_CRITICAL,
|
1490 |
+
esc_html__( 'A plugin deleted a custom post', 'wp-security-audit-log' ),
|
1491 |
+
esc_html__( 'A plugin automatically deleted the following custom post: %PostTitle%.', 'wp-security-audit-log' ),
|
1492 |
),
|
1493 |
array(
|
1494 |
2108,
|
1495 |
E_NOTICE,
|
1496 |
+
esc_html__( 'A plugin modified a custom post', 'wp-security-audit-log' ),
|
1497 |
+
esc_html__( 'Plugin modified the custom post %PostTitle%. View the post: %EditorLinkPost%.', 'wp-security-audit-log' ),
|
1498 |
),
|
1499 |
),
|
1500 |
|
1506 |
*
|
1507 |
* @deprecated 3.1.0
|
1508 |
*/
|
1509 |
+
esc_html__( 'Pages', 'wp-security-audit-log' ) => array(
|
1510 |
array(
|
1511 |
2004,
|
1512 |
E_NOTICE,
|
1513 |
+
esc_html__( 'User created a new WordPress page and saved it as draft', 'wp-security-audit-log' ),
|
1514 |
+
esc_html__( 'Created a new page called %PostTitle% and saved it as draft. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1515 |
),
|
1516 |
array(
|
1517 |
2005,
|
1518 |
E_NOTICE,
|
1519 |
+
esc_html__( 'User published a WordPress page', 'wp-security-audit-log' ),
|
1520 |
+
esc_html__( 'Published a page called %PostTitle%. Page URL is %PostUrl%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1521 |
),
|
1522 |
array(
|
1523 |
2006,
|
1524 |
E_NOTICE,
|
1525 |
+
esc_html__( 'User modified a published WordPress page', 'wp-security-audit-log' ),
|
1526 |
+
esc_html__( 'Modified the published page %PostTitle%. Page URL is %PostUrl%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1527 |
),
|
1528 |
array(
|
1529 |
2007,
|
1530 |
E_NOTICE,
|
1531 |
+
esc_html__( 'User modified a draft WordPress page', 'wp-security-audit-log' ),
|
1532 |
+
esc_html__( 'Modified the draft page %PostTitle%. Page ID is %PostID%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1533 |
),
|
1534 |
array(
|
1535 |
2009,
|
1536 |
E_WARNING,
|
1537 |
+
esc_html__( 'User permanently deleted a page from the trash', 'wp-security-audit-log' ),
|
1538 |
+
esc_html__( 'Permanently deleted the page %PostTitle%.', 'wp-security-audit-log' ),
|
1539 |
),
|
1540 |
array(
|
1541 |
2013,
|
1542 |
E_WARNING,
|
1543 |
+
esc_html__( 'User moved WordPress page to the trash', 'wp-security-audit-log' ),
|
1544 |
+
esc_html__( 'Moved the page %PostTitle% to trash. Page URL was %PostUrl%.', 'wp-security-audit-log' ),
|
1545 |
),
|
1546 |
array(
|
1547 |
2015,
|
1548 |
E_CRITICAL,
|
1549 |
+
esc_html__( 'User restored a WordPress page from trash', 'wp-security-audit-log' ),
|
1550 |
+
esc_html__( 'Page %PostTitle% has been restored from trash. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1551 |
),
|
1552 |
array(
|
1553 |
2018,
|
1554 |
E_NOTICE,
|
1555 |
+
esc_html__( 'User changed page URL', 'wp-security-audit-log' ),
|
1556 |
+
esc_html__( 'Changed the URL of the page %PostTitle% from %OldUrl% to %NewUrl%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1557 |
),
|
1558 |
array(
|
1559 |
2020,
|
1560 |
E_NOTICE,
|
1561 |
+
esc_html__( 'User changed page author', 'wp-security-audit-log' ),
|
1562 |
+
esc_html__( 'Changed the author of the page %PostTitle% from %OldAuthor% to %NewAuthor%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1563 |
),
|
1564 |
array(
|
1565 |
2022,
|
1566 |
E_NOTICE,
|
1567 |
+
esc_html__( 'User changed page status', 'wp-security-audit-log' ),
|
1568 |
+
esc_html__( 'Changed the status of the page %PostTitle% from %OldStatus% to %NewStatus%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1569 |
),
|
1570 |
array(
|
1571 |
2026,
|
1572 |
E_WARNING,
|
1573 |
+
esc_html__( 'User changed the visibility of a page post', 'wp-security-audit-log' ),
|
1574 |
+
esc_html__( 'Changed the visibility of the page %PostTitle% from %OldVisibility% to %NewVisibility%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1575 |
),
|
1576 |
array(
|
1577 |
2028,
|
1578 |
E_NOTICE,
|
1579 |
+
esc_html__( 'User changed the date of a page post', 'wp-security-audit-log' ),
|
1580 |
+
esc_html__( 'Changed the date of the page %PostTitle% from %OldDate% to %NewDate%. %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1581 |
),
|
1582 |
array(
|
1583 |
2059,
|
1584 |
E_CRITICAL,
|
1585 |
+
esc_html__( 'User created a custom field for a page', 'wp-security-audit-log' ),
|
1586 |
+
esc_html__( 'Created a new custom field called %MetaKey% with value %MetaValue% in the page %PostTitle% %EditorLinkPage%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1587 |
),
|
1588 |
array(
|
1589 |
2060,
|
1590 |
E_CRITICAL,
|
1591 |
+
esc_html__( 'User updated a custom field value for a page', 'wp-security-audit-log' ),
|
1592 |
+
esc_html__( 'Modified the value of the custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in the page %PostTitle% %EditorLinkPage%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1593 |
),
|
1594 |
array(
|
1595 |
2061,
|
1596 |
E_CRITICAL,
|
1597 |
+
esc_html__( 'User deleted a custom field from a page', 'wp-security-audit-log' ),
|
1598 |
+
esc_html__( 'Deleted the custom field %MetaKey% with id %MetaID% from page %PostTitle% %EditorLinkPage%<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1599 |
),
|
1600 |
array(
|
1601 |
2064,
|
1602 |
E_CRITICAL,
|
1603 |
+
esc_html__( 'User updated a custom field name for a page', 'wp-security-audit-log' ),
|
1604 |
+
esc_html__( 'Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in the page %PostTitle% %EditorLinkPage%.<br>%MetaLink%.', 'wp-security-audit-log' ),
|
1605 |
),
|
1606 |
array(
|
1607 |
2066,
|
1608 |
E_WARNING,
|
1609 |
+
esc_html__( 'User modified content for a published page', 'wp-security-audit-log' ),
|
1610 |
+
esc_html__( 'Modified the content of the published page %PostTitle%. Page URL is %PostUrl%. %RevisionLink% %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1611 |
),
|
1612 |
array(
|
1613 |
2069,
|
1614 |
E_NOTICE,
|
1615 |
+
esc_html__( 'User modified content for a draft page', 'wp-security-audit-log' ),
|
1616 |
+
esc_html__( 'Modified the content of draft page %PostTitle%.%RevisionLink% %EditorLinkPage%.', 'wp-security-audit-log' ),
|
1617 |
),
|
1618 |
array(
|
1619 |
2075,
|
1620 |
E_NOTICE,
|
1621 |
+
esc_html__( 'User scheduled a page', 'wp-security-audit-log'
|
|