Version Description
Download this release
Release Info
Developer | WPWhiteSecurity |
Plugin | WP Security Audit Log |
Version | 3.0.0 |
Comparing to | |
See all releases |
Code changes from version 2.6.9.1 to 3.0.0
- classes/AbstractLogger.php +30 -22
- classes/AbstractSandboxTask.php +98 -74
- classes/AbstractSensor.php +96 -63
- classes/AbstractView.php +240 -203
- classes/Adapters/ActiveRecordInterface.php +85 -13
- classes/Adapters/MetaInterface.php +30 -10
- classes/Adapters/MySQL/ActiveRecordAdapter.php +701 -669
- classes/Adapters/MySQL/MetaAdapter.php +130 -70
- classes/Adapters/MySQL/OccurrenceAdapter.php +307 -245
- classes/Adapters/MySQL/OptionAdapter.php +161 -108
- classes/Adapters/MySQL/QueryAdapter.php +259 -236
- classes/Adapters/MySQL/TmpUserAdapter.php +58 -32
- classes/Adapters/OccurrenceInterface.php +61 -9
- classes/Adapters/QueryInterface.php +36 -6
- classes/Alert.php +127 -113
- classes/AlertManager.php +165 -142
- classes/AuditLogListView.php +731 -568
- classes/Autoloader.php +87 -70
- classes/Connector/AbstractConnector.php +72 -35
- classes/Connector/ConnectorFactory.php +134 -102
- classes/Connector/ConnectorInterface.php +52 -10
- classes/Connector/MySQLDB.php +681 -666
- classes/Connector/wp-db-custom.php +51 -36
- classes/ConstantManager.php +98 -90
- classes/EDD_SL_Plugin_Updater.php +212 -164
- classes/Helpers/DataHelper.php +35 -22
- classes/LicenseManager.php +260 -188
- classes/Loggers/Database.php +217 -207
- classes/Models/ActiveRecord.php +382 -337
- classes/Models/Meta.php +92 -49
- classes/Models/Occurrence.php +287 -245
- classes/Models/OccurrenceQuery.php +52 -32
- classes/Models/Option.php +160 -121
- classes/Models/Query.php +334 -263
- classes/Models/TmpUser.php +36 -5
- classes/Nicer.php +300 -288
- classes/SensorManager.php +82 -69
- classes/Sensors/BBPress.php +615 -519
- classes/Sensors/Comments.php +200 -170
- classes/Sensors/Content.php +970 -647
- classes/Sensors/Database.php +193 -150
- classes/Sensors/Files.php +106 -76
- classes/Sensors/LogInOut.php +433 -370
- classes/Sensors/Menus.php +645 -514
- classes/Sensors/MetaData.php +271 -181
- classes/Sensors/Multisite.php +232 -183
- classes/Sensors/PhpErrors.php +166 -128
- classes/Sensors/PluginsThemes.php +424 -215
- classes/Sensors/Request.php +109 -68
- classes/Sensors/System.php +920 -724
- classes/Sensors/UserProfile.php +266 -184
- classes/Sensors/Widgets.php +289 -242
- classes/Sensors/WooCommerce.php +1346 -859
- classes/Settings.php +485 -463
- classes/SimpleProfiler.php +41 -47
- classes/ViewManager.php +309 -283
- classes/Views/About.php +0 -94
- classes/Views/AuditLog.php +178 -115
- classes/Views/EmailNotifications.php +167 -57
- classes/Views/Extensions.php +0 -137
- classes/Views/ExternalDB.php +166 -57
- classes/Views/Help.php +182 -79
- classes/Views/Licensing.php +155 -92
- classes/Views/LogInUsers.php +168 -56
- classes/Views/Reports.php +167 -56
- classes/Views/Search.php +160 -56
- classes/Views/Settings.php +240 -169
classes/AbstractLogger.php
CHANGED
@@ -1,29 +1,37 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* Abstract class used in the Logger.
|
|
|
6 |
* @see Loggers/Database.php
|
|
|
7 |
*/
|
8 |
-
abstract class WSAL_AbstractLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
* @param integer $siteid (Optional) site_id
|
26 |
-
* @param bool $migrated (Optional) is_migrated
|
27 |
-
*/
|
28 |
-
public abstract function Log($type, $data = array(), $date = null, $siteid = null, $migrated = false);
|
29 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* Abstract class used in the Logger.
|
4 |
+
*
|
5 |
* @see Loggers/Database.php
|
6 |
+
* @package Wsal
|
7 |
*/
|
8 |
+
abstract class WSAL_AbstractLogger {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Instance of WpSecurityAuditLog.
|
12 |
+
*
|
13 |
+
* @var object
|
14 |
+
*/
|
15 |
+
protected $plugin;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Method: Constructor.
|
19 |
+
*
|
20 |
+
* @param object $plugin - Instance of WpSecurityAuditLog.
|
21 |
+
* @since 1.0.0
|
22 |
+
*/
|
23 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
24 |
+
$this->plugin = $plugin;
|
25 |
+
}
|
26 |
|
27 |
+
/**
|
28 |
+
* Log alert abstract.
|
29 |
+
*
|
30 |
+
* @param integer $type - Alert code.
|
31 |
+
* @param array $data - Metadata.
|
32 |
+
* @param integer $date (Optional) - Created on.
|
33 |
+
* @param integer $siteid (Optional) - Site id.
|
34 |
+
* @param bool $migrated (Optional) - Is migrated.
|
35 |
+
*/
|
36 |
+
public abstract function Log( $type, $data = array(), $date = null, $siteid = null, $migrated = false );
|
|
|
|
|
|
|
|
|
37 |
}
|
classes/AbstractSandboxTask.php
CHANGED
@@ -1,79 +1,103 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* @package Wsal
|
4 |
*/
|
5 |
-
abstract class WSAL_AbstractSandboxTask
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Abstract Sandbox Task class.
|
4 |
+
*
|
5 |
* @package Wsal
|
6 |
*/
|
7 |
+
abstract class WSAL_AbstractSandboxTask {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Method: Constructor.
|
11 |
+
*
|
12 |
+
* @since 1.0.0
|
13 |
+
*/
|
14 |
+
public function __construct() {
|
15 |
+
// Remove time limit and clear output buffers.
|
16 |
+
set_time_limit( 0 );
|
17 |
+
ob_implicit_flush( true );
|
18 |
+
while ( ob_get_level() ) {
|
19 |
+
ob_end_flush();
|
20 |
+
}
|
21 |
+
|
22 |
+
// Set up shutdown handler.
|
23 |
+
register_shutdown_function( array( $this, 'Shutdown' ) );
|
24 |
+
|
25 |
+
// Run event sequence.
|
26 |
+
$this->Header();
|
27 |
+
try {
|
28 |
+
$this->Execute();
|
29 |
+
} catch ( Exception $ex ) {
|
30 |
+
$this->Message( get_class( $ex ) . ' [' . basename( $ex->getFile() ) . ':' . $ex->getLine() . ']: ' . $ex->getMessage() );
|
31 |
+
$this->Message( $ex->getTraceAsString(), true );
|
32 |
+
}
|
33 |
+
$this->Footer();
|
34 |
+
|
35 |
+
// Shutdown.
|
36 |
+
die();
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Header.
|
41 |
+
*/
|
42 |
+
protected function Header() {
|
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>';
|
46 |
+
echo ' <span id="msg"></span> <span id="prg"></span>';
|
47 |
+
echo '</div>';
|
48 |
+
echo '<div id="msgs" style="font-family: Consolas; margin-top: 30px; white-space: pre;"></div>';
|
49 |
+
echo '<script>';
|
50 |
+
echo ' var bar = document.getElementById("bar");';
|
51 |
+
echo ' var msg = document.getElementById("msg");';
|
52 |
+
echo ' var prg = document.getElementById("prg");';
|
53 |
+
echo ' var msgs = document.getElementById("msgs");';
|
54 |
+
echo '</script>';
|
55 |
+
flush();
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Footer.
|
60 |
+
*/
|
61 |
+
protected function Footer() {
|
62 |
+
echo '<div style="display: none;">';
|
63 |
+
flush();
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Method: Execute.
|
68 |
+
*/
|
69 |
+
protected abstract function Execute();
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Method: Shutdown.
|
73 |
+
*/
|
74 |
+
public function Shutdown() {
|
75 |
+
echo '</div></body></html>';
|
76 |
+
flush();
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Method: Show progress.
|
81 |
+
*
|
82 |
+
* @param mix $percent - Progress percentage.
|
83 |
+
*/
|
84 |
+
protected function Progress( $percent ) {
|
85 |
+
echo '<script>bar.style.width=prg.innerHTML="' . number_format( $percent, 2 ) . '%";</script>';
|
86 |
+
flush();
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Method: Message.
|
91 |
+
*
|
92 |
+
* @param string $message - Message.
|
93 |
+
* @param bool $sticky - True if sticky.
|
94 |
+
*/
|
95 |
+
protected function Message( $message, $sticky = false ) {
|
96 |
+
if ( $sticky ) {
|
97 |
+
echo '<script>msgs.appendChild(document.createTextNode(' . json_encode( $message . PHP_EOL ) . ')); window.scroll(0, document.body.scrollHeight);</script>';
|
98 |
+
} else {
|
99 |
+
echo '<script>msg.innerHTML=' . json_encode( $message ) . ';</script>';
|
100 |
+
}
|
101 |
+
flush();
|
102 |
+
}
|
103 |
}
|
classes/AbstractSensor.php
CHANGED
@@ -1,72 +1,105 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* Abstract class used in all the sensors.
|
|
|
6 |
* @see Sensors/*.php
|
|
|
7 |
*/
|
8 |
-
abstract class WSAL_AbstractSensor
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
protected function Log($type, $message, $args)
|
31 |
-
{
|
32 |
-
$this->plugin->alerts->Trigger($type, array(
|
33 |
-
'Message' => $message,
|
34 |
-
'Context' => $args,
|
35 |
-
'Trace' => debug_backtrace(),
|
36 |
-
));
|
37 |
-
}
|
38 |
-
|
39 |
-
protected function LogError($message, $args)
|
40 |
-
{
|
41 |
-
$this->Log(0001, $message, $args);
|
42 |
-
}
|
43 |
-
|
44 |
-
protected function LogWarn($message, $args)
|
45 |
-
{
|
46 |
-
$this->Log(0002, $message, $args);
|
47 |
-
}
|
48 |
-
|
49 |
-
protected function LogInfo($message, $args)
|
50 |
-
{
|
51 |
-
$this->Log(0003, $message, $args);
|
52 |
-
}
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* Abstract class used in all the sensors.
|
4 |
+
*
|
5 |
* @see Sensors/*.php
|
6 |
+
* @package Wsal
|
7 |
*/
|
8 |
+
abstract class WSAL_AbstractSensor {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Instance of WpSecurityAuditLog.
|
12 |
+
*
|
13 |
+
* @var object
|
14 |
+
*/
|
15 |
+
protected $plugin;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Method: Constructor.
|
19 |
+
*
|
20 |
+
* @param object $plugin - Instance of WpSecurityAuditLog.
|
21 |
+
*/
|
22 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
23 |
+
$this->plugin = $plugin;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Whether we are running on multisite or not.
|
28 |
+
*
|
29 |
+
* @return boolean
|
30 |
+
*/
|
31 |
+
protected function IsMultisite() {
|
32 |
+
return function_exists( 'is_multisite' ) && is_multisite();
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Method: Hook events related to sensor.
|
37 |
+
*/
|
38 |
+
abstract function HookEvents();
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Method: Log the message for sensor.
|
42 |
+
*
|
43 |
+
* @param int $type - Type of alert.
|
44 |
+
* @param string $message - Alert message.
|
45 |
+
* @param mix $args - Message arguments.
|
46 |
+
*/
|
47 |
+
protected function Log( $type, $message, $args ) {
|
48 |
+
$this->plugin->alerts->Trigger(
|
49 |
+
$type, array(
|
50 |
+
'Message' => $message,
|
51 |
+
'Context' => $args,
|
52 |
+
'Trace' => debug_backtrace(),
|
53 |
+
)
|
54 |
+
);
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Method: Log error message for sensor.
|
59 |
+
*
|
60 |
+
* @param string $message - Alert message.
|
61 |
+
* @param mix $args - Message arguments.
|
62 |
+
*/
|
63 |
+
protected function LogError( $message, $args ) {
|
64 |
+
$this->Log( 0001, $message, $args );
|
65 |
+
}
|
66 |
|
67 |
+
/**
|
68 |
+
* Method: Log warning message for sensor.
|
69 |
+
*
|
70 |
+
* @param string $message - Alert message.
|
71 |
+
* @param mix $args - Message arguments.
|
72 |
+
*/
|
73 |
+
protected function LogWarn( $message, $args ) {
|
74 |
+
$this->Log( 0002, $message, $args );
|
75 |
+
}
|
76 |
|
77 |
+
/**
|
78 |
+
* Method: Log info message for sensor.
|
79 |
+
*
|
80 |
+
* @param string $message - Alert message.
|
81 |
+
* @param mix $args - Message arguments.
|
82 |
+
*/
|
83 |
+
protected function LogInfo( $message, $args ) {
|
84 |
+
$this->Log( 0003, $message, $args );
|
85 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
+
/**
|
88 |
+
* Check to see whether or not the specified directory is accessible
|
89 |
+
*
|
90 |
+
* @param string $dir_path - Directory path.
|
91 |
+
* @return boolean
|
92 |
+
*/
|
93 |
+
protected function CheckDirectory( $dir_path ) {
|
94 |
+
if ( ! is_dir( $dir_path ) ) {
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
if ( ! is_readable( $dir_path ) ) {
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
if ( ! is_writable( $dir_path ) ) {
|
101 |
+
return false;
|
102 |
+
}
|
103 |
+
return true;
|
104 |
+
}
|
105 |
}
|
classes/AbstractView.php
CHANGED
@@ -1,209 +1,246 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* Abstract class used in all the views.
|
|
|
6 |
* @see Views/*.php
|
|
|
7 |
*/
|
8 |
-
abstract class WSAL_AbstractView
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* Abstract class used in all the views.
|
4 |
+
*
|
5 |
* @see Views/*.php
|
6 |
+
* @package Wsal
|
7 |
*/
|
8 |
+
abstract class WSAL_AbstractView {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Instance of WpSecurityAuditLog.
|
12 |
+
*
|
13 |
+
* @var object
|
14 |
+
*/
|
15 |
+
protected $_plugin;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* WordPress version.
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
protected $_wpversion;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Contains the result to a call to add_submenu_page().
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
public $hook_suffix = '';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Tells us whether this view is currently being displayed or not.
|
33 |
+
*
|
34 |
+
* @var boolean
|
35 |
+
*/
|
36 |
+
public $is_active = false;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Allowed notice names.
|
40 |
+
*
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
+
public static $AllowedNoticeNames = array();
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Constructor.
|
47 |
+
*
|
48 |
+
* @param object $plugin - Instance of WpSecurityAuditLog.
|
49 |
+
*/
|
50 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
51 |
+
$this->_plugin = $plugin;
|
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->_wpversion = floatval( $wp_version );
|
59 |
+
|
60 |
+
// Handle admin notices.
|
61 |
+
add_action( 'wp_ajax_AjaxDismissNotice', array( $this, 'AjaxDismissNotice' ) );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Dismiss an admin notice through ajax.
|
66 |
+
*
|
67 |
+
* @internal
|
68 |
+
*/
|
69 |
+
public function AjaxDismissNotice() {
|
70 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
71 |
+
die( 'Access Denied.' );
|
72 |
+
}
|
73 |
+
|
74 |
+
// Filter $_POST array for security.
|
75 |
+
$post_array = filter_input_array( INPUT_POST );
|
76 |
+
|
77 |
+
if ( ! isset( $post_array['notice'] ) ) {
|
78 |
+
die( 'Notice name expected as "notice" parameter.' );
|
79 |
+
}
|
80 |
+
|
81 |
+
$this->DismissNotice( $post_array['notice'] );
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Method: Check if notice is dismissed.
|
86 |
+
*
|
87 |
+
* @param string $name — Name of notice.
|
88 |
+
* @return boolean — Whether notice got dismissed or not.
|
89 |
+
*/
|
90 |
+
public function IsNoticeDismissed( $name ) {
|
91 |
+
$user_id = get_current_user_id();
|
92 |
+
$meta_key = 'wsal-notice-' . $name;
|
93 |
+
self::$AllowedNoticeNames[] = $name;
|
94 |
+
return ! ! get_user_meta( $user_id, $meta_key, true );
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Method: Dismiss notice.
|
99 |
+
*
|
100 |
+
* @param string $name — Name of notice to dismiss.
|
101 |
+
*/
|
102 |
+
public function DismissNotice( $name ) {
|
103 |
+
$user_id = get_current_user_id();
|
104 |
+
$meta_key = 'wsal-notice-' . $name;
|
105 |
+
$old_value = get_user_meta( $user_id, $meta_key, true );
|
106 |
+
if ( in_array( $name, self::$AllowedNoticeNames ) || false === $old_value ) {
|
107 |
+
update_user_meta( $user_id, $meta_key, '1' );
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Method: Register notice.
|
113 |
+
*
|
114 |
+
* @param string $name — Makes this notice available.
|
115 |
+
*/
|
116 |
+
public function RegisterNotice( $name ) {
|
117 |
+
self::$AllowedNoticeNames[] = $name;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Method: Return page name (for menu etc).
|
122 |
+
*
|
123 |
+
* @return string
|
124 |
+
*/
|
125 |
+
abstract public function GetName();
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Method: Return page title.
|
129 |
+
*
|
130 |
+
* @return string
|
131 |
+
*/
|
132 |
+
abstract public function GetTitle();
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Method: Page icon name.
|
136 |
+
*
|
137 |
+
* @return string
|
138 |
+
*/
|
139 |
+
abstract public function GetIcon();
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Method: Menu weight, the higher this is, the lower it goes.
|
143 |
+
*
|
144 |
+
* @return int
|
145 |
+
*/
|
146 |
+
abstract public function GetWeight();
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Renders and outputs the view directly.
|
150 |
+
*/
|
151 |
+
abstract public function Render();
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Renders the view icon (this has been deprecated in newwer WP versions).
|
155 |
+
*/
|
156 |
+
public function RenderIcon() {
|
157 |
+
?>
|
158 |
+
<div id="icon-plugins" class="icon32"><br></div>
|
159 |
+
<?php
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Renders the view title.
|
164 |
+
*/
|
165 |
+
public function RenderTitle() {
|
166 |
+
?>
|
167 |
+
<h2><?php echo esc_html( $this->GetTitle() ); ?></h2>
|
168 |
+
<?php
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Method: Render content of the view.
|
173 |
+
*
|
174 |
+
* @link self::Render()
|
175 |
+
*/
|
176 |
+
public function RenderContent() {
|
177 |
+
$this->Render();
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Method: Whether page should appear in menu or not.
|
182 |
+
*
|
183 |
+
* @return boolean
|
184 |
+
*/
|
185 |
+
public function IsVisible() {
|
186 |
+
return true;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Method: Whether page should be accessible or not.
|
191 |
+
*
|
192 |
+
* @return boolean
|
193 |
+
*/
|
194 |
+
public function IsAccessible() {
|
195 |
+
return true;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Used for rendering stuff into head tag.
|
200 |
+
*/
|
201 |
+
public function Header() {
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Used for rendering stuff in page fotoer.
|
206 |
+
*/
|
207 |
+
public function Footer() {
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Method: Safe view menu name.
|
212 |
+
*
|
213 |
+
* @return string
|
214 |
+
*/
|
215 |
+
public function GetSafeViewName() {
|
216 |
+
return 'wsal-' . preg_replace( '/[^A-Za-z0-9\-]/', '-', $this->GetViewName() );
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Override this and make it return true to create a shortcut link in plugin page to the view.
|
221 |
+
*
|
222 |
+
* @return boolean
|
223 |
+
*/
|
224 |
+
public function HasPluginShortcutLink() {
|
225 |
+
return false;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Method: URL to backend page for displaying view.
|
230 |
+
*
|
231 |
+
* @return string
|
232 |
+
*/
|
233 |
+
public function GetUrl() {
|
234 |
+
$fn = function_exists( 'network_admin_url' ) ? 'network_admin_url' : 'admin_url';
|
235 |
+
return $fn( 'admin.php?page=' . $this->GetSafeViewName() );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Method: Generates view name out of class name.
|
240 |
+
*
|
241 |
+
* @return string
|
242 |
+
*/
|
243 |
+
public function GetViewName() {
|
244 |
+
return strtolower( str_replace( array( 'WSAL_Views_', 'WSAL_' ), '', get_class( $this ) ) );
|
245 |
+
}
|
246 |
}
|
classes/Adapters/ActiveRecordInterface.php
CHANGED
@@ -1,19 +1,91 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* Interface used by the ActiveRecord.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*/
|
7 |
-
interface WSAL_Adapters_ActiveRecordInterface
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Active Record Interface.
|
4 |
*
|
5 |
* Interface used by the ActiveRecord.
|
6 |
+
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Interface used by the ActiveRecord.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
interface WSAL_Adapters_ActiveRecordInterface {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Is installed?
|
24 |
+
*/
|
25 |
+
public function IsInstalled();
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Install.
|
29 |
+
*/
|
30 |
+
public function Install();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Uninstall.
|
34 |
+
*/
|
35 |
+
public function Uninstall();
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Load.
|
39 |
+
*
|
40 |
+
* @param string $cond - Query Condition.
|
41 |
+
* @param array $args - Query arguments.
|
42 |
+
*/
|
43 |
+
public function Load( $cond = '%d', $args = array( 1 ) );
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Save.
|
47 |
+
*
|
48 |
+
* @param object $activeRecord - Active Record object.
|
49 |
+
*/
|
50 |
+
public function Save( $activeRecord );
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Delete.
|
54 |
+
*
|
55 |
+
* @param object $activeRecord - Active Record object.
|
56 |
+
*/
|
57 |
+
public function Delete( $activeRecord );
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Load with Multiple Conditions.
|
61 |
+
*
|
62 |
+
* @param string $cond - Query Condition.
|
63 |
+
* @param array $args - Query arguments.
|
64 |
+
*/
|
65 |
+
public function LoadMulti( $cond, $args = array() );
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Load and call foreach.
|
69 |
+
*
|
70 |
+
* @param string $callback - Callback.
|
71 |
+
* @param string $cond - Query Condition.
|
72 |
+
* @param array $args - Query arguments.
|
73 |
+
*/
|
74 |
+
public function LoadAndCallForEach( $callback, $cond = '%d', $args = array( 1 ) );
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Count.
|
78 |
+
*
|
79 |
+
* @param string $cond - Query Condition.
|
80 |
+
* @param array $args - Query arguments.
|
81 |
+
*/
|
82 |
+
public function Count( $cond = '%d', $args = array( 1 ) );
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Multiple Query.
|
86 |
+
*
|
87 |
+
* @param array $query - Query Condition.
|
88 |
+
* @param array $args - Query arguments.
|
89 |
+
*/
|
90 |
+
public function LoadMultiQuery( $query, $args = array() );
|
91 |
}
|
classes/Adapters/MetaInterface.php
CHANGED
@@ -1,17 +1,37 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Interface used by the Metadata.
|
|
|
|
|
6 |
*/
|
7 |
-
interface WSAL_Adapters_MetaInterface
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
15 |
|
16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Meta Interface.
|
4 |
+
*
|
5 |
+
* Interface used by the Metadata.
|
6 |
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* Interface used by the Metadata.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
interface WSAL_Adapters_MetaInterface {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Create a meta object
|
24 |
+
*
|
25 |
+
* @param array $occurenceIds - Array of meta data.
|
26 |
+
* @return int ID of the new meta data
|
27 |
+
*/
|
28 |
+
public function deleteByOccurenceIds( $occurenceIds );
|
29 |
|
30 |
+
/**
|
31 |
+
* Load by name and occurrence id.
|
32 |
+
*
|
33 |
+
* @param string $metaName - Meta name.
|
34 |
+
* @param int $occurenceId - Occurrence ID.
|
35 |
+
*/
|
36 |
+
public function loadByNameAndOccurenceId( $metaName, $occurenceId );
|
37 |
}
|
classes/Adapters/MySQL/ActiveRecordAdapter.php
CHANGED
@@ -1,679 +1,711 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL database ActiveRecord class.
|
5 |
*
|
6 |
* MySQL generic table used for Save, Read, Create or Delete
|
7 |
* elements in the Database.
|
8 |
* There are also the functions used in the Report Add-On to get the reports.
|
|
|
|
|
9 |
*/
|
10 |
-
class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInterface
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
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 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
679 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Adapter: Active Record.
|
4 |
+
*
|
5 |
+
* MySQL database ActiveRecord class.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* MySQL database ActiveRecord class.
|
17 |
*
|
18 |
* MySQL generic table used for Save, Read, Create or Delete
|
19 |
* elements in the Database.
|
20 |
* There are also the functions used in the Report Add-On to get the reports.
|
21 |
+
*
|
22 |
+
* @package Wsal
|
23 |
*/
|
24 |
+
class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInterface {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* DB Connection
|
28 |
+
*
|
29 |
+
* @var array
|
30 |
+
*/
|
31 |
+
protected $connection;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Contains the table name
|
35 |
+
*
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
protected $_table;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Contains primary key column name, override as required.
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
protected $_idkey = '';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Method: Constructor.
|
49 |
+
*
|
50 |
+
* @param array $conn - Connection array.
|
51 |
+
*/
|
52 |
+
public function __construct( $conn ) {
|
53 |
+
$this->connection = $conn;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Returns the model class for adapter.
|
58 |
+
*
|
59 |
+
* @return WSAL_Models_ActiveRecord
|
60 |
+
*/
|
61 |
+
public function GetModel() {
|
62 |
+
return new WSAL_Models_ActiveRecord();
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Returns table name.
|
67 |
+
*
|
68 |
+
* @return string
|
69 |
+
*/
|
70 |
+
public function GetTable() {
|
71 |
+
$_wpdb = $this->connection;
|
72 |
+
return $_wpdb->base_prefix . $this->_table;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Used for WordPress prefix
|
77 |
+
*
|
78 |
+
* @return string Returns table name of WordPress.
|
79 |
+
*/
|
80 |
+
public function GetWPTable() {
|
81 |
+
global $wpdb;
|
82 |
+
return $wpdb->base_prefix . $this->_table;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* SQL table options (constraints, foreign keys, indexes etc).
|
87 |
+
*
|
88 |
+
* @return string
|
89 |
+
*/
|
90 |
+
protected function GetTableOptions() {
|
91 |
+
return ' PRIMARY KEY (' . $this->_idkey . ')';
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Returns this records' columns.
|
96 |
+
*
|
97 |
+
* @return array
|
98 |
+
*/
|
99 |
+
public function GetColumns() {
|
100 |
+
$model = $this->GetModel();
|
101 |
+
|
102 |
+
if ( ! isset( $this->_column_cache ) ) {
|
103 |
+
$this->_column_cache = array();
|
104 |
+
foreach ( array_keys( get_object_vars( $model ) ) as $col ) {
|
105 |
+
if ( trim( $col ) && $col[0] != '_' ) {
|
106 |
+
$this->_column_cache[] = $col;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
}
|
110 |
+
return $this->_column_cache;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Returns whether table structure is installed or not.
|
115 |
+
*
|
116 |
+
* @deprecated
|
117 |
+
* @return boolean
|
118 |
+
*/
|
119 |
+
public function IsInstalled() {
|
120 |
+
$_wpdb = $this->connection;
|
121 |
+
$sql = 'SHOW TABLES LIKE "' . $this->GetTable() . '"';
|
122 |
+
return strtolower( $_wpdb->get_var( $sql ) ) == strtolower( $this->GetTable() );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Install this ActiveRecord structure into DB.
|
127 |
+
*/
|
128 |
+
public function Install() {
|
129 |
+
$_wpdb = $this->connection;
|
130 |
+
$_wpdb->query( $this->_GetInstallQuery() );
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Install this ActiveRecord structure into DB WordPress.
|
135 |
+
*/
|
136 |
+
public function InstallOriginal() {
|
137 |
+
global $wpdb;
|
138 |
+
$wpdb->query( $this->_GetInstallQuery( true ) );
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Remove this ActiveRecord structure from DB.
|
143 |
+
*/
|
144 |
+
public function Uninstall() {
|
145 |
+
$_wpdb = $this->connection;
|
146 |
+
$_wpdb->query( $this->_GetUninstallQuery() );
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Save an active record into DB.
|
151 |
+
*
|
152 |
+
* @param object $active_record - ActiveRecord object.
|
153 |
+
* @return integer|boolean - Either the number of modified/inserted rows or false on failure.
|
154 |
+
*/
|
155 |
+
public function Save( $active_record ) {
|
156 |
+
$_wpdb = $this->connection;
|
157 |
+
$copy = $active_record;
|
158 |
+
$data = array();
|
159 |
+
$format = array();
|
160 |
+
|
161 |
+
foreach ( $this->GetColumns() as $index => $key ) {
|
162 |
+
if ( $key == $this->_idkey ) {
|
163 |
+
$_id_index = $index;
|
164 |
+
}
|
165 |
+
|
166 |
+
$val = $copy->$key;
|
167 |
+
$deffmt = '%s';
|
168 |
+
if ( is_int( $copy->$key ) ) {
|
169 |
+
$deffmt = '%d';
|
170 |
+
}
|
171 |
+
if ( is_float( $copy->$key ) ) {
|
172 |
+
$deffmt = '%f';
|
173 |
+
}
|
174 |
+
if ( is_array( $copy->$key ) || is_object( $copy->$key ) ) {
|
175 |
+
$data[ $key ] = WSAL_Helpers_DataHelper::JsonEncode( $val );
|
176 |
+
} else {
|
177 |
+
$data[ $key ] = $val;
|
178 |
+
}
|
179 |
+
$format[] = $deffmt;
|
180 |
+
}
|
181 |
+
|
182 |
+
if ( isset( $data[ $this->_idkey ] ) && empty( $data[ $this->_idkey ] ) ) {
|
183 |
+
unset( $data[ $this->_idkey ] );
|
184 |
+
unset( $format[ $_id_index ] );
|
185 |
+
}
|
186 |
+
|
187 |
+
$result = $_wpdb->replace( $this->GetTable(), $data, $format );
|
188 |
+
|
189 |
+
if ( false !== $result ) {
|
190 |
+
if ( $_wpdb->insert_id ) {
|
191 |
+
$copy->setId( $_wpdb->insert_id );
|
192 |
+
}
|
193 |
+
}
|
194 |
+
return $result;
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Load record from DB (Single row).
|
199 |
+
*
|
200 |
+
* @param string $cond - (Optional) Load condition.
|
201 |
+
* @param array $args - (Optional) Load condition arguments.
|
202 |
+
*/
|
203 |
+
public function Load( $cond = '%d', $args = array( 1 ) ) {
|
204 |
+
$_wpdb = $this->connection;
|
205 |
+
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
206 |
+
$data = $_wpdb->get_row( $sql, ARRAY_A );
|
207 |
+
return $data;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Load records from DB (Multi rows).
|
212 |
+
*
|
213 |
+
* @param string $cond Load condition.
|
214 |
+
* @param array $args (Optional) Load condition arguments.
|
215 |
+
*/
|
216 |
+
public function LoadArray( $cond, $args = array() ) {
|
217 |
+
$_wpdb = $this->connection;
|
218 |
+
$result = array();
|
219 |
+
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
220 |
+
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
221 |
+
$result[] = $this->getModel()->LoadData( $data );
|
222 |
+
}
|
223 |
+
return $result;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Delete DB record.
|
228 |
+
*
|
229 |
+
* @param object $active_record - ActiveRecord object.
|
230 |
+
* @return int|boolean - Either the amount of deleted rows or False on error.
|
231 |
+
*/
|
232 |
+
public function Delete( $active_record ) {
|
233 |
+
$_wpdb = $this->connection;
|
234 |
+
$result = $_wpdb->delete(
|
235 |
+
$this->GetTable(),
|
236 |
+
$active_record->getId()
|
237 |
+
);
|
238 |
+
return $result;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Delete records in DB matching a query.
|
243 |
+
*
|
244 |
+
* @param string $query Full SQL query.
|
245 |
+
* @param array $args (Optional) Query arguments.
|
246 |
+
*/
|
247 |
+
public function DeleteQuery( $query, $args = array() ) {
|
248 |
+
$_wpdb = $this->connection;
|
249 |
+
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
250 |
+
$result = $_wpdb->query( $sql );
|
251 |
+
return $result;
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Load multiple records from DB.
|
256 |
+
*
|
257 |
+
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
258 |
+
* @param array $args (Optional) Load condition arguments (rg: array(45) ).
|
259 |
+
* @return self[] List of loaded records.
|
260 |
+
*/
|
261 |
+
public function LoadMulti( $cond, $args = array() ) {
|
262 |
+
$_wpdb = $this->connection;
|
263 |
+
$result = array();
|
264 |
+
$sql = ( ! is_array( $args ) || ! count( $args )) // Do we really need to prepare() or not?
|
265 |
+
? ($cond)
|
266 |
+
: $_wpdb->prepare( $cond, $args );
|
267 |
+
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
268 |
+
$result[] = $this->getModel()->LoadData( $data );
|
269 |
+
}
|
270 |
+
return $result;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Load multiple records from DB and call a callback for each record.
|
275 |
+
* This function is very memory-efficient, it doesn't load records in bulk.
|
276 |
+
*
|
277 |
+
* @param callable $callback The callback to invoke.
|
278 |
+
* @param string $cond (Optional) Load condition.
|
279 |
+
* @param array $args (Optional) Load condition arguments.
|
280 |
+
*/
|
281 |
+
public function LoadAndCallForEach( $callback, $cond = '%d', $args = array( 1 ) ) {
|
282 |
+
$_wpdb = $this->connection;
|
283 |
+
$class = get_called_class();
|
284 |
+
$sql = $_wpdb->prepare( 'SELECT * FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
285 |
+
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
286 |
+
call_user_func( $callback, new $class( $data ) );
|
287 |
+
}
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Count records in the DB matching a condition.
|
292 |
+
* If no parameters are given, this counts the number of records in the DB table.
|
293 |
+
*
|
294 |
+
* @param string $cond (Optional) Query condition.
|
295 |
+
* @param array $args (Optional) Condition arguments.
|
296 |
+
* @return int Number of matching records.
|
297 |
+
*/
|
298 |
+
public function Count( $cond = '%d', $args = array( 1 ) ) {
|
299 |
+
$_wpdb = $this->connection;
|
300 |
+
$class = get_called_class();
|
301 |
+
$sql = $_wpdb->prepare( 'SELECT COUNT(*) FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args );
|
302 |
+
return (int) $_wpdb->get_var( $sql );
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Count records in the DB matching a query.
|
307 |
+
*
|
308 |
+
* @param string $query Full SQL query.
|
309 |
+
* @param array $args (Optional) Query arguments.
|
310 |
+
* @return int Number of matching records.
|
311 |
+
*/
|
312 |
+
public function CountQuery( $query, $args = array() ) {
|
313 |
+
$_wpdb = $this->connection;
|
314 |
+
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
315 |
+
return (int) $_wpdb->get_var( $sql );
|
316 |
+
}
|
317 |
+
|
318 |
+
/**
|
319 |
+
* Similar to LoadMulti but allows the use of a full SQL query.
|
320 |
+
*
|
321 |
+
* @param string $query Full SQL query.
|
322 |
+
* @param array $args (Optional) Query arguments.
|
323 |
+
* @return self[] List of loaded records.
|
324 |
+
*/
|
325 |
+
public function LoadMultiQuery( $query, $args = array() ) {
|
326 |
+
$_wpdb = $this->connection;
|
327 |
+
$class = get_called_class();
|
328 |
+
$result = array();
|
329 |
+
$sql = count( $args ) ? $_wpdb->prepare( $query, $args ) : $query;
|
330 |
+
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
331 |
+
$result[] = $this->getModel()->LoadData( $data );
|
332 |
+
}
|
333 |
+
return $result;
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Table install query.
|
338 |
+
*
|
339 |
+
* @param string $prefix - (Optional) Table prefix.
|
340 |
+
* @return string - Must return SQL for creating table.
|
341 |
+
*/
|
342 |
+
protected function _GetInstallQuery( $prefix = false ) {
|
343 |
+
$_wpdb = $this->connection;
|
344 |
+
|
345 |
+
$class = get_class( $this );
|
346 |
+
$copy = new $class( $this->connection );
|
347 |
+
$table_name = ($prefix) ? $this->GetWPTable() : $this->GetTable();
|
348 |
+
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
349 |
+
|
350 |
+
foreach ( $this->GetColumns() as $key ) {
|
351 |
+
$sql .= ' ';
|
352 |
+
switch ( true ) {
|
353 |
+
case $key == $copy->_idkey:
|
354 |
+
$sql .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
|
355 |
+
break;
|
356 |
+
case is_integer( $copy->$key ):
|
357 |
+
$sql .= $key . ' BIGINT NOT NULL,' . PHP_EOL;
|
358 |
+
break;
|
359 |
+
case is_float( $copy->$key ):
|
360 |
+
$sql .= $key . ' DOUBLE NOT NULL,' . PHP_EOL;
|
361 |
+
break;
|
362 |
+
case is_string( $copy->$key ):
|
363 |
+
$maxlength = $key . '_maxlength';
|
364 |
+
if ( property_exists( $class, $maxlength ) ) {
|
365 |
+
$sql .= $key . ' VARCHAR(' . intval( $class::$$maxlength ) . ') NOT NULL,' . PHP_EOL;
|
366 |
+
} else {
|
367 |
+
$sql .= $key . ' TEXT NOT NULL,' . PHP_EOL;
|
368 |
+
}
|
369 |
+
break;
|
370 |
+
case is_bool( $copy->$key ):
|
371 |
+
$sql .= $key . ' BIT NOT NULL,' . PHP_EOL;
|
372 |
+
break;
|
373 |
+
case is_array( $copy->$key ):
|
374 |
+
case is_object( $copy->$key ):
|
375 |
+
$sql .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
376 |
+
break;
|
377 |
+
}
|
378 |
+
}
|
379 |
+
|
380 |
+
$sql .= $this->GetTableOptions() . PHP_EOL;
|
381 |
+
|
382 |
+
$sql .= ')';
|
383 |
+
|
384 |
+
if ( ! empty( $_wpdb->charset ) ) {
|
385 |
+
$sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
|
386 |
+
}
|
387 |
+
|
388 |
+
return $sql;
|
389 |
+
}
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Must return SQL for removing table (at a minimum, it should be ` 'DROP TABLE ' . $this->_table `).
|
393 |
+
*
|
394 |
+
* @return string
|
395 |
+
*/
|
396 |
+
protected function _GetUninstallQuery() {
|
397 |
+
return 'DROP TABLE ' . $this->GetTable();
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Get Users user_login.
|
402 |
+
*
|
403 |
+
* @param int $_user_id - User ID.
|
404 |
+
* @return string comma separated users login
|
405 |
+
*/
|
406 |
+
private function GetUserNames( $_user_id ) {
|
407 |
+
global $wpdb;
|
408 |
+
|
409 |
+
$user_names = '0';
|
410 |
+
if ( ! empty( $_user_id ) && 'null' != $_user_id ) {
|
411 |
+
$sql = 'SELECT user_login FROM ' . $wpdb->users . ' WHERE find_in_set(ID, @userId) > 0';
|
412 |
+
$wpdb->query( "SET @userId = $_user_id" );
|
413 |
+
$result = $wpdb->get_results( $sql, ARRAY_A );
|
414 |
+
$users_array = array();
|
415 |
+
foreach ( $result as $item ) {
|
416 |
+
$users_array[] = '"' . $item['user_login'] . '"';
|
417 |
+
}
|
418 |
+
$user_names = implode( ', ', $users_array );
|
419 |
+
}
|
420 |
+
return $user_names;
|
421 |
+
}
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Function used in WSAL reporting extension.
|
425 |
+
*
|
426 |
+
* @param int $_site_id - Site ID.
|
427 |
+
* @param int $_user_id - User ID.
|
428 |
+
* @param string $_role_name - User role.
|
429 |
+
* @param int $_alert_code - Alert code.
|
430 |
+
* @param timestamp $_start_timestamp - From created_on.
|
431 |
+
* @param timestamp $_end_timestamp - To created_on.
|
432 |
+
* @param timestamp $_next_date - (Optional) Created on >.
|
433 |
+
* @param int $_limit - (Optional) Limit.
|
434 |
+
* @return array Report results
|
435 |
+
*/
|
436 |
+
public function GetReporting( $_site_id, $_user_id, $_role_name, $_alert_code, $_start_timestamp, $_end_timestamp, $_next_date = null, $_limit = 0 ) {
|
437 |
+
global $wpdb;
|
438 |
+
$user_names = $this->GetUserNames( $_user_id );
|
439 |
+
|
440 |
+
$_wpdb = $this->connection;
|
441 |
+
$_wpdb->set_charset( $_wpdb->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
442 |
+
// Tables.
|
443 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
444 |
+
$table_meta = $meta->GetTable(); // Metadata.
|
445 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
446 |
+
$table_occ = $occurrence->GetTable(); // Occurrences.
|
447 |
+
|
448 |
+
$condition_date = ! empty( $_next_date ) ? ' AND occ.created_on < ' . $_next_date : '';
|
449 |
+
|
450 |
+
$sql = "SELECT DISTINCT
|
451 |
+
occ.id,
|
452 |
+
occ.alert_id,
|
453 |
+
occ.site_id,
|
454 |
+
occ.created_on,
|
455 |
+
replace(replace(replace((
|
456 |
+
SELECT t1.value FROM $table_meta AS t1 WHERE t1.name = 'CurrentUserRoles' AND t1.occurrence_id = occ.id LIMIT 1), '[', ''), ']', ''), '\\'', '') AS roles,
|
457 |
+
(SELECT replace(t2.value, '\"','') FROM $table_meta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id LIMIT 1) AS ip,
|
458 |
+
(SELECT replace(t3.value, '\"', '') FROM $table_meta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id LIMIT 1) AS ua,
|
459 |
+
COALESCE(
|
460 |
+
(SELECT replace(t4.value, '\"', '') FROM $table_meta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id LIMIT 1),
|
461 |
+
(SELECT replace(t5.value, '\"', '') FROM $table_meta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id LIMIT 1)
|
462 |
+
) as user_id
|
463 |
+
FROM $table_occ AS occ
|
464 |
+
JOIN $table_meta AS meta ON meta.occurrence_id = occ.id
|
465 |
+
WHERE
|
466 |
+
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
467 |
+
AND (@userId is NULL OR (
|
468 |
+
(meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
469 |
+
OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
470 |
+
))
|
471 |
+
AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
|
472 |
+
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
473 |
+
))
|
474 |
+
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
475 |
+
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
476 |
+
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
477 |
+
{$condition_date}
|
478 |
+
ORDER BY
|
479 |
+
created_on DESC
|
480 |
+
";
|
481 |
+
|
482 |
+
$_wpdb->query( "SET @siteId = $_site_id" );
|
483 |
+
$_wpdb->query( "SET @userId = $_user_id" );
|
484 |
+
$_wpdb->query( "SET @roleName = $_role_name" );
|
485 |
+
$_wpdb->query( "SET @alertCode = $_alert_code" );
|
486 |
+
$_wpdb->query( "SET @startTimestamp = $_start_timestamp" );
|
487 |
+
$_wpdb->query( "SET @endTimestamp = $_end_timestamp" );
|
488 |
+
|
489 |
+
if ( ! empty( $_limit ) ) {
|
490 |
+
$sql .= " LIMIT {$_limit}";
|
491 |
+
}
|
492 |
+
$results = $_wpdb->get_results( $sql );
|
493 |
+
if ( ! empty( $results ) ) {
|
494 |
+
foreach ( $results as $row ) {
|
495 |
+
$sql = "SELECT t6.ID FROM $wpdb->users AS t6 WHERE t6.user_login = \"$row->user_id\"";
|
496 |
+
$user_id = $wpdb->get_var( $sql );
|
497 |
+
if ( null == $user_id ) {
|
498 |
+
$sql = "SELECT t4.ID FROM $wpdb->users AS t4 WHERE t4.ID = \"$row->user_id\"";
|
499 |
+
$user_id = $wpdb->get_var( $sql );
|
500 |
+
}
|
501 |
+
$row->user_id = $user_id;
|
502 |
+
$results['lastDate'] = $row->created_on;
|
503 |
+
}
|
504 |
+
}
|
505 |
+
|
506 |
+
return $results;
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Function used in WSAL reporting extension.
|
511 |
+
* Check if criteria are matching in the DB.
|
512 |
+
*
|
513 |
+
* @param mixed $criteria - Query conditions.
|
514 |
+
* @return int count of distinct values
|
515 |
+
*/
|
516 |
+
public function CheckMatchReportCriteria( $criteria ) {
|
517 |
+
$_site_id = $criteria['siteId'];
|
518 |
+
$_user_id = $criteria['userId'];
|
519 |
+
$_role_name = $criteria['roleName'];
|
520 |
+
$_alert_code = $criteria['alertCode'];
|
521 |
+
$_start_timestamp = $criteria['startTimestamp'];
|
522 |
+
$_end_timestamp = $criteria['endTimestamp'];
|
523 |
+
$_ip_address = $criteria['ipAddress'];
|
524 |
+
|
525 |
+
$_wpdb = $this->connection;
|
526 |
+
$_wpdb->set_charset( $_wpdb->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
527 |
+
// Tables.
|
528 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
529 |
+
$table_meta = $meta->GetTable(); // Metadata.
|
530 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
531 |
+
$table_occ = $occurrence->GetTable(); // Occurrences.
|
532 |
+
|
533 |
+
$user_names = $this->GetUserNames( $_user_id );
|
534 |
+
|
535 |
+
$sql = "SELECT COUNT(DISTINCT occ.id) FROM $table_occ AS occ
|
536 |
+
JOIN $table_meta AS meta ON meta.occurrence_id = occ.id
|
537 |
+
WHERE
|
538 |
+
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
539 |
+
AND (@userId is NULL OR (
|
540 |
+
(meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
541 |
+
OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
542 |
+
))
|
543 |
+
AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
|
544 |
+
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
545 |
+
))
|
546 |
+
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
547 |
+
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
548 |
+
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
549 |
+
AND (@ipAddress is NULL OR (meta.name = 'ClientIP' AND find_in_set(meta.value, @ipAddress) > 0))
|
550 |
+
";
|
551 |
+
|
552 |
+
$_wpdb->query( "SET @siteId = $_site_id" );
|
553 |
+
$_wpdb->query( "SET @userId = $_user_id" );
|
554 |
+
$_wpdb->query( "SET @roleName = $_role_name" );
|
555 |
+
$_wpdb->query( "SET @alertCode = $_alert_code" );
|
556 |
+
$_wpdb->query( "SET @startTimestamp = $_start_timestamp" );
|
557 |
+
$_wpdb->query( "SET @endTimestamp = $_end_timestamp" );
|
558 |
+
$_wpdb->query( "SET @ipAddress = $_ip_address" );
|
559 |
+
|
560 |
+
$count = (int) $_wpdb->get_var( $sql );
|
561 |
+
return $count;
|
562 |
+
}
|
563 |
+
|
564 |
+
/**
|
565 |
+
* Function used in WSAL reporting extension.
|
566 |
+
* List of unique IP addresses used by the same user.
|
567 |
+
*
|
568 |
+
* @param int $_site_id - Site ID.
|
569 |
+
* @param timestamp $_start_timestamp - From created_on.
|
570 |
+
* @param timestamp $_end_timestamp - To created_on.
|
571 |
+
* @param int $_user_id - (Optional) User ID.
|
572 |
+
* @param string $_role_name - (Optional) User role.
|
573 |
+
* @param string $_ip_address - (Optional) IP address.
|
574 |
+
* @param int $_alert_code - (Optional) Alert code.
|
575 |
+
* @param int $_limit - (Optional) Limit.
|
576 |
+
* @return array Report results grouped by IP and Username
|
577 |
+
*/
|
578 |
+
public function GetReportGrouped( $_site_id, $_start_timestamp, $_end_timestamp, $_user_id = 'null', $_role_name = 'null', $_ip_address = 'null', $_alert_code = 'null', $_limit = 0 ) {
|
579 |
+
global $wpdb;
|
580 |
+
$user_names = $this->GetUserNames( $_user_id );
|
581 |
+
|
582 |
+
$_wpdb = $this->connection;
|
583 |
+
$_wpdb->set_charset( $_wpdb->dbh, 'utf8mb4', 'utf8mb4_general_ci' );
|
584 |
+
// Tables.
|
585 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
586 |
+
$table_meta = $meta->GetTable(); // Metadata.
|
587 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
588 |
+
$table_occ = $occurrence->GetTable(); // Occurrences.
|
589 |
+
// Get temp table `wsal_tmp_users`.
|
590 |
+
$tmp_users = new WSAL_Adapters_MySQL_TmpUser( $this->connection );
|
591 |
+
// If the table exist.
|
592 |
+
if ( $tmp_users->IsInstalled() ) {
|
593 |
+
$table_users = $tmp_users->GetTable(); // tmp_users.
|
594 |
+
$this->TempUsers( $table_users );
|
595 |
+
} else {
|
596 |
+
$table_users = $wpdb->users;
|
597 |
+
}
|
598 |
+
|
599 |
+
$sql = "SELECT DISTINCT *
|
600 |
+
FROM (SELECT DISTINCT
|
601 |
+
occ.site_id,
|
602 |
+
CONVERT((SELECT replace(t1.value, '\"', '') FROM $table_meta as t1 WHERE t1.name = 'Username' AND t1.occurrence_id = occ.id LIMIT 1) using UTF8) AS user_login ,
|
603 |
+
CONVERT((SELECT replace(t3.value, '\"','') FROM $table_meta as t3 WHERE t3.name = 'ClientIP' AND t3.occurrence_id = occ.id LIMIT 1) using UTF8) AS ip
|
604 |
+
FROM $table_occ AS occ
|
605 |
+
JOIN $table_meta AS meta ON meta.occurrence_id = occ.id
|
606 |
+
WHERE
|
607 |
+
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
608 |
+
AND (@userId is NULL OR (
|
609 |
+
(meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
610 |
+
OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
611 |
+
))
|
612 |
+
AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
|
613 |
+
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
614 |
+
))
|
615 |
+
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
616 |
+
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
617 |
+
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
618 |
+
AND (@ipAddress is NULL OR (meta.name = 'ClientIP' AND find_in_set(meta.value, @ipAddress) > 0))
|
619 |
+
HAVING user_login IS NOT NULL
|
620 |
+
UNION ALL
|
621 |
+
SELECT DISTINCT
|
622 |
+
occ.site_id,
|
623 |
+
CONVERT((SELECT u.user_login
|
624 |
+
FROM $table_meta as t2
|
625 |
+
JOIN $table_users AS u ON u.ID = replace(t2.value, '\"', '')
|
626 |
+
WHERE t2.name = 'CurrentUserID'
|
627 |
+
AND t2.occurrence_id = occ.id
|
628 |
+
GROUP BY u.ID
|
629 |
+
LIMIT 1) using UTF8) AS user_login,
|
630 |
+
CONVERT((SELECT replace(t4.value, '\"','') FROM $table_meta as t4 WHERE t4.name = 'ClientIP' AND t4.occurrence_id = occ.id LIMIT 1) using UTF8) AS ip
|
631 |
+
FROM $table_occ AS occ
|
632 |
+
JOIN $table_meta AS meta ON meta.occurrence_id = occ.id
|
633 |
+
WHERE
|
634 |
+
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
635 |
+
AND (@userId is NULL OR (
|
636 |
+
(meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
637 |
+
OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
638 |
+
))
|
639 |
+
AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
|
640 |
+
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
641 |
+
))
|
642 |
+
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
643 |
+
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
644 |
+
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
645 |
+
AND (@ipAddress is NULL OR (meta.name = 'ClientIP' AND find_in_set(meta.value, @ipAddress) > 0))
|
646 |
+
HAVING user_login IS NOT NULL) ip_logins
|
647 |
+
WHERE user_login NOT IN ('Website Visitor', 'Plugins', 'Plugin')
|
648 |
+
ORDER BY user_login ASC
|
649 |
+
";
|
650 |
+
$_wpdb->query( "SET @siteId = $_site_id" );
|
651 |
+
$_wpdb->query( "SET @userId = $_user_id" );
|
652 |
+
$_wpdb->query( "SET @roleName = $_role_name" );
|
653 |
+
$_wpdb->query( "SET @alertCode = $_alert_code" );
|
654 |
+
$_wpdb->query( "SET @startTimestamp = $_start_timestamp" );
|
655 |
+
$_wpdb->query( "SET @endTimestamp = $_end_timestamp" );
|
656 |
+
$_wpdb->query( "SET @ipAddress = $_ip_address" );
|
657 |
+
if ( ! empty( $_limit ) ) {
|
658 |
+
$sql .= " LIMIT {$_limit}";
|
659 |
+
}
|
660 |
+
|
661 |
+
$grouped_types = array();
|
662 |
+
$results = $_wpdb->get_results( $sql );
|
663 |
+
if ( ! empty( $results ) ) {
|
664 |
+
foreach ( $results as $key => $row ) {
|
665 |
+
// Get the display_name only for the first row & if the user_login changed from the previous row.
|
666 |
+
if ( 0 == $key || ($key > 1 && $results[ ($key - 1) ]->user_login != $row->user_login) ) {
|
667 |
+
$sql = "SELECT t5.display_name FROM $wpdb->users AS t5 WHERE t5.user_login = \"$row->user_login\"";
|
668 |
+
$display_name = $wpdb->get_var( $sql );
|
669 |
+
}
|
670 |
+
$row->display_name = $display_name;
|
671 |
+
|
672 |
+
if ( ! isset( $grouped_types[ $row->user_login ] ) ) {
|
673 |
+
$grouped_types[ $row->user_login ] = array(
|
674 |
+
'site_id' => $row->site_id,
|
675 |
+
'user_login' => $row->user_login,
|
676 |
+
'display_name' => $row->display_name,
|
677 |
+
'ips' => array(),
|
678 |
+
);
|
679 |
+
}
|
680 |
+
|
681 |
+
$grouped_types[ $row->user_login ]['ips'][] = $row->ip;
|
682 |
+
}
|
683 |
+
}
|
684 |
+
|
685 |
+
return $grouped_types;
|
686 |
+
}
|
687 |
+
|
688 |
+
/**
|
689 |
+
* DELETE from table `tmp_users` and populate with users.
|
690 |
+
* It is used in the query of the above function.
|
691 |
+
*
|
692 |
+
* @param string $table_users - Table name.
|
693 |
+
*/
|
694 |
+
private function TempUsers( $table_users ) {
|
695 |
+
$_wpdb = $this->connection;
|
696 |
+
$sql = "DELETE FROM $table_users";
|
697 |
+
$_wpdb->query( $sql );
|
698 |
+
|
699 |
+
$sql = "INSERT INTO $table_users (ID, user_login) VALUES " ;
|
700 |
+
$users = get_users(
|
701 |
+
array(
|
702 |
+
'fields' => array( 'ID', 'user_login' ),
|
703 |
+
)
|
704 |
+
);
|
705 |
+
foreach ( $users as $user ) {
|
706 |
+
$sql .= '(' . $user->ID . ', \'' . $user->user_login . '\'), ';
|
707 |
+
}
|
708 |
+
$sql = rtrim( $sql, ', ' );
|
709 |
+
$_wpdb->query( $sql );
|
710 |
+
}
|
711 |
}
|
classes/Adapters/MySQL/MetaAdapter.php
CHANGED
@@ -1,84 +1,144 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL database Metadata class.
|
5 |
*
|
6 |
* MySQL wsal_metadata table used for to store the alert meta data:
|
7 |
* username, user_roles, client_ip, user_agent, post_id, post_title, etc.
|
|
|
|
|
8 |
*/
|
9 |
-
class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_MetaInterface
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
|
|
|
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
{
|
30 |
-
parent::__construct($conn);
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @return string SQL table options (constraints, foreign keys, indexes etc).
|
35 |
-
*/
|
36 |
-
protected function GetTableOptions()
|
37 |
-
{
|
38 |
-
return parent::GetTableOptions() . ',' . PHP_EOL
|
39 |
-
. ' KEY occurrence_name (occurrence_id,name)';
|
40 |
-
}
|
41 |
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Adapter: Meta data.
|
4 |
+
*
|
5 |
+
* MySQL database Metadata class.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* MySQL database Metadata class.
|
17 |
*
|
18 |
* MySQL wsal_metadata table used for to store the alert meta data:
|
19 |
* username, user_roles, client_ip, user_agent, post_id, post_title, etc.
|
20 |
+
*
|
21 |
+
* @package Wsal
|
22 |
*/
|
23 |
+
class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_MetaInterface {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Contains the table name.
|
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.
|
41 |
+
*
|
42 |
+
* @var int
|
43 |
+
*/
|
44 |
+
public $id = 0;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Occurrence id.
|
48 |
+
*
|
49 |
+
* @var int
|
50 |
+
*/
|
51 |
+
public $occurrence_id = 0;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Meta name.
|
55 |
+
*
|
56 |
+
* @var string
|
57 |
+
*/
|
58 |
+
public $name = '';
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Meta name max length.
|
62 |
+
*
|
63 |
+
* @var int
|
64 |
+
*/
|
65 |
+
public static $name_maxlength = 100;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Meta value.
|
69 |
+
*
|
70 |
+
* @var mix
|
71 |
+
*/
|
72 |
+
public $value = array(); // Force mixed type.
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Returns the model class for adapter.
|
76 |
+
*
|
77 |
+
* @return WSAL_Models_Meta
|
78 |
+
*/
|
79 |
+
public function GetModel() {
|
80 |
+
return new WSAL_Models_Meta();
|
81 |
+
}
|
82 |
|
83 |
+
/**
|
84 |
+
* Method: Constructor.
|
85 |
+
*
|
86 |
+
* @param array $conn - Connection array.
|
87 |
+
*/
|
88 |
+
public function __construct( $conn ) {
|
89 |
+
parent::__construct( $conn );
|
90 |
+
}
|
91 |
|
92 |
+
/**
|
93 |
+
* SQL table options (constraints, foreign keys, indexes etc).
|
94 |
+
*
|
95 |
+
* @return string
|
96 |
+
*/
|
97 |
+
protected function GetTableOptions() {
|
98 |
+
return parent::GetTableOptions() . ',' . PHP_EOL
|
99 |
+
. ' KEY occurrence_name (occurrence_id,name)';
|
100 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
+
/**
|
103 |
+
* Delete metadata by occurrence_id.
|
104 |
+
*
|
105 |
+
* @param array $occurence_ids - List of occurrence IDs.
|
106 |
+
*/
|
107 |
+
public function DeleteByOccurenceIds( $occurence_ids ) {
|
108 |
+
if ( ! empty( $occurence_ids ) ) {
|
109 |
+
$sql = 'DELETE FROM ' . $this->GetTable() . ' WHERE occurrence_id IN (' . implode( ',', $occurence_ids ) . ')';
|
110 |
+
// Execute query.
|
111 |
+
parent::DeleteQuery( $sql );
|
112 |
+
}
|
113 |
+
}
|
114 |
|
115 |
+
/**
|
116 |
+
* Load metadata by name and occurrence_id.
|
117 |
+
*
|
118 |
+
* @param string $meta_name - Metadata name.
|
119 |
+
* @param string $occurence_id - Metadata occurrence_id.
|
120 |
+
* @return WSAL_Meta[]
|
121 |
+
*/
|
122 |
+
public function LoadByNameAndOccurenceId( $meta_name, $occurence_id ) {
|
123 |
+
return $this->Load( 'occurrence_id = %d AND name = %s', array( $occurence_id, $meta_name ) );
|
124 |
+
}
|
125 |
|
126 |
+
/**
|
127 |
+
* Get distinct values of IPs.
|
128 |
+
*
|
129 |
+
* @param int $limit - (Optional) Limit.
|
130 |
+
* @return array - Distinct values of IPs.
|
131 |
+
*/
|
132 |
+
public function GetMatchingIPs( $limit = null ) {
|
133 |
+
$_wpdb = $this->connection;
|
134 |
+
$sql = "SELECT DISTINCT value FROM {$this->GetTable()} WHERE name = \"ClientIP\"";
|
135 |
+
if ( ! is_null( $limit ) ) {
|
136 |
+
$sql .= ' LIMIT ' . $limit;
|
137 |
+
}
|
138 |
+
$ips = $_wpdb->get_col( $sql );
|
139 |
+
foreach ( $ips as $key => $ip ) {
|
140 |
+
$ips[ $key ] = str_replace( '"', '', $ip );
|
141 |
+
}
|
142 |
+
return array_unique( $ips );
|
143 |
+
}
|
144 |
}
|
classes/Adapters/MySQL/OccurrenceAdapter.php
CHANGED
@@ -1,253 +1,315 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL database Occurrence class.
|
5 |
*
|
6 |
* MySQL wsal_occurrences table used for to store the alerts.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Adapter: Occurrence.
|
4 |
+
*
|
5 |
+
* MySQL database Occurrence class.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* MySQL database Occurrence class.
|
17 |
*
|
18 |
* MySQL wsal_occurrences table used for to store the alerts.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
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 |
+
* Meta data.
|
40 |
+
*
|
41 |
+
* @var WSAL_Meta
|
42 |
+
*/
|
43 |
+
protected $_meta;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Occurrence id.
|
47 |
+
*
|
48 |
+
* @var int
|
49 |
+
*/
|
50 |
+
public $id = 0;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Site id.
|
54 |
+
*
|
55 |
+
* @var int
|
56 |
+
*/
|
57 |
+
public $site_id = 0;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Alert id.
|
61 |
+
*
|
62 |
+
* @var int
|
63 |
+
*/
|
64 |
+
public $alert_id = 0;
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Created on.
|
68 |
+
*
|
69 |
+
* @var string
|
70 |
+
*/
|
71 |
+
public $created_on = 0.0;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Is read?
|
75 |
+
*
|
76 |
+
* @var bool
|
77 |
+
*/
|
78 |
+
public $is_read = false;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Is migrated?
|
82 |
+
*
|
83 |
+
* @var bool
|
84 |
+
*/
|
85 |
+
public $is_migrated = false;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Method: Constructor.
|
89 |
+
*
|
90 |
+
* @param array $conn - Connection array.
|
91 |
+
*/
|
92 |
+
public function __construct( $conn ) {
|
93 |
+
parent::__construct( $conn );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* SQL table options (constraints, foreign keys, indexes etc).
|
98 |
+
*
|
99 |
+
* @return string
|
100 |
+
*/
|
101 |
+
protected function GetTableOptions() {
|
102 |
+
return parent::GetTableOptions() . ',' . PHP_EOL
|
103 |
+
. ' KEY site_alert_created (site_id,alert_id,created_on)';
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Returns the model class for adapter.
|
108 |
+
*
|
109 |
+
* @return WSAL_Models_Occurrence
|
110 |
+
*/
|
111 |
+
public function GetModel() {
|
112 |
+
return new WSAL_Models_Occurrence();
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Returns metadata related to this event.
|
117 |
+
*
|
118 |
+
* @param object $occurence - Occurrence model instance.
|
119 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
120 |
+
* @return WSAL_Meta
|
121 |
+
*/
|
122 |
+
public function GetMeta( $occurence ) {
|
123 |
+
if ( ! isset( $this->_meta ) ) {
|
124 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
125 |
+
$this->_meta = $meta->Load( 'occurrence_id = %d', array( $occurence->id ) );
|
126 |
+
}
|
127 |
+
return $this->_meta;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Returns allmeta data related to this event.
|
132 |
+
*
|
133 |
+
* @param object $occurence - Occurrence model instance.
|
134 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::LoadArray()
|
135 |
+
* @return WSAL_Meta[]
|
136 |
+
*/
|
137 |
+
public function GetMultiMeta( $occurence ) {
|
138 |
+
if ( ! isset( $this->_meta ) ) {
|
139 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
140 |
+
$this->_meta = $meta->LoadArray( 'occurrence_id = %d', array( $occurence->id ) );
|
141 |
+
}
|
142 |
+
return $this->_meta;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Loads a meta item given its name.
|
147 |
+
*
|
148 |
+
* @param object $occurence - Occurrence model instance.
|
149 |
+
* @param string $name - Meta name.
|
150 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
151 |
+
* @return WSAL_Meta The meta item, be sure to checked if it was loaded successfully.
|
152 |
+
*/
|
153 |
+
public function GetNamedMeta( $occurence, $name ) {
|
154 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
155 |
+
$this->_meta = $meta->Load( 'occurrence_id = %d AND name = %s', array( $occurence->id, $name ) );
|
156 |
+
return $this->_meta;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Returns the first meta value from a given set of names. Useful when you have a mix of items that could provide a particular detail.
|
161 |
+
*
|
162 |
+
* @param object $occurence - Occurrence model instance.
|
163 |
+
* @param array $names - List of meta names.
|
164 |
+
* @return WSAL_Meta The first meta item that exists.
|
165 |
+
*/
|
166 |
+
public function GetFirstNamedMeta( $occurence, $names ) {
|
167 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
168 |
+
$query = '(' . str_repeat( 'name = %s OR ', count( $names ) ) . '0)';
|
169 |
+
$query = 'occurrence_id = %d AND ' . $query . ' ORDER BY name DESC LIMIT 1';
|
170 |
+
array_unshift( $names, $occurence->id ); // Prepend args with occurrence id.
|
171 |
+
|
172 |
+
$this->_meta = $meta->Load( $query, $names );
|
173 |
+
return $meta->getModel()->LoadData( $this->_meta );
|
174 |
+
|
175 |
+
// TO DO: Do we want to reintroduce is loaded check/logic?
|
176 |
+
// return $meta->IsLoaded() ? $meta : null;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Returns newest unique occurrences.
|
181 |
+
*
|
182 |
+
* @param integer $limit Maximum limit.
|
183 |
+
* @return WSAL_Occurrence[]
|
184 |
+
*/
|
185 |
+
public static function GetNewestUnique( $limit = PHP_INT_MAX ) {
|
186 |
+
$temp = new self();
|
187 |
+
return self::LoadMultiQuery('
|
188 |
+
SELECT *, COUNT(alert_id) as count
|
189 |
+
FROM (
|
190 |
+
SELECT *
|
191 |
+
FROM ' . $temp->GetTable() . '
|
192 |
+
ORDER BY created_on DESC
|
193 |
+
) AS temp_table
|
194 |
+
GROUP BY alert_id
|
195 |
+
LIMIT %d
|
196 |
+
', array( $limit )
|
197 |
+
);
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Gets occurences of the same type by IP and Username within specified time frame.
|
202 |
+
*
|
203 |
+
* @param array $args - User arguments.
|
204 |
+
* @return WSAL_Occurrence[]
|
205 |
+
*/
|
206 |
+
public function CheckKnownUsers( $args = array() ) {
|
207 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
208 |
+
return self::LoadMultiQuery(
|
209 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
210 |
+
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
211 |
+
and ipMeta.name = "ClientIP"
|
212 |
+
and ipMeta.value = %s
|
213 |
+
INNER JOIN `' . $tt2->GetTable() . '` usernameMeta on usernameMeta.occurrence_id = occurrence.id
|
214 |
+
and usernameMeta.name = "Username"
|
215 |
+
and usernameMeta.value = %s
|
216 |
+
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
217 |
+
AND (created_on BETWEEN %d AND %d)
|
218 |
+
GROUP BY occurrence.id',
|
219 |
+
$args
|
220 |
+
);
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Gets occurences of the same type by IP within specified time frame.
|
225 |
+
*
|
226 |
+
* @param array $args - User arguments.
|
227 |
+
* @return WSAL_Occurrence[]
|
228 |
+
*/
|
229 |
+
public function CheckUnKnownUsers( $args = array() ) {
|
230 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
231 |
+
return self::LoadMultiQuery(
|
232 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
233 |
+
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
234 |
+
and ipMeta.name = "ClientIP" and ipMeta.value = %s
|
235 |
+
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
236 |
+
AND (created_on BETWEEN %d AND %d)
|
237 |
+
GROUP BY occurrence.id',
|
238 |
+
$args
|
239 |
+
);
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Add conditions to the Query
|
244 |
+
*
|
245 |
+
* @param string $query - Query.
|
246 |
+
*/
|
247 |
+
protected function prepareOccurrenceQuery( $query ) {
|
248 |
+
$search_query_parameters = array();
|
249 |
+
$search_conditions = array();
|
250 |
+
$conditions = $query->getConditions();
|
251 |
+
|
252 |
+
// BUG: not all conditions are occurence related. maybe it's just a field site_id. need seperate arrays.
|
253 |
+
if ( ! empty( $conditions ) ) {
|
254 |
+
$tmp = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
255 |
+
$s_where_clause = '';
|
256 |
+
foreach ( $conditions as $field => $value ) {
|
257 |
+
if ( ! empty( $s_where_clause ) ) {
|
258 |
+
$s_where_clause .= ' AND ';
|
259 |
+
}
|
260 |
+
$s_where_clause .= 'name = %s AND value = %s';
|
261 |
+
$search_query_parameters[] = $field;
|
262 |
+
$search_query_parameters[] = $value;
|
263 |
+
}
|
264 |
+
|
265 |
+
$search_conditions[] = 'id IN (
|
266 |
+
SELECT DISTINCT occurrence_id
|
267 |
+
FROM ' . $tmp->GetTable() . '
|
268 |
+
WHERE ' . $s_where_clause . '
|
269 |
+
)';
|
270 |
+
}
|
271 |
+
|
272 |
+
// Do something with search query parameters and search conditions - give them to the query adapter?
|
273 |
+
return $search_conditions;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Gets occurrence by Post_id.
|
278 |
+
*
|
279 |
+
* @param int $post_id - Post ID.
|
280 |
+
* @return WSAL_Occurrence[]
|
281 |
+
*/
|
282 |
+
public function GetByPostID( $post_id ) {
|
283 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
284 |
+
return self::LoadMultiQuery(
|
285 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '`AS occurrence
|
286 |
+
INNER JOIN `' . $tt2->GetTable() . '`AS postMeta ON postMeta.occurrence_id = occurrence.id
|
287 |
+
and postMeta.name = "PostID"
|
288 |
+
and postMeta.value = %d
|
289 |
+
GROUP BY occurrence.id
|
290 |
+
ORDER BY created_on DESC',
|
291 |
+
array( $post_id )
|
292 |
+
);
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Gets occurences of the same type by IP within specified time frame.
|
297 |
+
*
|
298 |
+
* @param array $args - Query Arguments.
|
299 |
+
* @return WSAL_Occurrence[]
|
300 |
+
*/
|
301 |
+
public function CheckAlert404( $args = array() ) {
|
302 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
303 |
+
return self::LoadMultiQuery(
|
304 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
305 |
+
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
306 |
+
and ipMeta.name = "ClientIP" and ipMeta.value = %s
|
307 |
+
INNER JOIN `' . $tt2->GetTable() . '` usernameMeta on usernameMeta.occurrence_id = occurrence.id
|
308 |
+
and usernameMeta.name = "Username" and usernameMeta.value = %s
|
309 |
+
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
310 |
+
AND (created_on BETWEEN %d AND %d)
|
311 |
+
GROUP BY occurrence.id',
|
312 |
+
$args
|
313 |
+
);
|
314 |
+
}
|
315 |
}
|
classes/Adapters/MySQL/OptionAdapter.php
CHANGED
@@ -1,116 +1,169 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL database Option class.
|
5 |
*
|
6 |
* MySQL wsal_options table used for to store the plugin settings and Add-Ons settings.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Adapters_MySQL_Option extends WSAL_Adapters_MySQL_ActiveRecord
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Adapter: Option.
|
4 |
+
*
|
5 |
+
* MySQL database Option class.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* MySQL database Option class.
|
17 |
*
|
18 |
* MySQL wsal_options table used for to store the plugin settings and Add-Ons settings.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Adapters_MySQL_Option extends WSAL_Adapters_MySQL_ActiveRecord {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Contains the table name.
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
protected $_table = 'wsal_options';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Contains primary key column name, override as required.
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
protected $_idkey = 'id';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Option id.
|
40 |
+
*
|
41 |
+
* @var int
|
42 |
+
*/
|
43 |
+
public $id = 0;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Option name.
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
public $option_name = '';
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Option name max length.
|
54 |
+
*
|
55 |
+
* @var int
|
56 |
+
*/
|
57 |
+
public static $option_name_maxlength = 100;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Option value.
|
61 |
+
*
|
62 |
+
* @var mix
|
63 |
+
*/
|
64 |
+
public $option_value = '';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Method: Constructor.
|
68 |
+
*
|
69 |
+
* @param array $conn - Connection array.
|
70 |
+
*/
|
71 |
+
public function __construct( $conn ) {
|
72 |
+
parent::__construct( $conn );
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Returns the model class for adapter.
|
77 |
+
*
|
78 |
+
* @return WSAL_Models_Occurrence
|
79 |
+
*/
|
80 |
+
public function GetModel() {
|
81 |
+
return new WSAL_Models_Option();
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Get option by name.
|
86 |
+
*
|
87 |
+
* @param string $name - Option name.
|
88 |
+
* @return string|null - Option value.
|
89 |
+
*/
|
90 |
+
public function GetNamedOption( $name ) {
|
91 |
+
if ( $this->IsInstalled() ) {
|
92 |
+
return $this->Load( 'option_name = %s', array( $name ) );
|
93 |
+
} else {
|
94 |
+
return null;
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Get options by prefix (notifications stored in json format).
|
100 |
+
*
|
101 |
+
* @param string $opt_prefix - Prefix.
|
102 |
+
* @return array|null - Options.
|
103 |
+
*/
|
104 |
+
public function GetNotificationsSetting( $opt_prefix ) {
|
105 |
+
if ( $this->IsInstalled() ) {
|
106 |
+
return $this->LoadArray( 'option_name LIKE %s', array( $opt_prefix . '%' ) );
|
107 |
+
} else {
|
108 |
+
return null;
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Get option by id (notifications stored in json format).
|
114 |
+
*
|
115 |
+
* @param int $id - Option ID.
|
116 |
+
* @return string|null - Option.
|
117 |
+
*/
|
118 |
+
public function GetNotification( $id ) {
|
119 |
+
if ( $this->IsInstalled() ) {
|
120 |
+
return $this->Load( 'id = %d', array( $id ) );
|
121 |
+
} else {
|
122 |
+
return null;
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Delete option by name.
|
128 |
+
*
|
129 |
+
* @param string $name - Option name.
|
130 |
+
* @return boolean.
|
131 |
+
*/
|
132 |
+
public function DeleteByName( $name ) {
|
133 |
+
if ( ! empty( $name ) ) {
|
134 |
+
$sql = 'DELETE FROM ' . $this->GetTable() . " WHERE option_name = '" . $name . "'";
|
135 |
+
// Execute query.
|
136 |
+
return parent::DeleteQuery( $sql );
|
137 |
+
} else {
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Delete options start with prefix.
|
144 |
+
*
|
145 |
+
* @param string $opt_prefix - Prefix.
|
146 |
+
* @return boolean.
|
147 |
+
*/
|
148 |
+
public function DeleteByPrefix( $opt_prefix ) {
|
149 |
+
if ( ! empty( $opt_prefix ) ) {
|
150 |
+
$sql = 'DELETE FROM ' . $this->GetTable() . " WHERE option_name LIKE '" . $opt_prefix . "%'";
|
151 |
+
// Execute query.
|
152 |
+
return parent::DeleteQuery( $sql );
|
153 |
+
} else {
|
154 |
+
return false;
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Number of options start with prefix.
|
160 |
+
*
|
161 |
+
* @param string $opt_prefix - Prefix.
|
162 |
+
* @return integer Indicates the number of items.
|
163 |
+
*/
|
164 |
+
public function CountNotifications( $opt_prefix ) {
|
165 |
+
$_wpdb = $this->connection;
|
166 |
+
$sql = 'SELECT COUNT(id) FROM ' . $this->GetTable() . " WHERE option_name LIKE '" . $opt_prefix . "%'";
|
167 |
+
return (int) $_wpdb->get_var( $sql );
|
168 |
+
}
|
169 |
}
|
classes/Adapters/MySQL/QueryAdapter.php
CHANGED
@@ -1,269 +1,292 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL database Query class.
|
5 |
*
|
6 |
* The SQL query is created in this class, here the SQL is filled with
|
7 |
* the arguments.
|
|
|
|
|
8 |
*/
|
9 |
-
class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
|
|
|
|
|
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
|
116 |
-
|
117 |
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
|
137 |
-
|
138 |
-
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
|
208 |
-
|
209 |
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
|
221 |
-
|
222 |
-
|
223 |
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
|
241 |
-
|
242 |
-
|
243 |
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Adapter: Query.
|
4 |
+
*
|
5 |
+
* MySQL database Query class.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* MySQL database Query class.
|
17 |
*
|
18 |
* The SQL query is created in this class, here the SQL is filled with
|
19 |
* the arguments.
|
20 |
+
*
|
21 |
+
* @package Wsal
|
22 |
*/
|
23 |
+
class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* DB Connection
|
27 |
+
*
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
protected $connection;
|
31 |
|
32 |
+
/**
|
33 |
+
* Method: Constructor.
|
34 |
+
*
|
35 |
+
* @param array $conn - Connection array.
|
36 |
+
*/
|
37 |
+
public function __construct( $conn ) {
|
38 |
+
$this->connection = $conn;
|
39 |
+
}
|
40 |
|
41 |
+
/**
|
42 |
+
* Get the SQL filled with the args.
|
43 |
+
*
|
44 |
+
* @param object $query - Query object.
|
45 |
+
* @param array $args - Args of the query.
|
46 |
+
* @return string Generated sql.
|
47 |
+
*/
|
48 |
+
protected function GetSql( $query, &$args = array() ) {
|
49 |
+
$conditions = $query->getConditions();
|
50 |
+
$search_condition = $this->SearchCondition( $query );
|
51 |
+
$s_where_clause = '';
|
52 |
+
foreach ( $conditions as $field_name => $field_value ) {
|
53 |
+
if ( empty( $s_where_clause ) ) {
|
54 |
+
$s_where_clause .= ' WHERE ';
|
55 |
+
} else {
|
56 |
+
$s_where_clause .= ' AND ';
|
57 |
+
}
|
58 |
|
59 |
+
if ( is_array( $field_value ) ) {
|
60 |
+
$sub_where_clause = '(';
|
61 |
+
foreach ( $field_value as $or_field_name => $or_field_value ) {
|
62 |
+
if ( is_array( $or_field_value ) ) {
|
63 |
+
foreach ( $or_field_value as $value ) {
|
64 |
+
if ( '(' != $sub_where_clause ) {
|
65 |
+
$sub_where_clause .= ' OR ';
|
66 |
+
}
|
67 |
+
$sub_where_clause .= $or_field_name;
|
68 |
+
$args[] = $value;
|
69 |
+
}
|
70 |
+
} else {
|
71 |
+
if ( '(' != $sub_where_clause ) {
|
72 |
+
$sub_where_clause .= ' OR ';
|
73 |
+
}
|
74 |
+
$sub_where_clause .= $or_field_name;
|
75 |
+
$args[] = $or_field_value;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
$sub_where_clause .= ')';
|
79 |
+
$s_where_clause .= $sub_where_clause;
|
80 |
+
} else {
|
81 |
+
$s_where_clause .= $field_name;
|
82 |
+
$args[] = $field_value;
|
83 |
+
}
|
84 |
+
}
|
85 |
|
86 |
+
$from_data_sets = $query->getFrom();
|
87 |
+
$columns = $query->getColumns();
|
88 |
+
$order_bys = $query->getOrderBy();
|
89 |
|
90 |
+
$s_limit_clause = '';
|
91 |
+
if ( $query->getLimit() ) {
|
92 |
+
$s_limit_clause .= ' LIMIT ';
|
93 |
+
if ( $query->getOffset() ) {
|
94 |
+
$s_limit_clause .= $query->getOffset() . ', ';
|
95 |
+
}
|
96 |
+
$s_limit_clause .= $query->getLimit();
|
97 |
+
}
|
98 |
+
$join_clause = '';
|
99 |
+
if ( $query->hasMetaJoin() ) {
|
100 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
101 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
102 |
+
$join_clause = ' LEFT JOIN ' . $meta->GetTable() . ' AS meta ON meta.occurrence_id = ' . $occurrence->GetTable() . '.id ';
|
103 |
+
}
|
104 |
+
$fields = (empty( $columns )) ? $from_data_sets[0] . '.*' : implode( ',', $columns );
|
105 |
+
if ( ! empty( $search_condition ) ) {
|
106 |
+
$args[] = $search_condition['args'];
|
107 |
+
}
|
108 |
|
109 |
+
$sql = 'SELECT ' . $fields
|
110 |
+
. ' FROM ' . implode( ',', $from_data_sets )
|
111 |
+
. $join_clause
|
112 |
+
. $s_where_clause
|
113 |
+
. ( ! empty( $search_condition ) ? (empty( $s_where_clause ) ? ' WHERE ' . $search_condition['sql'] : ' AND ' . $search_condition['sql']) : '')
|
114 |
+
// @todo GROUP BY goes here
|
115 |
+
. ( ! empty( $order_bys ) ? (' ORDER BY ' . implode( ', ', array_keys( $order_bys ) ) . ' ' . implode( ', ', array_values( $order_bys ) )) : '')
|
116 |
+
. $s_limit_clause;
|
117 |
+
return $sql;
|
118 |
+
}
|
119 |
|
120 |
+
/**
|
121 |
+
* Get an instance of the ActiveRecord Adapter.
|
122 |
+
*
|
123 |
+
* @return WSAL_Adapters_MySQL_ActiveRecord
|
124 |
+
*/
|
125 |
+
protected function getActiveRecordAdapter() {
|
126 |
+
return new WSAL_Adapters_MySQL_ActiveRecord( $this->connection );
|
127 |
+
}
|
128 |
|
129 |
+
/**
|
130 |
+
* Execute query and return data as $ar_cls objects.
|
131 |
+
*
|
132 |
+
* @param object $query - Query object.
|
133 |
+
* @return WSAL_Models_ActiveRecord[]
|
134 |
+
*/
|
135 |
+
public function Execute( $query ) {
|
136 |
+
$args = array();
|
137 |
+
$sql = $this->GetSql( $query, $args );
|
138 |
|
139 |
+
$occurence_adapter = $query->getConnector()->getAdapter( 'Occurrence' );
|
140 |
|
141 |
+
if ( in_array( $occurence_adapter->GetTable(), $query->getFrom() ) ) {
|
142 |
+
return $occurence_adapter->LoadMulti( $sql, $args );
|
143 |
+
} else {
|
144 |
+
return $this->getActiveRecordAdapter()->LoadMulti( $sql, $args );
|
145 |
+
}
|
146 |
+
}
|
147 |
|
148 |
+
/**
|
149 |
+
* Count query
|
150 |
+
*
|
151 |
+
* @param object $query - Query object.
|
152 |
+
* @return integer counting records.
|
153 |
+
*/
|
154 |
+
public function Count( $query ) {
|
155 |
+
// Back up columns, use COUNT as default column and generate sql.
|
156 |
+
$cols = $query->getColumns();
|
157 |
+
$query->clearColumns();
|
158 |
+
$query->addColumn( 'COUNT(*)' );
|
159 |
|
160 |
+
$args = array();
|
161 |
+
$sql = $this->GetSql( $query, $args );
|
162 |
|
163 |
+
// Restore columns.
|
164 |
+
$query->setColumns( $cols );
|
165 |
+
// Execute query and return result.
|
166 |
+
return $this->getActiveRecordAdapter()->CountQuery( $sql, $args );
|
167 |
+
}
|
168 |
|
169 |
+
/**
|
170 |
+
* Count DELETE query
|
171 |
+
*
|
172 |
+
* @param object $query - Query object.
|
173 |
+
* @return integer counting records.
|
174 |
+
*/
|
175 |
+
public function CountDelete( $query ) {
|
176 |
+
$result = $this->GetSqlDelete( $query, true );
|
177 |
+
// Execute query and return result.
|
178 |
+
return $this->getActiveRecordAdapter()->CountQuery( $result['sql'], $result['args'] );
|
179 |
+
}
|
180 |
|
181 |
+
/**
|
182 |
+
* Query for deleting records
|
183 |
+
*
|
184 |
+
* @param object $query query object.
|
185 |
+
*/
|
186 |
+
public function Delete( $query ) {
|
187 |
+
$result = $this->GetSqlDelete( $query );
|
188 |
+
$this->DeleteMetas( $query, $result['args'] );
|
189 |
+
return $this->getActiveRecordAdapter()->DeleteQuery( $result['sql'], $result['args'] );
|
190 |
+
}
|
191 |
|
192 |
+
/**
|
193 |
+
* Load occurrence IDs then delete Metadata by occurrence_id
|
194 |
+
*
|
195 |
+
* @param object $query - Query object.
|
196 |
+
* @param array $args - Args of the query.
|
197 |
+
*/
|
198 |
+
public function DeleteMetas( $query, $args ) {
|
199 |
+
// Back up columns, use COUNT as default column and generate sql.
|
200 |
+
$cols = $query->getColumns();
|
201 |
+
$query->clearColumns();
|
202 |
+
$query->addColumn( 'id' );
|
203 |
+
$sql = $this->GetSql( $query );
|
204 |
+
// Restore columns.
|
205 |
+
$query->setColumns( $cols );
|
206 |
|
207 |
+
$_wpdb = $this->connection;
|
208 |
+
$occ_ids = array();
|
209 |
+
$sql = ( ! empty( $args ) ? $_wpdb->prepare( $sql, $args ) : $sql);
|
210 |
+
foreach ( $_wpdb->get_results( $sql, ARRAY_A ) as $data ) {
|
211 |
+
$occ_ids[] = $data['id'];
|
212 |
+
}
|
213 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
214 |
+
$meta->DeleteByOccurenceIds( $occ_ids );
|
215 |
+
}
|
216 |
|
217 |
+
/**
|
218 |
+
* Get the DELETE query SQL filled with the args.
|
219 |
+
*
|
220 |
+
* @param object $query - Query object.
|
221 |
+
* @param bool $get_count - Get count.
|
222 |
+
* @return string - Generated sql.
|
223 |
+
*/
|
224 |
+
public function GetSqlDelete( $query, $get_count = false ) {
|
225 |
+
$result = array();
|
226 |
+
$args = array();
|
227 |
+
// Back up columns, remove them for DELETE and generate sql.
|
228 |
+
$cols = $query->getColumns();
|
229 |
+
$query->clearColumns();
|
230 |
|
231 |
+
$conditions = $query->getConditions();
|
232 |
|
233 |
+
$s_where_clause = '';
|
234 |
+
foreach ( $conditions as $field_name => $field_value ) {
|
235 |
+
if ( empty( $s_where_clause ) ) {
|
236 |
+
$s_where_clause .= ' WHERE ';
|
237 |
+
} else {
|
238 |
+
$s_where_clause .= ' AND ';
|
239 |
+
}
|
240 |
+
$s_where_clause .= $field_name;
|
241 |
+
$args[] = $field_value;
|
242 |
+
}
|
243 |
|
244 |
+
$from_data_sets = $query->getFrom();
|
245 |
+
$order_bys = $query->getOrderBy();
|
246 |
|
247 |
+
$s_limit_clause = '';
|
248 |
+
if ( $query->getLimit() ) {
|
249 |
+
$s_limit_clause .= ' LIMIT ';
|
250 |
+
if ( $query->getOffset() ) {
|
251 |
+
$s_limit_clause .= $query->getOffset() . ', ';
|
252 |
+
}
|
253 |
+
$s_limit_clause .= $query->getLimit();
|
254 |
+
}
|
255 |
+
$result['sql'] = ($get_count ? 'SELECT COUNT(*) FROM ' : 'DELETE FROM ')
|
256 |
+
. implode( ',', $from_data_sets )
|
257 |
+
. $s_where_clause
|
258 |
+
. ( ! empty( $order_bys ) ? (' ORDER BY ' . implode( ', ', array_keys( $order_bys ) ) . ' ' . implode( ', ', array_values( $order_bys ) )) : '')
|
259 |
+
. $s_limit_clause;
|
260 |
+
$result['args'] = $args;
|
261 |
+
// Restore columns.
|
262 |
+
$query->setColumns( $cols );
|
263 |
|
264 |
+
return $result;
|
265 |
+
}
|
266 |
|
267 |
+
/**
|
268 |
+
* Search by alert code OR by Metadata value.
|
269 |
+
*
|
270 |
+
* @param object $query - Query object.
|
271 |
+
*/
|
272 |
+
public function SearchCondition( $query ) {
|
273 |
+
$condition = $query->getSearchCondition();
|
274 |
+
if ( empty( $condition ) ) {
|
275 |
+
return null;
|
276 |
+
}
|
277 |
+
$search_conditions = array();
|
278 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $this->connection );
|
279 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $this->connection );
|
280 |
+
if ( is_numeric( $condition ) && strlen( $condition ) == 4 ) {
|
281 |
+
$search_conditions['sql'] = $occurrence->GetTable() . '.alert_id LIKE %s';
|
282 |
+
} else {
|
283 |
+
$search_conditions['sql'] = $occurrence->GetTable() . '.id IN (
|
284 |
+
SELECT DISTINCT occurrence_id
|
285 |
+
FROM ' . $meta->GetTable() . '
|
286 |
+
WHERE TRIM(BOTH "\"" FROM value) LIKE %s
|
287 |
+
)';
|
288 |
+
}
|
289 |
+
$search_conditions['args'] = '%' . $condition . '%';
|
290 |
+
return $search_conditions;
|
291 |
+
}
|
292 |
}
|
classes/Adapters/MySQL/TmpUserAdapter.php
CHANGED
@@ -1,45 +1,71 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL database TmpUser class.
|
5 |
*
|
6 |
* This class is used for create a temporary table to store the WP users
|
7 |
* when the External DB Add-On is activated and the Alerts are stored on an external DB
|
8 |
* because the query between plugin tables and the internal wp_uses table is not possible.
|
9 |
-
*
|
|
|
|
|
10 |
*/
|
11 |
class WSAL_Adapters_MySQL_TmpUser extends WSAL_Adapters_MySQL_ActiveRecord {
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
$table_name = ($prefix) ? $this->GetWPTable() : $this->GetTable();
|
35 |
-
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
36 |
-
$sql .= 'ID BIGINT NOT NULL,' . PHP_EOL;
|
37 |
-
$sql .= 'user_login VARCHAR(60) NOT NULL,' . PHP_EOL;
|
38 |
-
$sql .= 'INDEX (ID)' . PHP_EOL;
|
39 |
-
$sql .= ')';
|
40 |
-
if (!empty($_wpdb->charset)) {
|
41 |
-
$sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
|
42 |
-
}
|
43 |
-
return $sql;
|
44 |
-
}
|
45 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Adapter: Meta data.
|
4 |
+
*
|
5 |
+
* MySQL database Metadata class.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* MySQL database TmpUser class.
|
17 |
*
|
18 |
* This class is used for create a temporary table to store the WP users
|
19 |
* when the External DB Add-On is activated and the Alerts are stored on an external DB
|
20 |
* because the query between plugin tables and the internal wp_uses table is not possible.
|
21 |
+
*
|
22 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord->GetReportGrouped()
|
23 |
+
* @package Wsal
|
24 |
*/
|
25 |
class WSAL_Adapters_MySQL_TmpUser extends WSAL_Adapters_MySQL_ActiveRecord {
|
26 |
|
27 |
+
/**
|
28 |
+
* Contains the table name.
|
29 |
+
*
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
protected $_table = 'wsal_tmp_users';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Returns the model class for adapter.
|
36 |
+
*
|
37 |
+
* @return WSAL_Models_TmpUser
|
38 |
+
*/
|
39 |
+
public function GetModel() {
|
40 |
+
return new WSAL_Models_TmpUser();
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Method: Constructor.
|
45 |
+
*
|
46 |
+
* @param array $conn - Connection array.
|
47 |
+
*/
|
48 |
+
public function __construct( $conn ) {
|
49 |
+
parent::__construct( $conn );
|
50 |
+
}
|
51 |
|
52 |
+
/**
|
53 |
+
* Must return SQL for creating table.
|
54 |
+
*
|
55 |
+
* @param mix $prefix - Prefix.
|
56 |
+
* @return string
|
57 |
+
*/
|
58 |
+
protected function _GetInstallQuery( $prefix = false ) {
|
59 |
+
$_wpdb = $this->connection;
|
60 |
+
$table_name = ($prefix) ? $this->GetWPTable() : $this->GetTable();
|
61 |
+
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
62 |
+
$sql .= 'ID BIGINT NOT NULL,' . PHP_EOL;
|
63 |
+
$sql .= 'user_login VARCHAR(60) NOT NULL,' . PHP_EOL;
|
64 |
+
$sql .= 'INDEX (ID)' . PHP_EOL;
|
65 |
+
$sql .= ')';
|
66 |
+
if ( ! empty( $_wpdb->charset ) ) {
|
67 |
+
$sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
|
68 |
+
}
|
69 |
+
return $sql;
|
70 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
}
|
classes/Adapters/OccurrenceInterface.php
CHANGED
@@ -1,15 +1,67 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* Interface used by the Occurrence.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*/
|
7 |
-
interface WSAL_Adapters_OccurrenceInterface
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Occurrence Interface.
|
4 |
*
|
5 |
* Interface used by the Occurrence.
|
6 |
+
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Interface used by the Occurrence.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
interface WSAL_Adapters_OccurrenceInterface {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Get Meta.
|
24 |
+
*
|
25 |
+
* @param object $occurence - Instance of occurence object.
|
26 |
+
*/
|
27 |
+
public function GetMeta( $occurence );
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Loads a meta item given its name.
|
31 |
+
*
|
32 |
+
* @param object $occurence - Instance of occurence object.
|
33 |
+
* @param string $name - Meta name.
|
34 |
+
*/
|
35 |
+
public function GetNamedMeta( $occurence, $name );
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Returns the first meta value from a given set of names.
|
39 |
+
* Useful when you have a mix of items that could provide
|
40 |
+
* a particular detail.
|
41 |
+
*
|
42 |
+
* @param object $occurence - Instance of occurence object.
|
43 |
+
* @param array $names - List of Meta names.
|
44 |
+
*/
|
45 |
+
public function GetFirstNamedMeta( $occurence, $names );
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Returns newest unique occurrences.
|
49 |
+
*
|
50 |
+
* @param integer $limit - Maximum limit.
|
51 |
+
*/
|
52 |
+
public static function GetNewestUnique( $limit = PHP_INT_MAX );
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Gets occurences of the same type by IP and Username within specified time frame.
|
56 |
+
*
|
57 |
+
* @param array $args - Arguments.
|
58 |
+
*/
|
59 |
+
public function CheckKnownUsers( $args = array() );
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Gets occurences of the same type by IP within specified time frame.
|
63 |
+
*
|
64 |
+
* @param array $args - Arguments.
|
65 |
+
*/
|
66 |
+
public function CheckUnKnownUsers( $args = array() );
|
67 |
}
|
classes/Adapters/QueryInterface.php
CHANGED
@@ -1,12 +1,42 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* Interface used by the Query.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*/
|
7 |
-
interface WSAL_Adapters_QueryInterface
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Query Interface.
|
4 |
*
|
5 |
* Interface used by the Query.
|
6 |
+
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Interface used by the Query.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
interface WSAL_Adapters_QueryInterface {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Execute query and return data as $ar_cls objects.
|
24 |
+
*
|
25 |
+
* @param object $query - Query object.
|
26 |
+
*/
|
27 |
+
public function Execute( $query );
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Count query.
|
31 |
+
*
|
32 |
+
* @param object $query - Query object.
|
33 |
+
*/
|
34 |
+
public function Count( $query );
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Query for deleting records.
|
38 |
+
*
|
39 |
+
* @param object $query - Query object.
|
40 |
+
*/
|
41 |
+
public function Delete( $query );
|
42 |
}
|
classes/Alert.php
CHANGED
@@ -1,119 +1,133 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* WSAL_Alert Object class.
|
|
|
|
|
6 |
*/
|
7 |
-
final class WSAL_Alert
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Alert message (variables between '%' are expanded to values).
|
41 |
-
* @var string
|
42 |
-
*/
|
43 |
-
public $mesg = '';
|
44 |
-
|
45 |
-
public function __construct($type = 0, $code = 0, $catg = '', $subcatg = '', $desc = '', $mesg = '')
|
46 |
-
{
|
47 |
-
$this->type = $type;
|
48 |
-
$this->code = $code;
|
49 |
-
$this->catg = $catg;
|
50 |
-
$this->subcatg = $subcatg;
|
51 |
-
$this->desc = $desc;
|
52 |
-
$this->mesg = $mesg;
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Retrieves a value for a particular meta variable expression.
|
57 |
-
* @param string $expr Expression, eg: User->Name looks for a Name property for meta named User.
|
58 |
-
* @param array $metaData (Optional) Meta data relevant to expression.
|
59 |
-
* @return mixed The value nearest to the expression.
|
60 |
-
*/
|
61 |
-
protected function GetMetaExprValue($expr, $metaData = array())
|
62 |
-
{
|
63 |
-
// TODO Handle function calls (and methods?)
|
64 |
-
$expr = explode('->', $expr);
|
65 |
-
$meta = array_shift($expr);
|
66 |
-
$meta = isset($metaData[$meta]) ? $metaData[$meta] : null;
|
67 |
-
foreach ($expr as $part) {
|
68 |
-
if (is_scalar($meta) || is_null($meta)) {
|
69 |
-
return $meta; // this isn't 100% correct
|
70 |
-
}
|
71 |
-
$meta = is_array($meta) ? $meta[$part] : $meta->$part;
|
72 |
-
}
|
73 |
-
return is_scalar($meta) ? (string)$meta : var_export($meta, true);
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Expands a message with variables by replacing variables with meta data values.
|
78 |
-
* @param string $mesg The original message.
|
79 |
-
* @param array $metaData (Optional) Meta data relevant to message.
|
80 |
-
* @param callable|null $metaFormatter (Optional) Callback for formatting meta values.
|
81 |
-
* @param string $afterMeta (Optional) Some text to put after meta values.
|
82 |
-
* @return string The expanded message.
|
83 |
-
*/
|
84 |
-
protected function GetFormattedMesg($origMesg, $metaData = array(), $metaFormatter = null)
|
85 |
-
{
|
86 |
-
// tokenize message with regex
|
87 |
-
$mesg = preg_split('/(%.*?%)/', (string)$origMesg, -1, PREG_SPLIT_DELIM_CAPTURE);
|
88 |
-
if (!is_array($mesg)) {
|
89 |
-
return (string)$origMesg;
|
90 |
-
}
|
91 |
-
// handle tokenized message
|
92 |
-
foreach ($mesg as $i => $token) {
|
93 |
-
// handle escaped percent sign
|
94 |
-
if ($token == '%%') {
|
95 |
-
$mesg[$i] = '%';
|
96 |
-
} else if (substr($token, 0, 1) == '%' && substr($token, -1, 1) == '%') {
|
97 |
-
// handle complex expressions
|
98 |
-
$mesg[$i] = $this->GetMetaExprValue(substr($token, 1, -1), $metaData);
|
99 |
-
if ($metaFormatter) {
|
100 |
-
$mesg[$i] = call_user_func($metaFormatter, $token, $mesg[$i]);
|
101 |
-
}
|
102 |
-
}
|
103 |
-
}
|
104 |
-
// compact message and return
|
105 |
-
return implode('', $mesg);
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Gets alert message.
|
110 |
-
* @param array $metaData (Optional) Meta data relevant to message.
|
111 |
-
* @param callable|null $metaFormatter (Optional) Meta formatter callback.
|
112 |
-
* @param string|null $mesg (Optional) Override message template to use.
|
113 |
-
* @return string Fully formatted message.
|
114 |
-
*/
|
115 |
-
public function GetMessage($metaData = array(), $metaFormatter = null, $mesg = null)
|
116 |
-
{
|
117 |
-
return $this->GetFormattedMesg(is_null($mesg) ? $this->mesg : $mesg, $metaData, $metaFormatter);
|
118 |
-
}
|
119 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* WSAL_Alert Object class.
|
4 |
+
*
|
5 |
+
* @package Wsal
|
6 |
*/
|
7 |
+
final class WSAL_Alert {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Alert type (used when triggering an alert etc).
|
11 |
+
*
|
12 |
+
* @var integer
|
13 |
+
*/
|
14 |
+
public $type = 0;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Alert error level (E_* constant).
|
18 |
+
*
|
19 |
+
* @var integer
|
20 |
+
*/
|
21 |
+
public $code = 0;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Alert category (alerts are grouped by matching categories).
|
25 |
+
*
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
public $catg = '';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Alert sub category.
|
32 |
+
*
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
public $subcatg = '';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Alert description (ie, describes what happens when alert is triggered).
|
39 |
+
*
|
40 |
+
* @var string
|
41 |
+
*/
|
42 |
+
public $desc = '';
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Alert message (variables between '%' are expanded to values).
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
public $mesg = '';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Method: Constructor.
|
53 |
+
*
|
54 |
+
* @param integer $type - Type of alert.
|
55 |
+
* @param integer $code - Code of alert.
|
56 |
+
* @param string $catg - Category of alert.
|
57 |
+
* @param string $subcatg - Subcategory of alert.
|
58 |
+
* @param string $desc - Description.
|
59 |
+
* @param string $mesg - Alert message.
|
60 |
+
*/
|
61 |
+
public function __construct( $type = 0, $code = 0, $catg = '', $subcatg = '', $desc = '', $mesg = '' ) {
|
62 |
+
$this->type = $type;
|
63 |
+
$this->code = $code;
|
64 |
+
$this->catg = $catg;
|
65 |
+
$this->subcatg = $subcatg;
|
66 |
+
$this->desc = $desc;
|
67 |
+
$this->mesg = $mesg;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Retrieves a value for a particular meta variable expression.
|
72 |
+
*
|
73 |
+
* @param string $expr Expression, eg: User->Name looks for a Name property for meta named User.
|
74 |
+
* @param array $meta_data (Optional) Meta data relevant to expression.
|
75 |
+
* @return mixed The value nearest to the expression.
|
76 |
+
*/
|
77 |
+
protected function GetMetaExprValue( $expr, $meta_data = array() ) {
|
78 |
+
// TODO: Handle function calls (and methods?).
|
79 |
+
$expr = explode( '->', $expr );
|
80 |
+
$meta = array_shift( $expr );
|
81 |
+
$meta = isset( $meta_data[ $meta ] ) ? $meta_data[ $meta ] : null;
|
82 |
+
foreach ( $expr as $part ) {
|
83 |
+
if ( is_scalar( $meta ) || is_null( $meta ) ) {
|
84 |
+
return $meta; // This isn't 100% correct.
|
85 |
+
}
|
86 |
+
$meta = is_array( $meta ) ? $meta[ $part ] : $meta->$part;
|
87 |
+
}
|
88 |
+
return is_scalar( $meta ) ? (string) $meta : var_export( $meta, true );
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Expands a message with variables by replacing variables with meta data values.
|
93 |
+
*
|
94 |
+
* @param string $orig_mesg The original message.
|
95 |
+
* @param array $meta_data (Optional) Meta data relevant to message.
|
96 |
+
* @param callable|null $meta_formatter (Optional) Callback for formatting meta values.
|
97 |
+
* @return string The expanded message.
|
98 |
+
*/
|
99 |
+
protected function GetFormattedMesg( $orig_mesg, $meta_data = array(), $meta_formatter = null ) {
|
100 |
+
// Tokenize message with regex.
|
101 |
+
$mesg = preg_split( '/(%.*?%)/', (string) $orig_mesg, -1, PREG_SPLIT_DELIM_CAPTURE );
|
102 |
+
if ( ! is_array( $mesg ) ) {
|
103 |
+
return (string) $orig_mesg;
|
104 |
+
}
|
105 |
+
// Handle tokenized message.
|
106 |
+
foreach ( $mesg as $i => $token ) {
|
107 |
+
// Handle escaped percent sign.
|
108 |
+
if ( '%%' == $token ) {
|
109 |
+
$mesg[ $i ] = '%';
|
110 |
+
} elseif ( substr( $token, 0, 1 ) == '%' && substr( $token, -1, 1 ) == '%' ) {
|
111 |
+
// Handle complex expressions.
|
112 |
+
$mesg[ $i ] = $this->GetMetaExprValue( substr( $token, 1, -1 ), $meta_data );
|
113 |
+
if ( $meta_formatter ) {
|
114 |
+
$mesg[ $i ] = call_user_func( $meta_formatter, $token, $mesg[ $i ] );
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
// Compact message and return.
|
119 |
+
return implode( '', $mesg );
|
120 |
+
}
|
121 |
|
122 |
+
/**
|
123 |
+
* Gets alert message.
|
124 |
+
*
|
125 |
+
* @param array $meta_data (Optional) Meta data relevant to message.
|
126 |
+
* @param callable|null $meta_formatter (Optional) Meta formatter callback.
|
127 |
+
* @param string|null $mesg (Optional) Override message template to use.
|
128 |
+
* @return string Fully formatted message.
|
129 |
+
*/
|
130 |
+
public function GetMessage( $meta_data = array(), $meta_formatter = null, $mesg = null ) {
|
131 |
+
return $this->GetFormattedMesg( is_null( $mesg ) ? $this->mesg : $mesg, $meta_data, $meta_formatter );
|
132 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
classes/AlertManager.php
CHANGED
@@ -1,89 +1,97 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* WSAL_AlertManager class.
|
6 |
* It is the actual trigger for the alerts.
|
|
|
|
|
7 |
*/
|
8 |
-
final class WSAL_AlertManager
|
9 |
-
|
10 |
/**
|
11 |
-
*
|
|
|
|
|
12 |
*/
|
13 |
protected $_alerts = array();
|
14 |
|
15 |
/**
|
16 |
-
*
|
|
|
|
|
17 |
*/
|
18 |
protected $_loggers = array();
|
19 |
|
20 |
/**
|
21 |
-
*
|
|
|
|
|
22 |
*/
|
23 |
protected $plugin;
|
24 |
|
25 |
/**
|
26 |
* Contains a list of alerts to trigger.
|
|
|
27 |
* @var array
|
28 |
*/
|
29 |
protected $_pipeline = array();
|
30 |
|
31 |
/**
|
32 |
* Contains an array of alerts that have been triggered for this request.
|
|
|
33 |
* @var int[]
|
34 |
*/
|
35 |
protected $_triggered_types = array();
|
36 |
|
37 |
/**
|
38 |
* Create new AlertManager instance.
|
39 |
-
*
|
|
|
40 |
*/
|
41 |
-
public function __construct(WpSecurityAuditLog $plugin)
|
42 |
-
{
|
43 |
$this->plugin = $plugin;
|
44 |
-
foreach (glob(dirname(__FILE__) . '/Loggers/*.php') as $file) {
|
45 |
-
$this->AddFromFile($file);
|
46 |
}
|
47 |
|
48 |
-
add_action('shutdown', array($this, '_CommitPipeline'));
|
49 |
}
|
50 |
|
51 |
/**
|
52 |
* Add new logger from file inside autoloader path.
|
|
|
53 |
* @param string $file Path to file.
|
54 |
*/
|
55 |
-
public function AddFromFile($file)
|
56 |
-
|
57 |
-
$this->AddFromClass($this->plugin->GetClassFileClassName($file));
|
58 |
}
|
59 |
|
60 |
/**
|
61 |
* Add new logger given class name.
|
|
|
62 |
* @param string $class Class name.
|
63 |
*/
|
64 |
-
public function AddFromClass($class)
|
65 |
-
|
66 |
-
$this->AddInstance(new $class($this->plugin));
|
67 |
}
|
68 |
|
69 |
/**
|
70 |
* Add newly created logger to list.
|
|
|
71 |
* @param WSAL_AbstractLogger $logger The new logger.
|
72 |
*/
|
73 |
-
public function AddInstance(WSAL_AbstractLogger $logger)
|
74 |
-
{
|
75 |
$this->_loggers[] = $logger;
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
* Remove logger by class name.
|
|
|
80 |
* @param string $class The class name.
|
81 |
*/
|
82 |
-
public function RemoveByClass($class)
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
unset($this->_loggers[$i]);
|
87 |
}
|
88 |
}
|
89 |
}
|
@@ -93,7 +101,7 @@ final class WSAL_AlertManager
|
|
93 |
*
|
94 |
* @param integer $type Alert type.
|
95 |
* @param array $data Alert data.
|
96 |
-
* @param bool
|
97 |
*/
|
98 |
public function Trigger( $type, $data = array(), $delayed = false ) {
|
99 |
|
@@ -134,17 +142,17 @@ final class WSAL_AlertManager
|
|
134 |
|
135 |
/**
|
136 |
* Check enable user and roles.
|
137 |
-
*
|
138 |
-
* @param
|
139 |
-
* @
|
|
|
140 |
*/
|
141 |
-
public function CheckEnableUserRoles($user, $roles)
|
142 |
-
{
|
143 |
$is_enable = true;
|
144 |
-
if (
|
145 |
$is_enable = false;
|
146 |
}
|
147 |
-
if (
|
148 |
$is_enable = false;
|
149 |
}
|
150 |
return $is_enable;
|
@@ -153,9 +161,9 @@ final class WSAL_AlertManager
|
|
153 |
/**
|
154 |
* Trigger only if a condition is met at the end of request.
|
155 |
*
|
156 |
-
* @param integer $type Alert type ID.
|
157 |
-
* @param array $data Alert data.
|
158 |
-
* @param callable $cond A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
159 |
*/
|
160 |
public function TriggerIf( $type, $data, $cond = null ) {
|
161 |
$username = wp_get_current_user()->user_login;
|
@@ -171,46 +179,55 @@ final class WSAL_AlertManager
|
|
171 |
}
|
172 |
|
173 |
/**
|
174 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
*/
|
176 |
-
protected function _CommitItem($type, $data, $cond, $_retry = true)
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
// ok, convert alert to a log entry
|
182 |
$this->_triggered_types[] = $type;
|
183 |
-
$this->Log($type, $data);
|
184 |
-
} elseif ($_retry) {
|
185 |
-
//
|
186 |
$this->plugin->LoadDefaults();
|
187 |
-
return $this->_CommitItem($type, $data, $cond, false);
|
188 |
} else {
|
189 |
-
//
|
190 |
-
throw new Exception('Alert with code "' . $type . '" has not be registered.');
|
191 |
}
|
192 |
}
|
193 |
}
|
194 |
}
|
195 |
|
196 |
/**
|
197 |
-
*
|
|
|
|
|
198 |
*/
|
199 |
-
public function _CommitPipeline()
|
200 |
-
|
201 |
-
|
202 |
-
$this->_CommitItem($item['type'], $item['data'], $item['cond']);
|
203 |
}
|
204 |
}
|
205 |
|
206 |
/**
|
207 |
-
*
|
208 |
-
*
|
|
|
|
|
209 |
*/
|
210 |
-
public function WillTrigger($type)
|
211 |
-
|
212 |
-
|
213 |
-
if ($item['type'] == $type) {
|
214 |
return true;
|
215 |
}
|
216 |
}
|
@@ -218,48 +235,50 @@ final class WSAL_AlertManager
|
|
218 |
}
|
219 |
|
220 |
/**
|
221 |
-
*
|
222 |
-
*
|
|
|
|
|
223 |
*/
|
224 |
-
public function WillOrHasTriggered($type)
|
225 |
-
|
226 |
-
|
227 |
-
|| $this->WillTrigger($type);
|
228 |
}
|
229 |
|
230 |
/**
|
231 |
* Register an alert type.
|
232 |
-
*
|
|
|
|
|
233 |
*/
|
234 |
-
public function Register($info)
|
235 |
-
|
236 |
-
|
237 |
-
// handle single item
|
238 |
list($type, $code, $catg, $subcatg, $desc, $mesg) = $info;
|
239 |
-
if (isset($this->_alerts[$type])) {
|
240 |
-
throw new Exception("Alert $type already registered with Alert Manager.");
|
241 |
}
|
242 |
-
$this->_alerts[$type] = new WSAL_Alert($type, $code, $catg, $subcatg, $desc, $mesg);
|
243 |
} else {
|
244 |
-
//
|
245 |
-
foreach (func_get_args() as $arg) {
|
246 |
-
$this->Register($arg);
|
247 |
}
|
248 |
}
|
249 |
}
|
250 |
|
251 |
/**
|
252 |
* Register a whole group of items.
|
253 |
-
*
|
|
|
254 |
* Item values is an array of [type, code, description, message] respectively.
|
255 |
*/
|
256 |
-
public function RegisterGroup($groups)
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
foreach ($subgroup as $item) {
|
261 |
list($type, $code, $desc, $mesg) = $item;
|
262 |
-
$this->Register(array($type, $code, $name, $subname, $desc, $mesg));
|
263 |
}
|
264 |
}
|
265 |
}
|
@@ -267,76 +286,78 @@ final class WSAL_AlertManager
|
|
267 |
|
268 |
/**
|
269 |
* Returns whether alert of type $type is enabled or not.
|
|
|
270 |
* @param integer $type Alert type.
|
271 |
* @return boolean True if enabled, false otherwise.
|
272 |
*/
|
273 |
-
public function IsEnabled($type)
|
274 |
-
|
275 |
-
return !in_array($type, $this->GetDisabledAlerts());
|
276 |
}
|
277 |
|
278 |
/**
|
279 |
* Disables a set of alerts by type.
|
|
|
280 |
* @param int[] $types Alert type codes to be disabled.
|
281 |
*/
|
282 |
-
public function SetDisabledAlerts($types)
|
283 |
-
|
284 |
-
$this->plugin->settings->SetDisabledAlerts($types);
|
285 |
}
|
286 |
|
287 |
/**
|
288 |
-
*
|
|
|
|
|
289 |
*/
|
290 |
-
public function GetDisabledAlerts()
|
291 |
-
{
|
292 |
return $this->plugin->settings->GetDisabledAlerts();
|
293 |
}
|
294 |
|
295 |
/**
|
296 |
-
*
|
|
|
|
|
297 |
*/
|
298 |
-
public function GetLoggers()
|
299 |
-
{
|
300 |
return $this->_loggers;
|
301 |
}
|
302 |
|
303 |
/**
|
304 |
* Converts an Alert into a Log entry (by invoking loggers).
|
305 |
* You should not call this method directly.
|
306 |
-
*
|
307 |
-
* @param
|
308 |
-
|
309 |
-
|
310 |
-
{
|
311 |
-
if (!isset($data['ClientIP'])) {
|
312 |
-
$
|
313 |
-
if (!empty($
|
314 |
-
$data['ClientIP'] = $
|
315 |
}
|
316 |
}
|
317 |
-
if (!isset($data['OtherIPs']) && $this->plugin->settings->IsMainIPFromProxy()) {
|
318 |
-
$
|
319 |
-
if (!empty($
|
320 |
-
$data['OtherIPs'] = $
|
321 |
}
|
322 |
}
|
323 |
-
if (!isset($data['UserAgent'])) {
|
324 |
-
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
325 |
$data['UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
|
326 |
}
|
327 |
}
|
328 |
-
if (!isset($data['Username']) && !isset($data['CurrentUserID'])) {
|
329 |
-
if (function_exists('get_current_user_id')) {
|
330 |
$data['CurrentUserID'] = get_current_user_id();
|
331 |
}
|
332 |
}
|
333 |
-
if (!isset($data['CurrentUserRoles']) && function_exists('is_user_logged_in') && is_user_logged_in()) {
|
334 |
-
$
|
335 |
-
if (!empty($
|
336 |
-
$data['CurrentUserRoles'] = $
|
337 |
}
|
338 |
}
|
339 |
-
// Check if the user management plugin is loaded and adds the SessionID
|
340 |
if ( class_exists( 'WSAL_User_Management_Plugin' ) ) {
|
341 |
if ( function_exists( 'get_current_user_id' ) ) {
|
342 |
$session_tokens = get_user_meta( get_current_user_id(), 'session_tokens', true );
|
@@ -346,25 +367,22 @@ final class WSAL_AlertManager
|
|
346 |
}
|
347 |
}
|
348 |
}
|
349 |
-
//if(isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != $data['ClientIP'])
|
350 |
-
// $data['ClientHost'] = $_SERVER['REMOTE_HOST'];
|
351 |
-
//$data['OtherIPs'] = $_SERVER['REMOTE_HOST'];
|
352 |
|
353 |
-
foreach ($this->_loggers as $logger) {
|
354 |
-
$logger->Log($type, $data);
|
355 |
}
|
356 |
}
|
357 |
|
358 |
/**
|
359 |
* Return alert given alert type.
|
360 |
-
*
|
361 |
-
* @param
|
|
|
362 |
* @return WSAL_Alert
|
363 |
*/
|
364 |
-
public function GetAlert($type, $default = null)
|
365 |
-
|
366 |
-
|
367 |
-
if ($alert->type == $type) {
|
368 |
return $alert;
|
369 |
}
|
370 |
}
|
@@ -373,30 +391,30 @@ final class WSAL_AlertManager
|
|
373 |
|
374 |
/**
|
375 |
* Returns all supported alerts.
|
|
|
376 |
* @return WSAL_Alert[]
|
377 |
*/
|
378 |
-
public function GetAlerts()
|
379 |
-
{
|
380 |
return $this->_alerts;
|
381 |
}
|
382 |
|
383 |
/**
|
384 |
* Returns all supported alerts.
|
|
|
385 |
* @return array
|
386 |
*/
|
387 |
-
public function GetCategorizedAlerts()
|
388 |
-
{
|
389 |
$result = array();
|
390 |
-
foreach ($this->_alerts as $alert) {
|
391 |
-
if (!isset($result[$alert->catg])) {
|
392 |
-
$result[$alert->catg] = array();
|
393 |
}
|
394 |
-
if (!isset($result[$alert->catg][$alert->subcatg])) {
|
395 |
-
$result[$alert->catg][$alert->subcatg] = array();
|
396 |
}
|
397 |
-
$result[$alert->catg][$alert->subcatg][] = $alert;
|
398 |
}
|
399 |
-
ksort($result);
|
400 |
return $result;
|
401 |
}
|
402 |
|
@@ -411,7 +429,9 @@ final class WSAL_AlertManager
|
|
411 |
}
|
412 |
|
413 |
/**
|
414 |
-
*
|
|
|
|
|
415 |
*/
|
416 |
public function GetDisabledUsers() {
|
417 |
return $this->plugin->settings->GetExcludedMonitoringUsers();
|
@@ -463,6 +483,9 @@ final class WSAL_AlertManager
|
|
463 |
return $this->plugin->settings->get_excluded_post_types();
|
464 |
}
|
465 |
|
|
|
|
|
|
|
466 |
private function IsDisabledIP() {
|
467 |
$is_disabled = false;
|
468 |
$ip = $this->plugin->settings->GetMainClientIP();
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* WSAL_AlertManager class.
|
4 |
* It is the actual trigger for the alerts.
|
5 |
+
*
|
6 |
+
* @package Wsal
|
7 |
*/
|
8 |
+
final class WSAL_AlertManager {
|
9 |
+
|
10 |
/**
|
11 |
+
* Array of alerts (WSAL_Alert).
|
12 |
+
*
|
13 |
+
* @var array
|
14 |
*/
|
15 |
protected $_alerts = array();
|
16 |
|
17 |
/**
|
18 |
+
* Array of loggers (WSAL_AbstractLogger).
|
19 |
+
*
|
20 |
+
* @var array
|
21 |
*/
|
22 |
protected $_loggers = array();
|
23 |
|
24 |
/**
|
25 |
+
* Instance of WpSecurityAuditLog.
|
26 |
+
*
|
27 |
+
* @var object
|
28 |
*/
|
29 |
protected $plugin;
|
30 |
|
31 |
/**
|
32 |
* Contains a list of alerts to trigger.
|
33 |
+
*
|
34 |
* @var array
|
35 |
*/
|
36 |
protected $_pipeline = array();
|
37 |
|
38 |
/**
|
39 |
* Contains an array of alerts that have been triggered for this request.
|
40 |
+
*
|
41 |
* @var int[]
|
42 |
*/
|
43 |
protected $_triggered_types = array();
|
44 |
|
45 |
/**
|
46 |
* Create new AlertManager instance.
|
47 |
+
*
|
48 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
49 |
*/
|
50 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
|
|
51 |
$this->plugin = $plugin;
|
52 |
+
foreach ( glob( dirname( __FILE__ ) . '/Loggers/*.php' ) as $file ) {
|
53 |
+
$this->AddFromFile( $file );
|
54 |
}
|
55 |
|
56 |
+
add_action( 'shutdown', array( $this, '_CommitPipeline' ) );
|
57 |
}
|
58 |
|
59 |
/**
|
60 |
* Add new logger from file inside autoloader path.
|
61 |
+
*
|
62 |
* @param string $file Path to file.
|
63 |
*/
|
64 |
+
public function AddFromFile( $file ) {
|
65 |
+
$this->AddFromClass( $this->plugin->GetClassFileClassName( $file ) );
|
|
|
66 |
}
|
67 |
|
68 |
/**
|
69 |
* Add new logger given class name.
|
70 |
+
*
|
71 |
* @param string $class Class name.
|
72 |
*/
|
73 |
+
public function AddFromClass( $class ) {
|
74 |
+
$this->AddInstance( new $class( $this->plugin ) );
|
|
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
* Add newly created logger to list.
|
79 |
+
*
|
80 |
* @param WSAL_AbstractLogger $logger The new logger.
|
81 |
*/
|
82 |
+
public function AddInstance( WSAL_AbstractLogger $logger ) {
|
|
|
83 |
$this->_loggers[] = $logger;
|
84 |
}
|
85 |
|
86 |
/**
|
87 |
* Remove logger by class name.
|
88 |
+
*
|
89 |
* @param string $class The class name.
|
90 |
*/
|
91 |
+
public function RemoveByClass( $class ) {
|
92 |
+
foreach ( $this->_loggers as $i => $inst ) {
|
93 |
+
if ( get_class( $inst ) == $class ) {
|
94 |
+
unset( $this->_loggers[ $i ] );
|
|
|
95 |
}
|
96 |
}
|
97 |
}
|
101 |
*
|
102 |
* @param integer $type Alert type.
|
103 |
* @param array $data Alert data.
|
104 |
+
* @param bool $delayed - False if delayed, true if not.
|
105 |
*/
|
106 |
public function Trigger( $type, $data = array(), $delayed = false ) {
|
107 |
|
142 |
|
143 |
/**
|
144 |
* Check enable user and roles.
|
145 |
+
*
|
146 |
+
* @param string $user - Username.
|
147 |
+
* @param array $roles - User roles.
|
148 |
+
* @return boolean - True if enable false otherwise.
|
149 |
*/
|
150 |
+
public function CheckEnableUserRoles( $user, $roles ) {
|
|
|
151 |
$is_enable = true;
|
152 |
+
if ( '' != $user && $this->IsDisabledUser( $user ) ) {
|
153 |
$is_enable = false;
|
154 |
}
|
155 |
+
if ( '' != $roles && $this->IsDisabledRole( $roles ) ) {
|
156 |
$is_enable = false;
|
157 |
}
|
158 |
return $is_enable;
|
161 |
/**
|
162 |
* Trigger only if a condition is met at the end of request.
|
163 |
*
|
164 |
+
* @param integer $type - Alert type ID.
|
165 |
+
* @param array $data - Alert data.
|
166 |
+
* @param callable $cond - A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
167 |
*/
|
168 |
public function TriggerIf( $type, $data, $cond = null ) {
|
169 |
$username = wp_get_current_user()->user_login;
|
179 |
}
|
180 |
|
181 |
/**
|
182 |
+
* Method: Commit an alert now.
|
183 |
+
*
|
184 |
+
* @param int $type - Alert type.
|
185 |
+
* @param array $data - Data of the alert.
|
186 |
+
* @param array $cond - Condition for the alert.
|
187 |
+
* @param bool $_retry - Retry.
|
188 |
+
* @internal
|
189 |
+
*
|
190 |
+
* @throws string - Error if alert is not registered.
|
191 |
*/
|
192 |
+
protected function _CommitItem( $type, $data, $cond, $_retry = true ) {
|
193 |
+
if ( ! $cond || ! ! call_user_func( $cond, $this ) ) {
|
194 |
+
if ( $this->IsEnabled( $type ) ) {
|
195 |
+
if ( isset( $this->_alerts[ $type ] ) ) {
|
196 |
+
// Ok, convert alert to a log entry.
|
|
|
197 |
$this->_triggered_types[] = $type;
|
198 |
+
$this->Log( $type, $data );
|
199 |
+
} elseif ( $_retry ) {
|
200 |
+
// This is the last attempt at loading alerts from default file.
|
201 |
$this->plugin->LoadDefaults();
|
202 |
+
return $this->_CommitItem( $type, $data, $cond, false );
|
203 |
} else {
|
204 |
+
// In general this shouldn't happen, but it could, so we handle it here.
|
205 |
+
throw new Exception( 'Alert with code "' . $type . '" has not be registered.' );
|
206 |
}
|
207 |
}
|
208 |
}
|
209 |
}
|
210 |
|
211 |
/**
|
212 |
+
* Method: Runs over triggered alerts in pipeline and passes them to loggers.
|
213 |
+
*
|
214 |
+
* @internal
|
215 |
*/
|
216 |
+
public function _CommitPipeline() {
|
217 |
+
foreach ( $this->_pipeline as $item ) {
|
218 |
+
$this->_CommitItem( $item['type'], $item['data'], $item['cond'] );
|
|
|
219 |
}
|
220 |
}
|
221 |
|
222 |
/**
|
223 |
+
* Method: True if at the end of request an alert of this type will be triggered.
|
224 |
+
*
|
225 |
+
* @param integer $type - Alert type ID.
|
226 |
+
* @return boolean
|
227 |
*/
|
228 |
+
public function WillTrigger( $type ) {
|
229 |
+
foreach ( $this->_pipeline as $item ) {
|
230 |
+
if ( $item['type'] == $type ) {
|
|
|
231 |
return true;
|
232 |
}
|
233 |
}
|
235 |
}
|
236 |
|
237 |
/**
|
238 |
+
* Method: True if an alert has been or will be triggered in this request, false otherwise.
|
239 |
+
*
|
240 |
+
* @param int $type - Alert type ID.
|
241 |
+
* @return boolean
|
242 |
*/
|
243 |
+
public function WillOrHasTriggered( $type ) {
|
244 |
+
return in_array( $type, $this->_triggered_types )
|
245 |
+
|| $this->WillTrigger( $type );
|
|
|
246 |
}
|
247 |
|
248 |
/**
|
249 |
* Register an alert type.
|
250 |
+
*
|
251 |
+
* @param array $info - Array of [type, code, category, description, message] respectively.
|
252 |
+
* @throws string - Error if alert is already registered.
|
253 |
*/
|
254 |
+
public function Register( $info ) {
|
255 |
+
if ( func_num_args() == 1 ) {
|
256 |
+
// Handle single item.
|
|
|
257 |
list($type, $code, $catg, $subcatg, $desc, $mesg) = $info;
|
258 |
+
if ( isset( $this->_alerts[ $type ] ) ) {
|
259 |
+
throw new Exception( "Alert $type already registered with Alert Manager." );
|
260 |
}
|
261 |
+
$this->_alerts[ $type ] = new WSAL_Alert( $type, $code, $catg, $subcatg, $desc, $mesg );
|
262 |
} else {
|
263 |
+
// Handle multiple items.
|
264 |
+
foreach ( func_get_args() as $arg ) {
|
265 |
+
$this->Register( $arg );
|
266 |
}
|
267 |
}
|
268 |
}
|
269 |
|
270 |
/**
|
271 |
* Register a whole group of items.
|
272 |
+
*
|
273 |
+
* @param array $groups - An array with group name as the index and an array of group items as the value.
|
274 |
* Item values is an array of [type, code, description, message] respectively.
|
275 |
*/
|
276 |
+
public function RegisterGroup( $groups ) {
|
277 |
+
foreach ( $groups as $name => $group ) {
|
278 |
+
foreach ( $group as $subname => $subgroup ) {
|
279 |
+
foreach ( $subgroup as $item ) {
|
|
|
280 |
list($type, $code, $desc, $mesg) = $item;
|
281 |
+
$this->Register( array( $type, $code, $name, $subname, $desc, $mesg ) );
|
282 |
}
|
283 |
}
|
284 |
}
|
286 |
|
287 |
/**
|
288 |
* Returns whether alert of type $type is enabled or not.
|
289 |
+
*
|
290 |
* @param integer $type Alert type.
|
291 |
* @return boolean True if enabled, false otherwise.
|
292 |
*/
|
293 |
+
public function IsEnabled( $type ) {
|
294 |
+
return ! in_array( $type, $this->GetDisabledAlerts() );
|
|
|
295 |
}
|
296 |
|
297 |
/**
|
298 |
* Disables a set of alerts by type.
|
299 |
+
*
|
300 |
* @param int[] $types Alert type codes to be disabled.
|
301 |
*/
|
302 |
+
public function SetDisabledAlerts( $types ) {
|
303 |
+
$this->plugin->settings->SetDisabledAlerts( $types );
|
|
|
304 |
}
|
305 |
|
306 |
/**
|
307 |
+
* Method: Returns an array of disabled alerts' type code.
|
308 |
+
*
|
309 |
+
* @return int[]
|
310 |
*/
|
311 |
+
public function GetDisabledAlerts() {
|
|
|
312 |
return $this->plugin->settings->GetDisabledAlerts();
|
313 |
}
|
314 |
|
315 |
/**
|
316 |
+
* Method: Returns an array of loaded loggers.
|
317 |
+
*
|
318 |
+
* @return WSAL_AbstractLogger[]
|
319 |
*/
|
320 |
+
public function GetLoggers() {
|
|
|
321 |
return $this->_loggers;
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
* Converts an Alert into a Log entry (by invoking loggers).
|
326 |
* You should not call this method directly.
|
327 |
+
*
|
328 |
+
* @param integer $type - Alert type.
|
329 |
+
* @param array $data - Misc alert data.
|
330 |
+
*/
|
331 |
+
protected function Log( $type, $data = array() ) {
|
332 |
+
if ( ! isset( $data['ClientIP'] ) ) {
|
333 |
+
$client_ip = $this->plugin->settings->GetMainClientIP();
|
334 |
+
if ( ! empty( $client_ip ) ) {
|
335 |
+
$data['ClientIP'] = $client_ip;
|
336 |
}
|
337 |
}
|
338 |
+
if ( ! isset( $data['OtherIPs'] ) && $this->plugin->settings->IsMainIPFromProxy() ) {
|
339 |
+
$other_ips = $this->plugin->settings->GetClientIPs();
|
340 |
+
if ( ! empty( $other_ips ) ) {
|
341 |
+
$data['OtherIPs'] = $other_ips;
|
342 |
}
|
343 |
}
|
344 |
+
if ( ! isset( $data['UserAgent'] ) ) {
|
345 |
+
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
|
346 |
$data['UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
|
347 |
}
|
348 |
}
|
349 |
+
if ( ! isset( $data['Username'] ) && ! isset( $data['CurrentUserID'] ) ) {
|
350 |
+
if ( function_exists( 'get_current_user_id' ) ) {
|
351 |
$data['CurrentUserID'] = get_current_user_id();
|
352 |
}
|
353 |
}
|
354 |
+
if ( ! isset( $data['CurrentUserRoles'] ) && function_exists( 'is_user_logged_in' ) && is_user_logged_in() ) {
|
355 |
+
$current_user_roles = $this->plugin->settings->GetCurrentUserRoles();
|
356 |
+
if ( ! empty( $current_user_roles ) ) {
|
357 |
+
$data['CurrentUserRoles'] = $current_user_roles;
|
358 |
}
|
359 |
}
|
360 |
+
// Check if the user management plugin is loaded and adds the SessionID.
|
361 |
if ( class_exists( 'WSAL_User_Management_Plugin' ) ) {
|
362 |
if ( function_exists( 'get_current_user_id' ) ) {
|
363 |
$session_tokens = get_user_meta( get_current_user_id(), 'session_tokens', true );
|
367 |
}
|
368 |
}
|
369 |
}
|
|
|
|
|
|
|
370 |
|
371 |
+
foreach ( $this->_loggers as $logger ) {
|
372 |
+
$logger->Log( $type, $data );
|
373 |
}
|
374 |
}
|
375 |
|
376 |
/**
|
377 |
* Return alert given alert type.
|
378 |
+
*
|
379 |
+
* @param integer $type - Alert type.
|
380 |
+
* @param mixed $default - Returned if alert is not found.
|
381 |
* @return WSAL_Alert
|
382 |
*/
|
383 |
+
public function GetAlert( $type, $default = null ) {
|
384 |
+
foreach ( $this->_alerts as $alert ) {
|
385 |
+
if ( $alert->type == $type ) {
|
|
|
386 |
return $alert;
|
387 |
}
|
388 |
}
|
391 |
|
392 |
/**
|
393 |
* Returns all supported alerts.
|
394 |
+
*
|
395 |
* @return WSAL_Alert[]
|
396 |
*/
|
397 |
+
public function GetAlerts() {
|
|
|
398 |
return $this->_alerts;
|
399 |
}
|
400 |
|
401 |
/**
|
402 |
* Returns all supported alerts.
|
403 |
+
*
|
404 |
* @return array
|
405 |
*/
|
406 |
+
public function GetCategorizedAlerts() {
|
|
|
407 |
$result = array();
|
408 |
+
foreach ( $this->_alerts as $alert ) {
|
409 |
+
if ( ! isset( $result[ $alert->catg ] ) ) {
|
410 |
+
$result[ $alert->catg ] = array();
|
411 |
}
|
412 |
+
if ( ! isset( $result[ $alert->catg ][ $alert->subcatg ] ) ) {
|
413 |
+
$result[ $alert->catg ][ $alert->subcatg ] = array();
|
414 |
}
|
415 |
+
$result[ $alert->catg ][ $alert->subcatg ][] = $alert;
|
416 |
}
|
417 |
+
ksort( $result );
|
418 |
return $result;
|
419 |
}
|
420 |
|
429 |
}
|
430 |
|
431 |
/**
|
432 |
+
* Method: Returns an array of disabled users.
|
433 |
+
*
|
434 |
+
* @return array.
|
435 |
*/
|
436 |
public function GetDisabledUsers() {
|
437 |
return $this->plugin->settings->GetExcludedMonitoringUsers();
|
483 |
return $this->plugin->settings->get_excluded_post_types();
|
484 |
}
|
485 |
|
486 |
+
/**
|
487 |
+
* Method: Returns if IP is disabled or not.
|
488 |
+
*/
|
489 |
private function IsDisabledIP() {
|
490 |
$is_disabled = false;
|
491 |
$ip = $this->plugin->settings->GetMainClientIP();
|
classes/AuditLogListView.php
CHANGED
@@ -1,575 +1,738 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
-
require_once(ABSPATH . 'wp-admin/includes/admin.php');
|
4 |
-
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
|
5 |
/**
|
6 |
-
*
|
|
|
|
|
7 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
* This view is included in Audit Log Viewer Page.
|
|
|
9 |
* @see Views/AuditLog.php
|
|
|
10 |
*/
|
11 |
-
class WSAL_AuditLogListView extends WP_List_Table
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
575 |
}
|
1 |
<?php
|
|
|
|
|
|
|
2 |
/**
|
3 |
+
* Audit Log List View
|
4 |
+
*
|
5 |
+
* CLass file for audit log list view.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
require_once( ABSPATH . 'wp-admin/includes/admin.php' );
|
17 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
18 |
+
|
19 |
+
/**
|
20 |
* This view is included in Audit Log Viewer Page.
|
21 |
+
*
|
22 |
* @see Views/AuditLog.php
|
23 |
+
* @package Wsal
|
24 |
*/
|
25 |
+
class WSAL_AuditLogListView extends WP_List_Table {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Instance of WpSecurityAuditLog.
|
29 |
+
*
|
30 |
+
* @var object
|
31 |
+
*/
|
32 |
+
protected $_plugin;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* GMT Offset
|
36 |
+
*
|
37 |
+
* @var string
|
38 |
+
*/
|
39 |
+
protected $_gmt_offset_sec = 0;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Method: Constructor.
|
43 |
+
*
|
44 |
+
* @param object $plugin - Instance of WpSecurityAuditLog.
|
45 |
+
*/
|
46 |
+
public function __construct( $plugin ) {
|
47 |
+
$this->_plugin = $plugin;
|
48 |
+
|
49 |
+
$timezone = $this->_plugin->settings->GetTimezone();
|
50 |
+
if ( $timezone ) {
|
51 |
+
$this->_gmt_offset_sec = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
|
52 |
+
} else {
|
53 |
+
$this->_gmt_offset_sec = date( 'Z' );
|
54 |
+
}
|
55 |
+
|
56 |
+
parent::__construct(
|
57 |
+
array(
|
58 |
+
'singular' => 'log',
|
59 |
+
'plural' => 'logs',
|
60 |
+
'ajax' => true,
|
61 |
+
'screen' => 'interval-list',
|
62 |
+
)
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Empty View.
|
68 |
+
*/
|
69 |
+
public function no_items() {
|
70 |
+
esc_html_e( 'No events so far.', 'wp-security-audit-log' );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Table navigation.
|
75 |
+
*
|
76 |
+
* @param string $which - Position of the nav.
|
77 |
+
*/
|
78 |
+
public function extra_tablenav( $which ) {
|
79 |
+
// Items-per-page widget.
|
80 |
+
$p = $this->_plugin->settings->GetViewPerPage();
|
81 |
+
$items = array( 5, 10, 15, 30, 50 );
|
82 |
+
if ( ! in_array( $p, $items ) ) {
|
83 |
+
$items[] = $p;
|
84 |
+
}
|
85 |
+
|
86 |
+
?>
|
87 |
+
<div class="wsal-ipp wsal-ipp-<?php echo esc_attr( $which ); ?>">
|
88 |
+
<?php esc_html_e( 'Show ', 'wp-security-audit-log' ); ?>
|
89 |
+
<select class="wsal-ipps" onfocus="WsalIppsFocus(value);" onchange="WsalIppsChange(value);">
|
90 |
+
<?php foreach ( $items as $item ) { ?>
|
91 |
+
<option
|
92 |
+
value="<?php echo is_string( $item ) ? '' : esc_attr( $item ); ?>"
|
93 |
+
<?php
|
94 |
+
if ( $item == $p ) {
|
95 |
+
echo 'selected="selected"';
|
96 |
+
}
|
97 |
+
?>
|
98 |
+
>
|
99 |
+
<?php echo esc_html( $item ); ?>
|
100 |
+
</option>
|
101 |
+
<?php } ?>
|
102 |
+
</select>
|
103 |
+
<?php esc_html_e( ' Items', 'wp-security-audit-log' ); ?>
|
104 |
+
</div>
|
105 |
+
|
106 |
+
<?php
|
107 |
+
// Show site alerts widget.
|
108 |
+
if ( $this->is_multisite() && $this->is_main_blog() ) {
|
109 |
+
$curr = $this->get_view_site_id();
|
110 |
+
?>
|
111 |
+
<div class="wsal-ssa wsal-ssa-<?php echo esc_attr( $which ); ?>">
|
112 |
+
<?php if ( $this->get_site_count() > 15 ) { ?>
|
113 |
+
<?php $curr = $curr ? get_blog_details( $curr ) : null; ?>
|
114 |
+
<?php $curr = $curr ? ($curr->blogname . ' (' . $curr->domain . ')') : 'All Sites'; ?>
|
115 |
+
<input type="text" class="wsal-ssas" value="<?php echo esc_attr( $curr ); ?>"/>
|
116 |
+
<?php } else { ?>
|
117 |
+
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
118 |
+
<option value="0"><?php esc_html_e( 'All Sites', 'wp-security-audit-log' ); ?></option>
|
119 |
+
<?php foreach ( $this->get_sites() as $info ) { ?>
|
120 |
+
<option value="<?php echo esc_attr( $info->blog_id ); ?>"
|
121 |
+
<?php
|
122 |
+
if ( $info->blog_id == $curr ) {
|
123 |
+
echo 'selected="selected"';
|
124 |
+
}
|
125 |
+
?>
|
126 |
+
>
|
127 |
+
<?php echo esc_html( $info->blogname ) . ' (' . esc_html( $info->domain ) . ')'; ?>
|
128 |
+
</option>
|
129 |
+
<?php } ?>
|
130 |
+
</select>
|
131 |
+
<?php } ?>
|
132 |
+
</div>
|
133 |
+
<?php
|
134 |
+
}
|
135 |
+
|
136 |
+
// Switch to live or archive DB.
|
137 |
+
if ( $this->_plugin->settings->IsArchivingEnabled() ) {
|
138 |
+
$selected = 'live';
|
139 |
+
$selected_db = get_transient( 'wsal_wp_selected_db' );
|
140 |
+
if ( $selected_db && 'archive' == $selected_db ) {
|
141 |
+
$selected = 'archive';
|
142 |
+
}
|
143 |
+
?>
|
144 |
+
<div class="wsal-ssa wsal-db">
|
145 |
+
<select class="wsal-db" onchange="WsalDBChange(value);">
|
146 |
+
<option value="live"
|
147 |
+
<?php
|
148 |
+
if ( 'live' == $selected ) {
|
149 |
+
echo 'selected="selected"';
|
150 |
+
}
|
151 |
+
?>
|
152 |
+
>
|
153 |
+
<?php esc_html_e( 'Live Database', 'wp-security-audit-log' ); ?>
|
154 |
+
</option>
|
155 |
+
<option value="archive"
|
156 |
+
<?php
|
157 |
+
if ( 'archive' == $selected ) {
|
158 |
+
echo 'selected="selected"';
|
159 |
+
}
|
160 |
+
?>
|
161 |
+
>
|
162 |
+
<?php esc_html_e( 'Archive Database', 'wp-security-audit-log' ); ?>
|
163 |
+
</option>
|
164 |
+
</select>
|
165 |
+
</div>
|
166 |
+
<?php
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Method: Object with keys: blog_id, blogname, domain.
|
172 |
+
*
|
173 |
+
* @param int|null $limit - Maximum number of sites to return (null = no limit).
|
174 |
+
* @return object
|
175 |
+
*/
|
176 |
+
public function get_sites( $limit = null ) {
|
177 |
+
global $wpdb;
|
178 |
+
// Build query.
|
179 |
+
$sql = 'SELECT blog_id, domain FROM ' . $wpdb->blogs;
|
180 |
+
if ( ! is_null( $limit ) ) {
|
181 |
+
$sql .= ' LIMIT ' . $limit;
|
182 |
+
}
|
183 |
+
|
184 |
+
// Execute query.
|
185 |
+
$res = $wpdb->get_results( $sql );
|
186 |
+
|
187 |
+
// Modify result.
|
188 |
+
foreach ( $res as $row ) {
|
189 |
+
$row->blogname = get_blog_option( $row->blog_id, 'blogname' );
|
190 |
+
}
|
191 |
+
|
192 |
+
// Return result.
|
193 |
+
return $res;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Method: The number of sites on the network.
|
198 |
+
*
|
199 |
+
* @return int
|
200 |
+
*/
|
201 |
+
public function get_site_count() {
|
202 |
+
global $wpdb;
|
203 |
+
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
204 |
+
return (int) $wpdb->get_var( $sql );
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Method: Get View Columns.
|
209 |
+
*
|
210 |
+
* @return array
|
211 |
+
*/
|
212 |
+
public function get_columns() {
|
213 |
+
$type_name = $this->_plugin->settings->get_type_username();
|
214 |
+
if ( 'display_name' === $type_name ) {
|
215 |
+
$name_column = __( 'User', 'wp-security-audit-log' );
|
216 |
+
} elseif ( 'username' === $type_name ) {
|
217 |
+
$name_column = __( 'Username', 'wp-security-audit-log' );
|
218 |
+
}
|
219 |
+
$cols = array(
|
220 |
+
'type' => __( 'Alert ID', 'wp-security-audit-log' ),
|
221 |
+
'code' => __( 'Type', 'wp-security-audit-log' ),
|
222 |
+
'crtd' => __( 'Date', 'wp-security-audit-log' ),
|
223 |
+
'user' => $name_column,
|
224 |
+
'scip' => __( 'Source IP', 'wp-security-audit-log' ),
|
225 |
+
);
|
226 |
+
if ( $this->is_multisite() && $this->is_main_blog() && ! $this->is_specific_view() ) {
|
227 |
+
$cols['site'] = __( 'Site', 'wp-security-audit-log' );
|
228 |
+
}
|
229 |
+
$cols['mesg'] = __( 'Message', 'wp-security-audit-log' );
|
230 |
+
$sel_columns = $this->_plugin->settings->GetColumnsSelected();
|
231 |
+
if ( ! empty( $sel_columns ) ) {
|
232 |
+
unset( $cols );
|
233 |
+
$sel_columns = (array) json_decode( $sel_columns );
|
234 |
+
foreach ( $sel_columns as $key => $value ) {
|
235 |
+
switch ( $key ) {
|
236 |
+
case 'alert_code':
|
237 |
+
$cols['type'] = __( 'Alert ID', 'wp-security-audit-log' );
|
238 |
+
break;
|
239 |
+
case 'type':
|
240 |
+
$cols['code'] = __( 'Type', 'wp-security-audit-log' );
|
241 |
+
break;
|
242 |
+
case 'date':
|
243 |
+
$cols['crtd'] = __( 'Date', 'wp-security-audit-log' );
|
244 |
+
break;
|
245 |
+
case 'username':
|
246 |
+
$cols['user'] = $name_column;
|
247 |
+
break;
|
248 |
+
case 'source_ip':
|
249 |
+
$cols['scip'] = __( 'Source IP', 'wp-security-audit-log' );
|
250 |
+
break;
|
251 |
+
case 'site':
|
252 |
+
$cols['site'] = __( 'Site', 'wp-security-audit-log' );
|
253 |
+
break;
|
254 |
+
case 'message':
|
255 |
+
$cols['mesg'] = __( 'Message', 'wp-security-audit-log' );
|
256 |
+
break;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
}
|
260 |
+
if ( $this->_plugin->settings->IsDataInspectorEnabled() ) {
|
261 |
+
$cols['data'] = '';
|
262 |
+
}
|
263 |
+
return $cols;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Method: Get checkbox column.
|
268 |
+
*
|
269 |
+
* @param object $item - Item.
|
270 |
+
* @return string
|
271 |
+
*/
|
272 |
+
public function column_cb( $item ) {
|
273 |
+
return '<input type="checkbox" value="' . $item->id . '" '
|
274 |
+
. 'name="' . esc_attr( $this->_args['singular'] ) . '[]"/>';
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Method: Get Sortable Columns.
|
279 |
+
*
|
280 |
+
* @return array
|
281 |
+
*/
|
282 |
+
public function get_sortable_columns() {
|
283 |
+
return array(
|
284 |
+
'read' => array( 'is_read', false ),
|
285 |
+
'type' => array( 'alert_id', false ),
|
286 |
+
'crtd' => array( 'created_on', true ),
|
287 |
+
'user' => array( 'user', true ),
|
288 |
+
'scip' => array( 'scip', false ),
|
289 |
+
);
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Method: Get default column values.
|
294 |
+
*
|
295 |
+
* @param object $item - Column item.
|
296 |
+
* @param string $column_name - Name of the column.
|
297 |
+
*/
|
298 |
+
public function column_default( $item, $column_name ) {
|
299 |
+
// Get date format.
|
300 |
+
$datetime_format = $this->_plugin->settings->GetDatetimeFormat();
|
301 |
+
|
302 |
+
switch ( $column_name ) {
|
303 |
+
case 'read':
|
304 |
+
return '<span class="log-read log-read-'
|
305 |
+
. ($item->is_read ? 'old' : 'new')
|
306 |
+
. '" title="' . __( 'Click to toggle.', 'wp-security-audit-log' ) . '"></span>';
|
307 |
+
case 'type':
|
308 |
+
$code = $this->_plugin->alerts->GetAlert( $item->alert_id );
|
309 |
+
$extra_msg = '';
|
310 |
+
$data_link = '';
|
311 |
+
$modification_alerts = array( 1002, 1003, 6007, 6023 );
|
312 |
+
if ( in_array( $item->alert_id, $modification_alerts, true ) ) {
|
313 |
+
$extra_msg = '. Modify this alert.';
|
314 |
+
if ( 1002 === $item->alert_id || 1003 === $item->alert_id ) {
|
315 |
+
$data_link = add_query_arg( 'page', 'wsal-togglealerts#tab-users-profiles---activity', admin_url( 'admin.php' ) );
|
316 |
+
} elseif ( 6007 === $item->alert_id || 6023 === $item->alert_id ) {
|
317 |
+
$data_link = add_query_arg( 'page', 'wsal-togglealerts#tab-system-activity', admin_url( 'admin.php' ) );
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'edit' ) ) {
|
322 |
+
return '<span class="log-disable">' . str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
323 |
+
}
|
324 |
+
|
325 |
+
return '<span class="log-disable" data-disable-alert-nonce="' . wp_create_nonce( 'disable-alert-nonce' . $item->alert_id ) . '" data-tooltip="' . __( 'Disable this type of alerts.', 'wp-security-audit-log' ) . '<br>' . $item->alert_id . ' - ' . esc_html( $code->desc ) . $extra_msg . '" data-alert-id="' . $item->alert_id . '" ' . esc_attr( 'data-link=' . $data_link ) . ' >'
|
326 |
+
. str_pad( $item->alert_id, 4, '0', STR_PAD_LEFT ) . ' </span>';
|
327 |
+
case 'code':
|
328 |
+
$code = $this->_plugin->alerts->GetAlert( $item->alert_id );
|
329 |
+
$code = $code ? $code->code : 0;
|
330 |
+
$const = (object) array(
|
331 |
+
'name' => 'E_UNKNOWN',
|
332 |
+
'value' => 0,
|
333 |
+
'description' => __( 'Unknown error code.', 'wp-security-audit-log' ),
|
334 |
+
);
|
335 |
+
$const = $this->_plugin->constants->GetConstantBy( 'value', $code, $const );
|
336 |
+
if ( 'E_CRITICAL' == $const->name ) {
|
337 |
+
$const->name = 'Critical';
|
338 |
+
} elseif ( 'E_WARNING' == $const->name ) {
|
339 |
+
$const->name = 'Warning';
|
340 |
+
} elseif ( 'E_NOTICE' == $const->name ) {
|
341 |
+
$const->name = 'Notification';
|
342 |
+
}
|
343 |
+
return '<a class="tooltip" href="#" data-tooltip="' . esc_html( $const->name ) . '"><span class="log-type log-type-' . $const->value
|
344 |
+
. '"></span></a>';
|
345 |
+
case 'crtd':
|
346 |
+
return $item->created_on ? (
|
347 |
+
str_replace(
|
348 |
+
'$$$',
|
349 |
+
substr( number_format( fmod( $item->created_on + $this->_gmt_offset_sec, 1 ), 3 ), 2 ),
|
350 |
+
date( $datetime_format, $item->created_on + $this->_gmt_offset_sec )
|
351 |
+
)
|
352 |
+
) : '<i>unknown</i>';
|
353 |
+
case 'user':
|
354 |
+
$username = $item->GetUsername();
|
355 |
+
$type_name = $this->_plugin->settings->get_type_username();
|
356 |
+
if ( $username && ( $user = get_user_by( 'login', $username ) ) ) {
|
357 |
+
$image = get_avatar( $user->ID, 32 );
|
358 |
+
if ( 'display_name' == $type_name ) {
|
359 |
+
$display_name = $user->first_name . ' ' . $user->last_name;
|
360 |
+
} elseif ( 'username' == $type_name ) {
|
361 |
+
$display_name = $user->user_login;
|
362 |
+
}
|
363 |
+
|
364 |
+
if ( class_exists( 'WSAL_SearchExtension' ) ) {
|
365 |
+
$tooltip = esc_attr__( 'Show me all activity by this User', 'wp-security-audit-log' );
|
366 |
+
|
367 |
+
$uhtml = '<a class="search-user" data-tooltip="' . $tooltip . '" data-user="' . $user->user_login . '" href="' . admin_url( 'user-edit.php?user_id=' . $user->ID )
|
368 |
+
. '" target="_blank">' . esc_html( $display_name ) . '</a>';
|
369 |
+
} else {
|
370 |
+
$uhtml = '<a href="' . admin_url( 'user-edit.php?user_id=' . $user->ID )
|
371 |
+
. '" target="_blank">' . esc_html( $display_name ) . '</a>';
|
372 |
+
}
|
373 |
+
|
374 |
+
$roles = $item->GetUserRoles();
|
375 |
+
if ( is_array( $roles ) && count( $roles ) ) {
|
376 |
+
$roles = esc_html( ucwords( implode( ', ', $roles ) ) );
|
377 |
+
} elseif ( is_string( $roles ) && '' != $roles ) {
|
378 |
+
$roles = esc_html( ucwords( str_replace( array( '"', '[', ']' ), ' ', $roles ) ) );
|
379 |
+
} else {
|
380 |
+
$roles = '<i>' . __( 'Unknown', 'wp-security-audit-log' ) . '</i>';
|
381 |
+
}
|
382 |
+
} elseif ( 'Plugin' == $username ) {
|
383 |
+
$image = '<img src="' . $this->_plugin->GetBaseUrl() . '/img/plugin-logo.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
384 |
+
$uhtml = '<i>' . __( 'Plugin', 'wp-security-audit-log' ) . '</i>';
|
385 |
+
$roles = '';
|
386 |
+
} elseif ( 'Plugins' == $username ) {
|
387 |
+
$image = '<img src="' . $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
388 |
+
$uhtml = '<i>' . __( 'Plugins', 'wp-security-audit-log' ) . '</i>';
|
389 |
+
$roles = '';
|
390 |
+
} elseif ( 'Website Visitor' == $username ) {
|
391 |
+
$image = '<img src="' . $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
392 |
+
$uhtml = '<i>' . __( 'Website Visitor', 'wp-security-audit-log' ) . '</i>';
|
393 |
+
$roles = '';
|
394 |
+
} else {
|
395 |
+
$image = '<img src="' . $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
396 |
+
$uhtml = '<i>' . __( 'System', 'wp-security-audit-log' ) . '</i>';
|
397 |
+
$roles = '';
|
398 |
+
}
|
399 |
+
return $image . $uhtml . '<br/>' . $roles;
|
400 |
+
case 'scip':
|
401 |
+
$scip = $item->GetSourceIP();
|
402 |
+
if ( is_string( $scip ) ) {
|
403 |
+
$scip = str_replace( array( '"', '[', ']' ), '', $scip );
|
404 |
+
}
|
405 |
+
|
406 |
+
$oips = array(); // $item->GetOtherIPs();
|
407 |
+
|
408 |
+
// If there's no IP...
|
409 |
+
if ( is_null( $scip ) || '' == $scip ) {
|
410 |
+
return '<i>unknown</i>';
|
411 |
+
}
|
412 |
+
|
413 |
+
// If there's only one IP...
|
414 |
+
$link = 'http://whatismyipaddress.com/ip/' . $scip . '?utm_source=plugin&utm_medium=referral&utm_campaign=WPSAL';
|
415 |
+
if ( class_exists( 'WSAL_SearchExtension' ) ) {
|
416 |
+
$tooltip = esc_attr__( 'Show me all activity originating from this IP Address', 'wp-security-audit-log' );
|
417 |
+
|
418 |
+
if ( count( $oips ) < 2 ) {
|
419 |
+
return "<a class='search-ip' data-tooltip='$tooltip' data-ip='$scip' target='_blank' href='$link'>" . esc_html( $scip ) . '</a>';
|
420 |
+
}
|
421 |
+
} else {
|
422 |
+
if ( count( $oips ) < 2 ) {
|
423 |
+
return "<a target='_blank' href='$link'>" . esc_html( $scip ) . '</a>';
|
424 |
+
}
|
425 |
+
}
|
426 |
+
|
427 |
+
// If there are many IPs...
|
428 |
+
if ( class_exists( 'WSAL_SearchExtension' ) ) {
|
429 |
+
$tooltip = esc_attr__( 'Show me all activity originating from this IP Address', 'wp-security-audit-log' );
|
430 |
+
|
431 |
+
$html = "<a class='search-ip' data-tooltip='$tooltip' data-ip='$scip' target='_blank' href='http://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
432 |
+
foreach ( $oips as $ip ) {
|
433 |
+
if ( $scip != $ip ) {
|
434 |
+
$html .= '<div>' . $ip . '</div>';
|
435 |
+
}
|
436 |
+
}
|
437 |
+
$html .= '</div>';
|
438 |
+
return $html;
|
439 |
+
} else {
|
440 |
+
$html = "<a target='_blank' href='http://whatismyipaddress.com/ip/$scip'>" . esc_html( $scip ) . '</a> <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more…)</a><div style="display: none;">';
|
441 |
+
foreach ( $oips as $ip ) {
|
442 |
+
if ( $scip != $ip ) {
|
443 |
+
$html .= '<div>' . $ip . '</div>';
|
444 |
+
}
|
445 |
+
}
|
446 |
+
$html .= '</div>';
|
447 |
+
return $html;
|
448 |
+
}
|
449 |
+
|
450 |
+
case 'site':
|
451 |
+
$info = get_blog_details( $item->site_id, true );
|
452 |
+
return ! $info ? ('Unknown Site ' . $item->site_id)
|
453 |
+
: ('<a href="' . esc_attr( $info->siteurl ) . '">' . esc_html( $info->blogname ) . '</a>');
|
454 |
+
case 'mesg':
|
455 |
+
return '<div id="Event' . $item->id . '">' . $item->GetMessage( array( $this, 'meta_formatter' ) ) . '</div>';
|
456 |
+
case 'data':
|
457 |
+
$url = admin_url( 'admin-ajax.php' ) . '?action=AjaxInspector&occurrence=' . $item->id;
|
458 |
+
return '<a class="more-info thickbox" title="' . __( 'Alert Data Inspector', 'wp-security-audit-log' ) . '"'
|
459 |
+
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
460 |
+
default:
|
461 |
+
return isset( $item->$column_name )
|
462 |
+
? esc_html( $item->$column_name )
|
463 |
+
: 'Column "' . esc_html( $column_name ) . '" not found';
|
464 |
+
}
|
465 |
+
}
|
466 |
+
|
467 |
+
/**
|
468 |
+
* Method: Reorder string items.
|
469 |
+
*
|
470 |
+
* @param object $a - Item to compare.
|
471 |
+
* @param object $b - Item to compare.
|
472 |
+
* @return int
|
473 |
+
*/
|
474 |
+
public function reorder_items_str( $a, $b ) {
|
475 |
+
$result = strcmp( $a->{$this->_orderby}, $b->{$this->_orderby} );
|
476 |
+
return ( 'asc' === $this->_order ) ? $result : -$result;
|
477 |
+
}
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Method: Reorder items.
|
481 |
+
*
|
482 |
+
* @param object $a - Item to compare.
|
483 |
+
* @param object $b - Item to compare.
|
484 |
+
* @return int
|
485 |
+
*/
|
486 |
+
public function reorder_items_int( $a, $b ) {
|
487 |
+
$result = $a->{$this->_orderby} - $b->{$this->_orderby};
|
488 |
+
return ( 'asc' === $this->_order ) ? $result : -$result;
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* Method: Meta data formater.
|
493 |
+
*
|
494 |
+
* @param string $name - Name of the data.
|
495 |
+
* @param mix $value - Value of the data.
|
496 |
+
* @return string
|
497 |
+
*/
|
498 |
+
public function meta_formatter( $name, $value ) {
|
499 |
+
switch ( true ) {
|
500 |
+
case '%Message%' == $name:
|
501 |
+
return esc_html( $value );
|
502 |
+
|
503 |
+
case '%PromoMessage%' == $name:
|
504 |
+
return '<p class="promo-alert">' . $value . '</p>';
|
505 |
+
|
506 |
+
case '%PromoLink%' == $name:
|
507 |
+
case '%CommentLink%' == $name:
|
508 |
+
case '%CommentMsg%' == $name:
|
509 |
+
return $value;
|
510 |
+
|
511 |
+
case '%MetaLink%' == $name:
|
512 |
+
if ( ! empty( $value ) ) {
|
513 |
+
return "<a href=\"#\" data-disable-custom-nonce='" . wp_create_nonce( 'disable-custom-nonce' . $value ) . "' onclick=\"WsalDisableCustom(this, '" . $value . "');\"> Exclude Custom Field from the Monitoring</a>";
|
514 |
+
} else {
|
515 |
+
return '';
|
516 |
+
}
|
517 |
+
|
518 |
+
case '%RevisionLink%' == $name:
|
519 |
+
return ' Click <a target="_blank" href="' . esc_url( $value ) . '">here</a> to see the content changes.';
|
520 |
+
|
521 |
+
case '%EditorLinkPost%' == $name:
|
522 |
+
return ' <a target="_blank" href="' . esc_url( $value ) . '">View the post</a>';
|
523 |
+
|
524 |
+
case '%EditorLinkPage%' == $name:
|
525 |
+
return ' <a target="_blank" href="' . esc_url( $value ) . '">View the page</a>';
|
526 |
+
|
527 |
+
case '%CategoryLink%' == $name:
|
528 |
+
return ' <a target="_blank" href="' . esc_url( $value ) . '">View the category</a>';
|
529 |
+
|
530 |
+
case '%TagLink%' == $name:
|
531 |
+
return ' <a target="_blank" href="' . esc_url( $value ) . '">View the tag</a>';
|
532 |
+
|
533 |
+
case '%EditorLinkForum%' == $name:
|
534 |
+
return ' <a target="_blank" href="' . esc_url( $value ) . '">View the forum</a>';
|
535 |
+
|
536 |
+
case '%EditorLinkTopic%' == $name:
|
537 |
+
return ' <a target="_blank" href="' . esc_url( $value ) . '">View the topic</a>';
|
538 |
+
|
539 |
+
case in_array( $name, array( '%MetaValue%', '%MetaValueOld%', '%MetaValueNew%' ) ):
|
540 |
+
return '<strong>' . (
|
541 |
+
strlen( $value ) > 50 ? (esc_html( substr( $value, 0, 50 ) ) . '…') : esc_html( $value )
|
542 |
+
) . '</strong>';
|
543 |
+
|
544 |
+
case '%ClientIP%' == $name:
|
545 |
+
if ( is_string( $value ) ) {
|
546 |
+
return '<strong>' . str_replace( array( '"', '[', ']' ), '', $value ) . '</strong>';
|
547 |
+
} else {
|
548 |
+
return '<i>unknown</i>';
|
549 |
+
}
|
550 |
+
|
551 |
+
case '%LinkFile%' == $name:
|
552 |
+
if ( 'NULL' != $value ) {
|
553 |
+
return '<a href="' . esc_url( $value ) . '" download>Download the Log file</a>';
|
554 |
+
} else {
|
555 |
+
return 'Click <a href="' . esc_url( admin_url( 'admin.php?page=wsal-togglealerts#tab-system-activity' ) ) . '">here</a> to log such requests to file';
|
556 |
+
}
|
557 |
+
|
558 |
+
case '%LogFileLink%' === $name:
|
559 |
+
if ( ! empty( $value ) && 'on' === $this->_plugin->GetGlobalOption( 'log-visitor-failed-login' ) ) {
|
560 |
+
return '<a href="' . esc_url( $value ) . '" download>Download the Log file</a>';
|
561 |
+
} elseif ( ! empty( $value ) ) {
|
562 |
+
return '<a href="' . esc_url( $value ) . '">Keep a record of the usernames</a>';
|
563 |
+
}
|
564 |
+
// Failed login file link.
|
565 |
+
case '%LogFileText%' === $name:
|
566 |
+
return esc_html( $value );
|
567 |
+
// Failed login file text.
|
568 |
+
case strncmp( $value, 'http://', 7 ) === 0:
|
569 |
+
case strncmp( $value, 'https://', 7 ) === 0:
|
570 |
+
return '<a href="' . esc_html( $value ) . '" title="' . esc_html( $value ) . '" target="_blank">' . esc_html( $value ) . '</a>';
|
571 |
+
|
572 |
+
default:
|
573 |
+
return '<strong>' . esc_html( $value ) . '</strong>';
|
574 |
+
}
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Method: Check if multisite.
|
579 |
+
*
|
580 |
+
* @return bool
|
581 |
+
*/
|
582 |
+
protected function is_multisite() {
|
583 |
+
return $this->_plugin->IsMultisite();
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Method: Check if the blog is main blog.
|
588 |
+
*
|
589 |
+
* @return bool
|
590 |
+
*/
|
591 |
+
protected function is_main_blog() {
|
592 |
+
return get_current_blog_id() == 1;
|
593 |
+
}
|
594 |
+
|
595 |
+
/**
|
596 |
+
* Method: Check if it is a specific view.
|
597 |
+
*
|
598 |
+
* @return bool
|
599 |
+
*/
|
600 |
+
protected function is_specific_view() {
|
601 |
+
// Filter $_POST array for security.
|
602 |
+
$post_array = filter_input_array( INPUT_POST );
|
603 |
+
|
604 |
+
return isset( $post_array['wsal-cbid'] ) && '0' != $post_array['wsal-cbid'];
|
605 |
+
}
|
606 |
+
|
607 |
+
/**
|
608 |
+
* Method: Get a specific view.
|
609 |
+
*
|
610 |
+
* @return int
|
611 |
+
*/
|
612 |
+
protected function get_specific_view() {
|
613 |
+
// Filter $_POST array for security.
|
614 |
+
$post_array = filter_input_array( INPUT_POST );
|
615 |
+
|
616 |
+
return isset( $post_array['wsal-cbid'] ) ? (int) $post_array['wsal-cbid'] : 0;
|
617 |
+
}
|
618 |
+
|
619 |
+
/**
|
620 |
+
* Method: Get view site id.
|
621 |
+
*
|
622 |
+
* @return int
|
623 |
+
*/
|
624 |
+
protected function get_view_site_id() {
|
625 |
+
switch ( true ) {
|
626 |
+
// Non-multisite.
|
627 |
+
case ! $this->is_multisite():
|
628 |
+
return 0;
|
629 |
+
// Multisite + main site view.
|
630 |
+
case $this->is_main_blog() && ! $this->is_specific_view():
|
631 |
+
return 0;
|
632 |
+
// Multisite + switched site view.
|
633 |
+
case $this->is_main_blog() && $this->is_specific_view():
|
634 |
+
return $this->get_specific_view();
|
635 |
+
// Multisite + local site view.
|
636 |
+
default:
|
637 |
+
return get_current_blog_id();
|
638 |
+
}
|
639 |
+
}
|
640 |
+
|
641 |
+
/**
|
642 |
+
* Method: Prepare items.
|
643 |
+
*/
|
644 |
+
public function prepare_items() {
|
645 |
+
if ( $this->_plugin->settings->IsArchivingEnabled() ) {
|
646 |
+
// Switch to Archive DB.
|
647 |
+
$selected_db = get_transient( 'wsal_wp_selected_db' );
|
648 |
+
if ( $selected_db && 'archive' == $selected_db ) {
|
649 |
+
$this->_plugin->settings->SwitchToArchiveDB();
|
650 |
+
}
|
651 |
+
}
|
652 |
+
|
653 |
+
$per_page = $this->_plugin->settings->GetViewPerPage();
|
654 |
+
|
655 |
+
$columns = $this->get_columns();
|
656 |
+
$hidden = array();
|
657 |
+
$sortable = $this->get_sortable_columns();
|
658 |
+
|
659 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
660 |
+
|
661 |
+
// $this->process_bulk_action();
|
662 |
+
// TO DO: Get rid of OccurrenceQuery and use the Occurence Model.
|
663 |
+
$query = new WSAL_Models_OccurrenceQuery();
|
664 |
+
|
665 |
+
$bid = (int) $this->get_view_site_id();
|
666 |
+
if ( $bid ) {
|
667 |
+
$query->addCondition( 'site_id = %s ', $bid );
|
668 |
+
}
|
669 |
+
|
670 |
+
$query = apply_filters( 'wsal_auditlog_query', $query );
|
671 |
+
|
672 |
+
$total_items = $query->getAdapter()->Count( $query );
|
673 |
+
|
674 |
+
// Filter $_GET and $_POST arrays for security.
|
675 |
+
$get_array = filter_input_array( INPUT_GET );
|
676 |
+
|
677 |
+
if ( empty( $get_array['orderby'] ) ) {
|
678 |
+
$query->addOrderBy( 'created_on', true );
|
679 |
+
} else {
|
680 |
+
$order_by_field = $get_array['orderby'];
|
681 |
+
|
682 |
+
$is_descending = true;
|
683 |
+
if ( ! empty( $get_array['order'] ) && 'asc' == $get_array['order'] ) {
|
684 |
+
$is_descending = false;
|
685 |
+
}
|
686 |
+
|
687 |
+
// TO DO: Allow order by meta values.
|
688 |
+
if ( 'scip' == $order_by_field ) {
|
689 |
+
$query->addMetaJoin();
|
690 |
+
$query->addOrderBy( 'CASE WHEN meta.name = "ClientIP" THEN meta.value END', $is_descending );
|
691 |
+
} elseif ( 'user' == $order_by_field ) {
|
692 |
+
$query->addMetaJoin();
|
693 |
+
$query->addOrderBy( 'CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $is_descending );
|
694 |
+
} else {
|
695 |
+
$tmp = new WSAL_Models_Occurrence();
|
696 |
+
// Making sure the field exists to order by.
|
697 |
+
if ( isset( $tmp->{$order_by_field} ) ) {
|
698 |
+
// TODO: We used to use a custom comparator ... is it safe to let MySQL do the ordering now?.
|
699 |
+
$query->addOrderBy( $get_array['orderby'], $is_descending );
|
700 |
+
|
701 |
+
} else {
|
702 |
+
$query->addOrderBy( 'created_on', true );
|
703 |
+
}
|
704 |
+
}
|
705 |
+
}
|
706 |
+
|
707 |
+
// @todo Modify $query instead
|
708 |
+
// @deprecated
|
709 |
+
// $data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
|
710 |
+
$query->setOffset( ($this->get_pagenum() - 1) * $per_page );
|
711 |
+
$query->setLimit( $per_page );
|
712 |
+
|
713 |
+
$this->items = $query->getAdapter()->Execute( $query );
|
714 |
+
|
715 |
+
$this->set_pagination_args(
|
716 |
+
array(
|
717 |
+
'total_items' => $total_items,
|
718 |
+
'per_page' => $per_page,
|
719 |
+
'total_pages' => ceil( $total_items / $per_page ),
|
720 |
+
)
|
721 |
+
);
|
722 |
+
}
|
723 |
+
|
724 |
+
/**
|
725 |
+
* Method: Output Single row.
|
726 |
+
*
|
727 |
+
* @param object $item - Item.
|
728 |
+
*/
|
729 |
+
public function single_row( $item ) {
|
730 |
+
if ( 9999 == $item->alert_id ) {
|
731 |
+
echo '<tr style="background-color: #D5E46E">';
|
732 |
+
$this->single_row_columns( $item );
|
733 |
+
echo '</tr>';
|
734 |
+
} else {
|
735 |
+
parent::single_row( $item );
|
736 |
+
}
|
737 |
+
}
|
738 |
}
|
classes/Autoloader.php
CHANGED
@@ -1,76 +1,93 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* Classes Auto Loader.
|
|
|
|
|
6 |
*/
|
7 |
class WSAL_Autoloader {
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* Classes Auto Loader.
|
4 |
+
*
|
5 |
+
* @package Wsal
|
6 |
*/
|
7 |
class WSAL_Autoloader {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Instance of WpSecurityAuditLog.
|
11 |
+
*
|
12 |
+
* @var object
|
13 |
+
*/
|
14 |
+
protected $plugin;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Paths to load.
|
18 |
+
*
|
19 |
+
* @var array
|
20 |
+
*/
|
21 |
+
protected $paths = array();
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Method: Constructor.
|
25 |
+
*
|
26 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
27 |
+
*/
|
28 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
29 |
+
$this->plugin = $plugin;
|
30 |
+
|
31 |
+
// Register autoloader.
|
32 |
+
spl_autoload_register( array( $this, 'LoadClass' ) );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Method: Register class.
|
37 |
+
*
|
38 |
+
* @param string $prefix - Prefix of the class.
|
39 |
+
* @param string $path - Path of the file.
|
40 |
+
*/
|
41 |
+
public function Register( $prefix, $path ) {
|
42 |
+
if ( ! isset( $this->paths[ $prefix ] ) ) {
|
43 |
+
$this->paths[ $prefix ] = array();
|
44 |
+
}
|
45 |
+
$this->paths[ $prefix ][] = rtrim( str_replace( '\\', '/', $path ), '/' ) . '/';
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* This is the class autoloader. You should not call this directly.
|
50 |
+
*
|
51 |
+
* @param string $class - Class name.
|
52 |
+
* @return boolean - True if class is found and loaded, false otherwise.
|
53 |
+
*/
|
54 |
+
public function LoadClass( $class ) {
|
55 |
+
foreach ( $this->paths as $prefix => $paths ) {
|
56 |
+
foreach ( $paths as $path ) {
|
57 |
+
if ( strstr( $class, $prefix ) !== false ) {
|
58 |
+
$file = $path . str_replace( '_', DIRECTORY_SEPARATOR, substr( $class, strlen( $prefix ) ) ) . '.php';
|
59 |
+
if ( file_exists( $file ) ) {
|
60 |
+
$s = $this->plugin->profiler->Start( 'Autoload ' . basename( $file ) );
|
61 |
+
require_once( $file );
|
62 |
+
$s->Stop();
|
63 |
+
return class_exists( $class, false ) || interface_exists( $class, false );
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Returns the class name of a particular file that contains the class.
|
73 |
+
*
|
74 |
+
* @param string $file File name.
|
75 |
+
* @return string|false Class name or false on error.
|
76 |
+
*/
|
77 |
+
public function GetClassFileClassName( $file ) {
|
78 |
+
$file = str_replace( '\\', '/', $file ); // Win/DOS hotfix.
|
79 |
+
|
80 |
+
foreach ( $this->paths as $prefix => $paths ) {
|
81 |
+
foreach ( $paths as $path ) {
|
82 |
+
if ( strstr( $file, $path ) !== false ) {
|
83 |
+
return str_replace(
|
84 |
+
array( $path, '/' ),
|
85 |
+
array( $prefix, '_' ),
|
86 |
+
substr( $file, 0, -4 ) // Remove '.php'.
|
87 |
+
);
|
88 |
+
}
|
89 |
+
}
|
90 |
+
}
|
91 |
+
return false;
|
92 |
+
}
|
93 |
}
|
classes/Connector/AbstractConnector.php
CHANGED
@@ -1,43 +1,80 @@
|
|
1 |
<?php
|
2 |
-
//require_once('ConnectorInterface.php');
|
3 |
-
require_once('wp-db-custom.php');
|
4 |
/**
|
|
|
|
|
|
|
|
|
5 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
* Adapter Classes loader class.
|
7 |
*
|
8 |
* Abstract class used as a class loader.
|
|
|
|
|
9 |
*/
|
10 |
-
abstract class WSAL_Connector_AbstractConnector
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
1 |
<?php
|
|
|
|
|
2 |
/**
|
3 |
+
* Class: Abstract Connector.
|
4 |
+
*
|
5 |
+
* Abstract class used as a class loader.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
// require_once('ConnectorInterface.php');.
|
16 |
+
require_once( 'wp-db-custom.php' );
|
17 |
+
|
18 |
+
/**
|
19 |
* Adapter Classes loader class.
|
20 |
*
|
21 |
* Abstract class used as a class loader.
|
22 |
+
*
|
23 |
+
* @package Wsal
|
24 |
*/
|
25 |
+
abstract class WSAL_Connector_AbstractConnector {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Connection Variable.
|
29 |
+
*
|
30 |
+
* @var null
|
31 |
+
*/
|
32 |
+
protected $connection = null;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Adapter Base Path.
|
36 |
+
*
|
37 |
+
* @var null
|
38 |
+
*/
|
39 |
+
protected $adaptersBasePath = null;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Adapter Directory Name.
|
43 |
+
*
|
44 |
+
* @var null
|
45 |
+
*/
|
46 |
+
protected $adaptersDirName = null;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Method: Constructor.
|
50 |
+
*
|
51 |
+
* @param string $adapters_dir_name - Adapter directory name.
|
52 |
+
*/
|
53 |
+
public function __construct( $adapters_dir_name = null ) {
|
54 |
+
$this->adaptersBasePath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Adapters' . DIRECTORY_SEPARATOR;
|
55 |
+
|
56 |
+
// require_once($this->adaptersBasePath . 'ActiveRecordInterface.php');
|
57 |
+
// require_once($this->adaptersBasePath . 'MetaInterface.php');
|
58 |
+
// require_once($this->adaptersBasePath . 'OccurrenceInterface.php');
|
59 |
+
// require_once($this->adaptersBasePath . 'QueryInterface.php');
|
60 |
+
if ( ! empty( $adapters_dir_name ) ) {
|
61 |
+
$this->adaptersDirName = $adapters_dir_name;
|
62 |
+
require_once( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'ActiveRecordAdapter.php' );
|
63 |
+
require_once( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'MetaAdapter.php' );
|
64 |
+
require_once( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'OccurrenceAdapter.php' );
|
65 |
+
require_once( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'QueryAdapter.php' );
|
66 |
+
require_once( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'TmpUserAdapter.php' );
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Method: Get adapters directory.
|
72 |
+
*/
|
73 |
+
public function getAdaptersDirectory() {
|
74 |
+
if ( ! empty( $this->adaptersBasePath ) && ! empty( $this->adaptersDirName ) ) {
|
75 |
+
return $this->adaptersBasePath . $this->adaptersDirName;
|
76 |
+
} else {
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
}
|
80 |
}
|
classes/Connector/ConnectorFactory.php
CHANGED
@@ -1,115 +1,147 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* Class WSAL_Connector_ConnectorFactory.
|
5 |
*
|
6 |
* Abstract class used for create the connector, only MySQL is implemented.
|
7 |
-
*
|
|
|
|
|
8 |
*/
|
9 |
-
abstract class WSAL_Connector_ConnectorFactory
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
//TO DO: Load connection config
|
36 |
-
if (self::$connector == null || !empty($config) || $reset) {
|
37 |
-
switch (strtolower($connectionConfig['type'])) {
|
38 |
-
//TO DO: Add other connectors
|
39 |
-
case 'mysql':
|
40 |
-
default:
|
41 |
-
//use config
|
42 |
-
self::$connector = new WSAL_Connector_MySQLDB($connectionConfig);
|
43 |
-
}
|
44 |
-
}
|
45 |
-
return self::$connector;
|
46 |
-
}
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Abstract Connector Factory.
|
4 |
+
*
|
5 |
+
* Abstract class used for create the connector, only MySQL is implemented.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* Class WSAL_Connector_ConnectorFactory.
|
17 |
*
|
18 |
* Abstract class used for create the connector, only MySQL is implemented.
|
19 |
+
*
|
20 |
+
* @todo Add other adapters.
|
21 |
+
* @package Wsal
|
22 |
*/
|
23 |
+
abstract class WSAL_Connector_ConnectorFactory {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Connector.
|
27 |
+
*
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
public static $connector;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Default Connector.
|
34 |
+
*
|
35 |
+
* @var bool
|
36 |
+
*/
|
37 |
+
public static $defaultConnector;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Adapter.
|
41 |
+
*
|
42 |
+
* @var string
|
43 |
+
*/
|
44 |
+
public static $adapter;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Returns the a default WPDB connector for saving options
|
48 |
+
*/
|
49 |
+
public static function GetDefaultConnector() {
|
50 |
+
return new WSAL_Connector_MySQLDB();
|
51 |
+
}
|
52 |
|
53 |
+
/**
|
54 |
+
* Returns a connector singleton
|
55 |
+
*
|
56 |
+
* @param array $config - Connection config.
|
57 |
+
* @param bool $reset - True if reset.
|
58 |
+
* @return WSAL_Connector_ConnectorInterface
|
59 |
+
*/
|
60 |
+
public static function GetConnector( $config = null, $reset = false ) {
|
61 |
+
if ( ! empty( $config ) ) {
|
62 |
+
$connection_config = $config;
|
63 |
+
} else {
|
64 |
+
$connection_config = self::GetConfig();
|
65 |
+
}
|
66 |
|
67 |
+
// TO DO: Load connection config.
|
68 |
+
if ( null == self::$connector || ! empty( $config ) || $reset ) {
|
69 |
+
switch ( strtolower( $connection_config['type'] ) ) {
|
70 |
+
// TO DO: Add other connectors.
|
71 |
+
case 'mysql':
|
72 |
+
default:
|
73 |
+
// Use config.
|
74 |
+
self::$connector = new WSAL_Connector_MySQLDB( $connection_config );
|
75 |
+
}
|
76 |
+
}
|
77 |
+
return self::$connector;
|
78 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
+
/**
|
81 |
+
* Get the adapter config stored in the DB
|
82 |
+
*
|
83 |
+
* @return array|null adapter config
|
84 |
+
*/
|
85 |
+
public static function GetConfig() {
|
86 |
+
$conf = new WSAL_Settings( WpSecurityAuditLog::GetInstance() );
|
87 |
+
$type = $conf->GetAdapterConfig( 'adapter-type' );
|
88 |
+
if ( empty( $type ) ) {
|
89 |
+
return null;
|
90 |
+
} else {
|
91 |
+
return array(
|
92 |
+
'type' => $conf->GetAdapterConfig( 'adapter-type' ),
|
93 |
+
'user' => $conf->GetAdapterConfig( 'adapter-user' ),
|
94 |
+
'password' => $conf->GetAdapterConfig( 'adapter-password' ),
|
95 |
+
'name' => $conf->GetAdapterConfig( 'adapter-name' ),
|
96 |
+
'hostname' => $conf->GetAdapterConfig( 'adapter-hostname' ),
|
97 |
+
'base_prefix' => $conf->GetAdapterConfig( 'adapter-base-prefix' ),
|
98 |
+
);
|
99 |
+
}
|
100 |
+
}
|
101 |
|
102 |
+
/**
|
103 |
+
* Check the adapter config with a test connection.
|
104 |
+
*
|
105 |
+
* @param string $type - Adapter type.
|
106 |
+
* @param string $user - Adapter user.
|
107 |
+
* @param string $password - Adapter password.
|
108 |
+
* @param string $name - Adapter name.
|
109 |
+
* @param string $hostname - Adapter hostname.
|
110 |
+
* @param string $base_prefix - Adapter base_prefix.
|
111 |
+
* @return boolean true|false
|
112 |
+
*/
|
113 |
+
public static function CheckConfig( $type, $user, $password, $name, $hostname, $base_prefix ) {
|
114 |
+
$result = false;
|
115 |
+
$config = self::GetConfigArray( $type, $user, $password, $name, $hostname, $base_prefix );
|
116 |
+
switch ( strtolower( $type ) ) {
|
117 |
+
// TO DO: Add other connectors.
|
118 |
+
case 'mysql':
|
119 |
+
default:
|
120 |
+
$test = new WSAL_Connector_MySQLDB( $config );
|
121 |
+
$result = $test->TestConnection();
|
122 |
+
}
|
123 |
+
return $result;
|
124 |
+
}
|
125 |
|
126 |
+
/**
|
127 |
+
* Create array config.
|
128 |
+
*
|
129 |
+
* @param string $type - Adapter type.
|
130 |
+
* @param string $user - Adapter user.
|
131 |
+
* @param string $password - Adapter password.
|
132 |
+
* @param string $name - Adapter name.
|
133 |
+
* @param string $hostname - Adapter hostname.
|
134 |
+
* @param string $base_prefix - Adapter base_prefix.
|
135 |
+
* @return array config
|
136 |
+
*/
|
137 |
+
public static function GetConfigArray( $type, $user, $password, $name, $hostname, $base_prefix ) {
|
138 |
+
return array(
|
139 |
+
'type' => $type,
|
140 |
+
'user' => $user,
|
141 |
+
'password' => $password,
|
142 |
+
'name' => $name,
|
143 |
+
'hostname' => $hostname,
|
144 |
+
'base_prefix' => $base_prefix,
|
145 |
+
);
|
146 |
+
}
|
147 |
}
|
classes/Connector/ConnectorInterface.php
CHANGED
@@ -1,16 +1,58 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* Interface used by the WSAL_Connector.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*/
|
7 |
-
interface WSAL_Connector_ConnectorInterface
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Connection Interface
|
4 |
*
|
5 |
* Interface used by the WSAL_Connector.
|
6 |
+
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Interface used by the WSAL_Connector.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
interface WSAL_Connector_ConnectorInterface {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Gets the adapter.
|
24 |
+
*
|
25 |
+
* @param string $class_name - Class name.
|
26 |
+
*/
|
27 |
+
public function getAdapter( $class_name );
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Get the connection.
|
31 |
+
*/
|
32 |
+
public function getConnection();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Close the connection.
|
36 |
+
*/
|
37 |
+
public function closeConnection();
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Is installed?
|
41 |
+
*/
|
42 |
+
public function isInstalled();
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Can migrate?
|
46 |
+
*/
|
47 |
+
public function canMigrate();
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Install all.
|
51 |
+
*/
|
52 |
+
public function installAll();
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Uninstall all.
|
56 |
+
*/
|
57 |
+
public function uninstallAll();
|
58 |
}
|
classes/Connector/MySQLDB.php
CHANGED
@@ -1,673 +1,688 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* MySQL Connector Class
|
5 |
* It uses wpdb WordPress DB Class
|
|
|
|
|
6 |
*/
|
7 |
-
class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
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 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: MySQL DB Connector.
|
4 |
+
*
|
5 |
+
* MySQL Connector Class
|
6 |
+
* It uses wpdb WordPress DB Class
|
7 |
+
*
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* MySQL Connector Class
|
18 |
* It uses wpdb WordPress DB Class
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Connection Configuration.
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $connectionConfig = null;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Constructor.
|
33 |
+
*
|
34 |
+
* @param array $connection_config - Connection config.
|
35 |
+
*/
|
36 |
+
public function __construct( $connection_config = null ) {
|
37 |
+
$this->connectionConfig = $connection_config;
|
38 |
+
parent::__construct( 'MySQL' );
|
39 |
+
require_once( $this->getAdaptersDirectory() . '/OptionAdapter.php' );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Test the connection.
|
44 |
+
*
|
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->connectionConfig;
|
50 |
+
$password = $this->decryptString( $connection_config['password'] );
|
51 |
+
$new_wpdb = new wpdbCustom( $connection_config['user'], $password, $connection_config['name'], $connection_config['hostname'] );
|
52 |
+
|
53 |
+
// Database Error.
|
54 |
+
if ( ! $new_wpdb->has_connected ) {
|
55 |
+
throw new Exception( 'Connection failed. Please check your connection details.' );
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Creates a connection and returns it
|
61 |
+
*
|
62 |
+
* @return Instance of WPDB
|
63 |
+
*/
|
64 |
+
private function createConnection() {
|
65 |
+
if ( ! empty( $this->connectionConfig ) ) {
|
66 |
+
// TO DO: Use the provided connection config.
|
67 |
+
$connection_config = $this->connectionConfig;
|
68 |
+
$password = $this->decryptString( $connection_config['password'] );
|
69 |
+
$new_wpdb = new wpdb( $connection_config['user'], $password, $connection_config['name'], $connection_config['hostname'] );
|
70 |
+
$new_wpdb->set_prefix( $connection_config['base_prefix'] );
|
71 |
+
return $new_wpdb;
|
72 |
+
} else {
|
73 |
+
global $wpdb;
|
74 |
+
return $wpdb;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Returns a wpdb instance
|
80 |
+
*
|
81 |
+
* @return wpdb
|
82 |
+
*/
|
83 |
+
public function getConnection() {
|
84 |
+
if ( ! empty( $this->connection ) ) {
|
85 |
+
return $this->connection;
|
86 |
+
} else {
|
87 |
+
$this->connection = $this->createConnection();
|
88 |
+
return $this->connection;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Close DB connection
|
94 |
+
*/
|
95 |
+
public function closeConnection() {
|
96 |
+
$current_wpdb = $this->getConnection();
|
97 |
+
$result = $current_wpdb->close();
|
98 |
+
return $result;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Gets an adapter for the specified model.
|
103 |
+
*
|
104 |
+
* @param string $class_name - Class name.
|
105 |
+
* @return WSAL_Adapters_MySQL_{class_name}
|
106 |
+
*/
|
107 |
+
public function getAdapter( $class_name ) {
|
108 |
+
$obj_name = $this->getAdapterClassName( $class_name );
|
109 |
+
return new $obj_name( $this->getConnection() );
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Gets an adapter class name for the specified model.
|
114 |
+
*
|
115 |
+
* @param string $class_name - Class name.
|
116 |
+
* @return WSAL_Adapters_MySQL_{class_name}
|
117 |
+
*/
|
118 |
+
protected function getAdapterClassName( $class_name ) {
|
119 |
+
return 'WSAL_Adapters_MySQL_' . $class_name;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Checks if the necessary tables are available
|
124 |
+
*
|
125 |
+
* @return bool true|false
|
126 |
+
*/
|
127 |
+
public function isInstalled() {
|
128 |
+
global $wpdb;
|
129 |
+
$table = $wpdb->base_prefix . 'wsal_occurrences';
|
130 |
+
return ($wpdb->get_var( 'SHOW TABLES LIKE "' . $table . '"' ) == $table);
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Checks if old version tables are available
|
135 |
+
*
|
136 |
+
* @return bool true|false
|
137 |
+
*/
|
138 |
+
public function canMigrate() {
|
139 |
+
$wpdb = $this->getConnection();
|
140 |
+
$table = $wpdb->base_prefix . 'wordpress_auditlog_events';
|
141 |
+
return ($wpdb->get_var( 'SHOW TABLES LIKE "' . $table . '"' ) == $table);
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Install all DB tables.
|
146 |
+
*
|
147 |
+
* @param bool $exclude_options - True if excluding.
|
148 |
+
*/
|
149 |
+
public function installAll( $exclude_options = false ) {
|
150 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
151 |
+
|
152 |
+
foreach ( glob( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php' ) as $file ) {
|
153 |
+
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
154 |
+
$file_name = $file_path[ count( $file_path ) - 1 ];
|
155 |
+
$class_name = $this->getAdapterClassName( str_replace( 'Adapter.php', '', $file_name ) );
|
156 |
+
|
157 |
+
$class = new $class_name( $this->getConnection() );
|
158 |
+
if ( $exclude_options && $class instanceof WSAL_Adapters_MySQL_Option ) {
|
159 |
+
continue;
|
160 |
+
}
|
161 |
+
|
162 |
+
// Exclude the tmp_users table.
|
163 |
+
if ( ! $exclude_options && $class instanceof WSAL_Adapters_MySQL_TmpUser ) {
|
164 |
+
continue;
|
165 |
+
}
|
166 |
+
|
167 |
+
if ( is_subclass_of( $class, 'WSAL_Adapters_MySQL_ActiveRecord' ) ) {
|
168 |
+
$class->Install();
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Uninstall all DB tables.
|
175 |
+
*/
|
176 |
+
public function uninstallAll() {
|
177 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
178 |
+
|
179 |
+
foreach ( glob( $this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php' ) as $file ) {
|
180 |
+
$file_path = explode( DIRECTORY_SEPARATOR, $file );
|
181 |
+
$file_name = $file_path[ count( $file_path ) - 1 ];
|
182 |
+
$class_name = $this->getAdapterClassName( str_replace( 'Adapter.php', '', $file_name ) );
|
183 |
+
|
184 |
+
$class = new $class_name( $this->getConnection() );
|
185 |
+
if ( is_subclass_of( $class, 'WSAL_Adapters_MySQL_ActiveRecord' ) ) {
|
186 |
+
$class->Uninstall();
|
187 |
+
}
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Increase occurrence ID
|
193 |
+
*
|
194 |
+
* @return integer MAX(id)
|
195 |
+
*/
|
196 |
+
private function GetIncreaseOccurrence() {
|
197 |
+
$_wpdb = $this->getConnection();
|
198 |
+
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
199 |
+
$sql = 'SELECT MAX(id) FROM ' . $occurrence_new->GetTable();
|
200 |
+
return (int) $_wpdb->get_var( $sql );
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Migrate Metadata from WP DB to External DB.
|
205 |
+
*
|
206 |
+
* @param integer $index - Index.
|
207 |
+
* @param integer $limit - Limit.
|
208 |
+
*/
|
209 |
+
public function MigrateMeta( $index, $limit ) {
|
210 |
+
$result = null;
|
211 |
+
$offset = ($index * $limit);
|
212 |
+
global $wpdb;
|
213 |
+
$_wpdb = $this->getConnection();
|
214 |
+
// Add +1 because an alert is generated after delete the metadata table.
|
215 |
+
$increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
|
216 |
+
|
217 |
+
// Load data Meta from WP.
|
218 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $wpdb );
|
219 |
+
if ( ! $meta->IsInstalled() ) {
|
220 |
+
$result['empty'] = true;
|
221 |
+
return $result;
|
222 |
+
}
|
223 |
+
$sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
224 |
+
$metadata = $wpdb->get_results( $sql, ARRAY_A );
|
225 |
+
|
226 |
+
// Insert data to External DB.
|
227 |
+
if ( ! empty( $metadata ) ) {
|
228 |
+
$meta_new = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
229 |
+
|
230 |
+
$index++;
|
231 |
+
$sql = 'INSERT INTO ' . $meta_new->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
|
232 |
+
foreach ( $metadata as $entry ) {
|
233 |
+
$occurrence_id = intval( $entry['occurrence_id'] ) + $increase_occurrence_id;
|
234 |
+
$sql .= '(' . $occurrence_id . ', \'' . $entry['name'] . '\', \'' . str_replace( array( "'", "\'" ), "\'", $entry['value'] ) . '\'), ';
|
235 |
+
}
|
236 |
+
$sql = rtrim( $sql, ', ' );
|
237 |
+
$_wpdb->query( $sql );
|
238 |
+
|
239 |
+
$result['complete'] = false;
|
240 |
+
} else {
|
241 |
+
$result['complete'] = true;
|
242 |
+
$this->DeleteAfterMigrate( $meta );
|
243 |
+
}
|
244 |
+
$result['index'] = $index;
|
245 |
+
return $result;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Migrate Occurrences from WP DB to External DB.
|
250 |
+
*
|
251 |
+
* @param integer $index - Index.
|
252 |
+
* @param integer $limit - Limit.
|
253 |
+
*/
|
254 |
+
public function MigrateOccurrence( $index, $limit ) {
|
255 |
+
$result = null;
|
256 |
+
$offset = ($index * $limit);
|
257 |
+
global $wpdb;
|
258 |
+
$_wpdb = $this->getConnection();
|
259 |
+
|
260 |
+
// Load data Occurrences from WP.
|
261 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $wpdb );
|
262 |
+
if ( ! $occurrence->IsInstalled() ) {
|
263 |
+
$result['empty'] = true;
|
264 |
+
return $result;
|
265 |
+
}
|
266 |
+
$sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
267 |
+
$occurrences = $wpdb->get_results( $sql, ARRAY_A );
|
268 |
+
|
269 |
+
// Insert data to External DB.
|
270 |
+
if ( ! empty( $occurrences ) ) {
|
271 |
+
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
272 |
+
|
273 |
+
$index++;
|
274 |
+
$sql = 'INSERT INTO ' . $occurrence_new->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
|
275 |
+
foreach ( $occurrences as $entry ) {
|
276 |
+
$sql .= '(' . $entry['site_id'] . ', ' . $entry['alert_id'] . ', ' . $entry['created_on'] . ', ' . $entry['is_read'] . '), ';
|
277 |
+
}
|
278 |
+
$sql = rtrim( $sql, ', ' );
|
279 |
+
$_wpdb->query( $sql );
|
280 |
+
|
281 |
+
$result['complete'] = false;
|
282 |
+
} else {
|
283 |
+
$result['complete'] = true;
|
284 |
+
$this->DeleteAfterMigrate( $occurrence );
|
285 |
+
}
|
286 |
+
$result['index'] = $index;
|
287 |
+
return $result;
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Migrate Back Occurrences from External DB to WP DB.
|
292 |
+
*
|
293 |
+
* @param integer $index - Index.
|
294 |
+
* @param integer $limit - Limit.
|
295 |
+
*/
|
296 |
+
public function MigrateBackOccurrence( $index, $limit ) {
|
297 |
+
$result = null;
|
298 |
+
$offset = ($index * $limit);
|
299 |
+
global $wpdb;
|
300 |
+
$_wpdb = $this->getConnection();
|
301 |
+
|
302 |
+
// Load data Occurrences from External DB.
|
303 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
304 |
+
if ( ! $occurrence->IsInstalled() ) {
|
305 |
+
$result['empty'] = true;
|
306 |
+
return $result;
|
307 |
+
}
|
308 |
+
$sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
309 |
+
$occurrences = $_wpdb->get_results( $sql, ARRAY_A );
|
310 |
+
|
311 |
+
// Insert data to WP.
|
312 |
+
if ( ! empty( $occurrences ) ) {
|
313 |
+
$occurrence_wp = new WSAL_Adapters_MySQL_Occurrence( $wpdb );
|
314 |
+
|
315 |
+
$index++;
|
316 |
+
$sql = 'INSERT INTO ' . $occurrence_wp->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
|
317 |
+
foreach ( $occurrences as $entry ) {
|
318 |
+
$sql .= '(' . $entry['id'] . ', ' . $entry['site_id'] . ', ' . $entry['alert_id'] . ', ' . $entry['created_on'] . ', ' . $entry['is_read'] . '), ';
|
319 |
+
}
|
320 |
+
$sql = rtrim( $sql, ', ' );
|
321 |
+
$wpdb->query( $sql );
|
322 |
+
|
323 |
+
$result['complete'] = false;
|
324 |
+
} else {
|
325 |
+
$result['complete'] = true;
|
326 |
+
}
|
327 |
+
$result['index'] = $index;
|
328 |
+
return $result;
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Migrate Back Metadata from External DB to WP DB.
|
333 |
+
*
|
334 |
+
* @param integer $index - Index.
|
335 |
+
* @param integer $limit - Limit.
|
336 |
+
*/
|
337 |
+
public function MigrateBackMeta( $index, $limit ) {
|
338 |
+
$result = null;
|
339 |
+
$offset = ($index * $limit);
|
340 |
+
global $wpdb;
|
341 |
+
$_wpdb = $this->getConnection();
|
342 |
+
|
343 |
+
// Load data Meta from External DB.
|
344 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
345 |
+
if ( ! $meta->IsInstalled() ) {
|
346 |
+
$result['empty'] = true;
|
347 |
+
return $result;
|
348 |
+
}
|
349 |
+
$sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
350 |
+
$metadata = $_wpdb->get_results( $sql, ARRAY_A );
|
351 |
+
|
352 |
+
// Insert data to WP.
|
353 |
+
if ( ! empty( $metadata ) ) {
|
354 |
+
$meta_wp = new WSAL_Adapters_MySQL_Meta( $wpdb );
|
355 |
+
|
356 |
+
$index++;
|
357 |
+
$sql = 'INSERT INTO ' . $meta_wp->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
|
358 |
+
foreach ( $metadata as $entry ) {
|
359 |
+
$sql .= '(' . $entry['occurrence_id'] . ', \'' . $entry['name'] . '\', \'' . str_replace( array( "'", "\'" ), "\'", $entry['value'] ) . '\'), ';
|
360 |
+
}
|
361 |
+
$sql = rtrim( $sql, ', ' );
|
362 |
+
$wpdb->query( $sql );
|
363 |
+
|
364 |
+
$result['complete'] = false;
|
365 |
+
} else {
|
366 |
+
$result['complete'] = true;
|
367 |
+
}
|
368 |
+
$result['index'] = $index;
|
369 |
+
return $result;
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Delete after Migrate alerts.
|
374 |
+
*
|
375 |
+
* @param object $record - Type of record.
|
376 |
+
*/
|
377 |
+
private function DeleteAfterMigrate( $record ) {
|
378 |
+
global $wpdb;
|
379 |
+
$sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
|
380 |
+
$wpdb->query( $sql );
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Encrypt plain text.
|
385 |
+
* Encrypt string, before saves it to the DB.
|
386 |
+
*
|
387 |
+
* @param string $plaintext - Plain text that is going to be encrypted.
|
388 |
+
* @return string
|
389 |
+
* @since 2.6.3
|
390 |
+
*/
|
391 |
+
public function encryptString( $plaintext ) {
|
392 |
+
// Check for previous version.
|
393 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
394 |
+
$version = $plugin->GetGlobalOption( 'version', '0.0.0' );
|
395 |
+
|
396 |
+
if ( -1 === version_compare( $version, '2.6.2' ) ) {
|
397 |
+
return $this->encryptString_fallback( $plaintext );
|
398 |
+
}
|
399 |
+
|
400 |
+
$ciphertext = false;
|
401 |
+
|
402 |
+
$encrypt_method = 'AES-256-CBC';
|
403 |
+
$secret_key = $this->truncateKey();
|
404 |
+
$secret_iv = $this->get_openssl_iv();
|
405 |
+
|
406 |
+
// Hash the key.
|
407 |
+
$key = hash( 'sha256', $secret_key );
|
408 |
+
|
409 |
+
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning.
|
410 |
+
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
|
411 |
+
|
412 |
+
$ciphertext = openssl_encrypt( $plaintext, $encrypt_method, $key, 0, $iv );
|
413 |
+
$ciphertext = base64_encode( $ciphertext );
|
414 |
+
|
415 |
+
return $ciphertext;
|
416 |
+
}
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Encrypt plain text - Fallback.
|
420 |
+
*
|
421 |
+
* @param string $plaintext - Plain text that is going to be encrypted.
|
422 |
+
* @return string
|
423 |
+
* @since 2.6.3
|
424 |
+
*/
|
425 |
+
public function encryptString_fallback( $plaintext ) {
|
426 |
+
$iv_size = mcrypt_get_iv_size( MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC );
|
427 |
+
$iv = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
|
428 |
+
$key = $this->truncateKey();
|
429 |
+
$ciphertext = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv );
|
430 |
+
$ciphertext = $iv . $ciphertext;
|
431 |
+
$ciphertext_base64 = base64_encode( $ciphertext );
|
432 |
+
return $ciphertext_base64;
|
433 |
+
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Decrypt the encrypted string.
|
437 |
+
* Decrypt string, after reads it from the DB.
|
438 |
+
*
|
439 |
+
* @param string $ciphertext_base64 - encrypted string.
|
440 |
+
* @return string
|
441 |
+
* @since 2.6.3
|
442 |
+
*/
|
443 |
+
public function decryptString( $ciphertext_base64 ) {
|
444 |
+
// Check for previous version.
|
445 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
446 |
+
$version = $plugin->GetGlobalOption( 'version', '0.0.0' );
|
447 |
+
|
448 |
+
if ( -1 === version_compare( $version, '2.6.2' ) ) {
|
449 |
+
return $this->decryptString_fallback( $ciphertext_base64 );
|
450 |
+
}
|
451 |
+
|
452 |
+
$plaintext = false;
|
453 |
+
|
454 |
+
$encrypt_method = 'AES-256-CBC';
|
455 |
+
$secret_key = $this->truncateKey();
|
456 |
+
$secret_iv = $this->get_openssl_iv();
|
457 |
+
|
458 |
+
// Hash the key.
|
459 |
+
$key = hash( 'sha256', $secret_key );
|
460 |
+
|
461 |
+
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning.
|
462 |
+
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
|
463 |
+
|
464 |
+
$plaintext = openssl_decrypt( base64_decode( $ciphertext_base64 ), $encrypt_method, $key, 0, $iv );
|
465 |
+
|
466 |
+
return $plaintext;
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Decrypt the encrypted string - Fallback.
|
471 |
+
*
|
472 |
+
* @param string $ciphertext_base64 - encrypted string.
|
473 |
+
* @return string
|
474 |
+
* @since 2.6.3
|
475 |
+
*/
|
476 |
+
public function decryptString_fallback( $ciphertext_base64 ) {
|
477 |
+
$ciphertext_dec = base64_decode( $ciphertext_base64 );
|
478 |
+
$iv_size = mcrypt_get_iv_size( MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC );
|
479 |
+
$iv_dec = substr( $ciphertext_dec, 0, $iv_size );
|
480 |
+
$ciphertext_dec = substr( $ciphertext_dec, $iv_size );
|
481 |
+
$key = $this->truncateKey();
|
482 |
+
$plaintext_dec = mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec );
|
483 |
+
return rtrim( $plaintext_dec, "\0" );
|
484 |
+
}
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Mirroring Occurrences and Metadata Tables.
|
488 |
+
* Read from current DB and copy into Mirroring DB.
|
489 |
+
*
|
490 |
+
* @param array $args - Archive Database and limit by date.
|
491 |
+
*/
|
492 |
+
public function MirroringAlertsToDB( $args ) {
|
493 |
+
$last_created_on = null;
|
494 |
+
$first_occurrence_id = null;
|
495 |
+
$_wpdb = $this->getConnection();
|
496 |
+
$mirroring_db = $args['mirroring_db'];
|
497 |
+
|
498 |
+
// Load data Occurrences from WP.
|
499 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
500 |
+
if ( ! $occurrence->IsInstalled() ) {
|
501 |
+
return null;
|
502 |
+
}
|
503 |
+
|
504 |
+
$sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' WHERE created_on > ' . $args['last_created_on'];
|
505 |
+
$occurrences = $_wpdb->get_results( $sql, ARRAY_A );
|
506 |
+
|
507 |
+
if ( ! empty( $occurrences ) ) {
|
508 |
+
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $mirroring_db );
|
509 |
+
|
510 |
+
$sql = 'INSERT INTO ' . $occurrence_new->GetTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
|
511 |
+
foreach ( $occurrences as $entry ) {
|
512 |
+
$sql .= '(' . $entry['id'] . ', ' . $entry['site_id'] . ', ' . $entry['alert_id'] . ', ' . $entry['created_on'] . ', ' . $entry['is_read'] . '), ';
|
513 |
+
$last_created_on = $entry['created_on'];
|
514 |
+
// Save the first id.
|
515 |
+
if ( empty( $first_occurrence_id ) ) {
|
516 |
+
$first_occurrence_id = $entry['id'];
|
517 |
+
}
|
518 |
+
}
|
519 |
+
$sql = rtrim( $sql, ', ' );
|
520 |
+
$mirroring_db->query( $sql );
|
521 |
+
}
|
522 |
+
|
523 |
+
// Load data Meta from WP.
|
524 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
525 |
+
if ( ! $meta->IsInstalled() ) {
|
526 |
+
return null;
|
527 |
+
}
|
528 |
+
if ( ! empty( $first_occurrence_id ) ) {
|
529 |
+
$sql = 'SELECT * FROM ' . $meta->GetTable() . ' WHERE occurrence_id >= ' . $first_occurrence_id;
|
530 |
+
$metadata = $_wpdb->get_results( $sql, ARRAY_A );
|
531 |
+
|
532 |
+
if ( ! empty( $metadata ) ) {
|
533 |
+
$meta_new = new WSAL_Adapters_MySQL_Meta( $mirroring_db );
|
534 |
+
|
535 |
+
$sql = 'INSERT INTO ' . $meta_new->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
|
536 |
+
foreach ( $metadata as $entry ) {
|
537 |
+
$sql .= '(' . $entry['occurrence_id'] . ', \'' . $entry['name'] . '\', \'' . str_replace( array( "'", "\'" ), "\'", $entry['value'] ) . '\'), ';
|
538 |
+
}
|
539 |
+
$sql = rtrim( $sql, ', ' );
|
540 |
+
$mirroring_db->query( $sql );
|
541 |
+
}
|
542 |
+
}
|
543 |
+
return $last_created_on;
|
544 |
+
}
|
545 |
+
|
546 |
+
/**
|
547 |
+
* Archiving Occurrences Table.
|
548 |
+
* Read from current DB and copy into Archive DB.
|
549 |
+
*
|
550 |
+
* @param array $args - Archive Database and limit by count OR by date.
|
551 |
+
*/
|
552 |
+
public function ArchiveOccurrence( $args ) {
|
553 |
+
$_wpdb = $this->getConnection();
|
554 |
+
$archive_db = $args['archive_db'];
|
555 |
+
|
556 |
+
// Load data Occurrences from WP.
|
557 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
558 |
+
if ( ! $occurrence->IsInstalled() ) {
|
559 |
+
return null;
|
560 |
+
}
|
561 |
+
if ( ! empty( $args['by_date'] ) ) {
|
562 |
+
$sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' WHERE created_on <= ' . $args['by_date'];
|
563 |
+
}
|
564 |
+
|
565 |
+
if ( ! empty( $args['by_limit'] ) ) {
|
566 |
+
$sql = 'SELECT occ.* FROM ' . $occurrence->GetTable() . ' occ
|
567 |
+
LEFT JOIN (SELECT id FROM ' . $occurrence->GetTable() . ' order by created_on DESC limit ' . $args['by_limit'] . ') as ids
|
568 |
+
on ids.id = occ.id
|
569 |
+
WHERE ids.id IS NULL';
|
570 |
+
}
|
571 |
+
if ( ! empty( $args['last_created_on'] ) ) {
|
572 |
+
$sql .= ' AND created_on > ' . $args['last_created_on'];
|
573 |
+
}
|
574 |
+
$sql .= ' ORDER BY created_on ASC';
|
575 |
+
if ( ! empty( $args['limit'] ) ) {
|
576 |
+
$sql .= ' LIMIT ' . $args['limit'];
|
577 |
+
}
|
578 |
+
$occurrences = $_wpdb->get_results( $sql, ARRAY_A );
|
579 |
+
|
580 |
+
// Insert data to Archive DB.
|
581 |
+
if ( ! empty( $occurrences ) ) {
|
582 |
+
$last = end( $occurrences );
|
583 |
+
$args['last_created_on'] = $last['created_on'];
|
584 |
+
$args['occurence_ids'] = array();
|
585 |
+
|
586 |
+
$occurrence_new = new WSAL_Adapters_MySQL_Occurrence( $archive_db );
|
587 |
+
|
588 |
+
$sql = 'INSERT INTO ' . $occurrence_new->GetTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
|
589 |
+
foreach ( $occurrences as $entry ) {
|
590 |
+
$sql .= '(' . $entry['id'] . ', ' . $entry['site_id'] . ', ' . $entry['alert_id'] . ', ' . $entry['created_on'] . ', ' . $entry['is_read'] . '), ';
|
591 |
+
$args['occurence_ids'][] = $entry['id'];
|
592 |
+
}
|
593 |
+
$sql = rtrim( $sql, ', ' );
|
594 |
+
$archive_db->query( $sql );
|
595 |
+
return $args;
|
596 |
+
} else {
|
597 |
+
return false;
|
598 |
+
}
|
599 |
+
}
|
600 |
+
|
601 |
+
/**
|
602 |
+
* Archiving Metadata Table.
|
603 |
+
* Read from current DB and copy into Archive DB.
|
604 |
+
*
|
605 |
+
* @param array $args - Archive Database and occurrences IDs.
|
606 |
+
*/
|
607 |
+
public function ArchiveMeta( $args ) {
|
608 |
+
$_wpdb = $this->getConnection();
|
609 |
+
$archive_db = $args['archive_db'];
|
610 |
+
|
611 |
+
// Load data Meta from WP.
|
612 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
613 |
+
if ( ! $meta->IsInstalled() ) {
|
614 |
+
return null;
|
615 |
+
}
|
616 |
+
$s_occurence_ids = implode( ', ', $args['occurence_ids'] );
|
617 |
+
$sql = 'SELECT * FROM ' . $meta->GetTable() . ' WHERE occurrence_id IN (' . $s_occurence_ids . ')';
|
618 |
+
$metadata = $_wpdb->get_results( $sql, ARRAY_A );
|
619 |
+
|
620 |
+
// Insert data to Archive DB.
|
621 |
+
if ( ! empty( $metadata ) ) {
|
622 |
+
$meta_new = new WSAL_Adapters_MySQL_Meta( $archive_db );
|
623 |
+
|
624 |
+
$sql = 'INSERT INTO ' . $meta_new->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
|
625 |
+
foreach ( $metadata as $entry ) {
|
626 |
+
$sql .= '(' . $entry['occurrence_id'] . ', \'' . $entry['name'] . '\', \'' . str_replace( array( "'", "\'" ), "\'", $entry['value'] ) . '\'), ';
|
627 |
+
}
|
628 |
+
$sql = rtrim( $sql, ', ' );
|
629 |
+
$archive_db->query( $sql );
|
630 |
+
return $args;
|
631 |
+
} else {
|
632 |
+
return false;
|
633 |
+
}
|
634 |
+
}
|
635 |
+
|
636 |
+
/**
|
637 |
+
* Delete Occurrences and Metadata after archiving.
|
638 |
+
*
|
639 |
+
* @param array $args - Archive Database and occurrences IDs.
|
640 |
+
*/
|
641 |
+
public function DeleteAfterArchive( $args ) {
|
642 |
+
$_wpdb = $this->getConnection();
|
643 |
+
$archive_db = $args['archive_db'];
|
644 |
+
|
645 |
+
$s_occurence_ids = implode( ', ', $args['occurence_ids'] );
|
646 |
+
|
647 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence( $_wpdb );
|
648 |
+
$sql = 'DELETE FROM ' . $occurrence->GetTable() . ' WHERE id IN (' . $s_occurence_ids . ')';
|
649 |
+
$_wpdb->query( $sql );
|
650 |
+
|
651 |
+
$meta = new WSAL_Adapters_MySQL_Meta( $_wpdb );
|
652 |
+
$sql = 'DELETE FROM ' . $meta->GetTable() . ' WHERE occurrence_id IN (' . $s_occurence_ids . ')';
|
653 |
+
$_wpdb->query( $sql );
|
654 |
+
}
|
655 |
+
|
656 |
+
/**
|
657 |
+
* Truncate string longer than 32 characters.
|
658 |
+
* Authentication Unique Key @see wp-config.php
|
659 |
+
*
|
660 |
+
* @return string AUTH_KEY
|
661 |
+
*/
|
662 |
+
private function truncateKey() {
|
663 |
+
if ( ! defined( 'AUTH_KEY' ) ) {
|
664 |
+
return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
|
665 |
+
}
|
666 |
+
$key_size = strlen( AUTH_KEY );
|
667 |
+
if ( $key_size > 32 ) {
|
668 |
+
return substr( AUTH_KEY, 0, 32 );
|
669 |
+
} else {
|
670 |
+
return AUTH_KEY;
|
671 |
+
}
|
672 |
+
}
|
673 |
+
|
674 |
+
/**
|
675 |
+
* Get OpenSSL IV for DB.
|
676 |
+
*
|
677 |
+
* @since 2.6.3
|
678 |
+
*/
|
679 |
+
private function get_openssl_iv() {
|
680 |
+
$secret_openssl_iv = 'і-(аэ┤#≥и┴зейН';
|
681 |
+
$key_size = strlen( $secret_openssl_iv );
|
682 |
+
if ( $key_size > 32 ) {
|
683 |
+
return substr( $secret_openssl_iv, 0, 32 );
|
684 |
+
} else {
|
685 |
+
return $secret_openssl_iv;
|
686 |
+
}
|
687 |
+
}
|
688 |
}
|
classes/Connector/wp-db-custom.php
CHANGED
@@ -1,44 +1,59 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* Test the DB connection.
|
5 |
* It uses wpdb WordPress DB Class.
|
|
|
|
|
6 |
*/
|
7 |
-
class wpdbCustom extends wpdb
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
|
42 |
-
|
43 |
-
|
44 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Custom DB Class
|
4 |
+
*
|
5 |
+
* Test the DB connection.
|
6 |
+
* It uses wpdb WordPress DB Class.
|
7 |
+
*
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Test the DB connection.
|
18 |
* It uses wpdb WordPress DB Class.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class wpdbCustom extends wpdb {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Overwrite wpdb class for set $allow_bail to false
|
26 |
+
* and hide the print of the error
|
27 |
+
*
|
28 |
+
* @global string $wp_version
|
29 |
+
* @param string $dbuser - MySQL database user.
|
30 |
+
* @param string $dbpassword - MySQL database password.
|
31 |
+
* @param string $dbname - MySQL database name.
|
32 |
+
* @param string $dbhost - MySQL database host.
|
33 |
+
*/
|
34 |
+
public function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) {
|
35 |
+
register_shutdown_function( array( $this, '__destruct' ) );
|
36 |
+
if ( WP_DEBUG && WP_DEBUG_DISPLAY ) {
|
37 |
+
$this->show_errors();
|
38 |
+
}
|
39 |
+
if ( function_exists( 'mysqli_connect' ) ) {
|
40 |
+
if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
|
41 |
+
$this->use_mysqli = ! WP_USE_EXT_MYSQL;
|
42 |
+
} elseif ( version_compare( phpversion(), '5.5', '>=' ) || ! function_exists( 'mysql_connect' ) ) {
|
43 |
+
$this->use_mysqli = true;
|
44 |
+
} elseif ( false !== strpos( $GLOBALS['wp_version'], '-' ) ) {
|
45 |
+
$this->use_mysqli = true;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
$this->dbuser = $dbuser;
|
49 |
+
$this->dbpassword = $dbpassword;
|
50 |
+
$this->dbname = $dbname;
|
51 |
+
$this->dbhost = $dbhost;
|
52 |
+
// wp-config.php creation will manually connect when ready.
|
53 |
+
if ( defined( 'WP_SETUP_CONFIG' ) ) {
|
54 |
+
return;
|
55 |
+
}
|
56 |
|
57 |
+
$this->db_connect( false );
|
58 |
+
}
|
59 |
}
|
classes/ConstantManager.php
CHANGED
@@ -1,96 +1,104 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
* Class used for Constants,
|
6 |
* E_NOTICE, E_WARNING, E_CRITICAL, etc.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_ConstantManager
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
3 |
* Class used for Constants,
|
4 |
* E_NOTICE, E_WARNING, E_CRITICAL, etc.
|
5 |
+
*
|
6 |
+
* @package Wsal
|
7 |
*/
|
8 |
+
class WSAL_ConstantManager {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Constants array.
|
12 |
+
*
|
13 |
+
* @var array
|
14 |
+
*/
|
15 |
+
protected $_constants = array();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Use an existing PHP constant.
|
19 |
+
*
|
20 |
+
* @param string $name - Constant name.
|
21 |
+
* @param string $description - Constant description.
|
22 |
+
*/
|
23 |
+
public function UseConstant( $name, $description = '' ) {
|
24 |
+
$this->_constants[] = (object) array(
|
25 |
+
'name' => $name,
|
26 |
+
'value' => constant( $name ),
|
27 |
+
'description' => $description,
|
28 |
+
);
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Add new PHP constant.
|
33 |
+
*
|
34 |
+
* @param string $name - Constant name.
|
35 |
+
* @param integer|string $value - Constant value.
|
36 |
+
* @param string $description - Constant description.
|
37 |
+
* @throws string - Error if a constant is already defined.
|
38 |
+
*/
|
39 |
+
public function AddConstant( $name, $value, $description = '' ) {
|
40 |
+
// Check for constant conflict and define new one if required.
|
41 |
+
if ( defined( $name ) && constant( $name ) !== $value ) {
|
42 |
+
throw new Exception( 'Constant already defined with a different value.' );
|
43 |
+
} else {
|
44 |
+
define( $name, $value );
|
45 |
+
}
|
46 |
+
// Add constant to da list.
|
47 |
+
$this->UseConstant( $name, $description );
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Add multiple constants in one go.
|
52 |
+
*
|
53 |
+
* @param array $items - Array of arrays with name, value, description pairs.
|
54 |
+
*/
|
55 |
+
public function AddConstants( $items ) {
|
56 |
+
foreach ( $items as $item ) {
|
57 |
+
$this->AddConstant(
|
58 |
+
$item['name'],
|
59 |
+
$item['value'],
|
60 |
+
$item['description']
|
61 |
+
);
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Use multiple constants in one go.
|
67 |
+
*
|
68 |
+
* @param array $items - Array of arrays with name, description pairs.
|
69 |
+
*/
|
70 |
+
public function UseConstants( $items ) {
|
71 |
+
foreach ( $items as $item ) {
|
72 |
+
$this->UseConstant(
|
73 |
+
$item['name'],
|
74 |
+
$item['description']
|
75 |
+
);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Get constant details by a particular detail.
|
81 |
+
*
|
82 |
+
* @param string $what - The type of detail: 'name', 'value'.
|
83 |
+
* @param mixed $value - The detail expected value.
|
84 |
+
* @param mix $default - Default value of constant.
|
85 |
+
* @throws string - Error if detail type is unexpected.
|
86 |
+
* @return mixed Either constant details (props: name, value, description) or $default if not found.
|
87 |
+
*/
|
88 |
+
public function GetConstantBy( $what, $value, $default = null ) {
|
89 |
+
// Make sure we do have some constants.
|
90 |
+
if ( count( $this->_constants ) ) {
|
91 |
+
// Make sure that constants do have a $what property.
|
92 |
+
if ( ! isset( $this->_constants[0]->$what ) ) {
|
93 |
+
throw new Exception( 'Unexpected detail type "' . $what . '".' );
|
94 |
+
}
|
95 |
+
// Return constant match the property value.
|
96 |
+
foreach ( $this->_constants as $constant ) {
|
97 |
+
if ( $constant->$what == $value ) {
|
98 |
+
return $constant;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
return $default;
|
103 |
+
}
|
104 |
}
|
classes/EDD_SL_Plugin_Updater.php
CHANGED
@@ -1,173 +1,221 @@
|
|
1 |
<?php
|
2 |
-
// uncomment this line for testing
|
3 |
-
//set_site_transient( 'update_plugins', null );
|
4 |
-
|
5 |
/**
|
|
|
|
|
|
|
|
|
6 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
* Allows plugins to use their own update API.
|
8 |
*
|
9 |
* @author Pippin Williamson
|
10 |
* @version 1.2
|
|
|
11 |
*/
|
12 |
-
class EDD_SL_Plugin_Updater
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
}
|
1 |
<?php
|
|
|
|
|
|
|
2 |
/**
|
3 |
+
* Class: Plugin Updater.
|
4 |
+
*
|
5 |
+
* Allowes plugins to use their own update API.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
// Uncomment this line for testing.
|
16 |
+
// set_site_transient( 'update_plugins', null );
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Class: Plugin Updater.
|
20 |
+
*
|
21 |
* Allows plugins to use their own update API.
|
22 |
*
|
23 |
* @author Pippin Williamson
|
24 |
* @version 1.2
|
25 |
+
* @package Wsal
|
26 |
*/
|
27 |
+
class EDD_SL_Plugin_Updater {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* API URL.
|
31 |
+
*
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
private $api_url = '';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* API Data.
|
38 |
+
*
|
39 |
+
* @var array
|
40 |
+
*/
|
41 |
+
private $api_data = array();
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Plugin Name.
|
45 |
+
*
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
+
private $name = '';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* SLug.
|
52 |
+
*
|
53 |
+
* @var string
|
54 |
+
*/
|
55 |
+
private $slug = '';
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Check?
|
59 |
+
*
|
60 |
+
* @var bool
|
61 |
+
*/
|
62 |
+
private $do_check = false;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Class constructor.
|
66 |
+
*
|
67 |
+
* @uses plugin_basename()
|
68 |
+
* @uses hook()
|
69 |
+
*
|
70 |
+
* @param string $_api_url The URL pointing to the custom API endpoint.
|
71 |
+
* @param string $_plugin_file Path to the plugin file.
|
72 |
+
* @param array $_api_data Optional data to send with API calls.
|
73 |
+
* @return void
|
74 |
+
*/
|
75 |
+
public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
76 |
+
$this->api_url = trailingslashit( $_api_url );
|
77 |
+
$this->api_data = urlencode_deep( $_api_data );
|
78 |
+
$this->name = plugin_basename( $_plugin_file );
|
79 |
+
$this->slug = basename( $_plugin_file, '.php' );
|
80 |
+
$this->version = $_api_data['version'];
|
81 |
+
|
82 |
+
// Set up hooks.
|
83 |
+
$this->hook();
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Set up WordPress filters to hook into WP's update process.
|
88 |
+
*
|
89 |
+
* @uses add_filter()
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
private function hook() {
|
93 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
|
94 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
95 |
+
add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Check for Updates at the defined API endpoint and modify the update array.
|
100 |
+
*
|
101 |
+
* This function dives into the update API just when WordPress creates its update array,
|
102 |
+
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
103 |
+
* It is reassembled from parts of the native WordPress plugin update code.
|
104 |
+
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
105 |
+
*
|
106 |
+
* @uses api_request()
|
107 |
+
*
|
108 |
+
* @param array $_transient_data Update array build by WordPress.
|
109 |
+
* @return array Modified update array with custom plugin data.
|
110 |
+
*/
|
111 |
+
public function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
|
112 |
+
if ( empty( $_transient_data ) || ! $this->do_check ) {
|
113 |
+
// This ensures that the custom API request only runs on the second time that WP fires the update check.
|
114 |
+
$this->do_check = true;
|
115 |
+
return $_transient_data;
|
116 |
+
}
|
117 |
+
|
118 |
+
$to_send = array(
|
119 |
+
'slug' => $this->slug,
|
120 |
+
);
|
121 |
+
$api_response = $this->api_request( 'plugin_latest_version', $to_send );
|
122 |
+
|
123 |
+
if ( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
|
124 |
+
if ( version_compare( $this->version, $api_response->new_version, '<' ) ) {
|
125 |
+
$_transient_data->response[ $this->name ] = $api_response;
|
126 |
+
}
|
127 |
+
}
|
128 |
+
return $_transient_data;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Updates information on the "View version x.x details" page with custom data.
|
133 |
+
*
|
134 |
+
* @uses api_request()
|
135 |
+
*
|
136 |
+
* @param mixed $_data - Data.
|
137 |
+
* @param string $_action - Action.
|
138 |
+
* @param object $_args - Arguments.
|
139 |
+
* @return object $_data
|
140 |
+
*/
|
141 |
+
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
142 |
+
if ( ( 'plugin_information' != $_action ) || ! isset( $_args->slug ) || ($_args->slug != $this->slug) ) {
|
143 |
+
return $_data;
|
144 |
+
}
|
145 |
+
$to_send = array(
|
146 |
+
'slug' => $this->slug,
|
147 |
+
);
|
148 |
+
|
149 |
+
$api_response = $this->api_request( 'plugin_information', $to_send );
|
150 |
+
if ( false !== $api_response ) {
|
151 |
+
$_data = $api_response;
|
152 |
+
}
|
153 |
+
|
154 |
+
return $_data;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Disable SSL verification in order to prevent download update failures
|
159 |
+
*
|
160 |
+
* @param array $args - Arguments.
|
161 |
+
* @param string $url - URL.
|
162 |
+
* @return array $args
|
163 |
+
*/
|
164 |
+
public function http_request_args( $args, $url ) {
|
165 |
+
// If it is an https request and we are performing a package download, disable ssl verification.
|
166 |
+
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
|
167 |
+
$args['sslverify'] = false;
|
168 |
+
}
|
169 |
+
return $args;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
174 |
+
*
|
175 |
+
* @uses get_bloginfo()
|
176 |
+
* @uses wp_remote_post()
|
177 |
+
* @uses is_wp_error()
|
178 |
+
*
|
179 |
+
* @param string $_action The requested action.
|
180 |
+
* @param array $_data Parameters for the API action.
|
181 |
+
* @return false||object
|
182 |
+
*/
|
183 |
+
private function api_request( $_action, $_data ) {
|
184 |
+
global $wp_version;
|
185 |
+
$data = array_merge( $this->api_data, $_data );
|
186 |
+
|
187 |
+
if ( $data['slug'] != $this->slug ) {
|
188 |
+
return;
|
189 |
+
}
|
190 |
+
|
191 |
+
if ( empty( $data['license'] ) ) {
|
192 |
+
return;
|
193 |
+
}
|
194 |
+
|
195 |
+
$api_params = array(
|
196 |
+
'edd_action' => 'get_version',
|
197 |
+
'license' => $data['license'],
|
198 |
+
'name' => $data['item_name'],
|
199 |
+
'slug' => $this->slug,
|
200 |
+
'author' => $data['author'],
|
201 |
+
'url' => home_url(),
|
202 |
+
);
|
203 |
+
$request = wp_remote_post(
|
204 |
+
$this->api_url, array(
|
205 |
+
'timeout' => 15,
|
206 |
+
'sslverify' => false,
|
207 |
+
'body' => $api_params,
|
208 |
+
)
|
209 |
+
);
|
210 |
+
|
211 |
+
if ( ! is_wp_error( $request ) ) {
|
212 |
+
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
213 |
+
if ( $request && isset( $request->sections ) ) {
|
214 |
+
$request->sections = maybe_unserialize( $request->sections );
|
215 |
+
}
|
216 |
+
return $request;
|
217 |
+
} else {
|
218 |
+
return false;
|
219 |
+
}
|
220 |
+
}
|
221 |
}
|
classes/Helpers/DataHelper.php
CHANGED
@@ -1,28 +1,41 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Helper class used for encode/decode json data.
|
|
|
|
|
6 |
*/
|
7 |
-
class WSAL_Helpers_DataHelper
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Data Helper.
|
4 |
+
*
|
5 |
+
* Helper class used for encode/decode json data..
|
6 |
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* Helper class used for encode/decode json data.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
class WSAL_Helpers_DataHelper {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* A wrapper for JSON encoding that fixes potential issues.
|
24 |
+
*
|
25 |
+
* @param mixed $data The data to encode.
|
26 |
+
* @return string JSON string.
|
27 |
+
*/
|
28 |
+
public static function JsonEncode( $data ) {
|
29 |
+
return @json_encode( $data );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* A wrapper for JSON encoding that fixes potential issues.
|
34 |
+
*
|
35 |
+
* @param string $data - The JSON string to decode.
|
36 |
+
* @return mixed Decoded data.
|
37 |
+
*/
|
38 |
+
public static function JsonDecode( $data ) {
|
39 |
+
return @json_decode( $data );
|
40 |
+
}
|
41 |
}
|
classes/LicenseManager.php
CHANGED
@@ -1,196 +1,268 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
//
|
4 |
-
if(!
|
5 |
-
|
6 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
/**
|
8 |
-
*
|
9 |
*
|
10 |
* License Manager used in all the Add-Ons licenses.
|
|
|
|
|
11 |
*/
|
12 |
-
class WSAL_LicenseManager
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Class: License Manager.
|
4 |
+
*
|
5 |
+
* License manager used in all the Add-Ons licenses.
|
6 |
+
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
}
|
14 |
+
|
15 |
+
// Since other plugins might use this class.
|
16 |
+
if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
|
17 |
+
require_once( 'EDD_SL_Plugin_Updater.php' );
|
18 |
+
}
|
19 |
+
|
20 |
/**
|
21 |
+
* Class: License Manager.
|
22 |
*
|
23 |
* License Manager used in all the Add-Ons licenses.
|
24 |
+
*
|
25 |
+
* @package Wsal
|
26 |
*/
|
27 |
+
class WSAL_LicenseManager {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Instance of WpSecurityAuditLog.
|
31 |
+
*
|
32 |
+
* @var WpSecurityAuditLog
|
33 |
+
*/
|
34 |
+
protected $plugin;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Array of Add-Ons.
|
38 |
+
*
|
39 |
+
* @var array
|
40 |
+
*/
|
41 |
+
protected $plugins = array();
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Method: Constructor.
|
45 |
+
*
|
46 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
47 |
+
*/
|
48 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
49 |
+
$this->plugin = $plugin;
|
50 |
+
add_action( 'plugins_loaded', array( $this, 'LoadPlugins' ) );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Method: Get Store URL.
|
55 |
+
*/
|
56 |
+
protected function GetStoreUrl() {
|
57 |
+
return 'https://www.wpsecurityauditlog.com/';
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Method: Count Add-Ons.
|
62 |
+
*/
|
63 |
+
public function CountPlugins() {
|
64 |
+
return count( $this->plugins );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Method: Get Add-Ons.
|
69 |
+
*/
|
70 |
+
public function Plugins() {
|
71 |
+
return $this->plugins;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Method: Load Add-Ons.
|
76 |
+
*/
|
77 |
+
public function LoadPlugins() {
|
78 |
+
foreach ( apply_filters( 'wsal_register', array() ) as $plugin_file ) {
|
79 |
+
$this->AddPremiumPlugin( $plugin_file );
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Method: Get Plugin Data.
|
85 |
+
*
|
86 |
+
* @param string $plugin_file - Plugin file.
|
87 |
+
* @param string $license - Plugin License.
|
88 |
+
*/
|
89 |
+
protected function GetPluginData( $plugin_file, $license ) {
|
90 |
+
// A hack since get_plugin_data() is not available now.
|
91 |
+
$plugin_data = get_file_data(
|
92 |
+
$plugin_file, array(
|
93 |
+
'Name' => 'Plugin Name',
|
94 |
+
'PluginURI' => 'Plugin URI',
|
95 |
+
'Version' => 'Version',
|
96 |
+
'Description' => 'Description',
|
97 |
+
'Author' => 'Author',
|
98 |
+
'TextDomain' => 'Text Domain',
|
99 |
+
'DomainPath' => 'Domain Path',
|
100 |
+
), 'plugin'
|
101 |
+
);
|
102 |
+
|
103 |
+
$plugin_updater = is_null( $license )
|
104 |
+
? null
|
105 |
+
: new EDD_SL_Plugin_Updater(
|
106 |
+
$this->GetStoreUrl(),
|
107 |
+
$plugin_file,
|
108 |
+
array(
|
109 |
+
'license' => $license,
|
110 |
+
'item_name' => $plugin_data['Name'],
|
111 |
+
'author' => $plugin_data['Author'],
|
112 |
+
'version' => $plugin_data['Version'],
|
113 |
+
)
|
114 |
+
);
|
115 |
+
|
116 |
+
return array(
|
117 |
+
'PluginData' => $plugin_data,
|
118 |
+
'EddUpdater' => $plugin_updater,
|
119 |
+
);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Method: Add Premium Plugin.
|
124 |
+
*
|
125 |
+
* @param string $plugin_file - Plugin File.
|
126 |
+
*/
|
127 |
+
public function AddPremiumPlugin( $plugin_file ) {
|
128 |
+
if ( isset( $plugin_file ) ) {
|
129 |
+
$name = sanitize_key( basename( $plugin_file ) );
|
130 |
+
$license = $this->plugin->settings->GetLicenseKey( $name );
|
131 |
+
$this->plugins[ $name ] = $this->GetPluginData( $plugin_file, $license );
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Method: Add Plugin.
|
137 |
+
*
|
138 |
+
* @param string $plugin_file - Plugin File.
|
139 |
+
*/
|
140 |
+
public function AddPlugin( $plugin_file ) {
|
141 |
+
if ( isset( $plugin_file ) ) {
|
142 |
+
$name = sanitize_key( basename( $plugin_file ) );
|
143 |
+
$this->plugins[ $name ] = $this->GetPluginData( $plugin_file, null );
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Method: Get Blog IDs.
|
149 |
+
*/
|
150 |
+
protected function GetBlogIds() {
|
151 |
+
global $wpdb;
|
152 |
+
$sql = 'SELECT blog_id FROM ' . $wpdb->blogs;
|
153 |
+
return $wpdb->get_col( $sql );
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Method: Activate Premium Plugin license.
|
158 |
+
*
|
159 |
+
* @param string $name - Plugin name.
|
160 |
+
* @param string $license - Plugin license.
|
161 |
+
*/
|
162 |
+
public function ActivateLicense( $name, $license ) {
|
163 |
+
$this->plugin->settings->SetLicenseKey( $name, $license );
|
164 |
+
|
165 |
+
$plugins = $this->Plugins();
|
166 |
+
$api_params = array(
|
167 |
+
'edd_action' => 'activate_license',
|
168 |
+
'license' => urlencode( $license ),
|
169 |
+
'item_name' => urlencode( $plugins[ $name ]['PluginData']['Name'] ),
|
170 |
+
'url' => urlencode( home_url() ),
|
171 |
+
);
|
172 |
+
|
173 |
+
$blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array( 1 );
|
174 |
+
|
175 |
+
foreach ( $blog_ids as $blog_id ) {
|
176 |
+
if ( $this->plugin->IsMultisite() ) {
|
177 |
+
$api_params['url'] = urlencode( get_home_url( $blog_id ) );
|
178 |
+
}
|
179 |
+
|
180 |
+
$response = wp_remote_get(
|
181 |
+
esc_url_raw( add_query_arg( $api_params, $this->GetStoreUrl() ) ),
|
182 |
+
array(
|
183 |
+
'timeout' => 15,
|
184 |
+
'sslverify' => false,
|
185 |
+
)
|
186 |
+
);
|
187 |
+
|
188 |
+
if ( is_wp_error( $response ) ) {
|
189 |
+
$this->plugin->settings->SetLicenseErrors( $name, 'Invalid Licensing Server Response: ' . $response->get_error_message() );
|
190 |
+
$this->DeactivateLicense( $name, $license );
|
191 |
+
return false;
|
192 |
+
}
|
193 |
+
|
194 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
195 |
+
|
196 |
+
if ( is_object( $license_data ) ) {
|
197 |
+
$this->plugin->settings->SetLicenseStatus( $name, $license_data->license );
|
198 |
+
if ( 'valid' !== $license_data->license ) {
|
199 |
+
$error = 'License Not Valid';
|
200 |
+
if ( isset( $license_data->error ) ) {
|
201 |
+
$error .= ': ' . ucfirst( str_replace( '_', ' ', $license_data->error ) );
|
202 |
+
}
|
203 |
+
$this->plugin->settings->SetLicenseErrors( $name, $error );
|
204 |
+
$this->DeactivateLicense( $name, $license );
|
205 |
+
return false;
|
206 |
+
}
|
207 |
+
} else {
|
208 |
+
$this->plugin->settings->SetLicenseErrors( $name, 'Unexpected Licensing Server Response' );
|
209 |
+
$this->DeactivateLicense( $name, $license );
|
210 |
+
return false;
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
return true;
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Method: Check Plugin License.
|
219 |
+
*
|
220 |
+
* @param string $name - Plugin name.
|
221 |
+
*/
|
222 |
+
public function IsLicenseValid( $name ) {
|
223 |
+
return trim( strtolower( $this->plugin->settings->GetLicenseStatus( $name ) ) ) === 'valid';
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Method: Deactivate Premium Plugin license.
|
228 |
+
*
|
229 |
+
* @param string $name - Plugin name.
|
230 |
+
* @param string $license - Plugin license.
|
231 |
+
*/
|
232 |
+
public function DeactivateLicense( $name, $license = null ) {
|
233 |
+
$this->plugin->settings->SetLicenseStatus( $name, '' );
|
234 |
+
|
235 |
+
// Deactivate it on the server (if license was given).
|
236 |
+
if ( ! is_null( $license ) ) {
|
237 |
+
$plugins = $this->Plugins();
|
238 |
+
$api_params = array(
|
239 |
+
'edd_action' => 'deactivate_license',
|
240 |
+
'license' => urlencode( $license ),
|
241 |
+
'item_name' => urlencode( $plugins[ $name ]['PluginData']['Name'] ),
|
242 |
+
'url' => urlencode( home_url() ),
|
243 |
+
);
|
244 |
+
|
245 |
+
$blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array( 1 );
|
246 |
+
|
247 |
+
foreach ( $blog_ids as $blog_id ) {
|
248 |
+
if ( $this->plugin->IsMultisite() ) {
|
249 |
+
$api_params['url'] = urlencode( get_home_url( $blog_id ) );
|
250 |
+
}
|
251 |
+
|
252 |
+
$response = wp_remote_get(
|
253 |
+
esc_url_raw( add_query_arg( $api_params, $this->GetStoreUrl() ) ),
|
254 |
+
array(
|
255 |
+
'timeout' => 15,
|
256 |
+
'sslverify' => false,
|
257 |
+
)
|
258 |
+
);
|
259 |
+
|
260 |
+
if ( is_wp_error( $response ) ) {
|
261 |
+
return false;
|
262 |
+
}
|
263 |
+
|
264 |
+
wp_remote_retrieve_body( $response );
|
265 |
+
}
|
266 |
+
}
|
267 |
+
}
|
268 |
}
|
classes/Loggers/Database.php
CHANGED
@@ -1,207 +1,217 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
*
|
4 |
-
*
|
5 |
-
*
|
6 |
-
*
|
7 |
-
*
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Class: Logger
|
4 |
+
*
|
5 |
+
* Logger class for wsal.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Loggers Class.
|
18 |
+
*
|
19 |
+
* This class store the logs in the Database and adds the promo
|
20 |
+
* alerts, there is also the function to clean up alerts.
|
21 |
+
*
|
22 |
+
* @package Wsal
|
23 |
+
*/
|
24 |
+
class WSAL_Loggers_Database extends WSAL_AbstractLogger {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Method: Constructor.
|
28 |
+
*
|
29 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
30 |
+
* @since 1.0.0
|
31 |
+
*/
|
32 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
33 |
+
parent::__construct( $plugin );
|
34 |
+
$plugin->AddCleanupHook( array( $this, 'CleanUp' ) );
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Log alert.
|
39 |
+
*
|
40 |
+
* @param integer $type - Alert code.
|
41 |
+
* @param array $data - Metadata.
|
42 |
+
* @param integer $date (Optional) - created_on.
|
43 |
+
* @param integer $siteid (Optional) - site_id.
|
44 |
+
* @param bool $migrated (Optional) - is_migrated.
|
45 |
+
*/
|
46 |
+
public function Log( $type, $data = array(), $date = null, $siteid = null, $migrated = false ) {
|
47 |
+
// Is this a php alert, and if so, are we logging such alerts?
|
48 |
+
if ( $type < 0010 && ! $this->plugin->settings->IsPhpErrorLoggingEnabled() ) {
|
49 |
+
return;
|
50 |
+
}
|
51 |
+
|
52 |
+
// Create new occurrence.
|
53 |
+
$occ = new WSAL_Models_Occurrence();
|
54 |
+
$occ->is_migrated = $migrated;
|
55 |
+
$occ->created_on = $date;
|
56 |
+
$occ->alert_id = $type;
|
57 |
+
$occ->site_id = ! is_null( $siteid ) ? $siteid
|
58 |
+
: (function_exists( 'get_current_blog_id' ) ? get_current_blog_id() : 0);
|
59 |
+
$occ->Save();
|
60 |
+
|
61 |
+
// Set up meta data.
|
62 |
+
$occ->SetMeta( $data );
|
63 |
+
|
64 |
+
// Inject for promoting the paid add-ons.
|
65 |
+
if ( 9999 != $type ) {
|
66 |
+
$this->AlertInject( $occ );
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Clean Up alerts by date OR by max number.
|
72 |
+
*/
|
73 |
+
public function CleanUp() {
|
74 |
+
$now = current_time( 'timestamp' );
|
75 |
+
$max_sdate = $this->plugin->settings->GetPruningDate();
|
76 |
+
$max_count = $this->plugin->settings->GetPruningLimit();
|
77 |
+
$is_date_e = $this->plugin->settings->IsPruningDateEnabled();
|
78 |
+
$is_limt_e = $this->plugin->settings->IsPruningLimitEnabled();
|
79 |
+
|
80 |
+
if ( ! $is_date_e && ! $is_limt_e ) {
|
81 |
+
return;
|
82 |
+
} // Pruning disabled.
|
83 |
+
$occ = new WSAL_Models_Occurrence();
|
84 |
+
$cnt_items = $occ->Count();
|
85 |
+
|
86 |
+
// Check if there is something to delete.
|
87 |
+
if ( $is_limt_e && ($cnt_items < $max_count) ) {
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
|
91 |
+
$max_stamp = $now - (strtotime( $max_sdate ) - $now);
|
92 |
+
$max_items = (int) max( ($cnt_items - $max_count) + 1, 0 );
|
93 |
+
|
94 |
+
$query = new WSAL_Models_OccurrenceQuery();
|
95 |
+
$query->addOrderBy( 'created_on', false );
|
96 |
+
// TO DO: Fixing data.
|
97 |
+
if ( $is_date_e ) {
|
98 |
+
$query->addCondition( 'created_on <= %s', intval( $max_stamp ) );
|
99 |
+
}
|
100 |
+
if ( $is_limt_e ) {
|
101 |
+
$query->setLimit( $max_items );
|
102 |
+
}
|
103 |
+
|
104 |
+
if ( ($max_items - 1) == 0 ) {
|
105 |
+
return; // Nothing to delete.
|
106 |
+
}
|
107 |
+
|
108 |
+
$result = $query->getAdapter()->GetSqlDelete( $query );
|
109 |
+
$deleted_count = $query->getAdapter()->Delete( $query );
|
110 |
+
|
111 |
+
if ( 0 == $deleted_count ) {
|
112 |
+
return; // Nothing to delete.
|
113 |
+
}
|
114 |
+
// Keep track of what we're doing.
|
115 |
+
$this->plugin->alerts->Trigger(
|
116 |
+
0003, array(
|
117 |
+
'Message' => 'Running system cleanup.',
|
118 |
+
'Query SQL' => $result['sql'],
|
119 |
+
'Query Args' => $result['args'],
|
120 |
+
), true
|
121 |
+
);
|
122 |
+
|
123 |
+
// Notify system.
|
124 |
+
do_action( 'wsal_prune', $deleted_count, vsprintf( $result['sql'], $result['args'] ) );
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Inject Promo alert every $count alerts if no Add-ons are activated.
|
129 |
+
*
|
130 |
+
* @param object $occurrence - Occurrence, instance of WSAL_Models_Occurrence.
|
131 |
+
*/
|
132 |
+
private function AlertInject( $occurrence ) {
|
133 |
+
$count = $this->CheckPromoToShow();
|
134 |
+
if ( $count && $occurrence->getId() != 0 ) {
|
135 |
+
if ( ($occurrence->getId() % $count) == 0 ) {
|
136 |
+
$promo_to_send = $this->GetPromoAlert();
|
137 |
+
if ( ! empty( $promo_to_send ) ) {
|
138 |
+
$upgrade_link = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
139 |
+
$more_info_link = add_query_arg(
|
140 |
+
array(
|
141 |
+
'utm_source' => 'alert',
|
142 |
+
'utm_medium' => 'page',
|
143 |
+
'utm_content' => 'alert+more+info',
|
144 |
+
'utm_campaign' => 'upgrade+premium',
|
145 |
+
),
|
146 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
147 |
+
);
|
148 |
+
$upgrade = '<a href="' . $upgrade_link . '">' . __( 'Upgrade to Premium', 'wp-security-audit-log' ) . '</a>';
|
149 |
+
$more_info = '<a href="' . $more_info_link . '" target="_blank">' . __( 'More Information', 'wp-security-audit-log' ) . '</a>';
|
150 |
+
$this->Log(
|
151 |
+
9999, array(
|
152 |
+
'ClientIP' => '127.0.0.1',
|
153 |
+
'Username' => 'Plugin',
|
154 |
+
'PromoMessage' => sprintf( $promo_to_send['message'], $upgrade, $more_info ),
|
155 |
+
'PromoName' => $promo_to_send['name'],
|
156 |
+
)
|
157 |
+
);
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Get the promo id, to send each time a different promo,
|
165 |
+
* keeping the last id saved in the DB.
|
166 |
+
*
|
167 |
+
* @return integer $promoToSend - The array index.
|
168 |
+
*/
|
169 |
+
private function GetPromoAlert() {
|
170 |
+
$last_promo_sent_id = $this->plugin->GetGlobalOption( 'promo-send-id' );
|
171 |
+
$last_promo_sent_id = empty( $last_promo_sent_id ) ? 0 : $last_promo_sent_id;
|
172 |
+
$promo_to_send = null;
|
173 |
+
$promo_alerts = $this->GetActivePromoText();
|
174 |
+
if ( ! empty( $promo_alerts ) ) {
|
175 |
+
$promo_to_send = isset( $promo_alerts[ $last_promo_sent_id ] ) ? $promo_alerts[ $last_promo_sent_id ] : $promo_alerts[0];
|
176 |
+
|
177 |
+
if ( $last_promo_sent_id < count( $promo_alerts ) - 1 ) {
|
178 |
+
$last_promo_sent_id++;
|
179 |
+
} else {
|
180 |
+
$last_promo_sent_id = 0;
|
181 |
+
}
|
182 |
+
$this->plugin->SetGlobalOption( 'promo-send-id', $last_promo_sent_id );
|
183 |
+
}
|
184 |
+
return $promo_to_send;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Array of promo.
|
189 |
+
*
|
190 |
+
* @return array $promo_alerts - The array of promo.
|
191 |
+
*/
|
192 |
+
private function GetActivePromoText() {
|
193 |
+
$promo_alerts = array();
|
194 |
+
$promo_alerts[] = array(
|
195 |
+
'name' => 'Upgrade to Premium',
|
196 |
+
'message' => 'See who is logged in, create user productivity reports, get notified instantly via email of important changes, add search and much more. <strong>%1$s</strong> | <strong>%2$s</strong>',
|
197 |
+
);
|
198 |
+
$promo_alerts[] = array(
|
199 |
+
'name' => 'See Who is Logged In, receive Email Alerts, generate User Productivity Reports and more!',
|
200 |
+
'message' => 'Upgrade to premium and extend the plugin’s features with email alerts, reports tool, free-text based search, user logins and sessions management and more! <strong>%1$s</strong> | <strong>%2$s</strong>',
|
201 |
+
);
|
202 |
+
return $promo_alerts;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Check condition to show promo.
|
207 |
+
*
|
208 |
+
* @return integer|null - Counter alert.
|
209 |
+
*/
|
210 |
+
private function CheckPromoToShow() {
|
211 |
+
// If the package is free, show the promo.
|
212 |
+
if ( wsal_freemius()->is_not_paying() ) {
|
213 |
+
return 80;
|
214 |
+
}
|
215 |
+
return null;
|
216 |
+
}
|
217 |
+
}
|
classes/Models/ActiveRecord.php
CHANGED
@@ -1,344 +1,389 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Abstract ActiveRecord model is the generic model for any kind
|
6 |
* of adapter.
|
|
|
|
|
7 |
*/
|
8 |
-
abstract class WSAL_Models_ActiveRecord
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Abstract Active Record
|
4 |
+
*
|
5 |
+
* Abstract ActiveRecord model is the generic model for any kind
|
6 |
+
* of adapter.
|
7 |
*
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Abstract ActiveRecord model is the generic model for any kind
|
18 |
* of adapter.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
abstract class WSAL_Models_ActiveRecord {
|
23 |
+
|
24 |
+
const STATE_UNKNOWN = 'unknown';
|
25 |
+
const STATE_CREATED = 'created';
|
26 |
+
const STATE_UPDATED = 'updated';
|
27 |
+
const STATE_DELETED = 'deleted';
|
28 |
+
const STATE_LOADED = 'loaded';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Data connector
|
32 |
+
*
|
33 |
+
* @var WSAL_Connector_ConnectorFactory
|
34 |
+
*/
|
35 |
+
protected $connector;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Record ID.
|
39 |
+
*
|
40 |
+
* @var boolean
|
41 |
+
*/
|
42 |
+
protected $id = false;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Adapter Name.
|
46 |
+
*
|
47 |
+
* @var null
|
48 |
+
*/
|
49 |
+
protected $adapterName = null;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Use Default Adapter.
|
53 |
+
*
|
54 |
+
* @var boolean
|
55 |
+
*/
|
56 |
+
protected $useDefaultAdapter = false;
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Record State.
|
60 |
+
*
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
protected $_state = self::STATE_UNKNOWN;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Cache.
|
67 |
+
*
|
68 |
+
* @var array
|
69 |
+
*/
|
70 |
+
protected static $_cache = array();
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Returns this records' fields.
|
74 |
+
*
|
75 |
+
* @return array
|
76 |
+
*/
|
77 |
+
public function GetFields() {
|
78 |
+
if ( ! isset( $this->_column_cache ) ) {
|
79 |
+
$this->_column_cache = array();
|
80 |
+
foreach ( array_keys( get_object_vars( $this ) ) as $col ) {
|
81 |
+
if ( trim( $col ) && '_' != $col[0] ) {
|
82 |
+
$this->_column_cache[] = $col;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
}
|
86 |
+
return $this->_column_cache;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Sets the id.
|
91 |
+
*
|
92 |
+
* @param integer $id - ID.
|
93 |
+
*/
|
94 |
+
public function setId( $id ) {
|
95 |
+
$this->id = $id;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Gets the id.
|
100 |
+
*
|
101 |
+
* @return integer $id.
|
102 |
+
*/
|
103 |
+
public function getId() {
|
104 |
+
return $this->id;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Method: Constructor.
|
109 |
+
*
|
110 |
+
* @param array $data - Active data.
|
111 |
+
* @throws Exception - Requires adapterName.
|
112 |
+
*/
|
113 |
+
public function __construct( $data = null ) {
|
114 |
+
if ( ! $this->adapterName ) {
|
115 |
+
throw new Exception( 'Class "' . __CLASS__ . '" requires "adapterName" to be set.' );
|
116 |
+
}
|
117 |
+
if ( ! is_null( $data ) ) {
|
118 |
+
$this->LoadData( $data );
|
119 |
+
$this->_state = self::STATE_LOADED;
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Gets the connector.
|
125 |
+
*
|
126 |
+
* @return WSAL_Connector_ConnectorInterface
|
127 |
+
*/
|
128 |
+
protected function getConnector() {
|
129 |
+
if ( ! empty( $this->connector ) ) {
|
130 |
+
return $this->connector;
|
131 |
+
}
|
132 |
+
if ( $this->useDefaultAdapter ) {
|
133 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
134 |
+
} else {
|
135 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
136 |
+
}
|
137 |
+
return $this->connector;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Gets an adapter for the specified model
|
142 |
+
* based on the adapter name.
|
143 |
+
*
|
144 |
+
* @see WSAL_Connector_ConnectorInterface::getAdapter()
|
145 |
+
*/
|
146 |
+
public function getAdapter() {
|
147 |
+
return $this->getConnector()->getAdapter( $this->adapterName );
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Load record from DB.
|
152 |
+
*
|
153 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Load()
|
154 |
+
* @param string $cond (Optional) Load condition.
|
155 |
+
* @param array $args (Optional) Load condition arguments.
|
156 |
+
*/
|
157 |
+
public function Load( $cond = '%d', $args = array( 1 ) ) {
|
158 |
+
$this->_state = self::STATE_UNKNOWN;
|
159 |
+
|
160 |
+
$data = $this->getAdapter()->Load( $cond, $args );
|
161 |
+
if ( ! is_null( $data ) ) {
|
162 |
+
$this->LoadData( $data );
|
163 |
+
$this->_state = self::STATE_LOADED;
|
164 |
+
}
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Load object data from variable.
|
169 |
+
*
|
170 |
+
* @param array|object $data Data array or object.
|
171 |
+
* @throws Exception - Unsupported type.
|
172 |
+
*/
|
173 |
+
public function LoadData( $data ) {
|
174 |
+
$copy = get_class( $this );
|
175 |
+
$copy = new $copy();
|
176 |
+
foreach ( (array) $data as $key => $val ) {
|
177 |
+
if ( isset( $copy->$key ) ) {
|
178 |
+
switch ( true ) {
|
179 |
+
case $this->is_ip_address( $val ):
|
180 |
+
$this->$key = (string) $val;
|
181 |
+
break;
|
182 |
+
case is_array( $copy->$key ):
|
183 |
+
case is_object( $copy->$key ):
|
184 |
+
$json_decoded_val = WSAL_Helpers_DataHelper::JsonDecode( $val );
|
185 |
+
$this->$key = ( null == $json_decoded_val ) ? $val : $json_decoded_val;
|
186 |
+
break;
|
187 |
+
case is_int( $copy->$key ):
|
188 |
+
$this->$key = (int) $val;
|
189 |
+
break;
|
190 |
+
case is_float( $copy->$key ):
|
191 |
+
$this->$key = (float) $val;
|
192 |
+
break;
|
193 |
+
case is_bool( $copy->$key ):
|
194 |
+
$this->$key = (bool) $val;
|
195 |
+
break;
|
196 |
+
case is_string( $copy->$key ):
|
197 |
+
$this->$key = (string) $val;
|
198 |
+
break;
|
199 |
+
default:
|
200 |
+
throw new Exception( 'Unsupported type "' . gettype( $copy->$key ) . '"' );
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
return $this;
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Save this active record
|
209 |
+
*
|
210 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Save()
|
211 |
+
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
212 |
+
*/
|
213 |
+
public function Save() {
|
214 |
+
$this->_state = self::STATE_UNKNOWN;
|
215 |
+
|
216 |
+
// Use today's date if not set up.
|
217 |
+
if ( is_null( $this->created_on ) ) {
|
218 |
+
$this->created_on = $this->GetMicrotime();
|
219 |
+
}
|
220 |
+
$update_id = $this->getId();
|
221 |
+
$result = $this->getAdapter()->Save( $this );
|
222 |
+
|
223 |
+
if ( false !== $result ) {
|
224 |
+
$this->_state = ( ! empty( $update_id )) ? self::STATE_UPDATED : self::STATE_CREATED;
|
225 |
+
}
|
226 |
+
return $result;
|
227 |
+
}
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Deletes this active record.
|
231 |
+
*
|
232 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Delete()
|
233 |
+
* @return int|boolean Either the amount of deleted rows or False on error.
|
234 |
+
*/
|
235 |
+
public function Delete() {
|
236 |
+
$this->_state = self::STATE_UNKNOWN;
|
237 |
+
$result = $this->getAdapter()->Delete( $this );
|
238 |
+
if ( false !== $result ) {
|
239 |
+
$this->_state = self::STATE_DELETED;
|
240 |
+
}
|
241 |
+
return $result;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Count records that matching a condition.
|
246 |
+
*
|
247 |
+
* @param string $cond - Condition.
|
248 |
+
* @param array $args - Arguments.
|
249 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Count()
|
250 |
+
* @return int count
|
251 |
+
*/
|
252 |
+
public function Count( $cond = '%d', $args = array( 1 ) ) {
|
253 |
+
$result = $this->getAdapter()->Count( $cond, $args );
|
254 |
+
return $result;
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* Check state loaded.
|
259 |
+
*
|
260 |
+
* @return bool
|
261 |
+
*/
|
262 |
+
public function IsLoaded() {
|
263 |
+
return self::STATE_LOADED == $this->_state;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Check state saved.
|
268 |
+
*
|
269 |
+
* @return bool
|
270 |
+
*/
|
271 |
+
public function IsSaved() {
|
272 |
+
return self::STATE_CREATED == $this->_state
|
273 |
+
|| self::STATE_UPDATED == $this->_state;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Check state created.
|
278 |
+
*
|
279 |
+
* @return bool
|
280 |
+
*/
|
281 |
+
public function IsCreated() {
|
282 |
+
return self::STATE_CREATED == $this->_state;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Check state updated.
|
287 |
+
*
|
288 |
+
* @return bool
|
289 |
+
*/
|
290 |
+
public function IsUpdated() {
|
291 |
+
return self::STATE_UPDATED == $this->_state;
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Check if the Record structure is created.
|
296 |
+
*
|
297 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::IsInstalled()
|
298 |
+
* @return bool
|
299 |
+
*/
|
300 |
+
public function IsInstalled() {
|
301 |
+
return $this->getAdapter()->IsInstalled();
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Install the Record structure.
|
306 |
+
*
|
307 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Install()
|
308 |
+
*/
|
309 |
+
public function Install() {
|
310 |
+
return $this->getAdapter()->Install();
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Check state deleted.
|
315 |
+
*
|
316 |
+
* @return bool
|
317 |
+
*/
|
318 |
+
public function IsDeleted() {
|
319 |
+
return self::STATE_DELETED == $this->_state;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Load ActiveRecord from DB or cache.
|
324 |
+
*
|
325 |
+
* @param string $target ActiveRecord class name.
|
326 |
+
* @param string $query Load condition.
|
327 |
+
* @param array $args Arguments used in condition.
|
328 |
+
* @return WSAL_Models_ActiveRecord
|
329 |
+
*/
|
330 |
+
protected static function CacheLoad( $target, $query, $args ) {
|
331 |
+
$index = $target . '::' . vsprintf( $query, $args );
|
332 |
+
if ( ! isset( self::$_cache[ $index ] ) ) {
|
333 |
+
self::$_cache[ $index ] = new $target();
|
334 |
+
self::$_cache[ $index ]->Load( $query, $args );
|
335 |
+
}
|
336 |
+
return self::$_cache[ $index ];
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* Remove ActiveRecord cache.
|
341 |
+
*
|
342 |
+
* @param string $target ActiveRecord class name.
|
343 |
+
* @param string $query Load condition.
|
344 |
+
* @param array $args Arguments used in condition.
|
345 |
+
*/
|
346 |
+
protected static function CacheRemove( $target, $query, $args ) {
|
347 |
+
$index = $target . '::' . sprintf( $query, $args );
|
348 |
+
if ( ! isset( self::$_cache[ $index ] ) ) {
|
349 |
+
unset( self::$_cache[ $index ] );
|
350 |
+
}
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Clear the cache.
|
355 |
+
*/
|
356 |
+
protected static function CacheClear() {
|
357 |
+
self::$_cache = array();
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* Function used in WSAL reporting extension.
|
362 |
+
*
|
363 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::GetReporting()
|
364 |
+
* @param int $_site_id - Site ID.
|
365 |
+
* @param int $_user_id - User ID.
|
366 |
+
* @param string $_role_name - User role.
|
367 |
+
* @param int $_alert_code - Alert code.
|
368 |
+
* @param timestamp $_start_timestamp - From created_on.
|
369 |
+
* @param timestamp $_end_timestamp - To created_on.
|
370 |
+
* @return array - Report results.
|
371 |
+
*/
|
372 |
+
public function GetReporting( $_site_id, $_user_id, $_role_name, $_alert_code, $_start_timestamp, $_end_timestamp ) {
|
373 |
+
return $this->getAdapter()->GetReporting( $_site_id, $_user_id, $_role_name, $_alert_code, $_start_timestamp, $_end_timestamp );
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Check if the float is IPv4 instead.
|
378 |
+
*
|
379 |
+
* @see WSAL_Models_ActiveRecord::LoadData()
|
380 |
+
* @param float $ip_address - Number to check.
|
381 |
+
* @return bool result validation
|
382 |
+
*/
|
383 |
+
private function is_ip_address( $ip_address ) {
|
384 |
+
if ( filter_var( $ip_address, FILTER_VALIDATE_IP ) !== false ) {
|
385 |
+
return true;
|
386 |
+
}
|
387 |
+
return false;
|
388 |
+
}
|
389 |
}
|
classes/Models/Meta.php
CHANGED
@@ -1,56 +1,99 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* Metadata model is the model for the Metadata adapter,
|
6 |
* used for save and update the metadata.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Models_Meta extends WSAL_Models_ActiveRecord
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Meta Model Class
|
4 |
*
|
5 |
* Metadata model is the model for the Metadata adapter,
|
6 |
* used for save and update the metadata.
|
7 |
+
*
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Metadata model is the model for the Metadata adapter,
|
18 |
+
* used for save and update the metadata.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Meta ID.
|
26 |
+
*
|
27 |
+
* @var integer
|
28 |
+
*/
|
29 |
+
public $id = 0;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Occurrence ID.
|
33 |
+
*
|
34 |
+
* @var integer
|
35 |
+
*/
|
36 |
+
public $occurrence_id = 0;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Meta Name.
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
public $name = '';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Meta Value.
|
47 |
+
*
|
48 |
+
* @var array
|
49 |
+
*/
|
50 |
+
public $value = array(); // Force mixed type.
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Model Name.
|
54 |
+
*
|
55 |
+
* @var string
|
56 |
+
*/
|
57 |
+
protected $adapterName = 'Meta';
|
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 SaveMeta() {
|
66 |
+
$this->_state = self::STATE_UNKNOWN;
|
67 |
+
$update_id = $this->getId();
|
68 |
+
$result = $this->getAdapter()->Save( $this );
|
69 |
+
|
70 |
+
if ( false !== $result ) {
|
71 |
+
$this->_state = ( ! empty( $update_id )) ? self::STATE_UPDATED : self::STATE_CREATED;
|
72 |
+
}
|
73 |
+
return $result;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Update Metadata by name and occurrence_id.
|
78 |
+
*
|
79 |
+
* @see WSAL_Adapters_MySQL_Meta::LoadByNameAndOccurenceId()
|
80 |
+
* @param string $name - Meta name.
|
81 |
+
* @param mixed $value - Meta value.
|
82 |
+
* @param integer $occurrence_id - Occurrence_id.
|
83 |
+
*/
|
84 |
+
public function UpdateByNameAndOccurenceId( $name, $value, $occurrence_id ) {
|
85 |
+
$meta = $this->getAdapter()->LoadByNameAndOccurenceId( $name, $occurrence_id );
|
86 |
+
if ( ! empty( $meta ) ) {
|
87 |
+
$this->id = $meta['id'];
|
88 |
+
$this->occurrence_id = $meta['occurrence_id'];
|
89 |
+
$this->name = $meta['name'];
|
90 |
+
$this->value = $value;
|
91 |
+
$this->saveMeta();
|
92 |
+
} else {
|
93 |
+
$this->occurrence_id = $occurrence_id;
|
94 |
+
$this->name = $name;
|
95 |
+
$this->value = $value;
|
96 |
+
$this->SaveMeta();
|
97 |
+
}
|
98 |
+
}
|
99 |
}
|
classes/Models/Occurrence.php
CHANGED
@@ -1,252 +1,294 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* Occurrence model is the model for the Occurrence adapter,
|
6 |
* used for get the alert, set the meta fields, etc.
|
|
|
|
|
7 |
*/
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Occurrence Model Class
|
4 |
*
|
5 |
* Occurrence model is the model for the Occurrence adapter,
|
6 |
* used for get the alert, set the meta fields, etc.
|
7 |
+
*
|
8 |
+
* @package Wsal
|
9 |
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Occurrence model is the model for the Occurrence adapter,
|
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 |
+
/**
|
25 |
+
* Occurrence ID.
|
26 |
+
*
|
27 |
+
* @var integer
|
28 |
+
*/
|
29 |
+
public $id = 0;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Site ID.
|
33 |
+
*
|
34 |
+
* @var integer
|
35 |
+
*/
|
36 |
+
public $site_id = 0;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Alert ID.
|
40 |
+
*
|
41 |
+
* @var integer
|
42 |
+
*/
|
43 |
+
public $alert_id = 0;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Created On.
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
public $created_on = 0.0;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Is read.
|
54 |
+
*
|
55 |
+
* @var bool
|
56 |
+
*/
|
57 |
+
public $is_read = false;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Is migrated.
|
61 |
+
*
|
62 |
+
* @var bool
|
63 |
+
*/
|
64 |
+
public $is_migrated = false;
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Model Name.
|
68 |
+
*
|
69 |
+
* @var string
|
70 |
+
*/
|
71 |
+
protected $adapterName = 'Occurrence';
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Returns the alert related to this occurrence.
|
75 |
+
*
|
76 |
+
* @see WSAL_AlertManager::GetAlert()
|
77 |
+
* @return WSAL_Alert
|
78 |
+
*/
|
79 |
+
public function GetAlert() {
|
80 |
+
return WpSecurityAuditLog::GetInstance()->alerts->GetAlert( $this->alert_id );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Returns the value of a meta item.
|
85 |
+
*
|
86 |
+
* @see WSAL_Adapters_MySQL_Occurrence::GetNamedMeta()
|
87 |
+
* @param string $name - Name of meta item.
|
88 |
+
* @param mixed $default - Default value returned when meta does not exist.
|
89 |
+
* @return mixed The value, if meta item does not exist $default returned.
|
90 |
+
*/
|
91 |
+
public function GetMetaValue( $name, $default = array() ) {
|
92 |
+
// Get meta adapter.
|
93 |
+
$meta = $this->getAdapter()->GetNamedMeta( $this, $name );
|
94 |
+
return maybe_unserialize( $meta['value'] );
|
95 |
+
|
96 |
+
// TO DO: re-introduce add is loaded check before running query
|
97 |
+
// return $meta->IsLoaded() ? $meta->value : $default;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Sets the value of a meta item (creates or updates meta item).
|
102 |
+
*
|
103 |
+
* @param string $name - Meta name.
|
104 |
+
* @param mixed $value - Meta value.
|
105 |
+
*/
|
106 |
+
public function SetMetaValue( $name, $value ) {
|
107 |
+
if ( ! empty( $value ) ) {
|
108 |
+
// Get meta adapter.
|
109 |
+
$model = new WSAL_Models_Meta();
|
110 |
+
$model->occurrence_id = $this->getId();
|
111 |
+
$model->name = $name;
|
112 |
+
$model->value = maybe_serialize( $value );
|
113 |
+
$model->SaveMeta();
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Update Metadata of this occurrence by name.
|
119 |
+
*
|
120 |
+
* @see WSAL_Models_Meta::UpdateByNameAndOccurenceId()
|
121 |
+
* @param string $name - Meta name.
|
122 |
+
* @param mixed $value - Meta value.
|
123 |
+
*/
|
124 |
+
public function UpdateMetaValue( $name, $value ) {
|
125 |
+
$model = new WSAL_Models_Meta();
|
126 |
+
$model->UpdateByNameAndOccurenceId( $name, $value, $this->getId() );
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Returns a key-value pair of meta data.
|
131 |
+
*
|
132 |
+
* @see WSAL_Adapters_MySQL_Occurrence::GetMultiMeta()
|
133 |
+
* @return array
|
134 |
+
*/
|
135 |
+
public function GetMetaArray() {
|
136 |
+
$result = array();
|
137 |
+
$metas = $this->getAdapter()->GetMultiMeta( $this );
|
138 |
+
foreach ( $metas as $meta ) {
|
139 |
+
$result[ $meta->name ] = maybe_unserialize( $meta->value );
|
140 |
+
}
|
141 |
+
return $result;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Creates or updates all meta data passed as an array of meta-key/meta-value pairs.
|
146 |
+
*
|
147 |
+
* @param array $data - New meta data.
|
148 |
+
*/
|
149 |
+
public function SetMeta( $data ) {
|
150 |
+
foreach ( (array) $data as $key => $val ) {
|
151 |
+
$this->SetMetaValue( $key, $val );
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Gets alert message.
|
157 |
+
*
|
158 |
+
* @see WSAL_Alert::GetMessage()
|
159 |
+
* @param callable|null $meta_formatter (Optional) Meta formatter callback.
|
160 |
+
* @return string Full-formatted message.
|
161 |
+
*/
|
162 |
+
public function GetMessage( $meta_formatter = null ) {
|
163 |
+
if ( ! isset( $this->_cachedmessage ) ) {
|
164 |
+
// Get correct message entry.
|
165 |
+
if ( $this->is_migrated ) {
|
166 |
+
$this->_cachedmessage = $this->GetMetaValue( 'MigratedMesg', false );
|
167 |
+
}
|
168 |
+
if ( ! $this->is_migrated || ! $this->_cachedmessage ) {
|
169 |
+
$this->_cachedmessage = $this->GetAlert()->mesg;
|
170 |
+
}
|
171 |
+
// Fill variables in message.
|
172 |
+
$this->_cachedmessage = $this->GetAlert()->GetMessage( $this->GetMetaArray(), $meta_formatter, $this->_cachedmessage );
|
173 |
+
}
|
174 |
+
return $this->_cachedmessage;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Delete occurrence as well as associated meta data.
|
179 |
+
*
|
180 |
+
* @see WSAL_Adapters_ActiveRecordInterface::Delete()
|
181 |
+
* @return boolean True on success, false on failure.
|
182 |
+
*/
|
183 |
+
public function Delete() {
|
184 |
+
foreach ( $this->getAdapter()->GetMeta() as $meta ) {
|
185 |
+
$meta->Delete();
|
186 |
+
}
|
187 |
+
return parent::Delete();
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Gets the username.
|
192 |
+
*
|
193 |
+
* @see WSAL_Adapters_MySQL_Occurrence::GetFirstNamedMeta()
|
194 |
+
* @return string User's username.
|
195 |
+
*/
|
196 |
+
public function GetUsername() {
|
197 |
+
$meta = $this->getAdapter()->GetFirstNamedMeta( $this, array( 'Username', 'CurrentUserID' ) );
|
198 |
+
if ( $meta ) {
|
199 |
+
switch ( true ) {
|
200 |
+
case 'Username' == $meta->name:
|
201 |
+
return $meta->value;
|
202 |
+
case 'CurrentUserID' == $meta->name:
|
203 |
+
return ($data = get_userdata( $meta->value )) ? $data->user_login : null;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
return null;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Gets the Client IP.
|
211 |
+
*
|
212 |
+
* @return string IP address of request.
|
213 |
+
*/
|
214 |
+
public function GetSourceIP() {
|
215 |
+
return $this->GetMetaValue( 'ClientIP', '' );
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Gets if there are other IPs.
|
220 |
+
*
|
221 |
+
* @return string IP address of request (from proxies etc).
|
222 |
+
*/
|
223 |
+
public function GetOtherIPs() {
|
224 |
+
$result = array();
|
225 |
+
$data = (array) $this->GetMetaValue( 'OtherIPs', array() );
|
226 |
+
foreach ( $data as $ips ) {
|
227 |
+
foreach ( $ips as $ip ) {
|
228 |
+
$result[] = $ip;
|
229 |
+
}
|
230 |
+
}
|
231 |
+
return array_unique( $result );
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Gets user roles.
|
236 |
+
*
|
237 |
+
* @return array Array of user roles.
|
238 |
+
*/
|
239 |
+
public function GetUserRoles() {
|
240 |
+
return $this->GetMetaValue( 'CurrentUserRoles', array() );
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Method: Get Microtime.
|
245 |
+
*
|
246 |
+
* @return float - Number of seconds (and microseconds as fraction) since unix Day 0.
|
247 |
+
* @todo This needs some caching.
|
248 |
+
*/
|
249 |
+
protected function GetMicrotime() {
|
250 |
+
return microtime( true );// + get_option('gmt_offset') * HOUR_IN_SECONDS;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Finds occurences of the same type by IP and Username within specified time frame.
|
255 |
+
*
|
256 |
+
* @param array $args - Query args.
|
257 |
+
* @return WSAL_Occurrence[]
|
258 |
+
*/
|
259 |
+
public function CheckKnownUsers( $args = array() ) {
|
260 |
+
return $this->getAdapter()->CheckKnownUsers( $args );
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Finds occurences of the same type by IP within specified time frame.
|
265 |
+
*
|
266 |
+
* @param array $args - Query args.
|
267 |
+
* @return WSAL_Occurrence[]
|
268 |
+
*/
|
269 |
+
public function CheckUnKnownUsers( $args = array() ) {
|
270 |
+
return $this->getAdapter()->CheckUnKnownUsers( $args );
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Gets occurrence by Post_id
|
275 |
+
*
|
276 |
+
* @see WSAL_Adapters_MySQL_Occurrence::GetByPostID()
|
277 |
+
* @param integer $post_id - Post ID.
|
278 |
+
* @return WSAL_Occurrence[]
|
279 |
+
*/
|
280 |
+
public function GetByPostID( $post_id ) {
|
281 |
+
return $this->getAdapter()->GetByPostID( $post_id );
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Gets occurences of the same type by IP within specified time frame.
|
286 |
+
*
|
287 |
+
* @see WSAL_Adapters_MySQL_Occurrence::CheckAlert404()
|
288 |
+
* @param array $args - Query args.
|
289 |
+
* @return WSAL_Occurrence[]
|
290 |
+
*/
|
291 |
+
public function CheckAlert404( $args = array() ) {
|
292 |
+
return $this->getAdapter()->CheckAlert404( $args );
|
293 |
+
}
|
294 |
}
|
classes/Models/OccurrenceQuery.php
CHANGED
@@ -1,42 +1,62 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* OccurrenceQuery model adds or clears arguments in the Query model.
|
|
|
|
|
6 |
*/
|
7 |
-
class WSAL_Models_OccurrenceQuery extends WSAL_Models_Query
|
8 |
-
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
);
|
41 |
-
}
|
42 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Occurrence Query Class
|
4 |
+
*
|
5 |
+
* OccurrenceQuery model adds or clears arguments in the Query model.
|
6 |
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* OccurrenceQuery model adds or clears arguments in the Query model.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
class WSAL_Models_OccurrenceQuery extends WSAL_Models_Query {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Query Arguments.
|
24 |
+
*
|
25 |
+
* @var array
|
26 |
+
*/
|
27 |
+
protected $arguments = array();
|
28 |
|
29 |
+
/**
|
30 |
+
* Sets arguments.
|
31 |
+
*
|
32 |
+
* @param string $field - Name field.
|
33 |
+
* @param mixed $value - Value.
|
34 |
+
* @return self
|
35 |
+
*/
|
36 |
+
public function addArgument( $field, $value ) {
|
37 |
+
$this->arguments[ $field ] = $value;
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
|
41 |
+
/**
|
42 |
+
* Resets arguments.
|
43 |
+
*
|
44 |
+
* @return self
|
45 |
+
*/
|
46 |
+
public function clearArguments() {
|
47 |
+
$this->arguments = array();
|
48 |
+
return $this;
|
49 |
+
}
|
50 |
|
51 |
+
/**
|
52 |
+
* Method: Constructor
|
53 |
+
*
|
54 |
+
* @since 1.0.0
|
55 |
+
*/
|
56 |
+
public function __construct() {
|
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->addFrom( $this->getConnector()->getAdapter( 'Occurrence' )->GetTable() );
|
61 |
+
}
|
|
|
|
|
62 |
}
|
classes/Models/Option.php
CHANGED
@@ -1,128 +1,167 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
*
|
6 |
* Option Model gets and sets the options of the wsal_options table in the database.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Models_Option extends WSAL_Models_ActiveRecord
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Options Model Class
|
4 |
+
*
|
5 |
+
* Option Model gets and sets the options of the wsal_options table in the database.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* WordPress options are always loaded from the default WordPress database.
|
17 |
*
|
18 |
* Option Model gets and sets the options of the wsal_options table in the database.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Models_Option extends WSAL_Models_ActiveRecord {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Option ID.
|
26 |
+
*
|
27 |
+
* @var int
|
28 |
+
*/
|
29 |
+
public $id = '';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Option Name.
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public $option_name = '';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Option Value.
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
public $option_value = '';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Model Name.
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
protected $adapterName = 'Option';
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Options are always stored in WPDB. This setting ensures that.
|
54 |
+
*
|
55 |
+
* @var bool
|
56 |
+
*/
|
57 |
+
protected $useDefaultAdapter = true;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Sets Option record.
|
61 |
+
*
|
62 |
+
* @param string $name - Option name.
|
63 |
+
* @param mixed $value - Option value.
|
64 |
+
*/
|
65 |
+
public function SetOptionValue( $name, $value ) {
|
66 |
+
$option = $this->getAdapter()->GetNamedOption( $name );
|
67 |
+
$this->id = $option['id'];
|
68 |
+
$this->option_name = $name;
|
69 |
+
// Serialize if $value is array or object.
|
70 |
+
$value = maybe_serialize( $value );
|
71 |
+
$this->option_value = $value;
|
72 |
+
return $this->Save();
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Gets Option record.
|
77 |
+
*
|
78 |
+
* @param string $name - Option name.
|
79 |
+
* @param mixed $default - (Optional) Default value.
|
80 |
+
* @return mixed option value
|
81 |
+
*/
|
82 |
+
public function GetOptionValue( $name, $default = array() ) {
|
83 |
+
$option = $this->getAdapter()->GetNamedOption( $name );
|
84 |
+
$this->option_value = ( ! empty( $option )) ? $option['option_value'] : null;
|
85 |
+
if ( ! empty( $this->option_value ) ) {
|
86 |
+
$this->_state = self::STATE_LOADED;
|
87 |
+
}
|
88 |
+
// Unserialize if $value is array or object.
|
89 |
+
$this->option_value = maybe_unserialize( $this->option_value );
|
90 |
+
return $this->IsLoaded() ? $this->option_value : $default;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Save Option record.
|
95 |
+
*
|
96 |
+
* @see WSAL_Adapters_MySQL_ActiveRecord::Save()
|
97 |
+
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
98 |
+
*/
|
99 |
+
public function Save() {
|
100 |
+
$this->_state = self::STATE_UNKNOWN;
|
101 |
+
|
102 |
+
$update_id = $this->getId();
|
103 |
+
$result = $this->getAdapter()->Save( $this );
|
104 |
+
|
105 |
+
if ( false !== $result ) {
|
106 |
+
$this->_state = ( ! empty( $update_id )) ? self::STATE_UPDATED : self::STATE_CREATED;
|
107 |
+
}
|
108 |
+
return $result;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Get options by prefix (notifications stored in json format).
|
113 |
+
*
|
114 |
+
* @see WSAL_Adapters_MySQL_Option::GetNotificationsSetting()
|
115 |
+
* @param string $opt_prefix - Prefix.
|
116 |
+
* @return array|null options
|
117 |
+
*/
|
118 |
+
public function GetNotificationsSetting( $opt_prefix ) {
|
119 |
+
return $this->getAdapter()->GetNotificationsSetting( $opt_prefix );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Get option by id (notifications stored in json format).
|
124 |
+
*
|
125 |
+
* @see WSAL_Adapters_MySQL_Option::GetNotification()
|
126 |
+
* @param int $id - Option ID.
|
127 |
+
* @return string|null option
|
128 |
+
*/
|
129 |
+
public function GetNotification( $id ) {
|
130 |
+
return $this->LoadData(
|
131 |
+
$this->getAdapter()->GetNotification( $id )
|
132 |
+
);
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Delete option by name.
|
137 |
+
*
|
138 |
+
* @see WSAL_Adapters_MySQL_Option::DeleteByName()
|
139 |
+
* @param string $name - Option name.
|
140 |
+
* @return boolean
|
141 |
+
*/
|
142 |
+
public function DeleteByName( $name ) {
|
143 |
+
return $this->getAdapter()->DeleteByName( $name );
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Delete options start with prefix.
|
148 |
+
*
|
149 |
+
* @see WSAL_Adapters_MySQL_Option::DeleteByPrefix()
|
150 |
+
* @param string $opt_prefix - Prefix.
|
151 |
+
* @return boolean
|
152 |
+
*/
|
153 |
+
public function DeleteByPrefix( $opt_prefix ) {
|
154 |
+
return $this->getAdapter()->DeleteByPrefix( $opt_prefix );
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Number of options start with prefix.
|
159 |
+
*
|
160 |
+
* @see WSAL_Adapters_MySQL_Option::CountNotifications()
|
161 |
+
* @param string $opt_prefix - Prefix.
|
162 |
+
* @return integer Indicates the number of items.
|
163 |
+
*/
|
164 |
+
public function CountNotifications( $opt_prefix ) {
|
165 |
+
return $this->getAdapter()->CountNotifications( $opt_prefix );
|
166 |
+
}
|
167 |
}
|
classes/Models/Query.php
CHANGED
@@ -1,271 +1,342 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* Query Class.
|
5 |
*
|
6 |
* Query model is the class for all the query conditions.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Models_Query
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: Query Model Class
|
4 |
+
*
|
5 |
+
* Query model is the class for all the query conditions.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* Query Class.
|
17 |
*
|
18 |
* Query model is the class for all the query conditions.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Models_Query {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Table Column.
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $columns = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Query Conditions.
|
33 |
+
*
|
34 |
+
* @var array
|
35 |
+
*/
|
36 |
+
protected $conditions = array();
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Order By.
|
40 |
+
*
|
41 |
+
* @var array
|
42 |
+
*/
|
43 |
+
protected $orderBy = array();
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Offset.
|
47 |
+
*
|
48 |
+
* @var mixed
|
49 |
+
*/
|
50 |
+
protected $offset = null;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Limit.
|
54 |
+
*
|
55 |
+
* @var mixed
|
56 |
+
*/
|
57 |
+
protected $limit = null;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* From.
|
61 |
+
*
|
62 |
+
* @var array
|
63 |
+
*/
|
64 |
+
protected $from = array();
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Meta Join.
|
68 |
+
*
|
69 |
+
* @var bool
|
70 |
+
*/
|
71 |
+
protected $meta_join = false;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Search Condition.
|
75 |
+
*
|
76 |
+
* @var mixed
|
77 |
+
*/
|
78 |
+
protected $searchCondition = null;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Use Default Adapter.
|
82 |
+
*
|
83 |
+
* @var bool
|
84 |
+
*/
|
85 |
+
protected $useDefaultAdapter = false;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Method: Constructor.
|
89 |
+
*
|
90 |
+
* @since 1.0.0
|
91 |
+
*/
|
92 |
+
public function __construct() {
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Initialize a connector singleton.
|
97 |
+
*
|
98 |
+
* @return WSAL_Connector_ConnectorInterface
|
99 |
+
*/
|
100 |
+
public function getConnector() {
|
101 |
+
if ( ! empty( $this->connector ) ) {
|
102 |
+
return $this->connector;
|
103 |
+
}
|
104 |
+
if ( $this->useDefaultAdapter ) {
|
105 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
106 |
+
} else {
|
107 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
108 |
+
}
|
109 |
+
return $this->connector;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Gets the adapter.
|
114 |
+
*
|
115 |
+
* @return WSAL_Adapters_MySQL_Query
|
116 |
+
*/
|
117 |
+
public function getAdapter() {
|
118 |
+
return $this->getConnector()->getAdapter( 'Query' );
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Add a column.
|
123 |
+
*
|
124 |
+
* @param mixed $column - Column value.
|
125 |
+
* @return self
|
126 |
+
*/
|
127 |
+
public function addColumn( $column ) {
|
128 |
+
$this->columns[] = $column;
|
129 |
+
return $this;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Clear all columns.
|
134 |
+
*
|
135 |
+
* @return self
|
136 |
+
*/
|
137 |
+
public function clearColumns() {
|
138 |
+
$this->columns = array();
|
139 |
+
return $this;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Get columns.
|
144 |
+
*
|
145 |
+
* @return array $columns
|
146 |
+
*/
|
147 |
+
public function getColumns() {
|
148 |
+
return $this->columns;
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Set all columns.
|
153 |
+
*
|
154 |
+
* @param array $columns - Columns values.
|
155 |
+
* @return self
|
156 |
+
*/
|
157 |
+
public function setColumns( $columns ) {
|
158 |
+
$this->columns = $columns;
|
159 |
+
return $this;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Add conditions.
|
164 |
+
*
|
165 |
+
* @param string $field - Condition field.
|
166 |
+
* @param mixed $value - Condition value.
|
167 |
+
* @return self
|
168 |
+
*/
|
169 |
+
public function addCondition( $field, $value ) {
|
170 |
+
$this->conditions[ $field ] = $value;
|
171 |
+
return $this;
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Add OR condition.
|
176 |
+
*
|
177 |
+
* @param array $add_conditions - Multi conditions.
|
178 |
+
*/
|
179 |
+
public function addORCondition( $add_conditions ) {
|
180 |
+
$this->conditions[] = $add_conditions;
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Clear all conditions.
|
185 |
+
*
|
186 |
+
* @return self
|
187 |
+
*/
|
188 |
+
public function clearConditions() {
|
189 |
+
$this->conditions = array();
|
190 |
+
return $this;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Get all conditions.
|
195 |
+
*
|
196 |
+
* @return array $conditions
|
197 |
+
*/
|
198 |
+
public function getConditions() {
|
199 |
+
return $this->conditions;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Add order by.
|
204 |
+
*
|
205 |
+
* @param string $field - Field name.
|
206 |
+
* @param boolean $is_descending - (Optional) Ascending/descending.
|
207 |
+
* @return self
|
208 |
+
*/
|
209 |
+
public function addOrderBy( $field, $is_descending = false ) {
|
210 |
+
$order = ($is_descending) ? 'DESC' : 'ASC';
|
211 |
+
$this->orderBy[ $field ] = $order;
|
212 |
+
return $this;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Clear order by.
|
217 |
+
*
|
218 |
+
* @return self
|
219 |
+
*/
|
220 |
+
public function clearOrderBy() {
|
221 |
+
$this->orderBy = array();
|
222 |
+
return $this;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Get order by.
|
227 |
+
*
|
228 |
+
* @return array $orderBy
|
229 |
+
*/
|
230 |
+
public function getOrderBy() {
|
231 |
+
return $this->orderBy;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Add from.
|
236 |
+
*
|
237 |
+
* @param string $from_data_set - Data set.
|
238 |
+
* @return self
|
239 |
+
*/
|
240 |
+
public function addFrom( $from_data_set ) {
|
241 |
+
$this->from[] = $from_data_set;
|
242 |
+
return $this;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Reset from.
|
247 |
+
*
|
248 |
+
* @return self
|
249 |
+
*/
|
250 |
+
public function clearFrom() {
|
251 |
+
$this->from = array();
|
252 |
+
return $this;
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Get from.
|
257 |
+
*
|
258 |
+
* @return string $from data set
|
259 |
+
*/
|
260 |
+
public function getFrom() {
|
261 |
+
return $this->from;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Gets the value of limit.
|
266 |
+
*
|
267 |
+
* @return mixed
|
268 |
+
*/
|
269 |
+
public function getLimit() {
|
270 |
+
return $this->limit;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Sets the value of limit.
|
275 |
+
*
|
276 |
+
* @param mixed $limit - The limit.
|
277 |
+
* @return self
|
278 |
+
*/
|
279 |
+
public function setLimit( $limit ) {
|
280 |
+
$this->limit = $limit;
|
281 |
+
return $this;
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Gets the value of offset.
|
286 |
+
*
|
287 |
+
* @return mixed
|
288 |
+
*/
|
289 |
+
public function getOffset() {
|
290 |
+
return $this->offset;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Sets the value of offset.
|
295 |
+
*
|
296 |
+
* @param mixed $offset - The offset.
|
297 |
+
* @return self
|
298 |
+
*/
|
299 |
+
public function setOffset( $offset ) {
|
300 |
+
$this->offset = $offset;
|
301 |
+
return $this;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Adds condition.
|
306 |
+
*
|
307 |
+
* @param mixed $value - Condition.
|
308 |
+
* @return self
|
309 |
+
*/
|
310 |
+
public function addSearchCondition( $value ) {
|
311 |
+
$this->searchCondition = $value;
|
312 |
+
return $this;
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Gets condition.
|
317 |
+
*
|
318 |
+
* @return self
|
319 |
+
*/
|
320 |
+
public function getSearchCondition() {
|
321 |
+
return $this->searchCondition;
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Check meta join.
|
326 |
+
*
|
327 |
+
* @return boolean
|
328 |
+
*/
|
329 |
+
public function hasMetaJoin() {
|
330 |
+
return $this->meta_join;
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Adds meta join.
|
335 |
+
*
|
336 |
+
* @return self
|
337 |
+
*/
|
338 |
+
public function addMetaJoin() {
|
339 |
+
$this->meta_join = true;
|
340 |
+
return $this;
|
341 |
+
}
|
342 |
}
|
classes/Models/TmpUser.php
CHANGED
@@ -1,13 +1,44 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
* Model tmp_users
|
5 |
*
|
6 |
* Model used for the Temporary WP_users table.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Models_TmpUser extends WSAL_Models_ActiveRecord
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: TmpUser Model Class
|
4 |
+
*
|
5 |
+
* Model used for the Temporary WP_users table.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* Model tmp_users
|
17 |
*
|
18 |
* Model used for the Temporary WP_users table.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Models_TmpUser extends WSAL_Models_ActiveRecord {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* User ID.
|
26 |
+
*
|
27 |
+
* @var integer
|
28 |
+
*/
|
29 |
+
public $id = 0;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Username.
|
33 |
+
*
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
public $user_login = '';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Model Name.
|
40 |
+
*
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
protected $adapterName = 'TmpUser';
|
44 |
}
|
classes/Nicer.php
CHANGED
@@ -1,299 +1,311 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
* @package Wsal
|
4 |
* Inspects and prints out PHP values as HTML in a nicer way than print_r().
|
|
|
5 |
* @author Christian Sciberras <christian@sciberras.me>
|
6 |
* @copyright (c) 2013, Christian Sciberras
|
7 |
* @license https://raw.github.com/uuf6429/nice_r/master/LICENSE MIT License
|
8 |
* @link https://github.com/uuf6429/nice_r GitHub Repository
|
9 |
* @version 2.0
|
10 |
* @since 2.0
|
|
|
11 |
*/
|
12 |
-
class WSAL_Nicer
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
}
|
1 |
<?php
|
2 |
/**
|
|
|
3 |
* Inspects and prints out PHP values as HTML in a nicer way than print_r().
|
4 |
+
*
|
5 |
* @author Christian Sciberras <christian@sciberras.me>
|
6 |
* @copyright (c) 2013, Christian Sciberras
|
7 |
* @license https://raw.github.com/uuf6429/nice_r/master/LICENSE MIT License
|
8 |
* @link https://github.com/uuf6429/nice_r GitHub Repository
|
9 |
* @version 2.0
|
10 |
* @since 2.0
|
11 |
+
* @package Wsal
|
12 |
*/
|
13 |
+
class WSAL_Nicer {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Input string.
|
17 |
+
*
|
18 |
+
* @var mix
|
19 |
+
*/
|
20 |
+
protected $value;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Allows modification of CSS class prefix.
|
24 |
+
*
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
public $css_class = 'nice_r';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Allows modification of HTML id prefix.
|
31 |
+
*
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
public $html_id = 'nice_r_v';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Allows modification of JS function used to toggle sections.
|
38 |
+
*
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
public $js_func = 'nice_r_toggle';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Whether to inspect and output methods for objects or not.
|
45 |
+
*
|
46 |
+
* @var boolean
|
47 |
+
*/
|
48 |
+
public $inspect_methods = false;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Since PHP does not support private constants, we'll have to settle for private static fields.
|
52 |
+
*
|
53 |
+
* @var string
|
54 |
+
*/
|
55 |
+
protected static $BEEN_THERE = '__NICE_R_INFINITE_RECURSION_PROTECT__';
|
56 |
+
|
57 |
+
/**
|
58 |
+
* True if ReflectionClass exists.
|
59 |
+
*
|
60 |
+
* @var bool
|
61 |
+
*/
|
62 |
+
protected $_has_reflection = null;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Constructs new renderer instance.
|
66 |
+
*
|
67 |
+
* @param mixed $value The value to inspect and render.
|
68 |
+
* @param boolean $inspect_methods Whether to inspect and output methods for objects or not.
|
69 |
+
*/
|
70 |
+
public function __construct( $value, $inspect_methods = false ) {
|
71 |
+
$this->value = $value;
|
72 |
+
$this->inspect_methods = $inspect_methods;
|
73 |
+
|
74 |
+
if ( is_null( $this->_has_reflection ) ) {
|
75 |
+
$this->_has_reflection = class_exists( 'ReflectionClass' );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Generates the inspector HTML and returns it as a string.
|
81 |
+
*
|
82 |
+
* @return string Generated HTML.
|
83 |
+
*/
|
84 |
+
public function generate() {
|
85 |
+
return $this->_generate_value( $this->value, $this->css_class );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Renders the inspector HTML directly to the browser.
|
90 |
+
*/
|
91 |
+
public function render() {
|
92 |
+
echo $this->generate();
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Converts a string to HTML, encoding any special characters.
|
97 |
+
*
|
98 |
+
* @param string $text The original string.
|
99 |
+
* @return string The string as HTML.
|
100 |
+
*/
|
101 |
+
protected function _esc_html( $text ) {
|
102 |
+
return htmlspecialchars( $text, ENT_QUOTES, 'UTF-8' );
|
103 |
+
}
|
104 |
+
|
105 |
+
protected function _inspect_array( &$html, &$var ) {
|
106 |
+
$has_subitems = false;
|
107 |
+
|
108 |
+
foreach ( $var as $k => $v ) {
|
109 |
+
if ( $k !== self::$BEEN_THERE ) {
|
110 |
+
$html .= $this->_generate_keyvalue( $k, $v );
|
111 |
+
$has_subitems = true;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
if ( ! $has_subitems ) {
|
116 |
+
$html .= '<span class="' . $this->css_class . '_ni">Empty Array</span>';
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
protected function _inspect_object( &$html, &$var ) {
|
121 |
+
// Render properties.
|
122 |
+
$has_subitems = false;
|
123 |
+
|
124 |
+
foreach ( (array) $var as $k => $v ) {
|
125 |
+
if ( $k !== self::$BEEN_THERE ) {
|
126 |
+
$html .= $this->_generate_keyvalue( $k, $v );
|
127 |
+
$has_subitems = true;
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
if ( ! $has_subitems ) {
|
132 |
+
$html .= '<span class="' . $this->css_class . '_ni">No Properties</span>';
|
133 |
+
}
|
134 |
+
|
135 |
+
// Render methods (if enabled).
|
136 |
+
if ( $this->inspect_methods ) {
|
137 |
+
$has_subitems = false;
|
138 |
+
|
139 |
+
foreach ( (array) get_class_methods( $var ) as $method ) {
|
140 |
+
$html .= $this->_generate_callable( $var, $method );
|
141 |
+
$has_subitems = true;
|
142 |
+
}
|
143 |
+
|
144 |
+
if ( ! $has_subitems ) {
|
145 |
+
$html .= '<span class="' . $this->css_class . '_ni">No Methods</span>';
|
146 |
+
}
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Render a single particular value.
|
152 |
+
*
|
153 |
+
* @param mixed $var The value to render.
|
154 |
+
* @param string $class Parent CSS class.
|
155 |
+
* @param string $id Item HTML id.
|
156 |
+
*/
|
157 |
+
protected function _generate_value( $var, $class = '', $id = '' ) {
|
158 |
+
$BEENTHERE = self::$BEEN_THERE;
|
159 |
+
$class .= ' ' . $this->css_class . '_t_' . gettype( $var );
|
160 |
+
|
161 |
+
$html = '<div id="' . $id . '" class="' . $class . '">';
|
162 |
+
switch ( true ) {
|
163 |
+
// Handle arrays.
|
164 |
+
case is_array( $var ):
|
165 |
+
if ( isset( $var[ $BEENTHERE ] ) ) {
|
166 |
+
$html .= '<span class="' . $this->css_class . '_ir">Infinite Recursion Detected!</span>';
|
167 |
+
} else {
|
168 |
+
$var[ $BEENTHERE ] = true;
|
169 |
+
$this->_inspect_array( $html, $var );
|
170 |
+
unset( $var[ $BEENTHERE ] );
|
171 |
+
}
|
172 |
+
break;
|
173 |
+
|
174 |
+
// Handle objects.
|
175 |
+
case is_object( $var ):
|
176 |
+
if ( isset( $var->$BEENTHERE ) ) {
|
177 |
+
$html .= '<span class="' . $this->css_class . '_ir">Infinite Recursion Detected!</span>';
|
178 |
+
} else {
|
179 |
+
$var->$BEENTHERE = true;
|
180 |
+
$this->_inspect_object( $html, $var );
|
181 |
+
unset( $var->$BEENTHERE );
|
182 |
+
}
|
183 |
+
break;
|
184 |
+
|
185 |
+
// Handle simple types.
|
186 |
+
default:
|
187 |
+
$html .= $this->_generate_keyvalue( '', $var );
|
188 |
+
break;
|
189 |
+
}
|
190 |
+
|
191 |
+
return $html . '</div>';
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Generates a new unique ID for tagging elements.
|
196 |
+
*
|
197 |
+
* @staticvar int $id
|
198 |
+
* @return integer An ID unique per request.
|
199 |
+
*/
|
200 |
+
protected function _generate_dropid() {
|
201 |
+
static $id = 0;
|
202 |
+
return ++$id;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Render a key-value pair.
|
207 |
+
*
|
208 |
+
* @staticvar int $id Specifies element id.
|
209 |
+
* @param string $key Key name.
|
210 |
+
* @param mixed $val Key value.
|
211 |
+
*/
|
212 |
+
protected function _generate_keyvalue( $key, $val ) {
|
213 |
+
$id = $this->_generate_dropid();
|
214 |
+
$p = ''; // Preview
|
215 |
+
$d = ''; // Description
|
216 |
+
$t = gettype( $val ); // Get data type.
|
217 |
+
$is_hash = ( 'array' == $t ) || ( 'object' == $t );
|
218 |
+
|
219 |
+
switch ( $t ) {
|
220 |
+
case 'boolean':
|
221 |
+
$p = $val ? 'TRUE' : 'FALSE';
|
222 |
+
break;
|
223 |
+
case 'integer':
|
224 |
+
case 'double':
|
225 |
+
$p = (string) $val;
|
226 |
+
break;
|
227 |
+
case 'string':
|
228 |
+
$d .= ', ' . strlen( $val ) . ' characters';
|
229 |
+
$p = $val;
|
230 |
+
break;
|
231 |
+
case 'resource':
|
232 |
+
$d .= ', ' . get_resource_type( $val ) . ' type';
|
233 |
+
$p = (string) $val;
|
234 |
+
break;
|
235 |
+
case 'array':
|
236 |
+
$d .= ', ' . count( $val ) . ' elements';
|
237 |
+
break;
|
238 |
+
case 'object':
|
239 |
+
$d .= ', ' . get_class( $val ) . ', ' . count( get_object_vars( $val ) ) . ' properties';
|
240 |
+
break;
|
241 |
+
}
|
242 |
+
|
243 |
+
$cls = $this->css_class;
|
244 |
+
$xcls = ! $is_hash ? $cls . '_ad' : '';
|
245 |
+
$html = '<a ' . ($is_hash ? 'href="javascript:;"' : '') . ' onclick="' . $this->js_func . '(\'' . $this->html_id . '\',\'' . $id . '\');">';
|
246 |
+
$html .= ' <span class="' . $cls . '_a ' . $xcls . '" id="' . $this->html_id . '_a' . $id . '">►</span>';
|
247 |
+
$html .= ' <span class="' . $cls . '_k">' . $this->_esc_html( $key ) . '</span>';
|
248 |
+
$html .= ' <span class="' . $cls . '_d">(<span>' . ucwords( $t ) . '</span>' . $d . ')</span>';
|
249 |
+
$html .= ' <span class="' . $cls . '_p ' . $cls . '_t_' . $t . '">' . $this->_esc_html( $p ) . '</span>';
|
250 |
+
$html .= '</a>';
|
251 |
+
|
252 |
+
if ( $is_hash ) {
|
253 |
+
$html .= $this->_generate_value( $val, $cls . '_v', $this->html_id . '_v' . $id );
|
254 |
+
}
|
255 |
+
|
256 |
+
return $html;
|
257 |
+
}
|
258 |
+
|
259 |
+
protected function _generate_callable( $context, $callback ) {
|
260 |
+
$id = $this->_generate_dropid();
|
261 |
+
$ref = null;
|
262 |
+
$name = 'Anonymous';
|
263 |
+
$cls = $this->css_class;
|
264 |
+
|
265 |
+
if ( $this->_has_reflection ) {
|
266 |
+
if ( is_null( $context ) ) {
|
267 |
+
$ref = new ReflectionFunction( $callback );
|
268 |
+
} else {
|
269 |
+
$ref = new ReflectionMethod( $context, $callback );
|
270 |
+
}
|
271 |
+
$name = $ref->getName();
|
272 |
+
} elseif ( is_string( $callback ) ) {
|
273 |
+
$name = $callback;
|
274 |
+
}
|
275 |
+
|
276 |
+
if ( ! is_null( $ref ) ) {
|
277 |
+
$doc = $ref->getDocComment();
|
278 |
+
$prms = array();
|
279 |
+
foreach ( $ref->getParameters() as $p ) {
|
280 |
+
$prms[] = '$' . $p->getName() . (
|
281 |
+
$p->isDefaultValueAvailable()
|
282 |
+
? (
|
283 |
+
' = <span class="' . $cls . '_mv">' . (
|
284 |
+
$p->isDefaultValueConstant()
|
285 |
+
? $p->getDefaultValueConstantName()
|
286 |
+
: var_export( $p->getDefaultValue(), true )
|
287 |
+
) . '</span>'
|
288 |
+
)
|
289 |
+
: ''
|
290 |
+
);
|
291 |
+
}
|
292 |
+
} else {
|
293 |
+
$doc = null;
|
294 |
+
$prms = array( '???' );
|
295 |
+
}
|
296 |
+
|
297 |
+
$xcls = ! $doc ? $cls . '_ad' : '';
|
298 |
+
$html = '<a class="' . $cls . '_c" ' . ($doc ? 'href="javascript:;"' : '') . ' onclick="' . $this->js_func . '(\'' . $this->html_id . '\',\'' . $id . '\');">';
|
299 |
+
$html .= ' <span class="' . $cls . '_a ' . $xcls . '">►</span>';
|
300 |
+
$html .= ' <span class="' . $cls . '_k">' . $this->_esc_html( $name ) . '<span class="' . $cls . '_ma">(<span>' . implode( ', ', $prms ) . '</span>)</span></span>';
|
301 |
+
$html .= '</a>';
|
302 |
+
|
303 |
+
if ( $doc ) {
|
304 |
+
$html .= '<div id="' . $this->html_id . '_v' . $id . '" class="nice_r_v ' . $this->css_class . '_t_comment">';
|
305 |
+
$html .= nl2br( str_replace( ' ', ' ', $this->_esc_html( $doc ) ) );
|
306 |
+
$html .= '</div>';
|
307 |
+
}
|
308 |
+
|
309 |
+
return $html;
|
310 |
+
}
|
311 |
}
|
classes/SensorManager.php
CHANGED
@@ -1,75 +1,88 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* This Class load all the sensors and initialize them.
|
|
|
|
|
6 |
*/
|
7 |
-
final class WSAL_SensorManager extends WSAL_AbstractSensor
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor Manager.
|
4 |
*
|
5 |
* This Class load all the sensors and initialize them.
|
6 |
+
*
|
7 |
+
* @package Wsal
|
8 |
*/
|
9 |
+
final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Array of sensors.
|
13 |
+
*
|
14 |
+
* @var WSAL_AbstractSensor[]
|
15 |
+
*/
|
16 |
+
protected $sensors = array();
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Method: Constructor.
|
20 |
+
*
|
21 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
22 |
+
*/
|
23 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
24 |
+
parent::__construct( $plugin );
|
25 |
+
|
26 |
+
foreach ( glob( dirname( __FILE__ ) . '/Sensors/*.php' ) as $file ) {
|
27 |
+
$this->AddFromFile( $file );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Load Custom Sensor files from /wp-content/uploads/wp-security-audit-log/custom-sensors/
|
32 |
+
*/
|
33 |
+
$upload_dir = wp_upload_dir();
|
34 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log' . DIRECTORY_SEPARATOR . 'custom-sensors' . DIRECTORY_SEPARATOR;
|
35 |
+
// Check directory.
|
36 |
+
if ( is_dir( $uploads_dir_path ) && is_readable( $uploads_dir_path ) ) {
|
37 |
+
foreach ( glob( $uploads_dir_path . '*.php' ) as $file ) {
|
38 |
+
require_once( $file );
|
39 |
+
$file = substr( $file, 0, -4 );
|
40 |
+
$class = 'WSAL_Sensors_' . str_replace( $uploads_dir_path, '', $file );
|
41 |
+
$this->AddFromClass( $class );
|
42 |
+
}
|
43 |
+
}
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Method: Hook events of the sensors.
|
48 |
+
*/
|
49 |
+
public function HookEvents() {
|
50 |
+
foreach ( $this->sensors as $sensor ) {
|
51 |
+
$sensor->HookEvents();
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Method: Get the sensors.
|
57 |
+
*/
|
58 |
+
public function GetSensors() {
|
59 |
+
return $this->sensors;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Add new sensor from file inside autoloader path.
|
64 |
+
*
|
65 |
+
* @param string $file Path to file.
|
66 |
+
*/
|
67 |
+
public function AddFromFile( $file ) {
|
68 |
+
$this->AddFromClass( $this->plugin->GetClassFileClassName( $file ) );
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Add new sensor given class name.
|
73 |
+
*
|
74 |
+
* @param string $class Class name.
|
75 |
+
*/
|
76 |
+
public function AddFromClass( $class ) {
|
77 |
+
$this->AddInstance( new $class( $this->plugin ) );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Add newly created sensor to list.
|
82 |
+
*
|
83 |
+
* @param WSAL_AbstractSensor $sensor The new sensor.
|
84 |
+
*/
|
85 |
+
public function AddInstance( WSAL_AbstractSensor $sensor ) {
|
86 |
+
$this->sensors[] = $sensor;
|
87 |
+
}
|
88 |
}
|
classes/Sensors/BBPress.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Support for BBPress Forum Plugin.
|
6 |
*
|
7 |
* 8000 User created new forum
|
@@ -23,523 +35,607 @@
|
|
23 |
* 8020 User permanently deleted topic
|
24 |
* 8021 User restored topic from trash
|
25 |
* 8022 User changed visibility of a topic
|
|
|
|
|
|
|
26 |
*/
|
27 |
-
class WSAL_Sensors_BBPress extends WSAL_AbstractSensor
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
545 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: BBPress
|
4 |
+
*
|
5 |
+
* BBPress sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Support for BBPress Forum Plugin.
|
18 |
*
|
19 |
* 8000 User created new forum
|
35 |
* 8020 User permanently deleted topic
|
36 |
* 8021 User restored topic from trash
|
37 |
* 8022 User changed visibility of a topic
|
38 |
+
*
|
39 |
+
* @package Wsal
|
40 |
+
* @subpackage Sensors
|
41 |
*/
|
42 |
+
class WSAL_Sensors_BBPress extends WSAL_AbstractSensor {
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Old permalink
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*/
|
49 |
+
protected $_OldLink = null;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Listening to events using WP hooks.
|
53 |
+
*/
|
54 |
+
public function HookEvents() {
|
55 |
+
if ( current_user_can( 'edit_posts' ) ) {
|
56 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
57 |
+
}
|
58 |
+
add_action( 'post_updated', array( $this, 'CheckForumChange' ), 10, 3 );
|
59 |
+
add_action( 'delete_post', array( $this, 'EventForumDeleted' ), 10, 1 );
|
60 |
+
add_action( 'wp_trash_post', array( $this, 'EventForumTrashed' ), 10, 1 );
|
61 |
+
add_action( 'untrash_post', array( $this, 'EventForumUntrashed' ) );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Triggered when a user accesses the admin area.
|
66 |
+
*/
|
67 |
+
public function EventAdminInit() {
|
68 |
+
// Load old data, if applicable.
|
69 |
+
$this->RetrieveOldData();
|
70 |
+
// Check for Ajax changes.
|
71 |
+
$this->TriggerAjaxChange();
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Retrieve Old data.
|
76 |
+
*
|
77 |
+
* @global mixed $_POST post data
|
78 |
+
*/
|
79 |
+
protected function RetrieveOldData() {
|
80 |
+
// Filter $_POST array for security.
|
81 |
+
$post_array = filter_input_array( INPUT_POST );
|
82 |
+
|
83 |
+
if ( isset( $post_array['post_ID'] )
|
84 |
+
&& isset( $post_array['_wpnonce'] )
|
85 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
86 |
+
return false;
|
87 |
+
}
|
88 |
+
|
89 |
+
if ( isset( $post_array ) && isset( $post_array['post_ID'] )
|
90 |
+
&& ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
|
91 |
+
&& ! ( isset( $post_array['action'] ) && 'autosave' === $post_array['action'] )
|
92 |
+
) {
|
93 |
+
$post_id = intval( $post_array['post_ID'] );
|
94 |
+
$this->_OldLink = get_permalink( $post_id );
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Calls event forum changes.
|
100 |
+
*
|
101 |
+
* @param integer $post_id - Post ID.
|
102 |
+
* @param stdClass $newpost - The new post.
|
103 |
+
* @param stdClass $oldpost - The old post.
|
104 |
+
*/
|
105 |
+
public function CheckForumChange( $post_id, $newpost, $oldpost ) {
|
106 |
+
if ( $this->CheckBBPress( $oldpost ) ) {
|
107 |
+
$changes = 0 + $this->EventForumCreation( $oldpost, $newpost );
|
108 |
+
// Change Visibility.
|
109 |
+
if ( ! $changes ) {
|
110 |
+
$changes = $this->EventForumChangedVisibility( $oldpost );
|
111 |
+
}
|
112 |
+
// Change Type.
|
113 |
+
if ( ! $changes ) {
|
114 |
+
$changes = $this->EventForumChangedType( $oldpost );
|
115 |
+
}
|
116 |
+
// Change status.
|
117 |
+
if ( ! $changes ) {
|
118 |
+
$changes = $this->EventForumChangedStatus( $oldpost );
|
119 |
+
}
|
120 |
+
// Change Order, Parent or URL.
|
121 |
+
if ( ! $changes ) {
|
122 |
+
$changes = $this->EventForumChanged( $oldpost, $newpost );
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Permanently deleted.
|
129 |
+
*
|
130 |
+
* @param integer $post_id Post ID.
|
131 |
+
*/
|
132 |
+
public function EventForumDeleted( $post_id ) {
|
133 |
+
$post = get_post( $post_id );
|
134 |
+
if ( $this->CheckBBPress( $post ) ) {
|
135 |
+
switch ( $post->post_type ) {
|
136 |
+
case 'forum':
|
137 |
+
$this->EventForumByCode( $post, 8006 );
|
138 |
+
break;
|
139 |
+
case 'topic':
|
140 |
+
$this->EventTopicByCode( $post, 8020 );
|
141 |
+
break;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Moved to Trash.
|
148 |
+
*
|
149 |
+
* @param integer $post_id Post ID.
|
150 |
+
*/
|
151 |
+
public function EventForumTrashed( $post_id ) {
|
152 |
+
$post = get_post( $post_id );
|
153 |
+
if ( $this->CheckBBPress( $post ) ) {
|
154 |
+
switch ( $post->post_type ) {
|
155 |
+
case 'forum':
|
156 |
+
$this->EventForumByCode( $post, 8005 );
|
157 |
+
break;
|
158 |
+
case 'topic':
|
159 |
+
$this->EventTopicByCode( $post, 8019 );
|
160 |
+
break;
|
161 |
+
}
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Restored from Trash.
|
167 |
+
*
|
168 |
+
* @param integer $post_id Post ID.
|
169 |
+
*/
|
170 |
+
public function EventForumUntrashed( $post_id ) {
|
171 |
+
$post = get_post( $post_id );
|
172 |
+
if ( $this->CheckBBPress( $post ) ) {
|
173 |
+
switch ( $post->post_type ) {
|
174 |
+
case 'forum':
|
175 |
+
$this->EventForumByCode( $post, 8007 );
|
176 |
+
break;
|
177 |
+
case 'topic':
|
178 |
+
$this->EventTopicByCode( $post, 8021 );
|
179 |
+
break;
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Check post type.
|
186 |
+
*
|
187 |
+
* @param stdClass $post Post.
|
188 |
+
* @return boolean
|
189 |
+
*/
|
190 |
+
private function CheckBBPress( $post ) {
|
191 |
+
switch ( $post->post_type ) {
|
192 |
+
case 'forum':
|
193 |
+
case 'topic':
|
194 |
+
case 'reply':
|
195 |
+
return true;
|
196 |
+
default:
|
197 |
+
return false;
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Event post creation.
|
203 |
+
*
|
204 |
+
* @param stdClass $old_post - The old post.
|
205 |
+
* @param stdClass $new_post - The new post.
|
206 |
+
* @return boolean
|
207 |
+
*/
|
208 |
+
private function EventForumCreation( $old_post, $new_post ) {
|
209 |
+
// Filter $_POST array for security.
|
210 |
+
$post_array = filter_input_array( INPUT_POST );
|
211 |
+
|
212 |
+
if ( isset( $post_array['post_ID'] )
|
213 |
+
&& isset( $post_array['_wpnonce'] )
|
214 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
215 |
+
return false;
|
216 |
+
}
|
217 |
+
|
218 |
+
$original = isset( $post_array['original_post_status'] ) ? $post_array['original_post_status'] : '';
|
219 |
+
if ( 'draft' === $old_post->post_status || 'auto-draft' === $original ) {
|
220 |
+
$editor_link = $this->GetEditorLink( $new_post );
|
221 |
+
if ( 'publish' === $new_post->post_status ) {
|
222 |
+
switch ( $old_post->post_type ) {
|
223 |
+
case 'forum':
|
224 |
+
$this->plugin->alerts->Trigger(
|
225 |
+
8000, array(
|
226 |
+
'ForumName' => $new_post->post_title,
|
227 |
+
'ForumURL' => get_permalink( $new_post->ID ),
|
228 |
+
$editor_link['name'] => $editor_link['value'],
|
229 |
+
)
|
230 |
+
);
|
231 |
+
break;
|
232 |
+
case 'topic':
|
233 |
+
$this->plugin->alerts->Trigger(
|
234 |
+
8014, array(
|
235 |
+
'TopicName' => $new_post->post_title,
|
236 |
+
'TopicURL' => get_permalink( $new_post->ID ),
|
237 |
+
$editor_link['name'] => $editor_link['value'],
|
238 |
+
)
|
239 |
+
);
|
240 |
+
break;
|
241 |
+
}
|
242 |
+
return 1;
|
243 |
+
}
|
244 |
+
}
|
245 |
+
return 0;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Event post changed visibility.
|
250 |
+
*
|
251 |
+
* @param stdClass $post The post.
|
252 |
+
* @return boolean $result
|
253 |
+
*/
|
254 |
+
private function EventForumChangedVisibility( $post ) {
|
255 |
+
// Filter $_POST array for security.
|
256 |
+
$post_array = filter_input_array( INPUT_POST );
|
257 |
+
|
258 |
+
if ( isset( $post_array['post_ID'] )
|
259 |
+
&& isset( $post_array['_wpnonce'] )
|
260 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
261 |
+
return false;
|
262 |
+
}
|
263 |
+
|
264 |
+
$result = 0;
|
265 |
+
$editor_link = $this->GetEditorLink( $post );
|
266 |
+
switch ( $post->post_type ) {
|
267 |
+
case 'forum':
|
268 |
+
$old_visibility = ! empty( $post_array['visibility'] ) ? $post_array['visibility'] : '';
|
269 |
+
$new_visibility = ! empty( $post_array['bbp_forum_visibility'] ) ? $post_array['bbp_forum_visibility'] : '';
|
270 |
+
$new_visibility = ( 'publish' === $new_visibility ) ? 'public' : $new_visibility;
|
271 |
+
|
272 |
+
if ( ! empty( $new_visibility ) && 'auto-draft' != $old_visibility && $old_visibility != $new_visibility ) {
|
273 |
+
$this->plugin->alerts->Trigger(
|
274 |
+
8002, array(
|
275 |
+
'ForumName' => $post->post_title,
|
276 |
+
'OldVisibility' => $old_visibility,
|
277 |
+
'NewVisibility' => $new_visibility,
|
278 |
+
$editor_link['name'] => $editor_link['value'],
|
279 |
+
)
|
280 |
+
);
|
281 |
+
$result = 1;
|
282 |
+
}
|
283 |
+
break;
|
284 |
+
case 'topic':
|
285 |
+
$old_visibility = ! empty( $post_array['hidden_post_visibility'] ) ? $post_array['hidden_post_visibility'] : '';
|
286 |
+
$new_visibility = ! empty( $post_array['visibility'] ) ? $post_array['visibility'] : '';
|
287 |
+
$new_visibility = ( 'password' === $new_visibility ) ? 'password protected' : $new_visibility;
|
288 |
+
|
289 |
+
if ( ! empty( $new_visibility ) && 'auto-draft' != $old_visibility && $old_visibility != $new_visibility ) {
|
290 |
+
$this->plugin->alerts->Trigger(
|
291 |
+
8022, array(
|
292 |
+
'TopicName' => $post->post_title,
|
293 |
+
'OldVisibility' => $old_visibility,
|
294 |
+
'NewVisibility' => $new_visibility,
|
295 |
+
$editor_link['name'] => $editor_link['value'],
|
296 |
+
)
|
297 |
+
);
|
298 |
+
$result = 1;
|
299 |
+
}
|
300 |
+
break;
|
301 |
+
}
|
302 |
+
return $result;
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Event post changed type.
|
307 |
+
*
|
308 |
+
* @param stdClass $post The post.
|
309 |
+
* @return boolean $result
|
310 |
+
*/
|
311 |
+
private function EventForumChangedType( $post ) {
|
312 |
+
// Filter $_POST array for security.
|
313 |
+
$post_array = filter_input_array( INPUT_POST );
|
314 |
+
|
315 |
+
if ( isset( $post_array['post_ID'] )
|
316 |
+
&& isset( $post_array['_wpnonce'] )
|
317 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
318 |
+
return false;
|
319 |
+
}
|
320 |
+
|
321 |
+
$result = 0;
|
322 |
+
$editor_link = $this->GetEditorLink( $post );
|
323 |
+
switch ( $post->post_type ) {
|
324 |
+
case 'forum':
|
325 |
+
$bbp_forum_type = get_post_meta( $post->ID, '_bbp_forum_type', true );
|
326 |
+
$old_type = ! empty( $bbp_forum_type ) ? $bbp_forum_type : 'forum';
|
327 |
+
$new_type = ! empty( $post_array['bbp_forum_type'] ) ? $post_array['bbp_forum_type'] : '';
|
328 |
+
if ( ! empty( $new_type ) && $old_type != $new_type ) {
|
329 |
+
$this->plugin->alerts->Trigger(
|
330 |
+
8011, array(
|
331 |
+
'ForumName' => $post->post_title,
|
332 |
+
'OldType' => $old_type,
|
333 |
+
'NewType' => $new_type,
|
334 |
+
$editor_link['name'] => $editor_link['value'],
|
335 |
+
)
|
336 |
+
);
|
337 |
+
$result = 1;
|
338 |
+
}
|
339 |
+
break;
|
340 |
+
case 'topic':
|
341 |
+
if ( ! empty( $post_array['parent_id'] ) ) {
|
342 |
+
$post_id = $post_array['parent_id'];
|
343 |
+
} else {
|
344 |
+
$post_id = $post->ID;
|
345 |
+
}
|
346 |
+
$bbp_sticky_topics = maybe_unserialize( get_post_meta( $post_id, '_bbp_sticky_topics', true ) );
|
347 |
+
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
348 |
+
$bbp_super_sticky_topics = maybe_unserialize( $fn( '_bbp_super_sticky_topics' ) );
|
349 |
+
if ( ! empty( $bbp_sticky_topics ) && in_array( $post->ID, $bbp_sticky_topics ) ) {
|
350 |
+
$old_type = 'sticky';
|
351 |
+
} elseif ( ! empty( $bbp_super_sticky_topics ) && in_array( $post->ID, $bbp_super_sticky_topics ) ) {
|
352 |
+
$old_type = 'super';
|
353 |
+
} else {
|
354 |
+
$old_type = 'unstick';
|
355 |
+
}
|
356 |
+
$new_type = ! empty( $post_array['bbp_stick_topic'] ) ? $post_array['bbp_stick_topic'] : '';
|
357 |
+
if ( ! empty( $new_type ) && $old_type != $new_type ) {
|
358 |
+
$this->plugin->alerts->Trigger(
|
359 |
+
8016, array(
|
360 |
+
'TopicName' => $post->post_title,
|
361 |
+
'OldType' => ( 'unstick' == $old_type ) ? 'normal' : (( 'super' == $old_type ) ? 'super sticky' : $old_type),
|
362 |
+
'NewType' => ( 'unstick' == $new_type ) ? 'normal' : (( 'super' == $new_type ) ? 'super sticky' : $new_type),
|
363 |
+
$editor_link['name'] => $editor_link['value'],
|
364 |
+
)
|
365 |
+
);
|
366 |
+
$result = 1;
|
367 |
+
}
|
368 |
+
break;
|
369 |
+
}
|
370 |
+
return $result;
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Event post changed status.
|
375 |
+
*
|
376 |
+
* @param stdClass $post The post.
|
377 |
+
* @return boolean $result
|
378 |
+
*/
|
379 |
+
private function EventForumChangedStatus( $post ) {
|
380 |
+
// Filter $_POST and $_GET array for security.
|
381 |
+
$post_array = filter_input_array( INPUT_POST );
|
382 |
+
$get_array = filter_input_array( INPUT_GET );
|
383 |
+
|
384 |
+
if ( isset( $post_array['post_ID'] )
|
385 |
+
&& isset( $post_array['_wpnonce'] )
|
386 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
387 |
+
return false;
|
388 |
+
}
|
389 |
+
|
390 |
+
$result = 0;
|
391 |
+
$editor_link = $this->GetEditorLink( $post );
|
392 |
+
switch ( $post->post_type ) {
|
393 |
+
case 'forum':
|
394 |
+
$bbp_status = get_post_meta( $post->ID, '_bbp_status', true );
|
395 |
+
$old_status = ! empty( $bbp_status ) ? $bbp_status : 'open';
|
396 |
+
$new_status = ! empty( $post_array['bbp_forum_status'] ) ? $post_array['bbp_forum_status'] : '';
|
397 |
+
if ( ! empty( $new_status ) && $old_status !== $new_status ) {
|
398 |
+
$this->plugin->alerts->Trigger(
|
399 |
+
8001, array(
|
400 |
+
'ForumName' => $post->post_title,
|
401 |
+
'OldStatus' => $old_status,
|
402 |
+
'NewStatus' => $new_status,
|
403 |
+
$editor_link['name'] => $editor_link['value'],
|
404 |
+
)
|
405 |
+
);
|
406 |
+
$result = 1;
|
407 |
+
}
|
408 |
+
break;
|
409 |
+
case 'topic':
|
410 |
+
$old_status = ! empty( $post_array['original_post_status'] ) ? $post_array['original_post_status'] : '';
|
411 |
+
$new_status = ! empty( $post_array['post_status'] ) ? $post_array['post_status'] : '';
|
412 |
+
// In case of Ajax request Spam/Not spam.
|
413 |
+
if ( isset( $get_array['action'] ) && 'bbp_toggle_topic_spam' === $get_array['action'] ) {
|
414 |
+
$old_status = $post->post_status;
|
415 |
+
$new_status = 'spam';
|
416 |
+
if ( isset( $get_array['post_status'] ) && 'spam' === $get_array['post_status'] ) {
|
417 |
+
$new_status = 'publish';
|
418 |
+
}
|
419 |
+
}
|
420 |
+
// In case of Ajax request Close/Open.
|
421 |
+
if ( isset( $get_array['action'] ) && 'bbp_toggle_topic_close' === $get_array['action'] ) {
|
422 |
+
$old_status = $post->post_status;
|
423 |
+
$new_status = 'closed';
|
424 |
+
if ( isset( $get_array['post_status'] ) && 'closed' === $get_array['post_status'] ) {
|
425 |
+
$new_status = 'publish';
|
426 |
+
}
|
427 |
+
}
|
428 |
+
if ( ! empty( $new_status ) && $old_status !== $new_status ) {
|
429 |
+
$this->plugin->alerts->Trigger(
|
430 |
+
8015, array(
|
431 |
+
'TopicName' => $post->post_title,
|
432 |
+
'OldStatus' => ( 'publish' === $old_status ) ? 'open' : $old_status,
|
433 |
+
'NewStatus' => ( 'publish' === $new_status ) ? 'open' : $new_status,
|
434 |
+
$editor_link['name'] => $editor_link['value'],
|
435 |
+
)
|
436 |
+
);
|
437 |
+
$result = 1;
|
438 |
+
}
|
439 |
+
break;
|
440 |
+
}
|
441 |
+
return $result;
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Event post changed (order, parent, URL).
|
446 |
+
*
|
447 |
+
* @param stdClass $old_post - The old post.
|
448 |
+
* @param stdClass $new_post - The new post.
|
449 |
+
* @return boolean $result
|
450 |
+
*/
|
451 |
+
private function EventForumChanged( $old_post, $new_post ) {
|
452 |
+
$editor_link = $this->GetEditorLink( $new_post );
|
453 |
+
// Changed Order.
|
454 |
+
if ( $old_post->menu_order != $new_post->menu_order ) {
|
455 |
+
$this->plugin->alerts->Trigger(
|
456 |
+
8004, array(
|
457 |
+
'ForumName' => $new_post->post_title,
|
458 |
+
'OldOrder' => $old_post->menu_order,
|
459 |
+
'NewOrder' => $new_post->menu_order,
|
460 |
+
$editor_link['name'] => $editor_link['value'],
|
461 |
+
)
|
462 |
+
);
|
463 |
+
return 1;
|
464 |
+
}
|
465 |
+
// Changed Parent.
|
466 |
+
if ( $old_post->post_parent != $new_post->post_parent ) {
|
467 |
+
switch ( $old_post->post_type ) {
|
468 |
+
case 'forum':
|
469 |
+
$this->plugin->alerts->Trigger(
|
470 |
+
8008, array(
|
471 |
+
'ForumName' => $new_post->post_title,
|
472 |
+
'OldParent' => $old_post->post_parent ? get_the_title( $old_post->post_parent ) : 'no parent',
|
473 |
+
'NewParent' => $new_post->post_parent ? get_the_title( $new_post->post_parent ) : 'no parent',
|
474 |
+
$editor_link['name'] => $editor_link['value'],
|
475 |
+
)
|
476 |
+
);
|
477 |
+
break;
|
478 |
+
case 'topic':
|
479 |
+
$this->plugin->alerts->Trigger(
|
480 |
+
8018, array(
|
481 |
+
'TopicName' => $new_post->post_title,
|
482 |
+
'OldForum' => $old_post->post_parent ? get_the_title( $old_post->post_parent ) : 'no parent',
|
483 |
+
'NewForum' => $new_post->post_parent ? get_the_title( $new_post->post_parent ) : 'no parent',
|
484 |
+
$editor_link['name'] => $editor_link['value'],
|
485 |
+
)
|
486 |
+
);
|
487 |
+
break;
|
488 |
+
}
|
489 |
+
return 1;
|
490 |
+
}
|
491 |
+
// Changed URL.
|
492 |
+
$old_link = $this->_OldLink;
|
493 |
+
$new_link = get_permalink( $new_post->ID );
|
494 |
+
if ( ! empty( $old_link ) && $old_link != $new_link ) {
|
495 |
+
switch ( $old_post->post_type ) {
|
496 |
+
case 'forum':
|
497 |
+
$this->plugin->alerts->Trigger(
|
498 |
+
8003, array(
|
499 |
+
'ForumName' => $new_post->post_title,
|
500 |
+
'OldUrl' => $old_link,
|
501 |
+
'NewUrl' => $new_link,
|
502 |
+
$editor_link['name'] => $editor_link['value'],
|
503 |
+
)
|
504 |
+
);
|
505 |
+
break;
|
506 |
+
case 'topic':
|
507 |
+
$this->plugin->alerts->Trigger(
|
508 |
+
8017, array(
|
509 |
+
'TopicName' => $new_post->post_title,
|
510 |
+
'OldUrl' => $old_link,
|
511 |
+
'NewUrl' => $new_link,
|
512 |
+
$editor_link['name'] => $editor_link['value'],
|
513 |
+
)
|
514 |
+
);
|
515 |
+
break;
|
516 |
+
}
|
517 |
+
return 1;
|
518 |
+
}
|
519 |
+
return 0;
|
520 |
+
}
|
521 |
+
|
522 |
+
/**
|
523 |
+
* Trigger Event (Forum).
|
524 |
+
*
|
525 |
+
* @param stdClass $post - The post.
|
526 |
+
* @param integer $event - Event code.
|
527 |
+
*/
|
528 |
+
private function EventForumByCode( $post, $event ) {
|
529 |
+
$editor_link = $this->GetEditorLink( $post );
|
530 |
+
$this->plugin->alerts->Trigger(
|
531 |
+
$event, array(
|
532 |
+
'ForumID' => $post->ID,
|
533 |
+
'ForumName' => $post->post_title,
|
534 |
+
$editor_link['name'] => $editor_link['value'],
|
535 |
+
)
|
536 |
+
);
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Trigger Event (Topic).
|
541 |
+
*
|
542 |
+
* @param stdClass $post - The post.
|
543 |
+
* @param integer $event - Event code.
|
544 |
+
*/
|
545 |
+
private function EventTopicByCode( $post, $event ) {
|
546 |
+
$editor_link = $this->GetEditorLink( $post );
|
547 |
+
$this->plugin->alerts->Trigger(
|
548 |
+
$event, array(
|
549 |
+
'TopicID' => $post->ID,
|
550 |
+
'TopicName' => $post->post_title,
|
551 |
+
$editor_link['name'] => $editor_link['value'],
|
552 |
+
)
|
553 |
+
);
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Trigger of ajax events generated in the Topic Grid
|
558 |
+
*
|
559 |
+
* @global mixed $_GET Get data
|
560 |
+
*/
|
561 |
+
public function TriggerAjaxChange() {
|
562 |
+
// Filter $_GET array for security.
|
563 |
+
$get_array = filter_input_array( INPUT_GET );
|
564 |
+
|
565 |
+
if ( ! empty( $get_array['post_type'] ) && ! empty( $get_array['topic_id'] ) ) {
|
566 |
+
if ( 'topic' == $get_array['post_type'] ) {
|
567 |
+
$post = get_post( $get_array['topic_id'] );
|
568 |
+
|
569 |
+
// Topic type.
|
570 |
+
if ( isset( $get_array['action'] ) && 'bbp_toggle_topic_stick' == $get_array['action'] ) {
|
571 |
+
if ( ! empty( $post->post_parent ) ) {
|
572 |
+
$post_id = $post->post_parent;
|
573 |
+
} else {
|
574 |
+
$post_id = $get_array['topic_id'];
|
575 |
+
}
|
576 |
+
|
577 |
+
$bbp_sticky_topics = maybe_unserialize( get_post_meta( $post_id, '_bbp_sticky_topics', true ) );
|
578 |
+
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
579 |
+
$bbp_super_sticky_topics = maybe_unserialize( $fn( '_bbp_super_sticky_topics' ) );
|
580 |
+
if ( ! empty( $bbp_sticky_topics ) && in_array( $get_array['topic_id'], $bbp_sticky_topics ) ) {
|
581 |
+
$old_type = 'sticky';
|
582 |
+
} elseif ( ! empty( $bbp_super_sticky_topics ) && in_array( $get_array['topic_id'], $bbp_super_sticky_topics ) ) {
|
583 |
+
$old_type = 'super sticky';
|
584 |
+
} else {
|
585 |
+
$old_type = 'normal';
|
586 |
+
}
|
587 |
+
|
588 |
+
switch ( $old_type ) {
|
589 |
+
case 'sticky':
|
590 |
+
case 'super sticky':
|
591 |
+
$new_type = 'normal';
|
592 |
+
break;
|
593 |
+
case 'normal':
|
594 |
+
if ( isset( $get_array['super'] ) && 1 == $get_array['super'] ) {
|
595 |
+
$new_type = 'super sticky';
|
596 |
+
} else {
|
597 |
+
$new_type = 'sticky';
|
598 |
+
}
|
599 |
+
break;
|
600 |
+
}
|
601 |
+
$editor_link = $this->GetEditorLink( $post );
|
602 |
+
|
603 |
+
if ( ! empty( $new_type ) && $old_type != $new_type ) {
|
604 |
+
$this->plugin->alerts->Trigger(
|
605 |
+
8016, array(
|
606 |
+
'TopicName' => $post->post_title,
|
607 |
+
'OldType' => $old_type,
|
608 |
+
'NewType' => $new_type,
|
609 |
+
$editor_link['name'] => $editor_link['value'],
|
610 |
+
)
|
611 |
+
);
|
612 |
+
}
|
613 |
+
}
|
614 |
+
}
|
615 |
+
}
|
616 |
+
}
|
617 |
+
|
618 |
+
/**
|
619 |
+
* Get editor link.
|
620 |
+
*
|
621 |
+
* @param stdClass $post - The post.
|
622 |
+
* @return array $editor_link_array - Name and value link.
|
623 |
+
*/
|
624 |
+
private function GetEditorLink( $post ) {
|
625 |
+
$name = 'EditorLink';
|
626 |
+
switch ( $post->post_type ) {
|
627 |
+
case 'forum':
|
628 |
+
$name .= 'Forum' ;
|
629 |
+
break;
|
630 |
+
case 'topic':
|
631 |
+
$name .= 'Topic' ;
|
632 |
+
break;
|
633 |
+
}
|
634 |
+
$value = get_edit_post_link( $post->ID );
|
635 |
+
$editor_link_array = array(
|
636 |
+
'name' => $name,
|
637 |
+
'value' => $value,
|
638 |
+
);
|
639 |
+
return $editor_link_array;
|
640 |
+
}
|
641 |
}
|
classes/Sensors/Comments.php
CHANGED
@@ -1,8 +1,20 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*
|
7 |
* 2090 User approved a comment
|
8 |
* 2091 User unapproved a comment
|
@@ -14,173 +26,191 @@
|
|
14 |
* 2097 User restored a comment from the trash
|
15 |
* 2098 User permanently deleted a comment
|
16 |
* 2099 User posted a comment
|
|
|
|
|
|
|
17 |
*/
|
18 |
-
class WSAL_Sensors_Comments extends WSAL_AbstractSensor
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Comments
|
4 |
+
*
|
5 |
+
* Comments sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* WordPress Comments.
|
18 |
*
|
19 |
* 2090 User approved a comment
|
20 |
* 2091 User unapproved a comment
|
26 |
* 2097 User restored a comment from the trash
|
27 |
* 2098 User permanently deleted a comment
|
28 |
* 2099 User posted a comment
|
29 |
+
*
|
30 |
+
* @package Wsal
|
31 |
+
* @subpackage Sensors
|
32 |
*/
|
33 |
+
class WSAL_Sensors_Comments extends WSAL_AbstractSensor {
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Listening to events using WP hooks.
|
37 |
+
*/
|
38 |
+
public function HookEvents() {
|
39 |
+
add_action( 'edit_comment', array( $this, 'EventCommentEdit' ), 10, 1 );
|
40 |
+
add_action( 'transition_comment_status', array( $this, 'EventCommentApprove' ), 10, 3 );
|
41 |
+
add_action( 'spammed_comment', array( $this, 'EventCommentSpam' ), 10, 1 );
|
42 |
+
add_action( 'unspammed_comment', array( $this, 'EventCommentUnspam' ), 10, 1 );
|
43 |
+
add_action( 'trashed_comment', array( $this, 'EventCommentTrash' ), 10, 1 );
|
44 |
+
add_action( 'untrashed_comment', array( $this, 'EventCommentUntrash' ), 10, 1 );
|
45 |
+
add_action( 'deleted_comment', array( $this, 'EventCommentDeleted' ), 10, 1 );
|
46 |
+
add_action( 'comment_post', array( $this, 'EventComment' ), 10, 2 );
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Trigger comment edit.
|
51 |
+
*
|
52 |
+
* @param integer $comment_id - Comment ID.
|
53 |
+
*/
|
54 |
+
public function EventCommentEdit( $comment_id ) {
|
55 |
+
$comment = get_comment( $comment_id );
|
56 |
+
$this->EventGeneric( $comment_id, 2093 );
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Trigger comment status.
|
61 |
+
*
|
62 |
+
* @param string $new_status - New status.
|
63 |
+
* @param string $old_status - Old status.
|
64 |
+
* @param stdClass $comment - Comment.
|
65 |
+
*/
|
66 |
+
public function EventCommentApprove( $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;
|
70 |
+
$fields = array(
|
71 |
+
'PostTitle' => $post->post_title,
|
72 |
+
'Author' => $comment->comment_author,
|
73 |
+
'Date' => $comment->comment_date,
|
74 |
+
'CommentLink' => '<a target="_blank" href="' . $comment_link . '">' . $comment->comment_date . '</a>',
|
75 |
+
);
|
76 |
+
|
77 |
+
if ( 'approved' == $new_status ) {
|
78 |
+
$this->plugin->alerts->Trigger( 2090, $fields );
|
79 |
+
}
|
80 |
+
if ( 'unapproved' == $new_status ) {
|
81 |
+
$this->plugin->alerts->Trigger( 2091, $fields );
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Trigger comment spam.
|
88 |
+
*
|
89 |
+
* @param integer $comment_id - Comment ID.
|
90 |
+
*/
|
91 |
+
public function EventCommentSpam( $comment_id ) {
|
92 |
+
$this->EventGeneric( $comment_id, 2094 );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Trigger comment unspam.
|
97 |
+
*
|
98 |
+
* @param integer $comment_id - Comment ID.
|
99 |
+
*/
|
100 |
+
public function EventCommentUnspam( $comment_id ) {
|
101 |
+
$this->EventGeneric( $comment_id, 2095 );
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Trigger comment trash.
|
106 |
+
*
|
107 |
+
* @param integer $comment_id - Comment ID.
|
108 |
+
*/
|
109 |
+
public function EventCommentTrash( $comment_id ) {
|
110 |
+
$this->EventGeneric( $comment_id, 2096 );
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Trigger comment untrash.
|
115 |
+
*
|
116 |
+
* @param integer $comment_id comment ID.
|
117 |
+
*/
|
118 |
+
public function EventCommentUntrash( $comment_id ) {
|
119 |
+
$this->EventGeneric( $comment_id, 2097 );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Trigger comment deleted.
|
124 |
+
*
|
125 |
+
* @param integer $comment_id comment ID.
|
126 |
+
*/
|
127 |
+
public function EventCommentDeleted( $comment_id ) {
|
128 |
+
$this->EventGeneric( $comment_id, 2098 );
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Fires immediately after a comment is inserted into the database.
|
133 |
+
*
|
134 |
+
* @param int $comment_id The comment ID.
|
135 |
+
* @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
|
136 |
+
*/
|
137 |
+
public function EventComment( $comment_id, $comment_approved = null ) {
|
138 |
+
// Filter $_POST array for security.
|
139 |
+
$post_array = filter_input_array( INPUT_POST );
|
140 |
+
|
141 |
+
if ( isset( $post_array['action'] ) && 'replyto-comment' == $post_array['action'] ) {
|
142 |
+
$this->EventGeneric( $comment_id, 2092 );
|
143 |
+
}
|
144 |
+
if ( isset( $post_array['comment'] ) ) {
|
145 |
+
$comment = get_comment( $comment_id );
|
146 |
+
if ( ! empty( $comment ) ) {
|
147 |
+
if ( 'spam' != $comment->comment_approved ) {
|
148 |
+
$post = get_post( $comment->comment_post_ID );
|
149 |
+
$comment_link = get_permalink( $post->ID ) . '#comment-' . $comment_id;
|
150 |
+
$fields = array(
|
151 |
+
'Date' => $comment->comment_date,
|
152 |
+
'CommentLink' => '<a target="_blank" href="' . $comment_link . '">' . $comment->comment_date . '</a>',
|
153 |
+
);
|
154 |
+
if ( ! username_exists( $comment->comment_author ) ) {
|
155 |
+
// Set the fields.
|
156 |
+
$fields['CommentMsg'] = sprintf( 'A comment was posted in response to the post <strong>%s</strong>. The comment was posted by <strong>%s</strong>', $post->post_title, $this->CheckAuthor( $comment ) );
|
157 |
+
$fields['Username'] = 'Website Visitor';
|
158 |
+
} else {
|
159 |
+
// Get user roles.
|
160 |
+
$user_data = get_user_by( 'login', $comment->comment_author );
|
161 |
+
$user_roles = $user_data->roles;
|
162 |
+
|
163 |
+
// Check if superadmin.
|
164 |
+
if ( function_exists( 'is_super_admin' ) && is_super_admin() ) {
|
165 |
+
$user_roles[] = 'superadmin';
|
166 |
+
}
|
167 |
+
|
168 |
+
// Set the fields.
|
169 |
+
$fields['Username'] = $comment->comment_author;
|
170 |
+
$fields['CurrentUserRoles'] = $user_roles;
|
171 |
+
$fields['CommentMsg'] = sprintf( 'Posted a comment in response to the post <strong>%s</strong>', $post->post_title );
|
172 |
+
}
|
173 |
+
|
174 |
+
$this->plugin->alerts->Trigger( 2099, $fields );
|
175 |
+
}
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Trigger generic event.
|
182 |
+
*
|
183 |
+
* @param integer $comment_id - Comment ID.
|
184 |
+
* @param integer $alert_code - Event code.
|
185 |
+
*/
|
186 |
+
private function EventGeneric( $comment_id, $alert_code ) {
|
187 |
+
$comment = get_comment( $comment_id );
|
188 |
+
if ( ! empty( $comment ) ) {
|
189 |
+
$post = get_post( $comment->comment_post_ID );
|
190 |
+
$comment_link = get_permalink( $post->ID ) . '#comment-' . $comment_id;
|
191 |
+
$fields = array(
|
192 |
+
'PostTitle' => $post->post_title,
|
193 |
+
'Author' => $comment->comment_author,
|
194 |
+
'Date' => $comment->comment_date,
|
195 |
+
'CommentLink' => '<a target="_blank" href="' . $comment_link . '">' . $comment->comment_date . '</a>',
|
196 |
+
);
|
197 |
+
|
198 |
+
$this->plugin->alerts->Trigger( $alert_code, $fields );
|
199 |
+
}
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Shows the username if the comment is owned by a user
|
204 |
+
* and the email if the comment was posted by a non WordPress user
|
205 |
+
*
|
206 |
+
* @param stdClass $comment - Comment.
|
207 |
+
* @return string - Author username or email.
|
208 |
+
*/
|
209 |
+
private function CheckAuthor( $comment ) {
|
210 |
+
if ( username_exists( $comment->comment_author ) ) {
|
211 |
+
return $comment->comment_author;
|
212 |
+
} else {
|
213 |
+
return $comment->comment_author_email;
|
214 |
+
}
|
215 |
+
}
|
216 |
}
|
classes/Sensors/Content.php
CHANGED
@@ -1,8 +1,20 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*
|
7 |
* 2000 User created a new blog post and saved it as draft
|
8 |
* 2001 User published a blog post
|
@@ -84,22 +96,32 @@
|
|
84 |
* 2123 User renamed tag
|
85 |
* 2124 User changed tag slug
|
86 |
* 2125 User changed tag description
|
|
|
|
|
|
|
87 |
*/
|
88 |
class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
|
89 |
/**
|
90 |
-
*
|
|
|
|
|
91 |
*/
|
92 |
-
protected $
|
93 |
|
94 |
/**
|
95 |
-
*
|
|
|
|
|
96 |
*/
|
97 |
-
protected $
|
98 |
|
99 |
/**
|
100 |
-
*
|
|
|
|
|
101 |
*/
|
102 |
-
protected $
|
103 |
|
104 |
/**
|
105 |
* Old tags.
|
@@ -109,36 +131,39 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
109 |
protected $_old_tags = null;
|
110 |
|
111 |
/**
|
112 |
-
*
|
|
|
|
|
113 |
*/
|
114 |
-
protected $
|
115 |
|
116 |
/**
|
117 |
-
*
|
|
|
|
|
118 |
*/
|
119 |
-
protected $
|
120 |
|
121 |
/**
|
122 |
* Listening to events using WP hooks.
|
123 |
*/
|
124 |
-
public function HookEvents()
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
add_action('
|
130 |
-
add_action('
|
131 |
-
add_action('
|
132 |
-
add_action('
|
133 |
-
add_action('
|
134 |
-
add_action('
|
135 |
-
|
136 |
-
|
137 |
-
add_action('create_category', array($this, 'EventCategoryCreation'), 10, 1);
|
138 |
add_action( 'create_post_tag', array( $this, 'EventTagCreation' ), 10, 1 );
|
139 |
|
140 |
add_action( 'wp_head', array( $this, 'ViewingPost' ), 10 );
|
141 |
-
add_filter('post_edit_form_tag', array($this, 'EditingPost'), 10, 1);
|
142 |
|
143 |
add_filter( 'wp_update_term_data', array( $this, 'event_terms_rename' ), 10, 4 );
|
144 |
}
|
@@ -153,7 +178,6 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
153 |
* @since 2.6.9
|
154 |
*/
|
155 |
public function event_terms_rename( $data, $term_id, $taxonomy, $args ) {
|
156 |
-
|
157 |
// Check if the taxonomy is term.
|
158 |
if ( 'post_tag' !== $taxonomy ) {
|
159 |
return $data;
|
@@ -169,29 +193,39 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
169 |
$old_name = $term->name;
|
170 |
$old_slug = $term->slug;
|
171 |
$old_desc = $term->description;
|
|
|
172 |
|
173 |
// Update if both names are not same.
|
174 |
if ( $old_name !== $new_name ) {
|
175 |
-
$this->plugin->alerts->Trigger(
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
179 |
}
|
180 |
|
181 |
// Update if both slugs are not same.
|
182 |
if ( $old_slug !== $new_slug ) {
|
183 |
-
$this->plugin->alerts->Trigger(
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
|
|
|
|
|
|
188 |
}
|
189 |
|
190 |
// Update if both descriptions are not same.
|
191 |
if ( $old_desc !== $new_desc ) {
|
192 |
-
$this->plugin->alerts->Trigger(
|
193 |
-
|
194 |
-
|
|
|
|
|
|
|
195 |
}
|
196 |
return $data;
|
197 |
|
@@ -199,32 +233,32 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
199 |
|
200 |
/**
|
201 |
* Gets the alert code based on the type of post.
|
202 |
-
*
|
203 |
-
* @param
|
204 |
-
* @param integer
|
205 |
-
* @param integer
|
206 |
-
* @
|
|
|
207 |
*/
|
208 |
-
protected function GetEventTypeForPostType($post, $
|
209 |
-
|
210 |
-
switch ($post->post_type) {
|
211 |
case 'page':
|
212 |
-
return $
|
213 |
case 'post':
|
214 |
-
return $
|
215 |
default:
|
216 |
-
return $
|
217 |
}
|
218 |
}
|
219 |
|
220 |
/**
|
221 |
* Triggered when a user accesses the admin area.
|
222 |
*/
|
223 |
-
public function
|
224 |
-
|
225 |
-
// load old data, if applicable
|
226 |
$this->RetrieveOldData();
|
227 |
-
|
|
|
228 |
$this->CheckCategoryDeletion();
|
229 |
|
230 |
// Check for tag changes.
|
@@ -233,125 +267,195 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
233 |
|
234 |
/**
|
235 |
* Retrieve Old data.
|
236 |
-
*
|
|
|
237 |
*/
|
238 |
-
protected function RetrieveOldData()
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
}
|
252 |
}
|
253 |
|
254 |
/**
|
255 |
* Get the template path.
|
256 |
-
*
|
257 |
-
* @
|
|
|
258 |
*/
|
259 |
-
protected function GetPostTemplate($post)
|
260 |
-
{
|
261 |
$id = $post->ID;
|
262 |
-
$template = get_page_template_slug($id);
|
263 |
$pagename = $post->post_name;
|
264 |
|
265 |
$templates = array();
|
266 |
-
if ($template && 0 === validate_file($template)) {
|
267 |
$templates[] = $template;
|
268 |
}
|
269 |
-
if ($pagename) {
|
270 |
$templates[] = "page-$pagename.php";
|
271 |
}
|
272 |
-
if ($id) {
|
273 |
$templates[] = "page-$id.php";
|
274 |
}
|
275 |
$templates[] = 'page.php';
|
276 |
|
277 |
-
return get_query_template('page', $templates);
|
278 |
}
|
279 |
|
280 |
/**
|
281 |
* Get post categories (array of category names).
|
282 |
-
*
|
283 |
-
* @
|
|
|
284 |
*/
|
285 |
-
protected function GetPostCategories($post)
|
286 |
-
|
287 |
-
|
|
|
|
|
|
|
288 |
}
|
289 |
|
290 |
/**
|
291 |
* Get post tags (array of tag names).
|
292 |
*
|
293 |
* @param stdClass $post - The post.
|
294 |
-
* @return array
|
295 |
*/
|
296 |
protected function get_post_tags( $post ) {
|
297 |
-
return wp_get_post_tags(
|
|
|
|
|
|
|
|
|
298 |
}
|
299 |
|
300 |
/**
|
301 |
* Check all the post changes.
|
302 |
-
*
|
303 |
-
* @param string
|
304 |
-
* @param
|
|
|
305 |
*/
|
306 |
-
public function EventPostChanged($
|
307 |
-
|
308 |
-
|
309 |
-
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
310 |
return;
|
311 |
}
|
312 |
-
if (empty($post->post_type)) {
|
313 |
return;
|
314 |
}
|
315 |
-
if ($post->post_type
|
316 |
return;
|
317 |
}
|
318 |
|
319 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
329 |
return;
|
330 |
}
|
331 |
-
if (
|
332 |
-
// Handle create post events
|
333 |
-
$this->CheckPostCreation($this->
|
334 |
} else {
|
335 |
-
// Handle update post events
|
336 |
$changes = 0
|
337 |
-
+ $this->CheckAuthorChange($this->
|
338 |
-
+ $this->CheckStatusChange($this->
|
339 |
-
+ $this->CheckParentChange($this->
|
340 |
-
+ $this->CheckStickyChange($this->
|
341 |
-
+ $this->CheckVisibilityChange($this->
|
342 |
-
+ $this->CheckTemplateChange($this->
|
343 |
-
+ $this->CheckCategoriesChange($this->
|
344 |
-
|
345 |
-
|
346 |
-
if (
|
347 |
-
$changes = $this->CheckDateChange($this->
|
348 |
-
if (
|
349 |
-
$changes = $this->CheckPermalinkChange($this->
|
350 |
-
// Comments/Trackbacks and Pingbacks
|
351 |
-
if (
|
352 |
-
$changes = $this->CheckCommentsPings($this->
|
353 |
-
if (
|
354 |
-
$changes = $this->CheckModificationChange($post->ID, $this->
|
355 |
}
|
356 |
}
|
357 |
}
|
@@ -362,49 +466,71 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
362 |
|
363 |
/**
|
364 |
* Check post creation.
|
|
|
365 |
* @global array $_POST
|
366 |
-
* @param stdClass $
|
367 |
-
* @param stdClass $
|
368 |
*/
|
369 |
-
protected function CheckPostCreation($
|
370 |
-
|
371 |
-
$
|
372 |
-
|
373 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
$event = 0;
|
375 |
$is_scheduled = false;
|
376 |
-
switch ($
|
377 |
case 'publish':
|
378 |
-
$event = $this->GetEventTypeForPostType($
|
379 |
break;
|
380 |
case 'draft':
|
381 |
-
$event = $this->GetEventTypeForPostType($
|
382 |
break;
|
383 |
case 'future':
|
384 |
-
$event = $this->GetEventTypeForPostType($
|
385 |
$is_scheduled = true;
|
386 |
break;
|
387 |
case 'pending':
|
388 |
$event = 2073;
|
389 |
break;
|
390 |
}
|
391 |
-
if ($event) {
|
392 |
-
$
|
393 |
-
if ($is_scheduled) {
|
394 |
-
$this->plugin->alerts->Trigger(
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
|
|
|
|
|
|
|
|
|
|
400 |
} else {
|
401 |
-
$this->plugin->alerts->Trigger(
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
|
|
|
|
|
|
|
|
408 |
}
|
409 |
}
|
410 |
}
|
@@ -413,121 +539,155 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
413 |
|
414 |
/**
|
415 |
* Post future publishing.
|
416 |
-
*
|
|
|
417 |
*/
|
418 |
-
public function EventPublishFuture($post_id)
|
419 |
-
|
420 |
-
$
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
$
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
|
|
|
|
|
|
432 |
}
|
433 |
}
|
434 |
|
435 |
/**
|
436 |
* Post permanently deleted.
|
437 |
-
*
|
|
|
438 |
*/
|
439 |
-
public function EventPostDeleted($post_id)
|
440 |
-
|
441 |
-
$
|
442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
return;
|
444 |
}
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
if ($
|
451 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
}
|
453 |
-
$editorLink = $this->GetEditorLink($post);
|
454 |
-
$this->plugin->alerts->Trigger($event, array(
|
455 |
-
'PostID' => $post->ID,
|
456 |
-
'PostType' => $post->post_type,
|
457 |
-
'PostTitle' => $post->post_title,
|
458 |
-
));
|
459 |
}
|
460 |
}
|
461 |
}
|
462 |
|
463 |
/**
|
464 |
* Post moved to the trash.
|
465 |
-
*
|
|
|
466 |
*/
|
467 |
-
public function EventPostTrashed($post_id)
|
468 |
-
|
469 |
-
|
470 |
-
if ($this->CheckOtherSensors($post)) {
|
471 |
return;
|
472 |
}
|
473 |
-
$event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
|
474 |
-
$
|
475 |
-
$this->plugin->alerts->Trigger(
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
|
|
|
|
|
|
|
|
482 |
}
|
483 |
|
484 |
/**
|
485 |
* Post restored from trash.
|
486 |
-
*
|
|
|
487 |
*/
|
488 |
-
public function EventPostUntrashed($post_id)
|
489 |
-
|
490 |
-
|
491 |
-
if ($this->CheckOtherSensors($post)) {
|
492 |
return;
|
493 |
}
|
494 |
-
$event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
|
495 |
-
$
|
496 |
-
$this->plugin->alerts->Trigger(
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
|
|
|
|
|
|
|
|
502 |
}
|
503 |
|
504 |
/**
|
505 |
* Post date changed.
|
506 |
-
*
|
507 |
-
* @param stdClass $
|
|
|
508 |
*/
|
509 |
-
protected function CheckDateChange($oldpost, $newpost)
|
510 |
-
|
511 |
-
$
|
512 |
-
|
513 |
-
if ($oldpost->post_status == 'draft') {
|
514 |
return 0;
|
515 |
}
|
516 |
-
$pending = $this->CheckReviewPendingChange($oldpost, $newpost);
|
517 |
-
if ($pending) {
|
518 |
return 0;
|
519 |
}
|
520 |
-
if ($from != $to) {
|
521 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
|
522 |
-
$
|
523 |
-
$this->plugin->alerts->Trigger(
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
|
|
|
|
|
|
|
|
531 |
return 1;
|
532 |
}
|
533 |
return 0;
|
@@ -535,19 +695,23 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
535 |
|
536 |
/**
|
537 |
* Revision used.
|
538 |
-
*
|
539 |
-
* @param stdClass $
|
|
|
540 |
*/
|
541 |
-
protected function CheckReviewPendingChange($oldpost, $newpost)
|
542 |
-
|
543 |
-
|
544 |
-
$
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
|
|
|
|
|
|
551 |
return 1;
|
552 |
}
|
553 |
return 0;
|
@@ -555,26 +719,30 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
555 |
|
556 |
/**
|
557 |
* Categories changed.
|
558 |
-
*
|
559 |
-
* @param array
|
560 |
-
* @param
|
|
|
561 |
*/
|
562 |
-
protected function CheckCategoriesChange($
|
563 |
-
|
564 |
-
$
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
$
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
|
|
|
|
|
|
578 |
return 1;
|
579 |
}
|
580 |
}
|
@@ -607,14 +775,18 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
607 |
$add_event = $this->GetEventTypeForPostType( $post, 2119, 0, 0 );
|
608 |
if ( $add_event ) {
|
609 |
$editor_link = $this->GetEditorLink( $post );
|
610 |
-
$post_status = ( 'publish' === $post->post_status ) ? 'published' : $
|
611 |
-
$this->plugin->alerts->Trigger(
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
|
|
|
|
|
|
|
|
618 |
}
|
619 |
}
|
620 |
|
@@ -622,14 +794,18 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
622 |
$remove_event = $this->GetEventTypeForPostType( $post, 2120, 0, 0 );
|
623 |
if ( $remove_event ) {
|
624 |
$editor_link = $this->GetEditorLink( $post );
|
625 |
-
$post_status = ( 'publish' === $post->post_status ) ? 'published' : $
|
626 |
-
$this->plugin->alerts->Trigger(
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
|
|
|
|
|
|
|
|
633 |
}
|
634 |
}
|
635 |
|
@@ -640,60 +816,85 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
640 |
|
641 |
/**
|
642 |
* Author changed.
|
643 |
-
*
|
644 |
-
* @param stdClass $
|
|
|
645 |
*/
|
646 |
-
protected function CheckAuthorChange($oldpost, $newpost)
|
647 |
-
|
648 |
-
|
649 |
-
$
|
650 |
-
$
|
651 |
-
$
|
652 |
-
$
|
653 |
-
$
|
654 |
-
$
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
|
|
|
|
|
|
663 |
return 1;
|
664 |
}
|
665 |
}
|
666 |
|
667 |
/**
|
668 |
* Status changed.
|
669 |
-
*
|
670 |
-
* @param stdClass $
|
|
|
671 |
*/
|
672 |
-
protected function CheckStatusChange($oldpost, $newpost)
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
686 |
} else {
|
687 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2021, 2022, 2039);
|
688 |
-
$
|
689 |
-
$this->plugin->alerts->Trigger(
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
|
|
|
|
|
|
|
|
697 |
}
|
698 |
return 1;
|
699 |
}
|
@@ -701,25 +902,29 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
701 |
|
702 |
/**
|
703 |
* Post parent changed.
|
704 |
-
*
|
705 |
-
* @param stdClass $
|
|
|
706 |
*/
|
707 |
-
protected function CheckParentChange($oldpost, $newpost)
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
$
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
|
|
|
|
|
|
723 |
return 1;
|
724 |
}
|
725 |
}
|
@@ -727,23 +932,27 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
727 |
|
728 |
/**
|
729 |
* Permalink changed.
|
730 |
-
*
|
731 |
-
* @param string
|
732 |
-
* @param
|
|
|
733 |
*/
|
734 |
-
protected function CheckPermalinkChange($
|
735 |
-
|
736 |
-
|
737 |
-
$
|
738 |
-
$
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
|
|
|
|
|
|
747 |
return 1;
|
748 |
}
|
749 |
return 0;
|
@@ -751,73 +960,81 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
751 |
|
752 |
/**
|
753 |
* Post visibility changed.
|
754 |
-
*
|
755 |
-
* @param stdClass $
|
756 |
-
* @param
|
757 |
-
* @param string
|
|
|
758 |
*/
|
759 |
-
protected function CheckVisibilityChange($oldpost, $newpost, $
|
760 |
-
|
761 |
-
if ($oldStatus == 'draft' || $newStatus == 'draft') {
|
762 |
return;
|
763 |
}
|
764 |
|
765 |
-
$
|
766 |
-
$
|
767 |
-
|
768 |
-
if ($oldpost->post_password) {
|
769 |
-
$
|
770 |
-
} elseif (
|
771 |
-
$
|
772 |
-
} elseif (
|
773 |
-
$
|
774 |
-
}
|
775 |
-
|
776 |
-
if ($newpost->post_password) {
|
777 |
-
$
|
778 |
-
} elseif (
|
779 |
-
$
|
780 |
-
} elseif (
|
781 |
-
$
|
782 |
-
}
|
783 |
-
|
784 |
-
if ($
|
785 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2025, 2026, 2040);
|
786 |
-
$
|
787 |
-
$this->plugin->alerts->Trigger(
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
|
|
|
|
|
|
|
|
795 |
return 1;
|
796 |
}
|
797 |
}
|
798 |
|
799 |
/**
|
800 |
* Post template changed.
|
801 |
-
*
|
802 |
-
* @param string
|
803 |
-
* @param
|
|
|
804 |
*/
|
805 |
-
protected function CheckTemplateChange($
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
$
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
|
|
|
|
|
|
821 |
return 1;
|
822 |
}
|
823 |
}
|
@@ -825,69 +1042,77 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
825 |
|
826 |
/**
|
827 |
* Post sets as sticky changes.
|
828 |
-
*
|
829 |
-
* @param string
|
830 |
-
* @param
|
|
|
831 |
*/
|
832 |
-
protected function CheckStickyChange($
|
833 |
-
|
834 |
-
|
835 |
-
$
|
836 |
-
$
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
|
|
|
|
|
|
844 |
return 1;
|
845 |
}
|
846 |
}
|
847 |
|
848 |
/**
|
849 |
* Post modified content.
|
850 |
-
*
|
851 |
-
* @param
|
852 |
-
* @param stdClass $
|
|
|
853 |
*/
|
854 |
-
public function CheckModificationChange($
|
855 |
-
|
856 |
-
if ($this->CheckOtherSensors($oldpost)) {
|
857 |
return;
|
858 |
}
|
859 |
-
$changes = $this->CheckTitleChange($oldpost, $newpost);
|
860 |
-
if (
|
861 |
-
$
|
862 |
|
863 |
-
if ($oldpost->post_modified != $newpost->post_modified) {
|
864 |
$event = 0;
|
865 |
// @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
|
866 |
-
switch ($oldpost->post_status) { // TODO or should this be $newpost?
|
867 |
case 'draft':
|
868 |
-
if ($
|
869 |
-
$event = $this->GetEventTypeForPostType($newpost, 2068, 2069, 2070);
|
870 |
} else {
|
871 |
-
$event = $this->GetEventTypeForPostType($newpost, 2003, 2007, 2032);
|
872 |
}
|
873 |
break;
|
874 |
case 'publish':
|
875 |
-
if ($
|
876 |
-
$event = $this->GetEventTypeForPostType($newpost, 2065, 2066, 2067);
|
877 |
} else {
|
878 |
-
$event = $this->GetEventTypeForPostType($newpost, 2002, 2006, 2031);
|
879 |
}
|
880 |
break;
|
881 |
}
|
882 |
-
if ($event) {
|
883 |
-
$
|
884 |
-
$this->plugin->alerts->Trigger(
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
|
|
|
|
|
|
|
|
891 |
return 1;
|
892 |
}
|
893 |
}
|
@@ -896,17 +1121,19 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
896 |
|
897 |
/**
|
898 |
* New category created.
|
899 |
-
*
|
|
|
900 |
*/
|
901 |
-
public function EventCategoryCreation($category_id)
|
902 |
-
|
903 |
-
$
|
904 |
-
$
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
|
|
910 |
}
|
911 |
|
912 |
/**
|
@@ -917,49 +1144,75 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
917 |
public function EventTagCreation( $tag_id ) {
|
918 |
$tag = get_tag( $tag_id );
|
919 |
$tag_link = $this->get_tag_link( $tag_id );
|
920 |
-
$this->plugin->alerts->Trigger(
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
|
|
|
|
925 |
}
|
926 |
|
927 |
/**
|
928 |
* Category deleted.
|
929 |
-
*
|
|
|
930 |
*/
|
931 |
-
protected function CheckCategoryDeletion()
|
932 |
-
|
933 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
934 |
return;
|
935 |
}
|
936 |
-
$action = !empty($
|
937 |
-
: (!empty($
|
938 |
-
if (
|
939 |
return;
|
940 |
}
|
941 |
|
942 |
-
$
|
943 |
|
944 |
-
if (isset($
|
945 |
-
if (
|
946 |
-
|
947 |
-
|
948 |
-
|
|
|
|
|
|
|
949 |
}
|
950 |
-
} elseif (
|
951 |
-
|
952 |
-
|
|
|
|
|
|
|
953 |
}
|
954 |
}
|
955 |
|
956 |
-
foreach ($
|
957 |
-
$category = get_category($
|
958 |
-
$this->plugin->alerts->Trigger(
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
|
|
|
|
963 |
}
|
964 |
}
|
965 |
|
@@ -969,9 +1222,21 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
969 |
* @global array $_POST - Post data
|
970 |
*/
|
971 |
protected function check_tag_deletion() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
972 |
|
973 |
-
// Filter
|
974 |
-
$post_array = filter_input_array( INPUT_POST );
|
975 |
|
976 |
// If post array is empty then return.
|
977 |
if ( empty( $post_array ) ) {
|
@@ -1007,59 +1272,80 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1007 |
|
1008 |
foreach ( $tag_ids as $tag_id ) {
|
1009 |
$tag = get_tag( $tag_id );
|
1010 |
-
$this->plugin->alerts->Trigger(
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
|
|
|
|
1015 |
}
|
1016 |
}
|
1017 |
|
1018 |
/**
|
1019 |
* Changed the parent of the category.
|
1020 |
-
*
|
|
|
1021 |
*/
|
1022 |
-
public function EventChangedCategoryParent()
|
1023 |
-
|
1024 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1025 |
return;
|
1026 |
}
|
1027 |
-
if (!current_user_can(
|
1028 |
return;
|
1029 |
}
|
1030 |
-
if (isset($
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
|
|
|
|
|
|
1036 |
} else {
|
1037 |
-
$
|
1038 |
}
|
1039 |
-
if (isset($
|
1040 |
-
$
|
1041 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1042 |
}
|
1043 |
-
$this->plugin->alerts->Trigger(2052, array(
|
1044 |
-
'CategoryName' => $category->name,
|
1045 |
-
'OldParent' => $oldParentName,
|
1046 |
-
'NewParent' => $newParentName,
|
1047 |
-
'CategoryLink' => $category_link
|
1048 |
-
));
|
1049 |
}
|
1050 |
}
|
1051 |
|
1052 |
/**
|
1053 |
* Check auto draft and the setting: Hide Plugin in Plugins Page
|
1054 |
-
*
|
1055 |
-
* @param
|
|
|
1056 |
* @return boolean
|
1057 |
*/
|
1058 |
-
private function CheckAutoDraft($code, $title)
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
if ($this->plugin->settings->IsWPBackend() == 1) {
|
1063 |
return true;
|
1064 |
} else {
|
1065 |
return false;
|
@@ -1071,13 +1357,13 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1071 |
|
1072 |
/**
|
1073 |
* Builds revision link.
|
1074 |
-
*
|
1075 |
-
* @
|
|
|
1076 |
*/
|
1077 |
-
private function getRevisionLink($revision_id)
|
1078 |
-
|
1079 |
-
|
1080 |
-
return admin_url('revision.php?revision='.$revision_id);
|
1081 |
} else {
|
1082 |
return null;
|
1083 |
}
|
@@ -1085,13 +1371,13 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1085 |
|
1086 |
/**
|
1087 |
* Builds category link.
|
1088 |
-
*
|
1089 |
-
* @
|
|
|
1090 |
*/
|
1091 |
-
private function getCategoryLink($category_id)
|
1092 |
-
|
1093 |
-
|
1094 |
-
return admin_url('term.php?taxnomy=category&tag_ID='.$category_id);
|
1095 |
} else {
|
1096 |
return null;
|
1097 |
}
|
@@ -1101,7 +1387,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1101 |
* Builds tag link.
|
1102 |
*
|
1103 |
* @param integer $tag_id - Tag ID.
|
1104 |
-
* @return string|null
|
1105 |
*/
|
1106 |
private function get_tag_link( $tag_id ) {
|
1107 |
if ( ! empty( $tag_id ) ) {
|
@@ -1115,7 +1401,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1115 |
* Ignore post from BBPress, WooCommerce Plugin
|
1116 |
* Triggered on the Sensors
|
1117 |
*
|
1118 |
-
* @param stdClass $post
|
1119 |
*/
|
1120 |
private function CheckOtherSensors( $post ) {
|
1121 |
if ( empty( $post ) || ! isset( $post->post_type ) ) {
|
@@ -1134,22 +1420,23 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1134 |
|
1135 |
/**
|
1136 |
* Triggered after save post for add revision link.
|
1137 |
-
*
|
1138 |
-
* @param
|
|
|
|
|
1139 |
*/
|
1140 |
-
public function SetRevisionLink($post_id, $post, $update)
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
$
|
1147 |
-
$occ =
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
$occ->SetMetaValue('RevisionLink', $revisionLink);
|
1153 |
}
|
1154 |
}
|
1155 |
}
|
@@ -1167,19 +1454,27 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1167 |
return $post->post_title;
|
1168 |
}
|
1169 |
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
|
|
|
|
|
|
1173 |
// Ignore this if we were on the same page so we avoid double audit entries.
|
1174 |
return;
|
1175 |
}
|
1176 |
if ( ! empty( $post->post_title ) ) {
|
1177 |
$event = $this->GetEventTypeForPostType( $post, 2101, 2103, 2105 );
|
1178 |
-
$this->plugin->alerts->Trigger(
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
|
|
|
|
|
|
|
|
|
|
1183 |
}
|
1184 |
}
|
1185 |
}
|
@@ -1187,30 +1482,39 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1187 |
|
1188 |
/**
|
1189 |
* Alerts for Editing of Posts, Pages and Custom Posts.
|
1190 |
-
*
|
|
|
1191 |
*/
|
1192 |
-
public function EditingPost($post)
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
if ($this->CheckOtherSensors($post)) {
|
1197 |
return $post;
|
1198 |
}
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
|
|
|
|
|
|
|
|
1203 |
return $post;
|
1204 |
}
|
1205 |
-
if (!empty($post->post_title)) {
|
1206 |
-
$event = $this->GetEventTypeForPostType($post, 2100, 2102, 2104);
|
1207 |
-
if (
|
1208 |
-
$
|
1209 |
-
$this->plugin->alerts->Trigger(
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
|
|
|
|
|
|
|
|
|
|
1214 |
}
|
1215 |
}
|
1216 |
}
|
@@ -1220,17 +1524,17 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1220 |
|
1221 |
/**
|
1222 |
* Check if the alert was triggered.
|
1223 |
-
*
|
|
|
1224 |
* @return boolean
|
1225 |
*/
|
1226 |
-
private function WasTriggered($alert_id)
|
1227 |
-
{
|
1228 |
$query = new WSAL_Models_OccurrenceQuery();
|
1229 |
-
$query->addOrderBy(
|
1230 |
-
$query->setLimit(1);
|
1231 |
-
$
|
1232 |
-
if (!empty($
|
1233 |
-
if ($
|
1234 |
return true;
|
1235 |
}
|
1236 |
}
|
@@ -1239,19 +1543,26 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1239 |
|
1240 |
/**
|
1241 |
* Changed title of a post.
|
1242 |
-
*
|
1243 |
-
* @param stdClass $
|
|
|
1244 |
*/
|
1245 |
-
private function CheckTitleChange($oldpost, $newpost)
|
1246 |
-
|
1247 |
-
|
1248 |
-
$
|
1249 |
-
$
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1255 |
return 1;
|
1256 |
}
|
1257 |
return 0;
|
@@ -1259,44 +1570,56 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1259 |
|
1260 |
/**
|
1261 |
* Comments/Trackbacks and Pingbacks check.
|
1262 |
-
*
|
1263 |
-
* @param stdClass $
|
|
|
1264 |
*/
|
1265 |
-
private function CheckCommentsPings($oldpost, $newpost)
|
1266 |
-
{
|
1267 |
$result = 0;
|
1268 |
-
// Comments
|
1269 |
-
if ($oldpost->comment_status != $newpost->comment_status) {
|
1270 |
$type = 'Comments';
|
1271 |
|
1272 |
-
if ($newpost->comment_status
|
1273 |
-
$event = $this->GetCommentsPingsEvent($newpost, 'enable');
|
1274 |
} else {
|
1275 |
-
$event = $this->GetCommentsPingsEvent($newpost, 'disable');
|
1276 |
}
|
1277 |
|
1278 |
-
$this->plugin->alerts->Trigger(
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1283 |
$result = 1;
|
1284 |
}
|
1285 |
-
// Trackbacks and Pingbacks
|
1286 |
-
if ($oldpost->ping_status != $newpost->ping_status) {
|
1287 |
$type = 'Trackbacks and Pingbacks';
|
1288 |
|
1289 |
-
if ($newpost->ping_status
|
1290 |
-
$event = $this->GetCommentsPingsEvent($newpost, 'enable');
|
1291 |
} else {
|
1292 |
-
$event = $this->GetCommentsPingsEvent($newpost, 'disable');
|
1293 |
}
|
1294 |
|
1295 |
-
$this->plugin->alerts->Trigger(
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1300 |
$result = 1;
|
1301 |
}
|
1302 |
return $result;
|
@@ -1304,34 +1627,34 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1304 |
|
1305 |
/**
|
1306 |
* Comments/Trackbacks and Pingbacks event code.
|
1307 |
-
*
|
1308 |
-
* @param
|
|
|
1309 |
*/
|
1310 |
-
private function GetCommentsPingsEvent($post, $status)
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
if ($status == 'disable') {
|
1315 |
$event = 2111;
|
1316 |
} else {
|
1317 |
$event = 2112;
|
1318 |
}
|
1319 |
} else {
|
1320 |
-
if (
|
1321 |
$event = 2113;
|
1322 |
} else {
|
1323 |
$event = 2114;
|
1324 |
}
|
1325 |
}
|
1326 |
} else {
|
1327 |
-
if ($post->post_status
|
1328 |
-
if (
|
1329 |
$event = 2115;
|
1330 |
} else {
|
1331 |
$event = 2116;
|
1332 |
}
|
1333 |
} else {
|
1334 |
-
if (
|
1335 |
$event = 2117;
|
1336 |
} else {
|
1337 |
$event = 2118;
|
@@ -1343,18 +1666,18 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
|
1343 |
|
1344 |
/**
|
1345 |
* Get editor link.
|
1346 |
-
*
|
1347 |
-
* @
|
|
|
1348 |
*/
|
1349 |
-
private function GetEditorLink($post)
|
1350 |
-
{
|
1351 |
$name = 'EditorLink';
|
1352 |
-
$name .= ($post->post_type
|
1353 |
-
$value = get_edit_post_link($post->ID);
|
1354 |
-
$
|
1355 |
'name' => $name,
|
1356 |
'value' => $value,
|
1357 |
);
|
1358 |
-
return $
|
1359 |
}
|
1360 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Content
|
4 |
+
*
|
5 |
+
* Content sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* WordPress contents (posts, pages and custom posts).
|
18 |
*
|
19 |
* 2000 User created a new blog post and saved it as draft
|
20 |
* 2001 User published a blog post
|
96 |
* 2123 User renamed tag
|
97 |
* 2124 User changed tag slug
|
98 |
* 2125 User changed tag description
|
99 |
+
*
|
100 |
+
* @package Wsal
|
101 |
+
* @subpackage Sensors
|
102 |
*/
|
103 |
class WSAL_Sensors_Content extends WSAL_AbstractSensor {
|
104 |
+
|
105 |
/**
|
106 |
+
* Old post.
|
107 |
+
*
|
108 |
+
* @var stdClass
|
109 |
*/
|
110 |
+
protected $_old_post = null;
|
111 |
|
112 |
/**
|
113 |
+
* Old permalink.
|
114 |
+
*
|
115 |
+
* @var string
|
116 |
*/
|
117 |
+
protected $_old_link = null;
|
118 |
|
119 |
/**
|
120 |
+
* Old categories.
|
121 |
+
*
|
122 |
+
* @var array
|
123 |
*/
|
124 |
+
protected $_old_cats = null;
|
125 |
|
126 |
/**
|
127 |
* Old tags.
|
131 |
protected $_old_tags = null;
|
132 |
|
133 |
/**
|
134 |
+
* Old path to file.
|
135 |
+
*
|
136 |
+
* @var string
|
137 |
*/
|
138 |
+
protected $_old_tmpl = null;
|
139 |
|
140 |
/**
|
141 |
+
* Old post is marked as sticky.
|
142 |
+
*
|
143 |
+
* @var boolean
|
144 |
*/
|
145 |
+
protected $_old_stky = null;
|
146 |
|
147 |
/**
|
148 |
* Listening to events using WP hooks.
|
149 |
*/
|
150 |
+
public function HookEvents() {
|
151 |
+
if ( current_user_can( 'edit_posts' ) ) {
|
152 |
+
add_action( 'admin_init', array( $this, 'EventWordPressInit' ) );
|
153 |
+
}
|
154 |
+
add_action( 'transition_post_status', array( $this, 'EventPostChanged' ), 10, 3 );
|
155 |
+
add_action( 'delete_post', array( $this, 'EventPostDeleted' ), 10, 1 );
|
156 |
+
add_action( 'wp_trash_post', array( $this, 'EventPostTrashed' ), 10, 1 );
|
157 |
+
add_action( 'untrash_post', array( $this, 'EventPostUntrashed' ) );
|
158 |
+
add_action( 'edit_category', array( $this, 'EventChangedCategoryParent' ) );
|
159 |
+
add_action( 'save_post', array( $this, 'SetRevisionLink' ), 10, 3 );
|
160 |
+
add_action( 'publish_future_post', array( $this, 'EventPublishFuture' ), 10, 1 );
|
161 |
+
|
162 |
+
add_action( 'create_category', array( $this, 'EventCategoryCreation' ), 10, 1 );
|
|
|
163 |
add_action( 'create_post_tag', array( $this, 'EventTagCreation' ), 10, 1 );
|
164 |
|
165 |
add_action( 'wp_head', array( $this, 'ViewingPost' ), 10 );
|
166 |
+
add_filter( 'post_edit_form_tag', array( $this, 'EditingPost' ), 10, 1 );
|
167 |
|
168 |
add_filter( 'wp_update_term_data', array( $this, 'event_terms_rename' ), 10, 4 );
|
169 |
}
|
178 |
* @since 2.6.9
|
179 |
*/
|
180 |
public function event_terms_rename( $data, $term_id, $taxonomy, $args ) {
|
|
|
181 |
// Check if the taxonomy is term.
|
182 |
if ( 'post_tag' !== $taxonomy ) {
|
183 |
return $data;
|
193 |
$old_name = $term->name;
|
194 |
$old_slug = $term->slug;
|
195 |
$old_desc = $term->description;
|
196 |
+
$term_link = $this->get_tag_link( $term_id );
|
197 |
|
198 |
// Update if both names are not same.
|
199 |
if ( $old_name !== $new_name ) {
|
200 |
+
$this->plugin->alerts->Trigger(
|
201 |
+
2123, array(
|
202 |
+
'old_name' => $old_name,
|
203 |
+
'new_name' => $new_name,
|
204 |
+
'TagLink' => $term_link,
|
205 |
+
)
|
206 |
+
);
|
207 |
}
|
208 |
|
209 |
// Update if both slugs are not same.
|
210 |
if ( $old_slug !== $new_slug ) {
|
211 |
+
$this->plugin->alerts->Trigger(
|
212 |
+
2124, array(
|
213 |
+
'tag' => $new_name,
|
214 |
+
'old_slug' => $old_slug,
|
215 |
+
'new_slug' => $new_slug,
|
216 |
+
'TagLink' => $term_link,
|
217 |
+
)
|
218 |
+
);
|
219 |
}
|
220 |
|
221 |
// Update if both descriptions are not same.
|
222 |
if ( $old_desc !== $new_desc ) {
|
223 |
+
$this->plugin->alerts->Trigger(
|
224 |
+
2125, array(
|
225 |
+
'tag' => $new_name,
|
226 |
+
'TagLink' => $term_link,
|
227 |
+
)
|
228 |
+
);
|
229 |
}
|
230 |
return $data;
|
231 |
|
233 |
|
234 |
/**
|
235 |
* Gets the alert code based on the type of post.
|
236 |
+
*
|
237 |
+
* @param stdClass $post - The post.
|
238 |
+
* @param integer $type_post - Alert code type post.
|
239 |
+
* @param integer $type_page - Alert code type page.
|
240 |
+
* @param integer $type_custom - Alert code type custom.
|
241 |
+
* @return integer - Alert code.
|
242 |
*/
|
243 |
+
protected function GetEventTypeForPostType( $post, $type_post, $type_page, $type_custom ) {
|
244 |
+
switch ( $post->post_type ) {
|
|
|
245 |
case 'page':
|
246 |
+
return $type_page;
|
247 |
case 'post':
|
248 |
+
return $type_post;
|
249 |
default:
|
250 |
+
return $type_custom;
|
251 |
}
|
252 |
}
|
253 |
|
254 |
/**
|
255 |
* Triggered when a user accesses the admin area.
|
256 |
*/
|
257 |
+
public function EventWordPressInit() {
|
258 |
+
// Load old data, if applicable.
|
|
|
259 |
$this->RetrieveOldData();
|
260 |
+
|
261 |
+
// Check for category changes.
|
262 |
$this->CheckCategoryDeletion();
|
263 |
|
264 |
// Check for tag changes.
|
267 |
|
268 |
/**
|
269 |
* Retrieve Old data.
|
270 |
+
*
|
271 |
+
* @global mixed $_POST - Post data.
|
272 |
*/
|
273 |
+
protected function RetrieveOldData() {
|
274 |
+
// Set filter input args.
|
275 |
+
$filter_input_args = array(
|
276 |
+
'post_ID' => FILTER_VALIDATE_INT,
|
277 |
+
'_wpnonce' => FILTER_SANITIZE_STRING,
|
278 |
+
'action' => FILTER_SANITIZE_STRING,
|
279 |
+
);
|
280 |
+
|
281 |
+
// Filter $_POST array for security.
|
282 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
283 |
+
|
284 |
+
if ( isset( $post_array['_wpnonce'] )
|
285 |
+
&& isset( $post_array['post_ID'] )
|
286 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
287 |
+
if ( isset( $post_array ) && isset( $post_array['post_ID'] )
|
288 |
+
&& ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
|
289 |
+
&& ! ( isset( $post_array['action'] ) && 'autosave' == $post_array['action'] )
|
290 |
+
) {
|
291 |
+
$post_id = intval( $post_array['post_ID'] );
|
292 |
+
$this->_old_post = get_post( $post_id );
|
293 |
+
$this->_old_link = get_permalink( $post_id );
|
294 |
+
$this->_old_tmpl = $this->GetPostTemplate( $this->_old_post );
|
295 |
+
$this->_old_cats = $this->GetPostCategories( $this->_old_post );
|
296 |
+
$this->_old_tags = $this->get_post_tags( $this->_old_post );
|
297 |
+
$this->_old_stky = in_array( $post_id, get_option( 'sticky_posts' ) );
|
298 |
+
}
|
299 |
+
} elseif ( isset( $post_array['post_ID'] ) && current_user_can( 'edit_post', $post_array['post_ID'] ) ) {
|
300 |
+
$post_id = intval( $post_array['post_ID'] );
|
301 |
+
$this->_old_post = get_post( $post_id );
|
302 |
+
$this->_old_link = get_permalink( $post_id );
|
303 |
+
$this->_old_tmpl = $this->GetPostTemplate( $this->_old_post );
|
304 |
+
$this->_old_cats = $this->GetPostCategories( $this->_old_post );
|
305 |
+
$this->_old_tags = $this->get_post_tags( $this->_old_post );
|
306 |
+
$this->_old_stky = in_array( $post_id, get_option( 'sticky_posts' ) );
|
307 |
}
|
308 |
}
|
309 |
|
310 |
/**
|
311 |
* Get the template path.
|
312 |
+
*
|
313 |
+
* @param stdClass $post - The post.
|
314 |
+
* @return string - Full path to file.
|
315 |
*/
|
316 |
+
protected function GetPostTemplate( $post ) {
|
|
|
317 |
$id = $post->ID;
|
318 |
+
$template = get_page_template_slug( $id );
|
319 |
$pagename = $post->post_name;
|
320 |
|
321 |
$templates = array();
|
322 |
+
if ( $template && 0 === validate_file( $template ) ) {
|
323 |
$templates[] = $template;
|
324 |
}
|
325 |
+
if ( $pagename ) {
|
326 |
$templates[] = "page-$pagename.php";
|
327 |
}
|
328 |
+
if ( $id ) {
|
329 |
$templates[] = "page-$id.php";
|
330 |
}
|
331 |
$templates[] = 'page.php';
|
332 |
|
333 |
+
return get_query_template( 'page', $templates );
|
334 |
}
|
335 |
|
336 |
/**
|
337 |
* Get post categories (array of category names).
|
338 |
+
*
|
339 |
+
* @param stdClass $post - The post.
|
340 |
+
* @return array - List of categories.
|
341 |
*/
|
342 |
+
protected function GetPostCategories( $post ) {
|
343 |
+
return wp_get_post_categories(
|
344 |
+
$post->ID, array(
|
345 |
+
'fields' => 'names',
|
346 |
+
)
|
347 |
+
);
|
348 |
}
|
349 |
|
350 |
/**
|
351 |
* Get post tags (array of tag names).
|
352 |
*
|
353 |
* @param stdClass $post - The post.
|
354 |
+
* @return array - List of tags.
|
355 |
*/
|
356 |
protected function get_post_tags( $post ) {
|
357 |
+
return wp_get_post_tags(
|
358 |
+
$post->ID, array(
|
359 |
+
'fields' => 'names',
|
360 |
+
)
|
361 |
+
);
|
362 |
}
|
363 |
|
364 |
/**
|
365 |
* Check all the post changes.
|
366 |
+
*
|
367 |
+
* @param string $new_status - New status.
|
368 |
+
* @param string $old_status - Old status.
|
369 |
+
* @param stdClass $post - The post.
|
370 |
*/
|
371 |
+
public function EventPostChanged( $new_status, $old_status, $post ) {
|
372 |
+
// Ignorable states.
|
373 |
+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
|
|
374 |
return;
|
375 |
}
|
376 |
+
if ( empty( $post->post_type ) ) {
|
377 |
return;
|
378 |
}
|
379 |
+
if ( 'revision' == $post->post_type ) {
|
380 |
return;
|
381 |
}
|
382 |
|
383 |
+
// Set filter input args.
|
384 |
+
$filter_input_args = array(
|
385 |
+
'post_ID' => FILTER_VALIDATE_INT,
|
386 |
+
'_wpnonce' => FILTER_SANITIZE_STRING,
|
387 |
+
'original_post_status' => FILTER_SANITIZE_STRING,
|
388 |
+
'sticky' => FILTER_SANITIZE_STRING,
|
389 |
+
'action' => FILTER_SANITIZE_STRING,
|
390 |
+
'_inline_edit' => FILTER_SANITIZE_STRING,
|
391 |
+
);
|
392 |
+
|
393 |
+
// Filter $_POST array for security.
|
394 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
395 |
+
|
396 |
+
// Verify nonce.
|
397 |
+
if ( isset( $post_array['_wpnonce'] )
|
398 |
+
&& isset( $post_array['post_ID'] )
|
399 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
400 |
+
// Edit Post Screen.
|
401 |
+
$original = isset( $post_array['original_post_status'] ) ? $post_array['original_post_status'] : '';
|
402 |
+
$this->trigger_post_change_alerts( $old_status, $new_status, $post, $original, isset( $post_array['sticky'] ) );
|
403 |
+
} elseif ( isset( $post_array['_inline_edit'] )
|
404 |
+
&& 'inline-save' === $post_array['action']
|
405 |
+
&& wp_verify_nonce( $post_array['_inline_edit'], 'inlineeditnonce' ) ) {
|
406 |
+
// Quick Post Edit.
|
407 |
+
$original = isset( $post_array['original_post_status'] ) ? $post_array['original_post_status'] : '';
|
408 |
+
$this->trigger_post_change_alerts( $old_status, $new_status, $post, $original, isset( $post_array['sticky'] ) );
|
409 |
+
}
|
410 |
+
}
|
411 |
|
412 |
+
/**
|
413 |
+
* Method: Trigger Post Change Alerts.
|
414 |
+
*
|
415 |
+
* @param string $old_status - Old status.
|
416 |
+
* @param string $new_status - New status.
|
417 |
+
* @param stdClass $post - The post.
|
418 |
+
* @param string $original - Original Post Status.
|
419 |
+
* @param string $sticky - Sticky post.
|
420 |
+
* @since 1.0.0
|
421 |
+
*/
|
422 |
+
public function trigger_post_change_alerts( $old_status, $new_status, $post, $original, $sticky ) {
|
423 |
+
WSAL_Sensors_Request::SetVars(
|
424 |
+
array(
|
425 |
+
'$new_status' => $new_status,
|
426 |
+
'$old_status' => $old_status,
|
427 |
+
'$original' => $original,
|
428 |
+
)
|
429 |
+
);
|
430 |
+
// Run checks.
|
431 |
+
if ( $this->_old_post ) {
|
432 |
+
if ( $this->CheckOtherSensors( $this->_old_post ) ) {
|
433 |
return;
|
434 |
}
|
435 |
+
if ( 'auto-draft' == $old_status || 'auto-draft' == $original ) {
|
436 |
+
// Handle create post events.
|
437 |
+
$this->CheckPostCreation( $this->_old_post, $post );
|
438 |
} else {
|
439 |
+
// Handle update post events.
|
440 |
$changes = 0
|
441 |
+
+ $this->CheckAuthorChange( $this->_old_post, $post )
|
442 |
+
+ $this->CheckStatusChange( $this->_old_post, $post )
|
443 |
+
+ $this->CheckParentChange( $this->_old_post, $post )
|
444 |
+
+ $this->CheckStickyChange( $this->_old_stky, $sticky, $post )
|
445 |
+
+ $this->CheckVisibilityChange( $this->_old_post, $post, $old_status, $new_status )
|
446 |
+
+ $this->CheckTemplateChange( $this->_old_tmpl, $this->GetPostTemplate( $post ), $post )
|
447 |
+
+ $this->CheckCategoriesChange( $this->_old_cats, $this->GetPostCategories( $post ), $post )
|
448 |
+
+ $this->check_tags_change( $this->_old_tags, $this->get_post_tags( $post ), $post );
|
449 |
+
|
450 |
+
if ( ! $changes ) {
|
451 |
+
$changes = $this->CheckDateChange( $this->_old_post, $post );
|
452 |
+
if ( ! $changes ) {
|
453 |
+
$changes = $this->CheckPermalinkChange( $this->_old_link, get_permalink( $post->ID ), $post );
|
454 |
+
// Comments/Trackbacks and Pingbacks.
|
455 |
+
if ( ! $changes ) {
|
456 |
+
$changes = $this->CheckCommentsPings( $this->_old_post, $post );
|
457 |
+
if ( ! $changes ) {
|
458 |
+
$changes = $this->CheckModificationChange( $post->ID, $this->_old_post, $post );
|
459 |
}
|
460 |
}
|
461 |
}
|
466 |
|
467 |
/**
|
468 |
* Check post creation.
|
469 |
+
*
|
470 |
* @global array $_POST
|
471 |
+
* @param stdClass $old_post - Old post.
|
472 |
+
* @param stdClass $new_post - New post.
|
473 |
*/
|
474 |
+
protected function CheckPostCreation( $old_post, $new_post ) {
|
475 |
+
// Set filter input args.
|
476 |
+
$filter_input_args = array(
|
477 |
+
'action' => FILTER_SANITIZE_STRING,
|
478 |
+
);
|
479 |
+
|
480 |
+
// Filter $_POST array for security.
|
481 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Nonce is already verified at this point.
|
485 |
+
*
|
486 |
+
* @see $this->EventPostChanged();
|
487 |
+
*/
|
488 |
+
$wp_actions = array( 'editpost', 'heartbeat' );
|
489 |
+
if ( isset( $post_array['action'] ) && in_array( $post_array['action'], $wp_actions ) ) {
|
490 |
+
if ( ! in_array( $new_post->post_type, array( 'attachment', 'revision', 'nav_menu_item' ) ) ) {
|
491 |
$event = 0;
|
492 |
$is_scheduled = false;
|
493 |
+
switch ( $new_post->post_status ) {
|
494 |
case 'publish':
|
495 |
+
$event = $this->GetEventTypeForPostType( $new_post, 2001, 2005, 2030 );
|
496 |
break;
|
497 |
case 'draft':
|
498 |
+
$event = $this->GetEventTypeForPostType( $new_post, 2000, 2004, 2029 );
|
499 |
break;
|
500 |
case 'future':
|
501 |
+
$event = $this->GetEventTypeForPostType( $new_post, 2074, 2075, 2076 );
|
502 |
$is_scheduled = true;
|
503 |
break;
|
504 |
case 'pending':
|
505 |
$event = 2073;
|
506 |
break;
|
507 |
}
|
508 |
+
if ( $event ) {
|
509 |
+
$editor_link = $this->GetEditorLink( $new_post );
|
510 |
+
if ( $is_scheduled ) {
|
511 |
+
$this->plugin->alerts->Trigger(
|
512 |
+
$event, array(
|
513 |
+
'PostID' => $new_post->ID,
|
514 |
+
'PostType' => $new_post->post_type,
|
515 |
+
'PostTitle' => $new_post->post_title,
|
516 |
+
'PostStatus' => $new_post->post_status,
|
517 |
+
'PostDate' => $new_post->post_date,
|
518 |
+
'PublishingDate' => $new_post->post_date,
|
519 |
+
$editor_link['name'] => $editor_link['value'],
|
520 |
+
)
|
521 |
+
);
|
522 |
} else {
|
523 |
+
$this->plugin->alerts->Trigger(
|
524 |
+
$event, array(
|
525 |
+
'PostID' => $new_post->ID,
|
526 |
+
'PostType' => $new_post->post_type,
|
527 |
+
'PostTitle' => $new_post->post_title,
|
528 |
+
'PostStatus' => $new_post->post_status,
|
529 |
+
'PostDate' => $new_post->post_date,
|
530 |
+
'PostUrl' => get_permalink( $new_post->ID ),
|
531 |
+
$editor_link['name'] => $editor_link['value'],
|
532 |
+
)
|
533 |
+
);
|
534 |
}
|
535 |
}
|
536 |
}
|
539 |
|
540 |
/**
|
541 |
* Post future publishing.
|
542 |
+
*
|
543 |
+
* @param integer $post_id - Post ID.
|
544 |
*/
|
545 |
+
public function EventPublishFuture( $post_id ) {
|
546 |
+
$post = get_post( $post_id );
|
547 |
+
$event = $this->GetEventTypeForPostType( $post, 2001, 2005, 2030 );
|
548 |
+
|
549 |
+
if ( $event ) {
|
550 |
+
$editor_link = $this->GetEditorLink( $post );
|
551 |
+
$this->plugin->alerts->Trigger(
|
552 |
+
$event, array(
|
553 |
+
'PostID' => $post->ID,
|
554 |
+
'PostType' => $post->post_type,
|
555 |
+
'PostTitle' => $post->post_title,
|
556 |
+
'PostStatus' => $post->post_status,
|
557 |
+
'PostDate' => $post->post_date,
|
558 |
+
'PostUrl' => get_permalink( $post->ID ),
|
559 |
+
$editor_link['name'] => $editor_link['value'],
|
560 |
+
)
|
561 |
+
);
|
562 |
}
|
563 |
}
|
564 |
|
565 |
/**
|
566 |
* Post permanently deleted.
|
567 |
+
*
|
568 |
+
* @param integer $post_id - Post ID.
|
569 |
*/
|
570 |
+
public function EventPostDeleted( $post_id ) {
|
571 |
+
// Set filter input args.
|
572 |
+
$filter_input_args = array(
|
573 |
+
'action' => FILTER_SANITIZE_STRING,
|
574 |
+
'_wpnonce' => FILTER_SANITIZE_STRING,
|
575 |
+
);
|
576 |
+
|
577 |
+
// Filter $_GET array for security.
|
578 |
+
$get_array = filter_input_array( INPUT_GET, $filter_input_args );
|
579 |
+
|
580 |
+
// Exclude CPTs from external plugins.
|
581 |
+
$post = get_post( $post_id );
|
582 |
+
if ( $this->CheckOtherSensors( $post ) ) {
|
583 |
return;
|
584 |
}
|
585 |
+
|
586 |
+
// Verify nonce.
|
587 |
+
if ( isset( $get_array['_wpnonce'] ) && wp_verify_nonce( $get_array['_wpnonce'], 'delete-post_' . $post_id ) ) {
|
588 |
+
$wp_actions = array( 'delete' );
|
589 |
+
if ( isset( $get_array['action'] ) && in_array( $get_array['action'], $wp_actions ) ) {
|
590 |
+
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item' ) ) ) { // Ignore attachments, revisions and menu items.
|
591 |
+
$event = $this->GetEventTypeForPostType( $post, 2008, 2009, 2033 );
|
592 |
+
// Check WordPress backend operations.
|
593 |
+
if ( $this->CheckAutoDraft( $event, $post->post_title ) ) {
|
594 |
+
return;
|
595 |
+
}
|
596 |
+
$editor_link = $this->GetEditorLink( $post );
|
597 |
+
$this->plugin->alerts->Trigger(
|
598 |
+
$event, array(
|
599 |
+
'PostID' => $post->ID,
|
600 |
+
'PostType' => $post->post_type,
|
601 |
+
'PostTitle' => $post->post_title,
|
602 |
+
'PostStatus' => $post->post_status,
|
603 |
+
'PostDate' => $post->post_date,
|
604 |
+
)
|
605 |
+
);
|
606 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
607 |
}
|
608 |
}
|
609 |
}
|
610 |
|
611 |
/**
|
612 |
* Post moved to the trash.
|
613 |
+
*
|
614 |
+
* @param integer $post_id - Post ID.
|
615 |
*/
|
616 |
+
public function EventPostTrashed( $post_id ) {
|
617 |
+
$post = get_post( $post_id );
|
618 |
+
if ( $this->CheckOtherSensors( $post ) ) {
|
|
|
619 |
return;
|
620 |
}
|
621 |
+
$event = $this->GetEventTypeForPostType( $post, 2012, 2013, 2034 );
|
622 |
+
$editor_link = $this->GetEditorLink( $post );
|
623 |
+
$this->plugin->alerts->Trigger(
|
624 |
+
$event, array(
|
625 |
+
'PostID' => $post->ID,
|
626 |
+
'PostType' => $post->post_type,
|
627 |
+
'PostTitle' => $post->post_title,
|
628 |
+
'PostStatus' => $post->post_status,
|
629 |
+
'PostDate' => $post->post_date,
|
630 |
+
'PostUrl' => get_permalink( $post->ID ),
|
631 |
+
$editor_link['name'] => $editor_link['value'],
|
632 |
+
)
|
633 |
+
);
|
634 |
}
|
635 |
|
636 |
/**
|
637 |
* Post restored from trash.
|
638 |
+
*
|
639 |
+
* @param integer $post_id - Post ID.
|
640 |
*/
|
641 |
+
public function EventPostUntrashed( $post_id ) {
|
642 |
+
$post = get_post( $post_id );
|
643 |
+
if ( $this->CheckOtherSensors( $post ) ) {
|
|
|
644 |
return;
|
645 |
}
|
646 |
+
$event = $this->GetEventTypeForPostType( $post, 2014, 2015, 2035 );
|
647 |
+
$editor_link = $this->GetEditorLink( $post );
|
648 |
+
$this->plugin->alerts->Trigger(
|
649 |
+
$event, array(
|
650 |
+
'PostID' => $post->ID,
|
651 |
+
'PostType' => $post->post_type,
|
652 |
+
'PostTitle' => $post->post_title,
|
653 |
+
'PostStatus' => $post->post_status,
|
654 |
+
'PostDate' => $post->post_date,
|
655 |
+
$editor_link['name'] => $editor_link['value'],
|
656 |
+
)
|
657 |
+
);
|
658 |
}
|
659 |
|
660 |
/**
|
661 |
* Post date changed.
|
662 |
+
*
|
663 |
+
* @param stdClass $oldpost - Old post.
|
664 |
+
* @param stdClass $newpost - New post.
|
665 |
*/
|
666 |
+
protected function CheckDateChange( $oldpost, $newpost ) {
|
667 |
+
$from = strtotime( $oldpost->post_date );
|
668 |
+
$to = strtotime( $newpost->post_date );
|
669 |
+
if ( 'draft' == $oldpost->post_status ) {
|
|
|
670 |
return 0;
|
671 |
}
|
672 |
+
$pending = $this->CheckReviewPendingChange( $oldpost, $newpost );
|
673 |
+
if ( $pending ) {
|
674 |
return 0;
|
675 |
}
|
676 |
+
if ( $from != $to ) {
|
677 |
+
$event = $this->GetEventTypeForPostType( $oldpost, 2027, 2028, 2041 );
|
678 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
679 |
+
$this->plugin->alerts->Trigger(
|
680 |
+
$event, array(
|
681 |
+
'PostID' => $oldpost->ID,
|
682 |
+
'PostType' => $oldpost->post_type,
|
683 |
+
'PostTitle' => $oldpost->post_title,
|
684 |
+
'PostStatus' => $oldpost->post_status,
|
685 |
+
'PostDate' => $newpost->post_date,
|
686 |
+
'OldDate' => $oldpost->post_date,
|
687 |
+
'NewDate' => $newpost->post_date,
|
688 |
+
$editor_link['name'] => $editor_link['value'],
|
689 |
+
)
|
690 |
+
);
|
691 |
return 1;
|
692 |
}
|
693 |
return 0;
|
695 |
|
696 |
/**
|
697 |
* Revision used.
|
698 |
+
*
|
699 |
+
* @param stdClass $oldpost - Old post.
|
700 |
+
* @param stdClass $newpost - New post.
|
701 |
*/
|
702 |
+
protected function CheckReviewPendingChange( $oldpost, $newpost ) {
|
703 |
+
if ( 'pending' == $oldpost->post_status ) {
|
704 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
705 |
+
$this->plugin->alerts->Trigger(
|
706 |
+
2072, array(
|
707 |
+
'PostID' => $oldpost->ID,
|
708 |
+
'PostType' => $oldpost->post_type,
|
709 |
+
'PostTitle' => $oldpost->post_title,
|
710 |
+
'PostStatus' => $oldpost->post_status,
|
711 |
+
'PostDate' => $oldpost->post_date,
|
712 |
+
$editor_link['name'] => $editor_link['value'],
|
713 |
+
)
|
714 |
+
);
|
715 |
return 1;
|
716 |
}
|
717 |
return 0;
|
719 |
|
720 |
/**
|
721 |
* Categories changed.
|
722 |
+
*
|
723 |
+
* @param array $old_cats - Old categories.
|
724 |
+
* @param array $new_cats - New categories.
|
725 |
+
* @param stdClass $post - The post.
|
726 |
*/
|
727 |
+
protected function CheckCategoriesChange( $old_cats, $new_cats, $post ) {
|
728 |
+
$old_cats = implode( ', ', $old_cats );
|
729 |
+
$new_cats = implode( ', ', $new_cats );
|
730 |
+
if ( $old_cats != $new_cats ) {
|
731 |
+
$event = $this->GetEventTypeForPostType( $post, 2016, 0, 2036 );
|
732 |
+
if ( $event ) {
|
733 |
+
$editor_link = $this->GetEditorLink( $post );
|
734 |
+
$this->plugin->alerts->Trigger(
|
735 |
+
$event, array(
|
736 |
+
'PostID' => $post->ID,
|
737 |
+
'PostType' => $post->post_type,
|
738 |
+
'PostTitle' => $post->post_title,
|
739 |
+
'PostStatus' => $post->post_status,
|
740 |
+
'PostDate' => $post->post_date,
|
741 |
+
'OldCategories' => $old_cats ? $old_cats : 'no categories',
|
742 |
+
'NewCategories' => $new_cats ? $new_cats : 'no categories',
|
743 |
+
$editor_link['name'] => $editor_link['value'],
|
744 |
+
)
|
745 |
+
);
|
746 |
return 1;
|
747 |
}
|
748 |
}
|
775 |
$add_event = $this->GetEventTypeForPostType( $post, 2119, 0, 0 );
|
776 |
if ( $add_event ) {
|
777 |
$editor_link = $this->GetEditorLink( $post );
|
778 |
+
$post_status = ( 'publish' === $post->post_status ) ? 'published' : $post->post_status;
|
779 |
+
$this->plugin->alerts->Trigger(
|
780 |
+
$add_event, array(
|
781 |
+
'PostID' => $post->ID,
|
782 |
+
'PostStatus' => $post_status,
|
783 |
+
'PostTitle' => $post->post_title,
|
784 |
+
'PostType' => $post->post_type,
|
785 |
+
'PostDate' => $post->post_date,
|
786 |
+
'tag' => $added_tags ? $added_tags : 'no tags',
|
787 |
+
$editor_link['name'] => $editor_link['value'],
|
788 |
+
)
|
789 |
+
);
|
790 |
}
|
791 |
}
|
792 |
|
794 |
$remove_event = $this->GetEventTypeForPostType( $post, 2120, 0, 0 );
|
795 |
if ( $remove_event ) {
|
796 |
$editor_link = $this->GetEditorLink( $post );
|
797 |
+
$post_status = ( 'publish' === $post->post_status ) ? 'published' : $post->post_status;
|
798 |
+
$this->plugin->alerts->Trigger(
|
799 |
+
$remove_event, array(
|
800 |
+
'PostID' => $post->ID,
|
801 |
+
'PostStatus' => $post_status,
|
802 |
+
'PostTitle' => $post->post_title,
|
803 |
+
'PostType' => $post->post_type,
|
804 |
+
'PostDate' => $post->post_date,
|
805 |
+
'tag' => $removed_tags ? $removed_tags : 'no tags',
|
806 |
+
$editor_link['name'] => $editor_link['value'],
|
807 |
+
)
|
808 |
+
);
|
809 |
}
|
810 |
}
|
811 |
|
816 |
|
817 |
/**
|
818 |
* Author changed.
|
819 |
+
*
|
820 |
+
* @param stdClass $oldpost - Old post.
|
821 |
+
* @param stdClass $newpost - New post.
|
822 |
*/
|
823 |
+
protected function CheckAuthorChange( $oldpost, $newpost ) {
|
824 |
+
if ( $oldpost->post_author != $newpost->post_author ) {
|
825 |
+
$event = $this->GetEventTypeForPostType( $oldpost, 2019, 2020, 2038 );
|
826 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
827 |
+
$old_author = get_userdata( $oldpost->post_author );
|
828 |
+
$old_author = (is_object( $old_author )) ? $old_author->user_login : 'N/A';
|
829 |
+
$new_author = get_userdata( $newpost->post_author );
|
830 |
+
$new_author = (is_object( $new_author )) ? $new_author->user_login : 'N/A';
|
831 |
+
$this->plugin->alerts->Trigger(
|
832 |
+
$event, array(
|
833 |
+
'PostID' => $oldpost->ID,
|
834 |
+
'PostType' => $oldpost->post_type,
|
835 |
+
'PostTitle' => $oldpost->post_title,
|
836 |
+
'PostStatus' => $oldpost->post_status,
|
837 |
+
'PostDate' => $oldpost->post_date,
|
838 |
+
'OldAuthor' => $old_author,
|
839 |
+
'NewAuthor' => $new_author,
|
840 |
+
$editor_link['name'] => $editor_link['value'],
|
841 |
+
)
|
842 |
+
);
|
843 |
return 1;
|
844 |
}
|
845 |
}
|
846 |
|
847 |
/**
|
848 |
* Status changed.
|
849 |
+
*
|
850 |
+
* @param stdClass $oldpost - Old post.
|
851 |
+
* @param stdClass $newpost - New post.
|
852 |
*/
|
853 |
+
protected function CheckStatusChange( $oldpost, $newpost ) {
|
854 |
+
// Set filter input args.
|
855 |
+
$filter_input_args = array(
|
856 |
+
'publish' => FILTER_SANITIZE_STRING,
|
857 |
+
);
|
858 |
+
|
859 |
+
// Filter $_POST array for security.
|
860 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
861 |
+
|
862 |
+
/**
|
863 |
+
* Nonce is already verified at this point.
|
864 |
+
*
|
865 |
+
* @see $this->EventPostChanged();
|
866 |
+
*/
|
867 |
+
if ( $oldpost->post_status != $newpost->post_status ) {
|
868 |
+
if ( isset( $post_array['publish'] ) ) {
|
869 |
+
// Special case (publishing a post).
|
870 |
+
$event = $this->GetEventTypeForPostType( $oldpost, 2001, 2005, 2030 );
|
871 |
+
$editor_link = $this->GetEditorLink( $newpost );
|
872 |
+
$this->plugin->alerts->Trigger(
|
873 |
+
$event, array(
|
874 |
+
'PostID' => $newpost->ID,
|
875 |
+
'PostType' => $newpost->post_type,
|
876 |
+
'PostTitle' => $newpost->post_title,
|
877 |
+
'PostStatus' => $newpost->post_status,
|
878 |
+
'PostDate' => $newpost->post_date,
|
879 |
+
'PostUrl' => get_permalink( $newpost->ID ),
|
880 |
+
$editor_link['name'] => $editor_link['value'],
|
881 |
+
)
|
882 |
+
);
|
883 |
} else {
|
884 |
+
$event = $this->GetEventTypeForPostType( $oldpost, 2021, 2022, 2039 );
|
885 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
886 |
+
$this->plugin->alerts->Trigger(
|
887 |
+
$event, array(
|
888 |
+
'PostID' => $oldpost->ID,
|
889 |
+
'PostType' => $oldpost->post_type,
|
890 |
+
'PostTitle' => $oldpost->post_title,
|
891 |
+
'PostStatus' => $newpost->post_status,
|
892 |
+
'PostDate' => $oldpost->post_date,
|
893 |
+
'OldStatus' => $oldpost->post_status,
|
894 |
+
'NewStatus' => $newpost->post_status,
|
895 |
+
$editor_link['name'] => $editor_link['value'],
|
896 |
+
)
|
897 |
+
);
|
898 |
}
|
899 |
return 1;
|
900 |
}
|
902 |
|
903 |
/**
|
904 |
* Post parent changed.
|
905 |
+
*
|
906 |
+
* @param stdClass $oldpost - Old post.
|
907 |
+
* @param stdClass $newpost - New post.
|
908 |
*/
|
909 |
+
protected function CheckParentChange( $oldpost, $newpost ) {
|
910 |
+
if ( $oldpost->post_parent != $newpost->post_parent ) {
|
911 |
+
$event = $this->GetEventTypeForPostType( $oldpost, 0, 2047, 0 );
|
912 |
+
if ( $event ) {
|
913 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
914 |
+
$this->plugin->alerts->Trigger(
|
915 |
+
$event, array(
|
916 |
+
'PostID' => $oldpost->ID,
|
917 |
+
'PostType' => $oldpost->post_type,
|
918 |
+
'PostTitle' => $oldpost->post_title,
|
919 |
+
'PostStatus' => $oldpost->post_status,
|
920 |
+
'PostDate' => $oldpost->post_date,
|
921 |
+
'OldParent' => $oldpost->post_parent,
|
922 |
+
'NewParent' => $newpost->post_parent,
|
923 |
+
'OldParentName' => $oldpost->post_parent ? get_the_title( $oldpost->post_parent ) : 'no parent',
|
924 |
+
'NewParentName' => $newpost->post_parent ? get_the_title( $newpost->post_parent ) : 'no parent',
|
925 |
+
$editor_link['name'] => $editor_link['value'],
|
926 |
+
)
|
927 |
+
);
|
928 |
return 1;
|
929 |
}
|
930 |
}
|
932 |
|
933 |
/**
|
934 |
* Permalink changed.
|
935 |
+
*
|
936 |
+
* @param string $old_link - Old permalink.
|
937 |
+
* @param string $new_link - New permalink.
|
938 |
+
* @param stdClass $post - The post.
|
939 |
*/
|
940 |
+
protected function CheckPermalinkChange( $old_link, $new_link, $post ) {
|
941 |
+
if ( $old_link != $new_link ) {
|
942 |
+
$event = $this->GetEventTypeForPostType( $post, 2017, 2018, 2037 );
|
943 |
+
$editor_link = $this->GetEditorLink( $post );
|
944 |
+
$this->plugin->alerts->Trigger(
|
945 |
+
$event, array(
|
946 |
+
'PostID' => $post->ID,
|
947 |
+
'PostType' => $post->post_type,
|
948 |
+
'PostTitle' => $post->post_title,
|
949 |
+
'PostStatus' => $post->post_status,
|
950 |
+
'PostDate' => $post->post_date,
|
951 |
+
'OldUrl' => $old_link,
|
952 |
+
'NewUrl' => $new_link,
|
953 |
+
$editor_link['name'] => $editor_link['value'],
|
954 |
+
)
|
955 |
+
);
|
956 |
return 1;
|
957 |
}
|
958 |
return 0;
|
960 |
|
961 |
/**
|
962 |
* Post visibility changed.
|
963 |
+
*
|
964 |
+
* @param stdClass $oldpost - Old post.
|
965 |
+
* @param stdClass $newpost - New post.
|
966 |
+
* @param string $old_status - Old status.
|
967 |
+
* @param string $new_status - New status.
|
968 |
*/
|
969 |
+
protected function CheckVisibilityChange( $oldpost, $newpost, $old_status, $new_status ) {
|
970 |
+
if ( 'draft' == $old_status || 'draft' == $new_status ) {
|
|
|
971 |
return;
|
972 |
}
|
973 |
|
974 |
+
$old_visibility = '';
|
975 |
+
$new_visibility = '';
|
976 |
+
|
977 |
+
if ( $oldpost->post_password ) {
|
978 |
+
$old_visibility = __( 'Password Protected', 'wp-security-audit-log' );
|
979 |
+
} elseif ( 'publish' == $old_status ) {
|
980 |
+
$old_visibility = __( 'Public', 'wp-security-audit-log' );
|
981 |
+
} elseif ( 'private' == $old_status ) {
|
982 |
+
$old_visibility = __( 'Private', 'wp-security-audit-log' );
|
983 |
+
}
|
984 |
+
|
985 |
+
if ( $newpost->post_password ) {
|
986 |
+
$new_visibility = __( 'Password Protected', 'wp-security-audit-log' );
|
987 |
+
} elseif ( 'publish' == $new_status ) {
|
988 |
+
$new_visibility = __( 'Public', 'wp-security-audit-log' );
|
989 |
+
} elseif ( 'private' == $new_status ) {
|
990 |
+
$new_visibility = __( 'Private', 'wp-security-audit-log' );
|
991 |
+
}
|
992 |
+
|
993 |
+
if ( $old_visibility && $new_visibility && ($old_visibility != $new_visibility) ) {
|
994 |
+
$event = $this->GetEventTypeForPostType( $oldpost, 2025, 2026, 2040 );
|
995 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
996 |
+
$this->plugin->alerts->Trigger(
|
997 |
+
$event, array(
|
998 |
+
'PostID' => $oldpost->ID,
|
999 |
+
'PostType' => $oldpost->post_type,
|
1000 |
+
'PostTitle' => $oldpost->post_title,
|
1001 |
+
'PostStatus' => $newpost->post_status,
|
1002 |
+
'PostDate' => $oldpost->post_date,
|
1003 |
+
'OldVisibility' => $old_visibility,
|
1004 |
+
'NewVisibility' => $new_visibility,
|
1005 |
+
$editor_link['name'] => $editor_link['value'],
|
1006 |
+
)
|
1007 |
+
);
|
1008 |
return 1;
|
1009 |
}
|
1010 |
}
|
1011 |
|
1012 |
/**
|
1013 |
* Post template changed.
|
1014 |
+
*
|
1015 |
+
* @param string $old_tmpl - Old template path.
|
1016 |
+
* @param string $new_tmpl - New template path.
|
1017 |
+
* @param stdClass $post - The post.
|
1018 |
*/
|
1019 |
+
protected function CheckTemplateChange( $old_tmpl, $new_tmpl, $post ) {
|
1020 |
+
if ( $old_tmpl != $new_tmpl ) {
|
1021 |
+
$event = $this->GetEventTypeForPostType( $post, 0, 2048, 0 );
|
1022 |
+
if ( $event ) {
|
1023 |
+
$editor_link = $this->GetEditorLink( $post );
|
1024 |
+
$this->plugin->alerts->Trigger(
|
1025 |
+
$event, array(
|
1026 |
+
'PostID' => $post->ID,
|
1027 |
+
'PostType' => $post->post_type,
|
1028 |
+
'PostTitle' => $post->post_title,
|
1029 |
+
'PostStatus' => $post->post_status,
|
1030 |
+
'PostDate' => $post->post_date,
|
1031 |
+
'OldTemplate' => ucwords( str_replace( array( '-', '_' ), ' ', basename( $old_tmpl, '.php' ) ) ),
|
1032 |
+
'NewTemplate' => ucwords( str_replace( array( '-', '_' ), ' ', basename( $new_tmpl, '.php' ) ) ),
|
1033 |
+
'OldTemplatePath' => $old_tmpl,
|
1034 |
+
'NewTemplatePath' => $new_tmpl,
|
1035 |
+
$editor_link['name'] => $editor_link['value'],
|
1036 |
+
)
|
1037 |
+
);
|
1038 |
return 1;
|
1039 |
}
|
1040 |
}
|
1042 |
|
1043 |
/**
|
1044 |
* Post sets as sticky changes.
|
1045 |
+
*
|
1046 |
+
* @param string $old_stky - Old template path.
|
1047 |
+
* @param string $new_stky - New template path.
|
1048 |
+
* @param stdClass $post - The post.
|
1049 |
*/
|
1050 |
+
protected function CheckStickyChange( $old_stky, $new_stky, $post ) {
|
1051 |
+
if ( $old_stky != $new_stky ) {
|
1052 |
+
$event = $new_stky ? 2049 : 2050;
|
1053 |
+
$editor_link = $this->GetEditorLink( $post );
|
1054 |
+
$this->plugin->alerts->Trigger(
|
1055 |
+
$event, array(
|
1056 |
+
'PostID' => $post->ID,
|
1057 |
+
'PostType' => $post->post_type,
|
1058 |
+
'PostTitle' => $post->post_title,
|
1059 |
+
'PostStatus' => $post->post_status,
|
1060 |
+
'PostDate' => $post->post_date,
|
1061 |
+
'PostUrl' => get_permalink( $post->ID ),
|
1062 |
+
$editor_link['name'] => $editor_link['value'],
|
1063 |
+
)
|
1064 |
+
);
|
1065 |
return 1;
|
1066 |
}
|
1067 |
}
|
1068 |
|
1069 |
/**
|
1070 |
* Post modified content.
|
1071 |
+
*
|
1072 |
+
* @param integer $post_id - Post ID.
|
1073 |
+
* @param stdClass $oldpost - Old post.
|
1074 |
+
* @param stdClass $newpost - New post.
|
1075 |
*/
|
1076 |
+
public function CheckModificationChange( $post_id, $oldpost, $newpost ) {
|
1077 |
+
if ( $this->CheckOtherSensors( $oldpost ) ) {
|
|
|
1078 |
return;
|
1079 |
}
|
1080 |
+
$changes = $this->CheckTitleChange( $oldpost, $newpost );
|
1081 |
+
if ( ! $changes ) {
|
1082 |
+
$content_changed = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
|
1083 |
|
1084 |
+
if ( $oldpost->post_modified != $newpost->post_modified ) {
|
1085 |
$event = 0;
|
1086 |
// @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
|
1087 |
+
switch ( $oldpost->post_status ) { // TODO or should this be $newpost?
|
1088 |
case 'draft':
|
1089 |
+
if ( $content_changed ) {
|
1090 |
+
$event = $this->GetEventTypeForPostType( $newpost, 2068, 2069, 2070 );
|
1091 |
} else {
|
1092 |
+
$event = $this->GetEventTypeForPostType( $newpost, 2003, 2007, 2032 );
|
1093 |
}
|
1094 |
break;
|
1095 |
case 'publish':
|
1096 |
+
if ( $content_changed ) {
|
1097 |
+
$event = $this->GetEventTypeForPostType( $newpost, 2065, 2066, 2067 );
|
1098 |
} else {
|
1099 |
+
$event = $this->GetEventTypeForPostType( $newpost, 2002, 2006, 2031 );
|
1100 |
}
|
1101 |
break;
|
1102 |
}
|
1103 |
+
if ( $event ) {
|
1104 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
1105 |
+
$this->plugin->alerts->Trigger(
|
1106 |
+
$event, array(
|
1107 |
+
'PostID' => $post_id,
|
1108 |
+
'PostType' => $oldpost->post_type,
|
1109 |
+
'PostTitle' => $oldpost->post_title,
|
1110 |
+
'PostStatus' => $oldpost->post_status,
|
1111 |
+
'PostDate' => $oldpost->post_date,
|
1112 |
+
'PostUrl' => get_permalink( $post_id ),
|
1113 |
+
$editor_link['name'] => $editor_link['value'],
|
1114 |
+
)
|
1115 |
+
);
|
1116 |
return 1;
|
1117 |
}
|
1118 |
}
|
1121 |
|
1122 |
/**
|
1123 |
* New category created.
|
1124 |
+
*
|
1125 |
+
* @param integer $category_id - Category ID.
|
1126 |
*/
|
1127 |
+
public function EventCategoryCreation( $category_id ) {
|
1128 |
+
$category = get_category( $category_id );
|
1129 |
+
$category_link = $this->getCategoryLink( $category_id );
|
1130 |
+
$this->plugin->alerts->Trigger(
|
1131 |
+
2023, array(
|
1132 |
+
'CategoryName' => $category->name,
|
1133 |
+
'Slug' => $category->slug,
|
1134 |
+
'CategoryLink' => $category_link,
|
1135 |
+
)
|
1136 |
+
);
|
1137 |
}
|
1138 |
|
1139 |
/**
|
1144 |
public function EventTagCreation( $tag_id ) {
|
1145 |
$tag = get_tag( $tag_id );
|
1146 |
$tag_link = $this->get_tag_link( $tag_id );
|
1147 |
+
$this->plugin->alerts->Trigger(
|
1148 |
+
2121, array(
|
1149 |
+
'TagName' => $tag->name,
|
1150 |
+
'Slug' => $tag->slug,
|
1151 |
+
'TagLink' => $tag_link,
|
1152 |
+
)
|
1153 |
+
);
|
1154 |
}
|
1155 |
|
1156 |
/**
|
1157 |
* Category deleted.
|
1158 |
+
*
|
1159 |
+
* @global array $_POST - Post data.
|
1160 |
*/
|
1161 |
+
protected function CheckCategoryDeletion() {
|
1162 |
+
// Set filter input args.
|
1163 |
+
$filter_input_args = array(
|
1164 |
+
'_wpnonce' => FILTER_SANITIZE_STRING,
|
1165 |
+
'action' => FILTER_SANITIZE_STRING,
|
1166 |
+
'action2' => FILTER_SANITIZE_STRING,
|
1167 |
+
'taxonomy' => FILTER_SANITIZE_STRING,
|
1168 |
+
'delete_tags' => array(
|
1169 |
+
'filter' => FILTER_SANITIZE_STRING,
|
1170 |
+
'flags' => FILTER_REQUIRE_ARRAY,
|
1171 |
+
),
|
1172 |
+
'tag_ID' => FILTER_VALIDATE_INT,
|
1173 |
+
);
|
1174 |
+
|
1175 |
+
// Filter $_POST array for security.
|
1176 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
1177 |
+
|
1178 |
+
if ( empty( $post_array ) ) {
|
1179 |
return;
|
1180 |
}
|
1181 |
+
$action = ! empty( $post_array['action'] ) ? $post_array['action']
|
1182 |
+
: ( ! empty( $post_array['action2'] ) ? $post_array['action2'] : '');
|
1183 |
+
if ( ! $action ) {
|
1184 |
return;
|
1185 |
}
|
1186 |
|
1187 |
+
$category_ids = array();
|
1188 |
|
1189 |
+
if ( isset( $post_array['taxonomy'] ) ) {
|
1190 |
+
if ( 'delete' == $action
|
1191 |
+
&& 'category' == $post_array['taxonomy']
|
1192 |
+
&& ! empty( $post_array['delete_tags'] )
|
1193 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'bulk-tags' ) ) {
|
1194 |
+
// Bulk delete.
|
1195 |
+
foreach ( $post_array['delete_tags'] as $delete_tag ) {
|
1196 |
+
$category_ids[] = $delete_tag;
|
1197 |
}
|
1198 |
+
} elseif ( 'delete-tag' == $action
|
1199 |
+
&& 'category' == $post_array['taxonomy']
|
1200 |
+
&& ! empty( $post_array['tag_ID'] )
|
1201 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'delete-tag_' . $post_array['tag_ID'] ) ) {
|
1202 |
+
// Single delete.
|
1203 |
+
$category_ids[] = $post_array['tag_ID'];
|
1204 |
}
|
1205 |
}
|
1206 |
|
1207 |
+
foreach ( $category_ids as $category_id ) {
|
1208 |
+
$category = get_category( $category_id );
|
1209 |
+
$this->plugin->alerts->Trigger(
|
1210 |
+
2024, array(
|
1211 |
+
'CategoryID' => $category_id,
|
1212 |
+
'CategoryName' => $category->cat_name,
|
1213 |
+
'Slug' => $category->slug,
|
1214 |
+
)
|
1215 |
+
);
|
1216 |
}
|
1217 |
}
|
1218 |
|
1222 |
* @global array $_POST - Post data
|
1223 |
*/
|
1224 |
protected function check_tag_deletion() {
|
1225 |
+
// Set filter input args.
|
1226 |
+
$filter_input_args = array(
|
1227 |
+
'_wpnonce' => FILTER_SANITIZE_STRING,
|
1228 |
+
'action' => FILTER_SANITIZE_STRING,
|
1229 |
+
'action2' => FILTER_SANITIZE_STRING,
|
1230 |
+
'taxonomy' => FILTER_SANITIZE_STRING,
|
1231 |
+
'delete_tags' => array(
|
1232 |
+
'filter' => FILTER_SANITIZE_STRING,
|
1233 |
+
'flags' => FILTER_REQUIRE_ARRAY,
|
1234 |
+
),
|
1235 |
+
'tag_ID' => FILTER_VALIDATE_INT,
|
1236 |
+
);
|
1237 |
|
1238 |
+
// Filter $_POST array for security.
|
1239 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
1240 |
|
1241 |
// If post array is empty then return.
|
1242 |
if ( empty( $post_array ) ) {
|
1272 |
|
1273 |
foreach ( $tag_ids as $tag_id ) {
|
1274 |
$tag = get_tag( $tag_id );
|
1275 |
+
$this->plugin->alerts->Trigger(
|
1276 |
+
2122, array(
|
1277 |
+
'TagID' => $tag_id,
|
1278 |
+
'TagName' => $tag->name,
|
1279 |
+
'Slug' => $tag->slug,
|
1280 |
+
)
|
1281 |
+
);
|
1282 |
}
|
1283 |
}
|
1284 |
|
1285 |
/**
|
1286 |
* Changed the parent of the category.
|
1287 |
+
*
|
1288 |
+
* @global array $_POST - Post data.
|
1289 |
*/
|
1290 |
+
public function EventChangedCategoryParent() {
|
1291 |
+
// Set filter input args.
|
1292 |
+
$filter_input_args = array(
|
1293 |
+
'_wpnonce' => FILTER_SANITIZE_STRING,
|
1294 |
+
'name' => FILTER_SANITIZE_STRING,
|
1295 |
+
'parent' => FILTER_SANITIZE_STRING,
|
1296 |
+
'tag_ID' => FILTER_VALIDATE_INT,
|
1297 |
+
);
|
1298 |
+
|
1299 |
+
// Filter $_POST array for security.
|
1300 |
+
$post_array = filter_input_array( INPUT_POST, $filter_input_args );
|
1301 |
+
|
1302 |
+
if ( empty( $post_array ) ) {
|
1303 |
return;
|
1304 |
}
|
1305 |
+
if ( ! current_user_can( 'manage_categories' ) ) {
|
1306 |
return;
|
1307 |
}
|
1308 |
+
if ( isset( $post_array['_wpnonce'] )
|
1309 |
+
&& isset( $post_array['name'] )
|
1310 |
+
&& isset( $post_array['tag_ID'] )
|
1311 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'update-tag_' . $post_array['tag_ID'] ) ) {
|
1312 |
+
$category = get_category( $post_array['tag_ID'] );
|
1313 |
+
$category_link = $this->getCategoryLink( $post_array['tag_ID'] );
|
1314 |
+
if ( 0 != $category->parent ) {
|
1315 |
+
$old_parent = get_category( $category->parent );
|
1316 |
+
$old_parent_name = (empty( $old_parent )) ? 'no parent' : $old_parent->name;
|
1317 |
} else {
|
1318 |
+
$old_parent_name = 'no parent';
|
1319 |
}
|
1320 |
+
if ( isset( $post_array['parent'] ) ) {
|
1321 |
+
$new_parent = get_category( $post_array['parent'] );
|
1322 |
+
$new_parent_name = (empty( $new_parent )) ? 'no parent' : $new_parent->name;
|
1323 |
+
}
|
1324 |
+
|
1325 |
+
if ( $old_parent_name !== $new_parent_name ) {
|
1326 |
+
$this->plugin->alerts->Trigger(
|
1327 |
+
2052, array(
|
1328 |
+
'CategoryName' => $category->name,
|
1329 |
+
'OldParent' => $old_parent_name,
|
1330 |
+
'NewParent' => $new_parent_name,
|
1331 |
+
'CategoryLink' => $category_link,
|
1332 |
+
)
|
1333 |
+
);
|
1334 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1335 |
}
|
1336 |
}
|
1337 |
|
1338 |
/**
|
1339 |
* Check auto draft and the setting: Hide Plugin in Plugins Page
|
1340 |
+
*
|
1341 |
+
* @param integer $code - Alert code.
|
1342 |
+
* @param string $title - Title.
|
1343 |
* @return boolean
|
1344 |
*/
|
1345 |
+
private function CheckAutoDraft( $code, $title ) {
|
1346 |
+
if ( 2008 == $code && 'auto-draft' == $title ) {
|
1347 |
+
// To do: Check setting else return false.
|
1348 |
+
if ( $this->plugin->settings->IsWPBackend() == 1 ) {
|
|
|
1349 |
return true;
|
1350 |
} else {
|
1351 |
return false;
|
1357 |
|
1358 |
/**
|
1359 |
* Builds revision link.
|
1360 |
+
*
|
1361 |
+
* @param integer $revision_id - Revision ID.
|
1362 |
+
* @return string|null - Link.
|
1363 |
*/
|
1364 |
+
private function getRevisionLink( $revision_id ) {
|
1365 |
+
if ( ! empty( $revision_id ) ) {
|
1366 |
+
return admin_url( 'revision.php?revision=' . $revision_id );
|
|
|
1367 |
} else {
|
1368 |
return null;
|
1369 |
}
|
1371 |
|
1372 |
/**
|
1373 |
* Builds category link.
|
1374 |
+
*
|
1375 |
+
* @param integer $category_id - Category ID.
|
1376 |
+
* @return string|null - Link.
|
1377 |
*/
|
1378 |
+
private function getCategoryLink( $category_id ) {
|
1379 |
+
if ( ! empty( $category_id ) ) {
|
1380 |
+
return admin_url( 'term.php?taxnomy=category&tag_ID=' . $category_id );
|
|
|
1381 |
} else {
|
1382 |
return null;
|
1383 |
}
|
1387 |
* Builds tag link.
|
1388 |
*
|
1389 |
* @param integer $tag_id - Tag ID.
|
1390 |
+
* @return string|null - Link.
|
1391 |
*/
|
1392 |
private function get_tag_link( $tag_id ) {
|
1393 |
if ( ! empty( $tag_id ) ) {
|
1401 |
* Ignore post from BBPress, WooCommerce Plugin
|
1402 |
* Triggered on the Sensors
|
1403 |
*
|
1404 |
+
* @param stdClass $post - The post.
|
1405 |
*/
|
1406 |
private function CheckOtherSensors( $post ) {
|
1407 |
if ( empty( $post ) || ! isset( $post->post_type ) ) {
|
1420 |
|
1421 |
/**
|
1422 |
* Triggered after save post for add revision link.
|
1423 |
+
*
|
1424 |
+
* @param integer $post_id - Post ID.
|
1425 |
+
* @param stdClass $post - Post.
|
1426 |
+
* @param bool $update - True if update.
|
1427 |
*/
|
1428 |
+
public function SetRevisionLink( $post_id, $post, $update ) {
|
1429 |
+
$revisions = wp_get_post_revisions( $post_id );
|
1430 |
+
if ( ! empty( $revisions ) ) {
|
1431 |
+
$revision = array_shift( $revisions );
|
1432 |
+
|
1433 |
+
$obj_occ = new WSAL_Models_Occurrence();
|
1434 |
+
$occ = $obj_occ->GetByPostID( $post_id );
|
1435 |
+
$occ = count( $occ ) ? $occ[0] : null;
|
1436 |
+
if ( ! empty( $occ ) ) {
|
1437 |
+
$revision_link = $this->getRevisionLink( $revision->ID );
|
1438 |
+
if ( ! empty( $revision_link ) ) {
|
1439 |
+
$occ->SetMetaValue( 'RevisionLink', $revision_link );
|
|
|
1440 |
}
|
1441 |
}
|
1442 |
}
|
1454 |
return $post->post_title;
|
1455 |
}
|
1456 |
|
1457 |
+
// Filter $_SERVER array for security.
|
1458 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
1459 |
+
|
1460 |
+
$current_path = $server_array['REQUEST_URI'];
|
1461 |
+
if ( ! empty( $server_array['HTTP_REFERER'] )
|
1462 |
+
&& strpos( $server_array['HTTP_REFERER'], $current_path ) !== false ) {
|
1463 |
// Ignore this if we were on the same page so we avoid double audit entries.
|
1464 |
return;
|
1465 |
}
|
1466 |
if ( ! empty( $post->post_title ) ) {
|
1467 |
$event = $this->GetEventTypeForPostType( $post, 2101, 2103, 2105 );
|
1468 |
+
$this->plugin->alerts->Trigger(
|
1469 |
+
$event, array(
|
1470 |
+
'PostID' => $post->ID,
|
1471 |
+
'PostType' => $post->post_type,
|
1472 |
+
'PostTitle' => $post->post_title,
|
1473 |
+
'PostStatus' => $post->post_status,
|
1474 |
+
'PostDate' => $post->post_date,
|
1475 |
+
'PostUrl' => get_permalink( $post->ID ),
|
1476 |
+
)
|
1477 |
+
);
|
1478 |
}
|
1479 |
}
|
1480 |
}
|
1482 |
|
1483 |
/**
|
1484 |
* Alerts for Editing of Posts, Pages and Custom Posts.
|
1485 |
+
*
|
1486 |
+
* @param stdClass $post - Post.
|
1487 |
*/
|
1488 |
+
public function EditingPost( $post ) {
|
1489 |
+
if ( is_user_logged_in() ) {
|
1490 |
+
if ( is_admin() ) {
|
1491 |
+
if ( $this->CheckOtherSensors( $post ) ) {
|
|
|
1492 |
return $post;
|
1493 |
}
|
1494 |
+
|
1495 |
+
// Filter $_SERVER array for security.
|
1496 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
1497 |
+
|
1498 |
+
$current_path = $server_array['SCRIPT_NAME'] . '?post=' . $post->ID;
|
1499 |
+
if ( ! empty( $server_array['HTTP_REFERER'] )
|
1500 |
+
&& strpos( $server_array['HTTP_REFERER'], $current_path ) !== false ) {
|
1501 |
+
// Ignore this if we were on the same page so we avoid double audit entries.
|
1502 |
return $post;
|
1503 |
}
|
1504 |
+
if ( ! empty( $post->post_title ) ) {
|
1505 |
+
$event = $this->GetEventTypeForPostType( $post, 2100, 2102, 2104 );
|
1506 |
+
if ( ! $this->WasTriggered( $event ) ) {
|
1507 |
+
$editor_link = $this->GetEditorLink( $post );
|
1508 |
+
$this->plugin->alerts->Trigger(
|
1509 |
+
$event, array(
|
1510 |
+
'PostID' => $post->ID,
|
1511 |
+
'PostType' => $post->post_type,
|
1512 |
+
'PostTitle' => $post->post_title,
|
1513 |
+
'PostStatus' => $post->post_status,
|
1514 |
+
'PostDate' => $post->post_date,
|
1515 |
+
$editor_link['name'] => $editor_link['value'],
|
1516 |
+
)
|
1517 |
+
);
|
1518 |
}
|
1519 |
}
|
1520 |
}
|
1524 |
|
1525 |
/**
|
1526 |
* Check if the alert was triggered.
|
1527 |
+
*
|
1528 |
+
* @param integer $alert_id - Alert code.
|
1529 |
* @return boolean
|
1530 |
*/
|
1531 |
+
private function WasTriggered( $alert_id ) {
|
|
|
1532 |
$query = new WSAL_Models_OccurrenceQuery();
|
1533 |
+
$query->addOrderBy( 'created_on', true );
|
1534 |
+
$query->setLimit( 1 );
|
1535 |
+
$last_occurence = $query->getAdapter()->Execute( $query );
|
1536 |
+
if ( ! empty( $last_occurence ) ) {
|
1537 |
+
if ( $last_occurence[0]->alert_id == $alert_id ) {
|
1538 |
return true;
|
1539 |
}
|
1540 |
}
|
1543 |
|
1544 |
/**
|
1545 |
* Changed title of a post.
|
1546 |
+
*
|
1547 |
+
* @param stdClass $oldpost - Old post.
|
1548 |
+
* @param stdClass $newpost - New post.
|
1549 |
*/
|
1550 |
+
private function CheckTitleChange( $oldpost, $newpost ) {
|
1551 |
+
if ( $oldpost->post_title != $newpost->post_title ) {
|
1552 |
+
$event = $this->GetEventTypeForPostType( $newpost, 2086, 2087, 2088 );
|
1553 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
1554 |
+
$this->plugin->alerts->Trigger(
|
1555 |
+
$event, array(
|
1556 |
+
'PostID' => $oldpost->ID,
|
1557 |
+
'PostTitle' => $newpost->post_title,
|
1558 |
+
'PostType' => $oldpost->post_type,
|
1559 |
+
'PostStatus' => $oldpost->post_status,
|
1560 |
+
'PostDate' => $oldpost->post_date,
|
1561 |
+
'OldTitle' => $oldpost->post_title,
|
1562 |
+
'NewTitle' => $newpost->post_title,
|
1563 |
+
$editor_link['name'] => $editor_link['value'],
|
1564 |
+
)
|
1565 |
+
);
|
1566 |
return 1;
|
1567 |
}
|
1568 |
return 0;
|
1570 |
|
1571 |
/**
|
1572 |
* Comments/Trackbacks and Pingbacks check.
|
1573 |
+
*
|
1574 |
+
* @param stdClass $oldpost - Old post.
|
1575 |
+
* @param stdClass $newpost - New post.
|
1576 |
*/
|
1577 |
+
private function CheckCommentsPings( $oldpost, $newpost ) {
|
|
|
1578 |
$result = 0;
|
1579 |
+
// Comments.
|
1580 |
+
if ( $oldpost->comment_status != $newpost->comment_status ) {
|
1581 |
$type = 'Comments';
|
1582 |
|
1583 |
+
if ( 'open' == $newpost->comment_status ) {
|
1584 |
+
$event = $this->GetCommentsPingsEvent( $newpost, 'enable' );
|
1585 |
} else {
|
1586 |
+
$event = $this->GetCommentsPingsEvent( $newpost, 'disable' );
|
1587 |
}
|
1588 |
|
1589 |
+
$this->plugin->alerts->Trigger(
|
1590 |
+
$event, array(
|
1591 |
+
'Type' => $type,
|
1592 |
+
'PostID' => $newpost->ID,
|
1593 |
+
'PostType' => $newpost->post_type,
|
1594 |
+
'PostStatus' => $newpost->post_status,
|
1595 |
+
'PostDate' => $newpost->post_date,
|
1596 |
+
'PostTitle' => $newpost->post_title,
|
1597 |
+
'PostUrl' => get_permalink( $newpost->ID ),
|
1598 |
+
)
|
1599 |
+
);
|
1600 |
$result = 1;
|
1601 |
}
|
1602 |
+
// Trackbacks and Pingbacks.
|
1603 |
+
if ( $oldpost->ping_status != $newpost->ping_status ) {
|
1604 |
$type = 'Trackbacks and Pingbacks';
|
1605 |
|
1606 |
+
if ( 'open' == $newpost->ping_status ) {
|
1607 |
+
$event = $this->GetCommentsPingsEvent( $newpost, 'enable' );
|
1608 |
} else {
|
1609 |
+
$event = $this->GetCommentsPingsEvent( $newpost, 'disable' );
|
1610 |
}
|
1611 |
|
1612 |
+
$this->plugin->alerts->Trigger(
|
1613 |
+
$event, array(
|
1614 |
+
'Type' => $type,
|
1615 |
+
'PostID' => $newpost->ID,
|
1616 |
+
'PostType' => $newpost->post_type,
|
1617 |
+
'PostStatus' => $newpost->post_status,
|
1618 |
+
'PostDate' => $newpost->post_date,
|
1619 |
+
'PostTitle' => $newpost->post_title,
|
1620 |
+
'PostUrl' => get_permalink( $newpost->ID ),
|
1621 |
+
)
|
1622 |
+
);
|
1623 |
$result = 1;
|
1624 |
}
|
1625 |
return $result;
|
1627 |
|
1628 |
/**
|
1629 |
* Comments/Trackbacks and Pingbacks event code.
|
1630 |
+
*
|
1631 |
+
* @param stdClass $post - The post.
|
1632 |
+
* @param string $status - The status.
|
1633 |
*/
|
1634 |
+
private function GetCommentsPingsEvent( $post, $status ) {
|
1635 |
+
if ( 'post' == $post->post_type ) {
|
1636 |
+
if ( 'publish' == $post->post_status ) {
|
1637 |
+
if ( 'disable' == $status ) {
|
|
|
1638 |
$event = 2111;
|
1639 |
} else {
|
1640 |
$event = 2112;
|
1641 |
}
|
1642 |
} else {
|
1643 |
+
if ( 'disable' == $status ) {
|
1644 |
$event = 2113;
|
1645 |
} else {
|
1646 |
$event = 2114;
|
1647 |
}
|
1648 |
}
|
1649 |
} else {
|
1650 |
+
if ( 'publish' == $post->post_status ) {
|
1651 |
+
if ( 'disable' == $status ) {
|
1652 |
$event = 2115;
|
1653 |
} else {
|
1654 |
$event = 2116;
|
1655 |
}
|
1656 |
} else {
|
1657 |
+
if ( 'disable' == $status ) {
|
1658 |
$event = 2117;
|
1659 |
} else {
|
1660 |
$event = 2118;
|
1666 |
|
1667 |
/**
|
1668 |
* Get editor link.
|
1669 |
+
*
|
1670 |
+
* @param stdClass $post - The post.
|
1671 |
+
* @return array $editor_link - Name and value link.
|
1672 |
*/
|
1673 |
+
private function GetEditorLink( $post ) {
|
|
|
1674 |
$name = 'EditorLink';
|
1675 |
+
$name .= ( 'page' == $post->post_type ) ? 'Page' : 'Post' ;
|
1676 |
+
$value = get_edit_post_link( $post->ID );
|
1677 |
+
$editor_link = array(
|
1678 |
'name' => $name,
|
1679 |
'value' => $value,
|
1680 |
);
|
1681 |
+
return $editor_link;
|
1682 |
}
|
1683 |
}
|
classes/Sensors/Database.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Database sensor.
|
6 |
*
|
7 |
* 5010 Plugin created tables
|
@@ -13,154 +25,185 @@
|
|
13 |
* 5016 Unknown component created tables
|
14 |
* 5017 Unknown component modified tables structure
|
15 |
* 5018 Unknown component deleted tables
|
|
|
|
|
|
|
16 |
*/
|
17 |
-
class WSAL_Sensors_Database extends WSAL_AbstractSensor
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Database
|
4 |
+
*
|
5 |
+
* Database sensors class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Database sensor.
|
18 |
*
|
19 |
* 5010 Plugin created tables
|
25 |
* 5016 Unknown component created tables
|
26 |
* 5017 Unknown component modified tables structure
|
27 |
* 5018 Unknown component deleted tables
|
28 |
+
*
|
29 |
+
* @package Wsal
|
30 |
+
* @subpackage Sensors
|
31 |
*/
|
32 |
+
class WSAL_Sensors_Database extends WSAL_AbstractSensor {
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Listening to events using WP hooks.
|
36 |
+
*/
|
37 |
+
public function HookEvents() {
|
38 |
+
add_action( 'dbdelta_queries', array( $this, 'EventDBDeltaQuery' ) );
|
39 |
+
add_action( 'query', array( $this, 'EventDropQuery' ) );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Checks for drop query.
|
44 |
+
*
|
45 |
+
* @param WP_Query $query - Query object.
|
46 |
+
*/
|
47 |
+
public function EventDropQuery( $query ) {
|
48 |
+
$table_names = array();
|
49 |
+
$str = explode( ' ', $query );
|
50 |
+
|
51 |
+
if ( preg_match( '|DROP TABLE ([^ ]*)|', $query ) ) {
|
52 |
+
if ( ! empty( $str[4] ) ) {
|
53 |
+
array_push( $table_names, $str[4] );
|
54 |
+
} else {
|
55 |
+
array_push( $table_names, $str[2] );
|
56 |
+
}
|
57 |
+
|
58 |
+
// Filter $_SERVER array for security.
|
59 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
60 |
+
|
61 |
+
$actype = basename( $server_array['SCRIPT_NAME'], '.php' );
|
62 |
+
$alert_options = $this->GetActionType( $actype );
|
63 |
+
}
|
64 |
+
|
65 |
+
if ( ! empty( $table_names ) ) {
|
66 |
+
$event_code = $this->GetEventQueryType( $actype, 'delete' );
|
67 |
+
$alert_options['TableNames'] = implode( ',', $table_names );
|
68 |
+
$this->plugin->alerts->Trigger( $event_code, $alert_options );
|
69 |
+
}
|
70 |
+
return $query;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Checks DB Delta queries.
|
75 |
+
*
|
76 |
+
* @param array $queries - Array of query.
|
77 |
+
*/
|
78 |
+
public function EventDBDeltaQuery( $queries ) {
|
79 |
+
$type_queries = array(
|
80 |
+
'create' => array(),
|
81 |
+
'update' => array(),
|
82 |
+
'delete' => array(),
|
83 |
+
);
|
84 |
+
global $wpdb;
|
85 |
+
|
86 |
+
foreach ( $queries as $qry ) {
|
87 |
+
$str = explode( ' ', $qry );
|
88 |
+
if ( preg_match( '|CREATE TABLE ([^ ]*)|', $qry ) ) {
|
89 |
+
if ( $wpdb->get_var( "SHOW TABLES LIKE '" . $str[2] . "'" ) != $str[2] ) {
|
90 |
+
/**
|
91 |
+
* Some plugins keep trying to create tables even
|
92 |
+
* when they already exist- would result in too
|
93 |
+
* many alerts.
|
94 |
+
*/
|
95 |
+
array_push( $type_queries['create'], $str[2] );
|
96 |
+
}
|
97 |
+
} elseif ( preg_match( '|ALTER TABLE ([^ ]*)|', $qry ) ) {
|
98 |
+
array_push( $type_queries['update'], $str[2] );
|
99 |
+
} elseif ( preg_match( '|DROP TABLE ([^ ]*)|', $qry ) ) {
|
100 |
+
if ( ! empty( $str[4] ) ) {
|
101 |
+
array_push( $type_queries['delete'], $str[4] );
|
102 |
+
} else {
|
103 |
+
array_push( $type_queries['delete'], $str[2] );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
if ( ! empty( $type_queries['create'] ) || ! empty( $type_queries['update'] ) || ! empty( $type_queries['delete'] ) ) {
|
109 |
+
// Filter $_SERVER array for security.
|
110 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
111 |
+
|
112 |
+
$actype = basename( $server_array['SCRIPT_NAME'], '.php' );
|
113 |
+
$alert_options = $this->GetActionType( $actype );
|
114 |
+
|
115 |
+
foreach ( $type_queries as $query_type => $table_names ) {
|
116 |
+
if ( ! empty( $table_names ) ) {
|
117 |
+
$event_code = $this->GetEventQueryType( $actype, $query_type );
|
118 |
+
$alert_options['TableNames'] = implode( ',', $table_names );
|
119 |
+
$this->plugin->alerts->Trigger( $event_code, $alert_options );
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
return $queries;
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Get code alert by action and type query.
|
129 |
+
*
|
130 |
+
* @param string $type_action - Plugins, themes or unknown.
|
131 |
+
* @param string $type_query - Create, update or delete.
|
132 |
+
*/
|
133 |
+
protected function GetEventQueryType( $type_action, $type_query ) {
|
134 |
+
switch ( $type_action ) {
|
135 |
+
case 'plugins':
|
136 |
+
if ( 'create' == $type_query ) {
|
137 |
+
return 5010;
|
138 |
+
} elseif ( 'update' == $type_query ) {
|
139 |
+
return 5011;
|
140 |
+
} elseif ( 'delete' == $type_query ) {
|
141 |
+
return 5012;
|
142 |
+
}
|
143 |
+
// In case of plugins.
|
144 |
+
case 'themes':
|
145 |
+
if ( 'create' == $type_query ) {
|
146 |
+
return 5013;
|
147 |
+
} elseif ( 'update' == $type_query ) {
|
148 |
+
return 5014;
|
149 |
+
} elseif ( 'delete' == $type_query ) {
|
150 |
+
return 5015;
|
151 |
+
}
|
152 |
+
// In case of themes.
|
153 |
+
default:
|
154 |
+
if ( 'create' == $type_query ) {
|
155 |
+
return 5016;
|
156 |
+
} elseif ( 'update' == $type_query ) {
|
157 |
+
return 5017;
|
158 |
+
} elseif ( 'delete' == $type_query ) {
|
159 |
+
return 5018;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Get info by action type.
|
166 |
+
*
|
167 |
+
* @param string $actype - Plugins, themes or unknown.
|
168 |
+
*/
|
169 |
+
protected function GetActionType( $actype ) {
|
170 |
+
// Filter $_GET array for security.
|
171 |
+
$get_array = filter_input_array( INPUT_GET );
|
172 |
+
|
173 |
+
$is_themes = 'themes' == $actype;
|
174 |
+
$is_plugins = 'plugins' == $actype;
|
175 |
+
|
176 |
+
// Action Plugin Component.
|
177 |
+
$alert_options = array();
|
178 |
+
if ( $is_plugins ) {
|
179 |
+
if ( isset( $get_array['plugin'] ) ) {
|
180 |
+
$plugin_file = $get_array['plugin'];
|
181 |
+
} else {
|
182 |
+
$plugin_file = $get_array['checked'][0];
|
183 |
+
}
|
184 |
+
$plugin_name = basename( $plugin_file, '.php' );
|
185 |
+
$plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name );
|
186 |
+
$plugin_name = ucwords( $plugin_name );
|
187 |
+
$alert_options['Plugin'] = (object) array(
|
188 |
+
'Name' => $plugin_name,
|
189 |
+
);
|
190 |
+
// Action Theme Component.
|
191 |
+
} elseif ( $is_themes ) {
|
192 |
+
if ( isset( $get_array['theme'] ) ) {
|
193 |
+
$theme_name = $get_array['theme'];
|
194 |
+
} else {
|
195 |
+
$theme_name = $get_array['checked'][0];
|
196 |
+
}
|
197 |
+
$theme_name = str_replace( array( '_', '-', ' ' ), ' ', $theme_name );
|
198 |
+
$theme_name = ucwords( $theme_name );
|
199 |
+
$alert_options['Theme'] = (object) array(
|
200 |
+
'Name' => $theme_name,
|
201 |
+
);
|
202 |
+
// Action Unknown Component.
|
203 |
+
} else {
|
204 |
+
$alert_options['Component'] = 'Unknown';
|
205 |
+
}
|
206 |
+
|
207 |
+
return $alert_options;
|
208 |
+
}
|
209 |
}
|
classes/Sensors/Files.php
CHANGED
@@ -1,87 +1,117 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Files sensor.
|
6 |
*
|
7 |
-
* 2010 User uploaded file
|
8 |
* 2011 User deleted file from Uploads directory
|
9 |
* 2046 User changed a file using the theme editor
|
10 |
* 2051 User changed a file using the plugin editor
|
|
|
|
|
|
|
11 |
*/
|
12 |
-
class WSAL_Sensors_Files extends WSAL_AbstractSensor
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
/**
|
30 |
-
* File uploaded.
|
31 |
-
* @param integer $attachmentID attachment ID
|
32 |
-
*/
|
33 |
-
public function EventFileUploaded($attachmentID)
|
34 |
-
{
|
35 |
-
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
36 |
-
if ($action != 'upload-theme' && $action != 'upload-plugin') {
|
37 |
-
$file = get_attached_file($attachmentID);
|
38 |
-
$this->plugin->alerts->Trigger(2010, array(
|
39 |
-
'AttachmentID' => $attachmentID,
|
40 |
-
'FileName' => basename($file),
|
41 |
-
'FilePath' => dirname($file),
|
42 |
-
));
|
43 |
-
}
|
44 |
-
$this->IsFileUploaded = true;
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Deleted file from uploads directory.
|
49 |
-
* @param integer $attachmentID attachment ID
|
50 |
-
*/
|
51 |
-
public function EventFileUploadedDeleted($attachmentID)
|
52 |
-
{
|
53 |
-
if ($this->IsFileUploaded) {
|
54 |
-
return;
|
55 |
-
}
|
56 |
-
$file = get_attached_file($attachmentID);
|
57 |
-
$this->plugin->alerts->Trigger(2011, array(
|
58 |
-
'AttachmentID' => $attachmentID,
|
59 |
-
'FileName' => basename($file),
|
60 |
-
'FilePath' => dirname($file),
|
61 |
-
));
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Triggered when a user accesses the admin area.
|
66 |
-
*/
|
67 |
-
public function EventAdminInit()
|
68 |
-
{
|
69 |
-
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
70 |
-
$is_theme_editor = basename($_SERVER['SCRIPT_NAME']) == 'theme-editor.php';
|
71 |
-
$is_plugin_editor = basename($_SERVER['SCRIPT_NAME']) == 'plugin-editor.php';
|
72 |
-
|
73 |
-
if ($is_theme_editor && $action == 'update') {
|
74 |
-
$this->plugin->alerts->Trigger(2046, array(
|
75 |
-
'File' => $_REQUEST['file'],
|
76 |
-
'Theme' => $_REQUEST['theme'],
|
77 |
-
));
|
78 |
-
}
|
79 |
-
|
80 |
-
if ($is_plugin_editor && $action == 'update') {
|
81 |
-
$this->plugin->alerts->Trigger(2051, array(
|
82 |
-
'File' => $_REQUEST['file'],
|
83 |
-
'Plugin' => $_REQUEST['plugin'],
|
84 |
-
));
|
85 |
-
}
|
86 |
-
}
|
87 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Files
|
4 |
+
*
|
5 |
+
* Files sensors class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Files sensor.
|
18 |
*
|
19 |
+
* 2010 User uploaded file in Uploads directory
|
20 |
* 2011 User deleted file from Uploads directory
|
21 |
* 2046 User changed a file using the theme editor
|
22 |
* 2051 User changed a file using the plugin editor
|
23 |
+
*
|
24 |
+
* @package Wsal
|
25 |
+
* @subpackage Sensors
|
26 |
*/
|
27 |
+
class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* File uploaded.
|
31 |
+
*
|
32 |
+
* @var boolean
|
33 |
+
*/
|
34 |
+
protected $is_file_uploaded = false;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Listening to events using WP hooks.
|
38 |
+
*/
|
39 |
+
public function HookEvents() {
|
40 |
+
add_action( 'add_attachment', array( $this, 'EventFileUploaded' ) );
|
41 |
+
add_action( 'delete_attachment', array( $this, 'EventFileUploadedDeleted' ) );
|
42 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* File uploaded.
|
47 |
+
*
|
48 |
+
* @param integer $attachment_id - Attachment ID.
|
49 |
+
*/
|
50 |
+
public function EventFileUploaded( $attachment_id ) {
|
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->Trigger(
|
58 |
+
2010, array(
|
59 |
+
'AttachmentID' => $attachment_id,
|
60 |
+
'FileName' => basename( $file ),
|
61 |
+
'FilePath' => dirname( $file ),
|
62 |
+
)
|
63 |
+
);
|
64 |
+
}
|
65 |
+
$this->is_file_uploaded = true;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Deleted file from uploads directory.
|
70 |
+
*
|
71 |
+
* @param integer $attachment_id - Attachment ID.
|
72 |
+
*/
|
73 |
+
public function EventFileUploadedDeleted( $attachment_id ) {
|
74 |
+
if ( $this->is_file_uploaded ) {
|
75 |
+
return;
|
76 |
+
}
|
77 |
+
$file = get_attached_file( $attachment_id );
|
78 |
+
$this->plugin->alerts->Trigger(
|
79 |
+
2011, array(
|
80 |
+
'AttachmentID' => $attachment_id,
|
81 |
+
'FileName' => basename( $file ),
|
82 |
+
'FilePath' => dirname( $file ),
|
83 |
+
)
|
84 |
+
);
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Triggered when a user accesses the admin area.
|
89 |
+
*/
|
90 |
+
public function EventAdminInit() {
|
91 |
+
// Filter global arrays for security.
|
92 |
+
$post_array = filter_input_array( INPUT_POST );
|
93 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
94 |
+
|
95 |
+
$action = isset( $post_array['action'] ) ? $post_array['action'] : '';
|
96 |
+
$is_theme_editor = 'theme-editor.php' == basename( $server_array['SCRIPT_NAME'] );
|
97 |
+
$is_plugin_editor = 'plugin-editor.php' == basename( $server_array['SCRIPT_NAME'] );
|
98 |
+
|
99 |
+
if ( $is_theme_editor && 'update' === $action ) {
|
100 |
+
$this->plugin->alerts->Trigger(
|
101 |
+
2046, array(
|
102 |
+
'File' => $post_array['file'],
|
103 |
+
'Theme' => $post_array['theme'],
|
104 |
+
)
|
105 |
+
);
|
106 |
+
}
|
107 |
|
108 |
+
if ( $is_plugin_editor && 'update' === $action ) {
|
109 |
+
$this->plugin->alerts->Trigger(
|
110 |
+
2051, array(
|
111 |
+
'File' => $post_array['file'],
|
112 |
+
'Plugin' => $post_array['plugin'],
|
113 |
+
)
|
114 |
+
);
|
115 |
+
}
|
116 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
}
|
classes/Sensors/LogInOut.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Login/Logout sensor.
|
6 |
*
|
7 |
* 1000 User logged in
|
@@ -10,374 +22,425 @@
|
|
10 |
* 1003 Login failed / non existing user
|
11 |
* 1004 Login blocked
|
12 |
* 4003 User has changed his or her password
|
|
|
|
|
|
|
13 |
*/
|
14 |
-
class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Log In & Log Out
|
4 |
+
*
|
5 |
+
* Log In & Out sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Login/Logout sensor.
|
18 |
*
|
19 |
* 1000 User logged in
|
22 |
* 1003 Login failed / non existing user
|
23 |
* 1004 Login blocked
|
24 |
* 4003 User has changed his or her password
|
25 |
+
*
|
26 |
+
* @package Wsal
|
27 |
+
* @subpackage Sensors
|
28 |
*/
|
29 |
+
class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Transient name.
|
33 |
+
* WordPress will prefix the name with "_transient_" or "_transient_timeout_" in the options table.
|
34 |
+
*/
|
35 |
+
const TRANSIENT_FAILEDLOGINS = 'wsal-failedlogins-known';
|
36 |
+
const TRANSIENT_FAILEDLOGINS_UNKNOWN = 'wsal-failedlogins-unknown';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Current user object
|
40 |
+
*
|
41 |
+
* @var WP_User
|
42 |
+
*/
|
43 |
+
protected $_current_user = null;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Listening to events using WP hooks.
|
47 |
+
*/
|
48 |
+
public function HookEvents() {
|
49 |
+
add_action( 'wp_login', array( $this, 'EventLogin' ), 10, 2 );
|
50 |
+
add_action( 'wp_logout', array( $this, 'EventLogout' ) );
|
51 |
+
add_action( 'password_reset', array( $this, 'EventPasswordReset' ), 10, 2 );
|
52 |
+
add_action( 'wp_login_failed', array( $this, 'EventLoginFailure' ) );
|
53 |
+
add_action( 'clear_auth_cookie', array( $this, 'GetCurrentUser' ), 10 );
|
54 |
+
add_filter( 'wp_login_blocked', array( $this, 'EventLoginBlocked' ), 10, 1 );
|
55 |
+
|
56 |
+
// Directory for logged in users log files.
|
57 |
+
$user_upload_dir = wp_upload_dir();
|
58 |
+
$user_upload_path = trailingslashit( $user_upload_dir['basedir'] . '/wp-security-audit-log/failed-logins/' );
|
59 |
+
if ( ! $this->CheckDirectory( $user_upload_path ) ) {
|
60 |
+
wp_mkdir_p( $user_upload_path );
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Sets current user.
|
66 |
+
*/
|
67 |
+
public function GetCurrentUser() {
|
68 |
+
$this->_current_user = wp_get_current_user();
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Event Login.
|
73 |
+
*
|
74 |
+
* @param string $user_login - Username.
|
75 |
+
* @param object $user - WP_User object.
|
76 |
+
*/
|
77 |
+
public function EventLogin( $user_login, $user = null ) {
|
78 |
+
if ( empty( $user ) ) {
|
79 |
+
$user = get_user_by( 'login', $user_login );
|
80 |
+
}
|
81 |
+
$user_roles = $this->plugin->settings->GetCurrentUserRoles( $user->roles );
|
82 |
+
if ( $this->plugin->settings->IsLoginSuperAdmin( $user_login ) ) {
|
83 |
+
$user_roles[] = 'superadmin';
|
84 |
+
}
|
85 |
+
$this->plugin->alerts->Trigger(
|
86 |
+
1000, array(
|
87 |
+
'Username' => $user_login,
|
88 |
+
'CurrentUserRoles' => $user_roles,
|
89 |
+
), true
|
90 |
+
);
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Event Logout.
|
95 |
+
*/
|
96 |
+
public function EventLogout() {
|
97 |
+
if ( 0 != $this->_current_user->ID ) {
|
98 |
+
$this->plugin->alerts->Trigger(
|
99 |
+
1001, array(
|
100 |
+
'CurrentUserID' => $this->_current_user->ID,
|
101 |
+
'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles( $this->_current_user->roles ),
|
102 |
+
), true
|
103 |
+
);
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Login failure limit count.
|
109 |
+
*
|
110 |
+
* @return int
|
111 |
+
*/
|
112 |
+
protected function GetLoginFailureLogLimit() {
|
113 |
+
return $this->plugin->settings->get_failed_login_limit();
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Non-existing Login failure limit count.
|
118 |
+
*
|
119 |
+
* @return int
|
120 |
+
*/
|
121 |
+
protected function GetVisitorLoginFailureLogLimit() {
|
122 |
+
return $this->plugin->settings->get_visitor_failed_login_limit();
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Expiration of the transient saved in the WP database.
|
127 |
+
*
|
128 |
+
* @return integer Time until expiration in seconds from now
|
129 |
+
*/
|
130 |
+
protected function GetLoginFailureExpiration() {
|
131 |
+
return 12 * 60 * 60;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Check failure limit.
|
136 |
+
*
|
137 |
+
* @param string $ip - IP address.
|
138 |
+
* @param integer $site_id - Blog ID.
|
139 |
+
* @param WP_User $user - User object.
|
140 |
+
* @return boolean - Passed limit true|false.
|
141 |
+
*/
|
142 |
+
protected function IsPastLoginFailureLimit( $ip, $site_id, $user ) {
|
143 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
144 |
+
if ( $user ) {
|
145 |
+
if ( -1 === (int) $this->GetLoginFailureLogLimit() ) {
|
146 |
+
return false;
|
147 |
+
} else {
|
148 |
+
$data_known = $get_fn( self::TRANSIENT_FAILEDLOGINS );
|
149 |
+
return ( false !== $data_known ) && isset( $data_known[ $site_id . ':' . $user->ID . ':' . $ip ] ) && ($data_known[ $site_id . ':' . $user->ID . ':' . $ip ] >= $this->GetLoginFailureLogLimit());
|
150 |
+
}
|
151 |
+
} else {
|
152 |
+
if ( -1 === (int) $this->GetVisitorLoginFailureLogLimit() ) {
|
153 |
+
return false;
|
154 |
+
} else {
|
155 |
+
$data_unknown = $get_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN );
|
156 |
+
return ( false !== $data_unknown ) && isset( $data_unknown[ $site_id . ':' . $ip ] ) && ($data_unknown[ $site_id . ':' . $ip ] >= $this->GetVisitorLoginFailureLogLimit());
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Increment failure limit.
|
163 |
+
*
|
164 |
+
* @param string $ip - IP address.
|
165 |
+
* @param integer $site_id - Blog ID.
|
166 |
+
* @param WP_User $user - User object.
|
167 |
+
*/
|
168 |
+
protected function IncrementLoginFailure( $ip, $site_id, $user ) {
|
169 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
170 |
+
$set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
|
171 |
+
if ( $user ) {
|
172 |
+
$data_known = $get_fn( self::TRANSIENT_FAILEDLOGINS );
|
173 |
+
if ( ! $data_known ) {
|
174 |
+
$data_known = array();
|
175 |
+
}
|
176 |
+
if ( ! isset( $data_known[ $site_id . ':' . $user->ID . ':' . $ip ] ) ) {
|
177 |
+
$data_known[ $site_id . ':' . $user->ID . ':' . $ip ] = 1;
|
178 |
+
}
|
179 |
+
$data_known[ $site_id . ':' . $user->ID . ':' . $ip ]++;
|
180 |
+
$set_fn( self::TRANSIENT_FAILEDLOGINS, $data_known, $this->GetLoginFailureExpiration() );
|
181 |
+
} else {
|
182 |
+
$data_unknown = $get_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN );
|
183 |
+
if ( ! $data_unknown ) {
|
184 |
+
$data_unknown = array();
|
185 |
+
}
|
186 |
+
if ( ! isset( $data_unknown[ $site_id . ':' . $ip ] ) ) {
|
187 |
+
$data_unknown[ $site_id . ':' . $ip ] = 1;
|
188 |
+
}
|
189 |
+
$data_unknown[ $site_id . ':' . $ip ]++;
|
190 |
+
$set_fn( self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $data_unknown, $this->GetLoginFailureExpiration() );
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Event Login failure.
|
196 |
+
*
|
197 |
+
* @param string $username Username.
|
198 |
+
*/
|
199 |
+
public function EventLoginFailure( $username ) {
|
200 |
+
list($y, $m, $d) = explode( '-', date( 'Y-m-d' ) );
|
201 |
+
|
202 |
+
$ip = $this->plugin->settings->GetMainClientIP();
|
203 |
+
|
204 |
+
// Filter $_POST global array for security.
|
205 |
+
$post_array = filter_input_array( INPUT_POST );
|
206 |
+
|
207 |
+
$username = array_key_exists( 'log', $post_array ) ? $post_array['log'] : $username;
|
208 |
+
$username = sanitize_user( $username );
|
209 |
+
$new_alert_code = 1003;
|
210 |
+
$user = get_user_by( 'login', $username );
|
211 |
+
$site_id = (function_exists( 'get_current_blog_id' ) ? get_current_blog_id() : 0);
|
212 |
+
if ( $user ) {
|
213 |
+
$new_alert_code = 1002;
|
214 |
+
$user_roles = $this->plugin->settings->GetCurrentUserRoles( $user->roles );
|
215 |
+
if ( $this->plugin->settings->IsLoginSuperAdmin( $username ) ) {
|
216 |
+
$user_roles[] = 'superadmin';
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
// Check if the alert is disabled from the "Enable/Disable Alerts" section.
|
221 |
+
if ( ! $this->plugin->alerts->IsEnabled( $new_alert_code ) ) {
|
222 |
+
return;
|
223 |
+
}
|
224 |
+
|
225 |
+
if ( $this->IsPastLoginFailureLimit( $ip, $site_id, $user ) ) {
|
226 |
+
return;
|
227 |
+
}
|
228 |
+
|
229 |
+
$obj_occurrence = new WSAL_Models_Occurrence();
|
230 |
+
|
231 |
+
if ( 1002 == $new_alert_code ) {
|
232 |
+
if ( ! $this->plugin->alerts->CheckEnableUserRoles( $username, $user_roles ) ) {
|
233 |
+
return;
|
234 |
+
}
|
235 |
+
$occ = $obj_occurrence->CheckKnownUsers(
|
236 |
+
array(
|
237 |
+
$ip,
|
238 |
+
$username,
|
239 |
+
1002,
|
240 |
+
$site_id,
|
241 |
+
mktime( 0, 0, 0, $m, $d, $y ),
|
242 |
+
mktime( 0, 0, 0, $m, $d + 1, $y ) - 1,
|
243 |
+
)
|
244 |
+
);
|
245 |
+
$occ = count( $occ ) ? $occ[0] : null;
|
246 |
+
|
247 |
+
if ( ! empty( $occ ) ) {
|
248 |
+
// Update existing record exists user.
|
249 |
+
$this->IncrementLoginFailure( $ip, $site_id, $user );
|
250 |
+
$new = $occ->GetMetaValue( 'Attempts', 0 ) + 1;
|
251 |
+
|
252 |
+
if ( -1 !== (int) $this->GetLoginFailureLogLimit()
|
253 |
+
&& $new > $this->GetLoginFailureLogLimit() ) {
|
254 |
+
$new = $this->GetLoginFailureLogLimit() . '+';
|
255 |
+
}
|
256 |
+
|
257 |
+
$occ->UpdateMetaValue( 'Attempts', $new );
|
258 |
+
$occ->UpdateMetaValue( 'Username', $username );
|
259 |
+
|
260 |
+
// $occ->SetMetaValue('CurrentUserRoles', $user_roles);
|
261 |
+
$occ->created_on = null;
|
262 |
+
$occ->Save();
|
263 |
+
} else {
|
264 |
+
// Create a new record exists user.
|
265 |
+
$this->plugin->alerts->Trigger(
|
266 |
+
$new_alert_code, array(
|
267 |
+
'Attempts' => 1,
|
268 |
+
'Username' => $username,
|
269 |
+
'CurrentUserRoles' => $user_roles,
|
270 |
+
)
|
271 |
+
);
|
272 |
+
}
|
273 |
+
} else {
|
274 |
+
$occ_unknown = $obj_occurrence->CheckUnKnownUsers(
|
275 |
+
array(
|
276 |
+
$ip,
|
277 |
+
1003,
|
278 |
+
$site_id,
|
279 |
+
mktime( 0, 0, 0, $m, $d, $y ),
|
280 |
+
mktime( 0, 0, 0, $m, $d + 1, $y ) - 1,
|
281 |
+
)
|
282 |
+
);
|
283 |
+
|
284 |
+
$occ_unknown = count( $occ_unknown ) ? $occ_unknown[0] : null;
|
285 |
+
if ( ! empty( $occ_unknown ) ) {
|
286 |
+
// Update existing record not exists user.
|
287 |
+
$this->IncrementLoginFailure( $ip, $site_id, false );
|
288 |
+
$new = $occ_unknown->GetMetaValue( 'Attempts', 0 ) + 1;
|
289 |
+
|
290 |
+
if ( 'on' === $this->plugin->GetGlobalOption( 'log-visitor-failed-login' ) ) {
|
291 |
+
$link_file = $this->WriteLog( $new, $username );
|
292 |
+
}
|
293 |
+
|
294 |
+
if ( -1 !== (int) $this->GetVisitorLoginFailureLogLimit()
|
295 |
+
&& $new > $this->GetVisitorLoginFailureLogLimit() ) {
|
296 |
+
$new = $this->GetVisitorLoginFailureLogLimit() . '+';
|
297 |
+
}
|
298 |
+
|
299 |
+
$occ_unknown->UpdateMetaValue( 'Attempts', $new );
|
300 |
+
if ( ! empty( $link_file ) && 'on' === $this->plugin->GetGlobalOption( 'log-visitor-failed-login' ) ) {
|
301 |
+
$occ_unknown->UpdateMetaValue( 'LogFileLink', $link_file );
|
302 |
+
} else {
|
303 |
+
$link_file = site_url() . '/wp-admin/admin.php?page=wsal-togglealerts#tab-users-profiles---activity';
|
304 |
+
$occ_unknown->UpdateMetaValue( 'LogFileLink', $link_file );
|
305 |
+
}
|
306 |
+
$occ_unknown->created_on = null;
|
307 |
+
$occ_unknown->Save();
|
308 |
+
} else {
|
309 |
+
$link_file = site_url() . '/wp-admin/admin.php?page=wsal-togglealerts#tab-users-profiles---activity';
|
310 |
+
$log_file_text = ' in a log file';
|
311 |
+
if ( 'on' === $this->plugin->GetGlobalOption( 'log-visitor-failed-login' ) ) {
|
312 |
+
$link_file = $this->WriteLog( 1, $username );
|
313 |
+
$log_file_text = ' with the usernames used during these failed login attempts';
|
314 |
+
}
|
315 |
+
|
316 |
+
// Create a new record not exists user.
|
317 |
+
$this->plugin->alerts->Trigger(
|
318 |
+
$new_alert_code, array(
|
319 |
+
'Attempts' => 1,
|
320 |
+
'LogFileLink' => $link_file,
|
321 |
+
'LogFileText' => $log_file_text,
|
322 |
+
)
|
323 |
+
);
|
324 |
+
}
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Event changed password.
|
330 |
+
*
|
331 |
+
* @param WP_User $user - User object.
|
332 |
+
* @param string $new_pass - New Password.
|
333 |
+
*/
|
334 |
+
public function EventPasswordReset( $user, $new_pass ) {
|
335 |
+
if ( ! empty( $user ) ) {
|
336 |
+
$user_roles = $this->plugin->settings->GetCurrentUserRoles( $user->roles );
|
337 |
+
$this->plugin->alerts->Trigger(
|
338 |
+
4003, array(
|
339 |
+
'Username' => $user->user_login,
|
340 |
+
'CurrentUserRoles' => $user_roles,
|
341 |
+
), true
|
342 |
+
);
|
343 |
+
}
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Event login blocked.
|
348 |
+
*
|
349 |
+
* @param string $username - Username.
|
350 |
+
*/
|
351 |
+
public function EventLoginBlocked( $username ) {
|
352 |
+
$user = get_user_by( 'login', $username );
|
353 |
+
$user_roles = $this->plugin->settings->GetCurrentUserRoles( $user->roles );
|
354 |
+
|
355 |
+
if ( $this->plugin->settings->IsLoginSuperAdmin( $username ) ) {
|
356 |
+
$user_roles[] = 'superadmin';
|
357 |
+
}
|
358 |
+
$this->plugin->alerts->Trigger(
|
359 |
+
1004, array(
|
360 |
+
'Username' => $username,
|
361 |
+
'CurrentUserRoles' => $user_roles,
|
362 |
+
), true
|
363 |
+
);
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Write log file.
|
368 |
+
*
|
369 |
+
* @param int $attempts - Number of attempt.
|
370 |
+
* @param string $username - Username.
|
371 |
+
* @author Ashar Irfan
|
372 |
+
* @since 2.6.9
|
373 |
+
*/
|
374 |
+
private function WriteLog( $attempts, $username = '' ) {
|
375 |
+
$name_file = null;
|
376 |
+
|
377 |
+
// Create/Append to the log file.
|
378 |
+
$data = 'Attempts: ' . $attempts . ' — Username: ' . $username;
|
379 |
+
|
380 |
+
$upload_dir = wp_upload_dir();
|
381 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/failed-logins/';
|
382 |
+
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/failed-logins/';
|
383 |
+
|
384 |
+
// Check directory.
|
385 |
+
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
386 |
+
$filename = 'failed_logins_usernames_' . date( 'Ymd' ) . '.log';
|
387 |
+
$fp = $uploads_dir_path . $filename;
|
388 |
+
$name_file = $uploads_url . $filename;
|
389 |
+
if ( ! $file = fopen( $fp, 'a' ) ) {
|
390 |
+
$i = 1;
|
391 |
+
$file_opened = false;
|
392 |
+
do {
|
393 |
+
$fp2 = substr( $fp, 0, -4 ) . '_' . $i . '.log';
|
394 |
+
if ( ! file_exists( $fp2 ) ) {
|
395 |
+
if ( $file = fopen( $fp2, 'a' ) ) {
|
396 |
+
$file_opened = true;
|
397 |
+
$name_file = $uploads_url . substr( $name_file, 0, -4 ) . '_' . $i . '.log';
|
398 |
+
}
|
399 |
+
} else {
|
400 |
+
$latest_filename = $this->GetLastModified( $uploads_dir_path, $filename );
|
401 |
+
$fp_last = $uploads_dir_path . $latest_filename;
|
402 |
+
if ( $file = fopen( $fp_last, 'a' ) ) {
|
403 |
+
$file_opened = true;
|
404 |
+
$name_file = $uploads_url . $latest_filename;
|
405 |
+
}
|
406 |
+
}
|
407 |
+
$i++;
|
408 |
+
} while ( ! $file_opened );
|
409 |
+
}
|
410 |
+
fwrite( $file, sprintf( "%s\n", $data ) );
|
411 |
+
fclose( $file );
|
412 |
+
}
|
413 |
+
|
414 |
+
return $name_file;
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Get the latest file modified.
|
419 |
+
*
|
420 |
+
* @param string $uploads_dir_path - Uploads directory path.
|
421 |
+
* @param string $filename - File name.
|
422 |
+
* @return string $latest_filename - File name.
|
423 |
+
*/
|
424 |
+
private function GetLastModified( $uploads_dir_path, $filename ) {
|
425 |
+
$filename = substr( $filename, 0, -4 );
|
426 |
+
$latest_mtime = 0;
|
427 |
+
$latest_filename = '';
|
428 |
+
if ( $handle = opendir( $uploads_dir_path ) ) {
|
429 |
+
while ( false !== ($entry = readdir( $handle )) ) {
|
430 |
+
if ( '.' != $entry && '..' != $entry ) {
|
431 |
+
$entry = strip_tags( $entry ); // Strip HTML Tags.
|
432 |
+
$entry = preg_replace( '/[\r\n\t ]+/', ' ', $entry ); // Remove Break/Tabs/Return Carriage.
|
433 |
+
$entry = preg_replace( '/[\"\*\/\:\<\>\?\'\|]+/', ' ', $entry ); // Remove Illegal Chars for folder and filename.
|
434 |
+
if ( preg_match( '/^' . $filename . '/i', $entry ) > 0 ) {
|
435 |
+
if ( filemtime( $uploads_dir_path . $entry ) > $latest_mtime ) {
|
436 |
+
$latest_mtime = filemtime( $uploads_dir_path . $entry );
|
437 |
+
$latest_filename = $entry;
|
438 |
+
}
|
439 |
+
}
|
440 |
+
}
|
441 |
+
}
|
442 |
+
closedir( $handle );
|
443 |
+
}
|
444 |
+
return $latest_filename;
|
445 |
+
}
|
446 |
}
|
classes/Sensors/Menus.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Menus sensor.
|
6 |
*
|
7 |
* 2078 User created new menu
|
@@ -13,518 +25,637 @@
|
|
13 |
* 2084 User changed name of a menu
|
14 |
* 2085 User changed order of the objects in a menu
|
15 |
* 2089 User moved objects as a sub-item
|
|
|
|
|
|
|
16 |
*/
|
17 |
-
class WSAL_Sensors_Menus extends WSAL_AbstractSensor
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
530 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Menus
|
4 |
+
*
|
5 |
+
* Menus sensor file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Menus sensor.
|
18 |
*
|
19 |
* 2078 User created new menu
|
25 |
* 2084 User changed name of a menu
|
26 |
* 2085 User changed order of the objects in a menu
|
27 |
* 2089 User moved objects as a sub-item
|
28 |
+
*
|
29 |
+
* @package Wsal
|
30 |
+
* @subpackage Sensors
|
31 |
*/
|
32 |
+
class WSAL_Sensors_Menus extends WSAL_AbstractSensor {
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Menu object.
|
36 |
+
*
|
37 |
+
* @var object
|
38 |
+
*/
|
39 |
+
protected $_old_menu = null;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Old Menu objects.
|
43 |
+
*
|
44 |
+
* @var array
|
45 |
+
*/
|
46 |
+
protected $_old_menu_terms = array();
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Old Menu Items.
|
50 |
+
*
|
51 |
+
* @var array
|
52 |
+
*/
|
53 |
+
protected $_old_menu_items = array();
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Old Menu Locations.
|
57 |
+
*
|
58 |
+
* @var array
|
59 |
+
*/
|
60 |
+
protected $_old_menu_locations = null;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Listening to events using WP hooks.
|
64 |
+
*/
|
65 |
+
public function HookEvents() {
|
66 |
+
add_action( 'wp_create_nav_menu', array( $this, 'CreateMenu' ), 10, 2 );
|
67 |
+
add_action( 'wp_delete_nav_menu', array( $this, 'DeleteMenu' ), 10, 1 );
|
68 |
+
add_action( 'wp_update_nav_menu', array( $this, 'UpdateMenu' ), 10, 2 );
|
69 |
+
|
70 |
+
add_action( 'wp_update_nav_menu_item', array( $this, 'UpdateMenuItem' ), 10, 3 );
|
71 |
+
add_action( 'admin_menu', array( $this, 'ManageMenuLocations' ) );
|
72 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
73 |
+
|
74 |
+
// Customizer trigger.
|
75 |
+
add_action( 'customize_register', array( $this, 'CustomizeInit' ) );
|
76 |
+
add_action( 'customize_save_after', array( $this, 'CustomizeSave' ) );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Menu item updated.
|
81 |
+
*
|
82 |
+
* @param int $menu_id - Menu ID.
|
83 |
+
* @param int $menu_item_db_id - Menu item DB ID.
|
84 |
+
* @param array $args - An array of items used to update menu.
|
85 |
+
*/
|
86 |
+
public function UpdateMenuItem( $menu_id, $menu_item_db_id, $args ) {
|
87 |
+
// Filter $_POST global array for security.
|
88 |
+
$post_array = filter_input_array( INPUT_POST );
|
89 |
+
|
90 |
+
$old_menu_items = array();
|
91 |
+
if ( isset( $post_array['menu-item-title'] ) && isset( $post_array['menu-name'] ) ) {
|
92 |
+
$is_changed_order = false;
|
93 |
+
$is_sub_item = false;
|
94 |
+
$new_menu_items = array_keys( $post_array['menu-item-title'] );
|
95 |
+
$items = wp_get_nav_menu_items( $menu_id );
|
96 |
+
if ( ! empty( $this->_old_menu_items ) ) {
|
97 |
+
foreach ( $this->_old_menu_items as $old_item ) {
|
98 |
+
if ( $old_item['menu_id'] == $menu_id ) {
|
99 |
+
$item_id = $old_item['item_id'];
|
100 |
+
if ( $item_id == $menu_item_db_id ) {
|
101 |
+
if ( $old_item['menu_order'] != $args['menu-item-position'] ) {
|
102 |
+
$is_changed_order = true;
|
103 |
+
}
|
104 |
+
if ( ! empty( $args['menu-item-parent-id'] ) ) {
|
105 |
+
$is_sub_item = true;
|
106 |
+
}
|
107 |
+
if ( ! empty( $args['menu-item-title'] ) && $old_item['title'] != $args['menu-item-title'] ) {
|
108 |
+
// Verify nonce.
|
109 |
+
if ( ! wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
110 |
+
return false;
|
111 |
+
}
|
112 |
+
|
113 |
+
$this->EventModifiedItems( $post_array['menu-item-object'][ $menu_item_db_id ], $post_array['menu-item-title'][ $menu_item_db_id ], $post_array['menu-name'] );
|
114 |
+
}
|
115 |
+
}
|
116 |
+
$old_menu_items[ $item_id ] = array(
|
117 |
+
'type' => $old_item['object'],
|
118 |
+
'title' => $old_item['title'],
|
119 |
+
'parent' => $old_item['menu_item_parent'],
|
120 |
+
);
|
121 |
+
}
|
122 |
+
}
|
123 |
+
}
|
124 |
+
if ( $is_changed_order && wp_verify_nonce( $post_array['meta-box-order-nonce'], 'meta-box-order' ) ) {
|
125 |
+
$item_name = $old_menu_items[ $menu_item_db_id ]['title'];
|
126 |
+
$this->EventChangeOrder( $item_name, $old_item['menu_name'] );
|
127 |
+
}
|
128 |
+
if ( $is_sub_item && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
129 |
+
$item_parent_id = $args['menu-item-parent-id'];
|
130 |
+
$item_name = $old_menu_items[ $menu_item_db_id ]['title'];
|
131 |
+
if ( $old_menu_items[ $menu_item_db_id ]['parent'] != $item_parent_id ) {
|
132 |
+
$parent_name = $old_menu_items[ $item_parent_id ]['title'];
|
133 |
+
$this->EventChangeSubItem( $item_name, $parent_name, $post_array['menu-name'] );
|
134 |
+
}
|
135 |
+
}
|
136 |
+
$added_items = array_diff( $new_menu_items, array_keys( $old_menu_items ) );
|
137 |
+
|
138 |
+
// Add Items to the menu.
|
139 |
+
if ( count( $added_items ) > 0 && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
140 |
+
if ( in_array( $menu_item_db_id, $added_items ) ) {
|
141 |
+
$this->EventAddItems( $post_array['menu-item-object'][ $menu_item_db_id ], $post_array['menu-item-title'][ $menu_item_db_id ], $post_array['menu-name'] );
|
142 |
+
}
|
143 |
+
}
|
144 |
+
$removed_items = array_diff( array_keys( $old_menu_items ), $new_menu_items );
|
145 |
+
|
146 |
+
// Remove items from the menu.
|
147 |
+
if ( count( $removed_items ) > 0 && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
148 |
+
if ( array_search( $menu_item_db_id, $new_menu_items ) == (count( $new_menu_items ) - 1) ) {
|
149 |
+
foreach ( $removed_items as $removed_item_id ) {
|
150 |
+
$this->EventRemoveItems( $old_menu_items[ $removed_item_id ]['type'], $old_menu_items[ $removed_item_id ]['title'], $post_array['menu-name'] );
|
151 |
+
}
|
152 |
+
}
|
153 |
+
}
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* New menu created.
|
159 |
+
*
|
160 |
+
* @param int $term_id - Term ID.
|
161 |
+
* @param array $menu_data - Menu data.
|
162 |
+
*/
|
163 |
+
public function CreateMenu( $term_id, $menu_data ) {
|
164 |
+
$this->plugin->alerts->Trigger(
|
165 |
+
2078, array(
|
166 |
+
'MenuName' => $menu_data['menu-name'],
|
167 |
+
)
|
168 |
+
);
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* New menu created.
|
173 |
+
*
|
174 |
+
* @global array $_POST Data post.
|
175 |
+
*/
|
176 |
+
public function ManageMenuLocations() {
|
177 |
+
// Filter $_POST global array for security.
|
178 |
+
$post_array = filter_input_array( INPUT_POST );
|
179 |
+
|
180 |
+
// Verify nonce.
|
181 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'save-menu-locations' ) ) {
|
182 |
+
return false;
|
183 |
+
}
|
184 |
+
|
185 |
+
// Manage Location tab.
|
186 |
+
if ( isset( $post_array['menu-locations'] ) ) {
|
187 |
+
$new_locations = $post_array['menu-locations'];
|
188 |
+
if ( isset( $new_locations['primary'] ) ) {
|
189 |
+
$this->LocationSetting( $new_locations['primary'], 'primary' );
|
190 |
+
}
|
191 |
+
if ( isset( $new_locations['social'] ) ) {
|
192 |
+
$this->LocationSetting( $new_locations['social'], 'social' );
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Menu location.
|
199 |
+
*
|
200 |
+
* @param integer $new_location - New location.
|
201 |
+
* @param string $type - Location type.
|
202 |
+
*/
|
203 |
+
private function LocationSetting( $new_location, $type ) {
|
204 |
+
$old_locations = get_nav_menu_locations();
|
205 |
+
if ( 0 != $new_location ) {
|
206 |
+
$menu = wp_get_nav_menu_object( $new_location );
|
207 |
+
if ( ! empty( $old_locations[ $type ] ) && $old_locations[ $type ] != $new_location ) {
|
208 |
+
$this->EventMenuSetting( $menu->name, 'Enabled', 'Location: ' . $type . ' menu' );
|
209 |
+
}
|
210 |
+
} else {
|
211 |
+
if ( ! empty( $old_locations[ $type ] ) ) {
|
212 |
+
$menu = wp_get_nav_menu_object( $old_locations[ $type ] );
|
213 |
+
$this->EventMenuSetting( $menu->name, 'Disabled', 'Location: ' . $type . ' menu' );
|
214 |
+
}
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Menu deleted.
|
220 |
+
*
|
221 |
+
* @param int $term_id - Term ID.
|
222 |
+
*/
|
223 |
+
public function DeleteMenu( $term_id ) {
|
224 |
+
if ( $this->_old_menu ) {
|
225 |
+
$this->plugin->alerts->Trigger(
|
226 |
+
2081, array(
|
227 |
+
'MenuName' => $this->_old_menu->name,
|
228 |
+
)
|
229 |
+
);
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Menu updated.
|
235 |
+
*
|
236 |
+
* @param int $menu_id - Menu ID.
|
237 |
+
* @param array $menu_data (Optional) Menu data.
|
238 |
+
*/
|
239 |
+
public function UpdateMenu( $menu_id, $menu_data = null ) {
|
240 |
+
if ( ! empty( $menu_data ) ) {
|
241 |
+
$content_names_old = array();
|
242 |
+
$content_types_old = array();
|
243 |
+
$content_order_old = array();
|
244 |
+
|
245 |
+
$items = wp_get_nav_menu_items( $menu_id );
|
246 |
+
if ( ! empty( $items ) ) {
|
247 |
+
foreach ( $items as $item ) {
|
248 |
+
array_push( $content_names_old, $item->title );
|
249 |
+
array_push( $content_types_old, $item->object );
|
250 |
+
$content_order_old[ $item->ID ] = $item->menu_order;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
// Filter $_POST global array for security.
|
255 |
+
$post_array = filter_input_array( INPUT_POST );
|
256 |
+
|
257 |
+
// Menu changed name.
|
258 |
+
if ( ! empty( $this->_old_menu_terms ) && isset( $post_array['menu'] ) && isset( $post_array['menu-name'] ) ) {
|
259 |
+
foreach ( $this->_old_menu_terms as $old_menu_term ) {
|
260 |
+
if ( $old_menu_term['term_id'] == $post_array['menu'] && wp_verify_nonce( $post_array['update-nav-menu-nonce'], 'update-nav_menu' ) ) {
|
261 |
+
if ( $old_menu_term['name'] != $post_array['menu-name'] ) {
|
262 |
+
$this->EventChangeName( $old_menu_term['name'], $post_array['menu-name'] );
|
263 |
+
} else {
|
264 |
+
// Remove the last menu item.
|
265 |
+
if ( count( $content_names_old ) == 1 && count( $content_types_old ) == 1 ) {
|
266 |
+
$this->EventRemoveItems( $content_types_old[0], $content_names_old[0], $post_array['menu-name'] );
|
267 |
+
}
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
}
|
272 |
+
|
273 |
+
// Enable/Disable menu setting.
|
274 |
+
$nav_menu_options = maybe_unserialize( get_option( 'nav_menu_options' ) );
|
275 |
+
$auto_add = null;
|
276 |
+
if ( isset( $nav_menu_options['auto_add'] ) ) {
|
277 |
+
if ( in_array( $menu_id, $nav_menu_options['auto_add'] ) ) {
|
278 |
+
if ( empty( $post_array['auto-add-pages'] ) ) {
|
279 |
+
$auto_add = 'Disabled';
|
280 |
+
}
|
281 |
+
} else {
|
282 |
+
if ( isset( $post_array['auto-add-pages'] ) ) {
|
283 |
+
$auto_add = 'Enabled';
|
284 |
+
}
|
285 |
+
}
|
286 |
+
} else {
|
287 |
+
if ( isset( $post_array['auto-add-pages'] ) ) {
|
288 |
+
$auto_add = 'Enabled';
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
// Alert 2082 Auto add pages.
|
293 |
+
if ( ! empty( $auto_add ) ) {
|
294 |
+
$this->EventMenuSetting( $menu_data['menu-name'], $auto_add, 'Auto add pages' );
|
295 |
+
}
|
296 |
+
|
297 |
+
$nav_menu_locations = get_nav_menu_locations();
|
298 |
+
|
299 |
+
$location_primary = null;
|
300 |
+
if ( isset( $this->_old_menu_locations['primary'] ) && isset( $nav_menu_locations['primary'] ) ) {
|
301 |
+
if ( $nav_menu_locations['primary'] == $menu_id && $this->_old_menu_locations['primary'] != $nav_menu_locations['primary'] ) {
|
302 |
+
$location_primary = 'Enabled';
|
303 |
+
}
|
304 |
+
} elseif ( empty( $this->_old_menu_locations['primary'] ) && isset( $nav_menu_locations['primary'] ) ) {
|
305 |
+
if ( $nav_menu_locations['primary'] == $menu_id ) {
|
306 |
+
$location_primary = 'Enabled';
|
307 |
+
}
|
308 |
+
} elseif ( isset( $this->_old_menu_locations['primary'] ) && empty( $nav_menu_locations['primary'] ) ) {
|
309 |
+
if ( $this->_old_menu_locations['primary'] == $menu_id ) {
|
310 |
+
$location_primary = 'Disabled';
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
// Alert 2082 Primary menu.
|
315 |
+
if ( ! empty( $location_primary ) ) {
|
316 |
+
$this->EventMenuSetting( $menu_data['menu-name'], $location_primary, 'Location: primary menu' );
|
317 |
+
}
|
318 |
+
|
319 |
+
$location_social = null;
|
320 |
+
if ( isset( $this->_old_menu_locations['social'] ) && isset( $nav_menu_locations['social'] ) ) {
|
321 |
+
if ( $nav_menu_locations['social'] == $menu_id && $this->_old_menu_locations['social'] != $nav_menu_locations['social'] ) {
|
322 |
+
$location_social = 'Enabled';
|
323 |
+
}
|
324 |
+
} elseif ( empty( $this->_old_menu_locations['social'] ) && isset( $nav_menu_locations['social'] ) ) {
|
325 |
+
if ( $nav_menu_locations['social'] == $menu_id ) {
|
326 |
+
$location_social = 'Enabled';
|
327 |
+
}
|
328 |
+
} elseif ( isset( $this->_old_menu_locations['social'] ) && empty( $nav_menu_locations['social'] ) ) {
|
329 |
+
if ( $this->_old_menu_locations['social'] == $menu_id ) {
|
330 |
+
$location_social = 'Disabled';
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
// Alert 2082 Social links menu.
|
335 |
+
if ( ! empty( $location_social ) ) {
|
336 |
+
$this->EventMenuSetting( $menu_data['menu-name'], $location_social, 'Location: social menu' );
|
337 |
+
}
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Set old menu terms and items.
|
343 |
+
*/
|
344 |
+
private function BuildOldMenuTermsAndItems() {
|
345 |
+
$menus = wp_get_nav_menus();
|
346 |
+
if ( ! empty( $menus ) ) {
|
347 |
+
foreach ( $menus as $menu ) {
|
348 |
+
array_push(
|
349 |
+
$this->_old_menu_terms, array(
|
350 |
+
'term_id' => $menu->term_id,
|
351 |
+
'name' => $menu->name,
|
352 |
+
)
|
353 |
+
);
|
354 |
+
$items = wp_get_nav_menu_items( $menu->term_id );
|
355 |
+
if ( ! empty( $items ) ) {
|
356 |
+
foreach ( $items as $item ) {
|
357 |
+
array_push(
|
358 |
+
$this->_old_menu_items, array(
|
359 |
+
'menu_id' => $menu->term_id,
|
360 |
+
'item_id' => $item->ID,
|
361 |
+
'title' => $item->title,
|
362 |
+
'object' => $item->object,
|
363 |
+
'menu_name' => $menu->name,
|
364 |
+
'menu_order' => $item->menu_order,
|
365 |
+
'url' => $item->url,
|
366 |
+
'menu_item_parent' => $item->menu_item_parent,
|
367 |
+
)
|
368 |
+
);
|
369 |
+
}
|
370 |
+
}
|
371 |
+
}
|
372 |
+
}
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Triggered when a user accesses the admin area.
|
377 |
+
*/
|
378 |
+
public function EventAdminInit() {
|
379 |
+
// Filter global arrays for security.
|
380 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
381 |
+
$get_array = filter_input_array( INPUT_GET );
|
382 |
+
|
383 |
+
$is_nav_menu = basename( $server_array['SCRIPT_NAME'] ) == 'nav-menus.php';
|
384 |
+
if ( $is_nav_menu ) {
|
385 |
+
if ( isset( $get_array['action'] ) && 'delete' == $get_array['action'] ) {
|
386 |
+
if ( isset( $get_array['menu'] ) ) {
|
387 |
+
$this->_old_menu = wp_get_nav_menu_object( $get_array['menu'] );
|
388 |
+
}
|
389 |
+
} else {
|
390 |
+
$this->BuildOldMenuTermsAndItems();
|
391 |
+
}
|
392 |
+
$this->_old_menu_locations = get_nav_menu_locations();
|
393 |
+
}
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* Customize set old data.
|
398 |
+
*/
|
399 |
+
public function CustomizeInit() {
|
400 |
+
$this->BuildOldMenuTermsAndItems();
|
401 |
+
$this->_old_menu_locations = get_nav_menu_locations();
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* Customize Events Function.
|
406 |
+
*/
|
407 |
+
public function CustomizeSave() {
|
408 |
+
$update_menus = array();
|
409 |
+
$menus = wp_get_nav_menus();
|
410 |
+
if ( ! empty( $menus ) ) {
|
411 |
+
foreach ( $menus as $menu ) {
|
412 |
+
array_push(
|
413 |
+
$update_menus, array(
|
414 |
+
'term_id' => $menu->term_id,
|
415 |
+
'name' => $menu->name,
|
416 |
+
)
|
417 |
+
);
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
// Deleted Menu.
|
422 |
+
if ( isset( $update_menus ) && isset( $this->_old_menu_terms ) ) {
|
423 |
+
$terms = array_diff( array_map( 'serialize', $this->_old_menu_terms ), array_map( 'serialize', $update_menus ) );
|
424 |
+
$terms = array_map( 'unserialize', $terms );
|
425 |
+
|
426 |
+
if ( isset( $terms ) && count( $terms ) > 0 ) {
|
427 |
+
foreach ( $terms as $term ) {
|
428 |
+
$this->plugin->alerts->Trigger(
|
429 |
+
2081, array(
|
430 |
+
'MenuName' => $term['name'],
|
431 |
+
)
|
432 |
+
);
|
433 |
+
}
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
// Filter $_POST global array for security.
|
438 |
+
$post_array = filter_input_array( INPUT_POST );
|
439 |
+
|
440 |
+
if ( isset( $post_array['action'] ) && 'customize_save' == $post_array['action'] ) {
|
441 |
+
if ( isset( $post_array['wp_customize'], $post_array['customized'] ) ) {
|
442 |
+
$customized = json_decode( wp_unslash( $post_array['customized'] ), true );
|
443 |
+
if ( is_array( $customized ) ) {
|
444 |
+
foreach ( $customized as $key => $value ) {
|
445 |
+
if ( ! empty( $value['nav_menu_term_id'] ) ) {
|
446 |
+
$is_occurred_event = false;
|
447 |
+
$menu = wp_get_nav_menu_object( $value['nav_menu_term_id'] );
|
448 |
+
$content_name = ! empty( $value['title'] ) ? $value['title'] : 'no title';
|
449 |
+
if ( ! empty( $this->_old_menu_items ) ) {
|
450 |
+
foreach ( $this->_old_menu_items as $old_item ) {
|
451 |
+
$item_id = substr( trim( $key, ']' ), 14 );
|
452 |
+
if ( $old_item['item_id'] == $item_id ) {
|
453 |
+
// Modified Items in the menu.
|
454 |
+
if ( $old_item['title'] != $content_name ) {
|
455 |
+
$is_occurred_event = true;
|
456 |
+
$this->EventModifiedItems( $value['type_label'], $content_name, $menu->name );
|
457 |
+
}
|
458 |
+
// Moved as a sub-item.
|
459 |
+
if ( $old_item['menu_item_parent'] != $value['menu_item_parent'] && 0 != $value['menu_item_parent'] ) {
|
460 |
+
$is_occurred_event = true;
|
461 |
+
$parent_name = $this->GetItemName( $value['nav_menu_term_id'], $value['menu_item_parent'] );
|
462 |
+
$this->EventChangeSubItem( $content_name, $parent_name, $menu->name );
|
463 |
+
}
|
464 |
+
// Changed order of the objects in a menu.
|
465 |
+
if ( $old_item['menu_order'] != $value['position'] ) {
|
466 |
+
$is_occurred_event = true;
|
467 |
+
$this->EventChangeOrder( $content_name, $menu->name );
|
468 |
+
}
|
469 |
+
}
|
470 |
+
}
|
471 |
+
}
|
472 |
+
// Add Items to the menu.
|
473 |
+
if ( ! $is_occurred_event ) {
|
474 |
+
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : $menu->name;
|
475 |
+
$this->EventAddItems( $value['type_label'], $content_name, $menu_name );
|
476 |
+
}
|
477 |
+
} else {
|
478 |
+
// Menu changed name.
|
479 |
+
if ( isset( $update_menus ) && isset( $this->_old_menu_terms ) ) {
|
480 |
+
foreach ( $this->_old_menu_terms as $old_menu ) {
|
481 |
+
foreach ( $update_menus as $update_menu ) {
|
482 |
+
if ( $old_menu['term_id'] == $update_menu['term_id'] && $old_menu['name'] != $update_menu['name'] ) {
|
483 |
+
$this->EventChangeName( $old_menu['name'], $update_menu['name'] );
|
484 |
+
}
|
485 |
+
}
|
486 |
+
}
|
487 |
+
}
|
488 |
+
// Setting Auto add pages.
|
489 |
+
if ( ! empty( $value ) && isset( $value['auto_add'] ) ) {
|
490 |
+
if ( $value['auto_add'] ) {
|
491 |
+
$this->EventMenuSetting( $value['name'], 'Enabled', 'Auto add pages' );
|
492 |
+
} else {
|
493 |
+
$this->EventMenuSetting( $value['name'], 'Disabled', 'Auto add pages' );
|
494 |
+
}
|
495 |
+
}
|
496 |
+
// Setting Location.
|
497 |
+
if ( false !== strpos( $key, 'nav_menu_locations[' ) ) {
|
498 |
+
$loc = substr( trim( $key, ']' ), 19 );
|
499 |
+
if ( ! empty( $value ) ) {
|
500 |
+
$menu = wp_get_nav_menu_object( $value );
|
501 |
+
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : ( ! empty( $menu ) ? $menu->name : '');
|
502 |
+
$this->EventMenuSetting( $menu_name, 'Enabled', 'Location: ' . $loc . ' menu' );
|
503 |
+
} else {
|
504 |
+
if ( ! empty( $this->_old_menu_locations[ $loc ] ) ) {
|
505 |
+
$menu = wp_get_nav_menu_object( $this->_old_menu_locations[ $loc ] );
|
506 |
+
$menu_name = ! empty( $customized['new_menu_name'] ) ? $customized['new_menu_name'] : ( ! empty( $menu ) ? $menu->name : '');
|
507 |
+
$this->EventMenuSetting( $menu_name, 'Disabled', 'Location: ' . $loc . ' menu' );
|
508 |
+
}
|
509 |
+
}
|
510 |
+
}
|
511 |
+
// Remove items from the menu.
|
512 |
+
if ( false !== strpos( $key, 'nav_menu_item[' ) ) {
|
513 |
+
$item_id = substr( trim( $key, ']' ), 14 );
|
514 |
+
if ( ! empty( $this->_old_menu_items ) ) {
|
515 |
+
foreach ( $this->_old_menu_items as $old_item ) {
|
516 |
+
if ( $old_item['item_id'] == $item_id ) {
|
517 |
+
$this->EventRemoveItems( $old_item['object'], $old_item['title'], $old_item['menu_name'] );
|
518 |
+
}
|
519 |
+
}
|
520 |
+
}
|
521 |
+
}
|
522 |
+
}
|
523 |
+
}
|
524 |
+
}
|
525 |
+
}
|
526 |
+
}
|
527 |
+
}
|
528 |
+
|
529 |
+
/**
|
530 |
+
* Added content to a menu.
|
531 |
+
*
|
532 |
+
* @param string $content_type - Type of content.
|
533 |
+
* @param string $content_name - Name of content.
|
534 |
+
* @param string $menu_name - Menu name.
|
535 |
+
*/
|
536 |
+
private function EventAddItems( $content_type, $content_name, $menu_name ) {
|
537 |
+
$this->plugin->alerts->Trigger(
|
538 |
+
2079, array(
|
539 |
+
'ContentType' => $content_type,
|
540 |
+
'ContentName' => $content_name,
|
541 |
+
'MenuName' => $menu_name,
|
542 |
+
)
|
543 |
+
);
|
544 |
+
}
|
545 |
+
|
546 |
+
/**
|
547 |
+
* Removed content from a menu.
|
548 |
+
*
|
549 |
+
* @param string $content_type - Type of content.
|
550 |
+
* @param string $content_name - Name of content.
|
551 |
+
* @param string $menu_name - Menu name.
|
552 |
+
*/
|
553 |
+
private function EventRemoveItems( $content_type, $content_name, $menu_name ) {
|
554 |
+
$this->plugin->alerts->Trigger(
|
555 |
+
2080, array(
|
556 |
+
'ContentType' => $content_type,
|
557 |
+
'ContentName' => $content_name,
|
558 |
+
'MenuName' => $menu_name,
|
559 |
+
)
|
560 |
+
);
|
561 |
+
}
|
562 |
+
|
563 |
+
/**
|
564 |
+
* Changed menu setting.
|
565 |
+
*
|
566 |
+
* @param string $menu_name - Menu Name.
|
567 |
+
* @param string $status - Status of menu.
|
568 |
+
* @param string $menu_setting - Menu setting.
|
569 |
+
*/
|
570 |
+
private function EventMenuSetting( $menu_name, $status, $menu_setting ) {
|
571 |
+
$this->plugin->alerts->Trigger(
|
572 |
+
2082, array(
|
573 |
+
'Status' => $status,
|
574 |
+
'MenuSetting' => $menu_setting,
|
575 |
+
'MenuName' => $menu_name,
|
576 |
+
)
|
577 |
+
);
|
578 |
+
}
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Modified content in a menu.
|
582 |
+
*
|
583 |
+
* @param string $content_type - Type of content.
|
584 |
+
* @param string $content_name - Name of content.
|
585 |
+
* @param string $menu_name - Menu name.
|
586 |
+
*/
|
587 |
+
private function EventModifiedItems( $content_type, $content_name, $menu_name ) {
|
588 |
+
$this->plugin->alerts->Trigger(
|
589 |
+
2083, array(
|
590 |
+
'ContentType' => $content_type,
|
591 |
+
'ContentName' => $content_name,
|
592 |
+
'MenuName' => $menu_name,
|
593 |
+
)
|
594 |
+
);
|
595 |
+
}
|
596 |
+
|
597 |
+
/**
|
598 |
+
* Changed name of a menu.
|
599 |
+
*
|
600 |
+
* @param string $old_menu_name - Old Menu Name.
|
601 |
+
* @param string $new_menu_name - New Menu Name.
|
602 |
+
*/
|
603 |
+
private function EventChangeName( $old_menu_name, $new_menu_name ) {
|
604 |
+
$this->plugin->alerts->Trigger(
|
605 |
+
2084, array(
|
606 |
+
'OldMenuName' => $old_menu_name,
|
607 |
+
'NewMenuName' => $new_menu_name,
|
608 |
+
)
|
609 |
+
);
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Changed order of the objects in a menu.
|
614 |
+
*
|
615 |
+
* @param string $item_name - Item name.
|
616 |
+
* @param string $menu_name - Menu name.
|
617 |
+
*/
|
618 |
+
private function EventChangeOrder( $item_name, $menu_name ) {
|
619 |
+
$this->plugin->alerts->Trigger(
|
620 |
+
2085, array(
|
621 |
+
'ItemName' => $item_name,
|
622 |
+
'MenuName' => $menu_name,
|
623 |
+
)
|
624 |
+
);
|
625 |
+
}
|
626 |
+
|
627 |
+
/**
|
628 |
+
* Moved objects as a sub-item.
|
629 |
+
*
|
630 |
+
* @param string $item_name - Item name.
|
631 |
+
* @param string $parent_name - Parent Name.
|
632 |
+
* @param string $menu_name - Menu Name.
|
633 |
+
*/
|
634 |
+
private function EventChangeSubItem( $item_name, $parent_name, $menu_name ) {
|
635 |
+
$this->plugin->alerts->Trigger(
|
636 |
+
2089, array(
|
637 |
+
'ItemName' => $item_name,
|
638 |
+
'ParentName' => $parent_name,
|
639 |
+
'MenuName' => $menu_name,
|
640 |
+
)
|
641 |
+
);
|
642 |
+
}
|
643 |
+
|
644 |
+
/**
|
645 |
+
* Get menu item name.
|
646 |
+
*
|
647 |
+
* @param int $term_id - Term ID.
|
648 |
+
* @param int $item_id - Item ID.
|
649 |
+
*/
|
650 |
+
private function GetItemName( $term_id, $item_id ) {
|
651 |
+
$item_name = '';
|
652 |
+
$menu_items = wp_get_nav_menu_items( $term_id );
|
653 |
+
foreach ( $menu_items as $menu_item ) {
|
654 |
+
if ( $menu_item->ID == $item_id ) {
|
655 |
+
$item_name = $menu_item->title;
|
656 |
+
break;
|
657 |
+
}
|
658 |
+
}
|
659 |
+
return $item_name;
|
660 |
+
}
|
661 |
}
|
classes/Sensors/MetaData.php
CHANGED
@@ -1,4 +1,18 @@
|
|
1 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
/**
|
3 |
* Custom fields (posts, pages, custom posts and users) sensor.
|
4 |
*
|
@@ -61,7 +75,7 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
61 |
/**
|
62 |
* Check "Excluded Custom Fields" or meta keys starts with "_".
|
63 |
*
|
64 |
-
* @param int
|
65 |
* @param string $meta_key - Meta key.
|
66 |
* @return boolean can log true|false
|
67 |
*/
|
@@ -84,14 +98,14 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
84 |
* @return boolean is excluded from monitoring true|false
|
85 |
*/
|
86 |
public function IsExcludedCustomFields( $custom ) {
|
87 |
-
$
|
88 |
-
if ( in_array( $custom, $
|
89 |
return true;
|
90 |
}
|
91 |
-
foreach ( $
|
92 |
-
if ( false !== strpos( $field,
|
93 |
-
//
|
94 |
-
if ( substr( $field, -1 ) == '*') {
|
95 |
$field = rtrim( $field, '*' );
|
96 |
if ( preg_match( "/^$field/", $custom ) ) {
|
97 |
return true;
|
@@ -107,15 +121,15 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
107 |
}
|
108 |
}
|
109 |
return false;
|
110 |
-
// return (in_array($custom, $
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
* Created a custom field.
|
115 |
*
|
116 |
-
* @param int
|
117 |
* @param string $meta_key - Meta key.
|
118 |
-
* @param mix
|
119 |
*/
|
120 |
public function EventPostMetaCreated( $object_id, $meta_key, $meta_value ) {
|
121 |
$post = get_post( $object_id );
|
@@ -129,45 +143,61 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
129 |
|
130 |
if ( empty( $meta_value ) && ( $this->null_meta_counter < 1 ) ) { // Report only one NULL meta value.
|
131 |
$this->null_meta_counter += 1;
|
132 |
-
}
|
133 |
return;
|
134 |
}
|
135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
$wp_action = array( 'add-meta' );
|
137 |
|
138 |
-
if ( isset( $
|
139 |
-
$
|
140 |
switch ( $post->post_type ) {
|
141 |
case 'page':
|
142 |
-
$this->plugin->alerts->Trigger(
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
|
|
150 |
break;
|
151 |
case 'post':
|
152 |
-
$this->plugin->alerts->Trigger(
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
|
|
|
|
160 |
break;
|
161 |
default:
|
162 |
-
$this->plugin->alerts->Trigger(
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
171 |
break;
|
172 |
}
|
173 |
}
|
@@ -176,8 +206,8 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
176 |
/**
|
177 |
* Sets the old meta.
|
178 |
*
|
179 |
-
* @param int
|
180 |
-
* @param int
|
181 |
* @param string $meta_key - Meta key.
|
182 |
*/
|
183 |
public function EventPostMetaUpdating( $meta_id, $object_id, $meta_key ) {
|
@@ -191,10 +221,10 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
191 |
/**
|
192 |
* Updated a custom field name/value.
|
193 |
*
|
194 |
-
* @param int
|
195 |
-
* @param int
|
196 |
* @param string $meta_key - Meta key.
|
197 |
-
* @param mix
|
198 |
*/
|
199 |
public function EventPostMetaUpdated( $meta_id, $object_id, $meta_key, $meta_value ) {
|
200 |
$post = get_post( $object_id );
|
@@ -206,90 +236,112 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
206 |
return;
|
207 |
}
|
208 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
$wp_action = array( 'add-meta' );
|
210 |
|
211 |
-
if ( isset( $
|
212 |
-
$
|
213 |
if ( isset( $this->old_meta[ $meta_id ] ) ) {
|
214 |
// Check change in meta key.
|
215 |
if ( $this->old_meta[ $meta_id ]->key != $meta_key ) {
|
216 |
switch ( $post->post_type ) {
|
217 |
case 'page':
|
218 |
-
$this->plugin->alerts->Trigger(
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
|
|
|
|
228 |
break;
|
229 |
case 'post':
|
230 |
-
$this->plugin->alerts->Trigger(
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
|
|
|
|
240 |
break;
|
241 |
default:
|
242 |
-
$this->plugin->alerts->Trigger(
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
|
|
253 |
break;
|
254 |
}
|
255 |
} elseif ( $this->old_meta[ $meta_id ]->val != $meta_value ) { // Check change in meta value.
|
256 |
switch ( $post->post_type ) {
|
257 |
case 'page':
|
258 |
-
$this->plugin->alerts->Trigger(
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
|
|
|
|
268 |
break;
|
269 |
case 'post':
|
270 |
-
$this->plugin->alerts->Trigger(
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
|
|
|
|
280 |
break;
|
281 |
default:
|
282 |
-
$this->plugin->alerts->Trigger(
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
|
|
|
|
293 |
break;
|
294 |
}
|
295 |
}
|
@@ -302,10 +354,10 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
302 |
/**
|
303 |
* Deleted a custom field.
|
304 |
*
|
305 |
-
* @param int
|
306 |
-
* @param int
|
307 |
* @param string $meta_key - Meta key.
|
308 |
-
* @param mix
|
309 |
*/
|
310 |
public function EventPostMetaDeleted( $meta_ids, $object_id, $meta_key, $meta_value ) {
|
311 |
|
@@ -316,45 +368,61 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
316 |
|
317 |
$post = get_post( $object_id );
|
318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
$wp_action = array( 'delete-meta' );
|
320 |
|
321 |
-
if ( isset( $
|
322 |
-
$
|
323 |
foreach ( $meta_ids as $meta_id ) {
|
324 |
if ( ! $this->CanLogMetaKey( $object_id, $meta_key ) ) {
|
325 |
continue;
|
326 |
}
|
327 |
switch ( $post->post_type ) {
|
328 |
case 'page':
|
329 |
-
$this->plugin->alerts->Trigger(
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
|
|
|
|
337 |
break;
|
338 |
case 'post':
|
339 |
-
$this->plugin->alerts->Trigger(
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
347 |
break;
|
348 |
default:
|
349 |
-
$this->plugin->alerts->Trigger(
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
|
|
|
|
358 |
break;
|
359 |
}
|
360 |
}
|
@@ -373,26 +441,26 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
373 |
/**
|
374 |
* Get editor link.
|
375 |
*
|
376 |
-
* @param stdClass $post
|
377 |
-
* @return array $
|
378 |
*/
|
379 |
private function GetEditorLink( $post ) {
|
380 |
$name = 'EditorLink';
|
381 |
$name .= ( 'page' == $post->post_type ) ? 'Page' : 'Post';
|
382 |
$value = get_edit_post_link( $post->ID );
|
383 |
-
$
|
384 |
'name' => $name,
|
385 |
'value' => $value,
|
386 |
);
|
387 |
-
return $
|
388 |
}
|
389 |
|
390 |
/**
|
391 |
* Create a custom field name/value.
|
392 |
*
|
393 |
-
* @param int
|
394 |
* @param string $meta_key - Meta key.
|
395 |
-
* @param mix
|
396 |
*/
|
397 |
public function event_user_meta_created( $object_id, $meta_key, $meta_value ) {
|
398 |
|
@@ -406,28 +474,35 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
406 |
|
407 |
if ( empty( $meta_value ) && ( $this->null_meta_counter < 1 ) ) { // Report only one NULL meta value.
|
408 |
$this->null_meta_counter += 1;
|
409 |
-
}
|
410 |
return;
|
411 |
}
|
412 |
|
413 |
-
//
|
414 |
-
$post_array =
|
|
|
|
|
|
|
|
|
|
|
415 |
|
416 |
// If update action is set then trigger the alert.
|
417 |
if ( isset( $post_array['action'] ) && ( 'update' == $post_array['action'] || 'createuser' == $post_array['action'] ) ) {
|
418 |
-
$this->plugin->alerts->Trigger(
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
|
|
|
|
423 |
}
|
424 |
}
|
425 |
|
426 |
/**
|
427 |
* Sets the old meta.
|
428 |
*
|
429 |
-
* @param int
|
430 |
-
* @param int
|
431 |
* @param string $meta_key - Meta key.
|
432 |
*/
|
433 |
public function event_user_meta_updating( $meta_id, $object_id, $meta_key ) {
|
@@ -459,20 +534,27 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
459 |
// User profile name related meta.
|
460 |
$username_meta = array( 'first_name', 'last_name', 'nickname' );
|
461 |
|
462 |
-
//
|
463 |
-
$post_array =
|
|
|
|
|
|
|
|
|
|
|
464 |
|
465 |
// If update action is set then trigger the alert.
|
466 |
if ( isset( $post_array['action'] ) && 'update' == $post_array['action'] ) {
|
467 |
if ( isset( $this->old_meta[ $meta_id ] ) && ! in_array( $meta_key, $username_meta, true ) ) {
|
468 |
// Check change in meta value.
|
469 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
470 |
-
$this->plugin->alerts->Trigger(
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
|
|
|
|
476 |
}
|
477 |
// Remove old meta update data.
|
478 |
unset( $this->old_meta[ $meta_id ] );
|
@@ -481,31 +563,37 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
481 |
switch ( $meta_key ) {
|
482 |
case 'first_name':
|
483 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
484 |
-
$this->plugin->alerts->Trigger(
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
|
|
|
|
489 |
}
|
490 |
break;
|
491 |
|
492 |
case 'last_name':
|
493 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
494 |
-
$this->plugin->alerts->Trigger(
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
|
|
|
|
499 |
}
|
500 |
break;
|
501 |
|
502 |
case 'nickname':
|
503 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
504 |
-
$this->plugin->alerts->Trigger(
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
|
|
|
|
509 |
}
|
510 |
break;
|
511 |
|
@@ -534,11 +622,13 @@ class WSAL_Sensors_MetaData extends WSAL_AbstractSensor {
|
|
534 |
|
535 |
// Alert if display name is changed.
|
536 |
if ( $old_display_name !== $new_display_name ) {
|
537 |
-
$this->plugin->alerts->Trigger(
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
|
|
|
|
542 |
}
|
543 |
|
544 |
}
|
1 |
<?php
|
2 |
+
/**
|
3 |
+
* Sensor: Meta Data
|
4 |
+
*
|
5 |
+
* Meta Data sensor file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* Custom fields (posts, pages, custom posts and users) sensor.
|
18 |
*
|
75 |
/**
|
76 |
* Check "Excluded Custom Fields" or meta keys starts with "_".
|
77 |
*
|
78 |
+
* @param int $object_id - Object ID.
|
79 |
* @param string $meta_key - Meta key.
|
80 |
* @return boolean can log true|false
|
81 |
*/
|
98 |
* @return boolean is excluded from monitoring true|false
|
99 |
*/
|
100 |
public function IsExcludedCustomFields( $custom ) {
|
101 |
+
$custom_fields = $this->plugin->settings->GetExcludedMonitoringCustom();
|
102 |
+
if ( in_array( $custom, $custom_fields ) ) {
|
103 |
return true;
|
104 |
}
|
105 |
+
foreach ( $custom_fields as $field ) {
|
106 |
+
if ( false !== strpos( $field, '*' ) ) {
|
107 |
+
// Wildcard str[any_character] when you enter (str*).
|
108 |
+
if ( substr( $field, -1 ) == '*' ) {
|
109 |
$field = rtrim( $field, '*' );
|
110 |
if ( preg_match( "/^$field/", $custom ) ) {
|
111 |
return true;
|
121 |
}
|
122 |
}
|
123 |
return false;
|
124 |
+
// return (in_array($custom, $custom_fields)) ? true : false;.
|
125 |
}
|
126 |
|
127 |
/**
|
128 |
* Created a custom field.
|
129 |
*
|
130 |
+
* @param int $object_id - Object ID.
|
131 |
* @param string $meta_key - Meta key.
|
132 |
+
* @param mix $meta_value - Meta value.
|
133 |
*/
|
134 |
public function EventPostMetaCreated( $object_id, $meta_key, $meta_value ) {
|
135 |
$post = get_post( $object_id );
|
143 |
|
144 |
if ( empty( $meta_value ) && ( $this->null_meta_counter < 1 ) ) { // Report only one NULL meta value.
|
145 |
$this->null_meta_counter += 1;
|
146 |
+
} elseif ( $this->null_meta_counter >= 1 ) { // Do not report if NULL meta values are more than one.
|
147 |
return;
|
148 |
}
|
149 |
|
150 |
+
// Filter $_POST global array for security.
|
151 |
+
$post_array = filter_input_array( INPUT_POST );
|
152 |
+
|
153 |
+
// Check nonce.
|
154 |
+
if ( isset( $post_array['_ajax_nonce-add-meta'] ) && ! wp_verify_nonce( $post_array['_ajax_nonce-add-meta'], 'add-meta' ) ) {
|
155 |
+
return false;
|
156 |
+
} elseif ( isset( $post_array['_wpnonce'] ) && isset( $post_array['post_ID'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
157 |
+
return false;
|
158 |
+
}
|
159 |
+
|
160 |
$wp_action = array( 'add-meta' );
|
161 |
|
162 |
+
if ( isset( $post_array['action'] ) && ( 'editpost' == $post_array['action'] || in_array( $post_array['action'], $wp_action ) ) ) {
|
163 |
+
$editor_link = $this->GetEditorLink( $post );
|
164 |
switch ( $post->post_type ) {
|
165 |
case 'page':
|
166 |
+
$this->plugin->alerts->Trigger(
|
167 |
+
2059, array(
|
168 |
+
'PostID' => $object_id,
|
169 |
+
'PostTitle' => $post->post_title,
|
170 |
+
'MetaKey' => $meta_key,
|
171 |
+
'MetaValue' => $meta_value,
|
172 |
+
'MetaLink' => $meta_key,
|
173 |
+
$editor_link['name'] => $editor_link['value'],
|
174 |
+
)
|
175 |
+
);
|
176 |
break;
|
177 |
case 'post':
|
178 |
+
$this->plugin->alerts->Trigger(
|
179 |
+
2053, array(
|
180 |
+
'PostID' => $object_id,
|
181 |
+
'PostTitle' => $post->post_title,
|
182 |
+
'MetaKey' => $meta_key,
|
183 |
+
'MetaValue' => $meta_value,
|
184 |
+
'MetaLink' => $meta_key,
|
185 |
+
$editor_link['name'] => $editor_link['value'],
|
186 |
+
)
|
187 |
+
);
|
188 |
break;
|
189 |
default:
|
190 |
+
$this->plugin->alerts->Trigger(
|
191 |
+
2056, array(
|
192 |
+
'PostID' => $object_id,
|
193 |
+
'PostTitle' => $post->post_title,
|
194 |
+
'PostType' => $post->post_type,
|
195 |
+
'MetaKey' => $meta_key,
|
196 |
+
'MetaValue' => $meta_value,
|
197 |
+
'MetaLink' => $meta_key,
|
198 |
+
$editor_link['name'] => $editor_link['value'],
|
199 |
+
)
|
200 |
+
);
|
201 |
break;
|
202 |
}
|
203 |
}
|
206 |
/**
|
207 |
* Sets the old meta.
|
208 |
*
|
209 |
+
* @param int $meta_id - Meta ID.
|
210 |
+
* @param int $object_id - Object ID.
|
211 |
* @param string $meta_key - Meta key.
|
212 |
*/
|
213 |
public function EventPostMetaUpdating( $meta_id, $object_id, $meta_key ) {
|
221 |
/**
|
222 |
* Updated a custom field name/value.
|
223 |
*
|
224 |
+
* @param int $meta_id - Meta ID.
|
225 |
+
* @param int $object_id - Object ID.
|
226 |
* @param string $meta_key - Meta key.
|
227 |
+
* @param mix $meta_value - Meta value.
|
228 |
*/
|
229 |
public function EventPostMetaUpdated( $meta_id, $object_id, $meta_key, $meta_value ) {
|
230 |
$post = get_post( $object_id );
|
236 |
return;
|
237 |
}
|
238 |
|
239 |
+
// Filter $_POST global array for security.
|
240 |
+
$post_array = filter_input_array( INPUT_POST );
|
241 |
+
|
242 |
+
// Check nonce.
|
243 |
+
if ( isset( $post_array['_ajax_nonce'] ) && ! wp_verify_nonce( $post_array['_ajax_nonce'], 'change-meta' ) ) {
|
244 |
+
return false;
|
245 |
+
} elseif ( isset( $post_array['_wpnonce'] ) && isset( $post_array['post_ID'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
246 |
+
return false;
|
247 |
+
}
|
248 |
+
|
249 |
$wp_action = array( 'add-meta' );
|
250 |
|
251 |
+
if ( isset( $post_array['action'] ) && ( 'editpost' == $post_array['action'] || in_array( $post_array['action'], $wp_action ) ) ) {
|
252 |
+
$editor_link = $this->GetEditorLink( $post );
|
253 |
if ( isset( $this->old_meta[ $meta_id ] ) ) {
|
254 |
// Check change in meta key.
|
255 |
if ( $this->old_meta[ $meta_id ]->key != $meta_key ) {
|
256 |
switch ( $post->post_type ) {
|
257 |
case 'page':
|
258 |
+
$this->plugin->alerts->Trigger(
|
259 |
+
2064, array(
|
260 |
+
'PostID' => $object_id,
|
261 |
+
'PostTitle' => $post->post_title,
|
262 |
+
'MetaID' => $meta_id,
|
263 |
+
'MetaKeyNew' => $meta_key,
|
264 |
+
'MetaKeyOld' => $this->old_meta[ $meta_id ]->key,
|
265 |
+
'MetaValue' => $meta_value,
|
266 |
+
'MetaLink' => $meta_key,
|
267 |
+
$editor_link['name'] => $editor_link['value'],
|
268 |
+
)
|
269 |
+
);
|
270 |
break;
|
271 |
case 'post':
|
272 |
+
$this->plugin->alerts->Trigger(
|
273 |
+
2062, array(
|
274 |
+
'PostID' => $object_id,
|
275 |
+
'PostTitle' => $post->post_title,
|
276 |
+
'MetaID' => $meta_id,
|
277 |
+
'MetaKeyNew' => $meta_key,
|
278 |
+
'MetaKeyOld' => $this->old_meta[ $meta_id ]->key,
|
279 |
+
'MetaValue' => $meta_value,
|
280 |
+
'MetaLink' => $meta_key,
|
281 |
+
$editor_link['name'] => $editor_link['value'],
|
282 |
+
)
|
283 |
+
);
|
284 |
break;
|
285 |
default:
|
286 |
+
$this->plugin->alerts->Trigger(
|
287 |
+
2063, array(
|
288 |
+
'PostID' => $object_id,
|
289 |
+
'PostTitle' => $post->post_title,
|
290 |
+
'PostType' => $post->post_type,
|
291 |
+
'MetaID' => $meta_id,
|
292 |
+
'MetaKeyNew' => $meta_key,
|
293 |
+
'MetaKeyOld' => $this->old_meta[ $meta_id ]->key,
|
294 |
+
'MetaValue' => $meta_value,
|
295 |
+
'MetaLink' => $smeta_key,
|
296 |
+
$editor_link['name'] => $editor_link['value'],
|
297 |
+
)
|
298 |
+
);
|
299 |
break;
|
300 |
}
|
301 |
} elseif ( $this->old_meta[ $meta_id ]->val != $meta_value ) { // Check change in meta value.
|
302 |
switch ( $post->post_type ) {
|
303 |
case 'page':
|
304 |
+
$this->plugin->alerts->Trigger(
|
305 |
+
2060, array(
|
306 |
+
'PostID' => $object_id,
|
307 |
+
'PostTitle' => $post->post_title,
|
308 |
+
'MetaID' => $meta_id,
|
309 |
+
'MetaKey' => $meta_key,
|
310 |
+
'MetaValueNew' => $meta_value,
|
311 |
+
'MetaValueOld' => $this->old_meta[ $meta_id ]->val,
|
312 |
+
'MetaLink' => $meta_key,
|
313 |
+
$editor_link['name'] => $editor_link['value'],
|
314 |
+
)
|
315 |
+
);
|
316 |
break;
|
317 |
case 'post':
|
318 |
+
$this->plugin->alerts->Trigger(
|
319 |
+
2054, array(
|
320 |
+
'PostID' => $object_id,
|
321 |
+
'PostTitle' => $post->post_title,
|
322 |
+
'MetaID' => $meta_id,
|
323 |
+
'MetaKey' => $meta_key,
|
324 |
+
'MetaValueNew' => $meta_value,
|
325 |
+
'MetaValueOld' => $this->old_meta[ $meta_id ]->val,
|
326 |
+
'MetaLink' => $meta_key,
|
327 |
+
$editor_link['name'] => $editor_link['value'],
|
328 |
+
)
|
329 |
+
);
|
330 |
break;
|
331 |
default:
|
332 |
+
$this->plugin->alerts->Trigger(
|
333 |
+
2057, array(
|
334 |
+
'PostID' => $object_id,
|
335 |
+
'PostTitle' => $post->post_title,
|
336 |
+
'PostType' => $post->post_type,
|
337 |
+
'MetaID' => $meta_id,
|
338 |
+
'MetaKey' => $meta_key,
|
339 |
+
'MetaValueNew' => $meta_value,
|
340 |
+
'MetaValueOld' => $this->old_meta[ $meta_id ]->val,
|
341 |
+
'MetaLink' => $meta_key,
|
342 |
+
$editor_link['name'] => $editor_link['value'],
|
343 |
+
)
|
344 |
+
);
|
345 |
break;
|
346 |
}
|
347 |
}
|
354 |
/**
|
355 |
* Deleted a custom field.
|
356 |
*
|
357 |
+
* @param int $meta_ids - Meta IDs.
|
358 |
+
* @param int $object_id - Object ID.
|
359 |
* @param string $meta_key - Meta key.
|
360 |
+
* @param mix $meta_value - Meta value.
|
361 |
*/
|
362 |
public function EventPostMetaDeleted( $meta_ids, $object_id, $meta_key, $meta_value ) {
|
363 |
|
368 |
|
369 |
$post = get_post( $object_id );
|
370 |
|
371 |
+
// Filter $_POST global array for security.
|
372 |
+
$post_array = filter_input_array( INPUT_POST );
|
373 |
+
|
374 |
+
// Check nonce.
|
375 |
+
if ( isset( $post_array['_ajax_nonce'] ) && ! wp_verify_nonce( $post_array['_ajax_nonce'], 'delete-meta_' . $post_array['id'] ) ) {
|
376 |
+
return false;
|
377 |
+
} elseif ( isset( $post_array['_wpnonce'] ) && isset( $post_array['post_ID'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
378 |
+
return false;
|
379 |
+
}
|
380 |
+
|
381 |
$wp_action = array( 'delete-meta' );
|
382 |
|
383 |
+
if ( isset( $post_array['action'] ) && in_array( $post_array['action'], $wp_action ) ) {
|
384 |
+
$editor_link = $this->GetEditorLink( $post );
|
385 |
foreach ( $meta_ids as $meta_id ) {
|
386 |
if ( ! $this->CanLogMetaKey( $object_id, $meta_key ) ) {
|
387 |
continue;
|
388 |
}
|
389 |
switch ( $post->post_type ) {
|
390 |
case 'page':
|
391 |
+
$this->plugin->alerts->Trigger(
|
392 |
+
2061, array(
|
393 |
+
'PostID' => $object_id,
|
394 |
+
'PostTitle' => $post->post_title,
|
395 |
+
'MetaID' => $meta_id,
|
396 |
+
'MetaKey' => $meta_key,
|
397 |
+
'MetaValue' => $meta_value,
|
398 |
+
$editor_link['name'] => $editor_link['value'],
|
399 |
+
)
|
400 |
+
);
|
401 |
break;
|
402 |
case 'post':
|
403 |
+
$this->plugin->alerts->Trigger(
|
404 |
+
2055, array(
|
405 |
+
'PostID' => $object_id,
|
406 |
+
'PostTitle' => $post->post_title,
|
407 |
+
'MetaID' => $meta_id,
|
408 |
+
'MetaKey' => $meta_key,
|
409 |
+
'MetaValue' => $meta_value,
|
410 |
+
$editor_link['name'] => $editor_link['value'],
|
411 |
+
)
|
412 |
+
);
|
413 |
break;
|
414 |
default:
|
415 |
+
$this->plugin->alerts->Trigger(
|
416 |
+
2058, array(
|
417 |
+
'PostID' => $object_id,
|
418 |
+
'PostTitle' => $post->post_title,
|
419 |
+
'PostType' => $post->post_type,
|
420 |
+
'MetaID' => $meta_id,
|
421 |
+
'MetaKey' => $meta_key,
|
422 |
+
'MetaValue' => $meta_value,
|
423 |
+
$editor_link['name'] => $editor_link['value'],
|
424 |
+
)
|
425 |
+
);
|
426 |
break;
|
427 |
}
|
428 |
}
|
441 |
/**
|
442 |
* Get editor link.
|
443 |
*
|
444 |
+
* @param stdClass $post - The post.
|
445 |
+
* @return array $editor_link - Name and value link
|
446 |
*/
|
447 |
private function GetEditorLink( $post ) {
|
448 |
$name = 'EditorLink';
|
449 |
$name .= ( 'page' == $post->post_type ) ? 'Page' : 'Post';
|
450 |
$value = get_edit_post_link( $post->ID );
|
451 |
+
$editor_link = array(
|
452 |
'name' => $name,
|
453 |
'value' => $value,
|
454 |
);
|
455 |
+
return $editor_link;
|
456 |
}
|
457 |
|
458 |
/**
|
459 |
* Create a custom field name/value.
|
460 |
*
|
461 |
+
* @param int $object_id - Object ID.
|
462 |
* @param string $meta_key - Meta key.
|
463 |
+
* @param mix $meta_value - Meta value.
|
464 |
*/
|
465 |
public function event_user_meta_created( $object_id, $meta_key, $meta_value ) {
|
466 |
|
474 |
|
475 |
if ( empty( $meta_value ) && ( $this->null_meta_counter < 1 ) ) { // Report only one NULL meta value.
|
476 |
$this->null_meta_counter += 1;
|
477 |
+
} elseif ( $this->null_meta_counter >= 1 ) { // Do not report if NULL meta values are more than one.
|
478 |
return;
|
479 |
}
|
480 |
|
481 |
+
// Filter $_POST global array for security.
|
482 |
+
$post_array = filter_input_array( INPUT_POST );
|
483 |
+
|
484 |
+
// Check nonce.
|
485 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update-user_' . $user->ID ) ) {
|
486 |
+
return false;
|
487 |
+
}
|
488 |
|
489 |
// If update action is set then trigger the alert.
|
490 |
if ( isset( $post_array['action'] ) && ( 'update' == $post_array['action'] || 'createuser' == $post_array['action'] ) ) {
|
491 |
+
$this->plugin->alerts->Trigger(
|
492 |
+
4016, array(
|
493 |
+
'TargetUsername' => $user->user_login,
|
494 |
+
'custom_field_name' => $meta_key,
|
495 |
+
'new_value' => $meta_value,
|
496 |
+
)
|
497 |
+
);
|
498 |
}
|
499 |
}
|
500 |
|
501 |
/**
|
502 |
* Sets the old meta.
|
503 |
*
|
504 |
+
* @param int $meta_id - Meta ID.
|
505 |
+
* @param int $object_id - Object ID.
|
506 |
* @param string $meta_key - Meta key.
|
507 |
*/
|
508 |
public function event_user_meta_updating( $meta_id, $object_id, $meta_key ) {
|
534 |
// User profile name related meta.
|
535 |
$username_meta = array( 'first_name', 'last_name', 'nickname' );
|
536 |
|
537 |
+
// Filter $_POST global array for security.
|
538 |
+
$post_array = filter_input_array( INPUT_POST );
|
539 |
+
|
540 |
+
// Check nonce.
|
541 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update-user_' . $user->ID ) ) {
|
542 |
+
return false;
|
543 |
+
}
|
544 |
|
545 |
// If update action is set then trigger the alert.
|
546 |
if ( isset( $post_array['action'] ) && 'update' == $post_array['action'] ) {
|
547 |
if ( isset( $this->old_meta[ $meta_id ] ) && ! in_array( $meta_key, $username_meta, true ) ) {
|
548 |
// Check change in meta value.
|
549 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
550 |
+
$this->plugin->alerts->Trigger(
|
551 |
+
4015, array(
|
552 |
+
'TargetUsername' => $user->user_login,
|
553 |
+
'custom_field_name' => $meta_key,
|
554 |
+
'new_value' => $meta_value,
|
555 |
+
'old_value' => $this->old_meta[ $meta_id ]->val,
|
556 |
+
)
|
557 |
+
);
|
558 |
}
|
559 |
// Remove old meta update data.
|
560 |
unset( $this->old_meta[ $meta_id ] );
|
563 |
switch ( $meta_key ) {
|
564 |
case 'first_name':
|
565 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
566 |
+
$this->plugin->alerts->Trigger(
|
567 |
+
4017, array(
|
568 |
+
'TargetUsername' => $user->user_login,
|
569 |
+
'new_firstname' => $meta_value,
|
570 |
+
'old_firstname' => $this->old_meta[ $meta_id ]->val,
|
571 |
+
)
|
572 |
+
);
|
573 |
}
|
574 |
break;
|
575 |
|
576 |
case 'last_name':
|
577 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
578 |
+
$this->plugin->alerts->Trigger(
|
579 |
+
4018, array(
|
580 |
+
'TargetUsername' => $user->user_login,
|
581 |
+
'new_lastname' => $meta_value,
|
582 |
+
'old_lastname' => $this->old_meta[ $meta_id ]->val,
|
583 |
+
)
|
584 |
+
);
|
585 |
}
|
586 |
break;
|
587 |
|
588 |
case 'nickname':
|
589 |
if ( $this->old_meta[ $meta_id ]->val != $meta_value ) {
|
590 |
+
$this->plugin->alerts->Trigger(
|
591 |
+
4019, array(
|
592 |
+
'TargetUsername' => $user->user_login,
|
593 |
+
'new_nickname' => $meta_value,
|
594 |
+
'old_nickname' => $this->old_meta[ $meta_id ]->val,
|
595 |
+
)
|
596 |
+
);
|
597 |
}
|
598 |
break;
|
599 |
|
622 |
|
623 |
// Alert if display name is changed.
|
624 |
if ( $old_display_name !== $new_display_name ) {
|
625 |
+
$this->plugin->alerts->Trigger(
|
626 |
+
4020, array(
|
627 |
+
'TargetUsername' => $new_userdata->user_login,
|
628 |
+
'new_displayname' => $new_display_name,
|
629 |
+
'old_displayname' => $old_display_name,
|
630 |
+
)
|
631 |
+
);
|
632 |
}
|
633 |
|
634 |
}
|
classes/Sensors/Multisite.php
CHANGED
@@ -1,8 +1,20 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*
|
7 |
* 4010 Existing user added to a site
|
8 |
* 4011 User removed from site
|
@@ -15,186 +27,223 @@
|
|
15 |
* 7005 Existing site deleted from network
|
16 |
* 5008 Activated theme on network
|
17 |
* 5009 Deactivated theme from network
|
|
|
|
|
|
|
18 |
*/
|
19 |
-
class WSAL_Sensors_Multisite extends WSAL_AbstractSensor
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Multisite
|
4 |
+
*
|
5 |
+
* Multisite sensor file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Multisite Sensor.
|
18 |
*
|
19 |
* 4010 Existing user added to a site
|
20 |
* 4011 User removed from site
|
27 |
* 7005 Existing site deleted from network
|
28 |
* 5008 Activated theme on network
|
29 |
* 5009 Deactivated theme from network
|
30 |
+
*
|
31 |
+
* @package Wsal
|
32 |
+
* @subpackage Sensors
|
33 |
*/
|
34 |
+
class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Allowed Themes.
|
38 |
+
*
|
39 |
+
* @var array
|
40 |
+
*/
|
41 |
+
protected $old_allowedthemes = null;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Listening to events using WP hooks.
|
45 |
+
*/
|
46 |
+
public function HookEvents() {
|
47 |
+
if ( $this->plugin->IsMultisite() ) {
|
48 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
49 |
+
if ( current_user_can( 'switch_themes' ) ) {
|
50 |
+
add_action( 'shutdown', array( $this, 'EventAdminShutdown' ) );
|
51 |
+
}
|
52 |
+
add_action( 'wpmu_new_blog', array( $this, 'EventNewBlog' ), 10, 1 );
|
53 |
+
add_action( 'archive_blog', array( $this, 'EventArchiveBlog' ) );
|
54 |
+
add_action( 'unarchive_blog', array( $this, 'EventUnarchiveBlog' ) );
|
55 |
+
add_action( 'activate_blog', array( $this, 'EventActivateBlog' ) );
|
56 |
+
add_action( 'deactivate_blog', array( $this, 'EventDeactivateBlog' ) );
|
57 |
+
add_action( 'delete_blog', array( $this, 'EventDeleteBlog' ) );
|
58 |
+
add_action( 'add_user_to_blog', array( $this, 'EventUserAddedToBlog' ), 10, 3 );
|
59 |
+
add_action( 'remove_user_from_blog', array( $this, 'EventUserRemovedFromBlog' ), 10, 2 );
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Triggered when a user accesses the admin area.
|
65 |
+
*/
|
66 |
+
public function EventAdminInit() {
|
67 |
+
$this->old_allowedthemes = array_keys( (array) get_site_option( 'allowedthemes' ) );
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Activated/Deactivated theme on network.
|
72 |
+
*/
|
73 |
+
public function EventAdminShutdown() {
|
74 |
+
if ( is_null( $this->old_allowedthemes ) ) {
|
75 |
+
return;
|
76 |
+
}
|
77 |
+
$new_allowedthemes = array_keys( (array) get_site_option( 'allowedthemes' ) );
|
78 |
+
|
79 |
+
// Check for enabled themes.
|
80 |
+
foreach ( $new_allowedthemes as $theme ) {
|
81 |
+
if ( ! in_array( $theme, (array) $this->old_allowedthemes ) ) {
|
82 |
+
$theme = wp_get_theme( $theme );
|
83 |
+
$this->plugin->alerts->Trigger(
|
84 |
+
5008, array(
|
85 |
+
'Theme' => (object) array(
|
86 |
+
'Name' => $theme->Name,
|
87 |
+
'ThemeURI' => $theme->ThemeURI,
|
88 |
+
'Description' => $theme->Description,
|
89 |
+
'Author' => $theme->Author,
|
90 |
+
'Version' => $theme->Version,
|
91 |
+
'get_template_directory' => $theme->get_template_directory(),
|
92 |
+
),
|
93 |
+
)
|
94 |
+
);
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
// Check for disabled themes.
|
99 |
+
foreach ( (array) $this->old_allowedthemes as $theme ) {
|
100 |
+
if ( ! in_array( $theme, $new_allowedthemes ) ) {
|
101 |
+
$theme = wp_get_theme( $theme );
|
102 |
+
$this->plugin->alerts->Trigger(
|
103 |
+
5009, array(
|
104 |
+
'Theme' => (object) array(
|
105 |
+
'Name' => $theme->Name,
|
106 |
+
'ThemeURI' => $theme->ThemeURI,
|
107 |
+
'Description' => $theme->Description,
|
108 |
+
'Author' => $theme->Author,
|
109 |
+
'Version' => $theme->Version,
|
110 |
+
'get_template_directory' => $theme->get_template_directory(),
|
111 |
+
),
|
112 |
+
)
|
113 |
+
);
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* New site added on the network.
|
120 |
+
*
|
121 |
+
* @param int $blog_id - Blog ID.
|
122 |
+
*/
|
123 |
+
public function EventNewBlog( $blog_id ) {
|
124 |
+
$this->plugin->alerts->Trigger(
|
125 |
+
7000, array(
|
126 |
+
'BlogID' => $blog_id,
|
127 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
128 |
+
)
|
129 |
+
);
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Existing site archived.
|
134 |
+
*
|
135 |
+
* @param int $blog_id - Blog ID.
|
136 |
+
*/
|
137 |
+
public function EventArchiveBlog( $blog_id ) {
|
138 |
+
$this->plugin->alerts->Trigger(
|
139 |
+
7001, array(
|
140 |
+
'BlogID' => $blog_id,
|
141 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
142 |
+
)
|
143 |
+
);
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Archived site has been unarchived.
|
148 |
+
*
|
149 |
+
* @param int $blog_id - Blog ID.
|
150 |
+
*/
|
151 |
+
public function EventUnarchiveBlog( $blog_id ) {
|
152 |
+
$this->plugin->alerts->Trigger(
|
153 |
+
7002, array(
|
154 |
+
'BlogID' => $blog_id,
|
155 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
156 |
+
)
|
157 |
+
);
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Deactivated site has been activated.
|
162 |
+
*
|
163 |
+
* @param int $blog_id - Blog ID.
|
164 |
+
*/
|
165 |
+
public function EventActivateBlog( $blog_id ) {
|
166 |
+
$this->plugin->alerts->Trigger(
|
167 |
+
7003, array(
|
168 |
+
'BlogID' => $blog_id,
|
169 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
170 |
+
)
|
171 |
+
);
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Site has been deactivated.
|
176 |
+
*
|
177 |
+
* @param int $blog_id - Blog ID.
|
178 |
+
*/
|
179 |
+
public function EventDeactivateBlog( $blog_id ) {
|
180 |
+
$this->plugin->alerts->Trigger(
|
181 |
+
7004, array(
|
182 |
+
'BlogID' => $blog_id,
|
183 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
184 |
+
)
|
185 |
+
);
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Existing site deleted from network.
|
190 |
+
*
|
191 |
+
* @param int $blog_id - Blog ID.
|
192 |
+
*/
|
193 |
+
public function EventDeleteBlog( $blog_id ) {
|
194 |
+
$this->plugin->alerts->Trigger(
|
195 |
+
7005, array(
|
196 |
+
'BlogID' => $blog_id,
|
197 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
198 |
+
)
|
199 |
+
);
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Existing user added to a site.
|
204 |
+
*
|
205 |
+
* @param int $user_id - User ID.
|
206 |
+
* @param string $role - User role.
|
207 |
+
* @param int $blog_id - Blog ID.
|
208 |
+
*/
|
209 |
+
public function EventUserAddedToBlog( $user_id, $role, $blog_id ) {
|
210 |
+
$this->plugin->alerts->TriggerIf(
|
211 |
+
4010, array(
|
212 |
+
'TargetUserID' => $user_id,
|
213 |
+
'TargetUsername' => get_userdata( $user_id )->user_login,
|
214 |
+
'TargetUserRole' => $role,
|
215 |
+
'BlogID' => $blog_id,
|
216 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
217 |
+
), array( $this, 'MustNotContainCreateUser' )
|
218 |
+
);
|
219 |
+
}
|
220 |
+
|
221 |
+
/**
|
222 |
+
* User removed from site.
|
223 |
+
*
|
224 |
+
* @param int $user_id - User ID.
|
225 |
+
* @param int $blog_id - Blog ID.
|
226 |
+
*/
|
227 |
+
public function EventUserRemovedFromBlog( $user_id, $blog_id ) {
|
228 |
+
$user = get_userdata( $user_id );
|
229 |
+
// $blog_id = (isset( $_REQUEST['id'] ) ? $_REQUEST['id'] : 0);
|
230 |
+
$this->plugin->alerts->TriggerIf(
|
231 |
+
4011, array(
|
232 |
+
'TargetUserID' => $user_id,
|
233 |
+
'TargetUsername' => $user->user_login,
|
234 |
+
'TargetUserRole' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
235 |
+
'BlogID' => $blog_id,
|
236 |
+
'SiteName' => get_blog_option( $blog_id, 'blogname' ),
|
237 |
+
), array( $this, 'MustNotContainCreateUser' )
|
238 |
+
);
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* New network user created.
|
243 |
+
*
|
244 |
+
* @param WSAL_AlertManager $mgr - Instance of Alert Manager.
|
245 |
+
*/
|
246 |
+
public function MustNotContainCreateUser( WSAL_AlertManager $mgr ) {
|
247 |
+
return ! $mgr->WillTrigger( 4012 );
|
248 |
+
}
|
249 |
}
|
classes/Sensors/PhpErrors.php
CHANGED
@@ -1,139 +1,177 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
*
|
7 |
* 0001 PHP error
|
8 |
* 0002 PHP warning
|
9 |
* 0003 PHP notice
|
10 |
* 0004 PHP exception
|
11 |
* 0005 PHP shutdown error
|
|
|
|
|
|
|
12 |
*/
|
13 |
-
class WSAL_Sensors_PhpErrors extends WSAL_AbstractSensor
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: PHP Errors
|
4 |
+
*
|
5 |
+
* PHP Errors sensor file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* PHP Errors sensor.
|
18 |
*
|
19 |
* 0001 PHP error
|
20 |
* 0002 PHP warning
|
21 |
* 0003 PHP notice
|
22 |
* 0004 PHP exception
|
23 |
* 0005 PHP shutdown error
|
24 |
+
*
|
25 |
+
* @package Wsal
|
26 |
+
* @subpackage Sensors
|
27 |
*/
|
28 |
+
class WSAL_Sensors_PhpErrors extends WSAL_AbstractSensor {
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Avoid Recursive Errors
|
32 |
+
*
|
33 |
+
* @var boolean
|
34 |
+
*/
|
35 |
+
protected $_avoid_error_recursion = false;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Last Error
|
39 |
+
*
|
40 |
+
* @var string
|
41 |
+
*/
|
42 |
+
protected $_maybe_last_error = null;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Error Types
|
46 |
+
*
|
47 |
+
* @var array
|
48 |
+
*/
|
49 |
+
protected $_error_types = array(
|
50 |
+
0001 => array( 1, 4, 16, 64, 256, 4096 ), // Errors.
|
51 |
+
0002 => array( 2, 32, 128, 512 ), // Warnings.
|
52 |
+
0003 => array( 8, 1024, 2048, 8192, 16384 ), // Notices.
|
53 |
+
0004 => array(), // Exceptions.
|
54 |
+
0005 => array(), // Shutdown.
|
55 |
+
);
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Listening to Php events.
|
59 |
+
*/
|
60 |
+
public function HookEvents() {
|
61 |
+
if ( $this->plugin->settings->IsPhpErrorLoggingEnabled() ) {
|
62 |
+
set_error_handler( array( $this, 'EventError' ), E_ALL );
|
63 |
+
set_exception_handler( array( $this, 'EventException' ) );
|
64 |
+
register_shutdown_function( array( $this, 'EventShutdown' ) );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Get the hash of the error.
|
70 |
+
*
|
71 |
+
* @param integer $code - Error code.
|
72 |
+
* @param string $mesg - Error message.
|
73 |
+
* @param string $file - File name.
|
74 |
+
* @param integer $line - Line number.
|
75 |
+
*/
|
76 |
+
protected function GetErrorHash( $code, $mesg, $file, $line ) {
|
77 |
+
return md5( implode( ':', func_get_args() ) );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* PHP error, warning or notice.
|
82 |
+
*
|
83 |
+
* @param integer $errno - Error code.
|
84 |
+
* @param string $errstr - Error message.
|
85 |
+
* @param string $errfile - File name.
|
86 |
+
* @param integer $errline - Line number.
|
87 |
+
* @param array $errcontext - Error context.
|
88 |
+
*/
|
89 |
+
public function EventError( $errno, $errstr, $errfile = 'unknown', $errline = 0, $errcontext = array() ) {
|
90 |
+
if ( $this->_avoid_error_recursion ) {
|
91 |
+
return;
|
92 |
+
}
|
93 |
+
|
94 |
+
$errbacktrace = 'No Backtrace';
|
95 |
+
if ( $this->plugin->settings->IsBacktraceLoggingEnabled() ) {
|
96 |
+
ob_start();
|
97 |
+
debug_print_backtrace();
|
98 |
+
$errbacktrace = ob_get_clean();
|
99 |
+
}
|
100 |
+
|
101 |
+
$data = array(
|
102 |
+
'Code' => $errno,
|
103 |
+
'Message' => $errstr,
|
104 |
+
'File' => $errfile,
|
105 |
+
'Line' => $errline,
|
106 |
+
'Context' => $errcontext,
|
107 |
+
'Trace' => $errbacktrace,
|
108 |
+
);
|
109 |
+
|
110 |
+
$type = 0002; // Default — middle ground.
|
111 |
+
foreach ( $this->_error_types as $temp => $codes ) {
|
112 |
+
if ( in_array( $errno, $codes ) ) {
|
113 |
+
$type = $temp;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
$this->_maybe_last_error = $this->GetErrorHash( $errno, $errstr, $errfile, $errline );
|
118 |
+
$this->_avoid_error_recursion = true;
|
119 |
+
$this->plugin->alerts->Trigger( $type, $data );
|
120 |
+
$this->_avoid_error_recursion = false;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* PHP exception.
|
125 |
+
*
|
126 |
+
* @param Exception $ex - Instance of Exception.
|
127 |
+
*/
|
128 |
+
public function EventException( Exception $ex ) {
|
129 |
+
if ( $this->_avoid_error_recursion ) {
|
130 |
+
return;
|
131 |
+
}
|
132 |
+
|
133 |
+
$errbacktrace = 'No Backtrace';
|
134 |
+
if ( $this->plugin->settings->IsBacktraceLoggingEnabled() ) {
|
135 |
+
$errbacktrace = $ex->getTraceAsString();
|
136 |
+
}
|
137 |
+
|
138 |
+
$data = array(
|
139 |
+
'Class' => get_class( $ex ),
|
140 |
+
'Code' => $ex->getCode(),
|
141 |
+
'Message' => $ex->getMessage(),
|
142 |
+
'File' => $ex->getFile(),
|
143 |
+
'Line' => $ex->getLine(),
|
144 |
+
'Trace' => $errbacktrace,
|
145 |
+
);
|
146 |
+
|
147 |
+
if ( method_exists( $ex, 'getContext' ) ) {
|
148 |
+
$data['Context'] = $ex->getContext();
|
149 |
+
}
|
150 |
+
|
151 |
+
$this->_avoid_error_recursion = true;
|
152 |
+
$this->plugin->alerts->Trigger( 0004, $data );
|
153 |
+
$this->_avoid_error_recursion = false;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* PHP shutdown error.
|
158 |
+
*/
|
159 |
+
public function EventShutdown() {
|
160 |
+
if ( $this->_avoid_error_recursion ) {
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
|
164 |
+
if ( ! ! ($e = error_get_last()) && ($this->_maybe_last_error != $this->GetErrorHash( $e['type'], $e['message'], $e['file'], $e['line'] )) ) {
|
165 |
+
$data = array(
|
166 |
+
'Code' => $e['type'],
|
167 |
+
'Message' => $e['message'],
|
168 |
+
'File' => $e['file'],
|
169 |
+
'Line' => $e['line'],
|
170 |
+
);
|
171 |
+
|
172 |
+
$this->_avoid_error_recursion = true;
|
173 |
+
$this->plugin->alerts->Trigger( 0005, $data );
|
174 |
+
$this->_avoid_error_recursion = false;
|
175 |
+
}
|
176 |
+
}
|
177 |
}
|
classes/Sensors/PluginsThemes.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Plugins & Themes sensor.
|
6 |
*
|
7 |
* 5000 User installed a plugin
|
@@ -22,10 +34,24 @@
|
|
22 |
* 2106 A plugin modified a post
|
23 |
* 2107 A plugin modified a page
|
24 |
* 2108 A plugin modified a custom post
|
|
|
|
|
|
|
25 |
*/
|
26 |
class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
27 |
|
|
|
|
|
|
|
|
|
|
|
28 |
protected $old_themes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
protected $old_plugins = array();
|
30 |
|
31 |
/**
|
@@ -57,165 +83,294 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
57 |
/**
|
58 |
* Install, uninstall, activate, deactivate, upgrade and update.
|
59 |
*/
|
60 |
-
public function EventAdminShutdown()
|
61 |
-
|
62 |
-
$
|
63 |
-
$
|
64 |
-
$
|
65 |
-
|
66 |
-
$
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
$
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
return $this->LogError(
|
73 |
-
'Expected exactly one new plugin but found ' . count($plugin),
|
74 |
-
array(
|
|
|
|
|
|
|
|
|
75 |
);
|
76 |
}
|
77 |
-
$
|
78 |
$plugin = get_plugins();
|
79 |
-
$plugin = $plugin[$
|
80 |
-
$
|
81 |
-
$this->plugin->alerts->Trigger(
|
82 |
-
|
83 |
-
'
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
91 |
}
|
92 |
|
93 |
-
//
|
94 |
-
if ($is_plugins && in_array($action, array('activate', 'activate-selected')) && current_user_can(
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
98 |
}
|
99 |
-
$
|
100 |
}
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
'
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
}
|
116 |
|
117 |
-
//
|
118 |
-
if ($is_plugins && in_array($action, array('deactivate', 'deactivate-selected')) && current_user_can(
|
119 |
-
|
120 |
-
|
121 |
-
|
|
|
122 |
}
|
123 |
-
$
|
124 |
}
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
'
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
}
|
139 |
}
|
140 |
|
141 |
-
//
|
142 |
-
if ($is_plugins && in_array($action, array('delete-selected')) && current_user_can(
|
143 |
-
if (!isset($
|
144 |
-
//
|
145 |
-
// TODO store plugin data in session here
|
146 |
} else {
|
147 |
// second step, after deletion approval
|
148 |
-
// TODO use plugin data from session
|
149 |
-
foreach ($
|
150 |
-
$
|
151 |
-
$
|
152 |
-
$
|
153 |
-
$
|
154 |
-
$this->plugin->alerts->Trigger(
|
155 |
-
|
156 |
-
|
157 |
-
'
|
158 |
-
|
159 |
-
|
|
|
|
|
160 |
}
|
161 |
}
|
162 |
}
|
163 |
|
164 |
-
//
|
165 |
-
if (in_array($action, array('delete-plugin')) && current_user_can(
|
166 |
-
if (isset($
|
167 |
-
$
|
168 |
-
$
|
169 |
-
$
|
170 |
-
$
|
171 |
-
$this->plugin->alerts->Trigger(
|
172 |
-
|
173 |
-
|
174 |
-
'
|
175 |
-
|
176 |
-
|
|
|
|
|
177 |
}
|
178 |
}
|
179 |
|
180 |
-
//
|
181 |
-
if (in_array($action, array('upgrade-plugin', 'update-plugin', 'update-selected')) && current_user_can(
|
182 |
$plugins = array();
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
$plugins
|
|
|
|
|
187 |
}
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
}
|
203 |
}
|
204 |
}
|
205 |
|
206 |
-
//
|
207 |
-
if (in_array($action, array('upgrade-theme', 'update-theme', 'update-selected-themes')) && current_user_can(
|
|
|
208 |
$themes = array();
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
$themes =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
-
if (isset($themes)) {
|
215 |
-
foreach ($themes as $theme_name) {
|
216 |
-
$theme = wp_get_theme($theme_name);
|
217 |
-
$this->plugin->alerts->Trigger(
|
218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
'Name' => $theme->Name,
|
220 |
'ThemeURI' => $theme->ThemeURI,
|
221 |
'Description' => $theme->Description,
|
@@ -223,105 +378,132 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
223 |
'Version' => $theme->Version,
|
224 |
'get_template_directory' => $theme->get_template_directory(),
|
225 |
),
|
226 |
-
)
|
227 |
-
|
228 |
-
}
|
229 |
-
}
|
230 |
-
|
231 |
-
// install theme
|
232 |
-
if (in_array($action, array('install-theme', 'upload-theme')) && current_user_can("install_themes")) {
|
233 |
-
$themes = array_diff(wp_get_themes(), $this->old_themes);
|
234 |
-
foreach ($themes as $theme) {
|
235 |
-
$this->plugin->alerts->Trigger(5005, array(
|
236 |
-
'Theme' => (object)array(
|
237 |
-
'Name' => $theme->Name,
|
238 |
-
'ThemeURI' => $theme->ThemeURI,
|
239 |
-
'Description' => $theme->Description,
|
240 |
-
'Author' => $theme->Author,
|
241 |
-
'Version' => $theme->Version,
|
242 |
-
'get_template_directory' => $theme->get_template_directory(),
|
243 |
-
),
|
244 |
-
));
|
245 |
}
|
246 |
}
|
247 |
|
248 |
-
//
|
249 |
-
if (in_array($action, array('delete-theme')) && current_user_can(
|
250 |
-
foreach ($this->GetRemovedThemes() as $theme) {
|
251 |
-
$this->plugin->alerts->Trigger(
|
252 |
-
|
253 |
-
'
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
|
|
|
|
261 |
}
|
262 |
}
|
263 |
}
|
264 |
|
265 |
/**
|
266 |
* Activated a theme.
|
267 |
-
*
|
|
|
268 |
*/
|
269 |
-
public function EventThemeActivated($
|
270 |
-
{
|
271 |
$theme = null;
|
272 |
-
foreach (wp_get_themes() as $item) {
|
273 |
-
if ($item->Name
|
274 |
$theme = $item;
|
275 |
break;
|
276 |
}
|
277 |
}
|
278 |
-
if ($theme
|
279 |
return $this->LogError(
|
280 |
'Could not locate theme named "' . $theme . '".',
|
281 |
-
array(
|
|
|
|
|
|
|
282 |
);
|
283 |
}
|
284 |
-
$this->plugin->alerts->Trigger(
|
285 |
-
|
286 |
-
'
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
|
|
|
|
294 |
}
|
295 |
|
296 |
/**
|
297 |
* Plugin creates/modifies posts.
|
298 |
*
|
299 |
-
* @param int
|
300 |
* @param object $post - Post object.
|
301 |
*/
|
302 |
public function EventPluginPostCreate( $post_id, $post ) {
|
303 |
-
$
|
304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) )
|
306 |
|| ! empty( $post->post_title ) ) {
|
307 |
// If the plugin modify the post.
|
308 |
-
if ( false !== strpos( $
|
309 |
$event = $this->GetEventTypeForPostType( $post, 2106, 2107, 2108 );
|
310 |
-
$
|
311 |
-
$this->plugin->alerts->Trigger(
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
|
|
|
|
317 |
} else {
|
318 |
$event = $this->GetEventTypeForPostType( $post, 5019, 5020, 5021 );
|
319 |
-
$this->plugin->alerts->Trigger(
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
|
|
|
|
325 |
}
|
326 |
}
|
327 |
}
|
@@ -333,51 +515,78 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
333 |
* @param integer $post_id - Post ID.
|
334 |
*/
|
335 |
public function EventPluginPostDelete( $post_id ) {
|
336 |
-
|
|
|
|
|
|
|
|
|
337 |
$post = get_post( $post_id );
|
338 |
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) )
|
339 |
|| ! empty( $post->post_title ) ) {
|
340 |
$event = $this->GetEventTypeForPostType( $post, 5025, 5026, 5027 );
|
341 |
-
$this->plugin->alerts->Trigger(
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
347 |
}
|
348 |
}
|
349 |
}
|
350 |
|
351 |
/**
|
352 |
* Get removed themes.
|
|
|
353 |
* @return array of WP_Theme objects
|
354 |
*/
|
355 |
-
protected function GetRemovedThemes()
|
356 |
-
{
|
357 |
$result = $this->old_themes;
|
358 |
-
foreach ($result as $i => $theme) {
|
359 |
-
if (file_exists($theme->get_template_directory())) {
|
360 |
-
unset($result[$i]);
|
361 |
}
|
362 |
}
|
363 |
-
return array_values($result);
|
364 |
}
|
365 |
|
366 |
/**
|
367 |
* Get event code by post type.
|
|
|
|
|
|
|
|
|
|
|
368 |
*/
|
369 |
-
protected function GetEventTypeForPostType( $post, $
|
370 |
if ( empty( $post ) || ! isset( $post->post_type ) ) {
|
371 |
return false;
|
372 |
}
|
373 |
|
374 |
switch ( $post->post_type ) {
|
375 |
case 'page':
|
376 |
-
return $
|
377 |
case 'post':
|
378 |
-
return $
|
379 |
default:
|
380 |
-
return $
|
381 |
}
|
382 |
}
|
383 |
|
@@ -385,16 +594,16 @@ class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
|
385 |
* Get editor link.
|
386 |
*
|
387 |
* @param object $post - The post object.
|
388 |
-
* @return array $
|
389 |
*/
|
390 |
private function GetEditorLink( $post ) {
|
391 |
$name = 'EditorLink';
|
392 |
-
$name .= ( $post->post_type
|
393 |
$value = get_edit_post_link( $post->ID );
|
394 |
-
$
|
395 |
-
'name'
|
396 |
'value' => $value,
|
397 |
);
|
398 |
-
return $
|
399 |
}
|
400 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Plugins & Themes
|
4 |
+
*
|
5 |
+
* Plugins & Themes sensor file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Plugins & Themes sensor.
|
18 |
*
|
19 |
* 5000 User installed a plugin
|
34 |
* 2106 A plugin modified a post
|
35 |
* 2107 A plugin modified a page
|
36 |
* 2108 A plugin modified a custom post
|
37 |
+
*
|
38 |
+
* @package Wsal
|
39 |
+
* @subpackage Sensors
|
40 |
*/
|
41 |
class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
42 |
|
43 |
+
/**
|
44 |
+
* List of Themes.
|
45 |
+
*
|
46 |
+
* @var array
|
47 |
+
*/
|
48 |
protected $old_themes = array();
|
49 |
+
|
50 |
+
/**
|
51 |
+
* List of Plugins.
|
52 |
+
*
|
53 |
+
* @var array
|
54 |
+
*/
|
55 |
protected $old_plugins = array();
|
56 |
|
57 |
/**
|
83 |
/**
|
84 |
* Install, uninstall, activate, deactivate, upgrade and update.
|
85 |
*/
|
86 |
+
public function EventAdminShutdown() {
|
87 |
+
// Filter global arrays for security.
|
88 |
+
$post_array = filter_input_array( INPUT_POST );
|
89 |
+
$get_array = filter_input_array( INPUT_GET );
|
90 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
91 |
+
|
92 |
+
$action = '';
|
93 |
+
if ( isset( $get_array['action'] ) && '-1' != $get_array['action'] ) {
|
94 |
+
$action = $get_array['action'];
|
95 |
+
} elseif ( isset( $post_array['action'] ) && '-1' != $post_array['action'] ) {
|
96 |
+
$action = $post_array['action'];
|
97 |
+
}
|
98 |
+
|
99 |
+
if ( isset( $get_array['action2'] ) && '-1' != $get_array['action2'] ) {
|
100 |
+
$action = $get_array['action2'];
|
101 |
+
} elseif ( isset( $post_array['action2'] ) && '-1' != $post_array['action2'] ) {
|
102 |
+
$action = $post_array['action2'];
|
103 |
+
}
|
104 |
+
|
105 |
+
$actype = basename( $server_array['SCRIPT_NAME'], '.php' );
|
106 |
+
$is_themes = 'themes' == $actype;
|
107 |
+
$is_plugins = 'plugins' == $actype;
|
108 |
+
|
109 |
+
// Install plugin.
|
110 |
+
if ( in_array( $action, array( 'install-plugin', 'upload-plugin' ) ) && current_user_can( 'install_plugins' ) ) {
|
111 |
+
$plugin = array_values( array_diff( array_keys( get_plugins() ), array_keys( $this->old_plugins ) ) );
|
112 |
+
if ( count( $plugin ) != 1 ) {
|
113 |
return $this->LogError(
|
114 |
+
'Expected exactly one new plugin but found ' . count( $plugin ),
|
115 |
+
array(
|
116 |
+
'NewPlugin' => $plugin,
|
117 |
+
'OldPlugins' => $this->old_plugins,
|
118 |
+
'NewPlugins' => get_plugins(),
|
119 |
+
)
|
120 |
);
|
121 |
}
|
122 |
+
$plugin_path = $plugin[0];
|
123 |
$plugin = get_plugins();
|
124 |
+
$plugin = $plugin[ $plugin_path ];
|
125 |
+
$plugin_path = plugin_dir_path( WP_PLUGIN_DIR . '/' . $plugin_path[0] );
|
126 |
+
$this->plugin->alerts->Trigger(
|
127 |
+
5000, array(
|
128 |
+
'Plugin' => (object) array(
|
129 |
+
'Name' => $plugin['Name'],
|
130 |
+
'PluginURI' => $plugin['PluginURI'],
|
131 |
+
'Version' => $plugin['Version'],
|
132 |
+
'Author' => $plugin['Author'],
|
133 |
+
'Network' => $plugin['Network'] ? 'True' : 'False',
|
134 |
+
'plugin_dir_path' => $plugin_path,
|
135 |
+
),
|
136 |
+
)
|
137 |
+
);
|
138 |
}
|
139 |
|
140 |
+
// Activate plugin.
|
141 |
+
if ( $is_plugins && in_array( $action, array( 'activate', 'activate-selected' ) ) && current_user_can( 'activate_plugins' ) ) {
|
142 |
+
// Check $_GET array case.
|
143 |
+
if ( isset( $get_array['plugin'] ) ) {
|
144 |
+
if ( ! isset( $get_array['checked'] ) ) {
|
145 |
+
$get_array['checked'] = array();
|
146 |
}
|
147 |
+
$get_array['checked'][] = $get_array['plugin'];
|
148 |
}
|
149 |
+
|
150 |
+
// Check $_POST array case.
|
151 |
+
if ( isset( $post_array['plugin'] ) ) {
|
152 |
+
if ( ! isset( $post_array['checked'] ) ) {
|
153 |
+
$post_array['checked'] = array();
|
154 |
+
}
|
155 |
+
$post_array['checked'][] = $post_array['plugin'];
|
156 |
+
}
|
157 |
+
|
158 |
+
if ( isset( $get_array['checked'] ) && ! empty( $get_array['checked'] ) ) {
|
159 |
+
foreach ( $get_array['checked'] as $plugin_file ) {
|
160 |
+
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
161 |
+
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
162 |
+
$this->plugin->alerts->Trigger(
|
163 |
+
5001, array(
|
164 |
+
'PluginFile' => $plugin_file,
|
165 |
+
'PluginData' => (object) array(
|
166 |
+
'Name' => $plugin_data['Name'],
|
167 |
+
'PluginURI' => $plugin_data['PluginURI'],
|
168 |
+
'Version' => $plugin_data['Version'],
|
169 |
+
'Author' => $plugin_data['Author'],
|
170 |
+
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
171 |
+
),
|
172 |
+
)
|
173 |
+
);
|
174 |
+
}
|
175 |
+
} elseif ( isset( $post_array['checked'] ) && ! empty( $post_array['checked'] ) ) {
|
176 |
+
foreach ( $post_array['checked'] as $plugin_file ) {
|
177 |
+
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
178 |
+
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
179 |
+
$this->plugin->alerts->Trigger(
|
180 |
+
5001, array(
|
181 |
+
'PluginFile' => $plugin_file,
|
182 |
+
'PluginData' => (object) array(
|
183 |
+
'Name' => $plugin_data['Name'],
|
184 |
+
'PluginURI' => $plugin_data['PluginURI'],
|
185 |
+
'Version' => $plugin_data['Version'],
|
186 |
+
'Author' => $plugin_data['Author'],
|
187 |
+
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
188 |
+
),
|
189 |
+
)
|
190 |
+
);
|
191 |
+
}
|
192 |
}
|
193 |
}
|
194 |
|
195 |
+
// Deactivate plugin.
|
196 |
+
if ( $is_plugins && in_array( $action, array( 'deactivate', 'deactivate-selected' ) ) && current_user_can( 'activate_plugins' ) ) {
|
197 |
+
// Check $_GET array case.
|
198 |
+
if ( isset( $get_array['plugin'] ) ) {
|
199 |
+
if ( ! isset( $get_array['checked'] ) ) {
|
200 |
+
$get_array['checked'] = array();
|
201 |
}
|
202 |
+
$get_array['checked'][] = $get_array['plugin'];
|
203 |
}
|
204 |
+
|
205 |
+
// Check $_POST array case.
|
206 |
+
if ( isset( $post_array['plugin'] ) ) {
|
207 |
+
if ( ! isset( $post_array['checked'] ) ) {
|
208 |
+
$post_array['checked'] = array();
|
209 |
+
}
|
210 |
+
$post_array['checked'][] = $post_array['plugin'];
|
211 |
+
}
|
212 |
+
|
213 |
+
if ( isset( $get_array['checked'] ) && ! empty( $get_array['checked'] ) ) {
|
214 |
+
foreach ( $get_array['checked'] as $plugin_file ) {
|
215 |
+
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
216 |
+
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
217 |
+
$this->plugin->alerts->Trigger(
|
218 |
+
5002, array(
|
219 |
+
'PluginFile' => $plugin_file,
|
220 |
+
'PluginData' => (object) array(
|
221 |
+
'Name' => $plugin_data['Name'],
|
222 |
+
'PluginURI' => $plugin_data['PluginURI'],
|
223 |
+
'Version' => $plugin_data['Version'],
|
224 |
+
'Author' => $plugin_data['Author'],
|
225 |
+
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
226 |
+
),
|
227 |
+
)
|
228 |
+
);
|
229 |
+
}
|
230 |
+
} elseif ( isset( $post_array['checked'] ) && ! empty( $post_array['checked'] ) ) {
|
231 |
+
foreach ( $post_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->Trigger(
|
235 |
+
5002, array(
|
236 |
+
'PluginFile' => $plugin_file,
|
237 |
+
'PluginData' => (object) array(
|
238 |
+
'Name' => $plugin_data['Name'],
|
239 |
+
'PluginURI' => $plugin_data['PluginURI'],
|
240 |
+
'Version' => $plugin_data['Version'],
|
241 |
+
'Author' => $plugin_data['Author'],
|
242 |
+
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
243 |
+
),
|
244 |
+
)
|
245 |
+
);
|
246 |
+
}
|
247 |
}
|
248 |
}
|
249 |
|
250 |
+
// Uninstall plugin.
|
251 |
+
if ( $is_plugins && in_array( $action, array( 'delete-selected' ) ) && current_user_can( 'delete_plugins' ) ) {
|
252 |
+
if ( ! isset( $post_array['verify-delete'] ) ) {
|
253 |
+
// First step, before user approves deletion
|
254 |
+
// TODO store plugin data in session here.
|
255 |
} else {
|
256 |
// second step, after deletion approval
|
257 |
+
// TODO use plugin data from session.
|
258 |
+
foreach ( $post_array['checked'] as $plugin_file ) {
|
259 |
+
$plugin_name = basename( $plugin_file, '.php' );
|
260 |
+
$plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name );
|
261 |
+
$plugin_name = ucwords( $plugin_name );
|
262 |
+
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
263 |
+
$this->plugin->alerts->Trigger(
|
264 |
+
5003, array(
|
265 |
+
'PluginFile' => $plugin_file,
|
266 |
+
'PluginData' => (object) array(
|
267 |
+
'Name' => $plugin_name,
|
268 |
+
),
|
269 |
+
)
|
270 |
+
);
|
271 |
}
|
272 |
}
|
273 |
}
|
274 |
|
275 |
+
// Uninstall plugin for WordPress version 4.6.
|
276 |
+
if ( in_array( $action, array( 'delete-plugin' ) ) && current_user_can( 'delete_plugins' ) ) {
|
277 |
+
if ( isset( $post_array['plugin'] ) ) {
|
278 |
+
$plugin_file = WP_PLUGIN_DIR . '/' . $post_array['plugin'];
|
279 |
+
$plugin_name = basename( $plugin_file, '.php' );
|
280 |
+
$plugin_name = str_replace( array( '_', '-', ' ' ), ' ', $plugin_name );
|
281 |
+
$plugin_name = ucwords( $plugin_name );
|
282 |
+
$this->plugin->alerts->Trigger(
|
283 |
+
5003, array(
|
284 |
+
'PluginFile' => $plugin_file,
|
285 |
+
'PluginData' => (object) array(
|
286 |
+
'Name' => $plugin_name,
|
287 |
+
),
|
288 |
+
)
|
289 |
+
);
|
290 |
}
|
291 |
}
|
292 |
|
293 |
+
// Upgrade plugin.
|
294 |
+
if ( in_array( $action, array( 'upgrade-plugin', 'update-plugin', 'update-selected' ) ) && current_user_can( 'update_plugins' ) ) {
|
295 |
$plugins = array();
|
296 |
+
|
297 |
+
// Check $_GET array cases.
|
298 |
+
if ( isset( $get_array['plugins'] ) ) {
|
299 |
+
$plugins = explode( ',', $get_array['plugins'] );
|
300 |
+
} elseif ( isset( $get_array['plugin'] ) ) {
|
301 |
+
$plugins[] = $get_array['plugin'];
|
302 |
}
|
303 |
+
|
304 |
+
// Check $_POST array cases.
|
305 |
+
if ( isset( $post_array['plugins'] ) ) {
|
306 |
+
$plugins = explode( ',', $post_array['plugins'] );
|
307 |
+
} elseif ( isset( $post_array['plugin'] ) ) {
|
308 |
+
$plugins[] = $post_array['plugin'];
|
309 |
+
}
|
310 |
+
if ( isset( $plugins ) ) {
|
311 |
+
foreach ( $plugins as $plugin_file ) {
|
312 |
+
$plugin_file = WP_PLUGIN_DIR . '/' . $plugin_file;
|
313 |
+
$plugin_data = get_plugin_data( $plugin_file, false, true );
|
314 |
+
$this->plugin->alerts->Trigger(
|
315 |
+
5004, array(
|
316 |
+
'PluginFile' => $plugin_file,
|
317 |
+
'PluginData' => (object) array(
|
318 |
+
'Name' => $plugin_data['Name'],
|
319 |
+
'PluginURI' => $plugin_data['PluginURI'],
|
320 |
+
'Version' => $plugin_data['Version'],
|
321 |
+
'Author' => $plugin_data['Author'],
|
322 |
+
'Network' => $plugin_data['Network'] ? 'True' : 'False',
|
323 |
+
),
|
324 |
+
)
|
325 |
+
);
|
326 |
}
|
327 |
}
|
328 |
}
|
329 |
|
330 |
+
// Update theme.
|
331 |
+
if ( in_array( $action, array( 'upgrade-theme', 'update-theme', 'update-selected-themes' ) ) && current_user_can( 'install_themes' ) ) {
|
332 |
+
// Themes.
|
333 |
$themes = array();
|
334 |
+
|
335 |
+
// Check $_GET array cases.
|
336 |
+
if ( isset( $get_array['slug'] ) || isset( $get_array['theme'] ) ) {
|
337 |
+
$themes[] = isset( $get_array['slug'] ) ? $get_array['slug'] : $get_array['theme'];
|
338 |
+
} elseif ( isset( $get_array['themes'] ) ) {
|
339 |
+
$themes = explode( ',', $get_array['themes'] );
|
340 |
+
}
|
341 |
+
|
342 |
+
// Check $_POST array cases.
|
343 |
+
if ( isset( $post_array['slug'] ) || isset( $post_array['theme'] ) ) {
|
344 |
+
$themes[] = isset( $post_array['slug'] ) ? $post_array['slug'] : $post_array['theme'];
|
345 |
+
} elseif ( isset( $post_array['themes'] ) ) {
|
346 |
+
$themes = explode( ',', $post_array['themes'] );
|
347 |
}
|
348 |
+
if ( isset( $themes ) ) {
|
349 |
+
foreach ( $themes as $theme_name ) {
|
350 |
+
$theme = wp_get_theme( $theme_name );
|
351 |
+
$this->plugin->alerts->Trigger(
|
352 |
+
5031, array(
|
353 |
+
'Theme' => (object) array(
|
354 |
+
'Name' => $theme->Name,
|
355 |
+
'ThemeURI' => $theme->ThemeURI,
|
356 |
+
'Description' => $theme->Description,
|
357 |
+
'Author' => $theme->Author,
|
358 |
+
'Version' => $theme->Version,
|
359 |
+
'get_template_directory' => $theme->get_template_directory(),
|
360 |
+
),
|
361 |
+
)
|
362 |
+
);
|
363 |
+
}
|
364 |
+
}
|
365 |
+
}
|
366 |
+
|
367 |
+
// Install theme.
|
368 |
+
if ( in_array( $action, array( 'install-theme', 'upload-theme' ) ) && current_user_can( 'install_themes' ) ) {
|
369 |
+
$themes = array_diff( wp_get_themes(), $this->old_themes );
|
370 |
+
foreach ( $themes as $theme ) {
|
371 |
+
$this->plugin->alerts->Trigger(
|
372 |
+
5005, array(
|
373 |
+
'Theme' => (object) array(
|
374 |
'Name' => $theme->Name,
|
375 |
'ThemeURI' => $theme->ThemeURI,
|
376 |
'Description' => $theme->Description,
|
378 |
'Version' => $theme->Version,
|
379 |
'get_template_directory' => $theme->get_template_directory(),
|
380 |
),
|
381 |
+
)
|
382 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
}
|
384 |
}
|
385 |
|
386 |
+
// Uninstall theme.
|
387 |
+
if ( in_array( $action, array( 'delete-theme' ) ) && current_user_can( 'install_themes' ) ) {
|
388 |
+
foreach ( $this->GetRemovedThemes() as $theme ) {
|
389 |
+
$this->plugin->alerts->Trigger(
|
390 |
+
5007, array(
|
391 |
+
'Theme' => (object) array(
|
392 |
+
'Name' => $theme->Name,
|
393 |
+
'ThemeURI' => $theme->ThemeURI,
|
394 |
+
'Description' => $theme->Description,
|
395 |
+
'Author' => $theme->Author,
|
396 |
+
'Version' => $theme->Version,
|
397 |
+
'get_template_directory' => $theme->get_template_directory(),
|
398 |
+
),
|
399 |
+
)
|
400 |
+
);
|
401 |
}
|
402 |
}
|
403 |
}
|
404 |
|
405 |
/**
|
406 |
* Activated a theme.
|
407 |
+
*
|
408 |
+
* @param string $theme_name - Theme name.
|
409 |
*/
|
410 |
+
public function EventThemeActivated( $theme_name ) {
|
|
|
411 |
$theme = null;
|
412 |
+
foreach ( wp_get_themes() as $item ) {
|
413 |
+
if ( $theme_name == $item->Name ) {
|
414 |
$theme = $item;
|
415 |
break;
|
416 |
}
|
417 |
}
|
418 |
+
if ( null == $theme ) {
|
419 |
return $this->LogError(
|
420 |
'Could not locate theme named "' . $theme . '".',
|
421 |
+
array(
|
422 |
+
'ThemeName' => $theme_name,
|
423 |
+
'Themes' => wp_get_themes(),
|
424 |
+
)
|
425 |
);
|
426 |
}
|
427 |
+
$this->plugin->alerts->Trigger(
|
428 |
+
5006, array(
|
429 |
+
'Theme' => (object) array(
|
430 |
+
'Name' => $theme->Name,
|
431 |
+
'ThemeURI' => $theme->ThemeURI,
|
432 |
+
'Description' => $theme->Description,
|
433 |
+
'Author' => $theme->Author,
|
434 |
+
'Version' => $theme->Version,
|
435 |
+
'get_template_directory' => $theme->get_template_directory(),
|
436 |
+
),
|
437 |
+
)
|
438 |
+
);
|
439 |
}
|
440 |
|
441 |
/**
|
442 |
* Plugin creates/modifies posts.
|
443 |
*
|
444 |
+
* @param int $post_id - Post ID.
|
445 |
* @param object $post - Post object.
|
446 |
*/
|
447 |
public function EventPluginPostCreate( $post_id, $post ) {
|
448 |
+
// Filter $_REQUEST array for security.
|
449 |
+
$get_array = filter_input_array( INPUT_GET );
|
450 |
+
$post_array = filter_input_array( INPUT_POST );
|
451 |
+
|
452 |
+
$wp_actions = array( 'editpost', 'heartbeat', 'inline-save', 'trash', 'untrash' );
|
453 |
+
if ( isset( $get_array['action'] ) && ! in_array( $get_array['action'], $wp_actions ) ) {
|
454 |
+
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) )
|
455 |
+
|| ! empty( $post->post_title ) ) {
|
456 |
+
// If the plugin modify the post.
|
457 |
+
if ( false !== strpos( $get_array['action'], 'edit' ) ) {
|
458 |
+
$event = $this->GetEventTypeForPostType( $post, 2106, 2107, 2108 );
|
459 |
+
$editor_link = $this->GetEditorLink( $post );
|
460 |
+
$this->plugin->alerts->Trigger(
|
461 |
+
$event, array(
|
462 |
+
'PostID' => $post->ID,
|
463 |
+
'PostType' => $post->post_type,
|
464 |
+
'PostTitle' => $post->post_title,
|
465 |
+
$editor_link['name'] => $editor_link['value'],
|
466 |
+
)
|
467 |
+
);
|
468 |
+
} else {
|
469 |
+
$event = $this->GetEventTypeForPostType( $post, 5019, 5020, 5021 );
|
470 |
+
$this->plugin->alerts->Trigger(
|
471 |
+
$event, array(
|
472 |
+
'PostID' => $post->ID,
|
473 |
+
'PostType' => $post->post_type,
|
474 |
+
'PostTitle' => $post->post_title,
|
475 |
+
'Username' => 'Plugins',
|
476 |
+
)
|
477 |
+
);
|
478 |
+
}
|
479 |
+
}
|
480 |
+
}
|
481 |
+
|
482 |
+
if ( isset( $post_array['action'] ) && ! in_array( $post_array['action'], $wp_actions ) ) {
|
483 |
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) )
|
484 |
|| ! empty( $post->post_title ) ) {
|
485 |
// If the plugin modify the post.
|
486 |
+
if ( false !== strpos( $post_array['action'], 'edit' ) ) {
|
487 |
$event = $this->GetEventTypeForPostType( $post, 2106, 2107, 2108 );
|
488 |
+
$editor_link = $this->GetEditorLink( $post );
|
489 |
+
$this->plugin->alerts->Trigger(
|
490 |
+
$event, array(
|
491 |
+
'PostID' => $post->ID,
|
492 |
+
'PostType' => $post->post_type,
|
493 |
+
'PostTitle' => $post->post_title,
|
494 |
+
$editor_link['name'] => $editor_link['value'],
|
495 |
+
)
|
496 |
+
);
|
497 |
} else {
|
498 |
$event = $this->GetEventTypeForPostType( $post, 5019, 5020, 5021 );
|
499 |
+
$this->plugin->alerts->Trigger(
|
500 |
+
$event, array(
|
501 |
+
'PostID' => $post->ID,
|
502 |
+
'PostType' => $post->post_type,
|
503 |
+
'PostTitle' => $post->post_title,
|
504 |
+
'Username' => 'Plugins',
|
505 |
+
)
|
506 |
+
);
|
507 |
}
|
508 |
}
|
509 |
}
|
515 |
* @param integer $post_id - Post ID.
|
516 |
*/
|
517 |
public function EventPluginPostDelete( $post_id ) {
|
518 |
+
// Filter $_REQUEST array for security.
|
519 |
+
$get_array = filter_input_array( INPUT_GET );
|
520 |
+
$post_array = filter_input_array( INPUT_POST );
|
521 |
+
|
522 |
+
if ( empty( $get_array['action'] ) && isset( $get_array['page'] ) ) {
|
523 |
$post = get_post( $post_id );
|
524 |
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) )
|
525 |
|| ! empty( $post->post_title ) ) {
|
526 |
$event = $this->GetEventTypeForPostType( $post, 5025, 5026, 5027 );
|
527 |
+
$this->plugin->alerts->Trigger(
|
528 |
+
$event, array(
|
529 |
+
'PostID' => $post->ID,
|
530 |
+
'PostType' => $post->post_type,
|
531 |
+
'PostTitle' => $post->post_title,
|
532 |
+
'Username' => 'Plugins',
|
533 |
+
)
|
534 |
+
);
|
535 |
+
}
|
536 |
+
}
|
537 |
+
|
538 |
+
if ( empty( $post_array['action'] ) && isset( $post_array['page'] ) ) {
|
539 |
+
$post = get_post( $post_id );
|
540 |
+
if ( ! in_array( $post->post_type, array( 'attachment', 'revision', 'nav_menu_item', 'customize_changeset', 'custom_css' ) )
|
541 |
+
|| ! empty( $post->post_title ) ) {
|
542 |
+
$event = $this->GetEventTypeForPostType( $post, 5025, 5026, 5027 );
|
543 |
+
$this->plugin->alerts->Trigger(
|
544 |
+
$event, array(
|
545 |
+
'PostID' => $post->ID,
|
546 |
+
'PostType' => $post->post_type,
|
547 |
+
'PostTitle' => $post->post_title,
|
548 |
+
'Username' => 'Plugins',
|
549 |
+
)
|
550 |
+
);
|
551 |
}
|
552 |
}
|
553 |
}
|
554 |
|
555 |
/**
|
556 |
* Get removed themes.
|
557 |
+
*
|
558 |
* @return array of WP_Theme objects
|
559 |
*/
|
560 |
+
protected function GetRemovedThemes() {
|
|
|
561 |
$result = $this->old_themes;
|
562 |
+
foreach ( $result as $i => $theme ) {
|
563 |
+
if ( file_exists( $theme->get_template_directory() ) ) {
|
564 |
+
unset( $result[ $i ] );
|
565 |
}
|
566 |
}
|
567 |
+
return array_values( $result );
|
568 |
}
|
569 |
|
570 |
/**
|
571 |
* Get event code by post type.
|
572 |
+
*
|
573 |
+
* @param object $post - Post object.
|
574 |
+
* @param int $type_post - Code for post.
|
575 |
+
* @param int $type_page - Code for page.
|
576 |
+
* @param int $type_custom - Code for custom post type.
|
577 |
*/
|
578 |
+
protected function GetEventTypeForPostType( $post, $type_post, $type_page, $type_custom ) {
|
579 |
if ( empty( $post ) || ! isset( $post->post_type ) ) {
|
580 |
return false;
|
581 |
}
|
582 |
|
583 |
switch ( $post->post_type ) {
|
584 |
case 'page':
|
585 |
+
return $type_page;
|
586 |
case 'post':
|
587 |
+
return $type_post;
|
588 |
default:
|
589 |
+
return $type_custom;
|
590 |
}
|
591 |
}
|
592 |
|
594 |
* Get editor link.
|
595 |
*
|
596 |
* @param object $post - The post object.
|
597 |
+
* @return array $editor_link name and value link.
|
598 |
*/
|
599 |
private function GetEditorLink( $post ) {
|
600 |
$name = 'EditorLink';
|
601 |
+
$name .= ( 'page' == $post->post_type ) ? 'Page' : 'Post' ;
|
602 |
$value = get_edit_post_link( $post->ID );
|
603 |
+
$editor_link = array(
|
604 |
+
'name' => $name,
|
605 |
'value' => $value,
|
606 |
);
|
607 |
+
return $editor_link;
|
608 |
}
|
609 |
}
|
classes/Sensors/Request.php
CHANGED
@@ -1,75 +1,116 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Writes the Request.log.php file.
|
|
|
|
|
|
|
6 |
*/
|
7 |
-
class WSAL_Sensors_Request extends WSAL_AbstractSensor
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
return $this->LogError('Could not initialize request log file', array('file' => $file));
|
43 |
-
}
|
44 |
-
|
45 |
-
$f = fopen($file, 'a');
|
46 |
-
if ($f) {
|
47 |
-
if (!fwrite($f, $line)) {
|
48 |
-
$this->LogWarn('Could not write to log file', array('file' => $file));
|
49 |
-
}
|
50 |
-
if (!fclose($f)) {
|
51 |
-
$this->LogWarn('Could not close log file', array('file' => $file));
|
52 |
-
}
|
53 |
-
} else {
|
54 |
-
$this->LogWarn('Could not open log file', array('file' => $file));
|
55 |
-
}
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Sets $envvars element with key and value.
|
60 |
-
*/
|
61 |
-
public static function SetVar($name, $value)
|
62 |
-
{
|
63 |
-
self::$envvars[$name] = $value;
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Copy data array into $envvars array.
|
68 |
-
*/
|
69 |
-
public static function SetVars($data)
|
70 |
-
{
|
71 |
-
foreach ($data as $name => $value) {
|
72 |
-
self::SetVar($name, $value);
|
73 |
-
}
|
74 |
-
}
|
75 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Request
|
4 |
+
*
|
5 |
+
* Request sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Writes the Request.log.php file.
|
18 |
+
*
|
19 |
+
* @package Wsal
|
20 |
+
* @subpackage Sensors
|
21 |
*/
|
22 |
+
class WSAL_Sensors_Request extends WSAL_AbstractSensor {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Environment Variables
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected static $envvars = array();
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Listening to events using WP hooks.
|
33 |
+
*/
|
34 |
+
public function HookEvents() {
|
35 |
+
if ( $this->plugin->settings->IsRequestLoggingEnabled() ) {
|
36 |
+
add_action( 'shutdown', array( $this, 'EventShutdown' ) );
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Fires just before PHP shuts down execution.
|
42 |
+
*/
|
43 |
+
public function EventShutdown() {
|
44 |
+
// Filter global arrays for security.
|
45 |
+
$post_array = filter_input_array( INPUT_POST );
|
46 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
47 |
+
|
48 |
+
$upload_dir = wp_upload_dir();
|
49 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/';
|
50 |
+
if ( ! $this->CheckDirectory( $uploads_dir_path ) ) {
|
51 |
+
wp_mkdir_p( $uploads_dir_path );
|
52 |
+
}
|
53 |
+
|
54 |
+
$file = $uploads_dir_path . 'Request.log.php';
|
55 |
+
|
56 |
+
$line = '[' . date( 'Y-m-d H:i:s' ) . '] '
|
57 |
+
. $server_array['REQUEST_METHOD'] . ' '
|
58 |
+
. $server_array['REQUEST_URI'] . ' '
|
59 |
+
. ( ! empty( $post_array ) ? str_pad( PHP_EOL, 24 ) . json_encode( $post_array ) : '')
|
60 |
+
. ( ! empty( self::$envvars ) ? str_pad( PHP_EOL, 24 ) . json_encode( self::$envvars ) : '')
|
61 |
+
. PHP_EOL;
|
62 |
+
|
63 |
+
if ( ! file_exists( $file ) && ! file_put_contents( $file, '<' . '?php die(\'Access Denied\'); ?>' . PHP_EOL ) ) {
|
64 |
+
return $this->LogError(
|
65 |
+
'Could not initialize request log file', array(
|
66 |
+
'file' => $file,
|
67 |
+
)
|
68 |
+
);
|
69 |
+
}
|
70 |
+
|
71 |
+
$f = fopen( $file, 'a' );
|
72 |
+
if ( $f ) {
|
73 |
+
if ( ! fwrite( $f, $line ) ) {
|
74 |
+
$this->LogWarn(
|
75 |
+
'Could not write to log file', array(
|
76 |
+
'file' => $file,
|
77 |
+
)
|
78 |
+
);
|
79 |
+
}
|
80 |
+
if ( ! fclose( $f ) ) {
|
81 |
+
$this->LogWarn(
|
82 |
+
'Could not close log file', array(
|
83 |
+
'file' => $file,
|
84 |
+
)
|
85 |
+
);
|
86 |
+
}
|
87 |
+
} else {
|
88 |
+
$this->LogWarn(
|
89 |
+
'Could not open log file', array(
|
90 |
+
'file' => $file,
|
91 |
+
)
|
92 |
+
);
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Sets $envvars element with key and value.
|
98 |
+
*
|
99 |
+
* @param mixed $name - Key name of the variable.
|
100 |
+
* @param mixed $value - Value of the variable.
|
101 |
+
*/
|
102 |
+
public static function SetVar( $name, $value ) {
|
103 |
+
self::$envvars[ $name ] = $value;
|
104 |
+
}
|
105 |
|
106 |
+
/**
|
107 |
+
* Copy data array into $envvars array.
|
108 |
+
*
|
109 |
+
* @param array $data - Data array.
|
110 |
+
*/
|
111 |
+
public static function SetVars( $data ) {
|
112 |
+
foreach ( $data as $name => $value ) {
|
113 |
+
self::SetVar( $name, $value );
|
114 |
+
}
|
115 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
}
|
classes/Sensors/System.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* System Activity sensor.
|
6 |
*
|
7 |
* 6000 Events automatically pruned by system
|
@@ -28,730 +40,914 @@
|
|
28 |
* 6016 Changed the number of links that a comment must have to be held in the queue
|
29 |
* 6017 Modified the list of keywords for comments moderation
|
30 |
* 6018 Modified the list of keywords for comments blacklisting
|
|
|
|
|
|
|
31 |
*/
|
32 |
class WSAL_Sensors_System extends WSAL_AbstractSensor {
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
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 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
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 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
757 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: System Activity
|
4 |
+
*
|
5 |
+
* System activity sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* System Activity sensor.
|
18 |
*
|
19 |
* 6000 Events automatically pruned by system
|
40 |
* 6016 Changed the number of links that a comment must have to be held in the queue
|
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 |
+
* Transient name.
|
51 |
+
* WordPress will prefix the name with "_transient_"
|
52 |
+
* or "_transient_timeout_" in the options table.
|
53 |
+
*/
|
54 |
+
const TRANSIENT_404 = 'wsal-404-attempts';
|
55 |
+
const TRANSIENT_VISITOR_404 = 'wsal-visitor-404-attempts';
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Listening to events using WP hooks.
|
59 |
+
*/
|
60 |
+
public function HookEvents() {
|
61 |
+
|
62 |
+
add_action( 'wsal_prune', array( $this, 'EventPruneEvents' ), 10, 2 );
|
63 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
64 |
+
|
65 |
+
add_action( 'automatic_updates_complete', array( $this, 'WPUpdate' ), 10, 1 );
|
66 |
+
add_filter( 'template_redirect', array( $this, 'Event404' ) );
|
67 |
+
|
68 |
+
$upload_dir = wp_upload_dir();
|
69 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/';
|
70 |
+
if ( ! $this->CheckDirectory( $uploads_dir_path ) ) {
|
71 |
+
wp_mkdir_p( $uploads_dir_path );
|
72 |
+
}
|
73 |
+
|
74 |
+
// Directory for logged in users log files.
|
75 |
+
$user_upload_dir = wp_upload_dir();
|
76 |
+
$user_upload_path = trailingslashit( $user_upload_dir['basedir'] . '/wp-security-audit-log/404s/users/' );
|
77 |
+
if ( ! $this->CheckDirectory( $user_upload_path ) ) {
|
78 |
+
wp_mkdir_p( $user_upload_path );
|
79 |
+
}
|
80 |
+
|
81 |
+
// Directory for visitor log files.
|
82 |
+
$visitor_upload_dir = wp_upload_dir();
|
83 |
+
$visitor_upload_path = trailingslashit( $visitor_upload_dir['basedir'] . '/wp-security-audit-log/404s/visitors/' );
|
84 |
+
if ( ! $this->CheckDirectory( $visitor_upload_path ) ) {
|
85 |
+
wp_mkdir_p( $visitor_upload_path );
|
86 |
+
}
|
87 |
+
|
88 |
+
// Cron Job 404 log files pruning.
|
89 |
+
add_action( 'log_files_pruning', array( $this, 'LogFilesPruning' ) );
|
90 |
+
if ( ! wp_next_scheduled( 'log_files_pruning' ) ) {
|
91 |
+
wp_schedule_event( time(), 'daily', 'log_files_pruning' );
|
92 |
+
}
|
93 |
+
// whitelist options.
|
94 |
+
add_action( 'whitelist_options', array( $this, 'EventOptions' ), 10, 1 );
|
95 |
+
|
96 |
+
// Update admin email alert.
|
97 |
+
add_action( 'update_option_admin_email', array( $this, 'admin_email_changed' ), 10, 3 );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Alert: Admin email changed.
|
102 |
+
*
|
103 |
+
* @param mixed $old_value - The old option value.
|
104 |
+
* @param mixed $new_value - The new option value.
|
105 |
+
* @param string $option - Option name.
|
106 |
+
* @since 3.0.0
|
107 |
+
*/
|
108 |
+
public function admin_email_changed( $old_value, $new_value, $option ) {
|
109 |
+
// Check if the option is not empty and is admin_email.
|
110 |
+
if ( ! empty( $old_value ) && ! empty( $new_value )
|
111 |
+
&& ! empty( $option ) && 'admin_email' === $option ) {
|
112 |
+
if ( $old_value != $new_value ) {
|
113 |
+
$this->plugin->alerts->Trigger(
|
114 |
+
6003, array(
|
115 |
+
'OldEmail' => $old_value,
|
116 |
+
'NewEmail' => $new_value,
|
117 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
118 |
+
)
|
119 |
+
);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Method: Prune events function.
|
126 |
+
*
|
127 |
+
* @param int $count The number of deleted events.
|
128 |
+
* @param string $query Query that selected events for deletion.
|
129 |
+
*/
|
130 |
+
public function EventPruneEvents( $count, $query ) {
|
131 |
+
$this->plugin->alerts->Trigger(
|
132 |
+
6000, array(
|
133 |
+
'EventCount' => $count,
|
134 |
+
'PruneQuery' => $query,
|
135 |
+
)
|
136 |
+
);
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* 404 limit count.
|
141 |
+
*
|
142 |
+
* @return integer limit
|
143 |
+
*/
|
144 |
+
protected function Get404LogLimit() {
|
145 |
+
return $this->plugin->settings->Get404LogLimit();
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* 404 visitor limit count.
|
150 |
+
*
|
151 |
+
* @return integer limit
|
152 |
+
*/
|
153 |
+
protected function GetVisitor404LogLimit() {
|
154 |
+
return $this->plugin->settings->GetVisitor404LogLimit();
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Expiration of the transient saved in the WP database.
|
159 |
+
*
|
160 |
+
* @return integer Time until expiration in seconds from now
|
161 |
+
*/
|
162 |
+
protected function Get404Expiration() {
|
163 |
+
return 24 * 60 * 60;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Check 404 limit.
|
168 |
+
*
|
169 |
+
* @param integer $site_id - Blog ID.
|
170 |
+
* @param string $username - Username.
|
171 |
+
* @param string $ip - IP address.
|
172 |
+
* @return boolean passed limit true|false
|
173 |
+
*/
|
174 |
+
protected function IsPast404Limit( $site_id, $username, $ip ) {
|
175 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
176 |
+
$data = $get_fn( self::TRANSIENT_404 );
|
177 |
+
return ( false !== $data ) && isset( $data[ $site_id . ':' . $username . ':' . $ip ] ) && ($data[ $site_id . ':' . $username . ':' . $ip ] > $this->Get404LogLimit());
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Check visitor 404 limit.
|
182 |
+
*
|
183 |
+
* @param integer $site_id - Blog ID.
|
184 |
+
* @param string $username - Username.
|
185 |
+
* @param string $ip - IP address.
|
186 |
+
* @return boolean passed limit true|false
|
187 |
+
*/
|
188 |
+
protected function IsPastVisitor404Limit( $site_id, $username, $ip ) {
|
189 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
190 |
+
$data = $get_fn( self::TRANSIENT_VISITOR_404 );
|
191 |
+
return ( false !== $data ) && isset( $data[ $site_id . ':' . $username . ':' . $ip ] ) && ( $data[ $site_id . ':' . $username . ':' . $ip ] > $this->GetVisitor404LogLimit() );
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Increment 404 limit.
|
196 |
+
*
|
197 |
+
* @param integer $site_id - Blog ID.
|
198 |
+
* @param string $username - Username.
|
199 |
+
* @param string $ip - IP address.
|
200 |
+
*/
|
201 |
+
protected function Increment404( $site_id, $username, $ip ) {
|
202 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
203 |
+
$set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
|
204 |
+
|
205 |
+
$data = $get_fn( self::TRANSIENT_404 );
|
206 |
+
if ( ! $data ) {
|
207 |
+
$data = array();
|
208 |
+
}
|
209 |
+
if ( ! isset( $data[ $site_id . ':' . $username . ':' . $ip ] ) ) {
|
210 |
+
$data[ $site_id . ':' . $username . ':' . $ip ] = 1;
|
211 |
+
}
|
212 |
+
$data[ $site_id . ':' . $username . ':' . $ip ]++;
|
213 |
+
$set_fn( self::TRANSIENT_404, $data, $this->Get404Expiration() );
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Increment visitor 404 limit.
|
218 |
+
*
|
219 |
+
* @param integer $site_id - Blog ID.
|
220 |
+
* @param string $username - Username.
|
221 |
+
* @param string $ip - IP address.
|
222 |
+
*/
|
223 |
+
protected function IncrementVisitor404( $site_id, $username, $ip ) {
|
224 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
225 |
+
$set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
|
226 |
+
|
227 |
+
$data = $get_fn( self::TRANSIENT_VISITOR_404 );
|
228 |
+
if ( ! $data ) {
|
229 |
+
$data = array();
|
230 |
+
}
|
231 |
+
if ( ! isset( $data[ $site_id . ':' . $username . ':' . $ip ] ) ) {
|
232 |
+
$data[ $site_id . ':' . $username . ':' . $ip ] = 1;
|
233 |
+
}
|
234 |
+
$data[ $site_id . ':' . $username . ':' . $ip ]++;
|
235 |
+
$set_fn( self::TRANSIENT_VISITOR_404, $data, $this->Get404Expiration() );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Event 404 Not found.
|
240 |
+
*/
|
241 |
+
public function Event404() {
|
242 |
+
$attempts = 1;
|
243 |
+
|
244 |
+
global $wp_query;
|
245 |
+
if ( ! $wp_query->is_404 ) {
|
246 |
+
return;
|
247 |
+
}
|
248 |
+
$msg = 'times';
|
249 |
+
|
250 |
+
list( $y, $m, $d ) = explode( '-', date( 'Y-m-d' ) );
|
251 |
+
|
252 |
+
$site_id = ( function_exists( 'get_current_blog_id' ) ? get_current_blog_id() : 0 );
|
253 |
+
$ip = $this->plugin->settings->GetMainClientIP();
|
254 |
+
|
255 |
+
if ( ! is_user_logged_in() ) {
|
256 |
+
$username = 'Website Visitor';
|
257 |
+
} else {
|
258 |
+
$username = wp_get_current_user()->user_login;
|
259 |
+
}
|
260 |
+
|
261 |
+
if ( 'Website Visitor' !== $username ) {
|
262 |
+
// Check if the alert is disabled from the "Enable/Disable Alerts" section.
|
263 |
+
if ( ! $this->plugin->alerts->IsEnabled( 6007 ) ) {
|
264 |
+
return;
|
265 |
+
}
|
266 |
+
|
267 |
+
if ( $this->IsPast404Limit( $site_id, $username, $ip ) ) {
|
268 |
+
return;
|
269 |
+
}
|
270 |
+
|
271 |
+
$obj_occurrence = new WSAL_Models_Occurrence();
|
272 |
+
|
273 |
+
$occ = $obj_occurrence->CheckAlert404(
|
274 |
+
array(
|
275 |
+
$ip,
|
276 |
+
$username,
|
277 |
+
6007,
|
278 |
+
$site_id,
|
279 |
+
mktime( 0, 0, 0, $m, $d, $y ),
|
280 |
+
mktime( 0, 0, 0, $m, $d + 1, $y ) - 1,
|
281 |
+
)
|
282 |
+
);
|
283 |
+
|
284 |
+
$occ = count( $occ ) ? $occ[0] : null;
|
285 |
+
if ( ! empty( $occ ) ) {
|
286 |
+
// update existing record.
|
287 |
+
$this->Increment404( $site_id, $username, $ip );
|
288 |
+
$new = ( (int) $occ->GetMetaValue( 'Attempts', 0 ) ) + 1;
|
289 |
+
|
290 |
+
if ( $new > $this->Get404LogLimit() ) {
|
291 |
+
$new = 'more than ' . $this->Get404LogLimit();
|
292 |
+
$msg .= ' This could possible be a scan, therefore keep an eye on the activity from this IP Address';
|
293 |
+
}
|
294 |
+
|
295 |
+
$link_file = $this->WriteLog( $new, $ip, $username );
|
296 |
+
|
297 |
+
$occ->UpdateMetaValue( 'Attempts', $new );
|
298 |
+
$occ->UpdateMetaValue( 'Username', $username );
|
299 |
+
$occ->UpdateMetaValue( 'Msg', $msg );
|
300 |
+
if ( ! empty( $link_file ) ) {
|
301 |
+
$occ->UpdateMetaValue( 'LinkFile', $link_file );
|
302 |
+
}
|
303 |
+
$occ->created_on = null;
|
304 |
+
$occ->Save();
|
305 |
+
} else {
|
306 |
+
$link_file = $this->WriteLog( 1, $ip, $username );
|
307 |
+
// Create a new record.
|
308 |
+
$fields = array(
|
309 |
+
'Attempts' => 1,
|
310 |
+
'Username' => $username,
|
311 |
+
'Msg' => $msg,
|
312 |
+
);
|
313 |
+
if ( ! empty( $link_file ) ) {
|
314 |
+
$fields['LinkFile'] = $link_file;
|
315 |
+
}
|
316 |
+
$this->plugin->alerts->Trigger( 6007, $fields );
|
317 |
+
}
|
318 |
+
} else {
|
319 |
+
// Check if the alert is disabled from the "Enable/Disable Alerts" section.
|
320 |
+
if ( ! $this->plugin->alerts->IsEnabled( 6023 ) ) {
|
321 |
+
return;
|
322 |
+
}
|
323 |
+
|
324 |
+
if ( $this->IsPastVisitor404Limit( $site_id, $username, $ip ) ) {
|
325 |
+
return;
|
326 |
+
}
|
327 |
+
|
328 |
+
$obj_occurrence = new WSAL_Models_Occurrence();
|
329 |
+
|
330 |
+
$occ = $obj_occurrence->CheckAlert404(
|
331 |
+
array(
|
332 |
+
$ip,
|
333 |
+
$username,
|
334 |
+
6023,
|
335 |
+
$site_id,
|
336 |
+
mktime( 0, 0, 0, $m, $d, $y ),
|
337 |
+
mktime( 0, 0, 0, $m, $d + 1, $y ) - 1,
|
338 |
+
)
|
339 |
+
);
|
340 |
+
|
341 |
+
$occ = count( $occ ) ? $occ[0] : null;
|
342 |
+
if ( ! empty( $occ ) ) {
|
343 |
+
// Update existing record.
|
344 |
+
$this->IncrementVisitor404( $site_id, $username, $ip );
|
345 |
+
$new = ( (int) $occ->GetMetaValue( 'Attempts', 0 ) ) + 1;
|
346 |
+
|
347 |
+
if ( $new > $this->GetVisitor404LogLimit() ) {
|
348 |
+
$new = 'more than ' . $this->GetVisitor404LogLimit();
|
349 |
+
$msg .= ' This could possible be a scan, therefore keep an eye on the activity from this IP Address';
|
350 |
+
}
|
351 |
+
|
352 |
+
$link_file = $this->WriteLog( $new, $ip, $username, false );
|
353 |
+
|
354 |
+
$occ->UpdateMetaValue( 'Attempts', $new );
|
355 |
+
$occ->UpdateMetaValue( 'Username', $username );
|
356 |
+
$occ->UpdateMetaValue( 'Msg', $msg );
|
357 |
+
if ( ! empty( $link_file ) ) {
|
358 |
+
$occ->UpdateMetaValue( 'LinkFile', $link_file );
|
359 |
+
}
|
360 |
+
$occ->created_on = null;
|
361 |
+
$occ->Save();
|
362 |
+
} else {
|
363 |
+
$link_file = $this->WriteLog( 1, $ip, $username, false );
|
364 |
+
// Create a new record.
|
365 |
+
$fields = array(
|
366 |
+
'Attempts' => 1,
|
367 |
+
'Username' => $username,
|
368 |
+
'Msg' => $msg,
|
369 |
+
);
|
370 |
+
if ( ! empty( $link_file ) ) {
|
371 |
+
$fields['LinkFile'] = $link_file;
|
372 |
+
}
|
373 |
+
$this->plugin->alerts->Trigger( 6023, $fields );
|
374 |
+
}
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* Triggered when a user accesses the admin area.
|
380 |
+
*/
|
381 |
+
public function EventAdminInit() {
|
382 |
+
// Filter global arrays for security.
|
383 |
+
$post_array = filter_input_array( INPUT_POST );
|
384 |
+
$get_array = filter_input_array( INPUT_GET );
|
385 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
386 |
+
|
387 |
+
// Destroy all the session of the same user from user profile page.
|
388 |
+
if ( isset( $post_array['action'] ) && ( 'destroy-sessions' == $post_array['action'] ) && isset( $post_array['user_id'] ) ) {
|
389 |
+
$this->plugin->alerts->Trigger(
|
390 |
+
1006, array(
|
391 |
+
'TargetUserID' => $post_array['user_id'],
|
392 |
+
)
|
393 |
+
);
|
394 |
+
}
|
395 |
+
|
396 |
+
// Make sure user can actually modify target options.
|
397 |
+
if ( ! current_user_can( 'manage_options' ) && isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update' ) ) {
|
398 |
+
return;
|
399 |
+
}
|
400 |
+
|
401 |
+
$actype = basename( $server_array['SCRIPT_NAME'], '.php' );
|
402 |
+
$is_option_page = 'options' === $actype;
|
403 |
+
$is_network_settings = 'settings' === $actype;
|
404 |
+
$is_permalink_page = 'options-permalink' === $actype;
|
405 |
+
|
406 |
+
// WordPress URL changed.
|
407 |
+
if ( $is_option_page
|
408 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'general-options' )
|
409 |
+
&& ! empty( $post_array['siteurl'] ) ) {
|
410 |
+
$old_siteurl = get_option( 'siteurl' );
|
411 |
+
$new_siteurl = isset( $post_array['siteurl'] ) ? $post_array['siteurl'] : '';
|
412 |
+
if ( $old_siteurl !== $new_siteurl ) {
|
413 |
+
$this->plugin->alerts->Trigger(
|
414 |
+
6024, array(
|
415 |
+
'old_url' => $old_siteurl,
|
416 |
+
'new_url' => $new_siteurl,
|
417 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
418 |
+
)
|
419 |
+
);
|
420 |
+
}
|
421 |
+
}
|
422 |
+
|
423 |
+
// Site URL changed.
|
424 |
+
if ( $is_option_page
|
425 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'general-options' )
|
426 |
+
&& ! empty( $post_array['home'] ) ) {
|
427 |
+
$old_url = get_option( 'home' );
|
428 |
+
$new_url = isset( $post_array['home'] ) ? $post_array['home'] : '';
|
429 |
+
if ( $old_url !== $new_url ) {
|
430 |
+
$this->plugin->alerts->Trigger(
|
431 |
+
6025, array(
|
432 |
+
'old_url' => $old_url,
|
433 |
+
'new_url' => $new_url,
|
434 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
435 |
+
)
|
436 |
+
);
|
437 |
+
}
|
438 |
+
}
|
439 |
+
|
440 |
+
// Registeration Option.
|
441 |
+
if ( $is_option_page
|
442 |
+
&& wp_verify_nonce( $post_array['_wpnonce'], 'general-options' )
|
443 |
+
&& ( get_option( 'users_can_register' ) xor isset( $post_array['users_can_register'] ) ) ) {
|
444 |
+
$old = get_option( 'users_can_register' ) ? 'Enabled' : 'Disabled';
|
445 |
+
$new = isset( $post_array['users_can_register'] ) ? 'Enabled' : 'Disabled';
|
446 |
+
if ( $old != $new ) {
|
447 |
+
$this->plugin->alerts->Trigger(
|
448 |
+
6001, array(
|
449 |
+
'OldValue' => $old,
|
450 |
+
'NewValue' => $new,
|
451 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
452 |
+
)
|
453 |
+
);
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
+
// Default Role option.
|
458 |
+
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['default_role'] ) ) {
|
459 |
+
$old = get_option( 'default_role' );
|
460 |
+
$new = trim( $post_array['default_role'] );
|
461 |
+
if ( $old != $new ) {
|
462 |
+
$this->plugin->alerts->Trigger(
|
463 |
+
6002, array(
|
464 |
+
'OldRole' => $old,
|
465 |
+
'NewRole' => $new,
|
466 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
467 |
+
)
|
468 |
+
);
|
469 |
+
}
|
470 |
+
}
|
471 |
+
|
472 |
+
// Admin Email Option.
|
473 |
+
if ( $is_option_page && wp_verify_nonce( $post_array['_wpnonce'], 'general-options' ) && ! empty( $post_array['admin_email'] ) ) {
|
474 |
+
$old = get_option( 'admin_email' );
|
475 |
+
$new = trim( $post_array['admin_email'] );
|
476 |
+
if ( $old != $new ) {
|
477 |
+
$this->plugin->alerts->Trigger(
|
478 |
+
6003, array(
|
479 |
+
'OldEmail' => $old,
|
480 |
+
'NewEmail' => $new,
|
481 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
482 |
+
)
|
483 |
+
);
|
484 |
+
}
|
485 |
+
}
|
486 |
+
|
487 |
+
// Admin Email of Network.
|
488 |
+
if ( $is_network_settings && ! empty( $post_array['admin_email'] ) ) {
|
489 |
+
$old = get_site_option( 'admin_email' );
|
490 |
+
$new = trim( $post_array['admin_email'] );
|
491 |
+
if ( $old != $new ) {
|
492 |
+
$this->plugin->alerts->Trigger(
|
493 |
+
6003, array(
|
494 |
+
'OldEmail' => $old,
|
495 |
+
'NewEmail' => $new,
|
496 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
497 |
+
)
|
498 |
+
);
|
499 |
+
}
|
500 |
+
}
|
501 |
+
|
502 |
+
// Permalinks changed.
|
503 |
+
if ( $is_permalink_page && ! empty( $post_array['permalink_structure'] ) ) {
|
504 |
+
$old = get_option( 'permalink_structure' );
|
505 |
+
$new = trim( $post_array['permalink_structure'] );
|
506 |
+
if ( $old != $new ) {
|
507 |
+
$this->plugin->alerts->Trigger(
|
508 |
+
6005, array(
|
509 |
+
'OldPattern' => $old,
|
510 |
+
'NewPattern' => $new,
|
511 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
512 |
+
)
|
513 |
+
);
|
514 |
+
}
|
515 |
+
}
|
516 |
+
|
517 |
+
// Core Update.
|
518 |
+
if ( isset( $get_array['action'] ) && 'do-core-upgrade' === $get_array['action'] && isset( $post_array['version'] ) ) {
|
519 |
+
$old_version = get_bloginfo( 'version' );
|
520 |
+
$new_version = $post_array['version'];
|
521 |
+
if ( $old_version != $new_version ) {
|
522 |
+
$this->plugin->alerts->Trigger(
|
523 |
+
6004, array(
|
524 |
+
'OldVersion' => $old_version,
|
525 |
+
'NewVersion' => $new_version,
|
526 |
+
)
|
527 |
+
);
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
/* BBPress Forum support Setting */
|
532 |
+
if ( isset( $post_array['action'] ) && 'update' === $post_array['action'] && isset( $post_array['_bbp_default_role'] ) ) {
|
533 |
+
$old_role = get_option( '_bbp_default_role' );
|
534 |
+
$new_role = $post_array['_bbp_default_role'];
|
535 |
+
if ( $old_role != $new_role ) {
|
536 |
+
$this->plugin->alerts->Trigger(
|
537 |
+
8009, array(
|
538 |
+
'OldRole' => $old_role,
|
539 |
+
'NewRole' => $new_role,
|
540 |
+
)
|
541 |
+
);
|
542 |
+
}
|
543 |
+
}
|
544 |
+
|
545 |
+
if ( isset( $post_array['action'] ) && 'update' === $post_array['action'] && isset( $post_array['option_page'] ) && ( 'bbpress' === $post_array['option_page'] ) ) {
|
546 |
+
// Anonymous posting.
|
547 |
+
$allow_anonymous = get_option( '_bbp_allow_anonymous' );
|
548 |
+
$old_status = ! empty( $allow_anonymous ) ? 1 : 0;
|
549 |
+
$new_status = ! empty( $post_array['_bbp_allow_anonymous'] ) ? 1 : 0;
|
550 |
+
if ( $old_status !== $new_status ) {
|
551 |
+
$status = ( 1 === $new_status ) ? 'Enabled' : 'Disabled';
|
552 |
+
$this->plugin->alerts->Trigger(
|
553 |
+
8010, array(
|
554 |
+
'Status' => $status,
|
555 |
+
)
|
556 |
+
);
|
557 |
+
}
|
558 |
+
|
559 |
+
// Disallow editing after.
|
560 |
+
$bbp_edit_lock = get_option( '_bbp_edit_lock' );
|
561 |
+
$old_time = ! empty( $bbp_edit_lock ) ? $bbp_edit_lock : '';
|
562 |
+
$new_time = ! empty( $post_array['_bbp_edit_lock'] ) ? $post_array['_bbp_edit_lock'] : '';
|
563 |
+
if ( $old_time != $new_time ) {
|
564 |
+
$this->plugin->alerts->Trigger(
|
565 |
+
8012, array(
|
566 |
+
'OldTime' => $old_time,
|
567 |
+
'NewTime' => $new_time,
|
568 |
+
)
|
569 |
+
);
|
570 |
+
}
|
571 |
+
|
572 |
+
// Throttle posting every.
|
573 |
+
$bbp_throttle_time = get_option( '_bbp_throttle_time' );
|
574 |
+
$old_time2 = ! empty( $bbp_throttle_time ) ? $bbp_throttle_time : '';
|
575 |
+
$new_time2 = ! empty( $post_array['_bbp_throttle_time'] ) ? $post_array['_bbp_throttle_time'] : '';
|
576 |
+
if ( $old_time2 != $new_time2 ) {
|
577 |
+
$this->plugin->alerts->Trigger(
|
578 |
+
8013, array(
|
579 |
+
'OldTime' => $old_time2,
|
580 |
+
'NewTime' => $new_time2,
|
581 |
+
)
|
582 |
+
);
|
583 |
+
}
|
584 |
+
}
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* WordPress auto core update.
|
589 |
+
*
|
590 |
+
* @param array $automatic - Automatic update array.
|
591 |
+
*/
|
592 |
+
public function WPUpdate( $automatic ) {
|
593 |
+
if ( isset( $automatic['core'][0] ) ) {
|
594 |
+
$obj = $automatic['core'][0];
|
595 |
+
$old_version = get_bloginfo( 'version' );
|
596 |
+
$this->plugin->alerts->Trigger(
|
597 |
+
6004, array(
|
598 |
+
'OldVersion' => $old_version,
|
599 |
+
'NewVersion' => $obj->item->version . ' (auto update)',
|
600 |
+
)
|
601 |
+
);
|
602 |
+
}
|
603 |
+
}
|
604 |
+
|
605 |
+
/**
|
606 |
+
* Purge log files older than one month.
|
607 |
+
*/
|
608 |
+
public function LogFilesPruning() {
|
609 |
+
if ( $this->plugin->GetGlobalOption( 'purge-404-log', 'off' ) == 'on' ) {
|
610 |
+
$upload_dir = wp_upload_dir();
|
611 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/users/';
|
612 |
+
if ( is_dir( $uploads_dir_path ) ) {
|
613 |
+
if ( $handle = opendir( $uploads_dir_path ) ) {
|
614 |
+
while ( false !== ($entry = readdir( $handle )) ) {
|
615 |
+
if ( '.' != $entry && '..' != $entry ) {
|
616 |
+
if ( file_exists( $uploads_dir_path . $entry ) ) {
|
617 |
+
$modified = filemtime( $uploads_dir_path . $entry );
|
618 |
+
if ( $modified < strtotime( '-4 weeks' ) ) {
|
619 |
+
// Delete file.
|
620 |
+
unlink( $uploads_dir_path . $entry );
|
621 |
+
}
|
622 |
+
}
|
623 |
+
}
|
624 |
+
}
|
625 |
+
closedir( $handle );
|
626 |
+
}
|
627 |
+
}
|
628 |
+
}
|
629 |
+
if ( 'on' == $this->plugin->GetGlobalOption( 'purge-visitor-404-log', 'off' ) ) {
|
630 |
+
$upload_dir = wp_upload_dir();
|
631 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/visitors/';
|
632 |
+
if ( is_dir( $uploads_dir_path ) ) {
|
633 |
+
if ( $handle = opendir( $uploads_dir_path ) ) {
|
634 |
+
while ( false !== ( $entry = readdir( $handle ) ) ) {
|
635 |
+
if ( $entry != '.' && $entry != '..' ) {
|
636 |
+
if ( file_exists( $uploads_dir_path . $entry ) ) {
|
637 |
+
$modified = filemtime( $uploads_dir_path . $entry );
|
638 |
+
if ( $modified < strtotime( '-4 weeks' ) ) {
|
639 |
+
// Delete file.
|
640 |
+
unlink( $uploads_dir_path . $entry );
|
641 |
+
}
|
642 |
+
}
|
643 |
+
}
|
644 |
+
}
|
645 |
+
closedir( $handle );
|
646 |
+
}
|
647 |
+
}
|
648 |
+
}
|
649 |
+
}
|
650 |
+
|
651 |
+
/**
|
652 |
+
* Events from 6008 to 6018.
|
653 |
+
*
|
654 |
+
* @param array $whitelist - White list options.
|
655 |
+
*/
|
656 |
+
public function EventOptions( $whitelist = null ) {
|
657 |
+
// Filter global arrays for security.
|
658 |
+
$post_array = filter_input_array( INPUT_POST );
|
659 |
+
$get_array = filter_input_array( INPUT_GET );
|
660 |
+
|
661 |
+
if ( isset( $post_array['option_page'] ) && 'reading' === $post_array['option_page'] ) {
|
662 |
+
$old_status = (int) get_option( 'blog_public', 1 );
|
663 |
+
$new_status = isset( $post_array['blog_public'] ) ? 0 : 1;
|
664 |
+
if ( $old_status !== $new_status ) {
|
665 |
+
$this->plugin->alerts->Trigger(
|
666 |
+
6008, array(
|
667 |
+
'Status' => ( 0 === $new_status ) ? 'Enabled' : 'Disabled',
|
668 |
+
)
|
669 |
+
);
|
670 |
+
}
|
671 |
+
}
|
672 |
+
|
673 |
+
if ( isset( $post_array['option_page'] ) && 'discussion' === $post_array['option_page'] ) {
|
674 |
+
$old_status = get_option( 'default_comment_status', 'closed' );
|
675 |
+
$new_status = isset( $post_array['default_comment_status'] ) ? 'open' : 'closed';
|
676 |
+
if ( $old_status !== $new_status ) {
|
677 |
+
$this->plugin->alerts->Trigger(
|
678 |
+
6009, array(
|
679 |
+
'Status' => ( 'open' === $new_status ) ? 'Enabled' : 'Disabled',
|
680 |
+
)
|
681 |
+
);
|
682 |
+
}
|
683 |
+
|
684 |
+
$old_status = (int) get_option( 'require_name_email', 0 );
|
685 |
+
$new_status = isset( $post_array['require_name_email'] ) ? 1 : 0;
|
686 |
+
if ( $old_status !== $new_status ) {
|
687 |
+
$this->plugin->alerts->Trigger(
|
688 |
+
6010, array(
|
689 |
+
'Status' => ( 1 === $new_status ) ? 'Enabled' : 'Disabled',
|
690 |
+
)
|
691 |
+
);
|
692 |
+
}
|
693 |
+
|
694 |
+
$old_status = (int) get_option( 'comment_registration', 0 );
|
695 |
+
$new_status = isset( $post_array['comment_registration'] ) ? 1 : 0;
|
696 |
+
if ( $old_status !== $new_status ) {
|
697 |
+
$this->plugin->alerts->Trigger(
|
698 |
+
6011, array(
|
699 |
+
'Status' => ( 1 === $new_status ) ? 'Enabled' : 'Disabled',
|
700 |
+
)
|
701 |
+
);
|
702 |
+
}
|
703 |
+
|
704 |
+
$old_status = (int) get_option( 'close_comments_for_old_posts', 0 );
|
705 |
+
$new_status = isset( $post_array['close_comments_for_old_posts'] ) ? 1 : 0;
|
706 |
+
if ( $old_status !== $new_status ) {
|
707 |
+
$value = isset( $post_array['close_comments_days_old'] ) ? $post_array['close_comments_days_old'] : 0;
|
708 |
+
$this->plugin->alerts->Trigger(
|
709 |
+
6012, array(
|
710 |
+
'Status' => ( 1 === $new_status ) ? 'Enabled' : 'Disabled',
|
711 |
+
'Value' => $value,
|
712 |
+
)
|
713 |
+
);
|
714 |
+
}
|
715 |
+
|
716 |
+
$old_value = get_option( 'close_comments_days_old', 0 );
|
717 |
+
$new_value = isset( $post_array['close_comments_days_old'] ) ? $post_array['close_comments_days_old'] : 0;
|
718 |
+
if ( $old_value !== $new_value ) {
|
719 |
+
$this->plugin->alerts->Trigger(
|
720 |
+
6013, array(
|
721 |
+
'OldValue' => $old_value,
|
722 |
+
'NewValue' => $new_value,
|
723 |
+
)
|
724 |
+
);
|
725 |
+
}
|
726 |
+
|
727 |
+
$old_status = (int) get_option( 'comment_moderation', 0 );
|
728 |
+
$new_status = isset( $post_array['comment_moderation'] ) ? 1 : 0;
|
729 |
+
if ( $old_status !== $new_status ) {
|
730 |
+
$this->plugin->alerts->Trigger(
|
731 |
+
6014, array(
|
732 |
+
'Status' => ( 1 === $new_status ) ? 'Enabled' : 'Disabled',
|
733 |
+
)
|
734 |
+
);
|
735 |
+
}
|
736 |
+
|
737 |
+
$old_status = (int) get_option( 'comment_whitelist', 0 );
|
738 |
+
$new_status = isset( $post_array['comment_whitelist'] ) ? 1 : 0;
|
739 |
+
if ( $old_status !== $new_status ) {
|
740 |
+
$this->plugin->alerts->Trigger(
|
741 |
+
6015, array(
|
742 |
+
'Status' => ( 1 === $new_status ) ? 'Enabled' : 'Disabled',
|
743 |
+
)
|
744 |
+
);
|
745 |
+
}
|
746 |
+
|
747 |
+
$old_value = get_option( 'comment_max_links', 0 );
|
748 |
+
$new_value = isset( $post_array['comment_max_links'] ) ? $post_array['comment_max_links'] : 0;
|
749 |
+
if ( $old_value !== $new_value ) {
|
750 |
+
$this->plugin->alerts->Trigger(
|
751 |
+
6016, array(
|
752 |
+
'OldValue' => $old_value,
|
753 |
+
'NewValue' => $new_value,
|
754 |
+
)
|
755 |
+
);
|
756 |
+
}
|
757 |
+
|
758 |
+
$old_value = get_option( 'moderation_keys', 0 );
|
759 |
+
$new_value = isset( $post_array['moderation_keys'] ) ? $post_array['moderation_keys'] : 0;
|
760 |
+
if ( $old_value !== $new_value ) {
|
761 |
+
$this->plugin->alerts->Trigger( 6017, array() );
|
762 |
+
}
|
763 |
+
|
764 |
+
$old_value = get_option( 'blacklist_keys', 0 );
|
765 |
+
$new_value = isset( $post_array['blacklist_keys'] ) ? $post_array['blacklist_keys'] : 0;
|
766 |
+
if ( $old_value !== $new_value ) {
|
767 |
+
$this->plugin->alerts->Trigger( 6018, array() );
|
768 |
+
}
|
769 |
+
}
|
770 |
+
return $whitelist;
|
771 |
+
}
|
772 |
+
|
773 |
+
/**
|
774 |
+
* Write Log.
|
775 |
+
*
|
776 |
+
* Write a new line on 404 log file.
|
777 |
+
* Folder: /uploads/wp-security-audit-log/404s/
|
778 |
+
*
|
779 |
+
* @param int $attempts - Number of attempt.
|
780 |
+
* @param string $ip - IP address.
|
781 |
+
* @param string $username - Username.
|
782 |
+
* @param bool $logged_in - True if logged in.
|
783 |
+
*/
|
784 |
+
private function WriteLog( $attempts, $ip, $username = '', $logged_in = true ) {
|
785 |
+
$name_file = null;
|
786 |
+
|
787 |
+
if ( $logged_in ) {
|
788 |
+
if ( 'on' === $this->plugin->GetGlobalOption( 'log-404', 'off' ) ) {
|
789 |
+
// Filter global arrays for security.
|
790 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
791 |
+
|
792 |
+
// Request URL.
|
793 |
+
$request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL );
|
794 |
+
$url = site_url() . $request_uri;
|
795 |
+
|
796 |
+
// Get option to log referrer.
|
797 |
+
$log_referrer = $this->plugin->GetGlobalOption( 'log-404-referrer' );
|
798 |
+
|
799 |
+
if ( 'on' === $log_referrer ) {
|
800 |
+
// Get the referer.
|
801 |
+
if ( isset( $server_array['HTTP_REFERER'] ) ) {
|
802 |
+
$referrer = filter_input( INPUT_SERVER, 'HTTP_REFERER', FILTER_SANITIZE_URL );
|
803 |
+
}
|
804 |
+
|
805 |
+
// Create/Append to the log file.
|
806 |
+
$data = 'Request URL ' . $url . ' Referer ' . $referrer . ',';
|
807 |
+
} else {
|
808 |
+
// Create/Append to the log file.
|
809 |
+
$data = 'Request URL ' . $url . ',';
|
810 |
+
}
|
811 |
+
|
812 |
+
if ( ! is_user_logged_in() ) {
|
813 |
+
$username = '';
|
814 |
+
} else {
|
815 |
+
$username = $username . '_';
|
816 |
+
}
|
817 |
+
|
818 |
+
if ( '127.0.0.1' == $ip || '::1' == $ip ) {
|
819 |
+
$ip = 'localhost';
|
820 |
+
}
|
821 |
+
$upload_dir = wp_upload_dir();
|
822 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/users/';
|
823 |
+
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/404s/users/';
|
824 |
+
|
825 |
+
// Check directory.
|
826 |
+
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
827 |
+
$filename = '6007_' . date( 'Ymd' ) . '.log';
|
828 |
+
$fp = $uploads_dir_path . $filename;
|
829 |
+
$name_file = $uploads_url . $filename;
|
830 |
+
if ( ! $file = fopen( $fp, 'a' ) ) {
|
831 |
+
$i = 1;
|
832 |
+
$file_opened = false;
|
833 |
+
do {
|
834 |
+
$fp2 = substr( $fp, 0, -4 ) . '_' . $i . '.log';
|
835 |
+
if ( ! file_exists( $fp2 ) ) {
|
836 |
+
if ( $file = fopen( $fp2, 'a' ) ) {
|
837 |
+
$file_opened = true;
|
838 |
+
$name_file = $uploads_url . substr( $name_file, 0, -4 ) . '_' . $i . '.log';
|
839 |
+
}
|
840 |
+
} else {
|
841 |
+
$latest_filename = $this->GetLastModified( $uploads_dir_path, $filename );
|
842 |
+
$fp_last = $uploads_dir_path . $latest_filename;
|
843 |
+
if ( $file = fopen( $fp_last, 'a' ) ) {
|
844 |
+
$file_opened = true;
|
845 |
+
$name_file = $uploads_url . $latest_filename;
|
846 |
+
}
|
847 |
+
}
|
848 |
+
$i++;
|
849 |
+
} while ( ! $file_opened );
|
850 |
+
}
|
851 |
+
fwrite( $file, sprintf( "%s\n", $data ) );
|
852 |
+
fclose( $file );
|
853 |
+
}
|
854 |
+
}
|
855 |
+
} else {
|
856 |
+
if ( 'on' === $this->plugin->GetGlobalOption( 'log-visitor-404', 'off' ) ) {
|
857 |
+
// Filter global arrays for security.
|
858 |
+
$server_array = filter_input_array( INPUT_SERVER );
|
859 |
+
|
860 |
+
// Request URL.
|
861 |
+
$request_uri = filter_input( INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL );
|
862 |
+
$url = site_url() . $request_uri;
|
863 |
+
|
864 |
+
// Get option to log referrer.
|
865 |
+
$log_referrer = $this->plugin->GetGlobalOption( 'log-visitor-404-referrer' );
|
866 |
+
|
867 |
+
if ( 'on' === $log_referrer ) {
|
868 |
+
// Get the referer.
|
869 |
+
if ( isset( $server_array['HTTP_REFERER'] ) ) {
|
870 |
+
$referrer = filter_input( INPUT_SERVER, 'HTTP_REFERER', FILTER_SANITIZE_URL );
|
871 |
+
}
|
872 |
+
|
873 |
+
// Create/Append to the log file.
|
874 |
+
$data = 'Request URL ' . $url . ' Referer ' . $referrer . ',';
|
875 |
+
} else {
|
876 |
+
// Create/Append to the log file.
|
877 |
+
$data = 'Request URL ' . $url . ',';
|
878 |
+
}
|
879 |
+
|
880 |
+
$username = '';
|
881 |
+
|
882 |
+
if ( '127.0.0.1' == $ip || '::1' == $ip ) {
|
883 |
+
$ip = 'localhost';
|
884 |
+
}
|
885 |
+
$upload_dir = wp_upload_dir();
|
886 |
+
$uploads_dir_path = trailingslashit( $upload_dir['basedir'] ) . 'wp-security-audit-log/404s/visitors/';
|
887 |
+
$uploads_url = trailingslashit( $upload_dir['baseurl'] ) . 'wp-security-audit-log/404s/visitors/';
|
888 |
+
|
889 |
+
// Check directory.
|
890 |
+
if ( $this->CheckDirectory( $uploads_dir_path ) ) {
|
891 |
+
$filename = '6023_' . date( 'Ymd' ) . '.log';
|
892 |
+
$fp = $uploads_dir_path . $filename;
|
893 |
+
$name_file = $uploads_url . $filename;
|
894 |
+
if ( ! $file = fopen( $fp, 'a' ) ) {
|
895 |
+
$i = 1;
|
896 |
+
$file_opened = false;
|
897 |
+
do {
|
898 |
+
$fp2 = substr( $fp, 0, -4 ) . '_' . $i . '.log';
|
899 |
+
if ( ! file_exists( $fp2 ) ) {
|
900 |
+
if ( $file = fopen( $fp2, 'a' ) ) {
|
901 |
+
$file_opened = true;
|
902 |
+
$name_file = $uploads_url . substr( $name_file, 0, -4 ) . '_' . $i . '.log';
|
903 |
+
}
|
904 |
+
} else {
|
905 |
+
$latest_filename = $this->GetLastModified( $uploads_dir_path, $filename );
|
906 |
+
$fp_last = $uploads_dir_path . $latest_filename;
|
907 |
+
if ( $file = fopen( $fp_last, 'a' ) ) {
|
908 |
+
$file_opened = true;
|
909 |
+
$name_file = $uploads_url . $latest_filename;
|
910 |
+
}
|
911 |
+
}
|
912 |
+
$i++;
|
913 |
+
} while ( ! $file_opened );
|
914 |
+
}
|
915 |
+
fwrite( $file, sprintf( "%s\n", $data ) );
|
916 |
+
fclose( $file );
|
917 |
+
}
|
918 |
+
}
|
919 |
+
}
|
920 |
+
|
921 |
+
return $name_file;
|
922 |
+
}
|
923 |
+
|
924 |
+
/**
|
925 |
+
* Get the latest file modified.
|
926 |
+
*
|
927 |
+
* @param string $uploads_dir_path - Uploads directory path.
|
928 |
+
* @param string $filename - File name.
|
929 |
+
* @return string $latest_filename - File name.
|
930 |
+
*/
|
931 |
+
private function GetLastModified( $uploads_dir_path, $filename ) {
|
932 |
+
$filename = substr( $filename, 0, -4 );
|
933 |
+
$latest_mtime = 0;
|
934 |
+
$latest_filename = '';
|
935 |
+
if ( $handle = opendir( $uploads_dir_path ) ) {
|
936 |
+
while ( false !== ($entry = readdir( $handle )) ) {
|
937 |
+
if ( '.' != $entry && '..' != $entry ) {
|
938 |
+
$entry = strip_tags( $entry ); // Strip HTML Tags.
|
939 |
+
$entry = preg_replace( '/[\r\n\t ]+/', ' ', $entry ); // Remove Break/Tabs/Return Carriage.
|
940 |
+
$entry = preg_replace( '/[\"\*\/\:\<\>\?\'\|]+/', ' ', $entry ); // Remove Illegal Chars for folder and filename.
|
941 |
+
if ( preg_match( '/^' . $filename . '/i', $entry ) > 0 ) {
|
942 |
+
if ( filemtime( $uploads_dir_path . $entry ) > $latest_mtime ) {
|
943 |
+
$latest_mtime = filemtime( $uploads_dir_path . $entry );
|
944 |
+
$latest_filename = $entry;
|
945 |
+
}
|
946 |
+
}
|
947 |
+
}
|
948 |
+
}
|
949 |
+
closedir( $handle );
|
950 |
+
}
|
951 |
+
return $latest_filename;
|
952 |
+
}
|
953 |
}
|
classes/Sensors/UserProfile.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* User Profiles sensor.
|
6 |
*
|
7 |
* 4000 New user was created on WordPress
|
@@ -16,188 +28,258 @@
|
|
16 |
* 4009 User revoked from Super Admin privileges
|
17 |
* 4013 The forum role of a user was changed by another WordPress user
|
18 |
* 4014 User opened the profile page of another user
|
|
|
|
|
|
|
19 |
*/
|
20 |
-
class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: User Profile
|
4 |
+
*
|
5 |
+
* User profile sensor file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* User Profiles sensor.
|
18 |
*
|
19 |
* 4000 New user was created on WordPress
|
28 |
* 4009 User revoked from Super Admin privileges
|
29 |
* 4013 The forum role of a user was changed by another WordPress user
|
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 {
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Listening to events using WP hooks.
|
39 |
+
*/
|
40 |
+
public function HookEvents() {
|
41 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
42 |
+
add_action( 'user_register', array( $this, 'EventUserRegister' ) );
|
43 |
+
add_action( 'edit_user_profile_update', array( $this, 'EventUserChanged' ) );
|
44 |
+
add_action( 'personal_options_update', array( $this, 'EventUserChanged' ) );
|
45 |
+
add_action( 'delete_user', array( $this, 'EventUserDeleted' ) );
|
46 |
+
add_action( 'wpmu_delete_user', array( $this, 'EventUserDeleted' ) );
|
47 |
+
add_action( 'set_user_role', array( $this, 'EventUserRoleChanged' ), 10, 3 );
|
48 |
+
|
49 |
+
add_action( 'edit_user_profile', array( $this, 'EventOpenProfile' ), 10, 1 );
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* List of super admins.
|
54 |
+
*
|
55 |
+
* @var array
|
56 |
+
*/
|
57 |
+
protected $old_superadmins;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Triggered when a user accesses the admin area.
|
61 |
+
*/
|
62 |
+
public function EventAdminInit() {
|
63 |
+
if ( $this->IsMultisite() ) {
|
64 |
+
$this->old_superadmins = get_super_admins();
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Triggered when a user is registered.
|
70 |
+
*
|
71 |
+
* @param int $user_id - User ID of the registered user.
|
72 |
+
*/
|
73 |
+
public function EventUserRegister( $user_id ) {
|
74 |
+
$user = get_userdata( $user_id );
|
75 |
+
$ismu = function_exists( 'is_multisite' ) && is_multisite();
|
76 |
+
$event = $ismu ? 4012 : (is_user_logged_in() ? 4001 : 4000);
|
77 |
+
$current_user = wp_get_current_user();
|
78 |
+
$this->plugin->alerts->Trigger(
|
79 |
+
$event, array(
|
80 |
+
'NewUserID' => $user_id,
|
81 |
+
'UserChanger' => ! empty( $current_user ) ? $current_user->user_login : '',
|
82 |
+
'NewUserData' => (object) array(
|
83 |
+
'Username' => $user->user_login,
|
84 |
+
'FirstName' => $user->user_firstname,
|
85 |
+
'LastName' => $user->user_lastname,
|
86 |
+
'Email' => $user->user_email,
|
87 |
+
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
88 |
+
),
|
89 |
+
), true
|
90 |
+
);
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Triggered when a user role is changed.
|
95 |
+
*
|
96 |
+
* @param int $user_id - User ID of the user.
|
97 |
+
* @param string $role - String of new roles.
|
98 |
+
* @param string $old_roles - String of old roles.
|
99 |
+
*/
|
100 |
+
public function EventUserRoleChanged( $user_id, $role, $old_roles ) {
|
101 |
+
// Filter $_POST array for security.
|
102 |
+
$post_array = filter_input_array( INPUT_POST );
|
103 |
+
|
104 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'update-user_' . $user_id ) ) {
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
|
108 |
+
$user = get_userdata( $user_id );
|
109 |
+
$bbpress_roles = array( 'bbp_spectator', 'bbp_moderator', 'bbp_participant', 'bbp_keymaster', 'bbp_blocked' );
|
110 |
+
// Remove any BBPress roles.
|
111 |
+
if ( is_array( $old_roles ) ) {
|
112 |
+
foreach ( $old_roles as $value ) {
|
113 |
+
if ( in_array( $value, $bbpress_roles ) ) {
|
114 |
+
if ( isset( $post_array['bbp-forums-role'] ) && $post_array['bbp-forums-role'] != $value ) {
|
115 |
+
$current_user = wp_get_current_user();
|
116 |
+
$this->plugin->alerts->TriggerIf(
|
117 |
+
4013, array(
|
118 |
+
'TargetUsername' => $user->user_login,
|
119 |
+
'OldRole' => ucfirst( substr( $value, 4 ) ),
|
120 |
+
'NewRole' => ( isset( $post_array['bbp-forums-role'] ) ) ? ucfirst( substr( $post_array['bbp-forums-role'], 4 ) ) : false,
|
121 |
+
'UserChanger' => $current_user->user_login,
|
122 |
+
)
|
123 |
+
);
|
124 |
+
}
|
125 |
+
}
|
126 |
+
}
|
127 |
+
$old_roles = array_diff( $old_roles, $bbpress_roles );
|
128 |
+
}
|
129 |
+
$old_role = count( $old_roles ) ? implode( ', ', $old_roles ) : '';
|
130 |
+
$new_role = $role;
|
131 |
+
if ( $old_role != $new_role ) {
|
132 |
+
$this->plugin->alerts->TriggerIf(
|
133 |
+
4002, array(
|
134 |
+
'TargetUserID' => $user_id,
|
135 |
+
'TargetUsername' => $user->user_login,
|
136 |
+
'OldRole' => $old_role,
|
137 |
+
'NewRole' => $new_role,
|
138 |
+
), array( $this, 'MustNotContainUserChanges' )
|
139 |
+
);
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Triggered when a user changes email, password
|
145 |
+
* or user is granted or revoked super admin access.
|
146 |
+
*
|
147 |
+
* @param int $user_id - User ID of the registered user.
|
148 |
+
*/
|
149 |
+
public function EventUserChanged( $user_id ) {
|
150 |
+
// Filter $_POST array for security.
|
151 |
+
$post_array = filter_input_array( INPUT_POST );
|
152 |
+
|
153 |
+
// Get user data.
|
154 |
+
$user = get_userdata( $user_id );
|
155 |
+
|
156 |
+
// Password changed.
|
157 |
+
if ( ! empty( $post_array['pass1'] ) && ! empty( $post_array['pass2'] ) ) {
|
158 |
+
if ( trim( $post_array['pass1'] ) == trim( $post_array['pass2'] ) ) {
|
159 |
+
$event = get_current_user_id() == $user_id ? 4003 : 4004;
|
160 |
+
$this->plugin->alerts->Trigger(
|
161 |
+
$event, array(
|
162 |
+
'TargetUserID' => $user_id,
|
163 |
+
'TargetUserData' => (object) array(
|
164 |
+
'Username' => $user->user_login,
|
165 |
+
'Roles' => is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles,
|
166 |
+
),
|
167 |
+
)
|
168 |
+
);
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
// Email changed.
|
173 |
+
if ( ! empty( $post_array['email'] ) ) {
|
174 |
+
$old_email = $user->user_email;
|
175 |
+
$new_email = trim( $post_array['email'] );
|
176 |
+
if ( $old_email != $new_email ) {
|
177 |
+
$event = get_current_user_id() == $user_id ? 4005 : 4006;
|
178 |
+
$this->plugin->alerts->Trigger(
|
179 |
+
$event, array(
|
180 |
+
'TargetUserID' => $user_id,
|
181 |
+
'TargetUsername' => $user->user_login,
|
182 |
+
'OldEmail' => $old_email,
|
183 |
+
'NewEmail' => $new_email,
|
184 |
+
)
|
185 |
+
);
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
if ( $this->IsMultisite() ) {
|
190 |
+
$username = $user->user_login;
|
191 |
+
$enabled = isset( $post_array['super_admin'] );
|
192 |
+
|
193 |
+
if ( get_current_user_id() != $user_id ) {
|
194 |
+
// Super admin enabled.
|
195 |
+
if ( $enabled && ! in_array( $username, $this->old_superadmins ) ) {
|
196 |
+
$this->plugin->alerts->Trigger(
|
197 |
+
4008, array(
|
198 |
+
'TargetUserID' => $user_id,
|
199 |
+
'TargetUsername' => $user->user_login,
|
200 |
+
)
|
201 |
+
);
|
202 |
+
}
|
203 |
+
|
204 |
+
// Super admin disabled.
|
205 |
+
if ( ! $enabled && in_array( $username, $this->old_superadmins ) ) {
|
206 |
+
$this->plugin->alerts->Trigger(
|
207 |
+
4009, array(
|
208 |
+
'TargetUserID' => $user_id,
|
209 |
+
'TargetUsername' => $user->user_login,
|
210 |
+
)
|
211 |
+
);
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Triggered when a user is deleted.
|
219 |
+
*
|
220 |
+
* @param int $user_id - User ID of the registered user.
|
221 |
+
*/
|
222 |
+
public function EventUserDeleted( $user_id ) {
|
223 |
+
$user = get_userdata( $user_id );
|
224 |
+
$role = is_array( $user->roles ) ? implode( ', ', $user->roles ) : $user->roles;
|
225 |
+
$this->plugin->alerts->TriggerIf(
|
226 |
+
4007, array(
|
227 |
+
'TargetUserID' => $user_id,
|
228 |
+
'TargetUserData' => (object) array(
|
229 |
+
'Username' => $user->user_login,
|
230 |
+
'FirstName' => $user->user_firstname,
|
231 |
+
'LastName' => $user->user_lastname,
|
232 |
+
'Email' => $user->user_email,
|
233 |
+
'Roles' => $role ? $role : 'none',
|
234 |
+
),
|
235 |
+
), array( $this, 'MustNotContainCreateUser' )
|
236 |
+
);
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Triggered when a user profile is opened.
|
241 |
+
*
|
242 |
+
* @param object $user - Instance of WP_User.
|
243 |
+
*/
|
244 |
+
public function EventOpenProfile( $user ) {
|
245 |
+
if ( ! empty( $user ) ) {
|
246 |
+
$current_user = wp_get_current_user();
|
247 |
+
|
248 |
+
// Filter $_GET array for security.
|
249 |
+
$get_array = filter_input_array( INPUT_GET );
|
250 |
+
|
251 |
+
$updated = ( isset( $get_array['updated'] ) ) ? true : false;
|
252 |
+
if ( ! empty( $current_user ) && ( $user->ID !== $current_user->ID ) && empty( $updated ) ) {
|
253 |
+
$this->plugin->alerts->Trigger(
|
254 |
+
4014, array(
|
255 |
+
'UserChanger' => $current_user->user_login,
|
256 |
+
'TargetUsername' => $user->user_login,
|
257 |
+
)
|
258 |
+
);
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Must Not Contain Create User.
|
265 |
+
*
|
266 |
+
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
267 |
+
*/
|
268 |
+
public function MustNotContainCreateUser( WSAL_AlertManager $mgr ) {
|
269 |
+
return ! $mgr->WillTrigger( 4012 );
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Must Not Contain User Changes.
|
274 |
+
*
|
275 |
+
* @param WSAL_AlertManager $mgr - Instance of WSAL_AlertManager.
|
276 |
+
*/
|
277 |
+
public function MustNotContainUserChanges( WSAL_AlertManager $mgr ) {
|
278 |
+
return ! ( $mgr->WillOrHasTriggered( 4010 )
|
279 |
+
|| $mgr->WillOrHasTriggered( 4011 )
|
280 |
+
|| $mgr->WillOrHasTriggered( 4012 )
|
281 |
+
|| $mgr->WillOrHasTriggered( 4000 )
|
282 |
+
|| $mgr->WillOrHasTriggered( 4001 )
|
283 |
+
);
|
284 |
+
}
|
285 |
}
|
classes/Sensors/Widgets.php
CHANGED
@@ -1,7 +1,19 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Widgets sensor.
|
6 |
*
|
7 |
* 2042 User added a new widget
|
@@ -9,256 +21,291 @@
|
|
9 |
* 2044 User deleted widget
|
10 |
* 2045 User moved widget
|
11 |
* 2071 User changed widget position
|
|
|
|
|
|
|
12 |
*/
|
13 |
-
class WSAL_Sensors_Widgets extends WSAL_AbstractSensor
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Triggered when a user accesses the admin area.
|
31 |
-
* Moved widget.
|
32 |
-
*/
|
33 |
-
public function EventWidgetMove()
|
34 |
-
{
|
35 |
-
if (isset($_POST) && !empty($_POST['sidebars'])) {
|
36 |
-
$crtSidebars = $_POST['sidebars'];
|
37 |
-
$sidebars = array();
|
38 |
-
foreach ($crtSidebars as $key => $val) {
|
39 |
-
$sb = array();
|
40 |
-
if (!empty($val)) {
|
41 |
-
$val = explode(',', $val);
|
42 |
-
foreach ($val as $k => $v) {
|
43 |
-
if (strpos($v, 'widget-') === false) {
|
44 |
-
continue;
|
45 |
-
}
|
46 |
-
$sb[$k] = substr($v, strpos($v, '_') + 1);
|
47 |
-
}
|
48 |
-
}
|
49 |
-
$sidebars[$key] = $sb;
|
50 |
-
}
|
51 |
-
$crtSidebars = $sidebars;
|
52 |
-
$dbSidebars = get_option('sidebars_widgets');
|
53 |
-
$wName = $fromSidebar = $toSidebar = '';
|
54 |
-
foreach ($crtSidebars as $sidebarName => $values) {
|
55 |
-
if (is_array($values) && ! empty($values) && isset($dbSidebars[$sidebarName])) {
|
56 |
-
foreach ($values as $widgetName) {
|
57 |
-
if (! in_array($widgetName, $dbSidebars[$sidebarName])) {
|
58 |
-
$toSidebar = $sidebarName;
|
59 |
-
$wName = $widgetName;
|
60 |
-
foreach ($dbSidebars as $name => $v) {
|
61 |
-
if (is_array($v) && !empty($v) && in_array($widgetName, $v)) {
|
62 |
-
$fromSidebar = $name;
|
63 |
-
continue;
|
64 |
-
}
|
65 |
-
}
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
}
|
70 |
-
|
71 |
-
if (empty($wName) || empty($fromSidebar) || empty($toSidebar)) {
|
72 |
-
return;
|
73 |
-
}
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
return;
|
82 |
-
}
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
'NewSidebar' => $toSidebar,
|
88 |
-
));
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
/**
|
93 |
-
* Triggered when a user accesses the admin area.
|
94 |
-
* Changed widget position or moved widget.
|
95 |
-
*/
|
96 |
-
public function EventWidgetPostMove()
|
97 |
-
{
|
98 |
-
// #!-- generates the event 2071
|
99 |
-
if (isset($_REQUEST['action']) && ($_REQUEST['action']=='widgets-order')) {
|
100 |
-
if (isset($_REQUEST['sidebars'])) {
|
101 |
-
// Get the sidebars from $_REQUEST
|
102 |
-
$requestSidebars = array();
|
103 |
-
if ($_REQUEST['sidebars']) {
|
104 |
-
foreach ($_REQUEST['sidebars'] as $key => &$value) {
|
105 |
-
if (!empty($value)) {
|
106 |
-
// build the sidebars array
|
107 |
-
$value = explode(',', $value);
|
108 |
-
// Cleanup widgets' name
|
109 |
-
foreach ($value as $k => &$widgetName) {
|
110 |
-
$widgetName = preg_replace("/^([a-z]+-[0-9]+)+?_/i", '', $widgetName);
|
111 |
-
}
|
112 |
-
$requestSidebars[$key] = $value;
|
113 |
-
}
|
114 |
-
}
|
115 |
-
}
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
// Get global sidebars so we can retrieve the real name of the sidebar
|
121 |
-
global $wp_registered_sidebars;
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
if (isset($sidebar_widgets[$sidebarName])) {
|
126 |
-
foreach ($sidebar_widgets[$sidebarName] as $i => $widgetName) {
|
127 |
-
$index = array_search($widgetName, $widgets);
|
128 |
-
// check to see whether or not the widget has been moved
|
129 |
-
if ($i != $index) {
|
130 |
-
$sn = $sidebarName;
|
131 |
-
// Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebarName
|
132 |
-
if ($wp_registered_sidebars && isset($wp_registered_sidebars[$sidebarName])) {
|
133 |
-
$sn = $wp_registered_sidebars[$sidebarName]['name'];
|
134 |
-
}
|
135 |
-
$this->plugin->alerts->Trigger(2071, array(
|
136 |
-
'WidgetName' => $widgetName,
|
137 |
-
'OldPosition' => $i+1,
|
138 |
-
'NewPosition' => $index+1,
|
139 |
-
'Sidebar' => $sn,
|
140 |
-
));
|
141 |
-
}
|
142 |
-
}
|
143 |
-
}
|
144 |
-
}
|
145 |
-
}
|
146 |
-
}
|
147 |
-
}
|
148 |
-
// #!--
|
149 |
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
$postData = $_POST;
|
189 |
-
global $wp_registered_sidebars;
|
190 |
-
$canCheckSidebar = (empty($wp_registered_sidebars) ? false : true);
|
191 |
-
|
192 |
-
switch (true) {
|
193 |
-
// added widget
|
194 |
-
case isset($postData['add_new']) && $postData['add_new'] == 'multi':
|
195 |
-
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
196 |
-
if ($canCheckSidebar && preg_match('/^sidebar-/', $sidebar)) {
|
197 |
-
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
198 |
-
}
|
199 |
-
$this->plugin->alerts->Trigger(2042, array(
|
200 |
-
'WidgetName' => $postData['id_base'],
|
201 |
-
'Sidebar' => $sidebar,
|
202 |
-
));
|
203 |
-
break;
|
204 |
-
// deleted widget
|
205 |
-
case isset($postData['delete_widget']) && intval($postData['delete_widget']) == 1:
|
206 |
-
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
207 |
-
if ($canCheckSidebar && preg_match('/^sidebar-/', $sidebar)) {
|
208 |
-
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
209 |
-
}
|
210 |
-
$this->plugin->alerts->Trigger(2044, array(
|
211 |
-
'WidgetName' => $postData['id_base'],
|
212 |
-
'Sidebar' => $sidebar,
|
213 |
-
));
|
214 |
-
break;
|
215 |
-
// modified widget
|
216 |
-
case isset($postData['id_base']) && !empty($postData['id_base']):
|
217 |
-
$wId = 0;
|
218 |
-
if (!empty($postData['multi_number'])) {
|
219 |
-
$wId = intval($postData['multi_number']);
|
220 |
-
} elseif (!empty($postData['widget_number'])) {
|
221 |
-
$wId = intval($postData['widget_number']);
|
222 |
-
}
|
223 |
-
if (empty($wId)) {
|
224 |
-
return;
|
225 |
-
}
|
226 |
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
|
|
|
|
264 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: Widgets
|
4 |
+
*
|
5 |
+
* Widgets sensor class file.
|
6 |
+
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Widgets sensor.
|
18 |
*
|
19 |
* 2042 User added a new widget
|
21 |
* 2044 User deleted widget
|
22 |
* 2045 User moved widget
|
23 |
* 2071 User changed widget position
|
24 |
+
*
|
25 |
+
* @package Wsal
|
26 |
+
* @subpackage Sensors
|
27 |
*/
|
28 |
+
class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Widget Move Data
|
32 |
+
*
|
33 |
+
* @var array
|
34 |
+
*/
|
35 |
+
protected $_widget_move_data = null;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Listening to events using WP hooks.
|
39 |
+
*/
|
40 |
+
public function HookEvents() {
|
41 |
+
if ( current_user_can( 'edit_theme_options' ) ) {
|
42 |
+
add_action( 'admin_init', array( $this, 'EventWidgetMove' ) );
|
43 |
+
add_action( 'admin_init', array( $this, 'EventWidgetPostMove' ) );
|
44 |
+
}
|
45 |
+
add_action( 'sidebar_admin_setup', array( $this, 'EventWidgetActivity' ) );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Triggered when a user accesses the admin area.
|
50 |
+
* Moved widget.
|
51 |
+
*/
|
52 |
+
public function EventWidgetMove() {
|
53 |
+
// Filter $_POST array for security.
|
54 |
+
$post_array = filter_input_array( INPUT_POST );
|
55 |
+
|
56 |
+
if ( isset( $post_array['savewidgets'] ) ) {
|
57 |
+
check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
|
58 |
+
}
|
59 |
+
|
60 |
+
if ( isset( $post_array ) && ! empty( $post_array['sidebars'] ) ) {
|
61 |
+
$current_sidebars = $post_array['sidebars'];
|
62 |
+
$sidebars = array();
|
63 |
+
foreach ( $current_sidebars as $key => $val ) {
|
64 |
+
$sb = array();
|
65 |
+
if ( ! empty( $val ) ) {
|
66 |
+
$val = explode( ',', $val );
|
67 |
+
foreach ( $val as $k => $v ) {
|
68 |
+
if ( strpos( $v, 'widget-' ) === false ) {
|
69 |
+
continue;
|
70 |
+
}
|
71 |
+
$sb[ $k ] = substr( $v, strpos( $v, '_' ) + 1 );
|
72 |
+
}
|
73 |
+
}
|
74 |
+
$sidebars[ $key ] = $sb;
|
75 |
+
}
|
76 |
+
$current_sidebars = $sidebars;
|
77 |
+
$db_sidebars = get_option( 'sidebars_widgets' );
|
78 |
+
$widget_name = $from_sidebar = $to_sidebar = '';
|
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 |
+
$widget_name = $widget_name;
|
85 |
+
foreach ( $db_sidebars as $name => $v ) {
|
86 |
+
if ( is_array( $v ) && ! empty( $v ) && in_array( $widget_name, $v ) ) {
|
87 |
+
$from_sidebar = $name;
|
88 |
+
continue;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
if ( empty( $widget_name ) || empty( $from_sidebar ) || empty( $to_sidebar ) ) {
|
97 |
+
return;
|
98 |
+
}
|
99 |
+
|
100 |
+
if ( preg_match( '/^sidebar-/', $from_sidebar ) || preg_match( '/^sidebar-/', $to_sidebar ) ) {
|
101 |
+
// This option will hold the data needed to trigger the event 2045
|
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 |
+
return;
|
111 |
+
}
|
112 |
+
|
113 |
+
$this->plugin->alerts->Trigger(
|
114 |
+
2045, array(
|
115 |
+
'WidgetName' => $widget_name,
|
116 |
+
'OldSidebar' => $from_sidebar,
|
117 |
+
'NewSidebar' => $to_sidebar,
|
118 |
+
)
|
119 |
+
);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Triggered when a user accesses the admin area.
|
125 |
+
* Changed widget position or moved widget.
|
126 |
+
*/
|
127 |
+
public function EventWidgetPostMove() {
|
128 |
+
// Filter $_POST array for security.
|
129 |
+
$post_array = filter_input_array( INPUT_POST );
|
130 |
+
|
131 |
+
// #!-- generates the event 2071
|
132 |
+
if ( isset( $post_array['action'] ) && ('widgets-order' == $post_array['action']) ) {
|
133 |
+
if ( isset( $post_array['sidebars'] ) ) {
|
134 |
+
// Get the sidebars from $post_array.
|
135 |
+
$request_sidebars = array();
|
136 |
+
if ( $post_array['sidebars'] ) {
|
137 |
+
foreach ( $post_array['sidebars'] as $key => &$value ) {
|
138 |
+
if ( ! empty( $value ) ) {
|
139 |
+
// Build the sidebars array.
|
140 |
+
$value = explode( ',', $value );
|
141 |
+
// Cleanup widgets' name.
|
142 |
+
foreach ( $value as $k => &$widget_name ) {
|
143 |
+
$widget_name = preg_replace( '/^([a-z]+-[0-9]+)+?_/i', '', $widget_name );
|
144 |
+
}
|
145 |
+
$request_sidebars[ $key ] = $value;
|
146 |
+
}
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
if ( $request_sidebars ) {
|
151 |
+
// Get the sidebars from DATABASE.
|
152 |
+
$sidebar_widgets = wp_get_sidebars_widgets();
|
153 |
+
// Get global sidebars so we can retrieve the real name of the sidebar.
|
154 |
+
global $wp_registered_sidebars;
|
155 |
+
|
156 |
+
// Check in each array if there's any change.
|
157 |
+
foreach ( $request_sidebars as $sidebar_name => $widgets ) {
|
158 |
+
if ( isset( $sidebar_widgets[ $sidebar_name ] ) ) {
|
159 |
+
foreach ( $sidebar_widgets[ $sidebar_name ] as $i => $widget_name ) {
|
160 |
+
$index = array_search( $widget_name, $widgets );
|
161 |
+
// Check to see whether or not the widget has been moved.
|
162 |
+
if ( $i != $index ) {
|
163 |
+
$sn = $sidebar_name;
|
164 |
+
// Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebar_name.
|
165 |
+
if ( $wp_registered_sidebars && isset( $wp_registered_sidebars[ $sidebar_name ] ) ) {
|
166 |
+
$sn = $wp_registered_sidebars[ $sidebar_name ]['name'];
|
167 |
+
}
|
168 |
+
$this->plugin->alerts->Trigger(
|
169 |
+
2071, array(
|
170 |
+
'WidgetName' => $widget_name,
|
171 |
+
'OldPosition' => $i + 1,
|
172 |
+
'NewPosition' => $index + 1,
|
173 |
+
'Sidebar' => $sn,
|
174 |
+
)
|
175 |
+
);
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
// #!--
|
184 |
+
if ( $this->_widget_move_data ) {
|
185 |
+
$widget_name = $this->_widget_move_data['widget'];
|
186 |
+
$from_sidebar = $this->_widget_move_data['from'];
|
187 |
+
$to_sidebar = $this->_widget_move_data['to'];
|
188 |
+
|
189 |
+
global $wp_registered_sidebars;
|
190 |
+
|
191 |
+
if ( preg_match( '/^sidebar-/', $from_sidebar ) ) {
|
192 |
+
$from_sidebar = isset( $wp_registered_sidebars[ $from_sidebar ] )
|
193 |
+
? $wp_registered_sidebars[ $from_sidebar ]['name']
|
194 |
+
: $from_sidebar
|
195 |
+
;
|
196 |
+
}
|
197 |
+
|
198 |
+
if ( preg_match( '/^sidebar-/', $to_sidebar ) ) {
|
199 |
+
$to_sidebar = isset( $wp_registered_sidebars[ $to_sidebar ] )
|
200 |
+
? $wp_registered_sidebars[ $to_sidebar ]['name']
|
201 |
+
: $to_sidebar
|
202 |
+
;
|
203 |
+
}
|
204 |
|
205 |
+
$this->plugin->alerts->Trigger(
|
206 |
+
2045, array(
|
207 |
+
'WidgetName' => $widget_name,
|
208 |
+
'OldSidebar' => $from_sidebar,
|
209 |
+
'NewSidebar' => $to_sidebar,
|
210 |
+
)
|
211 |
+
);
|
212 |
+
}
|
213 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
214 |
|
215 |
+
/**
|
216 |
+
* Widgets Activity (added, modified, deleted).
|
217 |
+
*/
|
218 |
+
public function EventWidgetActivity() {
|
219 |
+
// Filter $_POST array for security.
|
220 |
+
$post_array = filter_input_array( INPUT_POST );
|
|
|
|
|
221 |
|
222 |
+
if ( ! isset( $post_array ) || ! isset( $post_array['widget-id'] ) || empty( $post_array['widget-id'] ) ) {
|
223 |
+
return;
|
224 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
|
226 |
+
if ( isset( $post_array['savewidgets'] ) ) {
|
227 |
+
check_ajax_referer( 'save-sidebar-widgets', 'savewidgets' );
|
228 |
+
}
|
|
|
|
|
229 |
|
230 |
+
global $wp_registered_sidebars;
|
231 |
+
$can_check_sidebar = (empty( $wp_registered_sidebars ) ? false : true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
|
233 |
+
switch ( true ) {
|
234 |
+
// Added widget.
|
235 |
+
case isset( $post_array['add_new'] ) && 'multi' == $post_array['add_new']:
|
236 |
+
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
237 |
+
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
238 |
+
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
239 |
+
}
|
240 |
+
$this->plugin->alerts->Trigger(
|
241 |
+
2042, array(
|
242 |
+
'WidgetName' => $post_array['id_base'],
|
243 |
+
'Sidebar' => $sidebar,
|
244 |
+
)
|
245 |
+
);
|
246 |
+
break;
|
247 |
+
// Deleted widget.
|
248 |
+
case isset( $post_array['delete_widget'] ) && intval( $post_array['delete_widget'] ) == 1:
|
249 |
+
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
250 |
+
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
251 |
+
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
252 |
+
}
|
253 |
+
$this->plugin->alerts->Trigger(
|
254 |
+
2044, array(
|
255 |
+
'WidgetName' => $post_array['id_base'],
|
256 |
+
'Sidebar' => $sidebar,
|
257 |
+
)
|
258 |
+
);
|
259 |
+
break;
|
260 |
+
// Modified widget.
|
261 |
+
case isset( $post_array['id_base'] ) && ! empty( $post_array['id_base'] ):
|
262 |
+
$widget_id = 0;
|
263 |
+
if ( ! empty( $post_array['multi_number'] ) ) {
|
264 |
+
$widget_id = intval( $post_array['multi_number'] );
|
265 |
+
} elseif ( ! empty( $post_array['widget_number'] ) ) {
|
266 |
+
$widget_id = intval( $post_array['widget_number'] );
|
267 |
+
}
|
268 |
+
if ( empty( $widget_id ) ) {
|
269 |
+
return;
|
270 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
|
272 |
+
$widget_name = $post_array['id_base'];
|
273 |
+
$sidebar = isset( $post_array['sidebar'] ) ? $post_array['sidebar'] : null;
|
274 |
+
$widget_data = isset( $post_array[ "widget-$widget_name" ][ $widget_id ] )
|
275 |
+
? $post_array[ "widget-$widget_name" ][ $widget_id ]
|
276 |
+
: null;
|
277 |
|
278 |
+
if ( empty( $widget_data ) ) {
|
279 |
+
return;
|
280 |
+
}
|
281 |
+
// Get info from db.
|
282 |
+
$widget_db_data = get_option( 'widget_' . $widget_name );
|
283 |
+
if ( empty( $widget_db_data[ $widget_id ] ) ) {
|
284 |
+
return;
|
285 |
+
}
|
286 |
|
287 |
+
// Transform 'on' -> 1.
|
288 |
+
foreach ( $widget_data as $k => $v ) {
|
289 |
+
if ( 'on' == $v ) {
|
290 |
+
$widget_data[ $k ] = 1;
|
291 |
+
}
|
292 |
+
}
|
293 |
|
294 |
+
// Compare - checks for any changes inside widgets.
|
295 |
+
$diff = array_diff_assoc( $widget_data, $widget_db_data[ $widget_id ] );
|
296 |
+
$count = count( $diff );
|
297 |
+
if ( $count > 0 ) {
|
298 |
+
if ( $can_check_sidebar && preg_match( '/^sidebar-/', $sidebar ) ) {
|
299 |
+
$sidebar = $wp_registered_sidebars[ $sidebar ]['name'];
|
300 |
+
}
|
301 |
+
$this->plugin->alerts->Trigger(
|
302 |
+
2043, array(
|
303 |
+
'WidgetName' => $widget_name,
|
304 |
+
'Sidebar' => $sidebar,
|
305 |
+
)
|
306 |
+
);
|
307 |
+
}
|
308 |
+
break;
|
309 |
+
}
|
310 |
+
}
|
311 |
}
|
classes/Sensors/WooCommerce.php
CHANGED
@@ -1,7 +1,18 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Support for WooCommerce Plugin.
|
6 |
*
|
7 |
* 9000 User created a new product
|
@@ -38,863 +49,1339 @@
|
|
38 |
* 9031 User changed the currency
|
39 |
* 9032 User Enabled/Disabled the use of coupons during checkout
|
40 |
* 9033 User Enabled/Disabled guest checkout
|
|
|
|
|
|
|
41 |
*/
|
42 |
-
class WSAL_Sensors_WooCommerce extends WSAL_AbstractSensor
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
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 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
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 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
900 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Sensor: WooCommerce
|
4 |
+
*
|
5 |
+
* WooCommerce sensor file.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* Support for WooCommerce Plugin.
|
17 |
*
|
18 |
* 9000 User created a new product
|
49 |
* 9031 User changed the currency
|
50 |
* 9032 User Enabled/Disabled the use of coupons during checkout
|
51 |
* 9033 User Enabled/Disabled guest checkout
|
52 |
+
*
|
53 |
+
* @package Wsal
|
54 |
+
* @subpackage Sensors
|
55 |
*/
|
56 |
+
class WSAL_Sensors_WooCommerce extends WSAL_AbstractSensor {
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Old Post.
|
60 |
+
*
|
61 |
+
* @var WP_Post
|
62 |
+
*/
|
63 |
+
protected $_old_post = null;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Old Post Link.
|
67 |
+
*
|
68 |
+
* @var string
|
69 |
+
*/
|
70 |
+
protected $_old_link = null;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Old Post Categories.
|
74 |
+
*
|
75 |
+
* @var array
|
76 |
+
*/
|
77 |
+
protected $_old_cats = null;
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Old Product Data.
|
81 |
+
*
|
82 |
+
* @var array
|
83 |
+
*/
|
84 |
+
protected $_old_data = null;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Old Product Stock Status.
|
88 |
+
*
|
89 |
+
* @var string
|
90 |
+
*/
|
91 |
+
protected $_old_stock_status = null;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Old Product File Names.
|
95 |
+
*
|
96 |
+
* @var array
|
97 |
+
*/
|
98 |
+
protected $_old_file_names = array();
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Old Product File URLs.
|
102 |
+
*
|
103 |
+
* @var array
|
104 |
+
*/
|
105 |
+
protected $_old_file_urls = array();
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Listening to events using WP hooks.
|
109 |
+
*/
|
110 |
+
public function HookEvents() {
|
111 |
+
if ( current_user_can( 'edit_posts' ) ) {
|
112 |
+
add_action( 'admin_init', array( $this, 'EventAdminInit' ) );
|
113 |
+
}
|
114 |
+
add_action( 'post_updated', array( $this, 'EventChanged' ), 10, 3 );
|
115 |
+
add_action( 'delete_post', array( $this, 'EventDeleted' ), 10, 1 );
|
116 |
+
add_action( 'wp_trash_post', array( $this, 'EventTrashed' ), 10, 1 );
|
117 |
+
add_action( 'untrash_post', array( $this, 'EventUntrashed' ) );
|
118 |
+
|
119 |
+
add_action( 'create_product_cat', array( $this, 'EventCategoryCreation' ), 10, 1 );
|
120 |
+
/* add_action('edit_product_cat', array($this, 'EventCategoryChanged'), 10, 1); */
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Triggered when a user accesses the admin area.
|
125 |
+
*/
|
126 |
+
public function EventAdminInit() {
|
127 |
+
// Load old data, if applicable.
|
128 |
+
$this->RetrieveOldData();
|
129 |
+
$this->CheckSettingsChange();
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Retrieve Old data.
|
134 |
+
*
|
135 |
+
* @global mixed $_POST post data
|
136 |
+
*/
|
137 |
+
protected function RetrieveOldData() {
|
138 |
+
// Filter POST global array.
|
139 |
+
$post_array = filter_input_array( INPUT_POST );
|
140 |
+
|
141 |
+
if ( isset( $post_array['post_ID'] )
|
142 |
+
&& isset( $post_array['_wpnonce'] )
|
143 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
144 |
+
return false;
|
145 |
+
}
|
146 |
+
|
147 |
+
if ( isset( $post_array ) && isset( $post_array['post_ID'] )
|
148 |
+
&& ! (defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE)
|
149 |
+
&& ! (isset( $post_array['action'] ) && 'autosave' == $post_array['action'] )
|
150 |
+
) {
|
151 |
+
$post_id = intval( $post_array['post_ID'] );
|
152 |
+
$this->_old_post = get_post( $post_id );
|
153 |
+
$this->_old_link = get_post_permalink( $post_id, false, true );
|
154 |
+
$this->_old_cats = $this->GetProductCategories( $this->_old_post );
|
155 |
+
$this->_old_data = $this->GetProductData( $this->_old_post );
|
156 |
+
$this->_old_stock_status = get_post_meta( $post_id, '_stock_status', true );
|
157 |
+
|
158 |
+
$old_downloadable_files = get_post_meta( $post_id, '_downloadable_files', true );
|
159 |
+
if ( ! empty( $old_downloadable_files ) ) {
|
160 |
+
foreach ( $old_downloadable_files as $file ) {
|
161 |
+
array_push( $this->_old_file_names, $file['name'] );
|
162 |
+
array_push( $this->_old_file_urls, $file['file'] );
|
163 |
+
}
|
164 |
+
}
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* WooCommerce Product Updated.
|
170 |
+
*
|
171 |
+
* @param integer $post_id - Post ID.
|
172 |
+
* @param stdClass $newpost - The new post.
|
173 |
+
* @param stdClass $oldpost - The old post.
|
174 |
+
*/
|
175 |
+
public function EventChanged( $post_id, $newpost, $oldpost ) {
|
176 |
+
if ( $this->CheckWooCommerce( $oldpost ) ) {
|
177 |
+
$changes = 0 + $this->EventCreation( $oldpost, $newpost );
|
178 |
+
if ( ! $changes ) {
|
179 |
+
// Change Categories.
|
180 |
+
$changes = $this->CheckCategoriesChange( $this->_old_cats, $this->GetProductCategories( $newpost ), $oldpost, $newpost );
|
181 |
+
}
|
182 |
+
if ( ! $changes ) {
|
183 |
+
// Change Short description, Text, URL, Product Data, Date, Visibility, etc.
|
184 |
+
$changes = 0
|
185 |
+
+ $this->CheckShortDescriptionChange( $oldpost, $newpost )
|
186 |
+
+ $this->CheckTextChange( $oldpost, $newpost )
|
187 |
+
+ $this->CheckProductDataChange( $this->_old_data, $newpost )
|
188 |
+
+ $this->CheckDateChange( $oldpost, $newpost )
|
189 |
+
+ $this->CheckVisibilityChange( $oldpost )
|
190 |
+
+ $this->CheckStatusChange( $oldpost, $newpost )
|
191 |
+
+ $this->CheckPriceChange( $oldpost )
|
192 |
+
+ $this->CheckSKUChange( $oldpost )
|
193 |
+
+ $this->CheckStockStatusChange( $oldpost )
|
194 |
+
+ $this->CheckStockQuantityChange( $oldpost )
|
195 |
+
+ $this->CheckTypeChange( $oldpost, $newpost )
|
196 |
+
+ $this->CheckWeightChange( $oldpost )
|
197 |
+
+ $this->CheckDimensionsChange( $oldpost )
|
198 |
+
+ $this->CheckDownloadableFileChange( $oldpost );
|
199 |
+
}
|
200 |
+
if ( ! $changes ) {
|
201 |
+
// Change Permalink.
|
202 |
+
$changes = $this->CheckPermalinkChange( $this->_old_link, get_post_permalink( $post_id, false, true ), $newpost );
|
203 |
+
if ( ! $changes ) {
|
204 |
+
// If no one of the above changes happen.
|
205 |
+
$this->CheckModifyChange( $oldpost, $newpost );
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* WooCommerce Product Created.
|
213 |
+
*
|
214 |
+
* Trigger events 9000, 9001.
|
215 |
+
*
|
216 |
+
* @param object $old_post - Old Product.
|
217 |
+
* @param object $new_post - New Product.
|
218 |
+
*/
|
219 |
+
private function EventCreation( $old_post, $new_post ) {
|
220 |
+
// Filter POST global array.
|
221 |
+
$post_array = filter_input_array( INPUT_POST );
|
222 |
+
|
223 |
+
if ( isset( $post_array['post_ID'] )
|
224 |
+
&& isset( $post_array['_wpnonce'] )
|
225 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
226 |
+
return false;
|
227 |
+
}
|
228 |
+
|
229 |
+
$original = isset( $post_array['original_post_status'] ) ? $post_array['original_post_status'] : '';
|
230 |
+
if ( 'draft' == $original && 'draft' == $new_post->post_status ) {
|
231 |
+
return 0;
|
232 |
+
}
|
233 |
+
|
234 |
+
if ( 'draft' == $old_post->post_status || 'auto-draft' == $original ) {
|
235 |
+
if ( 'product' == $old_post->post_type ) {
|
236 |
+
$editor_link = $this->GetEditorLink( $new_post );
|
237 |
+
if ( 'draft' == $new_post->post_status ) {
|
238 |
+
$this->plugin->alerts->Trigger(
|
239 |
+
9000, array(
|
240 |
+
'ProductTitle' => $new_post->post_title,
|
241 |
+
$editor_link['name'] => $editor_link['value'],
|
242 |
+
)
|
243 |
+
);
|
244 |
+
return 1;
|
245 |
+
} elseif ( 'publish' == $new_post->post_status ) {
|
246 |
+
$this->plugin->alerts->Trigger(
|
247 |
+
9001, array(
|
248 |
+
'ProductTitle' => $new_post->post_title,
|
249 |
+
'ProductUrl' => get_post_permalink( $new_post->ID ),
|
250 |
+
$editor_link['name'] => $editor_link['value'],
|
251 |
+
)
|
252 |
+
);
|
253 |
+
return 1;
|
254 |
+
}
|
255 |
+
}
|
256 |
+
}
|
257 |
+
return 0;
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Trigger events 9002
|
262 |
+
*
|
263 |
+
* @param int|WP_Term $term_id - Term ID.
|
264 |
+
*/
|
265 |
+
public function EventCategoryCreation( $term_id = null ) {
|
266 |
+
$term = get_term( $term_id );
|
267 |
+
if ( ! empty( $term ) ) {
|
268 |
+
$this->plugin->alerts->Trigger(
|
269 |
+
9002, array(
|
270 |
+
'CategoryName' => $term->name,
|
271 |
+
'Slug' => $term->slug,
|
272 |
+
)
|
273 |
+
);
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Not implemented
|
279 |
+
*
|
280 |
+
* @param int|WP_Term $term_id - Term ID.
|
281 |
+
*/
|
282 |
+
/**
|
283 |
+
public function EventCategoryChanged( $term_id = null ) {
|
284 |
+
$old_term = get_term( $term_id );
|
285 |
+
if ( isset( $_POST['taxonomy'] ) ) {
|
286 |
+
// new $term in $_POST
|
287 |
+
}
|
288 |
+
} */
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Trigger events 9003
|
292 |
+
*
|
293 |
+
* @param array $old_cats - Old Categories.
|
294 |
+
* @param array $new_cats - New Categories.
|
295 |
+
* @param object $oldpost - Old product object.
|
296 |
+
* @param object $newpost - New product object.
|
297 |
+
* @return int
|
298 |
+
*/
|
299 |
+
protected function CheckCategoriesChange( $old_cats, $new_cats, $oldpost, $newpost ) {
|
300 |
+
if ( 'trash' == $newpost->post_status || 'trash' == $oldpost->post_status ) {
|
301 |
+
return 0;
|
302 |
+
}
|
303 |
+
$old_cats = is_array( $old_cats ) ? implode( ', ', $old_cats ) : $old_cats;
|
304 |
+
$new_cats = is_array( $new_cats ) ? implode( ', ', $new_cats ) : $new_cats;
|
305 |
+
if ( $old_cats != $new_cats ) {
|
306 |
+
$editor_link = $this->GetEditorLink( $newpost );
|
307 |
+
$this->plugin->alerts->Trigger(
|
308 |
+
9003, array(
|
309 |
+
'ProductTitle' => $newpost->post_title,
|
310 |
+
'OldCategories' => $old_cats ? $old_cats : 'no categories',
|
311 |
+
'NewCategories' => $new_cats ? $new_cats : 'no categories',
|
312 |
+
$editor_link['name'] => $editor_link['value'],
|
313 |
+
)
|
314 |
+
);
|
315 |
+
return 1;
|
316 |
+
}
|
317 |
+
return 0;
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Trigger events 9004
|
322 |
+
*
|
323 |
+
* @param object $oldpost - Old product object.
|
324 |
+
* @param object $newpost - New product object.
|
325 |
+
* @return int
|
326 |
+
*/
|
327 |
+
protected function CheckShortDescriptionChange( $oldpost, $newpost ) {
|
328 |
+
if ( 'auto-draft' == $oldpost->post_status ) {
|
329 |
+
return 0;
|
330 |
+
}
|
331 |
+
if ( $oldpost->post_excerpt != $newpost->post_excerpt ) {
|
332 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
333 |
+
$this->plugin->alerts->Trigger(
|
334 |
+
9004, array(
|
335 |
+
'ProductTitle' => $oldpost->post_title,
|
336 |
+
$editor_link['name'] => $editor_link['value'],
|
337 |
+
)
|
338 |
+
);
|
339 |
+
return 1;
|
340 |
+
}
|
341 |
+
return 0;
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Trigger events 9005
|
346 |
+
*
|
347 |
+
* @param object $oldpost - Old product object.
|
348 |
+
* @param object $newpost - New product object.
|
349 |
+
* @return int
|
350 |
+
*/
|
351 |
+
protected function CheckTextChange( $oldpost, $newpost ) {
|
352 |
+
if ( 'auto-draft' == $oldpost->post_status ) {
|
353 |
+
return 0;
|
354 |
+
}
|
355 |
+
if ( $oldpost->post_content != $newpost->post_content ) {
|
356 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
357 |
+
$this->plugin->alerts->Trigger(
|
358 |
+
9005, array(
|
359 |
+
'ProductTitle' => $oldpost->post_title,
|
360 |
+
$editor_link['name'] => $editor_link['value'],
|
361 |
+
)
|
362 |
+
);
|
363 |
+
return 1;
|
364 |
+
}
|
365 |
+
return 0;
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Trigger events 9006
|
370 |
+
*
|
371 |
+
* @param string $old_link - Old product link.
|
372 |
+
* @param string $new_link - New product link.
|
373 |
+
* @param object $post - Product object.
|
374 |
+
* @return int
|
375 |
+
*/
|
376 |
+
protected function CheckPermalinkChange( $old_link, $new_link, $post ) {
|
377 |
+
if ( ($old_link && $new_link) && ($old_link != $new_link) ) {
|
378 |
+
$editor_link = $this->GetEditorLink( $post );
|
379 |
+
$this->plugin->alerts->Trigger(
|
380 |
+
9006, array(
|
381 |
+
'ProductTitle' => $post->post_title,
|
382 |
+
'OldUrl' => $old_link,
|
383 |
+
'NewUrl' => $new_link,
|
384 |
+
$editor_link['name'] => $editor_link['value'],
|
385 |
+
)
|
386 |
+
);
|
387 |
+
return 1;
|
388 |
+
}
|
389 |
+
return 0;
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Trigger events 9007
|
394 |
+
*
|
395 |
+
* @param array $old_data - Product Data.
|
396 |
+
* @param object $post - Product object.
|
397 |
+
* @return int
|
398 |
+
*/
|
399 |
+
protected function CheckProductDataChange( $old_data, $post ) {
|
400 |
+
// Filter POST global array.
|
401 |
+
$post_array = filter_input_array( INPUT_POST );
|
402 |
+
|
403 |
+
if ( isset( $post_array['post_ID'] )
|
404 |
+
&& isset( $post_array['_wpnonce'] )
|
405 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
406 |
+
return false;
|
407 |
+
}
|
408 |
+
|
409 |
+
if ( isset( $post_array['product-type'] ) ) {
|
410 |
+
$old_data = is_array( $old_data ) ? implode( ', ', $old_data ) : $old_data;
|
411 |
+
$new_data = $post_array['product-type'];
|
412 |
+
if ( $old_data != $new_data ) {
|
413 |
+
$editor_link = $this->GetEditorLink( $post );
|
414 |
+
$this->plugin->alerts->Trigger(
|
415 |
+
9007, array(
|
416 |
+
'ProductTitle' => $post->post_title,
|
417 |
+
$editor_link['name'] => $editor_link['value'],
|
418 |
+
)
|
419 |
+
);
|
420 |
+
return 1;
|
421 |
+
}
|
422 |
+
}
|
423 |
+
return 0;
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Trigger events 9008
|
428 |
+
*
|
429 |
+
* @param object $oldpost - Old product object.
|
430 |
+
* @param object $newpost - New product object.
|
431 |
+
* @return int
|
432 |
+
*/
|
433 |
+
protected function CheckDateChange( $oldpost, $newpost ) {
|
434 |
+
if ( 'draft' == $oldpost->post_status || 'auto-draft' == $oldpost->post_status ) {
|
435 |
+
return 0;
|
436 |
+
}
|
437 |
+
$from = strtotime( $oldpost->post_date );
|
438 |
+
$to = strtotime( $newpost->post_date );
|
439 |
+
if ( $from != $to ) {
|
440 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
441 |
+
$this->plugin->alerts->Trigger(
|
442 |
+
9008, array(
|
443 |
+
'ProductTitle' => $oldpost->post_title,
|
444 |
+
'OldDate' => $oldpost->post_date,
|
445 |
+
'NewDate' => $newpost->post_date,
|
446 |
+
$editor_link['name'] => $editor_link['value'],
|
447 |
+
)
|
448 |
+
);
|
449 |
+
return 1;
|
450 |
+
}
|
451 |
+
return 0;
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Trigger events 9009
|
456 |
+
*
|
457 |
+
* @param object $oldpost - Old product object.
|
458 |
+
* @return int
|
459 |
+
*/
|
460 |
+
protected function CheckVisibilityChange( $oldpost ) {
|
461 |
+
// Filter POST global array.
|
462 |
+
$post_array = filter_input_array( INPUT_POST );
|
463 |
+
|
464 |
+
if ( isset( $post_array['post_ID'] )
|
465 |
+
&& isset( $post_array['_wpnonce'] )
|
466 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
467 |
+
return false;
|
468 |
+
}
|
469 |
+
|
470 |
+
$old_visibility = isset( $post_array['hidden_post_visibility'] ) ? $post_array['hidden_post_visibility'] : null;
|
471 |
+
$new_visibility = isset( $post_array['visibility'] ) ? $post_array['visibility'] : null;
|
472 |
+
|
473 |
+
if ( 'password' == $old_visibility ) {
|
474 |
+
$old_visibility = __( 'Password Protected', 'wp-security-audit-log' );
|
475 |
+
} else {
|
476 |
+
$old_visibility = ucfirst( $old_visibility );
|
477 |
+
}
|
478 |
+
|
479 |
+
if ( 'password' == $new_visibility ) {
|
480 |
+
$new_visibility = __( 'Password Protected', 'wp-security-audit-log' );
|
481 |
+
} else {
|
482 |
+
$new_visibility = ucfirst( $new_visibility );
|
483 |
+
}
|
484 |
+
|
485 |
+
if ( ($old_visibility && $new_visibility) && ($old_visibility != $new_visibility) ) {
|
486 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
487 |
+
$this->plugin->alerts->Trigger(
|
488 |
+
9009, array(
|
489 |
+
'ProductTitle' => $oldpost->post_title,
|
490 |
+
'OldVisibility' => $old_visibility,
|
491 |
+
'NewVisibility' => $new_visibility,
|
492 |
+
$editor_link['name'] => $editor_link['value'],
|
493 |
+
)
|
494 |
+
);
|
495 |
+
return 1;
|
496 |
+
}
|
497 |
+
return 0;
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Trigger events 9010, 9011
|
502 |
+
*
|
503 |
+
* @param object $oldpost - Old product object.
|
504 |
+
* @param object $newpost - New product object.
|
505 |
+
* @return int
|
506 |
+
*/
|
507 |
+
protected function CheckModifyChange( $oldpost, $newpost ) {
|
508 |
+
if ( 'trash' == $newpost->post_status ) {
|
509 |
+
return 0;
|
510 |
+
}
|
511 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
512 |
+
if ( 'publish' == $oldpost->post_status ) {
|
513 |
+
$this->plugin->alerts->Trigger(
|
514 |
+
9010, array(
|
515 |
+
'ProductTitle' => $oldpost->post_title,
|
516 |
+
'ProductUrl' => get_post_permalink( $oldpost->ID ),
|
517 |
+
$editor_link['name'] => $editor_link['value'],
|
518 |
+
)
|
519 |
+
);
|
520 |
+
} elseif ( 'draft' == $oldpost->post_status ) {
|
521 |
+
$this->plugin->alerts->Trigger(
|
522 |
+
9011, array(
|
523 |
+
'ProductTitle' => $oldpost->post_title,
|
524 |
+
$editor_link['name'] => $editor_link['value'],
|
525 |
+
)
|
526 |
+
);
|
527 |
+
}
|
528 |
+
}
|
529 |
+
|
530 |
+
/**
|
531 |
+
* Moved to Trash 9012
|
532 |
+
*
|
533 |
+
* @param int $post_id - Product ID.
|
534 |
+
*/
|
535 |
+
public function EventTrashed( $post_id ) {
|
536 |
+
$post = get_post( $post_id );
|
537 |
+
if ( $this->CheckWooCommerce( $post ) ) {
|
538 |
+
$this->plugin->alerts->Trigger(
|
539 |
+
9012, array(
|
540 |
+
'ProductTitle' => $post->post_title,
|
541 |
+
'ProductUrl' => get_post_permalink( $post->ID ),
|
542 |
+
)
|
543 |
+
);
|
544 |
+
}
|
545 |
+
}
|
546 |
+
|
547 |
+
/**
|
548 |
+
* Permanently deleted 9013
|
549 |
+
*
|
550 |
+
* @param int $post_id - Product ID.
|
551 |
+
*/
|
552 |
+
public function EventDeleted( $post_id ) {
|
553 |
+
$post = get_post( $post_id );
|
554 |
+
if ( $this->CheckWooCommerce( $post ) ) {
|
555 |
+
$this->plugin->alerts->Trigger(
|
556 |
+
9013, array(
|
557 |
+
'ProductTitle' => $post->post_title,
|
558 |
+
)
|
559 |
+
);
|
560 |
+
}
|
561 |
+
}
|
562 |
+
|
563 |
+
/**
|
564 |
+
* Restored from Trash 9014
|
565 |
+
*
|
566 |
+
* @param int $post_id - Product ID.
|
567 |
+
*/
|
568 |
+
public function EventUntrashed( $post_id ) {
|
569 |
+
$post = get_post( $post_id );
|
570 |
+
if ( $this->CheckWooCommerce( $post ) ) {
|
571 |
+
$editor_link = $this->GetEditorLink( $post );
|
572 |
+
$this->plugin->alerts->Trigger(
|
573 |
+
9014, array(
|
574 |
+
'ProductTitle' => $post->post_title,
|
575 |
+
$editor_link['name'] => $editor_link['value'],
|
576 |
+
)
|
577 |
+
);
|
578 |
+
}
|
579 |
+
}
|
580 |
+
|
581 |
+
/**
|
582 |
+
* Trigger events 9015
|
583 |
+
*
|
584 |
+
* @param object $oldpost - Old product object.
|
585 |
+
* @param object $newpost - New product object.
|
586 |
+
* @return int
|
587 |
+
*/
|
588 |
+
protected function CheckStatusChange( $oldpost, $newpost ) {
|
589 |
+
if ( 'draft' == $oldpost->post_status || 'auto-draft' == $oldpost->post_status ) {
|
590 |
+
return 0;
|
591 |
+
}
|
592 |
+
if ( $oldpost->post_status != $newpost->post_status ) {
|
593 |
+
if ( 'trash' != $oldpost->post_status && 'trash' != $newpost->post_status ) {
|
594 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
595 |
+
$this->plugin->alerts->Trigger(
|
596 |
+
9015, array(
|
597 |
+
'ProductTitle' => $oldpost->post_title,
|
598 |
+
'OldStatus' => $oldpost->post_status,
|
599 |
+
'NewStatus' => $newpost->post_status,
|
600 |
+
$editor_link['name'] => $editor_link['value'],
|
601 |
+
)
|
602 |
+
);
|
603 |
+
return 1;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
return 0;
|
607 |
+
}
|
608 |
+
|
609 |
+
/**
|
610 |
+
* Trigger events 9016
|
611 |
+
*
|
612 |
+
* @param object $oldpost - Old product object.
|
613 |
+
* @return int
|
614 |
+
*/
|
615 |
+
protected function CheckPriceChange( $oldpost ) {
|
616 |
+
// Filter POST global array.
|
617 |
+
$post_array = filter_input_array( INPUT_POST );
|
618 |
+
|
619 |
+
if ( isset( $post_array['post_ID'] )
|
620 |
+
&& isset( $post_array['_wpnonce'] )
|
621 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
622 |
+
return false;
|
623 |
+
}
|
624 |
+
|
625 |
+
$result = 0;
|
626 |
+
$old_price = get_post_meta( $oldpost->ID, '_regular_price', true );
|
627 |
+
$old_sale_price = get_post_meta( $oldpost->ID, '_sale_price', true );
|
628 |
+
$new_price = isset( $post_array['_regular_price'] ) ? $post_array['_regular_price'] : null;
|
629 |
+
$new_sale_price = isset( $post_array['_sale_price'] ) ? $post_array['_sale_price'] : null;
|
630 |
+
|
631 |
+
if ( ($new_price) && ($old_price != $new_price) ) {
|
632 |
+
$result = $this->EventPrice( $oldpost, 'Regular price', $old_price, $new_price );
|
633 |
+
}
|
634 |
+
if ( ($new_sale_price) && ($old_sale_price != $new_sale_price) ) {
|
635 |
+
$result = $this->EventPrice( $oldpost, 'Sale price', $old_sale_price, $new_sale_price );
|
636 |
+
}
|
637 |
+
return $result;
|
638 |
+
}
|
639 |
+
|
640 |
+
/**
|
641 |
+
* Group the Price changes in one function
|
642 |
+
*
|
643 |
+
* @param object $oldpost - Old Product Object.
|
644 |
+
* @param string $type - Price Type.
|
645 |
+
* @param int $old_price - Old Product Price.
|
646 |
+
* @param int $new_price - New Product Price.
|
647 |
+
* @return int
|
648 |
+
*/
|
649 |
+
private function EventPrice( $oldpost, $type, $old_price, $new_price ) {
|
650 |
+
$currency = $this->GetCurrencySymbol( $this->GetConfig( 'currency' ) );
|
651 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
652 |
+
$this->plugin->alerts->Trigger(
|
653 |
+
9016, array(
|
654 |
+
'ProductTitle' => $oldpost->post_title,
|
655 |
+
'PriceType' => $type,
|
656 |
+
'OldPrice' => ( ! empty( $old_price ) ? $currency . $old_price : 0),
|
657 |
+
'NewPrice' => $currency . $new_price,
|
658 |
+
$editor_link['name'] => $editor_link['value'],
|
659 |
+
)
|
660 |
+
);
|
661 |
+
return 1;
|
662 |
+
}
|
663 |
+
|
664 |
+
/**
|
665 |
+
* Trigger events 9017
|
666 |
+
*
|
667 |
+
* @param object $oldpost - Old product object.
|
668 |
+
* @return int
|
669 |
+
*/
|
670 |
+
protected function CheckSKUChange( $oldpost ) {
|
671 |
+
// Filter POST global array.
|
672 |
+
$post_array = filter_input_array( INPUT_POST );
|
673 |
+
|
674 |
+
if ( isset( $post_array['post_ID'] )
|
675 |
+
&& isset( $post_array['_wpnonce'] )
|
676 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
677 |
+
return false;
|
678 |
+
}
|
679 |
+
|
680 |
+
$old_sku = get_post_meta( $oldpost->ID, '_sku', true );
|
681 |
+
$new_sku = isset( $post_array['_sku'] ) ? $post_array['_sku'] : null;
|
682 |
+
|
683 |
+
if ( ($new_sku) && ($old_sku != $new_sku) ) {
|
684 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
685 |
+
$this->plugin->alerts->Trigger(
|
686 |
+
9017, array(
|
687 |
+
'ProductTitle' => $oldpost->post_title,
|
688 |
+
'OldSku' => ( ! empty( $old_sku ) ? $old_sku : 0),
|
689 |
+
'NewSku' => $new_sku,
|
690 |
+
$editor_link['name'] => $editor_link['value'],
|
691 |
+
)
|
692 |
+
);
|
693 |
+
return 1;
|
694 |
+
}
|
695 |
+
return 0;
|
696 |
+
}
|
697 |
+
|
698 |
+
/**
|
699 |
+
* Trigger events 9018
|
700 |
+
*
|
701 |
+
* @param object $oldpost - Old product object.
|
702 |
+
* @return int
|
703 |
+
*/
|
704 |
+
protected function CheckStockStatusChange( $oldpost ) {
|
705 |
+
// Filter POST global array.
|
706 |
+
$post_array = filter_input_array( INPUT_POST );
|
707 |
+
|
708 |
+
if ( isset( $post_array['post_ID'] )
|
709 |
+
&& isset( $post_array['_wpnonce'] )
|
710 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
711 |
+
return false;
|
712 |
+
}
|
713 |
+
|
714 |
+
$old_status = $this->_old_stock_status;
|
715 |
+
$new_status = isset( $post_array['_stock_status'] ) ? $post_array['_stock_status'] : null;
|
716 |
+
|
717 |
+
if ( ($old_status && $new_status) && ($old_status != $new_status) ) {
|
718 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
719 |
+
$this->plugin->alerts->Trigger(
|
720 |
+
9018, array(
|
721 |
+
'ProductTitle' => $oldpost->post_title,
|
722 |
+
'OldStatus' => $this->GetStockStatusName( $old_status ),
|
723 |
+
'NewStatus' => $this->GetStockStatusName( $new_status ),
|
724 |
+
$editor_link['name'] => $editor_link['value'],
|
725 |
+
)
|
726 |
+
);
|
727 |
+
return 1;
|
728 |
+
}
|
729 |
+
return 0;
|
730 |
+
}
|
731 |
+
|
732 |
+
/**
|
733 |
+
* Trigger events 9019
|
734 |
+
*
|
735 |
+
* @param object $oldpost - Old product object.
|
736 |
+
* @return int
|
737 |
+
*/
|
738 |
+
protected function CheckStockQuantityChange( $oldpost ) {
|
739 |
+
// Filter POST global array.
|
740 |
+
$post_array = filter_input_array( INPUT_POST );
|
741 |
+
|
742 |
+
if ( isset( $post_array['post_ID'] )
|
743 |
+
&& isset( $post_array['_wpnonce'] )
|
744 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
745 |
+
return false;
|
746 |
+
}
|
747 |
+
|
748 |
+
$old_value = get_post_meta( $oldpost->ID, '_stock', true );
|
749 |
+
$new_value = isset( $post_array['_stock'] ) ? $post_array['_stock'] : null;
|
750 |
+
|
751 |
+
if ( ($new_value) && ($old_value != $new_value) ) {
|
752 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
753 |
+
$this->plugin->alerts->Trigger(
|
754 |
+
9019, array(
|
755 |
+
'ProductTitle' => $oldpost->post_title,
|
756 |
+
'OldValue' => ( ! empty( $old_value ) ? $old_value : 0),
|
757 |
+
'NewValue' => $new_value,
|
758 |
+
$editor_link['name'] => $editor_link['value'],
|
759 |
+
)
|
760 |
+
);
|
761 |
+
return 1;
|
762 |
+
}
|
763 |
+
return 0;
|
764 |
+
}
|
765 |
+
|
766 |
+
/**
|
767 |
+
* Trigger events 9020
|
768 |
+
*
|
769 |
+
* @param object $oldpost - Old product object.
|
770 |
+
* @param object $newpost - New product object.
|
771 |
+
* @return int
|
772 |
+
*/
|
773 |
+
protected function CheckTypeChange( $oldpost, $newpost ) {
|
774 |
+
// Filter POST global array.
|
775 |
+
$post_array = filter_input_array( INPUT_POST );
|
776 |
+
|
777 |
+
if ( isset( $post_array['post_ID'] )
|
778 |
+
&& isset( $post_array['_wpnonce'] )
|
779 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
780 |
+
return false;
|
781 |
+
}
|
782 |
+
|
783 |
+
$result = 0;
|
784 |
+
if ( 'trash' != $oldpost->post_status && 'trash' != $newpost->post_status ) {
|
785 |
+
$old_virtual = get_post_meta( $oldpost->ID, '_virtual', true );
|
786 |
+
$new_virtual = isset( $post_array['_virtual'] ) ? 'yes' : 'no';
|
787 |
+
$old_downloadable = get_post_meta( $oldpost->ID, '_downloadable', true );
|
788 |
+
$new_downloadable = isset( $post_array['_downloadable'] ) ? 'yes' : 'no';
|
789 |
+
|
790 |
+
if ( ($old_virtual && $new_virtual) && ($old_virtual != $new_virtual) ) {
|
791 |
+
$type = ( 'no' == $new_virtual ) ? 'Non Virtual' : 'Virtual';
|
792 |
+
$result = $this->EventType( $oldpost, $type );
|
793 |
+
}
|
794 |
+
if ( ($old_downloadable && $new_downloadable) && ($old_downloadable != $new_downloadable) ) {
|
795 |
+
$type = ( 'no' == $new_downloadable ) ? 'Non Downloadable' : 'Downloadable';
|
796 |
+
$result = $this->EventType( $oldpost, $type );
|
797 |
+
}
|
798 |
+
}
|
799 |
+
return $result;
|
800 |
+
}
|
801 |
+
|
802 |
+
/**
|
803 |
+
* Group the Type changes in one function.
|
804 |
+
*
|
805 |
+
* @param object $oldpost - Old product object.
|
806 |
+
* @param string $type - Product Type.
|
807 |
+
* @return int
|
808 |
+
*/
|
809 |
+
private function EventType( $oldpost, $type ) {
|
810 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
811 |
+
$this->plugin->alerts->Trigger(
|
812 |
+
9020, array(
|
813 |
+
'ProductTitle' => $oldpost->post_title,
|
814 |
+
'Type' => $type,
|
815 |
+
$editor_link['name'] => $editor_link['value'],
|
816 |
+
)
|
817 |
+
);
|
818 |
+
return 1;
|
819 |
+
}
|
820 |
+
|
821 |
+
/**
|
822 |
+
* Trigger events 9021
|
823 |
+
*
|
824 |
+
* @param object $oldpost - Old product object.
|
825 |
+
* @return int
|
826 |
+
*/
|
827 |
+
protected function CheckWeightChange( $oldpost ) {
|
828 |
+
// Filter POST global array.
|
829 |
+
$post_array = filter_input_array( INPUT_POST );
|
830 |
+
|
831 |
+
if ( isset( $post_array['post_ID'] )
|
832 |
+
&& isset( $post_array['_wpnonce'] )
|
833 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
834 |
+
return false;
|
835 |
+
}
|
836 |
+
|
837 |
+
$old_weight = get_post_meta( $oldpost->ID, '_weight', true );
|
838 |
+
$new_weight = isset( $post_array['_weight'] ) ? $post_array['_weight'] : null;
|
839 |
+
|
840 |
+
if ( ($new_weight) && ($old_weight != $new_weight) ) {
|
841 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
842 |
+
$this->plugin->alerts->Trigger(
|
843 |
+
9021, array(
|
844 |
+
'ProductTitle' => $oldpost->post_title,
|
845 |
+
'OldWeight' => ( ! empty( $old_weight ) ? $old_weight : 0),
|
846 |
+
'NewWeight' => $new_weight,
|
847 |
+
$editor_link['name'] => $editor_link['value'],
|
848 |
+
)
|
849 |
+
);
|
850 |
+
return 1;
|
851 |
+
}
|
852 |
+
return 0;
|
853 |
+
}
|
854 |
+
|
855 |
+
/**
|
856 |
+
* Trigger events 9022
|
857 |
+
*
|
858 |
+
* @param object $oldpost - Old product object.
|
859 |
+
* @return int
|
860 |
+
*/
|
861 |
+
protected function CheckDimensionsChange( $oldpost ) {
|
862 |
+
// Filter POST global array.
|
863 |
+
$post_array = filter_input_array( INPUT_POST );
|
864 |
+
|
865 |
+
if ( isset( $post_array['post_ID'] )
|
866 |
+
&& isset( $post_array['_wpnonce'] )
|
867 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
868 |
+
return false;
|
869 |
+
}
|
870 |
+
|
871 |
+
$result = 0;
|
872 |
+
$old_length = get_post_meta( $oldpost->ID, '_length', true );
|
873 |
+
$new_length = isset( $post_array['_length'] ) ? $post_array['_length'] : null;
|
874 |
+
$old_width = get_post_meta( $oldpost->ID, '_width', true );
|
875 |
+
$new_width = isset( $post_array['_width'] ) ? $post_array['_width'] : null;
|
876 |
+
$old_height = get_post_meta( $oldpost->ID, '_height', true );
|
877 |
+
$new_height = isset( $post_array['_height'] ) ? $post_array['_height'] : null;
|
878 |
+
|
879 |
+
if ( ($new_length) && ($old_length != $new_length) ) {
|
880 |
+
$result = $this->EventDimension( $oldpost, 'Length', $old_length, $new_length );
|
881 |
+
}
|
882 |
+
if ( ($new_width) && ($old_width != $new_width) ) {
|
883 |
+
$result = $this->EventDimension( $oldpost, 'Width', $old_width, $new_width );
|
884 |
+
}
|
885 |
+
if ( ($new_height) && ($old_height != $new_height) ) {
|
886 |
+
$result = $this->EventDimension( $oldpost, 'Height', $old_height, $new_height );
|
887 |
+
}
|
888 |
+
return $result;
|
889 |
+
}
|
890 |
+
|
891 |
+
/**
|
892 |
+
* Group the Dimension changes in one function.
|
893 |
+
*
|
894 |
+
* @param object $oldpost - Old Product object.
|
895 |
+
* @param string $type - Dimension type.
|
896 |
+
* @param string $old_dimension - Old dimension.
|
897 |
+
* @param string $new_dimension - New dimension.
|
898 |
+
* @return int
|
899 |
+
*/
|
900 |
+
private function EventDimension( $oldpost, $type, $old_dimension, $new_dimension ) {
|
901 |
+
$dimension_unit = $this->GetConfig( 'dimension_unit' );
|
902 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
903 |
+
$this->plugin->alerts->Trigger(
|
904 |
+
9022, array(
|
905 |
+
'ProductTitle' => $oldpost->post_title,
|
906 |
+
'DimensionType' => $type,
|
907 |
+
'OldDimension' => ( ! empty( $old_dimension ) ? $dimension_unit . ' ' . $old_dimension : 0),
|
908 |
+
'NewDimension' => $dimension_unit . ' ' . $new_dimension,
|
909 |
+
$editor_link['name'] => $editor_link['value'],
|
910 |
+
)
|
911 |
+
);
|
912 |
+
return 1;
|
913 |
+
}
|
914 |
+
|
915 |
+
/**
|
916 |
+
* Trigger events 9023, 9024, 9025, 9026
|
917 |
+
*
|
918 |
+
* @param object $oldpost - Old product object.
|
919 |
+
* @return int
|
920 |
+
*/
|
921 |
+
protected function CheckDownloadableFileChange( $oldpost ) {
|
922 |
+
// Filter POST global array.
|
923 |
+
$post_array = filter_input_array( INPUT_POST );
|
924 |
+
|
925 |
+
if ( isset( $post_array['post_ID'] )
|
926 |
+
&& isset( $post_array['_wpnonce'] )
|
927 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'update-post_' . $post_array['post_ID'] ) ) {
|
928 |
+
return false;
|
929 |
+
}
|
930 |
+
|
931 |
+
$result = 0;
|
932 |
+
$is_url_changed = false;
|
933 |
+
$is_name_changed = false;
|
934 |
+
$new_file_names = ! empty( $post_array['_wc_file_names'] ) ? $post_array['_wc_file_names'] : array();
|
935 |
+
$new_file_urls = ! empty( $post_array['_wc_file_urls'] ) ? $post_array['_wc_file_urls'] : array();
|
936 |
+
$editor_link = $this->GetEditorLink( $oldpost );
|
937 |
+
$added_urls = array_diff( $new_file_urls, $this->_old_file_urls );
|
938 |
+
|
939 |
+
// Added files to the product.
|
940 |
+
if ( count( $added_urls ) > 0 ) {
|
941 |
+
// If the file has only changed URL.
|
942 |
+
if ( count( $new_file_urls ) == count( $this->_old_file_urls ) ) {
|
943 |
+
$is_url_changed = true;
|
944 |
+
} else {
|
945 |
+
foreach ( $added_urls as $key => $url ) {
|
946 |
+
$this->plugin->alerts->Trigger(
|
947 |
+
9023, array(
|
948 |
+
'ProductTitle' => $oldpost->post_title,
|
949 |
+
'FileName' => $new_file_names[ $key ],
|
950 |
+
'FileUrl' => $url,
|
951 |
+
$editor_link['name'] => $editor_link['value'],
|
952 |
+
)
|
953 |
+
);
|
954 |
+
}
|
955 |
+
$result = 1;
|
956 |
+
}
|
957 |
+
}
|
958 |
+
|
959 |
+
$removed_urls = array_diff( $this->_old_file_urls, $new_file_urls );
|
960 |
+
// Removed files from the product.
|
961 |
+
if ( count( $removed_urls ) > 0 ) {
|
962 |
+
// If the file has only changed URL.
|
963 |
+
if ( count( $new_file_urls ) == count( $this->_old_file_urls ) ) {
|
964 |
+
$is_url_changed = true;
|
965 |
+
} else {
|
966 |
+
foreach ( $removed_urls as $key => $url ) {
|
967 |
+
$this->plugin->alerts->Trigger(
|
968 |
+
9024, array(
|
969 |
+
'ProductTitle' => $oldpost->post_title,
|
970 |
+
'FileName' => $this->_old_file_names[ $key ],
|
971 |
+
'FileUrl' => $url,
|
972 |
+
$editor_link['name'] => $editor_link['value'],
|
973 |
+
)
|
974 |
+
);
|
975 |
+
}
|
976 |
+
$result = 1;
|
977 |
+
}
|
978 |
+
}
|
979 |
+
|
980 |
+
$added_names = array_diff( $new_file_names, $this->_old_file_names );
|
981 |
+
if ( count( $added_names ) > 0 ) {
|
982 |
+
// If the file has only changed Name.
|
983 |
+
if ( count( $new_file_names ) == count( $this->_old_file_names ) ) {
|
984 |
+
foreach ( $added_names as $key => $name ) {
|
985 |
+
$this->plugin->alerts->Trigger(
|
986 |
+
9025, array(
|
987 |
+
'ProductTitle' => $oldpost->post_title,
|
988 |
+
'OldName' => $this->_old_file_names[ $key ],
|
989 |
+
'NewName' => $name,
|
990 |
+
$editor_link['name'] => $editor_link['value'],
|
991 |
+
)
|
992 |
+
);
|
993 |
+
}
|
994 |
+
$result = 1;
|
995 |
+
}
|
996 |
+
}
|
997 |
+
|
998 |
+
if ( $is_url_changed ) {
|
999 |
+
foreach ( $added_urls as $key => $url ) {
|
1000 |
+
$this->plugin->alerts->Trigger(
|
1001 |
+
9026, array(
|
1002 |
+
'ProductTitle' => $oldpost->post_title,
|
1003 |
+
'FileName' => $new_file_names[ $key ],
|
1004 |
+
'OldUrl' => $removed_urls[ $key ],
|
1005 |
+
'NewUrl' => $url,
|
1006 |
+
$editor_link['name'] => $editor_link['value'],
|
1007 |
+
)
|
1008 |
+
);
|
1009 |
+
}
|
1010 |
+
$result = 1;
|
1011 |
+
}
|
1012 |
+
return $result;
|
1013 |
+
}
|
1014 |
+
|
1015 |
+
/**
|
1016 |
+
* Trigger events Settings: 9027, 9028, 9029, 9030, 9031, 9032, 9033
|
1017 |
+
*/
|
1018 |
+
protected function CheckSettingsChange() {
|
1019 |
+
// Filter POST and GET global arrays.
|
1020 |
+
$post_array = filter_input_array( INPUT_POST );
|
1021 |
+
$get_array = filter_input_array( INPUT_GET );
|
1022 |
+
|
1023 |
+
if ( isset( $post_array['_wpnonce'] )
|
1024 |
+
&& ! wp_verify_nonce( $post_array['_wpnonce'], 'woocommerce-settings' ) ) {
|
1025 |
+
return false;
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
if ( isset( $get_array['page'] ) && 'wc-settings' == $get_array['page'] ) {
|
1029 |
+
if ( isset( $get_array['tab'] ) && 'products' == $get_array['tab'] ) {
|
1030 |
+
if ( isset( $post_array['woocommerce_weight_unit'] ) ) {
|
1031 |
+
$old_unit = $this->GetConfig( 'weight_unit' );
|
1032 |
+
$new_unit = $post_array['woocommerce_weight_unit'];
|
1033 |
+
if ( $old_unit != $new_unit ) {
|
1034 |
+
$this->plugin->alerts->Trigger(
|
1035 |
+
9027, array(
|
1036 |
+
'OldUnit' => $old_unit,
|
1037 |
+
'NewUnit' => $new_unit,
|
1038 |
+
)
|
1039 |
+
);
|
1040 |
+
}
|
1041 |
+
}
|
1042 |
+
if ( isset( $post_array['woocommerce_dimension_unit'] ) ) {
|
1043 |
+
$old_unit = $this->GetConfig( 'dimension_unit' );
|
1044 |
+
$new_unit = $post_array['woocommerce_dimension_unit'];
|
1045 |
+
if ( $old_unit != $new_unit ) {
|
1046 |
+
$this->plugin->alerts->Trigger(
|
1047 |
+
9028, array(
|
1048 |
+
'OldUnit' => $old_unit,
|
1049 |
+
'NewUnit' => $new_unit,
|
1050 |
+
)
|
1051 |
+
);
|
1052 |
+
}
|
1053 |
+
}
|
1054 |
+
} elseif ( isset( $get_array['tab'] ) && 'checkout' == $get_array['tab'] ) {
|
1055 |
+
if ( ! empty( $post_array ) && '' == $get_array['section'] ) {
|
1056 |
+
$old_enable_coupons = $this->GetConfig( 'enable_coupons' );
|
1057 |
+
$new_enable_coupons = isset( $post_array['woocommerce_enable_coupons'] ) ? 'yes' : 'no';
|
1058 |
+
if ( $old_enable_coupons != $new_enable_coupons ) {
|
1059 |
+
$status = ( 'yes' == $new_enable_coupons ) ? 'Enabled' : 'Disabled';
|
1060 |
+
$this->plugin->alerts->Trigger(
|
1061 |
+
9032, array(
|
1062 |
+
'Status' => $status,
|
1063 |
+
)
|
1064 |
+
);
|
1065 |
+
}
|
1066 |
+
$old_enable_guest_checkout = $this->GetConfig( 'enable_guest_checkout' );
|
1067 |
+
$new_enable_guest_checkout = isset( $post_array['woocommerce_enable_guest_checkout'] ) ? 'yes' : 'no';
|
1068 |
+
if ( $old_enable_guest_checkout != $new_enable_guest_checkout ) {
|
1069 |
+
$status = ( 'yes' == $new_enable_guest_checkout ) ? 'Enabled' : 'Disabled';
|
1070 |
+
$this->plugin->alerts->Trigger(
|
1071 |
+
9033, array(
|
1072 |
+
'Status' => $status,
|
1073 |
+
)
|
1074 |
+
);
|
1075 |
+
}
|
1076 |
+
} elseif ( ! empty( $post_array ) && 'cod' === $get_array['section'] ) {
|
1077 |
+
$old_cash_on_delivery = $this->GetConfig( 'cod_settings' );
|
1078 |
+
$old_cash_on_delivery = isset( $old_cash_on_delivery['enabled'] ) ? $old_cash_on_delivery['enabled'] : '';
|
1079 |
+
$new_cash_on_delivery = isset( $post_array['woocommerce_cod_enabled'] ) ? 'yes' : 'no';
|
1080 |
+
if ( $old_cash_on_delivery !== $new_cash_on_delivery ) {
|
1081 |
+
$status = ( 'yes' === $new_cash_on_delivery ) ? 'Enabled' : 'Disabled';
|
1082 |
+
$this->plugin->alerts->Trigger(
|
1083 |
+
9034, array(
|
1084 |
+
'Status' => $status,
|
1085 |
+
)
|
1086 |
+
);
|
1087 |
+
}
|
1088 |
+
}
|
1089 |
+
} else {
|
1090 |
+
if ( isset( $post_array['woocommerce_default_country'] ) ) {
|
1091 |
+
$old_location = $this->GetConfig( 'default_country' );
|
1092 |
+
$new_location = $post_array['woocommerce_default_country'];
|
1093 |
+
if ( $old_location != $new_location ) {
|
1094 |
+
$this->plugin->alerts->Trigger(
|
1095 |
+
9029, array(
|
1096 |
+
'OldLocation' => $old_location,
|
1097 |
+
'NewLocation' => $new_location,
|
1098 |
+
)
|
1099 |
+
);
|
1100 |
+
}
|
1101 |
+
$old_calc_taxes = $this->GetConfig( 'calc_taxes' );
|
1102 |
+
$new_calc_taxes = isset( $post_array['woocommerce_calc_taxes'] ) ? 'yes' : 'no';
|
1103 |
+
if ( $old_calc_taxes != $new_calc_taxes ) {
|
1104 |
+
$status = ( 'yes' == $new_calc_taxes ) ? 'Enabled' : 'Disabled';
|
1105 |
+
$this->plugin->alerts->Trigger(
|
1106 |
+
9030, array(
|
1107 |
+
'Status' => $status,
|
1108 |
+
)
|
1109 |
+
);
|
1110 |
+
}
|
1111 |
+
}
|
1112 |
+
if ( isset( $post_array['woocommerce_currency'] ) ) {
|
1113 |
+
$old_currency = $this->GetConfig( 'currency' );
|
1114 |
+
$new_currency = $post_array['woocommerce_currency'];
|
1115 |
+
if ( $old_currency != $new_currency ) {
|
1116 |
+
$this->plugin->alerts->Trigger(
|
1117 |
+
9031, array(
|
1118 |
+
'OldCurrency' => $old_currency,
|
1119 |
+
'NewCurrency' => $new_currency,
|
1120 |
+
)
|
1121 |
+
);
|
1122 |
+
}
|
1123 |
+
}
|
1124 |
+
}
|
1125 |
+
}
|
1126 |
+
}
|
1127 |
+
|
1128 |
+
/**
|
1129 |
+
* Get Stock Status Name.
|
1130 |
+
*
|
1131 |
+
* @param string $slug - Stock slug.
|
1132 |
+
* @return string
|
1133 |
+
*/
|
1134 |
+
private function GetStockStatusName( $slug ) {
|
1135 |
+
if ( 'instock' == $slug ) {
|
1136 |
+
return __( 'In stock', 'wp-security-audit-log' );
|
1137 |
+
} elseif ( 'outofstock' == $slug ) {
|
1138 |
+
return __( 'Out of stock', 'wp-security-audit-log' );
|
1139 |
+
}
|
1140 |
+
}
|
1141 |
+
|
1142 |
+
/**
|
1143 |
+
* Return: Product Categories.
|
1144 |
+
*
|
1145 |
+
* @param object $post - Product post object.
|
1146 |
+
* @return array
|
1147 |
+
*/
|
1148 |
+
protected function GetProductCategories( $post ) {
|
1149 |
+
return wp_get_post_terms(
|
1150 |
+
$post->ID, 'product_cat', array(
|
1151 |
+
'fields' => 'names',
|
1152 |
+
)
|
1153 |
+
);
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
/**
|
1157 |
+
* Return: Product Data.
|
1158 |
+
*
|
1159 |
+
* @param object $post - Product post object.
|
1160 |
+
* @return array
|
1161 |
+
*/
|
1162 |
+
protected function GetProductData( $post ) {
|
1163 |
+
return wp_get_post_terms(
|
1164 |
+
$post->ID, 'product_type', array(
|
1165 |
+
'fields' => 'names',
|
1166 |
+
)
|
1167 |
+
);
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
/**
|
1171 |
+
* Get the config setting
|
1172 |
+
*
|
1173 |
+
* @param string $option_name - Option Name.
|
1174 |
+
* @return string
|
1175 |
+
*/
|
1176 |
+
private function GetConfig( $option_name ) {
|
1177 |
+
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
1178 |
+
return $fn( 'woocommerce_' . $option_name );
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
/**
|
1182 |
+
* Check post type.
|
1183 |
+
*
|
1184 |
+
* @param stdClass $post - Post.
|
1185 |
+
* @return bool
|
1186 |
+
*/
|
1187 |
+
private function CheckWooCommerce( $post ) {
|
1188 |
+
switch ( $post->post_type ) {
|
1189 |
+
case 'product':
|
1190 |
+
return true;
|
1191 |
+
default:
|
1192 |
+
return false;
|
1193 |
+
}
|
1194 |
+
}
|
1195 |
+
|
1196 |
+
/**
|
1197 |
+
* Get editor link.
|
1198 |
+
*
|
1199 |
+
* @param stdClass $post - The post.
|
1200 |
+
* @return array $editor_link - Name and value link.
|
1201 |
+
*/
|
1202 |
+
private function GetEditorLink( $post ) {
|
1203 |
+
$name = 'EditorLinkProduct';
|
1204 |
+
$value = get_edit_post_link( $post->ID );
|
1205 |
+
$editor_link = array(
|
1206 |
+
'name' => $name,
|
1207 |
+
'value' => $value,
|
1208 |
+
);
|
1209 |
+
return $editor_link;
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
/**
|
1213 |
+
* Get Currency symbol.
|
1214 |
+
*
|
1215 |
+
* @param string $currency - Currency (default: '').
|
1216 |
+
* @return string
|
1217 |
+
*/
|
1218 |
+
private function GetCurrencySymbol( $currency = '' ) {
|
1219 |
+
$symbols = array(
|
1220 |
+
'AED' => 'د.إ',
|
1221 |
+
'AFN' => '؋',
|
1222 |
+
'ALL' => 'L',
|
1223 |
+
'AMD' => 'AMD',
|
1224 |
+
'ANG' => 'ƒ',
|
1225 |
+
'AOA' => 'Kz',
|
1226 |
+
'ARS' => '$',
|
1227 |
+
'AUD' => '$',
|
1228 |
+
'AWG' => 'ƒ',
|
1229 |
+
'AZN' => 'AZN',
|
1230 |
+
'BAM' => 'KM',
|
1231 |
+
'BBD' => '$',
|
1232 |
+
'BDT' => '৳ ',
|
1233 |
+
'BGN' => 'лв.',
|
1234 |
+
'BHD' => '.د.ب',
|
1235 |
+
'BIF' => 'Fr',
|
1236 |
+
'BMD' => '$',
|
1237 |
+
'BND' => '$',
|
1238 |
+
'BOB' => 'Bs.',
|
1239 |
+
'BRL' => 'R$',
|
1240 |
+
'BSD' => '$',
|
1241 |
+
'BTC' => '฿',
|
1242 |
+
'BTN' => 'Nu.',
|
1243 |
+
'BWP' => 'P',
|
1244 |
+
'BYR' => 'Br',
|
1245 |
+
'BZD' => '$',
|
1246 |
+
'CAD' => '$',
|
1247 |
+
'CDF' => 'Fr',
|
1248 |
+
'CHF' => 'CHF',
|
1249 |
+
'CLP' => '$',
|
1250 |
+
'CNY' => '¥',
|
1251 |
+
'COP' => '$',
|
1252 |
+
'CRC' => '₡',
|
1253 |
+
'CUC' => '$',
|
1254 |
+
'CUP' => '$',
|
1255 |
+
'CVE' => '$',
|
1256 |
+
'CZK' => 'Kč',
|
1257 |
+
'DJF' => 'Fr',
|
1258 |
+
'DKK' => 'DKK',
|
1259 |
+
'DOP' => 'RD$',
|
1260 |
+
'DZD' => 'د.ج',
|
1261 |
+
'EGP' => 'EGP',
|
1262 |
+
'ERN' => 'Nfk',
|
1263 |
+
'ETB' => 'Br',
|
1264 |
+
'EUR' => '€',
|
1265 |
+
'FJD' => '$',
|
1266 |
+
'FKP' => '£',
|
1267 |
+
'GBP' => '£',
|
1268 |
+
'GEL' => 'ლ',
|
1269 |
+
'GGP' => '£',
|
1270 |
+
'GHS' => '₵',
|
1271 |
+
'GIP' => '£',
|
1272 |
+
'GMD' => 'D',
|
1273 |
+
'GNF' => 'Fr',
|
1274 |
+
'GTQ' => 'Q',
|
1275 |
+
'GYD' => '$',
|
1276 |
+
'HKD' => '$',
|
1277 |
+
'HNL' => 'L',
|
1278 |
+
'HRK' => 'Kn',
|
1279 |
+
'HTG' => 'G',
|
1280 |
+
'HUF' => 'Ft',
|
1281 |
+
'IDR' => 'Rp',
|
1282 |
+
'ILS' => '₪',
|
1283 |
+
'IMP' => '£',
|
1284 |
+
'INR' => '₹',
|
1285 |
+
'IQD' => 'ع.د',
|
1286 |
+
'IRR' => '﷼',
|
1287 |
+
'ISK' => 'kr.',
|
1288 |
+
'JEP' => '£',
|
1289 |
+
'JMD' => '$',
|
1290 |
+
'JOD' => 'د.ا',
|
1291 |
+
'JPY' => '¥',
|
1292 |
+
'KES' => 'KSh',
|
1293 |
+
'KGS' => 'сом',
|
1294 |
+
'KHR' => '៛',
|
1295 |
+
'KMF' => 'Fr',
|
1296 |
+
'KPW' => '₩',
|
1297 |
+
'KRW' => '₩',
|
1298 |
+
'KWD' => 'د.ك',
|
1299 |
+
'KYD' => '$',
|
1300 |
+
'KZT' => 'KZT',
|
1301 |
+
'LAK' => '₭',
|
1302 |
+
'LBP' => 'ل.ل',
|
1303 |
+
'LKR' => 'රු',
|
1304 |
+
'LRD' => '$',
|
1305 |
+
'LSL' => 'L',
|
1306 |
+
'LYD' => 'ل.د',
|
1307 |
+
'MAD' => 'د. م.',
|
1308 |
+
'MAD' => 'د.م.',
|
1309 |
+
'MDL' => 'L',
|
1310 |
+
'MGA' => 'Ar',
|
1311 |
+
'MKD' => 'ден',
|
1312 |
+
'MMK' => 'Ks',
|
1313 |
+
'MNT' => '₮',
|
1314 |
+
'MOP' => 'P',
|
1315 |
+
'MRO' => 'UM',
|
1316 |
+
'MUR' => '₨',
|
1317 |
+
'MVR' => '.ރ',
|
1318 |
+
'MWK' => 'MK',
|
1319 |
+
'MXN' => '$',
|
1320 |
+
'MYR' => 'RM',
|
1321 |
+
'MZN' => 'MT',
|
1322 |
+
'NAD' => '$',
|
1323 |
+
'NGN' => '₦',
|
1324 |
+
'NIO' => 'C$',
|
1325 |
+
'NOK' => 'kr',
|
1326 |
+
'NPR' => '₨',
|
1327 |
+
'NZD' => '$',
|
1328 |
+
'OMR' => 'ر.ع.',
|
1329 |
+
'PAB' => 'B/.',
|
1330 |
+
'PEN' => 'S/.',
|
1331 |
+
'PGK' => 'K',
|
1332 |
+
'PHP' => '₱',
|
1333 |
+
'PKR' => '₨',
|
1334 |
+
'PLN' => 'zł',
|
1335 |
+
'PRB' => 'р.',
|
1336 |
+
'PYG' => '₲',
|
1337 |
+
'QAR' => 'ر.ق',
|
1338 |
+
'RMB' => '¥',
|
1339 |
+
'RON' => 'lei',
|
1340 |
+
'RSD' => 'дин.',
|
1341 |
+
'RUB' => '₽',
|
1342 |
+
'RWF' => 'Fr',
|
1343 |
+
'SAR' => 'ر.س',
|
1344 |
+
'SBD' => '$',
|
1345 |
+
'SCR' => '₨',
|
1346 |
+
'SDG' => 'ج.س.',
|
1347 |
+
'SEK' => 'kr',
|
1348 |
+
'SGD' => '$',
|
1349 |
+
'SHP' => '£',
|
1350 |
+
'SLL' => 'Le',
|
1351 |
+
'SOS' => 'Sh',
|
1352 |
+
'SRD' => '$',
|
1353 |
+
'SSP' => '£',
|
1354 |
+
'STD' => 'Db',
|
1355 |
+
'SYP' => 'ل.س',
|
1356 |
+
'SZL' => 'L',
|
1357 |
+
'THB' => '฿',
|
1358 |
+
'TJS' => 'ЅМ',
|
1359 |
+
'TMT' => 'm',
|
1360 |
+
'TND' => 'د.ت',
|
1361 |
+
'TOP' => 'T$',
|
1362 |
+
'TRY' => '₺',
|
1363 |
+
'TTD' => '$',
|
1364 |
+
'TWD' => 'NT$',
|
1365 |
+
'TZS' => 'Sh',
|
1366 |
+
'UAH' => '₴',
|
1367 |
+
'UGX' => 'UGX',
|
1368 |
+
'USD' => '$',
|
1369 |
+
'UYU' => '$',
|
1370 |
+
'UZS' => 'UZS',
|
1371 |
+
'VEF' => 'Bs F',
|
1372 |
+
'VND' => '₫',
|
1373 |
+
'VUV' => 'Vt',
|
1374 |
+
'WST' => 'T',
|
1375 |
+
'XAF' => 'Fr',
|
1376 |
+
'XCD' => '$',
|
1377 |
+
'XOF' => 'Fr',
|
1378 |
+
'XPF' => 'Fr',
|
1379 |
+
'YER' => '﷼',
|
1380 |
+
'ZAR' => 'R',
|
1381 |
+
'ZMW' => 'ZK',
|
1382 |
+
);
|
1383 |
+
$currency_symbol = isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : '';
|
1384 |
+
|
1385 |
+
return $currency_symbol;
|
1386 |
+
}
|
1387 |
}
|
classes/Settings.php
CHANGED
@@ -1,17 +1,31 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* This class is the actual controller of the Settings Page.
|
|
|
|
|
6 |
*/
|
7 |
-
class WSAL_Settings
|
8 |
-
|
9 |
/**
|
|
|
|
|
10 |
* @var WpSecurityAuditLog
|
11 |
*/
|
12 |
protected $_plugin;
|
13 |
|
14 |
-
// <editor-fold desc="Developer Options">
|
15 |
const OPT_DEV_DATA_INSPECTOR = 'd';
|
16 |
const OPT_DEV_PHP_ERRORS = 'p';
|
17 |
const OPT_DEV_REQUEST_LOG = 'r';
|
@@ -19,30 +33,66 @@ class WSAL_Settings
|
|
19 |
|
20 |
const ERROR_CODE_INVALID_IP = 901;
|
21 |
|
|
|
|
|
|
|
|
|
|
|
22 |
protected $_devoption = null;
|
23 |
|
|
|
|
|
|
|
|
|
|
|
24 |
protected $_pruning = 0;
|
25 |
|
|
|
|
|
|
|
|
|
|
|
26 |
protected $_disabled = null;
|
27 |
|
|
|
|
|
|
|
|
|
|
|
28 |
protected $_viewers = null;
|
29 |
|
|
|
|
|
|
|
|
|
|
|
30 |
protected $_editors = null;
|
31 |
|
|
|
|
|
|
|
|
|
|
|
32 |
protected $_perpage = null;
|
33 |
|
34 |
/**
|
35 |
-
* Users excluded from monitoring
|
|
|
|
|
36 |
*/
|
37 |
protected $_excluded_users = array();
|
38 |
|
39 |
/**
|
40 |
-
* Roles excluded from monitoring
|
|
|
|
|
41 |
*/
|
42 |
-
protected $_excluded_roles =
|
43 |
|
44 |
/**
|
45 |
-
* Custom fields excluded from monitoring
|
|
|
|
|
46 |
*/
|
47 |
protected $_excluded_custom = array();
|
48 |
|
@@ -54,180 +104,196 @@ class WSAL_Settings
|
|
54 |
protected $_post_types = array();
|
55 |
|
56 |
/**
|
57 |
-
* IP excluded from monitoring
|
|
|
|
|
58 |
*/
|
59 |
protected $_excluded_ip = array();
|
60 |
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
63 |
$this->_plugin = $plugin;
|
64 |
}
|
65 |
|
66 |
/**
|
67 |
-
*
|
|
|
|
|
68 |
*/
|
69 |
-
public function GetDefaultDevOptions()
|
70 |
-
{
|
71 |
return array();
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
* Returns whether a developer option is enabled or not.
|
76 |
-
*
|
77 |
-
* @
|
|
|
78 |
*/
|
79 |
-
public function IsDevOptionEnabled($option)
|
80 |
-
|
81 |
-
if (is_null($this->_devoption)) {
|
82 |
$this->_devoption = $this->_plugin->GetGlobalOption(
|
83 |
'dev-options',
|
84 |
-
implode(',', $this->GetDefaultDevOptions())
|
85 |
);
|
86 |
-
$this->_devoption = explode(',', $this->_devoption);
|
87 |
}
|
88 |
-
return in_array($option, $this->_devoption);
|
89 |
}
|
90 |
|
91 |
/**
|
92 |
-
*
|
|
|
|
|
93 |
*/
|
94 |
-
public function IsAnyDevOptionEnabled()
|
95 |
-
|
96 |
-
return !!$this->_plugin->GetGlobalOption('dev-options', null);
|
97 |
}
|
98 |
|
99 |
/**
|
100 |
* Sets whether a developer option is enabled or not.
|
101 |
-
*
|
102 |
-
* @param
|
|
|
103 |
*/
|
104 |
-
public function SetDevOptionEnabled($option, $enabled)
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
unset($this->_devoption[$p]);
|
111 |
}
|
112 |
-
//
|
113 |
-
if ($enabled) {
|
114 |
$this->_devoption[] = $option;
|
115 |
}
|
116 |
-
//
|
117 |
$this->_plugin->SetGlobalOption(
|
118 |
'dev-options',
|
119 |
-
implode(',', $this->_devoption)
|
120 |
);
|
121 |
}
|
122 |
|
123 |
/**
|
124 |
* Remove all enabled developer options.
|
125 |
*/
|
126 |
-
public function ClearDevOptions()
|
127 |
-
{
|
128 |
$this->_devoption = array();
|
129 |
-
$this->_plugin->SetGlobalOption('dev-options', '');
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
-
*
|
|
|
|
|
134 |
*/
|
135 |
-
public function IsDataInspectorEnabled()
|
136 |
-
|
137 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_DATA_INSPECTOR);
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
-
*
|
|
|
|
|
142 |
*/
|
143 |
-
public function IsPhpErrorLoggingEnabled()
|
144 |
-
|
145 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_PHP_ERRORS);
|
146 |
}
|
147 |
|
148 |
/**
|
149 |
-
*
|
|
|
|
|
150 |
*/
|
151 |
-
public function IsRequestLoggingEnabled()
|
152 |
-
|
153 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_REQUEST_LOG);
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
-
*
|
|
|
|
|
158 |
*/
|
159 |
-
public function IsBacktraceLoggingEnabled()
|
160 |
-
|
161 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_BACKTRACE_LOG);
|
162 |
}
|
163 |
|
164 |
-
// </editor-fold>
|
165 |
-
|
166 |
/**
|
167 |
-
*
|
|
|
|
|
168 |
*/
|
169 |
-
public function IsWidgetsEnabled()
|
170 |
-
|
171 |
-
return !$this->_plugin->GetGlobalOption('disable-widgets');
|
172 |
}
|
173 |
|
174 |
/**
|
175 |
-
*
|
|
|
|
|
176 |
*/
|
177 |
-
public function SetWidgetsEnabled($newvalue)
|
178 |
-
|
179 |
-
$this->_plugin->SetGlobalOption('disable-widgets', !$newvalue);
|
180 |
}
|
181 |
|
182 |
/**
|
183 |
-
*
|
|
|
|
|
184 |
*/
|
185 |
-
public function IsRefreshAlertsEnabled()
|
186 |
-
|
187 |
-
return !$this->_plugin->GetGlobalOption('disable-refresh');
|
188 |
}
|
189 |
|
190 |
/**
|
191 |
-
*
|
|
|
|
|
192 |
*/
|
193 |
-
public function SetRefreshAlertsEnabled($newvalue)
|
194 |
-
|
195 |
-
$this->_plugin->SetGlobalOption('disable-refresh', !$newvalue);
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
-
*
|
|
|
|
|
200 |
*/
|
201 |
-
public function GetDashboardWidgetMaxAlerts()
|
202 |
-
{
|
203 |
return 5;
|
204 |
}
|
205 |
|
206 |
-
// <editor-fold desc="Pruning Settings">
|
207 |
/**
|
208 |
-
*
|
|
|
|
|
209 |
*/
|
210 |
-
public function GetMaxAllowedAlerts()
|
211 |
-
{
|
212 |
return 5000;
|
213 |
}
|
214 |
|
215 |
/**
|
216 |
-
*
|
|
|
|
|
217 |
*/
|
218 |
-
public function GetDefaultPruningDate()
|
219 |
-
|
220 |
-
return '1 month';
|
221 |
}
|
222 |
|
223 |
/**
|
224 |
-
*
|
|
|
|
|
225 |
*/
|
226 |
-
public function GetPruningDate()
|
227 |
-
|
228 |
-
|
229 |
-
$this->_pruning
|
230 |
-
if (!strtotime($this->_pruning)) {
|
231 |
$this->_pruning = $this->GetDefaultPruningDate();
|
232 |
}
|
233 |
}
|
@@ -235,217 +301,210 @@ class WSAL_Settings
|
|
235 |
}
|
236 |
|
237 |
/**
|
238 |
-
*
|
|
|
|
|
239 |
*/
|
240 |
-
public function SetPruningDate($newvalue)
|
241 |
-
|
242 |
-
|
243 |
-
$this->_plugin->SetGlobalOption('pruning-date', $newvalue);
|
244 |
$this->_pruning = $newvalue;
|
245 |
}
|
246 |
}
|
247 |
|
248 |
/**
|
249 |
-
*
|
|
|
|
|
250 |
*/
|
251 |
-
public function GetPruningLimit()
|
252 |
-
|
253 |
-
$val = (int)$this->_plugin->GetGlobalOption('pruning-limit');
|
254 |
return $val ? $val : $this->GetMaxAllowedAlerts();
|
255 |
}
|
256 |
|
257 |
/**
|
258 |
-
*
|
|
|
|
|
259 |
*/
|
260 |
-
public function SetPruningLimit($newvalue)
|
261 |
-
|
262 |
-
$
|
263 |
-
$this->_plugin->SetGlobalOption('pruning-limit', $newvalue);
|
264 |
}
|
265 |
|
266 |
-
public function SetPruningDateEnabled($enabled)
|
267 |
-
|
268 |
-
$this->_plugin->SetGlobalOption('pruning-date-e', $enabled);
|
269 |
}
|
270 |
|
271 |
-
public function SetPruningLimitEnabled($enabled)
|
272 |
-
|
273 |
-
$this->_plugin->SetGlobalOption('pruning-limit-e', $enabled);
|
274 |
}
|
275 |
|
276 |
-
public function IsPruningDateEnabled(){
|
277 |
-
return $this->_plugin->GetGlobalOption('pruning-date-e');
|
278 |
}
|
279 |
|
280 |
-
public function IsPruningLimitEnabled()
|
281 |
-
|
282 |
-
return $this->_plugin->GetGlobalOption('pruning-limit-e');
|
283 |
}
|
284 |
|
285 |
-
public function IsRestrictAdmins()
|
286 |
-
|
287 |
-
return $this->_plugin->GetGlobalOption('restrict-admins', false);
|
288 |
}
|
289 |
|
290 |
/**
|
291 |
-
*
|
|
|
|
|
292 |
*/
|
293 |
-
public function IsSandboxPageEnabled()
|
294 |
-
|
295 |
-
|
296 |
-
return
|
297 |
}
|
298 |
|
299 |
-
public function SetRestrictAdmins($enable)
|
300 |
-
|
301 |
-
$this->_plugin->SetGlobalOption('restrict-admins', (bool)$enable);
|
302 |
}
|
303 |
|
304 |
-
|
305 |
-
|
306 |
-
{
|
307 |
-
return array(0000, 0001, 0002, 0003, 0004, 0005);
|
308 |
}
|
309 |
|
310 |
/**
|
311 |
-
*
|
|
|
|
|
312 |
*/
|
313 |
-
public function GetDisabledAlerts()
|
314 |
-
|
315 |
-
|
316 |
-
$this->_disabled =
|
317 |
-
$this->_disabled = $this->
|
318 |
-
$this->_disabled = (
|
319 |
-
$this->_disabled = array_map('intval', $this->_disabled);
|
320 |
}
|
321 |
return $this->_disabled;
|
322 |
}
|
323 |
|
324 |
/**
|
|
|
|
|
325 |
* @param array $types IDs alerts to disable.
|
326 |
*/
|
327 |
-
public function SetDisabledAlerts($types)
|
328 |
-
|
329 |
-
$this->
|
330 |
-
$this->_plugin->SetGlobalOption('disabled-alerts', implode(',', $this->_disabled));
|
331 |
}
|
332 |
|
333 |
-
public function IsIncognito()
|
334 |
-
|
335 |
-
return $this->_plugin->GetGlobalOption('hide-plugin');
|
336 |
}
|
337 |
|
338 |
-
public function SetIncognito($enabled)
|
339 |
-
|
340 |
-
return $this->_plugin->SetGlobalOption('hide-plugin', $enabled);
|
341 |
}
|
342 |
|
343 |
/**
|
344 |
* Checking if Logging is enabled.
|
345 |
*/
|
346 |
-
public function IsLoggingDisabled()
|
347 |
-
|
348 |
-
return $this->_plugin->GetGlobalOption('disable-logging');
|
349 |
}
|
350 |
|
351 |
-
public function SetLoggingDisabled($disabled)
|
352 |
-
|
353 |
-
return $this->_plugin->SetGlobalOption('disable-logging', $disabled);
|
354 |
}
|
355 |
|
356 |
/**
|
357 |
* Checking if the data will be removed.
|
358 |
*/
|
359 |
-
public function IsDeleteData()
|
360 |
-
|
361 |
-
return $this->_plugin->GetGlobalOption('delete-data');
|
362 |
}
|
363 |
|
364 |
-
public function SetDeleteData($enabled)
|
365 |
-
|
366 |
-
return $this->_plugin->SetGlobalOption('delete-data', $enabled);
|
367 |
}
|
368 |
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
{
|
373 |
-
$this->_viewers = $usersOrRoles;
|
374 |
-
$this->_plugin->SetGlobalOption('plugin-viewers', implode(',', $this->_viewers));
|
375 |
}
|
376 |
|
377 |
-
public function GetAllowedPluginViewers()
|
378 |
-
|
379 |
-
|
380 |
-
$this->_viewers = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-viewers'))));
|
381 |
}
|
382 |
return $this->_viewers;
|
383 |
}
|
384 |
|
385 |
-
public function SetAllowedPluginEditors($
|
386 |
-
|
387 |
-
$this->_editors
|
388 |
-
$this->_plugin->SetGlobalOption('plugin-editors', implode(',', $this->_editors));
|
389 |
}
|
390 |
|
391 |
-
public function GetAllowedPluginEditors()
|
392 |
-
|
393 |
-
|
394 |
-
$this->_editors = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-editors'))));
|
395 |
}
|
396 |
return $this->_editors;
|
397 |
}
|
398 |
|
399 |
-
public function SetViewPerPage($newvalue)
|
400 |
-
|
401 |
-
$this->
|
402 |
-
$this->_plugin->SetGlobalOption('items-per-page', $this->_perpage);
|
403 |
}
|
404 |
|
405 |
-
public function GetViewPerPage()
|
406 |
-
|
407 |
-
|
408 |
-
$this->_perpage = (int)$this->_plugin->GetGlobalOption('items-per-page', 10);
|
409 |
}
|
410 |
return $this->_perpage;
|
411 |
}
|
412 |
|
413 |
/**
|
|
|
|
|
414 |
* @param string $action Type of action, either 'view' or 'edit'.
|
415 |
* @return boolean If user has access or not.
|
416 |
*/
|
417 |
-
public function CurrentUserCan($action)
|
418 |
-
|
419 |
-
return $this->UserCan(wp_get_current_user(), $action);
|
420 |
}
|
421 |
|
422 |
/**
|
423 |
-
*
|
|
|
|
|
424 |
*/
|
425 |
-
protected function GetSuperAdmins()
|
426 |
-
{
|
427 |
return $this->_plugin->IsMultisite() ? get_super_admins() : array();
|
428 |
}
|
429 |
|
430 |
/**
|
431 |
-
*
|
|
|
|
|
432 |
*/
|
433 |
-
protected function GetAdmins()
|
434 |
-
|
435 |
-
|
436 |
-
|
|
|
|
|
|
|
437 |
global $wpdb;
|
438 |
-
$cap = $wpdb->prefix.
|
439 |
$sql = "SELECT DISTINCT $wpdb->users.user_login"
|
440 |
. " FROM $wpdb->users"
|
441 |
. " INNER JOIN $wpdb->usermeta ON ($wpdb->users.ID = $wpdb->usermeta.user_id )"
|
442 |
. " WHERE $wpdb->usermeta.meta_key = '$cap'"
|
443 |
. " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
|
444 |
-
return $wpdb->get_col($sql);
|
445 |
} else {
|
446 |
$result = array();
|
447 |
$query = 'role=administrator&fields[]=user_login';
|
448 |
-
foreach (get_users($query) as $user) {
|
449 |
$result[] = $user->user_login;
|
450 |
}
|
451 |
return $result;
|
@@ -454,202 +513,180 @@ class WSAL_Settings
|
|
454 |
|
455 |
/**
|
456 |
* Returns access tokens for a particular action.
|
457 |
-
*
|
|
|
458 |
* @return string[] List of tokens (usernames, roles etc).
|
459 |
*/
|
460 |
-
public function GetAccessTokens($action)
|
461 |
-
{
|
462 |
$allowed = array();
|
463 |
-
switch ($action) {
|
464 |
case 'view':
|
465 |
$allowed = $this->GetAllowedPluginViewers();
|
466 |
-
$allowed = array_merge($allowed, $this->GetAllowedPluginEditors());
|
467 |
-
if (
|
468 |
-
$allowed = array_merge($allowed, $this->GetSuperAdmins());
|
469 |
-
$allowed = array_merge($allowed, $this->GetAdmins());
|
470 |
}
|
471 |
break;
|
472 |
case 'edit':
|
473 |
$allowed = $this->GetAllowedPluginEditors();
|
474 |
-
if (
|
475 |
-
$allowed = array_merge($allowed, $this->_plugin->IsMultisite() ? $this->GetSuperAdmins() : $this->GetAdmins());
|
476 |
}
|
477 |
break;
|
478 |
default:
|
479 |
-
throw new Exception('Unknown action "'
|
480 |
}
|
481 |
-
if (
|
482 |
-
if (is_multisite()) {
|
483 |
-
$allowed = array_merge($allowed, get_super_admins());
|
484 |
} else {
|
485 |
$allowed[] = 'administrator';
|
486 |
}
|
487 |
}
|
488 |
-
return array_unique($allowed);
|
489 |
}
|
490 |
|
491 |
/**
|
492 |
-
*
|
493 |
-
*
|
|
|
|
|
494 |
* @return boolean If user has access or not.
|
495 |
*/
|
496 |
-
public function UserCan($user, $action)
|
497 |
-
|
498 |
-
|
499 |
-
$user = get_userdata($user);
|
500 |
}
|
501 |
-
$allowed = $this->GetAccessTokens($action);
|
502 |
-
$check = array_merge($user->roles, array($user->user_login));
|
503 |
-
foreach ($check as $item) {
|
504 |
-
if (in_array($item, $allowed)) {
|
505 |
return true;
|
506 |
}
|
507 |
}
|
508 |
return false;
|
509 |
}
|
510 |
|
511 |
-
public function GetCurrentUserRoles($
|
512 |
-
|
513 |
-
|
514 |
-
$baseRoles = wp_get_current_user()->roles;
|
515 |
}
|
516 |
-
if (function_exists('is_super_admin') && is_super_admin()) {
|
517 |
-
$
|
518 |
}
|
519 |
-
return $
|
520 |
}
|
521 |
|
522 |
-
public function IsLoginSuperAdmin($username)
|
523 |
-
|
524 |
-
|
525 |
-
if (function_exists('is_super_admin') && is_super_admin($userId)) {
|
526 |
return true;
|
527 |
} else {
|
528 |
return false;
|
529 |
}
|
530 |
}
|
531 |
|
532 |
-
|
533 |
-
|
534 |
-
// <editor-fold desc="Licensing">
|
535 |
-
public function GetLicenses()
|
536 |
-
{
|
537 |
-
return $this->_plugin->GetGlobalOption('licenses');
|
538 |
}
|
539 |
|
540 |
-
public function GetLicense($name)
|
541 |
-
{
|
542 |
$data = $this->GetLicenses();
|
543 |
-
$name = sanitize_key(basename($name));
|
544 |
-
return isset($data[$name]) ? $data[$name] : array();
|
545 |
}
|
546 |
|
547 |
-
public function SetLicenses($data)
|
548 |
-
|
549 |
-
$this->_plugin->SetGlobalOption('licenses', $data);
|
550 |
}
|
551 |
|
552 |
-
public function GetLicenseKey($name)
|
553 |
-
|
554 |
-
$data
|
555 |
-
return isset($data['key']) ? $data['key'] : '';
|
556 |
}
|
557 |
|
558 |
-
public function GetLicenseStatus($name){
|
559 |
-
$data = $this->GetLicense($name);
|
560 |
-
return isset($data['sts']) ? $data['sts'] : '';
|
561 |
}
|
562 |
|
563 |
-
public function GetLicenseErrors($name)
|
564 |
-
|
565 |
-
$data
|
566 |
-
return isset($data['err']) ? $data['err'] : '';
|
567 |
}
|
568 |
|
569 |
-
public function SetLicenseKey($name, $key)
|
570 |
-
{
|
571 |
$data = $this->GetLicenses();
|
572 |
-
if (!isset($data[$name])) {
|
573 |
-
$data[$name] = array();
|
574 |
}
|
575 |
-
$data[$name]['key'] = $key;
|
576 |
-
$this->SetLicenses($data);
|
577 |
}
|
578 |
|
579 |
-
public function SetLicenseStatus($name, $status)
|
580 |
-
{
|
581 |
$data = $this->GetLicenses();
|
582 |
-
if (!isset($data[$name])) {
|
583 |
-
$data[$name] = array();
|
584 |
}
|
585 |
-
$data[$name]['sts'] = $status;
|
586 |
-
$this->SetLicenses($data);
|
587 |
}
|
588 |
|
589 |
-
public function SetLicenseErrors($name, $errors)
|
590 |
-
{
|
591 |
$data = $this->GetLicenses();
|
592 |
-
if (!isset($data[$name])) {
|
593 |
-
$data[$name] = array();
|
594 |
}
|
595 |
-
$data[$name]['err'] = $errors;
|
596 |
-
$this->SetLicenses($data);
|
597 |
}
|
598 |
|
599 |
-
public function ClearLicenses()
|
600 |
-
|
601 |
-
$this->SetLicenses(array());
|
602 |
}
|
603 |
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
public function IsMainIPFromProxy()
|
608 |
-
{
|
609 |
-
return $this->_plugin->GetGlobalOption('use-proxy-ip');
|
610 |
}
|
611 |
|
612 |
-
public function SetMainIPFromProxy($enabled)
|
613 |
-
|
614 |
-
return $this->_plugin->SetGlobalOption('use-proxy-ip', $enabled);
|
615 |
}
|
616 |
|
617 |
-
public function IsInternalIPsFiltered()
|
618 |
-
|
619 |
-
return $this->_plugin->GetGlobalOption('filter-internal-ip');
|
620 |
}
|
621 |
|
622 |
-
public function SetInternalIPsFiltering($enabled)
|
623 |
-
|
624 |
-
return $this->_plugin->SetGlobalOption('filter-internal-ip', $enabled);
|
625 |
}
|
626 |
|
627 |
-
public function GetMainClientIP()
|
628 |
-
{
|
629 |
$result = null;
|
630 |
-
if ($this->IsMainIPFromProxy()) {
|
631 |
-
// TODO
|
632 |
$result = $this->GetClientIPs();
|
633 |
-
$result = reset($result);
|
634 |
-
$result = isset($result[0]) ? $result[0] : null;
|
635 |
-
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
636 |
-
$result = $this->NormalizeIP($_SERVER['REMOTE_ADDR']);
|
637 |
-
if (
|
638 |
-
$result =
|
639 |
}
|
640 |
}
|
641 |
return $result;
|
642 |
}
|
643 |
|
644 |
-
public function GetClientIPs()
|
645 |
-
{
|
646 |
$ips = array();
|
647 |
-
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) {
|
648 |
-
if (isset($_SERVER[$key])) {
|
649 |
-
$ips[$key] = array();
|
650 |
-
foreach (explode(',', $_SERVER[$key]) as $ip) {
|
651 |
-
if ($this->ValidateIP($ip = $this->NormalizeIP($ip))) {
|
652 |
-
$ips[$key][] = $ip;
|
653 |
}
|
654 |
}
|
655 |
}
|
@@ -657,59 +694,54 @@ class WSAL_Settings
|
|
657 |
return $ips;
|
658 |
}
|
659 |
|
660 |
-
protected function NormalizeIP($ip)
|
661 |
-
|
662 |
-
$ip
|
663 |
-
|
664 |
-
|
665 |
-
$ip = explode(':', $ip);
|
666 |
$ip = $ip[0];
|
667 |
} else {
|
668 |
-
// IPv6 with a port (eg: [::1]:80)
|
669 |
-
$ip = explode(']', $ip);
|
670 |
-
$ip = ltrim($ip[0], '[');
|
671 |
}
|
672 |
return $ip;
|
673 |
}
|
674 |
|
675 |
-
protected function ValidateIP($ip)
|
676 |
-
{
|
677 |
$opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
|
678 |
-
if ($this->IsInternalIPsFiltered()) {
|
679 |
$opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
680 |
}
|
681 |
-
$
|
682 |
-
if (
|
683 |
-
//Regex IPV4
|
684 |
-
if (preg_match(
|
685 |
return $ip;
|
686 |
-
}
|
687 |
-
|
688 |
-
elseif (preg_match("/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/", $ip)) {
|
689 |
return $ip;
|
690 |
}
|
691 |
-
if (
|
692 |
-
error_log(
|
693 |
}
|
694 |
return false;
|
695 |
} else {
|
696 |
-
return $
|
697 |
}
|
698 |
}
|
699 |
|
700 |
/**
|
701 |
-
* Users excluded from monitoring
|
702 |
*/
|
703 |
-
public function SetExcludedMonitoringUsers($users)
|
704 |
-
{
|
705 |
$this->_excluded_users = $users;
|
706 |
-
$this->_plugin->SetGlobalOption('excluded-users', esc_html(implode(',', $this->_excluded_users)));
|
707 |
}
|
708 |
|
709 |
-
public function GetExcludedMonitoringUsers()
|
710 |
-
|
711 |
-
|
712 |
-
$this->_excluded_users = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-users'))));
|
713 |
}
|
714 |
return $this->_excluded_users;
|
715 |
}
|
@@ -738,53 +770,47 @@ class WSAL_Settings
|
|
738 |
}
|
739 |
|
740 |
/**
|
741 |
-
* Roles excluded from monitoring
|
742 |
*/
|
743 |
-
public function SetExcludedMonitoringRoles($roles)
|
744 |
-
{
|
745 |
$this->_excluded_roles = $roles;
|
746 |
-
$this->_plugin->SetGlobalOption('excluded-roles', esc_html(implode(',', $this->_excluded_roles)));
|
747 |
}
|
748 |
|
749 |
-
public function GetExcludedMonitoringRoles()
|
750 |
-
|
751 |
-
|
752 |
-
$this->_excluded_roles = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-roles'))));
|
753 |
}
|
754 |
return $this->_excluded_roles;
|
755 |
}
|
756 |
|
757 |
/**
|
758 |
-
* Custom fields excluded from monitoring
|
759 |
*/
|
760 |
-
public function SetExcludedMonitoringCustom($custom)
|
761 |
-
{
|
762 |
$this->_excluded_custom = $custom;
|
763 |
-
$this->_plugin->SetGlobalOption('excluded-custom', esc_html(implode(',', $this->_excluded_custom)));
|
764 |
}
|
765 |
|
766 |
-
public function GetExcludedMonitoringCustom()
|
767 |
-
|
768 |
-
|
769 |
-
$this->_excluded_custom
|
770 |
-
asort($this->_excluded_custom);
|
771 |
}
|
772 |
return $this->_excluded_custom;
|
773 |
}
|
774 |
|
775 |
/**
|
776 |
-
* IP excluded from monitoring
|
777 |
*/
|
778 |
-
public function SetExcludedMonitoringIP($ip)
|
779 |
-
{
|
780 |
$this->_excluded_ip = $ip;
|
781 |
-
$this->_plugin->SetGlobalOption('excluded-ip', esc_html(implode(',', $this->_excluded_ip)));
|
782 |
}
|
783 |
|
784 |
-
public function GetExcludedMonitoringIP()
|
785 |
-
|
786 |
-
|
787 |
-
$this->_excluded_ip = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-ip'))));
|
788 |
}
|
789 |
return $this->_excluded_ip;
|
790 |
}
|
@@ -792,16 +818,15 @@ class WSAL_Settings
|
|
792 |
/**
|
793 |
* Datetime used in the Alerts.
|
794 |
*/
|
795 |
-
public function GetDatetimeFormat($
|
796 |
-
|
797 |
-
if ($lineBreak) {
|
798 |
$date_time_format = $this->GetDateFormat() . '<\b\r>' . $this->GetTimeFormat();
|
799 |
} else {
|
800 |
$date_time_format = $this->GetDateFormat() . ' ' . $this->GetTimeFormat();
|
801 |
}
|
802 |
|
803 |
-
$wp_time_format = get_option('time_format');
|
804 |
-
if (stripos($wp_time_format, 'A') !== false) {
|
805 |
$date_time_format .= '.$$$&\n\b\s\p;A';
|
806 |
} else {
|
807 |
$date_time_format .= '.$$$';
|
@@ -812,43 +837,40 @@ class WSAL_Settings
|
|
812 |
/**
|
813 |
* Date Format from WordPress General Settings.
|
814 |
*/
|
815 |
-
public function GetDateFormat()
|
816 |
-
|
817 |
-
$
|
818 |
-
$
|
819 |
-
$
|
820 |
-
$date_format = str_replace($search, $replace, $wp_date_format);
|
821 |
return $date_format;
|
822 |
}
|
823 |
|
824 |
/**
|
825 |
* Time Format from WordPress General Settings.
|
826 |
*/
|
827 |
-
public function GetTimeFormat()
|
828 |
-
|
829 |
-
$
|
830 |
-
$
|
831 |
-
$
|
832 |
-
$time_format = str_replace($search, $replace, $wp_time_format);
|
833 |
return $time_format;
|
834 |
}
|
835 |
|
836 |
/**
|
837 |
-
* Alerts Timestamp
|
838 |
-
*
|
|
|
839 |
*/
|
840 |
-
public function GetTimezone()
|
841 |
-
|
842 |
-
return $this->_plugin->GetGlobalOption('timezone', 0);
|
843 |
}
|
844 |
|
845 |
-
public function SetTimezone($newvalue)
|
846 |
-
|
847 |
-
return $this->_plugin->SetGlobalOption('timezone', $newvalue);
|
848 |
}
|
849 |
|
850 |
/**
|
851 |
-
* Get type of username to display
|
852 |
*/
|
853 |
public function get_type_username() {
|
854 |
return $this->_plugin->GetGlobalOption( 'type_username', 'display_name' );
|
@@ -864,84 +886,89 @@ class WSAL_Settings
|
|
864 |
return $this->_plugin->SetGlobalOption( 'type_username', $newvalue );
|
865 |
}
|
866 |
|
867 |
-
public function GetAdapterConfig($name_field)
|
868 |
-
|
869 |
-
return $this->_plugin->GetGlobalOption($name_field);
|
870 |
}
|
871 |
|
872 |
-
public function SetAdapterConfig($name_field, $newvalue)
|
873 |
-
|
874 |
-
return $this->_plugin->SetGlobalOption($name_field, trim($newvalue));
|
875 |
}
|
876 |
|
877 |
-
public function GetColumns()
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
882 |
}
|
883 |
$selected = $this->GetColumnsSelected();
|
884 |
-
if (!empty($selected)) {
|
885 |
-
$columns = array(
|
886 |
-
|
887 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
888 |
}
|
889 |
-
$selected = (array)json_decode($selected);
|
890 |
-
$columns = array_merge($columns, $selected);
|
891 |
return $columns;
|
892 |
} else {
|
893 |
return $columns;
|
894 |
}
|
895 |
}
|
896 |
|
897 |
-
public function GetColumnsSelected()
|
898 |
-
|
899 |
-
return $this->_plugin->GetGlobalOption('columns');
|
900 |
}
|
901 |
|
902 |
-
public function SetColumns($columns)
|
903 |
-
|
904 |
-
return $this->_plugin->SetGlobalOption('columns', json_encode($columns));
|
905 |
}
|
906 |
|
907 |
-
public function IsWPBackend()
|
908 |
-
|
909 |
-
return $this->_plugin->GetGlobalOption('wp-backend');
|
910 |
}
|
911 |
|
912 |
-
public function SetWPBackend($enabled)
|
913 |
-
|
914 |
-
return $this->_plugin->SetGlobalOption('wp-backend', $enabled);
|
915 |
}
|
916 |
|
917 |
-
public function SetFromEmail($email_address)
|
918 |
-
|
919 |
-
return $this->_plugin->SetGlobalOption('from-email', trim($email_address));
|
920 |
}
|
921 |
|
922 |
-
public function GetFromEmail()
|
923 |
-
|
924 |
-
return $this->_plugin->GetGlobalOption('from-email');
|
925 |
}
|
926 |
|
927 |
-
public function SetDisplayName($display_name)
|
928 |
-
|
929 |
-
return $this->_plugin->SetGlobalOption('display-name', trim($display_name));
|
930 |
}
|
931 |
|
932 |
-
public function GetDisplayName()
|
933 |
-
|
934 |
-
return $this->_plugin->GetGlobalOption('display-name');
|
935 |
}
|
936 |
|
937 |
-
public function Set404LogLimit($value)
|
938 |
-
|
939 |
-
return $this->_plugin->SetGlobalOption('log-404-limit', abs($value));
|
940 |
}
|
941 |
|
942 |
-
public function Get404LogLimit()
|
943 |
-
|
944 |
-
return $this->_plugin->GetGlobalOption('log-404-limit', 99);
|
945 |
}
|
946 |
|
947 |
/**
|
@@ -1009,28 +1036,23 @@ class WSAL_Settings
|
|
1009 |
return $this->_plugin->GetGlobalOption( 'log-visitor-failed-login-limit', 10 );
|
1010 |
}
|
1011 |
|
1012 |
-
|
1013 |
-
|
1014 |
-
public function IsArchivingEnabled()
|
1015 |
-
{
|
1016 |
-
return $this->_plugin->GetGlobalOption('archiving-e');
|
1017 |
}
|
1018 |
|
1019 |
/**
|
1020 |
-
* Switch to Archive DB if is enabled
|
1021 |
*/
|
1022 |
-
public function SwitchToArchiveDB()
|
1023 |
-
|
1024 |
-
|
1025 |
-
$
|
1026 |
-
$
|
1027 |
-
$
|
1028 |
-
$
|
1029 |
-
$
|
1030 |
-
$
|
1031 |
-
$
|
1032 |
-
$this->_plugin->getConnector($config)->getAdapter('Occurrence');
|
1033 |
}
|
1034 |
}
|
1035 |
-
// </editor-fold>
|
1036 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* Class: WSAL Settings.
|
4 |
+
*
|
5 |
+
* WSAL settings class.
|
6 |
*
|
7 |
+
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
* This class is the actual controller of the Settings Page.
|
17 |
+
*
|
18 |
+
* @package Wsal
|
19 |
*/
|
20 |
+
class WSAL_Settings {
|
21 |
+
|
22 |
/**
|
23 |
+
* Instance of the main plugin.
|
24 |
+
*
|
25 |
* @var WpSecurityAuditLog
|
26 |
*/
|
27 |
protected $_plugin;
|
28 |
|
|
|
29 |
const OPT_DEV_DATA_INSPECTOR = 'd';
|
30 |
const OPT_DEV_PHP_ERRORS = 'p';
|
31 |
const OPT_DEV_REQUEST_LOG = 'r';
|
33 |
|
34 |
const ERROR_CODE_INVALID_IP = 901;
|
35 |
|
36 |
+
/**
|
37 |
+
* Dev Options.
|
38 |
+
*
|
39 |
+
* @var array
|
40 |
+
*/
|
41 |
protected $_devoption = null;
|
42 |
|
43 |
+
/**
|
44 |
+
* Pruning Date.
|
45 |
+
*
|
46 |
+
* @var string
|
47 |
+
*/
|
48 |
protected $_pruning = 0;
|
49 |
|
50 |
+
/**
|
51 |
+
* IDs of disabled alerts.
|
52 |
+
*
|
53 |
+
* @var array
|
54 |
+
*/
|
55 |
protected $_disabled = null;
|
56 |
|
57 |
+
/**
|
58 |
+
* Allowed Plugin Viewers.
|
59 |
+
*
|
60 |
+
* @var array
|
61 |
+
*/
|
62 |
protected $_viewers = null;
|
63 |
|
64 |
+
/**
|
65 |
+
* Allowed Plugin Editors.
|
66 |
+
*
|
67 |
+
* @var array
|
68 |
+
*/
|
69 |
protected $_editors = null;
|
70 |
|
71 |
+
/**
|
72 |
+
* Alerts per page.
|
73 |
+
*
|
74 |
+
* @var int
|
75 |
+
*/
|
76 |
protected $_perpage = null;
|
77 |
|
78 |
/**
|
79 |
+
* Users excluded from monitoring.
|
80 |
+
*
|
81 |
+
* @var array
|
82 |
*/
|
83 |
protected $_excluded_users = array();
|
84 |
|
85 |
/**
|
86 |
+
* Roles excluded from monitoring.
|
87 |
+
*
|
88 |
+
* @var array
|
89 |
*/
|
90 |
+
protected $_excluded_roles = array();
|
91 |
|
92 |
/**
|
93 |
+
* Custom fields excluded from monitoring.
|
94 |
+
*
|
95 |
+
* @var array
|
96 |
*/
|
97 |
protected $_excluded_custom = array();
|
98 |
|
104 |
protected $_post_types = array();
|
105 |
|
106 |
/**
|
107 |
+
* IP excluded from monitoring.
|
108 |
+
*
|
109 |
+
* @var array
|
110 |
*/
|
111 |
protected $_excluded_ip = array();
|
112 |
|
113 |
+
/**
|
114 |
+
* Method: Constructor.
|
115 |
+
*
|
116 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
117 |
+
*/
|
118 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
119 |
$this->_plugin = $plugin;
|
120 |
}
|
121 |
|
122 |
/**
|
123 |
+
* Return array of developer options to be enabled by default.
|
124 |
+
*
|
125 |
+
* @return array
|
126 |
*/
|
127 |
+
public function GetDefaultDevOptions() {
|
|
|
128 |
return array();
|
129 |
}
|
130 |
|
131 |
/**
|
132 |
* Returns whether a developer option is enabled or not.
|
133 |
+
*
|
134 |
+
* @param string $option - See self::OPT_DEV_* constants.
|
135 |
+
* @return boolean - If option is enabled or not.
|
136 |
*/
|
137 |
+
public function IsDevOptionEnabled( $option ) {
|
138 |
+
if ( is_null( $this->_devoption ) ) {
|
|
|
139 |
$this->_devoption = $this->_plugin->GetGlobalOption(
|
140 |
'dev-options',
|
141 |
+
implode( ',', $this->GetDefaultDevOptions() )
|
142 |
);
|
143 |
+
$this->_devoption = explode( ',', $this->_devoption );
|
144 |
}
|
145 |
+
return in_array( $option, $this->_devoption );
|
146 |
}
|
147 |
|
148 |
/**
|
149 |
+
* Check whether any developer option has been enabled or not.
|
150 |
+
*
|
151 |
+
* @return boolean
|
152 |
*/
|
153 |
+
public function IsAnyDevOptionEnabled() {
|
154 |
+
return ! ! $this->_plugin->GetGlobalOption( 'dev-options', null );
|
|
|
155 |
}
|
156 |
|
157 |
/**
|
158 |
* Sets whether a developer option is enabled or not.
|
159 |
+
*
|
160 |
+
* @param string $option - See self::OPT_DEV_* constants.
|
161 |
+
* @param boolean $enabled - If option should be enabled or not.
|
162 |
*/
|
163 |
+
public function SetDevOptionEnabled( $option, $enabled ) {
|
164 |
+
// Make sure options have been loaded.
|
165 |
+
$this->IsDevOptionEnabled( '' );
|
166 |
+
// Remove option if it exists.
|
167 |
+
while ( ($p = array_search( $option, $this->_devoption )) !== false ) {
|
168 |
+
unset( $this->_devoption[ $p ] );
|
|
|
169 |
}
|
170 |
+
// Add option if callee wants it enabled.
|
171 |
+
if ( $enabled ) {
|
172 |
$this->_devoption[] = $option;
|
173 |
}
|
174 |
+
// Commit option.
|
175 |
$this->_plugin->SetGlobalOption(
|
176 |
'dev-options',
|
177 |
+
implode( ',', $this->_devoption )
|
178 |
);
|
179 |
}
|
180 |
|
181 |
/**
|
182 |
* Remove all enabled developer options.
|
183 |
*/
|
184 |
+
public function ClearDevOptions() {
|
|
|
185 |
$this->_devoption = array();
|
186 |
+
$this->_plugin->SetGlobalOption( 'dev-options', '' );
|
187 |
}
|
188 |
|
189 |
/**
|
190 |
+
* Check whether to enable data inspector or not.
|
191 |
+
*
|
192 |
+
* @return boolean
|
193 |
*/
|
194 |
+
public function IsDataInspectorEnabled() {
|
195 |
+
return $this->IsDevOptionEnabled( self::OPT_DEV_DATA_INSPECTOR );
|
|
|
196 |
}
|
197 |
|
198 |
/**
|
199 |
+
* Check whether to enable PHP error logging or not.
|
200 |
+
*
|
201 |
+
* @return boolean
|
202 |
*/
|
203 |
+
public function IsPhpErrorLoggingEnabled() {
|
204 |
+
return $this->IsDevOptionEnabled( self::OPT_DEV_PHP_ERRORS );
|
|
|
205 |
}
|
206 |
|
207 |
/**
|
208 |
+
* Check whether to log requests to file or not.
|
209 |
+
*
|
210 |
+
* @return boolean
|
211 |
*/
|
212 |
+
public function IsRequestLoggingEnabled() {
|
213 |
+
return $this->IsDevOptionEnabled( self::OPT_DEV_REQUEST_LOG );
|
|
|
214 |
}
|
215 |
|
216 |
/**
|
217 |
+
* Check whether to store debug backtrace for PHP alerts or not.
|
218 |
+
*
|
219 |
+
* @return boolean
|
220 |
*/
|
221 |
+
public function IsBacktraceLoggingEnabled() {
|
222 |
+
return $this->IsDevOptionEnabled( self::OPT_DEV_BACKTRACE_LOG );
|
|
|
223 |
}
|
224 |
|
|
|
|
|
225 |
/**
|
226 |
+
* Check whether dashboard widgets are enabled or not.
|
227 |
+
*
|
228 |
+
* @return boolean
|
229 |
*/
|
230 |
+
public function IsWidgetsEnabled() {
|
231 |
+
return ! $this->_plugin->GetGlobalOption( 'disable-widgets' );
|
|
|
232 |
}
|
233 |
|
234 |
/**
|
235 |
+
* Check whether dashboard widgets are enabled or not.
|
236 |
+
*
|
237 |
+
* @param boolean $newvalue - True if enabled.
|
238 |
*/
|
239 |
+
public function SetWidgetsEnabled( $newvalue ) {
|
240 |
+
$this->_plugin->SetGlobalOption( 'disable-widgets', ! $newvalue );
|
|
|
241 |
}
|
242 |
|
243 |
/**
|
244 |
+
* Check whether alerts in audit log view refresh automatically or not.
|
245 |
+
*
|
246 |
+
* @return boolean
|
247 |
*/
|
248 |
+
public function IsRefreshAlertsEnabled() {
|
249 |
+
return ! $this->_plugin->GetGlobalOption( 'disable-refresh' );
|
|
|
250 |
}
|
251 |
|
252 |
/**
|
253 |
+
* Check whether alerts in audit log view refresh automatically or not.
|
254 |
+
*
|
255 |
+
* @param boolean $newvalue - True if enabled.
|
256 |
*/
|
257 |
+
public function SetRefreshAlertsEnabled( $newvalue ) {
|
258 |
+
$this->_plugin->SetGlobalOption( 'disable-refresh', ! $newvalue );
|
|
|
259 |
}
|
260 |
|
261 |
/**
|
262 |
+
* Maximum number of alerts to show in dashboard widget.
|
263 |
+
*
|
264 |
+
* @return int
|
265 |
*/
|
266 |
+
public function GetDashboardWidgetMaxAlerts() {
|
|
|
267 |
return 5;
|
268 |
}
|
269 |
|
|
|
270 |
/**
|
271 |
+
* The maximum number of alerts allowable.
|
272 |
+
*
|
273 |
+
* @return int
|
274 |
*/
|
275 |
+
public function GetMaxAllowedAlerts() {
|
|
|
276 |
return 5000;
|
277 |
}
|
278 |
|
279 |
/**
|
280 |
+
* The default pruning date.
|
281 |
+
*
|
282 |
+
* @return string
|
283 |
*/
|
284 |
+
public function GetDefaultPruningDate() {
|
285 |
+
return '12 months';
|
|
|
286 |
}
|
287 |
|
288 |
/**
|
289 |
+
* The current pruning date.
|
290 |
+
*
|
291 |
+
* @return string
|
292 |
*/
|
293 |
+
public function GetPruningDate() {
|
294 |
+
if ( ! $this->_pruning ) {
|
295 |
+
$this->_pruning = $this->_plugin->GetGlobalOption( 'pruning-date' );
|
296 |
+
if ( ! strtotime( $this->_pruning ) ) {
|
|
|
297 |
$this->_pruning = $this->GetDefaultPruningDate();
|
298 |
}
|
299 |
}
|
301 |
}
|
302 |
|
303 |
/**
|
304 |
+
* Set the new pruning date.
|
305 |
+
*
|
306 |
+
* @param string $newvalue - The new pruning date.
|
307 |
*/
|
308 |
+
public function SetPruningDate( $newvalue ) {
|
309 |
+
if ( strtotime( $newvalue ) ) {
|
310 |
+
$this->_plugin->SetGlobalOption( 'pruning-date', $newvalue );
|
|
|
311 |
$this->_pruning = $newvalue;
|
312 |
}
|
313 |
}
|
314 |
|
315 |
/**
|
316 |
+
* Maximum number of alerts to keep.
|
317 |
+
*
|
318 |
+
* @return integer
|
319 |
*/
|
320 |
+
public function GetPruningLimit() {
|
321 |
+
$val = (int) $this->_plugin->GetGlobalOption( 'pruning-limit' );
|
|
|
322 |
return $val ? $val : $this->GetMaxAllowedAlerts();
|
323 |
}
|
324 |
|
325 |
/**
|
326 |
+
* Set pruning alerts limit.
|
327 |
+
*
|
328 |
+
* @param integer $newvalue - The new maximum number of alerts.
|
329 |
*/
|
330 |
+
public function SetPruningLimit( $newvalue ) {
|
331 |
+
$newvalue = max( /*min(*/ (int) $newvalue/*, $this->GetMaxAllowedAlerts())*/, 1 );
|
332 |
+
$this->_plugin->SetGlobalOption( 'pruning-limit', $newvalue );
|
|
|
333 |
}
|
334 |
|
335 |
+
public function SetPruningDateEnabled( $enabled ) {
|
336 |
+
$this->_plugin->SetGlobalOption( 'pruning-date-e', $enabled );
|
|
|
337 |
}
|
338 |
|
339 |
+
public function SetPruningLimitEnabled( $enabled ) {
|
340 |
+
$this->_plugin->SetGlobalOption( 'pruning-limit-e', $enabled );
|
|
|
341 |
}
|
342 |
|
343 |
+
public function IsPruningDateEnabled() {
|
344 |
+
return $this->_plugin->GetGlobalOption( 'pruning-date-e' );
|
345 |
}
|
346 |
|
347 |
+
public function IsPruningLimitEnabled() {
|
348 |
+
return $this->_plugin->GetGlobalOption( 'pruning-limit-e' );
|
|
|
349 |
}
|
350 |
|
351 |
+
public function IsRestrictAdmins() {
|
352 |
+
return $this->_plugin->GetGlobalOption( 'restrict-admins', false );
|
|
|
353 |
}
|
354 |
|
355 |
/**
|
356 |
+
* Sandbox functionality is now in an external plugin.
|
357 |
+
*
|
358 |
+
* @deprecated
|
359 |
*/
|
360 |
+
public function IsSandboxPageEnabled() {
|
361 |
+
// $plugins = $this->_plugin->licensing->plugins();
|
362 |
+
// return isset($plugins['wsal-sandbox-extensionphp']);
|
363 |
+
return esc_html__( 'This function is deprecated', 'wp-security-audit-log' );
|
364 |
}
|
365 |
|
366 |
+
public function SetRestrictAdmins( $enable ) {
|
367 |
+
$this->_plugin->SetGlobalOption( 'restrict-admins', (bool) $enable );
|
|
|
368 |
}
|
369 |
|
370 |
+
public function GetDefaultDisabledAlerts() {
|
371 |
+
return array( 0000, 0001, 0002, 0003, 0004, 0005 );
|
|
|
|
|
372 |
}
|
373 |
|
374 |
/**
|
375 |
+
* Return IDs of disabled alerts.
|
376 |
+
*
|
377 |
+
* @return array
|
378 |
*/
|
379 |
+
public function GetDisabledAlerts() {
|
380 |
+
if ( ! $this->_disabled ) {
|
381 |
+
$this->_disabled = implode( ',', $this->GetDefaultDisabledAlerts() );
|
382 |
+
$this->_disabled = $this->_plugin->GetGlobalOption( 'disabled-alerts', $this->_disabled );
|
383 |
+
$this->_disabled = ( '' == $this->_disabled ) ? array() : explode( ',', $this->_disabled );
|
384 |
+
$this->_disabled = array_map( 'intval', $this->_disabled );
|
|
|
385 |
}
|
386 |
return $this->_disabled;
|
387 |
}
|
388 |
|
389 |
/**
|
390 |
+
* Method: Set Disabled Alerts.
|
391 |
+
*
|
392 |
* @param array $types IDs alerts to disable.
|
393 |
*/
|
394 |
+
public function SetDisabledAlerts( $types ) {
|
395 |
+
$this->_disabled = array_unique( array_map( 'intval', $types ) );
|
396 |
+
$this->_plugin->SetGlobalOption( 'disabled-alerts', implode( ',', $this->_disabled ) );
|
|
|
397 |
}
|
398 |
|
399 |
+
public function IsIncognito() {
|
400 |
+
return $this->_plugin->GetGlobalOption( 'hide-plugin' );
|
|
|
401 |
}
|
402 |
|
403 |
+
public function SetIncognito( $enabled ) {
|
404 |
+
return $this->_plugin->SetGlobalOption( 'hide-plugin', $enabled );
|
|
|
405 |
}
|
406 |
|
407 |
/**
|
408 |
* Checking if Logging is enabled.
|
409 |
*/
|
410 |
+
public function IsLoggingDisabled() {
|
411 |
+
return $this->_plugin->GetGlobalOption( 'disable-logging' );
|
|
|
412 |
}
|
413 |
|
414 |
+
public function SetLoggingDisabled( $disabled ) {
|
415 |
+
return $this->_plugin->SetGlobalOption( 'disable-logging', $disabled );
|
|
|
416 |
}
|
417 |
|
418 |
/**
|
419 |
* Checking if the data will be removed.
|
420 |
*/
|
421 |
+
public function IsDeleteData() {
|
422 |
+
return $this->_plugin->GetGlobalOption( 'delete-data' );
|
|
|
423 |
}
|
424 |
|
425 |
+
public function SetDeleteData( $enabled ) {
|
426 |
+
return $this->_plugin->SetGlobalOption( 'delete-data', $enabled );
|
|
|
427 |
}
|
428 |
|
429 |
+
public function SetAllowedPluginViewers( $users_or_roles ) {
|
430 |
+
$this->_viewers = $users_or_roles;
|
431 |
+
$this->_plugin->SetGlobalOption( 'plugin-viewers', implode( ',', $this->_viewers ) );
|
|
|
|
|
|
|
432 |
}
|
433 |
|
434 |
+
public function GetAllowedPluginViewers() {
|
435 |
+
if ( is_null( $this->_viewers ) ) {
|
436 |
+
$this->_viewers = array_unique( array_filter( explode( ',', $this->_plugin->GetGlobalOption( 'plugin-viewers' ) ) ) );
|
|
|
437 |
}
|
438 |
return $this->_viewers;
|
439 |
}
|
440 |
|
441 |
+
public function SetAllowedPluginEditors( $users_or_roles ) {
|
442 |
+
$this->_editors = $users_or_roles;
|
443 |
+
$this->_plugin->SetGlobalOption( 'plugin-editors', implode( ',', $this->_editors ) );
|
|
|
444 |
}
|
445 |
|
446 |
+
public function GetAllowedPluginEditors() {
|
447 |
+
if ( is_null( $this->_editors ) ) {
|
448 |
+
$this->_editors = array_unique( array_filter( explode( ',', $this->_plugin->GetGlobalOption( 'plugin-editors' ) ) ) );
|
|
|
449 |
}
|
450 |
return $this->_editors;
|
451 |
}
|
452 |
|
453 |
+
public function SetViewPerPage( $newvalue ) {
|
454 |
+
$this->_perpage = max( $newvalue, 1 );
|
455 |
+
$this->_plugin->SetGlobalOption( 'items-per-page', $this->_perpage );
|
|
|
456 |
}
|
457 |
|
458 |
+
public function GetViewPerPage() {
|
459 |
+
if ( is_null( $this->_perpage ) ) {
|
460 |
+
$this->_perpage = (int) $this->_plugin->GetGlobalOption( 'items-per-page', 10 );
|
|
|
461 |
}
|
462 |
return $this->_perpage;
|
463 |
}
|
464 |
|
465 |
/**
|
466 |
+
* Check if current user can perform an action.
|
467 |
+
*
|
468 |
* @param string $action Type of action, either 'view' or 'edit'.
|
469 |
* @return boolean If user has access or not.
|
470 |
*/
|
471 |
+
public function CurrentUserCan( $action ) {
|
472 |
+
return $this->UserCan( wp_get_current_user(), $action );
|
|
|
473 |
}
|
474 |
|
475 |
/**
|
476 |
+
* Get list of superadmin usernames.
|
477 |
+
*
|
478 |
+
* @return array
|
479 |
*/
|
480 |
+
protected function GetSuperAdmins() {
|
|
|
481 |
return $this->_plugin->IsMultisite() ? get_super_admins() : array();
|
482 |
}
|
483 |
|
484 |
/**
|
485 |
+
* List of admin usernames.
|
486 |
+
*
|
487 |
+
* @return string[]
|
488 |
*/
|
489 |
+
protected function GetAdmins() {
|
490 |
+
if ( $this->_plugin->IsMultisite() ) {
|
491 |
+
/**
|
492 |
+
* Get list of admins.
|
493 |
+
*
|
494 |
+
* @see https://gist.github.com/1508426/65785a15b8638d43a9905effb59e4d97319ef8f8
|
495 |
+
*/
|
496 |
global $wpdb;
|
497 |
+
$cap = $wpdb->prefix . 'capabilities';
|
498 |
$sql = "SELECT DISTINCT $wpdb->users.user_login"
|
499 |
. " FROM $wpdb->users"
|
500 |
. " INNER JOIN $wpdb->usermeta ON ($wpdb->users.ID = $wpdb->usermeta.user_id )"
|
501 |
. " WHERE $wpdb->usermeta.meta_key = '$cap'"
|
502 |
. " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
|
503 |
+
return $wpdb->get_col( $sql );
|
504 |
} else {
|
505 |
$result = array();
|
506 |
$query = 'role=administrator&fields[]=user_login';
|
507 |
+
foreach ( get_users( $query ) as $user ) {
|
508 |
$result[] = $user->user_login;
|
509 |
}
|
510 |
return $result;
|
513 |
|
514 |
/**
|
515 |
* Returns access tokens for a particular action.
|
516 |
+
*
|
517 |
+
* @param string $action - Type of action.
|
518 |
* @return string[] List of tokens (usernames, roles etc).
|
519 |
*/
|
520 |
+
public function GetAccessTokens( $action ) {
|
|
|
521 |
$allowed = array();
|
522 |
+
switch ( $action ) {
|
523 |
case 'view':
|
524 |
$allowed = $this->GetAllowedPluginViewers();
|
525 |
+
$allowed = array_merge( $allowed, $this->GetAllowedPluginEditors() );
|
526 |
+
if ( ! $this->IsRestrictAdmins() ) {
|
527 |
+
$allowed = array_merge( $allowed, $this->GetSuperAdmins() );
|
528 |
+
$allowed = array_merge( $allowed, $this->GetAdmins() );
|
529 |
}
|
530 |
break;
|
531 |
case 'edit':
|
532 |
$allowed = $this->GetAllowedPluginEditors();
|
533 |
+
if ( ! $this->IsRestrictAdmins() ) {
|
534 |
+
$allowed = array_merge( $allowed, $this->_plugin->IsMultisite() ? $this->GetSuperAdmins() : $this->GetAdmins() );
|
535 |
}
|
536 |
break;
|
537 |
default:
|
538 |
+
throw new Exception( 'Unknown action "' . $action . '".' );
|
539 |
}
|
540 |
+
if ( ! $this->IsRestrictAdmins() ) {
|
541 |
+
if ( is_multisite() ) {
|
542 |
+
$allowed = array_merge( $allowed, get_super_admins() );
|
543 |
} else {
|
544 |
$allowed[] = 'administrator';
|
545 |
}
|
546 |
}
|
547 |
+
return array_unique( $allowed );
|
548 |
}
|
549 |
|
550 |
/**
|
551 |
+
* Check if user can perform an action.
|
552 |
+
*
|
553 |
+
* @param integer|WP_user $user - User object to check.
|
554 |
+
* @param string $action - Type of action, either 'view' or 'edit'.
|
555 |
* @return boolean If user has access or not.
|
556 |
*/
|
557 |
+
public function UserCan( $user, $action ) {
|
558 |
+
if ( is_int( $user ) ) {
|
559 |
+
$user = get_userdata( $user );
|
|
|
560 |
}
|
561 |
+
$allowed = $this->GetAccessTokens( $action );
|
562 |
+
$check = array_merge( $user->roles, array( $user->user_login ) );
|
563 |
+
foreach ( $check as $item ) {
|
564 |
+
if ( in_array( $item, $allowed ) ) {
|
565 |
return true;
|
566 |
}
|
567 |
}
|
568 |
return false;
|
569 |
}
|
570 |
|
571 |
+
public function GetCurrentUserRoles( $base_roles = null ) {
|
572 |
+
if ( null == $base_roles ) {
|
573 |
+
$base_roles = wp_get_current_user()->roles;
|
|
|
574 |
}
|
575 |
+
if ( function_exists( 'is_super_admin' ) && is_super_admin() ) {
|
576 |
+
$base_roles[] = 'superadmin';
|
577 |
}
|
578 |
+
return $base_roles;
|
579 |
}
|
580 |
|
581 |
+
public function IsLoginSuperAdmin( $username ) {
|
582 |
+
$user_id = username_exists( $username );
|
583 |
+
if ( function_exists( 'is_super_admin' ) && is_super_admin( $user_id ) ) {
|
|
|
584 |
return true;
|
585 |
} else {
|
586 |
return false;
|
587 |
}
|
588 |
}
|
589 |
|
590 |
+
public function GetLicenses() {
|
591 |
+
return $this->_plugin->GetGlobalOption( 'licenses' );
|
|
|
|
|
|
|
|
|
592 |
}
|
593 |
|
594 |
+
public function GetLicense( $name ) {
|
|
|
595 |
$data = $this->GetLicenses();
|
596 |
+
$name = sanitize_key( basename( $name ) );
|
597 |
+
return isset( $data[ $name ] ) ? $data[ $name ] : array();
|
598 |
}
|
599 |
|
600 |
+
public function SetLicenses( $data ) {
|
601 |
+
$this->_plugin->SetGlobalOption( 'licenses', $data );
|
|
|
602 |
}
|
603 |
|
604 |
+
public function GetLicenseKey( $name ) {
|
605 |
+
$data = $this->GetLicense( $name );
|
606 |
+
return isset( $data['key'] ) ? $data['key'] : '';
|
|
|
607 |
}
|
608 |
|
609 |
+
public function GetLicenseStatus( $name ) {
|
610 |
+
$data = $this->GetLicense( $name );
|
611 |
+
return isset( $data['sts'] ) ? $data['sts'] : '';
|
612 |
}
|
613 |
|
614 |
+
public function GetLicenseErrors( $name ) {
|
615 |
+
$data = $this->GetLicense( $name );
|
616 |
+
return isset( $data['err'] ) ? $data['err'] : '';
|
|
|
617 |
}
|
618 |
|
619 |
+
public function SetLicenseKey( $name, $key ) {
|
|
|
620 |
$data = $this->GetLicenses();
|
621 |
+
if ( ! isset( $data[ $name ] ) ) {
|
622 |
+
$data[ $name ] = array();
|
623 |
}
|
624 |
+
$data[ $name ]['key'] = $key;
|
625 |
+
$this->SetLicenses( $data );
|
626 |
}
|
627 |
|
628 |
+
public function SetLicenseStatus( $name, $status ) {
|
|
|
629 |
$data = $this->GetLicenses();
|
630 |
+
if ( ! isset( $data[ $name ] ) ) {
|
631 |
+
$data[ $name ] = array();
|
632 |
}
|
633 |
+
$data[ $name ]['sts'] = $status;
|
634 |
+
$this->SetLicenses( $data );
|
635 |
}
|
636 |
|
637 |
+
public function SetLicenseErrors( $name, $errors ) {
|
|
|
638 |
$data = $this->GetLicenses();
|
639 |
+
if ( ! isset( $data[ $name ] ) ) {
|
640 |
+
$data[ $name ] = array();
|
641 |
}
|
642 |
+
$data[ $name ]['err'] = $errors;
|
643 |
+
$this->SetLicenses( $data );
|
644 |
}
|
645 |
|
646 |
+
public function ClearLicenses() {
|
647 |
+
$this->SetLicenses( array() );
|
|
|
648 |
}
|
649 |
|
650 |
+
public function IsMainIPFromProxy() {
|
651 |
+
return $this->_plugin->GetGlobalOption( 'use-proxy-ip' );
|
|
|
|
|
|
|
|
|
652 |
}
|
653 |
|
654 |
+
public function SetMainIPFromProxy( $enabled ) {
|
655 |
+
return $this->_plugin->SetGlobalOption( 'use-proxy-ip', $enabled );
|
|
|
656 |
}
|
657 |
|
658 |
+
public function IsInternalIPsFiltered() {
|
659 |
+
return $this->_plugin->GetGlobalOption( 'filter-internal-ip' );
|
|
|
660 |
}
|
661 |
|
662 |
+
public function SetInternalIPsFiltering( $enabled ) {
|
663 |
+
return $this->_plugin->SetGlobalOption( 'filter-internal-ip', $enabled );
|
|
|
664 |
}
|
665 |
|
666 |
+
public function GetMainClientIP() {
|
|
|
667 |
$result = null;
|
668 |
+
if ( $this->IsMainIPFromProxy() ) {
|
669 |
+
// TODO: The algorithm below just gets the first IP in the list...we might want to make this more intelligent somehow.
|
670 |
$result = $this->GetClientIPs();
|
671 |
+
$result = reset( $result );
|
672 |
+
$result = isset( $result[0] ) ? $result[0] : null;
|
673 |
+
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
|
674 |
+
$result = $this->NormalizeIP( $_SERVER['REMOTE_ADDR'] );
|
675 |
+
if ( ! $this->ValidateIP( $result ) ) {
|
676 |
+
$result = 'Error ' . self::ERROR_CODE_INVALID_IP . ': Invalid IP Address';
|
677 |
}
|
678 |
}
|
679 |
return $result;
|
680 |
}
|
681 |
|
682 |
+
public function GetClientIPs() {
|
|
|
683 |
$ips = array();
|
684 |
+
foreach ( array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR' ) as $key ) {
|
685 |
+
if ( isset( $_SERVER[ $key ] ) ) {
|
686 |
+
$ips[ $key ] = array();
|
687 |
+
foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) {
|
688 |
+
if ( $this->ValidateIP( $ip = $this->NormalizeIP( $ip ) ) ) {
|
689 |
+
$ips[ $key ][] = $ip;
|
690 |
}
|
691 |
}
|
692 |
}
|
694 |
return $ips;
|
695 |
}
|
696 |
|
697 |
+
protected function NormalizeIP( $ip ) {
|
698 |
+
$ip = trim( $ip );
|
699 |
+
if ( strpos( $ip, ':' ) !== false && substr_count( $ip, '.' ) == 3 && strpos( $ip, '[' ) === false ) {
|
700 |
+
// IPv4 with a port (eg: 11.22.33.44:80).
|
701 |
+
$ip = explode( ':', $ip );
|
|
|
702 |
$ip = $ip[0];
|
703 |
} else {
|
704 |
+
// IPv6 with a port (eg: [::1]:80).
|
705 |
+
$ip = explode( ']', $ip );
|
706 |
+
$ip = ltrim( $ip[0], '[' );
|
707 |
}
|
708 |
return $ip;
|
709 |
}
|
710 |
|
711 |
+
protected function ValidateIP( $ip ) {
|
|
|
712 |
$opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
|
713 |
+
if ( $this->IsInternalIPsFiltered() ) {
|
714 |
$opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
715 |
}
|
716 |
+
$filtered_ip = filter_var( $ip, FILTER_VALIDATE_IP, $opts );
|
717 |
+
if ( ! $filtered_ip || empty( $filtered_ip ) ) {
|
718 |
+
// Regex IPV4.
|
719 |
+
if ( preg_match( '/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $ip ) ) {
|
720 |
return $ip;
|
721 |
+
} // Regex IPV6.
|
722 |
+
elseif ( preg_match( '/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/', $ip ) ) {
|
|
|
723 |
return $ip;
|
724 |
}
|
725 |
+
if ( ! $this->IsLoggingDisabled ) {
|
726 |
+
error_log( 'Invalid IP in ValidateIP function: ' . $ip );
|
727 |
}
|
728 |
return false;
|
729 |
} else {
|
730 |
+
return $filtered_ip;
|
731 |
}
|
732 |
}
|
733 |
|
734 |
/**
|
735 |
+
* Users excluded from monitoring.
|
736 |
*/
|
737 |
+
public function SetExcludedMonitoringUsers( $users ) {
|
|
|
738 |
$this->_excluded_users = $users;
|
739 |
+
$this->_plugin->SetGlobalOption( 'excluded-users', esc_html( implode( ',', $this->_excluded_users ) ) );
|
740 |
}
|
741 |
|
742 |
+
public function GetExcludedMonitoringUsers() {
|
743 |
+
if ( empty( $this->_excluded_users ) ) {
|
744 |
+
$this->_excluded_users = array_unique( array_filter( explode( ',', $this->_plugin->GetGlobalOption( 'excluded-users' ) ) ) );
|
|
|
745 |
}
|
746 |
return $this->_excluded_users;
|
747 |
}
|
770 |
}
|
771 |
|
772 |
/**
|
773 |
+
* Roles excluded from monitoring.
|
774 |
*/
|
775 |
+
public function SetExcludedMonitoringRoles( $roles ) {
|
|
|
776 |
$this->_excluded_roles = $roles;
|
777 |
+
$this->_plugin->SetGlobalOption( 'excluded-roles', esc_html( implode( ',', $this->_excluded_roles ) ) );
|
778 |
}
|
779 |
|
780 |
+
public function GetExcludedMonitoringRoles() {
|
781 |
+
if ( empty( $this->_excluded_roles ) ) {
|
782 |
+
$this->_excluded_roles = array_unique( array_filter( explode( ',', $this->_plugin->GetGlobalOption( 'excluded-roles' ) ) ) );
|
|
|
783 |
}
|
784 |
return $this->_excluded_roles;
|
785 |
}
|
786 |
|
787 |
/**
|
788 |
+
* Custom fields excluded from monitoring.
|
789 |
*/
|
790 |
+
public function SetExcludedMonitoringCustom( $custom ) {
|
|
|
791 |
$this->_excluded_custom = $custom;
|
792 |
+
$this->_plugin->SetGlobalOption( 'excluded-custom', esc_html( implode( ',', $this->_excluded_custom ) ) );
|
793 |
}
|
794 |
|
795 |
+
public function GetExcludedMonitoringCustom() {
|
796 |
+
if ( empty( $this->_excluded_custom ) ) {
|
797 |
+
$this->_excluded_custom = array_unique( array_filter( explode( ',', $this->_plugin->GetGlobalOption( 'excluded-custom' ) ) ) );
|
798 |
+
asort( $this->_excluded_custom );
|
|
|
799 |
}
|
800 |
return $this->_excluded_custom;
|
801 |
}
|
802 |
|
803 |
/**
|
804 |
+
* IP excluded from monitoring.
|
805 |
*/
|
806 |
+
public function SetExcludedMonitoringIP( $ip ) {
|
|
|
807 |
$this->_excluded_ip = $ip;
|
808 |
+
$this->_plugin->SetGlobalOption( 'excluded-ip', esc_html( implode( ',', $this->_excluded_ip ) ) );
|
809 |
}
|
810 |
|
811 |
+
public function GetExcludedMonitoringIP() {
|
812 |
+
if ( empty( $this->_excluded_ip ) ) {
|
813 |
+
$this->_excluded_ip = array_unique( array_filter( explode( ',', $this->_plugin->GetGlobalOption( 'excluded-ip' ) ) ) );
|
|
|
814 |
}
|
815 |
return $this->_excluded_ip;
|
816 |
}
|
818 |
/**
|
819 |
* Datetime used in the Alerts.
|
820 |
*/
|
821 |
+
public function GetDatetimeFormat( $line_break = true ) {
|
822 |
+
if ( $line_break ) {
|
|
|
823 |
$date_time_format = $this->GetDateFormat() . '<\b\r>' . $this->GetTimeFormat();
|
824 |
} else {
|
825 |
$date_time_format = $this->GetDateFormat() . ' ' . $this->GetTimeFormat();
|
826 |
}
|
827 |
|
828 |
+
$wp_time_format = get_option( 'time_format' );
|
829 |
+
if ( stripos( $wp_time_format, 'A' ) !== false ) {
|
830 |
$date_time_format .= '.$$$&\n\b\s\p;A';
|
831 |
} else {
|
832 |
$date_time_format .= '.$$$';
|
837 |
/**
|
838 |
* Date Format from WordPress General Settings.
|
839 |
*/
|
840 |
+
public function GetDateFormat() {
|
841 |
+
$wp_date_format = get_option( 'date_format' );
|
842 |
+
$search = array( 'F', 'M', 'n', 'j', ' ', '/', 'y', 'S', ',', 'l', 'D' );
|
843 |
+
$replace = array( 'm', 'm', 'm', 'd', '-', '-', 'Y', '', '', '', '' );
|
844 |
+
$date_format = str_replace( $search, $replace, $wp_date_format );
|
|
|
845 |
return $date_format;
|
846 |
}
|
847 |
|
848 |
/**
|
849 |
* Time Format from WordPress General Settings.
|
850 |
*/
|
851 |
+
public function GetTimeFormat() {
|
852 |
+
$wp_time_format = get_option( 'time_format' );
|
853 |
+
$search = array( 'a', 'A', 'T', ' ' );
|
854 |
+
$replace = array( '', '', '', '' );
|
855 |
+
$time_format = str_replace( $search, $replace, $wp_time_format );
|
|
|
856 |
return $time_format;
|
857 |
}
|
858 |
|
859 |
/**
|
860 |
+
* Alerts Timestamp.
|
861 |
+
*
|
862 |
+
* Server's timezone or WordPress' timezone.
|
863 |
*/
|
864 |
+
public function GetTimezone() {
|
865 |
+
return $this->_plugin->GetGlobalOption( 'timezone', 0 );
|
|
|
866 |
}
|
867 |
|
868 |
+
public function SetTimezone( $newvalue ) {
|
869 |
+
return $this->_plugin->SetGlobalOption( 'timezone', $newvalue );
|
|
|
870 |
}
|
871 |
|
872 |
/**
|
873 |
+
* Get type of username to display.
|
874 |
*/
|
875 |
public function get_type_username() {
|
876 |
return $this->_plugin->GetGlobalOption( 'type_username', 'display_name' );
|
886 |
return $this->_plugin->SetGlobalOption( 'type_username', $newvalue );
|
887 |
}
|
888 |
|
889 |
+
public function GetAdapterConfig( $name_field ) {
|
890 |
+
return $this->_plugin->GetGlobalOption( $name_field );
|
|
|
891 |
}
|
892 |
|
893 |
+
public function SetAdapterConfig( $name_field, $newvalue ) {
|
894 |
+
return $this->_plugin->SetGlobalOption( $name_field, trim( $newvalue ) );
|
|
|
895 |
}
|
896 |
|
897 |
+
public function GetColumns() {
|
898 |
+
$columns = array(
|
899 |
+
'alert_code' => '1',
|
900 |
+
'type' => '1',
|
901 |
+
'date' => '1',
|
902 |
+
'username' => '1',
|
903 |
+
'source_ip' => '1',
|
904 |
+
'message' => '1',
|
905 |
+
);
|
906 |
+
if ( $this->_plugin->IsMultisite() ) {
|
907 |
+
$columns = array_slice( $columns, 0, 5, true ) + array(
|
908 |
+
'site' => '1',
|
909 |
+
) + array_slice( $columns, 5, null, true );
|
910 |
}
|
911 |
$selected = $this->GetColumnsSelected();
|
912 |
+
if ( ! empty( $selected ) ) {
|
913 |
+
$columns = array(
|
914 |
+
'alert_code' => '0',
|
915 |
+
'type' => '0',
|
916 |
+
'date' => '0',
|
917 |
+
'username' => '0',
|
918 |
+
'source_ip' => '0',
|
919 |
+
'message' => '0',
|
920 |
+
);
|
921 |
+
if ( $this->_plugin->IsMultisite() ) {
|
922 |
+
$columns = array_slice( $columns, 0, 5, true ) + array(
|
923 |
+
'site' => '0',
|
924 |
+
) + array_slice( $columns, 5, null, true );
|
925 |
}
|
926 |
+
$selected = (array) json_decode( $selected );
|
927 |
+
$columns = array_merge( $columns, $selected );
|
928 |
return $columns;
|
929 |
} else {
|
930 |
return $columns;
|
931 |
}
|
932 |
}
|
933 |
|
934 |
+
public function GetColumnsSelected() {
|
935 |
+
return $this->_plugin->GetGlobalOption( 'columns' );
|
|
|
936 |
}
|
937 |
|
938 |
+
public function SetColumns( $columns ) {
|
939 |
+
return $this->_plugin->SetGlobalOption( 'columns', json_encode( $columns ) );
|
|
|
940 |
}
|
941 |
|
942 |
+
public function IsWPBackend() {
|
943 |
+
return $this->_plugin->GetGlobalOption( 'wp-backend' );
|
|
|
944 |
}
|
945 |
|
946 |
+
public function SetWPBackend( $enabled ) {
|
947 |
+
return $this->_plugin->SetGlobalOption( 'wp-backend', $enabled );
|
|
|
948 |
}
|
949 |
|
950 |
+
public function SetFromEmail( $email_address ) {
|
951 |
+
return $this->_plugin->SetGlobalOption( 'from-email', trim( $email_address ) );
|
|
|
952 |
}
|
953 |
|
954 |
+
public function GetFromEmail() {
|
955 |
+
return $this->_plugin->GetGlobalOption( 'from-email' );
|
|
|
956 |
}
|
957 |
|
958 |
+
public function SetDisplayName( $display_name ) {
|
959 |
+
return $this->_plugin->SetGlobalOption( 'display-name', trim( $display_name ) );
|
|
|
960 |
}
|
961 |
|
962 |
+
public function GetDisplayName() {
|
963 |
+
return $this->_plugin->GetGlobalOption( 'display-name' );
|
|
|
964 |
}
|
965 |
|
966 |
+
public function Set404LogLimit( $value ) {
|
967 |
+
return $this->_plugin->SetGlobalOption( 'log-404-limit', abs( $value ) );
|
|
|
968 |
}
|
969 |
|
970 |
+
public function Get404LogLimit() {
|
971 |
+
return $this->_plugin->GetGlobalOption( 'log-404-limit', 99 );
|
|
|
972 |
}
|
973 |
|
974 |
/**
|
1036 |
return $this->_plugin->GetGlobalOption( 'log-visitor-failed-login-limit', 10 );
|
1037 |
}
|
1038 |
|
1039 |
+
public function IsArchivingEnabled() {
|
1040 |
+
return $this->_plugin->GetGlobalOption( 'archiving-e' );
|
|
|
|
|
|
|
1041 |
}
|
1042 |
|
1043 |
/**
|
1044 |
+
* Switch to Archive DB if is enabled.
|
1045 |
*/
|
1046 |
+
public function SwitchToArchiveDB() {
|
1047 |
+
if ( $this->IsArchivingEnabled() ) {
|
1048 |
+
$archive_type = $this->_plugin->GetGlobalOption( 'archive-type' );
|
1049 |
+
$archive_user = $this->_plugin->GetGlobalOption( 'archive-user' );
|
1050 |
+
$password = $this->_plugin->GetGlobalOption( 'archive-password' );
|
1051 |
+
$archive_name = $this->_plugin->GetGlobalOption( 'archive-name' );
|
1052 |
+
$archive_hostname = $this->_plugin->GetGlobalOption( 'archive-hostname' );
|
1053 |
+
$archive_baseprefix = $this->_plugin->GetGlobalOption( 'archive-base-prefix' );
|
1054 |
+
$config = WSAL_Connector_ConnectorFactory::GetConfigArray( $archive_type, $archive_user, $password, $archive_name, $archive_hostname, $archive_baseprefix );
|
1055 |
+
$this->_plugin->getConnector( $config )->getAdapter( 'Occurrence' );
|
|
|
1056 |
}
|
1057 |
}
|
|
|
1058 |
}
|
classes/SimpleProfiler.php
CHANGED
@@ -2,53 +2,47 @@
|
|
2 |
/**
|
3 |
* @package Wsal
|
4 |
*/
|
5 |
-
class WSAL_SimpleProfiler
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
{
|
27 |
-
return $this->_items;
|
28 |
-
}
|
29 |
}
|
30 |
|
31 |
-
class WSAL_SimpleProfiler_Item
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
. str_pad(number_format($m_diff, 0), 12, ' ', STR_PAD_LEFT) . 'b '
|
52 |
-
. $this->name;
|
53 |
-
}
|
54 |
}
|
2 |
/**
|
3 |
* @package Wsal
|
4 |
*/
|
5 |
+
class WSAL_SimpleProfiler {
|
6 |
+
|
7 |
+
protected $_items = array();
|
8 |
+
|
9 |
+
public function Start( $name ) {
|
10 |
+
$item = new WSAL_SimpleProfiler_Item( $name );
|
11 |
+
$this->_items[] = $item;
|
12 |
+
return $item;
|
13 |
+
}
|
14 |
+
|
15 |
+
public function AsComment() {
|
16 |
+
echo '<!-- ' . esc_html( PHP_EOL );
|
17 |
+
foreach ( $this->_items as $item ) {
|
18 |
+
echo ' ' . esc_html( $item . PHP_EOL );
|
19 |
+
}
|
20 |
+
echo '-->' . esc_html( PHP_EOL );
|
21 |
+
}
|
22 |
+
|
23 |
+
public function GetItems() {
|
24 |
+
return $this->_items;
|
25 |
+
}
|
|
|
|
|
|
|
26 |
}
|
27 |
|
28 |
+
class WSAL_SimpleProfiler_Item {
|
29 |
+
|
30 |
+
public function __construct( $name ) {
|
31 |
+
$this->name = $name;
|
32 |
+
$this->t_bgn = microtime( true );
|
33 |
+
$this->m_bgn = memory_get_usage();
|
34 |
+
}
|
35 |
+
|
36 |
+
public function Stop() {
|
37 |
+
$this->t_end = microtime( true );
|
38 |
+
$this->m_end = memory_get_usage();
|
39 |
+
}
|
40 |
+
|
41 |
+
public function __toString() {
|
42 |
+
$t_diff = $this->t_end - $this->t_bgn;
|
43 |
+
$m_diff = $this->m_end - $this->m_bgn;
|
44 |
+
return number_format( $t_diff, 6 ) . 's '
|
45 |
+
. str_pad( number_format( $m_diff, 0 ), 12, ' ', STR_PAD_LEFT ) . 'b '
|
46 |
+
. $this->name;
|
47 |
+
}
|
|
|
|
|
|
|
48 |
}
|
classes/ViewManager.php
CHANGED
@@ -1,290 +1,316 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* This Class load all the views, initialize them and shows the active one.
|
6 |
* It creates also the menu items.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_ViewManager
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View Manager.
|
4 |
*
|
5 |
* This Class load all the views, initialize them and shows the active one.
|
6 |
* It creates also the menu items.
|
7 |
+
*
|
8 |
+
* @package Wsal
|
9 |
*/
|
10 |
+
class WSAL_ViewManager {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Array of views.
|
14 |
+
*
|
15 |
+
* @var WSAL_AbstractView[]
|
16 |
+
*/
|
17 |
+
public $views = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Instance of WpSecurityAuditLog.
|
21 |
+
*
|
22 |
+
* @var object
|
23 |
+
*/
|
24 |
+
protected $_plugin;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Active view.
|
28 |
+
*
|
29 |
+
* @var WSAL_AbstractView|null
|
30 |
+
*/
|
31 |
+
protected $_active_view = false;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Method: Constructor.
|
35 |
+
*
|
36 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
37 |
+
* @author Ashar Irfan
|
38 |
+
* @since 1.0.0
|
39 |
+
*/
|
40 |
+
public function __construct( WpSecurityAuditLog $plugin ) {
|
41 |
+
$this->_plugin = $plugin;
|
42 |
+
|
43 |
+
$skip_views = array();
|
44 |
+
|
45 |
+
// Load views.
|
46 |
+
foreach ( glob( dirname( __FILE__ ) . '/Views/*.php' ) as $file ) {
|
47 |
+
if ( empty( $skip_views ) || ! in_array( $file, $skip_views ) ) {
|
48 |
+
$this->AddFromFile( $file );
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
// Add menus.
|
53 |
+
add_action( 'admin_menu', array( $this, 'AddAdminMenus' ) );
|
54 |
+
add_action( 'network_admin_menu', array( $this, 'AddAdminMenus' ) );
|
55 |
+
|
56 |
+
// Add plugin shortcut links.
|
57 |
+
add_filter( 'plugin_action_links_' . $plugin->GetBaseName(), array( $this, 'AddPluginShortcuts' ) );
|
58 |
+
|
59 |
+
// Render header.
|
60 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'RenderViewHeader' ) );
|
61 |
+
|
62 |
+
// Render footer.
|
63 |
+
add_action( 'admin_footer', array( $this, 'RenderViewFooter' ) );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Add new view from file inside autoloader path.
|
68 |
+
*
|
69 |
+
* @param string $file Path to file.
|
70 |
+
*/
|
71 |
+
public function AddFromFile( $file ) {
|
72 |
+
$this->AddFromClass( $this->_plugin->GetClassFileClassName( $file ) );
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Add new view given class name.
|
77 |
+
*
|
78 |
+
* @param string $class Class name.
|
79 |
+
*/
|
80 |
+
public function AddFromClass( $class ) {
|
81 |
+
$this->AddInstance( new $class( $this->_plugin ) );
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Add newly created view to list.
|
86 |
+
*
|
87 |
+
* @param WSAL_AbstractView $view The new view.
|
88 |
+
*/
|
89 |
+
public function AddInstance( WSAL_AbstractView $view ) {
|
90 |
+
$this->views[] = $view;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Order views by their declared weight.
|
95 |
+
*/
|
96 |
+
public function ReorderViews() {
|
97 |
+
usort( $this->views, array( $this, 'OrderByWeight' ) );
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Get page order by its weight.
|
102 |
+
*
|
103 |
+
* @internal This has to be public for PHP to call it.
|
104 |
+
* @param WSAL_AbstractView $a - First view.
|
105 |
+
* @param WSAL_AbstractView $b - Second view.
|
106 |
+
* @return int
|
107 |
+
*/
|
108 |
+
public function OrderByWeight( WSAL_AbstractView $a, WSAL_AbstractView $b ) {
|
109 |
+
$wa = $a->GetWeight();
|
110 |
+
$wb = $b->GetWeight();
|
111 |
+
switch ( true ) {
|
112 |
+
case $wa < $wb:
|
113 |
+
return -1;
|
114 |
+
case $wa > $wb:
|
115 |
+
return 1;
|
116 |
+
default:
|
117 |
+
return 0;
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* WordPress Action
|
123 |
+
*/
|
124 |
+
public function AddAdminMenus() {
|
125 |
+
$this->ReorderViews();
|
126 |
+
|
127 |
+
if ( $this->_plugin->settings->CurrentUserCan( 'view' ) && count( $this->views ) ) {
|
128 |
+
// Add main menu.
|
129 |
+
$this->views[0]->hook_suffix = add_menu_page(
|
130 |
+
'WP Security Audit Log',
|
131 |
+
'Audit Log',
|
132 |
+
'read', // No capability requirement.
|
133 |
+
$this->views[0]->GetSafeViewName(),
|
134 |
+
array( $this, 'RenderViewBody' ),
|
135 |
+
$this->views[0]->GetIcon(),
|
136 |
+
'2.5' // Right after dashboard.
|
137 |
+
);
|
138 |
+
|
139 |
+
// Add menu items.
|
140 |
+
foreach ( $this->views as $view ) {
|
141 |
+
if ( $view->IsAccessible() ) {
|
142 |
+
if ( $this->GetClassNameByView( $view->GetSafeViewName() ) ) {
|
143 |
+
continue;
|
144 |
+
}
|
145 |
+
|
146 |
+
$view->hook_suffix = add_submenu_page(
|
147 |
+
$view->IsVisible() ? $this->views[0]->GetSafeViewName() : null,
|
148 |
+
$view->GetTitle(),
|
149 |
+
$view->GetName(),
|
150 |
+
'read', // No capability requirement.
|
151 |
+
$view->GetSafeViewName(),
|
152 |
+
array( $this, 'RenderViewBody' ),
|
153 |
+
$view->GetIcon()
|
154 |
+
);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* WordPress Filter
|
162 |
+
*
|
163 |
+
* @param array $old_links - Array of old links.
|
164 |
+
*/
|
165 |
+
public function AddPluginShortcuts( $old_links ) {
|
166 |
+
$this->ReorderViews();
|
167 |
+
|
168 |
+
$new_links = array();
|
169 |
+
foreach ( $this->views as $view ) {
|
170 |
+
if ( $view->HasPluginShortcutLink() ) {
|
171 |
+
$new_links[] =
|
172 |
+
'<a href="'
|
173 |
+
. admin_url( 'admin.php?page=' . $view->GetSafeViewName() )
|
174 |
+
. '">'
|
175 |
+
. $view->GetName()
|
176 |
+
. '</a>';
|
177 |
+
}
|
178 |
+
}
|
179 |
+
return array_merge( $new_links, $old_links );
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Returns page id of current page (or false on error).
|
184 |
+
*
|
185 |
+
* @return int
|
186 |
+
*/
|
187 |
+
protected function GetBackendPageIndex() {
|
188 |
+
// Get current view via $_GET array.
|
189 |
+
$current_view = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
190 |
+
|
191 |
+
if ( isset( $current_view ) ) {
|
192 |
+
foreach ( $this->views as $i => $view ) {
|
193 |
+
if ( $current_view === $view->GetSafeViewName() ) {
|
194 |
+
return $i;
|
195 |
+
}
|
196 |
+
}
|
197 |
+
}
|
198 |
+
return false;
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Returns the current active view or null if none.
|
203 |
+
*
|
204 |
+
* @return WSAL_AbstractView|null
|
205 |
+
*/
|
206 |
+
public function GetActiveView() {
|
207 |
+
if ( false === $this->_active_view ) {
|
208 |
+
$this->_active_view = null;
|
209 |
+
|
210 |
+
// Get current view via $_GET array.
|
211 |
+
$current_view = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
|
212 |
+
|
213 |
+
if ( isset( $current_view ) ) {
|
214 |
+
foreach ( $this->views as $view ) {
|
215 |
+
if ( $current_view === $view->GetSafeViewName() ) {
|
216 |
+
$this->_active_view = $view;
|
217 |
+
}
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
if ( $this->_active_view ) {
|
222 |
+
$this->_active_view->is_active = true;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
return $this->_active_view;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Render header of the current view.
|
230 |
+
*/
|
231 |
+
public function RenderViewHeader() {
|
232 |
+
if ( ! ! ($view = $this->GetActiveView()) ) {
|
233 |
+
$view->Header();
|
234 |
+
}
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Render footer of the current view.
|
239 |
+
*/
|
240 |
+
public function RenderViewFooter() {
|
241 |
+
if ( ! ! ($view = $this->GetActiveView()) ) {
|
242 |
+
$view->Footer();
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Render content of the current view.
|
248 |
+
*/
|
249 |
+
public function RenderViewBody() {
|
250 |
+
$view = $this->GetActiveView();
|
251 |
+
?>
|
252 |
+
<div class="wrap">
|
253 |
+
<?php
|
254 |
+
$view->RenderIcon();
|
255 |
+
$view->RenderTitle();
|
256 |
+
$view->RenderContent();
|
257 |
+
?>
|
258 |
+
</div>
|
259 |
+
<?php
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Returns view instance corresponding to its class name.
|
264 |
+
*
|
265 |
+
* @param string $class_name View class name.
|
266 |
+
* @return WSAL_AbstractView The view or false on failure.
|
267 |
+
*/
|
268 |
+
public function FindByClassName( $class_name ) {
|
269 |
+
foreach ( $this->views as $view ) {
|
270 |
+
if ( $view instanceof $class_name ) {
|
271 |
+
return $view;
|
272 |
+
}
|
273 |
+
}
|
274 |
+
return false;
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Method: Returns class name of the view using view name.
|
279 |
+
*
|
280 |
+
* @param string $view_slug - Slug of view.
|
281 |
+
* @since 1.0.0
|
282 |
+
*/
|
283 |
+
private function GetClassNameByView( $view_slug ) {
|
284 |
+
$not_show = false;
|
285 |
+
switch ( $view_slug ) {
|
286 |
+
case 'wsal-emailnotifications':
|
287 |
+
if ( class_exists( 'WSAL_NP_Plugin' ) ) {
|
288 |
+
$not_show = true;
|
289 |
+
}
|
290 |
+
break;
|
291 |
+
case 'wsal-loginusers':
|
292 |
+
if ( class_exists( 'WSAL_User_Management_Plugin' ) ) {
|
293 |
+
$not_show = true;
|
294 |
+
}
|
295 |
+
break;
|
296 |
+
case 'wsal-reports':
|
297 |
+
if ( class_exists( 'WSAL_Rep_Plugin' ) ) {
|
298 |
+
$not_show = true;
|
299 |
+
}
|
300 |
+
break;
|
301 |
+
case 'wsal-search':
|
302 |
+
if ( class_exists( 'WSAL_SearchExtension' ) ) {
|
303 |
+
$not_show = true;
|
304 |
+
}
|
305 |
+
break;
|
306 |
+
case 'wsal-externaldb':
|
307 |
+
if ( class_exists( 'WSAL_Ext_Plugin' ) ) {
|
308 |
+
$not_show = true;
|
309 |
+
}
|
310 |
+
break;
|
311 |
+
default:
|
312 |
+
break;
|
313 |
+
}
|
314 |
+
return $not_show;
|
315 |
+
}
|
316 |
}
|
classes/Views/About.php
DELETED
@@ -1,94 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
-
* About Page.
|
6 |
-
*/
|
7 |
-
class WSAL_Views_About extends WSAL_AbstractView
|
8 |
-
{
|
9 |
-
public function GetTitle()
|
10 |
-
{
|
11 |
-
return __('About WP Security Audit Log', 'wp-security-audit-log');
|
12 |
-
}
|
13 |
-
|
14 |
-
public function GetIcon()
|
15 |
-
{
|
16 |
-
return 'dashicons-editor-help';
|
17 |
-
}
|
18 |
-
|
19 |
-
public function GetName()
|
20 |
-
{
|
21 |
-
return __('About', 'wp-security-audit-log');
|
22 |
-
}
|
23 |
-
|
24 |
-
public function GetWeight()
|
25 |
-
{
|
26 |
-
return 6;
|
27 |
-
}
|
28 |
-
|
29 |
-
public function Render()
|
30 |
-
{
|
31 |
-
?><div class="metabox-holder" style="position: relative;">
|
32 |
-
|
33 |
-
<div class="postbox" style="margin-right: 270px;">
|
34 |
-
<!--h3 class="hndl"><span>About WP Security Audit Log</span></h3-->
|
35 |
-
<div class="inside">
|
36 |
-
<div class="activity-block">
|
37 |
-
<?php _e('WP Security Audit Log enables WordPress administrators and owners to identify WordPress security issues before they become a security problem by keeping a security audit log. WP Security Audit Log is developed by WordPress security professionals WP White Security.', 'wp-security-audit-log'); ?>
|
38 |
-
|
39 |
-
<h2><?php _e('Keep A WordPress Security Audit Log & Identify WordPress Security Issues', 'wp-security-audit-log'); ?></h2>
|
40 |
-
<p>
|
41 |
-
<?php _e('WP Security Audit Log logs everything happening on your WordPress blog or website and WordPress multisite network. By using WP Security Audit Log security plugin it is very easy to track suspicious user activity before it becomes a problem or a security issue. A WordPress security alert is generated by the plugin when:', 'wp-security-audit-log'); ?>
|
42 |
-
</p>
|
43 |
-
<ul style="list-style-type: disc; margin-left: 2.5em; list-style-position: outside;">
|
44 |
-
<li><?php _e('User creates a new user or a new user is registered', 'wp-security-audit-log'); ?></li>
|
45 |
-
<li><?php _e('Existing user changes the role, password or other properties of another user', 'wp-security-audit-log'); ?></li>
|
46 |
-
<li><?php _e('Existing user on a WordPress multisite network is added to a site', 'wp-security-audit-log'); ?></li>
|
47 |
-
<li><?php _e('User uploads or deletes a file, changes a password or email address', 'wp-security-audit-log'); ?></li>
|
48 |
-
<li><?php _e('User installs, activates, deactivates, upgrades or uninstalls a plugin', 'wp-security-audit-log'); ?></li>
|
49 |
-
<li><?php _e('User creates, modifies or deletes a new post, page, category or a custom post type', 'wp-security-audit-log'); ?></li>
|
50 |
-
<li><?php _e('User installs or activates a WordPress theme', 'wp-security-audit-log'); ?></li>
|
51 |
-
<li><?php _e('User adds, modifies or deletes a widget', 'wp-security-audit-log'); ?></li>
|
52 |
-
<li><?php _e('User uses the dashboard file editor', 'wp-security-audit-log'); ?></li>
|
53 |
-
<li><?php _e('WordPress settings are changed', 'wp-security-audit-log'); ?></li>
|
54 |
-
<li><?php _e('Failed login attempts', 'wp-security-audit-log'); ?></li>
|
55 |
-
<li><?php _e('and much more…', 'wp-security-audit-log'); ?></li>
|
56 |
-
</ul>
|
57 |
-
<br/>
|
58 |
-
Refer to the complete list of <a href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank">WordPress Security Alerts</a> for more information.
|
59 |
-
</div>
|
60 |
-
</div>
|
61 |
-
</div>
|
62 |
-
|
63 |
-
<div style="position: absolute; right: 70px; width: 180px; top: 10px;">
|
64 |
-
<div class="postbox">
|
65 |
-
<h3 class="hndl"><span><?php _e('Extend the Functionality & Get More Value from WP Security Audit Log', 'wp-security-audit-log'); ?></span></h3>
|
66 |
-
<div class="inside">
|
67 |
-
<p>
|
68 |
-
<?php _e('Get more value out of WP Security Audit Log by extending the functionality of WP Security Audit Log with the premium Add-Ons.'); ?>
|
69 |
-
</p>
|
70 |
-
<a class="button button-primary" href="http://www.wpsecurityauditlog.com/plugin-extensions/" target="_blank"><?php _e('See Add-Ons', 'wp-security-audit-log'); ?></a>
|
71 |
-
</div>
|
72 |
-
</div>
|
73 |
-
<div class="postbox">
|
74 |
-
<h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
|
75 |
-
<div class="inside">
|
76 |
-
<?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
|
77 |
-
<a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
|
78 |
-
</div>
|
79 |
-
</div>
|
80 |
-
<div class="postbox">
|
81 |
-
<h3 class="hndl"><span><?php _e('WordPress Security Services', 'wp-security-audit-log'); ?></span></h3>
|
82 |
-
<div class="inside">
|
83 |
-
<?php _e('Professional WordPress security services provided by WP White Security', 'wp-security-audit-log'); ?>
|
84 |
-
<ul>
|
85 |
-
<li><a href="http://www.wpwhitesecurity.com/wordpress-security-services/wordpress-security-hardening/?utm_source=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank">Security Hardening</a></li>
|
86 |
-
<li><a href="http://www.wpwhitesecurity.com/wordpress-security-services/wordpress-security-audit/?utm_source=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank">Security Audit</a></li>
|
87 |
-
<li><a href="http://www.wpwhitesecurity.com/wordpress-security-services/wordpress-plugins-security-code-audit-review/?utm_source=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank">Plugin Security Code Audit</a></li>
|
88 |
-
</ul>
|
89 |
-
</div>
|
90 |
-
</div>
|
91 |
-
</div>
|
92 |
-
</div><?php
|
93 |
-
}
|
94 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Views/AuditLog.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*
|
5 |
* Class file for Audit Log View.
|
6 |
*
|
7 |
-
* @since
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
@@ -39,9 +39,7 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
39 |
/**
|
40 |
* Method: Constructor
|
41 |
*
|
42 |
-
* @param
|
43 |
-
* @author Ashar Irfan
|
44 |
-
* @since 1.0.0
|
45 |
*/
|
46 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
47 |
parent::__construct( $plugin );
|
@@ -65,52 +63,87 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
65 |
public function AdminNoticesPremium() {
|
66 |
$is_current_view = $this->_plugin->views->GetActiveView() == $this;
|
67 |
// Check if any of the extensions is activated.
|
68 |
-
if ( ! class_exists( 'WSAL_NP_Plugin' )
|
|
|
|
|
|
|
|
|
69 |
if ( current_user_can( 'manage_options' ) && $is_current_view && ! $this->IsNoticeDismissed( 'premium-wsal-' . $this->_version ) ) { ?>
|
70 |
-
<div class="updated" data-notice-name="premium-wsal-<?php echo esc_attr( $this->_version ) ?>">
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
</div>
|
78 |
<?php
|
79 |
}
|
80 |
}
|
81 |
}
|
82 |
|
83 |
-
|
84 |
-
|
|
|
|
|
85 |
return true;
|
86 |
}
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
91 |
}
|
92 |
|
93 |
-
|
94 |
-
|
|
|
|
|
95 |
return $this->_wpversion < 3.8
|
96 |
? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
|
97 |
-
: '
|
98 |
}
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
103 |
}
|
104 |
|
105 |
-
|
106 |
-
|
|
|
|
|
107 |
return 1;
|
108 |
}
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
|
|
|
|
114 |
}
|
115 |
return $this->_listview;
|
116 |
}
|
@@ -125,36 +158,50 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
125 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
126 |
}
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
$this->GetListView()->prepare_items();
|
129 |
$occ = new WSAL_Models_Occurrence();
|
130 |
|
131 |
-
|
|
|
132 |
<div id="audit-log-viewer-content">
|
133 |
-
<input type="hidden" name="page" value="<?php echo
|
134 |
-
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr( isset( $
|
135 |
<?php do_action( 'wsal_auditlog_before_view', $this->GetListView() ); ?>
|
136 |
<?php $this->GetListView()->display(); ?>
|
137 |
<?php do_action( 'wsal_auditlog_after_view', $this->GetListView() ); ?>
|
138 |
</div>
|
139 |
</form>
|
140 |
|
141 |
-
<?php
|
142 |
-
|
|
|
|
|
143 |
<script type="text/javascript">
|
144 |
jQuery(document).ready( function() {
|
145 |
WsalAuditLogInit(
|
146 |
-
<?php
|
147 |
-
|
148 |
-
|
149 |
-
'
|
150 |
-
'
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
'
|
156 |
-
|
157 |
-
|
|
|
|
|
|
|
158 |
?>
|
159 |
);
|
160 |
} );
|
@@ -163,67 +210,77 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
163 |
<script type="text/javascript">
|
164 |
jQuery(document).ready( function() {
|
165 |
WsalAuditLogInit(
|
166 |
-
<?php
|
167 |
-
|
168 |
-
|
169 |
-
'
|
170 |
-
'
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
'
|
176 |
-
|
177 |
-
|
|
|
|
|
|
|
178 |
?>
|
179 |
);
|
180 |
} );
|
181 |
</script>
|
182 |
-
<?php
|
|
|
183 |
}
|
184 |
|
185 |
-
public function AjaxInspector()
|
186 |
-
|
187 |
-
|
188 |
-
die('Access Denied.');
|
189 |
}
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
192 |
}
|
193 |
$occ = new WSAL_Models_Occurrence();
|
194 |
-
$occ->Load('id = %d', array((int)$
|
195 |
|
196 |
echo '<!DOCTYPE html><html><head>';
|
197 |
-
echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
|
198 |
-
echo '<script type="text/javascript" src="'
|
199 |
echo '<style type="text/css">';
|
200 |
echo 'html, body { margin: 0; padding: 0; }';
|
201 |
echo '.nice_r { position: absolute; padding: 8px; }';
|
202 |
echo '.nice_r a { overflow: visible; }';
|
203 |
echo '</style>';
|
204 |
echo '</head><body>';
|
205 |
-
$nicer = new WSAL_Nicer($occ->GetMetaArray());
|
206 |
$nicer->render();
|
207 |
echo '</body></html>';
|
208 |
die;
|
209 |
}
|
210 |
|
211 |
-
public function AjaxRefresh()
|
212 |
-
|
213 |
-
|
214 |
-
die('Access Denied.');
|
215 |
}
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
218 |
}
|
219 |
|
220 |
-
$old = (int)$
|
221 |
$max = 40; // 40*500msec = 20sec
|
222 |
|
223 |
$is_archive = false;
|
224 |
-
if ($this->_plugin->settings->IsArchivingEnabled()) {
|
225 |
-
$selected_db = get_transient('wsal_wp_selected_db');
|
226 |
-
if ($selected_db && $selected_db
|
227 |
$is_archive = true;
|
228 |
}
|
229 |
}
|
@@ -231,81 +288,87 @@ class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
|
231 |
do {
|
232 |
$occ = new WSAL_Models_Occurrence();
|
233 |
$new = $occ->Count();
|
234 |
-
usleep(500000); // 500msec
|
235 |
-
} while (($old == $new) && (--$max > 0));
|
236 |
|
237 |
-
if ($is_archive) {
|
238 |
echo 'false';
|
239 |
} else {
|
240 |
-
echo $old == $new ? 'false' : $new;
|
241 |
}
|
242 |
die;
|
243 |
}
|
244 |
|
245 |
-
public function AjaxSetIpp()
|
246 |
-
|
247 |
-
|
248 |
-
die('Access Denied.');
|
249 |
}
|
250 |
-
|
251 |
-
|
|
|
|
|
|
|
|
|
252 |
}
|
253 |
-
$this->_plugin->settings->SetViewPerPage((int)$
|
254 |
die;
|
255 |
}
|
256 |
|
257 |
-
public function AjaxSearchSite()
|
258 |
-
|
259 |
-
|
260 |
-
die('Access Denied.');
|
261 |
}
|
262 |
-
|
263 |
-
|
|
|
|
|
|
|
|
|
264 |
}
|
265 |
$grp1 = array();
|
266 |
$grp2 = array();
|
267 |
|
268 |
-
$search = $
|
269 |
|
270 |
-
foreach ($this->GetListView()->get_sites() as $site) {
|
271 |
-
if (stripos($site->blogname, $search) !== false) {
|
272 |
$grp1[] = $site;
|
273 |
-
} elseif (stripos($site->domain, $search) !== false) {
|
274 |
$grp2[] = $site;
|
275 |
}
|
276 |
}
|
277 |
-
die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
|
278 |
}
|
279 |
|
280 |
-
public function AjaxSwitchDB()
|
281 |
-
|
282 |
-
|
283 |
-
|
|
|
|
|
284 |
}
|
285 |
}
|
286 |
|
287 |
-
public function Header()
|
288 |
-
{
|
289 |
add_thickbox();
|
290 |
-
wp_enqueue_style('darktooltip', $this->_plugin->GetBaseUrl() . '/css/darktooltip.css', array(), '');
|
291 |
wp_enqueue_style(
|
292 |
'auditlog',
|
293 |
$this->_plugin->GetBaseUrl() . '/css/auditlog.css',
|
294 |
array(),
|
295 |
-
filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
|
296 |
);
|
297 |
}
|
298 |
|
299 |
-
public function Footer()
|
300 |
-
|
301 |
-
wp_enqueue_script('jquery');
|
302 |
-
wp_enqueue_script(
|
303 |
-
wp_enqueue_script('suggest');
|
304 |
wp_enqueue_script(
|
305 |
'auditlog',
|
306 |
$this->_plugin->GetBaseUrl() . '/js/auditlog.js',
|
307 |
array(),
|
308 |
-
filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
|
309 |
);
|
310 |
}
|
311 |
}
|
4 |
*
|
5 |
* Class file for Audit Log View.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
* @package wsal
|
9 |
*/
|
10 |
|
39 |
/**
|
40 |
* Method: Constructor
|
41 |
*
|
42 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
|
|
|
|
43 |
*/
|
44 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
45 |
parent::__construct( $plugin );
|
63 |
public function AdminNoticesPremium() {
|
64 |
$is_current_view = $this->_plugin->views->GetActiveView() == $this;
|
65 |
// Check if any of the extensions is activated.
|
66 |
+
if ( ! class_exists( 'WSAL_NP_Plugin' )
|
67 |
+
&& ! class_exists( 'WSAL_Ext_Plugin' )
|
68 |
+
&& ! class_exists( 'WSAL_Rep_Plugin' )
|
69 |
+
&& ! class_exists( 'WSAL_SearchExtension' )
|
70 |
+
&& ! class_exists( 'WSAL_User_Management_Plugin' ) ) {
|
71 |
if ( current_user_can( 'manage_options' ) && $is_current_view && ! $this->IsNoticeDismissed( 'premium-wsal-' . $this->_version ) ) { ?>
|
72 |
+
<div class="updated wsal_notice" data-notice-name="premium-wsal-<?php echo esc_attr( $this->_version ); ?>">
|
73 |
+
<div class="wsal_notice__wrapper">
|
74 |
+
<img src="<?php echo esc_url( WSAL_BASE_URL ); ?>img/wsal-logo@2x.png">
|
75 |
+
<p>
|
76 |
+
<strong><?php esc_html_e( 'See who is logged in to your WordPress, create user productivity reports, get alerted via email of important changes and more!', 'wp-security-audit-log' ); ?></strong><br />
|
77 |
+
<?php esc_html_e( 'Unlock these powerful features and much more with the premium edition of WP Security Audit Log.', 'wp-security-audit-log' ); ?>
|
78 |
+
</p>
|
79 |
+
<!-- /.wsal_notice__wrapper -->
|
80 |
+
<div class="wsal_notice__btns">
|
81 |
+
<?php
|
82 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
83 |
+
$more_info = add_query_arg(
|
84 |
+
array(
|
85 |
+
'utm_source' => 'plugin',
|
86 |
+
'utm_medium' => 'banner',
|
87 |
+
'utm_content' => 'audit+log+viewier+more+info',
|
88 |
+
'utm_campaign' => 'upgrade+premium',
|
89 |
+
),
|
90 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
91 |
+
);
|
92 |
+
?>
|
93 |
+
<a href="<?php echo esc_url( $buy_now ); ?>" class="button button-primary buy-now"><?php esc_html_e( 'Buy Now', 'wp-security-audit-log' ); ?></a>
|
94 |
+
<a href="<?php echo esc_url( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
95 |
+
</div>
|
96 |
+
<!-- /.wsal_notice__btns -->
|
97 |
+
</div>
|
98 |
</div>
|
99 |
<?php
|
100 |
}
|
101 |
}
|
102 |
}
|
103 |
|
104 |
+
/**
|
105 |
+
* Method: Check if view has shortcut link.
|
106 |
+
*/
|
107 |
+
public function HasPluginShortcutLink() {
|
108 |
return true;
|
109 |
}
|
110 |
|
111 |
+
/**
|
112 |
+
* Method: Get View Title.
|
113 |
+
*/
|
114 |
+
public function GetTitle() {
|
115 |
+
return __( 'Audit Log Viewer', 'wp-security-audit-log' );
|
116 |
}
|
117 |
|
118 |
+
/**
|
119 |
+
* Method: Get View Icon.
|
120 |
+
*/
|
121 |
+
public function GetIcon() {
|
122 |
return $this->_wpversion < 3.8
|
123 |
? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
|
124 |
+
: $this->_plugin->GetBaseUrl() . '/img/wsal-menu-icon.svg';
|
125 |
}
|
126 |
|
127 |
+
/**
|
128 |
+
* Method: Get View Name.
|
129 |
+
*/
|
130 |
+
public function GetName() {
|
131 |
+
return __( 'Audit Log Viewer', 'wp-security-audit-log' );
|
132 |
}
|
133 |
|
134 |
+
/**
|
135 |
+
* Method: Get View Weight.
|
136 |
+
*/
|
137 |
+
public function GetWeight() {
|
138 |
return 1;
|
139 |
}
|
140 |
|
141 |
+
/**
|
142 |
+
* Method: Get View.
|
143 |
+
*/
|
144 |
+
protected function GetListView() {
|
145 |
+
if ( is_null( $this->_listview ) ) {
|
146 |
+
$this->_listview = new WSAL_AuditLogListView( $this->_plugin );
|
147 |
}
|
148 |
return $this->_listview;
|
149 |
}
|
158 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
159 |
}
|
160 |
|
161 |
+
// Filter $_POST array for security.
|
162 |
+
$post_array = filter_input_array( INPUT_POST );
|
163 |
+
|
164 |
+
// Verify nonce for security.
|
165 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'bulk-logs' ) ) {
|
166 |
+
wp_die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
167 |
+
}
|
168 |
+
|
169 |
$this->GetListView()->prepare_items();
|
170 |
$occ = new WSAL_Models_Occurrence();
|
171 |
|
172 |
+
?>
|
173 |
+
<form id="audit-log-viewer" method="post">
|
174 |
<div id="audit-log-viewer-content">
|
175 |
+
<input type="hidden" name="page" value="<?php echo filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING ); ?>" />
|
176 |
+
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr( isset( $post_array['wsal-cbid'] ) ? $post_array['wsal-cbid'] : '0' ); ?>" />
|
177 |
<?php do_action( 'wsal_auditlog_before_view', $this->GetListView() ); ?>
|
178 |
<?php $this->GetListView()->display(); ?>
|
179 |
<?php do_action( 'wsal_auditlog_after_view', $this->GetListView() ); ?>
|
180 |
</div>
|
181 |
</form>
|
182 |
|
183 |
+
<?php
|
184 |
+
if ( class_exists( 'WSAL_SearchExtension' ) &&
|
185 |
+
( isset( $post_array['Filters'] ) || ( isset( $post_array['s'] ) && trim( $post_array['s'] ) ) ) ) :
|
186 |
+
?>
|
187 |
<script type="text/javascript">
|
188 |
jQuery(document).ready( function() {
|
189 |
WsalAuditLogInit(
|
190 |
+
<?php
|
191 |
+
echo json_encode(
|
192 |
+
array(
|
193 |
+
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
194 |
+
'tr8n' => array(
|
195 |
+
'numofitems' => __( 'Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log' ),
|
196 |
+
'searchback' => __( 'All Sites', 'wp-security-audit-log' ),
|
197 |
+
'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
|
198 |
+
),
|
199 |
+
'autorefresh' => array(
|
200 |
+
'enabled' => false,
|
201 |
+
'token' => (int) $occ->Count(),
|
202 |
+
),
|
203 |
+
)
|
204 |
+
);
|
205 |
?>
|
206 |
);
|
207 |
} );
|
210 |
<script type="text/javascript">
|
211 |
jQuery(document).ready( function() {
|
212 |
WsalAuditLogInit(
|
213 |
+
<?php
|
214 |
+
echo json_encode(
|
215 |
+
array(
|
216 |
+
'ajaxurl' => admin_url( 'admin-ajax.php' ),
|
217 |
+
'tr8n' => array(
|
218 |
+
'numofitems' => __( 'Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log' ),
|
219 |
+
'searchback' => __( 'All Sites', 'wp-security-audit-log' ),
|
220 |
+
'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
|
221 |
+
),
|
222 |
+
'autorefresh' => array(
|
223 |
+
'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
|
224 |
+
'token' => (int) $occ->Count(),
|
225 |
+
),
|
226 |
+
)
|
227 |
+
);
|
228 |
?>
|
229 |
);
|
230 |
} );
|
231 |
</script>
|
232 |
+
<?php
|
233 |
+
endif;
|
234 |
}
|
235 |
|
236 |
+
public function AjaxInspector() {
|
237 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
238 |
+
die( 'Access Denied.' );
|
|
|
239 |
}
|
240 |
+
|
241 |
+
// Filter $_GET array for security.
|
242 |
+
$get_array = filter_input_array( INPUT_GET );
|
243 |
+
|
244 |
+
if ( ! isset( $get_array['occurrence'] ) ) {
|
245 |
+
die( 'Occurrence parameter expected.' );
|
246 |
}
|
247 |
$occ = new WSAL_Models_Occurrence();
|
248 |
+
$occ->Load( 'id = %d', array( (int) $get_array['occurrence'] ) );
|
249 |
|
250 |
echo '<!DOCTYPE html><html><head>';
|
251 |
+
echo '<link rel="stylesheet" id="open-sans-css" href="' . esc_url( $this->_plugin->GetBaseUrl() ) . '/css/nice_r.css" type="text/css" media="all">';
|
252 |
+
echo '<script type="text/javascript" src="' . esc_url( $this->_plugin->GetBaseUrl() ) . '/js/nice_r.js"></script>';
|
253 |
echo '<style type="text/css">';
|
254 |
echo 'html, body { margin: 0; padding: 0; }';
|
255 |
echo '.nice_r { position: absolute; padding: 8px; }';
|
256 |
echo '.nice_r a { overflow: visible; }';
|
257 |
echo '</style>';
|
258 |
echo '</head><body>';
|
259 |
+
$nicer = new WSAL_Nicer( $occ->GetMetaArray() );
|
260 |
$nicer->render();
|
261 |
echo '</body></html>';
|
262 |
die;
|
263 |
}
|
264 |
|
265 |
+
public function AjaxRefresh() {
|
266 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
267 |
+
die( 'Access Denied.' );
|
|
|
268 |
}
|
269 |
+
|
270 |
+
// Filter $_POST array for security.
|
271 |
+
$post_array = filter_input_array( INPUT_POST );
|
272 |
+
|
273 |
+
if ( ! isset( $post_array['logcount'] ) ) {
|
274 |
+
die( 'Log count parameter expected.' );
|
275 |
}
|
276 |
|
277 |
+
$old = (int) $post_array['logcount'];
|
278 |
$max = 40; // 40*500msec = 20sec
|
279 |
|
280 |
$is_archive = false;
|
281 |
+
if ( $this->_plugin->settings->IsArchivingEnabled() ) {
|
282 |
+
$selected_db = get_transient( 'wsal_wp_selected_db' );
|
283 |
+
if ( $selected_db && 'archive' == $selected_db ) {
|
284 |
$is_archive = true;
|
285 |
}
|
286 |
}
|
288 |
do {
|
289 |
$occ = new WSAL_Models_Occurrence();
|
290 |
$new = $occ->Count();
|
291 |
+
usleep( 500000 ); // 500msec
|
292 |
+
} while ( ($old == $new) && (--$max > 0) );
|
293 |
|
294 |
+
if ( $is_archive ) {
|
295 |
echo 'false';
|
296 |
} else {
|
297 |
+
echo $old == $new ? 'false' : esc_html( $new );
|
298 |
}
|
299 |
die;
|
300 |
}
|
301 |
|
302 |
+
public function AjaxSetIpp() {
|
303 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
304 |
+
die( 'Access Denied.' );
|
|
|
305 |
}
|
306 |
+
|
307 |
+
// Filter $_POST array for security.
|
308 |
+
$post_array = filter_input_array( INPUT_POST );
|
309 |
+
|
310 |
+
if ( ! isset( $post_array['count'] ) ) {
|
311 |
+
die( 'Count parameter expected.' );
|
312 |
}
|
313 |
+
$this->_plugin->settings->SetViewPerPage( (int) $post_array['count'] );
|
314 |
die;
|
315 |
}
|
316 |
|
317 |
+
public function AjaxSearchSite() {
|
318 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
319 |
+
die( 'Access Denied.' );
|
|
|
320 |
}
|
321 |
+
|
322 |
+
// Filter $_POST array for security.
|
323 |
+
$post_array = filter_input_array( INPUT_POST );
|
324 |
+
|
325 |
+
if ( ! isset( $post_array['search'] ) ) {
|
326 |
+
die( 'Search parameter expected.' );
|
327 |
}
|
328 |
$grp1 = array();
|
329 |
$grp2 = array();
|
330 |
|
331 |
+
$search = $post_array['search'];
|
332 |
|
333 |
+
foreach ( $this->GetListView()->get_sites() as $site ) {
|
334 |
+
if ( stripos( $site->blogname, $search ) !== false ) {
|
335 |
$grp1[] = $site;
|
336 |
+
} elseif ( stripos( $site->domain, $search ) !== false ) {
|
337 |
$grp2[] = $site;
|
338 |
}
|
339 |
}
|
340 |
+
die( json_encode( array_slice( $grp1 + $grp2, 0, 7 ) ) );
|
341 |
}
|
342 |
|
343 |
+
public function AjaxSwitchDB() {
|
344 |
+
// Filter $_POST array for security.
|
345 |
+
$post_array = filter_input_array( INPUT_POST );
|
346 |
+
|
347 |
+
if ( isset( $post_array['selected_db'] ) ) {
|
348 |
+
set_transient( 'wsal_wp_selected_db', $post_array['selected_db'], HOUR_IN_SECONDS );
|
349 |
}
|
350 |
}
|
351 |
|
352 |
+
public function Header() {
|
|
|
353 |
add_thickbox();
|
354 |
+
wp_enqueue_style( 'darktooltip', $this->_plugin->GetBaseUrl() . '/css/darktooltip.css', array(), '' );
|
355 |
wp_enqueue_style(
|
356 |
'auditlog',
|
357 |
$this->_plugin->GetBaseUrl() . '/css/auditlog.css',
|
358 |
array(),
|
359 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/auditlog.css' )
|
360 |
);
|
361 |
}
|
362 |
|
363 |
+
public function Footer() {
|
364 |
+
wp_enqueue_script( 'jquery' );
|
365 |
+
wp_enqueue_script( 'darktooltip', $this->_plugin->GetBaseUrl() . '/js/jquery.darktooltip.js', array( 'jquery' ), '' );
|
366 |
+
wp_enqueue_script( 'suggest' );
|
|
|
367 |
wp_enqueue_script(
|
368 |
'auditlog',
|
369 |
$this->_plugin->GetBaseUrl() . '/js/auditlog.js',
|
370 |
array(),
|
371 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/auditlog.js' )
|
372 |
);
|
373 |
}
|
374 |
}
|
classes/Views/EmailNotifications.php
CHANGED
@@ -1,65 +1,175 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Email Notifications Add-On promo Page.
|
6 |
* Used only if the plugin is not activated.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Views_EmailNotifications extends WSAL_AbstractView
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
<p>
|
56 |
-
<span class="description">
|
57 |
-
<strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
|
58 |
-
</span>
|
59 |
-
</p>
|
60 |
-
<?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
|
61 |
-
<a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
|
62 |
-
</div>
|
63 |
-
<?php
|
64 |
-
}
|
65 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Email Notifications Page
|
4 |
+
*
|
5 |
+
* WSAL email notifications page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Email Notifications Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Views_EmailNotifications extends WSAL_AbstractView {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Method: Get View Title.
|
26 |
+
*/
|
27 |
+
public function GetTitle() {
|
28 |
+
return __( 'Email Notifications Add-On', 'wp-security-audit-log' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Get View Icon.
|
33 |
+
*/
|
34 |
+
public function GetIcon() {
|
35 |
+
return 'dashicons-external';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Method: Get View Name.
|
40 |
+
*/
|
41 |
+
public function GetName() {
|
42 |
+
return __( 'Email Notifications ⇪', 'wp-security-audit-log' );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Get View Weight.
|
47 |
+
*/
|
48 |
+
public function GetWeight() {
|
49 |
+
return 9;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Method: Get View Header.
|
54 |
+
*/
|
55 |
+
public function Header() {
|
56 |
+
// Extension Page CSS.
|
57 |
+
wp_enqueue_style(
|
58 |
+
'extensions',
|
59 |
+
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
60 |
+
array(),
|
61 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/extensions.css' )
|
62 |
+
);
|
63 |
+
|
64 |
+
// Swipebox CSS.
|
65 |
+
wp_enqueue_style(
|
66 |
+
'wsal-swipebox-css',
|
67 |
+
$this->_plugin->GetBaseUrl() . '/css/swipebox.min.css',
|
68 |
+
array(),
|
69 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/swipebox.min.css' )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Method: Get View Footer.
|
75 |
+
*/
|
76 |
+
public function Footer() {
|
77 |
+
// jQuery.
|
78 |
+
wp_enqueue_script( 'jquery' );
|
79 |
+
|
80 |
+
// Swipebox JS.
|
81 |
+
wp_register_script(
|
82 |
+
'wsal-swipebox-js',
|
83 |
+
$this->_plugin->GetBaseUrl() . '/js/jquery.swipebox.min.js',
|
84 |
+
array( 'jquery' ),
|
85 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/jquery.swipebox.min.js' )
|
86 |
+
);
|
87 |
+
wp_enqueue_script( 'wsal-swipebox-js' );
|
88 |
+
|
89 |
+
// Extensions JS.
|
90 |
+
wp_register_script(
|
91 |
+
'wsal-extensions-js',
|
92 |
+
$this->_plugin->GetBaseUrl() . '/js/extensions.js',
|
93 |
+
array( 'wsal-swipebox-js' ),
|
94 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/extensions.js' )
|
95 |
+
);
|
96 |
+
wp_enqueue_script( 'wsal-extensions-js' );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Method: Get View Render.
|
101 |
+
*/
|
102 |
+
public function Render() {
|
103 |
+
?>
|
104 |
+
<div class="wrap-advertising-page-single">
|
105 |
+
<div class="wsal-row">
|
106 |
+
<div class="wsal-col">
|
107 |
+
<div class="icon" style='background-image:url("<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/envelope.jpg");'></div>
|
108 |
+
</div>
|
109 |
+
<!-- /.wsal-col -->
|
110 |
+
|
111 |
+
<div class="wsal-col">
|
112 |
+
<h3><?php esc_html_e( 'Email Notifications', 'wp-security-audit-log' ); ?></h3>
|
113 |
+
<p>
|
114 |
+
<?php esc_html_e( 'Upgrade to Premium to:', 'wp-security-audit-log' ); ?>
|
115 |
+
</p>
|
116 |
+
<p>
|
117 |
+
<ul class="wsal-features-list">
|
118 |
+
<li><?php esc_html_e( 'Configure email notifications to be instantly alerted of important changes,', 'wp-security-audit-log' ); ?></li>
|
119 |
+
<li><?php esc_html_e( 'Configure notifications for when users login, change content, install a plugin or do any other change,', 'wp-security-audit-log' ); ?></li>
|
120 |
+
<li><?php esc_html_e( 'Configure security email notifications,', 'wp-security-audit-log' ); ?></li>
|
121 |
+
<li><?php esc_html_e( 'Configure email notifications via a user friendly wizard,', 'wp-security-audit-log' ); ?></li>
|
122 |
+
<li><?php esc_html_e( 'Edit and create your own templates for email notifications,', 'wp-security-audit-log' ); ?></li>
|
123 |
+
<li><?php esc_html_e( '& more.', 'wp-security-audit-log' ); ?></li>
|
124 |
+
</ul>
|
125 |
+
</p>
|
126 |
+
<?php
|
127 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
128 |
+
$more_info = add_query_arg(
|
129 |
+
array(
|
130 |
+
'utm_source' => 'plugin',
|
131 |
+
'utm_medium' => 'page',
|
132 |
+
'utm_content' => 'email+more+info',
|
133 |
+
'utm_campaign' => 'upgrade+premium',
|
134 |
+
),
|
135 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
136 |
+
);
|
137 |
+
?>
|
138 |
+
<p>
|
139 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $buy_now ); ?>"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
|
140 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
141 |
+
</p>
|
142 |
+
</div>
|
143 |
+
<!-- /.wsal-col -->
|
144 |
+
</div>
|
145 |
+
<!-- /.wsal-row -->
|
146 |
+
|
147 |
+
<div class="wsal-row">
|
148 |
+
<div class="wsal-col">
|
149 |
+
<h3><?php esc_html_e( 'Screenshots', 'wp-security-audit-log' ); ?></h3>
|
150 |
|
151 |
+
<p>
|
152 |
+
<ul class="wsal-features-list">
|
153 |
+
<li>
|
154 |
+
<?php esc_html_e( 'Use the trigger builder to configure any type of email notification so you are instantly alerted of important changes on your WordPress.', 'wp-security-audit-log' ); ?><br />
|
155 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Use the trigger builder to configure any type of email notification so you are instantly alerted of important changes on your WordPress.', 'wp-security-audit-log' ); ?>"
|
156 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/email-notifications/email_notifications.png">
|
157 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/email-notifications/email_notifications.png">
|
158 |
+
</a>
|
159 |
+
</li>
|
160 |
+
<li>
|
161 |
+
<?php esc_html_e( 'Use the wizard to easily get started and quickly configure basic email notifications.', 'wp-security-audit-log' ); ?><br />
|
162 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Use the wizard to easily get started and quickly configure basic email notifications.', 'wp-security-audit-log' ); ?>"
|
163 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/email-notifications/email_notifications_wizard.png">
|
164 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/email-notifications/email_notifications_wizard.png">
|
165 |
+
</a>
|
166 |
+
</li>
|
167 |
+
</ul>
|
168 |
+
</p>
|
169 |
+
</div>
|
170 |
+
</div>
|
171 |
+
<!-- /.wsal-row -->
|
172 |
+
</div>
|
173 |
+
<?php
|
174 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
classes/Views/Extensions.php
DELETED
@@ -1,137 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package Wsal
|
4 |
-
*
|
5 |
-
* All Add-Ons promo Page.
|
6 |
-
* Used only if no plugins are activated.
|
7 |
-
*/
|
8 |
-
class WSAL_Views_Extensions extends WSAL_AbstractView
|
9 |
-
{
|
10 |
-
|
11 |
-
public function GetTitle()
|
12 |
-
{
|
13 |
-
return __('WP Security Audit Log Add-Ons', 'wp-security-audit-log');
|
14 |
-
}
|
15 |
-
|
16 |
-
public function GetIcon()
|
17 |
-
{
|
18 |
-
return 'dashicons-external';
|
19 |
-
}
|
20 |
-
|
21 |
-
public function GetName()
|
22 |
-
{
|
23 |
-
return __(' Add Functionality', 'wp-security-audit-log');
|
24 |
-
}
|
25 |
-
|
26 |
-
public function GetWeight()
|
27 |
-
{
|
28 |
-
return 3.5;
|
29 |
-
}
|
30 |
-
|
31 |
-
public function Header()
|
32 |
-
{
|
33 |
-
wp_enqueue_style(
|
34 |
-
'extensions',
|
35 |
-
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
36 |
-
array(),
|
37 |
-
filemtime($this->_plugin->GetBaseDir() . '/css/extensions.css')
|
38 |
-
);
|
39 |
-
}
|
40 |
-
|
41 |
-
public function Render()
|
42 |
-
{
|
43 |
-
?>
|
44 |
-
<p><?php _e('The below add-ons allow you to extend the functionality of WP Security Audit Log plugin and enable you to get more benefits out of the WordPress security audit, such as configurable email alerts, ability to search using free text based searches & filters, and generate user activity reports to meet regulatory compliance requirements.', 'wp-security-audit-log'); ?>
|
45 |
-
</p>
|
46 |
-
<div class="wrap-advertising-page">
|
47 |
-
<div class="extension all">
|
48 |
-
<?php $link = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
|
49 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>">
|
50 |
-
<h3><?php _e('All Add-Ons Bundle', 'wp-security-audit-log'); ?></h3>
|
51 |
-
</a>
|
52 |
-
<p><?php _e('Benefit from a 60% discount when you purchase all the add-ons as a single bundle.', 'wp-security-audit-log'); ?>
|
53 |
-
</p>
|
54 |
-
<p>
|
55 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this Bundle', 'wp-security-audit-log'); ?>
|
56 |
-
</a>
|
57 |
-
</p>
|
58 |
-
</div>
|
59 |
-
<?php if (!class_exists('WSAL_User_Management_Plugin')) { ?>
|
60 |
-
<div class="extension user-managment">
|
61 |
-
<?php $link = 'https://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=logins'; ?>
|
62 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>">
|
63 |
-
<h3><?php _e('Users Logins and Management', 'wp-security-audit-log'); ?></h3>
|
64 |
-
</a>
|
65 |
-
<p><?php _e('See who is logged in to your WordPress and manage user sessions and logins.', 'wp-security-audit-log'); ?>
|
66 |
-
|
67 |
-
</p>
|
68 |
-
<p>
|
69 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
|
70 |
-
</a>
|
71 |
-
</p>
|
72 |
-
</div>
|
73 |
-
<?php } ?>
|
74 |
-
<?php if (!class_exists('WSAL_NP_Plugin')) { ?>
|
75 |
-
<div class="extension email-notifications">
|
76 |
-
<?php $link = 'https://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=notifications'; ?>
|
77 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>">
|
78 |
-
<h3><?php _e('Email Notifications', 'wp-security-audit-log'); ?></h3>
|
79 |
-
</a>
|
80 |
-
<p><?php _e('Get notified instantly via email when important changes are made on your WordPress!', 'wp-security-audit-log'); ?>
|
81 |
-
|
82 |
-
</p>
|
83 |
-
<p>
|
84 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
|
85 |
-
</a>
|
86 |
-
</p>
|
87 |
-
</div>
|
88 |
-
<?php } ?>
|
89 |
-
<?php if (!class_exists('WSAL_Rep_Plugin')) { ?>
|
90 |
-
<div class="extension reports">
|
91 |
-
<?php $link = 'https://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=reports'; ?>
|
92 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>">
|
93 |
-
<h3><?php _e('Reports', 'wp-security-audit-log'); ?></h3>
|
94 |
-
</a>
|
95 |
-
<p><?php _e('Generate any type of user,site and activity report to keep track of user productivity and to meet regulatory compliance requirements.', 'wp-security-audit-log'); ?>
|
96 |
-
|
97 |
-
</p>
|
98 |
-
<p>
|
99 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
|
100 |
-
</a>
|
101 |
-
</p>
|
102 |
-
</div>
|
103 |
-
<?php } ?>
|
104 |
-
<?php if (!class_exists('WSAL_SearchExtension')) { ?>
|
105 |
-
<div class="extension search-ext">
|
106 |
-
<?php $link = 'https://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=search'; ?>
|
107 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>">
|
108 |
-
<h3><?php _e('Search', 'wp-security-audit-log'); ?></h3>
|
109 |
-
</a>
|
110 |
-
<p><?php _e('Do free-text based searches for specific activity in the WordPress audit trail. You can also use filters to fine-tune your searches.', 'wp-security-audit-log'); ?>
|
111 |
-
|
112 |
-
</p>
|
113 |
-
<p>
|
114 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
|
115 |
-
</a>
|
116 |
-
</p>
|
117 |
-
</div>
|
118 |
-
<?php } ?>
|
119 |
-
<?php if (!class_exists('WSAL_Ext_Plugin')) { ?>
|
120 |
-
<div class="extension external-db">
|
121 |
-
<?php $link = 'https://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=externaldb'; ?>
|
122 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>">
|
123 |
-
<h3><?php _e('External DB', 'wp-security-audit-log'); ?></h3>
|
124 |
-
</a>
|
125 |
-
<p><?php _e('Store the WordPress audit trial in an external database for a more secure and faster WordPress website.', 'wp-security-audit-log'); ?>
|
126 |
-
|
127 |
-
</p>
|
128 |
-
<p>
|
129 |
-
<a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
|
130 |
-
</a>
|
131 |
-
</p>
|
132 |
-
</div>
|
133 |
-
<?php } ?>
|
134 |
-
</div>
|
135 |
-
<?php
|
136 |
-
}
|
137 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Views/ExternalDB.php
CHANGED
@@ -1,65 +1,174 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* External DB Add-On promo Page.
|
6 |
* Used only if the plugin is not activated.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Views_ExternalDB extends WSAL_AbstractView
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
<p>
|
56 |
-
<span class="description">
|
57 |
-
<strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
|
58 |
-
</span>
|
59 |
-
</p>
|
60 |
-
<?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
|
61 |
-
<a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
|
62 |
-
</div>
|
63 |
-
<?php
|
64 |
-
}
|
65 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: External DB Page
|
4 |
+
*
|
5 |
+
* WSAL external db page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* External DB Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Views_ExternalDB extends WSAL_AbstractView {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Method: Get View Title.
|
26 |
+
*/
|
27 |
+
public function GetTitle() {
|
28 |
+
return __( 'External DB Add-On', 'wp-security-audit-log' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Get View Icon.
|
33 |
+
*/
|
34 |
+
public function GetIcon() {
|
35 |
+
return 'dashicons-external';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Method: Get View Name.
|
40 |
+
*/
|
41 |
+
public function GetName() {
|
42 |
+
return __( 'DB & Integrations ⇪', 'wp-security-audit-log' );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Get View Weight.
|
47 |
+
*/
|
48 |
+
public function GetWeight() {
|
49 |
+
return 10;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Method: Get View Header.
|
54 |
+
*/
|
55 |
+
public function Header() {
|
56 |
+
// Extension Page CSS.
|
57 |
+
wp_enqueue_style(
|
58 |
+
'extensions',
|
59 |
+
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
60 |
+
array(),
|
61 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/extensions.css' )
|
62 |
+
);
|
63 |
+
|
64 |
+
// Swipebox CSS.
|
65 |
+
wp_enqueue_style(
|
66 |
+
'wsal-swipebox-css',
|
67 |
+
$this->_plugin->GetBaseUrl() . '/css/swipebox.min.css',
|
68 |
+
array(),
|
69 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/swipebox.min.css' )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Method: Get View Footer.
|
75 |
+
*/
|
76 |
+
public function Footer() {
|
77 |
+
// jQuery.
|
78 |
+
wp_enqueue_script( 'jquery' );
|
79 |
+
|
80 |
+
// Swipebox JS.
|
81 |
+
wp_register_script(
|
82 |
+
'wsal-swipebox-js',
|
83 |
+
$this->_plugin->GetBaseUrl() . '/js/jquery.swipebox.min.js',
|
84 |
+
array( 'jquery' ),
|
85 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/jquery.swipebox.min.js' )
|
86 |
+
);
|
87 |
+
wp_enqueue_script( 'wsal-swipebox-js' );
|
88 |
+
|
89 |
+
// Extensions JS.
|
90 |
+
wp_register_script(
|
91 |
+
'wsal-extensions-js',
|
92 |
+
$this->_plugin->GetBaseUrl() . '/js/extensions.js',
|
93 |
+
array( 'wsal-swipebox-js' ),
|
94 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/extensions.js' )
|
95 |
+
);
|
96 |
+
wp_enqueue_script( 'wsal-extensions-js' );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Method: Get View.
|
101 |
+
*/
|
102 |
+
public function Render() {
|
103 |
+
?>
|
104 |
+
<div class="wrap-advertising-page-single">
|
105 |
+
<div class="wsal-row">
|
106 |
+
<div class="wsal-col">
|
107 |
+
<div class="icon" style='background-image:url("<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/database.jpg");'></div>
|
108 |
+
</div>
|
109 |
+
<!-- /.wsal-col -->
|
110 |
+
|
111 |
+
<div class="wsal-col">
|
112 |
+
<h3><?php esc_html_e( 'External DB', 'wp-security-audit-log' ); ?></h3>
|
113 |
+
<p>
|
114 |
+
<?php esc_html_e( 'Upgrade to Premium to:', 'wp-security-audit-log' ); ?>
|
115 |
+
</p>
|
116 |
+
<p>
|
117 |
+
<ul class="wsal-features-list">
|
118 |
+
<li><?php esc_html_e( 'Move the audit log to an external database for improved security & performance,', 'wp-security-audit-log' ); ?></li>
|
119 |
+
<li><?php esc_html_e( 'Centralize the audit log in your centralized logging system,', 'wp-security-audit-log' ); ?></li>
|
120 |
+
<li><?php esc_html_e( 'Mirror the audit trail to Syslog, Papertrail etc,', 'wp-security-audit-log' ); ?></li>
|
121 |
+
<li><?php esc_html_e( 'Configure archiving rules to archive old alerts in an archiving database,', 'wp-security-audit-log' ); ?></li>
|
122 |
+
<li><?php esc_html_e( '& more.', 'wp-security-audit-log' ); ?></li>
|
123 |
+
</ul>
|
124 |
+
</p>
|
125 |
+
<?php
|
126 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
127 |
+
$more_info = add_query_arg(
|
128 |
+
array(
|
129 |
+
'utm_source' => 'plugin',
|
130 |
+
'utm_medium' => 'page',
|
131 |
+
'utm_content' => 'db+more+info',
|
132 |
+
'utm_campaign' => 'upgrade+premium',
|
133 |
+
),
|
134 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
135 |
+
);
|
136 |
+
?>
|
137 |
+
<p>
|
138 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $buy_now ); ?>"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
|
139 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
140 |
+
</p>
|
141 |
+
</div>
|
142 |
+
<!-- /.wsal-col -->
|
143 |
+
</div>
|
144 |
+
<!-- /.wsal-row -->
|
145 |
+
|
146 |
+
<div class="wsal-row">
|
147 |
+
<div class="wsal-col">
|
148 |
+
<h3><?php esc_html_e( 'Screenshots', 'wp-security-audit-log' ); ?></h3>
|
149 |
|
150 |
+
<p>
|
151 |
+
<ul class="wsal-features-list">
|
152 |
+
<li>
|
153 |
+
<?php esc_html_e( 'Configure an external database so the WordPress audit trail is stored on it instead of the WordPress database.', 'wp-security-audit-log' ); ?><br />
|
154 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Configure an external database so the WordPress audit trail is stored on it instead of the WordPress database.', 'wp-security-audit-log' ); ?>"
|
155 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/external-db/external_database_1.png">
|
156 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/external-db/external_database_1.png">
|
157 |
+
</a>
|
158 |
+
</li>
|
159 |
+
<li>
|
160 |
+
<?php esc_html_e( 'Configure mirroring to keep a secondary copy of the WordPress audit trail on Syslog, Papertrail etc.', 'wp-security-audit-log' ); ?><br />
|
161 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Configure mirroring to keep a secondary copy of the WordPress audit trail on Syslog, Papertrail etc.', 'wp-security-audit-log' ); ?>"
|
162 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/external-db/extermal_database_mirroring_options.png">
|
163 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/external-db/extermal_database_mirroring_options.png">
|
164 |
+
</a>
|
165 |
+
</li>
|
166 |
+
</ul>
|
167 |
+
</p>
|
168 |
+
</div>
|
169 |
+
</div>
|
170 |
+
<!-- /.wsal-row -->
|
171 |
+
</div>
|
172 |
+
<?php
|
173 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
}
|
classes/Views/Help.php
CHANGED
@@ -1,89 +1,192 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Help Page.
|
6 |
-
*
|
|
|
7 |
* - Plugin Documentation
|
|
|
|
|
8 |
*/
|
9 |
-
class WSAL_Views_Help extends WSAL_AbstractView
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
<a class="button" href="https://www.wpsecurityauditlog.com/documentation/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php
|
58 |
-
|
59 |
-
<a class="button" href="
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
</div>
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Help
|
4 |
+
*
|
5 |
+
* WSAL help page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Help Page.
|
18 |
+
*
|
19 |
+
* - Plugin Support
|
20 |
* - Plugin Documentation
|
21 |
+
*
|
22 |
+
* @package Wsal
|
23 |
*/
|
24 |
+
class WSAL_Views_Help extends WSAL_AbstractView {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Method: Get View Title.
|
28 |
+
*/
|
29 |
+
public function GetTitle() {
|
30 |
+
return __( 'Help', 'wp-security-audit-log' );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Method: Get View Icon.
|
35 |
+
*/
|
36 |
+
public function GetIcon() {
|
37 |
+
return 'dashicons-sos';
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Method: Get View Name.
|
42 |
+
*/
|
43 |
+
public function GetName() {
|
44 |
+
return __( 'Help', 'wp-security-audit-log' );
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Method: Get View Weight.
|
49 |
+
*/
|
50 |
+
public function GetWeight() {
|
51 |
+
return 14;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Method: Get View Header.
|
56 |
+
*/
|
57 |
+
public function Header() {
|
58 |
+
wp_enqueue_style(
|
59 |
+
'extensions',
|
60 |
+
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
61 |
+
array(),
|
62 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/extensions.css' )
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Method: Get View.
|
68 |
+
*/
|
69 |
+
public function Render() {
|
70 |
+
?>
|
71 |
+
<div class="metabox-holder" style="position: relative;">
|
72 |
+
<div class="postbox">
|
73 |
+
<div class="inside wsal-block">
|
74 |
+
<div class="activity-block">
|
75 |
+
<h2><?php esc_html_e( 'Getting Started', 'wp-security-audit-log' ); ?></h2>
|
76 |
+
<p>
|
77 |
+
<?php esc_html_e( 'Getting started with WP Security Audit Log is really easy; once the plugin is installed it will automatically keep a log of everything that is happening on your website and you do not need to do anything. Watch the video below for a quick overview of the plugin.', 'wp-security-audit-log' ); ?>
|
78 |
+
</p>
|
79 |
+
<p>
|
80 |
+
<iframe class="wsal-youtube-embed" width="560" height="315" src="https://www.youtube.com/embed/1nopATCS-CQ?rel=0" frameborder="0" allowfullscreen></iframe>
|
81 |
+
</p>
|
82 |
+
</div>
|
83 |
+
<!-- /.activity-block -->
|
84 |
+
|
85 |
+
<div class="activity-block">
|
86 |
+
<h2><?php esc_html_e( 'Plugin Support', 'wp-security-audit-log' ); ?></h2>
|
87 |
+
<p>
|
88 |
+
<?php esc_html_e( 'Have you encountered or noticed any issues while using WP Security Audit Log plugin?', 'wp-security-audit-log' ); ?>
|
89 |
+
<?php esc_html_e( 'Or you want to report something to us? Click any of the options below to post on the plugin\'s forum or contact our support directly.', 'wp-security-audit-log' ); ?>
|
90 |
+
</p><p>
|
91 |
+
<a class="button" href="https://wordpress.org/support/plugin/wp-security-audit-log" target="_blank"><?php esc_html_e( 'Free Support Forum', 'wp-security-audit-log' ); ?></a>
|
92 |
+
|
93 |
+
<a class="button" href="http://www.wpsecurityauditlog.com/contact/" target="_blank"><?php esc_html_e( 'Free Support Email', 'wp-security-audit-log' ); ?></a>
|
94 |
+
</p>
|
95 |
+
</div>
|
96 |
+
<!-- /.activity-block -->
|
97 |
|
98 |
+
<div class="activity-block">
|
99 |
+
<h2><?php esc_html_e( 'Plugin Documentation', 'wp-security-audit-log' ); ?></h2>
|
100 |
+
<p>
|
101 |
+
<?php esc_html_e( 'For more technical information about the WP Security Audit Log plugin please visit the plugin’s knowledge base.', 'wp-security-audit-log' ); ?>
|
102 |
+
<?php esc_html_e( 'Refer to the list of WordPress security alerts for a complete list of Alerts and IDs that the plugin uses to keep a log of all the changes in the WordPress audit log.', 'wp-security-audit-log' ); ?>
|
103 |
+
</p><p>
|
104 |
+
<a class="button" href="http://www.wpsecurityauditlog.com/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php esc_html_e( 'Plugin Website', 'wp-security-audit-log' ); ?></a>
|
105 |
+
|
106 |
+
<a class="button" href="https://www.wpsecurityauditlog.com/support-documentation/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php esc_html_e( 'Knowledge Base', 'wp-security-audit-log' ); ?></a>
|
107 |
+
|
108 |
+
<a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php esc_html_e( 'List of WordPress Security Alerts', 'wp-security-audit-log' ); ?></a>
|
109 |
+
</p>
|
110 |
+
</div>
|
111 |
+
<!-- /.activity-block -->
|
|
|
112 |
|
113 |
+
<div class="activity-block">
|
114 |
+
<h2><?php esc_html_e( 'Rate WP Security Audit Log', 'wp-security-audit-log' ); ?></h2>
|
115 |
+
<p>
|
116 |
+
<?php esc_html_e( 'We work really hard to deliver a plugin that enables you to keep a record of all the changes that are happening on your WordPress.', 'wp-security-audit-log' ); ?>
|
117 |
+
<?php esc_html_e( 'It takes thousands of man-hours every year and endless amount of dedication to research, develop and maintain the free edition of WP Security Audit Log.', 'wp-security-audit-log' ); ?>
|
118 |
+
<?php esc_html_e( 'Therefore if you like what you see, and find WP Security Audit Log useful we ask you nothing more than to please rate our plugin.', 'wp-security-audit-log' ); ?>
|
119 |
+
<?php esc_html_e( 'We appreciate every star!', 'wp-security-audit-log' ); ?>
|
120 |
+
</p>
|
121 |
+
<p>
|
122 |
+
<a class="rating-link" href="https://en-gb.wordpress.org/plugins/wp-security-audit-log/#reviews" target="_blank">
|
123 |
+
<span class="dashicons dashicons-star-filled"></span>
|
124 |
+
<span class="dashicons dashicons-star-filled"></span>
|
125 |
+
<span class="dashicons dashicons-star-filled"></span>
|
126 |
+
<span class="dashicons dashicons-star-filled"></span>
|
127 |
+
<span class="dashicons dashicons-star-filled"></span>
|
128 |
+
</a>
|
129 |
+
<a class="button" href="https://en-gb.wordpress.org/plugins/wp-security-audit-log/#reviews" target="_blank"><?php esc_html_e( 'Rate Plugin', 'wp-security-audit-log' ); ?></a>
|
130 |
+
</p>
|
131 |
+
</div>
|
132 |
+
<!-- /.activity-block -->
|
133 |
+
</div>
|
134 |
+
</div>
|
135 |
|
136 |
+
<?php
|
137 |
+
$is_current_view = $this->_plugin->views->GetActiveView() == $this;
|
138 |
+
// Check if any of the extensions is activated.
|
139 |
+
if ( wsal_freemius()->is_not_paying() ) :
|
140 |
+
if ( current_user_can( 'manage_options' ) && $is_current_view ) :
|
141 |
+
?>
|
142 |
+
<div class="wsal-sidebar-advert">
|
143 |
+
<div class="postbox">
|
144 |
+
<h3 class="hndl"><span><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></span></h3>
|
145 |
+
<div class="inside">
|
146 |
+
<ul class="wsal-features-list">
|
147 |
+
<li>
|
148 |
+
<?php esc_html_e( 'See who is logged in', 'wp-security-audit-log' ); ?><br />
|
149 |
+
<?php esc_html_e( 'And remotely terminate sessions', 'wp-security-audit-log' ); ?>
|
150 |
+
</li>
|
151 |
+
<li>
|
152 |
+
<?php esc_html_e( 'Generate reports', 'wp-security-audit-log' ); ?><br />
|
153 |
+
<?php esc_html_e( 'Or configure automated email reports', 'wp-security-audit-log' ); ?>
|
154 |
+
</li>
|
155 |
+
<li>
|
156 |
+
<?php esc_html_e( 'Configure email notifications', 'wp-security-audit-log' ); ?><br />
|
157 |
+
<?php esc_html_e( 'Get instantly notified of important changes', 'wp-security-audit-log' ); ?>
|
158 |
+
</li>
|
159 |
+
<li>
|
160 |
+
<?php esc_html_e( 'Add Search', 'wp-security-audit-log' ); ?><br />
|
161 |
+
<?php esc_html_e( 'Easily track down suspicious behaviour', 'wp-security-audit-log' ); ?>
|
162 |
+
</li>
|
163 |
+
<li>
|
164 |
+
<?php esc_html_e( 'Integrate & Centralise', 'wp-security-audit-log' ); ?><br />
|
165 |
+
<?php esc_html_e( 'Export the logs to your centralised logging system', 'wp-security-audit-log' ); ?>
|
166 |
+
</li>
|
167 |
+
</ul>
|
168 |
+
<?php
|
169 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
170 |
+
$more_info = add_query_arg(
|
171 |
+
array(
|
172 |
+
'utm_source' => 'plugin',
|
173 |
+
'utm_medium' => 'page',
|
174 |
+
'utm_content' => 'update+more+info',
|
175 |
+
'utm_campaign' => 'upgrade+premium',
|
176 |
+
),
|
177 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
178 |
+
);
|
179 |
+
?>
|
180 |
+
<p>
|
181 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $buy_now ); ?>"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
|
182 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
183 |
+
</p>
|
184 |
+
</div>
|
185 |
+
</div>
|
186 |
+
</div>
|
187 |
+
<?php endif; ?>
|
188 |
+
<?php endif; ?>
|
189 |
+
</div>
|
190 |
+
<?php
|
191 |
+
}
|
192 |
}
|
classes/Views/Licensing.php
CHANGED
@@ -1,100 +1,163 @@
|
|
1 |
<?php
|
2 |
/**
|
|
|
|
|
|
|
|
|
3 |
* @package Wsal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
*
|
5 |
* Licensing Page for all the Add-Ons enabled.
|
|
|
|
|
6 |
*/
|
7 |
-
class WSAL_Views_Licensing extends WSAL_AbstractView
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
|
|
|
|
|
|
|
|
100 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Licensing
|
4 |
+
*
|
5 |
+
* WSAL licensing page.
|
6 |
+
*
|
7 |
* @package Wsal
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Exit if accessed directly.
|
11 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
12 |
+
exit;
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Class: Licensing View.
|
17 |
*
|
18 |
* Licensing Page for all the Add-Ons enabled.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Views_Licensing extends WSAL_AbstractView {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Method: Get View Title.
|
26 |
+
*/
|
27 |
+
public function GetTitle() {
|
28 |
+
return __( 'Licensing', 'wp-security-audit-log' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Get View Icon.
|
33 |
+
*/
|
34 |
+
public function GetIcon() {
|
35 |
+
return 'dashicons-cart';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Method: Get View Name.
|
40 |
+
*/
|
41 |
+
public function GetName() {
|
42 |
+
return __( 'Licensing', 'wp-security-audit-log' );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Get View Weight.
|
47 |
+
*/
|
48 |
+
public function GetWeight() {
|
49 |
+
return 13;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Check if the view is accessible.
|
54 |
+
*/
|
55 |
+
public function IsAccessible() {
|
56 |
+
return ! ! $this->_plugin->licensing->CountPlugins();
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Method: Save.
|
61 |
+
*/
|
62 |
+
protected function Save() {
|
63 |
+
// Clear licenses.
|
64 |
+
$this->_plugin->settings->ClearLicenses();
|
65 |
+
|
66 |
+
// Filter $_POST array for security.
|
67 |
+
$post_array = filter_input_array( INPUT_POST );
|
68 |
+
|
69 |
+
// Save and activate license.
|
70 |
+
if ( isset( $post_array['license'] ) ) {
|
71 |
+
foreach ( $post_array['license'] as $name => $key ) {
|
72 |
+
$this->_plugin->licensing->ActivateLicense( $name, $key );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Method: Get View.
|
79 |
+
*/
|
80 |
+
public function Render() {
|
81 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'edit' ) ) {
|
82 |
+
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
83 |
+
}
|
84 |
+
|
85 |
+
// Filter $_POST array for security.
|
86 |
+
$post_array = filter_input_array( INPUT_POST );
|
87 |
+
|
88 |
+
// Verify nonce for security.
|
89 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'wsal-licensing' ) ) {
|
90 |
+
wp_die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
91 |
+
}
|
92 |
|
93 |
+
if ( isset( $post_array['submit'] ) ) {
|
94 |
+
try {
|
95 |
+
$this->Save();
|
96 |
+
?><div class="updated"><p><?php esc_html_e( 'Settings have been saved.', 'wp-security-audit-log' ); ?></p></div>
|
97 |
+
<?php
|
98 |
+
} catch ( Exception $ex ) {
|
99 |
+
?>
|
100 |
+
<div class="error">
|
101 |
+
<p><?php esc_html_e( 'Error: ', 'wp-security-audit-log' ); ?><?php echo esc_html( $ex->getMessage() ); ?></p>
|
102 |
+
</div>
|
103 |
+
<?php
|
104 |
+
}
|
105 |
+
}
|
106 |
+
?>
|
107 |
+
<form id="audit-log-licensing" method="post">
|
108 |
+
<input type="hidden" name="page" value="<?php echo filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING ); ?>" />
|
109 |
+
<?php wp_nonce_field( 'wsal-licensing' ); ?>
|
110 |
+
<table class="wp-list-table widefat fixed">
|
111 |
+
<thead>
|
112 |
+
<tr>
|
113 |
+
<th><?php esc_html_e( 'Plugin', 'wp-security-audit-log' ); ?></th>
|
114 |
+
<th><?php esc_html_e( 'License', 'wp-security-audit-log' ); ?></th>
|
115 |
+
<th></th>
|
116 |
+
</tr>
|
117 |
+
</thead>
|
118 |
+
<tbody>
|
119 |
+
<?php $counter = 0; ?>
|
120 |
+
<?php foreach ( $this->_plugin->licensing->Plugins() as $name => $plugin ) : ?>
|
121 |
+
<?php $license_key = trim( $this->_plugin->settings->GetLicenseKey( $name ) ); ?>
|
122 |
+
<?php $license_status = trim( $this->_plugin->settings->GetLicenseStatus( $name ) ); ?>
|
123 |
+
<?php $license_errors = trim( $this->_plugin->settings->GetLicenseErrors( $name ) ); ?>
|
124 |
+
<tr class="<?php echo ( 0 === $counter++ % 2 ) ? 'alternate' : ''; ?>">
|
125 |
+
<td>
|
126 |
+
<a href="<?php echo esc_attr( $plugin['PluginData']['PluginURI'] ); ?>" target="_blank">
|
127 |
+
<?php echo esc_html( $plugin['PluginData']['Name'] ); ?>
|
128 |
+
</a><br/><small><b>
|
129 |
+
<?php esc_html_e( 'Version', 'wp-security-audit-log' ); ?>
|
130 |
+
<?php echo esc_html( $plugin['PluginData']['Version'] ); ?>
|
131 |
+
</b></small>
|
132 |
+
</td>
|
133 |
+
<td>
|
134 |
+
<input type="text" style="width: 100%; margin: 6px 0;"
|
135 |
+
name="license[<?php echo esc_attr( $name ); ?>]"
|
136 |
+
value="<?php echo esc_attr( $license_key ); ?>"/>
|
137 |
+
</td>
|
138 |
+
<td style="vertical-align: middle;">
|
139 |
+
<?php if ( $license_key ) : ?>
|
140 |
+
<?php if ( 'valid' === $license_status ) : ?>
|
141 |
+
<?php esc_html_e( 'Active', 'wp-security-audit-log' ); ?>
|
142 |
+
<?php else : ?>
|
143 |
+
<?php esc_html_e( 'Inactive', 'wp-security-audit-log' ); ?><br/>
|
144 |
+
<small><?php echo esc_html( $license_errors ); ?></small>
|
145 |
+
<?php endif; ?>
|
146 |
+
<?php endif; ?>
|
147 |
+
</td>
|
148 |
+
</tr>
|
149 |
+
<?php endforeach; ?>
|
150 |
+
</tbody>
|
151 |
+
<tfoot>
|
152 |
+
<tr>
|
153 |
+
<th><?php esc_html_e( 'Plugin', 'wp-security-audit-log' ); ?></th>
|
154 |
+
<th><?php esc_html_e( 'License', 'wp-security-audit-log' ); ?></th>
|
155 |
+
<th></th>
|
156 |
+
</tr>
|
157 |
+
</tfoot>
|
158 |
+
</table>
|
159 |
+
<?php submit_button(); ?>
|
160 |
+
</form>
|
161 |
+
<?php
|
162 |
+
}
|
163 |
}
|
classes/Views/LogInUsers.php
CHANGED
@@ -1,64 +1,176 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* User Sessions Management Add-On promo Page.
|
6 |
* Used only if the plugin is not activated.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Views_LogInUsers extends WSAL_AbstractView
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
<p>
|
55 |
-
<span class="description">
|
56 |
-
<strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
|
57 |
-
</span>
|
58 |
-
</p>
|
59 |
-
<?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
|
60 |
-
<a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
|
61 |
-
</div>
|
62 |
-
<?php
|
63 |
-
}
|
64 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Users Sessions Page
|
4 |
+
*
|
5 |
+
* WSAL users sessions page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* User Sessions Management Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Views_LogInUsers extends WSAL_AbstractView {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Method: Get View Title.
|
26 |
+
*/
|
27 |
+
public function GetTitle() {
|
28 |
+
return __( 'User Sessions Management Add-On', 'wp-security-audit-log' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Get View Icon.
|
33 |
+
*/
|
34 |
+
public function GetIcon() {
|
35 |
+
return 'dashicons-external';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Method: Get View Name.
|
40 |
+
*/
|
41 |
+
public function GetName() {
|
42 |
+
return __( 'Logged In Users ⇪', 'wp-security-audit-log' );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Get View Weight.
|
47 |
+
*/
|
48 |
+
public function GetWeight() {
|
49 |
+
return 7;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Method: Get View Header.
|
54 |
+
*/
|
55 |
+
public function Header() {
|
56 |
+
// Extension Page CSS.
|
57 |
+
wp_enqueue_style(
|
58 |
+
'extensions',
|
59 |
+
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
60 |
+
array(),
|
61 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/extensions.css' )
|
62 |
+
);
|
63 |
+
|
64 |
+
// Swipebox CSS.
|
65 |
+
wp_enqueue_style(
|
66 |
+
'wsal-swipebox-css',
|
67 |
+
$this->_plugin->GetBaseUrl() . '/css/swipebox.min.css',
|
68 |
+
array(),
|
69 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/swipebox.min.css' )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Method: Get View Footer.
|
75 |
+
*/
|
76 |
+
public function Footer() {
|
77 |
+
// jQuery.
|
78 |
+
wp_enqueue_script( 'jquery' );
|
79 |
+
|
80 |
+
// Swipebox JS.
|
81 |
+
wp_register_script(
|
82 |
+
'wsal-swipebox-js',
|
83 |
+
$this->_plugin->GetBaseUrl() . '/js/jquery.swipebox.min.js',
|
84 |
+
array( 'jquery' ),
|
85 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/jquery.swipebox.min.js' )
|
86 |
+
);
|
87 |
+
wp_enqueue_script( 'wsal-swipebox-js' );
|
88 |
+
|
89 |
+
// Extensions JS.
|
90 |
+
wp_register_script(
|
91 |
+
'wsal-extensions-js',
|
92 |
+
$this->_plugin->GetBaseUrl() . '/js/extensions.js',
|
93 |
+
array( 'wsal-swipebox-js' ),
|
94 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/extensions.js' )
|
95 |
+
);
|
96 |
+
wp_enqueue_script( 'wsal-extensions-js' );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Method: Get View.
|
101 |
+
*/
|
102 |
+
public function Render() {
|
103 |
+
?>
|
104 |
+
<div class="wrap-advertising-page-single">
|
105 |
+
<div class="wsal-row">
|
106 |
+
<div class="wsal-col">
|
107 |
+
<div class="icon" style='background-image:url("<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/monitoring.jpg");'></div>
|
108 |
+
</div>
|
109 |
+
<!-- /.wsal-col -->
|
110 |
+
|
111 |
+
<div class="wsal-col">
|
112 |
+
<h3><?php esc_html_e( 'Users Login and Management', 'wp-security-audit-log' ); ?></h3>
|
113 |
+
<p>
|
114 |
+
<?php esc_html_e( 'Upgrade to Premium to:', 'wp-security-audit-log' ); ?>
|
115 |
+
</p>
|
116 |
+
<p>
|
117 |
+
<ul class="wsal-features-list">
|
118 |
+
<li><?php esc_html_e( 'See who is logged in to your WordPress website,', 'wp-security-audit-log' ); ?></li>
|
119 |
+
<li><?php esc_html_e( 'When they logged in and from where,', 'wp-security-audit-log' ); ?></li>
|
120 |
+
<li><?php esc_html_e( 'The last change they did on your WordPress website,', 'wp-security-audit-log' ); ?></li>
|
121 |
+
<li><?php esc_html_e( 'Terminate their session with just a click of a button,', 'wp-security-audit-log' ); ?></li>
|
122 |
+
<li><?php esc_html_e( 'Block multiple sessions for the same user,', 'wp-security-audit-log' ); ?></li>
|
123 |
+
<li><?php esc_html_e( 'Get alerted when there are multiple sessions with the same username,', 'wp-security-audit-log' ); ?></li>
|
124 |
+
<li><?php esc_html_e( '& more.', 'wp-security-audit-log' ); ?></li>
|
125 |
+
</ul>
|
126 |
+
</p>
|
127 |
+
<?php
|
128 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
129 |
+
$more_info = add_query_arg(
|
130 |
+
array(
|
131 |
+
'utm_source' => 'plugin',
|
132 |
+
'utm_medium' => 'page',
|
133 |
+
'utm_content' => 'users+sessions+more+info',
|
134 |
+
'utm_campaign' => 'upgrade+premium',
|
135 |
+
),
|
136 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
137 |
+
);
|
138 |
+
?>
|
139 |
+
<p>
|
140 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $buy_now ); ?>"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
|
141 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
142 |
+
</p>
|
143 |
+
</div>
|
144 |
+
<!-- /.wsal-col -->
|
145 |
+
</div>
|
146 |
+
<!-- /.wsal-row -->
|
147 |
+
|
148 |
+
<div class="wsal-row">
|
149 |
+
<div class="wsal-col">
|
150 |
+
<h3><?php esc_html_e( 'Screenshots', 'wp-security-audit-log' ); ?></h3>
|
151 |
|
152 |
+
<p>
|
153 |
+
<ul class="wsal-features-list">
|
154 |
+
<li>
|
155 |
+
<?php esc_html_e( 'See who is logged in to your WordPress website and WordPress multisite network.', 'wp-security-audit-log' ); ?><br />
|
156 |
+
<a class="swipebox" title="<?php esc_attr_e( 'See who is logged in to your WordPress website and WordPress multisite network.', 'wp-security-audit-log' ); ?>"
|
157 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/users-sessions-management/logged_in_users.png">
|
158 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/users-sessions-management/logged_in_users.png">
|
159 |
+
</a>
|
160 |
+
</li>
|
161 |
+
<li>
|
162 |
+
<?php esc_html_e( 'Block multiple sessions for the same user and configure related email notifications.', 'wp-security-audit-log' ); ?><br />
|
163 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Block multiple sessions for the same user and configure related email notifications.', 'wp-security-audit-log' ); ?>"
|
164 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/users-sessions-management/users_session_management_config.png">
|
165 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/users-sessions-management/users_session_management_config.png">
|
166 |
+
</a>
|
167 |
+
</li>
|
168 |
+
</ul>
|
169 |
+
</p>
|
170 |
+
</div>
|
171 |
+
</div>
|
172 |
+
<!-- /.wsal-row -->
|
173 |
+
</div>
|
174 |
+
<?php
|
175 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
}
|
classes/Views/Reports.php
CHANGED
@@ -1,64 +1,175 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Reports Add-On promo Page.
|
6 |
* Used only if the plugin is not activated.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Views_Reports extends WSAL_AbstractView
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
<p>
|
55 |
-
<span class="description">
|
56 |
-
<strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
|
57 |
-
</span>
|
58 |
-
</p>
|
59 |
-
<?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
|
60 |
-
<a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
|
61 |
-
</div>
|
62 |
-
<?php
|
63 |
-
}
|
64 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Reports Page
|
4 |
+
*
|
5 |
+
* WSAL reports page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Reports Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Views_Reports extends WSAL_AbstractView {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Method: Get View Title.
|
26 |
+
*/
|
27 |
+
public function GetTitle() {
|
28 |
+
return __( 'Reports Add-On', 'wp-security-audit-log' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Get View Icon.
|
33 |
+
*/
|
34 |
+
public function GetIcon() {
|
35 |
+
return 'dashicons-external';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Method: Get View Name.
|
40 |
+
*/
|
41 |
+
public function GetName() {
|
42 |
+
return __( 'Reports ⇪', 'wp-security-audit-log' );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Get View Weight.
|
47 |
+
*/
|
48 |
+
public function GetWeight() {
|
49 |
+
return 8;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Method: Get View Header.
|
54 |
+
*/
|
55 |
+
public function Header() {
|
56 |
+
// Extension Page CSS.
|
57 |
+
wp_enqueue_style(
|
58 |
+
'extensions',
|
59 |
+
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
60 |
+
array(),
|
61 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/extensions.css' )
|
62 |
+
);
|
63 |
+
|
64 |
+
// Swipebox CSS.
|
65 |
+
wp_enqueue_style(
|
66 |
+
'wsal-swipebox-css',
|
67 |
+
$this->_plugin->GetBaseUrl() . '/css/swipebox.min.css',
|
68 |
+
array(),
|
69 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/swipebox.min.css' )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Method: Get View Footer.
|
75 |
+
*/
|
76 |
+
public function Footer() {
|
77 |
+
// jQuery.
|
78 |
+
wp_enqueue_script( 'jquery' );
|
79 |
+
|
80 |
+
// Swipebox JS.
|
81 |
+
wp_register_script(
|
82 |
+
'wsal-swipebox-js',
|
83 |
+
$this->_plugin->GetBaseUrl() . '/js/jquery.swipebox.min.js',
|
84 |
+
array( 'jquery' ),
|
85 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/jquery.swipebox.min.js' )
|
86 |
+
);
|
87 |
+
wp_enqueue_script( 'wsal-swipebox-js' );
|
88 |
+
|
89 |
+
// Extensions JS.
|
90 |
+
wp_register_script(
|
91 |
+
'wsal-extensions-js',
|
92 |
+
$this->_plugin->GetBaseUrl() . '/js/extensions.js',
|
93 |
+
array( 'wsal-swipebox-js' ),
|
94 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/extensions.js' )
|
95 |
+
);
|
96 |
+
wp_enqueue_script( 'wsal-extensions-js' );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Method: Get View.
|
101 |
+
*/
|
102 |
+
public function Render() {
|
103 |
+
?>
|
104 |
+
<div class="wrap-advertising-page-single">
|
105 |
+
<div class="wsal-row">
|
106 |
+
<div class="wsal-col">
|
107 |
+
<div class="icon" style='background-image:url("<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/file.jpg");'></div>
|
108 |
+
</div>
|
109 |
+
<!-- /.wsal-col -->
|
110 |
+
|
111 |
+
<div class="wsal-col">
|
112 |
+
<h3><?php esc_html_e( 'Reports', 'wp-security-audit-log' ); ?></h3>
|
113 |
+
<p>
|
114 |
+
<?php esc_html_e( 'Upgrade to Premium to:', 'wp-security-audit-log' ); ?>
|
115 |
+
</p>
|
116 |
+
<p>
|
117 |
+
<ul class="wsal-features-list">
|
118 |
+
<li><?php esc_html_e( 'Generate user activity, site (in multisite) and any other type of WordPress reports,', 'wp-security-audit-log' ); ?></li>
|
119 |
+
<li><?php esc_html_e( 'Configure automated daily, weekly, monthly & quarterly reports,', 'wp-security-audit-log' ); ?></li>
|
120 |
+
<li><?php esc_html_e( 'Receive reports automatically in your email,', 'wp-security-audit-log' ); ?></li>
|
121 |
+
<li><?php esc_html_e( 'Generate statistics reports on commonly used IP addresses, views per user, etc,', 'wp-security-audit-log' ); ?></li>
|
122 |
+
<li><?php esc_html_e( 'Export reports to HTML and CSV formats,', 'wp-security-audit-log' ); ?></li>
|
123 |
+
<li><?php esc_html_e( '& much more.', 'wp-security-audit-log' ); ?></li>
|
124 |
+
</ul>
|
125 |
+
</p>
|
126 |
+
<?php
|
127 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
128 |
+
$more_info = add_query_arg(
|
129 |
+
array(
|
130 |
+
'utm_source' => 'plugin',
|
131 |
+
'utm_medium' => 'page',
|
132 |
+
'utm_content' => 'reports+more+info',
|
133 |
+
'utm_campaign' => 'upgrade+premium',
|
134 |
+
),
|
135 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
136 |
+
);
|
137 |
+
?>
|
138 |
+
<p>
|
139 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $buy_now ); ?>"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
|
140 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
141 |
+
</p>
|
142 |
+
</div>
|
143 |
+
<!-- /.wsal-col -->
|
144 |
+
</div>
|
145 |
+
<!-- /.wsal-row -->
|
146 |
+
|
147 |
+
<div class="wsal-row">
|
148 |
+
<div class="wsal-col">
|
149 |
+
<h3><?php esc_html_e( 'Screenshots', 'wp-security-audit-log' ); ?></h3>
|
150 |
|
151 |
+
<p>
|
152 |
+
<ul class="wsal-features-list">
|
153 |
+
<li>
|
154 |
+
<?php esc_html_e( 'Generate any type of report and also configure daily, weekly, monthly and quarterly reports which are automatically sent to you via email.', 'wp-security-audit-log' ); ?><br />
|
155 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Generate any type of report and also configure daily, weekly, monthly and quarterly reports which are automatically sent to you via email.', 'wp-security-audit-log' ); ?>"
|
156 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/reports/reports_1.png">
|
157 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/reports/reports_1.png">
|
158 |
+
</a>
|
159 |
+
</li>
|
160 |
+
<li>
|
161 |
+
<?php esc_html_e( 'Generate statistical reports to get a better overview of what users are doing on your WordPress and WordPress multisite network are doing.', 'wp-security-audit-log' ); ?><br />
|
162 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Generate statistical reports to get a better overview of what users are doing on your WordPress and WordPress multisite network are doing.', 'wp-security-audit-log' ); ?>"
|
163 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/reports/reports_2.png">
|
164 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/reports/reports_2.png">
|
165 |
+
</a>
|
166 |
+
</li>
|
167 |
+
</ul>
|
168 |
+
</p>
|
169 |
+
</div>
|
170 |
+
</div>
|
171 |
+
<!-- /.wsal-row -->
|
172 |
+
</div>
|
173 |
+
<?php
|
174 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
classes/Views/Search.php
CHANGED
@@ -1,64 +1,168 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
|
|
|
|
4 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
* Search Add-On promo Page.
|
6 |
* Used only if the plugin is not activated.
|
|
|
|
|
7 |
*/
|
8 |
-
class WSAL_Views_Search extends WSAL_AbstractView
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
<?php _e('Do free-text based searches for specific activity in the WordPress audit trail.<br> You can also use the built-in filters to fine-tune your searches.', 'wp-security-audit-log'); ?>
|
48 |
-
</p>
|
49 |
-
<?php $url = 'https://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=searchpage&utm_campaign=search'; ?>
|
50 |
-
<p>
|
51 |
-
<a class="button-primary" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Learn More', 'wp-security-audit-log'); ?></a>
|
52 |
-
</p>
|
53 |
-
<div class="clear"></div>
|
54 |
-
<p>
|
55 |
-
<span class="description">
|
56 |
-
<strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
|
57 |
-
</span>
|
58 |
-
</p>
|
59 |
-
<?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
|
60 |
-
<a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
|
61 |
-
</div>
|
62 |
-
<?php
|
63 |
-
}
|
64 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* View: Users Sessions Page
|
4 |
+
*
|
5 |
+
* WSAL users sessions page.
|
6 |
*
|
7 |
+
* @since 1.0.0
|
8 |
+
* @package Wsal
|
9 |
+
*/
|
10 |
+
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
* Search Add-On promo Page.
|
18 |
* Used only if the plugin is not activated.
|
19 |
+
*
|
20 |
+
* @package Wsal
|
21 |
*/
|
22 |
+
class WSAL_Views_Search extends WSAL_AbstractView {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Method: Get View Title.
|
26 |
+
*/
|
27 |
+
public function GetTitle() {
|
28 |
+
return __( 'Search Add-On', 'wp-security-audit-log' );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Method: Get View Icon.
|
33 |
+
*/
|
34 |
+
public function GetIcon() {
|
35 |
+
return 'dashicons-external';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Method: Get View Name.
|
40 |
+
*/
|
41 |
+
public function GetName() {
|
42 |
+
return __( 'Search ⇪', 'wp-security-audit-log' );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Method: Get View Weight.
|
47 |
+
*/
|
48 |
+
public function GetWeight() {
|
49 |
+
return 11;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Method: Get View Header.
|
54 |
+
*/
|
55 |
+
public function Header() {
|
56 |
+
// Extension Page CSS.
|
57 |
+
wp_enqueue_style(
|
58 |
+
'extensions',
|
59 |
+
$this->_plugin->GetBaseUrl() . '/css/extensions.css',
|
60 |
+
array(),
|
61 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/extensions.css' )
|
62 |
+
);
|
63 |
+
|
64 |
+
// Swipebox CSS.
|
65 |
+
wp_enqueue_style(
|
66 |
+
'wsal-swipebox-css',
|
67 |
+
$this->_plugin->GetBaseUrl() . '/css/swipebox.min.css',
|
68 |
+
array(),
|
69 |
+
filemtime( $this->_plugin->GetBaseDir() . '/css/swipebox.min.css' )
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Method: Get View Footer.
|
75 |
+
*/
|
76 |
+
public function Footer() {
|
77 |
+
// jQuery.
|
78 |
+
wp_enqueue_script( 'jquery' );
|
79 |
+
|
80 |
+
// Swipebox JS.
|
81 |
+
wp_register_script(
|
82 |
+
'wsal-swipebox-js',
|
83 |
+
$this->_plugin->GetBaseUrl() . '/js/jquery.swipebox.min.js',
|
84 |
+
array( 'jquery' ),
|
85 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/jquery.swipebox.min.js' )
|
86 |
+
);
|
87 |
+
wp_enqueue_script( 'wsal-swipebox-js' );
|
88 |
+
|
89 |
+
// Extensions JS.
|
90 |
+
wp_register_script(
|
91 |
+
'wsal-extensions-js',
|
92 |
+
$this->_plugin->GetBaseUrl() . '/js/extensions.js',
|
93 |
+
array( 'wsal-swipebox-js' ),
|
94 |
+
filemtime( $this->_plugin->GetBaseDir() . '/js/extensions.js' )
|
95 |
+
);
|
96 |
+
wp_enqueue_script( 'wsal-extensions-js' );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Method: Get View.
|
101 |
+
*/
|
102 |
+
public function Render() {
|
103 |
+
?>
|
104 |
+
<div class="wrap-advertising-page-single">
|
105 |
+
<div class="wsal-row">
|
106 |
+
<div class="wsal-col">
|
107 |
+
<div class="icon" style='background-image:url("<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/search.jpg");'></div>
|
108 |
+
</div>
|
109 |
+
<!-- /.wsal-col -->
|
110 |
+
|
111 |
+
<div class="wsal-col">
|
112 |
+
<h3><?php esc_html_e( 'Search', 'wp-security-audit-log' ); ?></h3>
|
113 |
+
<p>
|
114 |
+
<?php esc_html_e( 'Upgrade to Premium to:', 'wp-security-audit-log' ); ?>
|
115 |
+
</p>
|
116 |
+
<p>
|
117 |
+
<ul class="wsal-features-list">
|
118 |
+
<li><?php esc_html_e( 'Easily find and track back a specific change or suspicious user behaviour,', 'wp-security-audit-log' ); ?></li>
|
119 |
+
<li><?php esc_html_e( 'Easily find the root of a problem to ease troubleshooting,', 'wp-security-audit-log' ); ?></li>
|
120 |
+
<li><?php esc_html_e( 'Do free-text based searches in the WordPress audit log,', 'wp-security-audit-log' ); ?></li>
|
121 |
+
<li><?php esc_html_e( 'Use filters to fine tune the search results,', 'wp-security-audit-log' ); ?></li>
|
122 |
+
<li><?php esc_html_e( 'Save search terms & filters for improved productivity,', 'wp-security-audit-log' ); ?></li>
|
123 |
+
<li><?php esc_html_e( '& more.', 'wp-security-audit-log' ); ?></li>
|
124 |
+
</ul>
|
125 |
+
</p>
|
126 |
+
<?php
|
127 |
+
$buy_now = add_query_arg( 'page', 'wsal-auditlog-pricing', admin_url( 'admin.php' ) );
|
128 |
+
$more_info = add_query_arg(
|
129 |
+
array(
|
130 |
+
'utm_source' => 'plugin',
|
131 |
+
'utm_medium' => 'page',
|
132 |
+
'utm_content' => 'search+more+info',
|
133 |
+
'utm_campaign' => 'upgrade+premium',
|
134 |
+
),
|
135 |
+
'https://www.wpsecurityauditlog.com/premium-features/'
|
136 |
+
);
|
137 |
+
?>
|
138 |
+
<p>
|
139 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $buy_now ); ?>"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
|
140 |
+
<a class="button-primary wsal-extension-btn" href="<?php echo esc_attr( $more_info ); ?>" target="_blank"><?php esc_html_e( 'More Information', 'wp-security-audit-log' ); ?></a>
|
141 |
+
</p>
|
142 |
+
</div>
|
143 |
+
<!-- /.wsal-col -->
|
144 |
+
</div>
|
145 |
+
<!-- /.wsal-row -->
|
146 |
+
|
147 |
+
<div class="wsal-row">
|
148 |
+
<div class="wsal-col">
|
149 |
+
<h3><?php esc_html_e( 'Screenshots', 'wp-security-audit-log' ); ?></h3>
|
150 |
|
151 |
+
<p>
|
152 |
+
<ul class="wsal-features-list">
|
153 |
+
<li>
|
154 |
+
<?php esc_html_e( 'Use the free-text based search to find a specific change and use the filters to fine tune the search results.', 'wp-security-audit-log' ); ?><br />
|
155 |
+
<a class="swipebox" title="<?php esc_attr_e( 'Use the free-text based search to find a specific change and use the filters to fine tune the search results.', 'wp-security-audit-log' ); ?>"
|
156 |
+
href="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/search/search.png">
|
157 |
+
<img width="500" src="<?php echo esc_url( $this->_plugin->GetBaseUrl() ); ?>/img/search/search.png">
|
158 |
+
</a>
|
159 |
+
</li>
|
160 |
+
</ul>
|
161 |
+
</p>
|
162 |
+
</div>
|
163 |
+
</div>
|
164 |
+
<!-- /.wsal-row -->
|
165 |
+
</div>
|
166 |
+
<?php
|
167 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
}
|
classes/Views/Settings.php
CHANGED
@@ -8,6 +8,11 @@
|
|
8 |
* @package Wsal
|
9 |
*/
|
10 |
|
|
|
|
|
|
|
|
|
|
|
11 |
/**
|
12 |
* Class: WSAL_Views_Settings
|
13 |
*
|
@@ -17,8 +22,18 @@
|
|
17 |
*/
|
18 |
class WSAL_Views_Settings extends WSAL_AbstractView {
|
19 |
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
21 |
|
|
|
|
|
|
|
|
|
|
|
22 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
23 |
parent::__construct( $plugin );
|
24 |
add_action( 'wp_ajax_AjaxCheckSecurityToken', array( $this, 'AjaxCheckSecurityToken' ) );
|
@@ -28,33 +43,47 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
28 |
add_action( 'wp_ajax_AjaxGetAllCPT', array( $this, 'AjaxGetAllCPT' ) );
|
29 |
}
|
30 |
|
31 |
-
|
32 |
-
|
|
|
|
|
33 |
return true;
|
34 |
}
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
39 |
}
|
40 |
|
41 |
-
|
42 |
-
|
|
|
|
|
43 |
return 'dashicons-admin-generic';
|
44 |
}
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
49 |
}
|
50 |
|
51 |
-
|
52 |
-
|
|
|
|
|
53 |
return 3;
|
54 |
}
|
55 |
|
|
|
|
|
|
|
|
|
|
|
56 |
protected function GetTokenType( $token ) {
|
57 |
-
|
58 |
// Get users.
|
59 |
$users = array();
|
60 |
foreach ( get_users( 'blog_id=0&fields[]=user_login' ) as $obj ) {
|
@@ -67,12 +96,17 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
67 |
// Get custom post types.
|
68 |
$post_types = get_post_types( array(), 'names', 'and' );
|
69 |
|
|
|
70 |
if ( in_array( $token, $users ) ) {
|
71 |
return 'user';
|
72 |
}
|
|
|
|
|
73 |
if ( in_array( $token, $roles ) ) {
|
74 |
return 'role';
|
75 |
}
|
|
|
|
|
76 |
if ( in_array( $token, $post_types ) ) {
|
77 |
return 'cpts';
|
78 |
}
|
@@ -81,97 +115,125 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
81 |
|
82 |
/**
|
83 |
* Method: Save settings.
|
84 |
-
*
|
85 |
-
* @since 1.0.0
|
86 |
*/
|
87 |
protected function Save() {
|
88 |
check_admin_referer( 'wsal-settings' );
|
89 |
-
|
90 |
-
|
91 |
-
$
|
92 |
-
|
93 |
-
|
94 |
-
$
|
95 |
-
$
|
96 |
-
|
97 |
-
$this->_plugin->settings->
|
98 |
-
$this->_plugin->settings->
|
99 |
-
$this->_plugin->settings->
|
100 |
-
|
101 |
-
|
102 |
-
$this->_plugin->settings->
|
103 |
-
$this->_plugin->settings->
|
104 |
-
|
105 |
-
$this->_plugin->settings->
|
106 |
-
|
107 |
-
$this->_plugin->settings->
|
108 |
-
|
109 |
-
$this->_plugin->settings->
|
110 |
-
$this->_plugin->settings->
|
111 |
-
$this->_plugin->settings->
|
112 |
-
$this->_plugin->settings->
|
113 |
-
$this->_plugin->settings->
|
114 |
-
|
115 |
-
$this->_plugin->settings->
|
116 |
-
$this->_plugin->settings->
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
}
|
120 |
$this->_plugin->settings->ClearDevOptions();
|
121 |
|
122 |
-
if ( isset( $
|
123 |
-
foreach ( $
|
124 |
$this->_plugin->settings->SetDevOptionEnabled( $opt, true );
|
125 |
}
|
126 |
}
|
127 |
}
|
128 |
|
|
|
|
|
|
|
129 |
public function AjaxCheckSecurityToken() {
|
130 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
131 |
die( 'Access Denied.' );
|
132 |
}
|
133 |
-
|
|
|
|
|
|
|
|
|
134 |
die( 'Token parameter expected.' );
|
135 |
}
|
136 |
-
die( $this->GetTokenType( $
|
137 |
}
|
138 |
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
|
|
|
|
143 |
}
|
144 |
$this->_plugin->CleanUp();
|
145 |
-
|
146 |
exit;
|
147 |
}
|
148 |
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
|
|
|
|
|
|
|
|
|
|
153 |
}
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
155 |
try {
|
156 |
$this->Save();
|
157 |
?><div class="updated">
|
158 |
-
<p><?php
|
159 |
-
</div
|
160 |
-
|
161 |
-
|
|
|
|
|
|
|
162 |
}
|
163 |
}
|
164 |
?>
|
165 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
166 |
-
<a href="#tab-general" class="nav-tab"><?php
|
167 |
-
<a href="#tab-audit-log" class="nav-tab"><?php
|
168 |
-
<a href="#tab-exclude" class="nav-tab"><?php
|
169 |
</h2>
|
170 |
-
|
171 |
<form id="audit-log-settings" method="post">
|
172 |
-
<input type="hidden" name="page" value="<?php echo
|
173 |
-
<input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
|
174 |
-
<?php wp_nonce_field('wsal-settings'); ?>
|
175 |
|
176 |
<div id="audit-log-adverts">
|
177 |
</div>
|
@@ -181,159 +243,168 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
181 |
<tbody>
|
182 |
<!-- From Email & Name -->
|
183 |
<tr>
|
184 |
-
<th><label for="FromEmail"><?php
|
185 |
<td>
|
186 |
<fieldset>
|
187 |
-
<label for="FromEmail"><?php
|
188 |
-
<input type="email" id="FromEmail" name="FromEmail" value="<?php echo esc_attr($this->_plugin->settings->GetFromEmail()); ?>" />
|
189 |
|
190 |
-
<label for="DisplayName"><?php
|
191 |
-
<input type="text" id="DisplayName" name="DisplayName" value="<?php echo esc_attr($this->_plugin->settings->GetDisplayName()); ?>" />
|
192 |
</fieldset>
|
193 |
<p class="description">
|
194 |
<?php
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
?>
|
200 |
</p>
|
201 |
</td>
|
202 |
</tr>
|
203 |
<!-- Alerts Dashboard Widget -->
|
204 |
<tr>
|
205 |
-
<th><label for="dwoption_on"><?php
|
206 |
<td>
|
207 |
<fieldset>
|
208 |
<?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
|
209 |
<label for="dwoption_on">
|
210 |
-
<input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php
|
211 |
-
<span><?php
|
212 |
</label>
|
213 |
<br/>
|
214 |
<label for="dwoption_off">
|
215 |
-
<input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php
|
216 |
-
<span><?php
|
217 |
</label>
|
218 |
<br/>
|
219 |
-
<p class="description"
|
|
|
220 |
echo sprintf(
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
|
|
225 |
</fieldset>
|
226 |
</td>
|
227 |
</tr>
|
228 |
<!-- Reverse Proxy / Firewall Options -->
|
229 |
<tr>
|
230 |
-
<th><label for="pioption_on"><?php
|
231 |
<td>
|
232 |
<fieldset>
|
233 |
<label for="EnableProxyIpCapture">
|
234 |
-
<input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
|
235 |
-
|
236 |
-
?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?>
|
237 |
</label>
|
238 |
<br/>
|
239 |
-
<span class="description"><?php
|
240 |
<br/>
|
241 |
<label for="EnableIpFiltering">
|
242 |
-
<input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
|
243 |
-
|
244 |
-
?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?>
|
245 |
</label>
|
246 |
<br/>
|
247 |
-
<span class="description"><?php
|
248 |
</fieldset>
|
249 |
</td>
|
250 |
</tr>
|
251 |
<!-- Can Manage Plugin -->
|
252 |
<tr>
|
253 |
-
<th><label for="EditorQueryBox"><?php
|
254 |
<td>
|
255 |
<fieldset>
|
256 |
<input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
|
257 |
<input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
258 |
<br style="clear: both;"/>
|
259 |
-
<p class="description"
|
260 |
-
|
261 |
-
|
262 |
-
<div id="EditorList"
|
263 |
-
foreach ($this->_plugin->settings->GetAllowedPluginEditors() as $item)
|
264 |
-
|
265 |
-
<input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
|
266 |
-
<?php echo esc_html($item); ?>
|
267 |
-
<?php if (wp_get_current_user()->user_login
|
268 |
<a href="javascript:;" title="Remove">×</a>
|
269 |
<?php } ?>
|
270 |
-
</span
|
271 |
-
|
272 |
-
|
273 |
</fieldset>
|
274 |
</td>
|
275 |
</tr>
|
276 |
<!-- Restrict Plugin Access -->
|
277 |
<tr>
|
278 |
-
<th><label for="RestrictAdmins"><?php
|
279 |
<td>
|
280 |
<fieldset>
|
281 |
-
<input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
|
282 |
<label for="RestrictAdmins">
|
283 |
<?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
|
284 |
-
<input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php
|
285 |
</label>
|
286 |
<br/>
|
287 |
<span class="description">
|
288 |
-
<?php
|
289 |
-
<?php
|
290 |
</span>
|
291 |
</fieldset>
|
292 |
</td>
|
293 |
</tr>
|
294 |
<!-- Developer Options -->
|
295 |
<tr>
|
296 |
-
<th><label><?php
|
297 |
<td>
|
298 |
<fieldset>
|
299 |
<?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
|
300 |
-
<a href="javascript:;" style="<?php
|
301 |
-
|
302 |
-
|
|
|
|
|
303 |
<p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;">
|
304 |
-
<?php
|
305 |
</p>
|
306 |
<?php
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
),
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
),
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
<?php
|
332 |
-
?></
|
333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
334 |
?>
|
335 |
<span class="description">
|
336 |
-
<?php
|
337 |
</span>
|
338 |
</div>
|
339 |
</fieldset>
|
@@ -341,24 +412,23 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
341 |
</tr>
|
342 |
<!-- Hide Plugin in Plugins Page -->
|
343 |
<tr>
|
344 |
-
<th><label for="Incognito"><?php
|
345 |
<td>
|
346 |
<fieldset>
|
347 |
<label for="Incognito">
|
348 |
-
<input type="checkbox" name="Incognito" value="1" id="Incognito"<?php
|
349 |
-
|
350 |
-
?>/> <?php _e('Hide', 'wp-security-audit-log'); ?>
|
351 |
</label>
|
352 |
<br/>
|
353 |
<span class="description">
|
354 |
-
<?php
|
355 |
</span>
|
356 |
</fieldset>
|
357 |
</td>
|
358 |
</tr>
|
359 |
<!-- Logging -->
|
360 |
<tr>
|
361 |
-
<th><label for="Logging"><?php
|
362 |
<td>
|
363 |
<fieldset>
|
364 |
<label for="Logging">
|
@@ -372,20 +442,22 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
372 |
</label>
|
373 |
<br/>
|
374 |
<span class="description">
|
375 |
-
<?php
|
376 |
</span>
|
377 |
</fieldset>
|
378 |
</td>
|
379 |
</tr>
|
380 |
<!-- Remove Data on Uninstall -->
|
381 |
<tr>
|
382 |
-
<th><label for="DeleteData"><?php
|
383 |
<td>
|
384 |
<fieldset>
|
385 |
<label for="DeleteData">
|
386 |
-
<input type="checkbox" name="DeleteData" value="1" id="DeleteData"
|
387 |
-
|
388 |
-
|
|
|
|
|
389 |
</label>
|
390 |
</fieldset>
|
391 |
</td>
|
@@ -397,124 +469,142 @@ class WSAL_Views_Settings extends WSAL_AbstractView {
|
|
397 |
<tbody>
|
398 |
<!-- Security Alerts Pruning -->
|
399 |
<?php
|
400 |
-
|
401 |
-
|
402 |
$disabled = 'disabled';
|
403 |
?>
|
404 |
<tr>
|
405 |
<td colspan="2">
|
406 |
-
<?php
|
407 |
</td>
|
408 |
</tr>
|
409 |
<?php } ?>
|
410 |
<tr>
|
411 |
-
<th><label for="delete1"><?php
|
412 |
<td>
|
413 |
<fieldset>
|
414 |
-
<?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
|
415 |
-
<?php $nbld = !($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
|
416 |
<label for="delete0">
|
417 |
-
|
418 |
-
<?php echo __('None', 'wp-security-audit-log'); ?>
|
8 |
* @package Wsal
|
9 |
*/
|
10 |
|
11 |
+
// Exit if accessed directly.
|
12 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
13 |
+
exit;
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* Class: WSAL_Views_Settings
|
18 |
*
|
22 |
*/
|
23 |
class WSAL_Views_Settings extends WSAL_AbstractView {
|
24 |
|
25 |
+
/**
|
26 |
+
* Adapter Message.
|
27 |
+
*
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $adapter_msg = '';
|
31 |
|
32 |
+
/**
|
33 |
+
* Method: Constructor.
|
34 |
+
*
|
35 |
+
* @param WpSecurityAuditLog $plugin - Instance of WpSecurityAuditLog.
|
36 |
+
*/
|
37 |
public function __construct( WpSecurityAuditLog $plugin ) {
|
38 |
parent::__construct( $plugin );
|
39 |
add_action( 'wp_ajax_AjaxCheckSecurityToken', array( $this, 'AjaxCheckSecurityToken' ) );
|
43 |
add_action( 'wp_ajax_AjaxGetAllCPT', array( $this, 'AjaxGetAllCPT' ) );
|
44 |
}
|
45 |
|
46 |
+
/**
|
47 |
+
* Method: Plugin Shortcut.
|
48 |
+
*/
|
49 |
+
public function HasPluginShortcutLink() {
|
50 |
return true;
|
51 |
}
|
52 |
|
53 |
+
/**
|
54 |
+
* Method: Get View Title.
|
55 |
+
*/
|
56 |
+
public function GetTitle() {
|
57 |
+
return __( 'Settings', 'wp-security-audit-log' );
|
58 |
}
|
59 |
|
60 |
+
/**
|
61 |
+
* Method: Get View Icon.
|
62 |
+
*/
|
63 |
+
public function GetIcon() {
|
64 |
return 'dashicons-admin-generic';
|
65 |
}
|
66 |
|
67 |
+
/**
|
68 |
+
* Method: Get View Name.
|
69 |
+
*/
|
70 |
+
public function GetName() {
|
71 |
+
return __( 'Settings', 'wp-security-audit-log' );
|
72 |
}
|
73 |
|
74 |
+
/**
|
75 |
+
* Method: Get View Weight.
|
76 |
+
*/
|
77 |
+
public function GetWeight() {
|
78 |
return 3;
|
79 |
}
|
80 |
|
81 |
+
/**
|
82 |
+
* Method: Get Token Type.
|
83 |
+
*
|
84 |
+
* @param string $token - Token type.
|
85 |
+
*/
|
86 |
protected function GetTokenType( $token ) {
|
|
|
87 |
// Get users.
|
88 |
$users = array();
|
89 |
foreach ( get_users( 'blog_id=0&fields[]=user_login' ) as $obj ) {
|
96 |
// Get custom post types.
|
97 |
$post_types = get_post_types( array(), 'names', 'and' );
|
98 |
|
99 |
+
// Check if the token matched users.
|
100 |
if ( in_array( $token, $users ) ) {
|
101 |
return 'user';
|
102 |
}
|
103 |
+
|
104 |
+
// Check if the token matched user roles.
|
105 |
if ( in_array( $token, $roles ) ) {
|
106 |
return 'role';
|
107 |
}
|
108 |
+
|
109 |
+
// Check if the token matched post types.
|
110 |
if ( in_array( $token, $post_types ) ) {
|
111 |
return 'cpts';
|
112 |
}
|
115 |
|
116 |
/**
|
117 |
* Method: Save settings.
|
|
|
|
|
118 |
*/
|
119 |
protected function Save() {
|
120 |
check_admin_referer( 'wsal-settings' );
|
121 |
+
|
122 |
+
// Filter $_POST array for security.
|
123 |
+
$post_array = filter_input_array( INPUT_POST );
|
124 |
+
|
125 |
+
// Get pruning date.
|
126 |
+
$pruning_date = isset( $post_array['PruningDate'] ) ? (int) $post_array['PruningDate'] : '';
|
127 |
+
$pruning_date = ( ! empty( $pruning_date ) ) ? $pruning_date . ' months' : '';
|
128 |
+
|
129 |
+
$this->_plugin->settings->SetPruningDateEnabled( isset( $post_array['PruneBy'] ) ? 'date' === $post_array['PruneBy'] : '' );
|
130 |
+
$this->_plugin->settings->SetPruningDate( $pruning_date );
|
131 |
+
$this->_plugin->settings->SetPruningLimitEnabled( isset( $post_array['PruneBy'] ) ? 'limit' === $post_array['PruneBy'] : '' );
|
132 |
+
$this->_plugin->settings->SetPruningLimit( isset( $post_array['PruningLimit'] ) ? $post_array['PruningLimit'] : '' );
|
133 |
+
|
134 |
+
$this->_plugin->settings->SetFromEmail( $post_array['FromEmail'] );
|
135 |
+
$this->_plugin->settings->SetDisplayName( $post_array['DisplayName'] );
|
136 |
+
|
137 |
+
$this->_plugin->settings->SetWidgetsEnabled( $post_array['EnableDashboardWidgets'] );
|
138 |
+
$this->_plugin->settings->SetAllowedPluginViewers( isset( $post_array['Viewers'] ) ? $post_array['Viewers'] : array() );
|
139 |
+
$this->_plugin->settings->SetAllowedPluginEditors( isset( $post_array['Editors'] ) ? $post_array['Editors'] : array() );
|
140 |
+
|
141 |
+
$this->_plugin->settings->SetExcludedMonitoringUsers( isset( $post_array['ExUsers'] ) ? $post_array['ExUsers'] : array() );
|
142 |
+
$this->_plugin->settings->SetExcludedMonitoringRoles( isset( $post_array['ExRoles'] ) ? $post_array['ExRoles'] : array() );
|
143 |
+
$this->_plugin->settings->SetExcludedMonitoringCustom( isset( $post_array['Customs'] ) ? $post_array['Customs'] : array() );
|
144 |
+
$this->_plugin->settings->SetExcludedMonitoringIP( isset( $post_array['IpAddrs'] ) ? $post_array['IpAddrs'] : array() );
|
145 |
+
$this->_plugin->settings->set_excluded_post_types( isset( $post_array['ExCPTss'] ) ? $post_array['ExCPTss'] : array() );
|
146 |
+
|
147 |
+
$this->_plugin->settings->SetRestrictAdmins( isset( $post_array['RestrictAdmins'] ) );
|
148 |
+
$this->_plugin->settings->SetRefreshAlertsEnabled( $post_array['EnableAuditViewRefresh'] );
|
149 |
+
$this->_plugin->settings->SetMainIPFromProxy( isset( $post_array['EnableProxyIpCapture'] ) );
|
150 |
+
$this->_plugin->settings->SetInternalIPsFiltering( isset( $post_array['EnableIpFiltering'] ) );
|
151 |
+
$this->_plugin->settings->SetIncognito( isset( $post_array['Incognito'] ) );
|
152 |
+
$this->_plugin->settings->SetLoggingDisabled( isset( $post_array['Logging'] ) );
|
153 |
+
$this->_plugin->settings->SetDeleteData( isset( $post_array['DeleteData'] ) );
|
154 |
+
$this->_plugin->settings->SetTimezone( $post_array['Timezone'] );
|
155 |
+
$this->_plugin->settings->set_type_username( $post_array['type_username'] );
|
156 |
+
$this->_plugin->settings->SetWPBackend( isset( $post_array['WPBackend'] ) );
|
157 |
+
if ( ! empty( $post_array['Columns'] ) ) {
|
158 |
+
$this->_plugin->settings->SetColumns( $post_array['Columns'] );
|
159 |
}
|
160 |
$this->_plugin->settings->ClearDevOptions();
|
161 |
|
162 |
+
if ( isset( $post_array['DevOptions'] ) ) {
|
163 |
+
foreach ( $post_array['DevOptions'] as $opt ) {
|
164 |
$this->_plugin->settings->SetDevOptionEnabled( $opt, true );
|
165 |
}
|
166 |
}
|
167 |
}
|
168 |
|
169 |
+
/**
|
170 |
+
* Method: Check security token.
|
171 |
+
*/
|
172 |
public function AjaxCheckSecurityToken() {
|
173 |
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
174 |
die( 'Access Denied.' );
|
175 |
}
|
176 |
+
|
177 |
+
// Filter $_POST array for security.
|
178 |
+
$post_array = filter_input_array( INPUT_POST );
|
179 |
+
|
180 |
+
if ( ! isset( $post_array['token'] ) ) {
|
181 |
die( 'Token parameter expected.' );
|
182 |
}
|
183 |
+
die( esc_html( $this->GetTokenType( $post_array['token'] ) ) );
|
184 |
}
|
185 |
|
186 |
+
/**
|
187 |
+
* Method: Run cleanup.
|
188 |
+
*/
|
189 |
+
public function AjaxRunCleanup() {
|
190 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
|
191 |
+
die( 'Access Denied.' );
|
192 |
}
|
193 |
$this->_plugin->CleanUp();
|
194 |
+
wp_safe_redirect( $this->GetUrl() );
|
195 |
exit;
|
196 |
}
|
197 |
|
198 |
+
/**
|
199 |
+
* Method: Get View.
|
200 |
+
*/
|
201 |
+
public function Render() {
|
202 |
+
// Filter $_POST array for security.
|
203 |
+
$post_array = filter_input_array( INPUT_POST );
|
204 |
+
|
205 |
+
if ( isset( $post_array['_wpnonce'] ) && ! wp_verify_nonce( $post_array['_wpnonce'], 'wsal-settings' ) ) {
|
206 |
+
wp_die( esc_html__( 'Nonce verification failed.', 'wp-security-audit-log' ) );
|
207 |
}
|
208 |
+
|
209 |
+
if ( ! $this->_plugin->settings->CurrentUserCan( 'edit' ) ) {
|
210 |
+
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
|
211 |
+
}
|
212 |
+
|
213 |
+
if ( isset( $post_array['submit'] ) ) {
|
214 |
try {
|
215 |
$this->Save();
|
216 |
?><div class="updated">
|
217 |
+
<p><?php esc_html_e( 'Settings have been saved.', 'wp-security-audit-log' ); ?></p>
|
218 |
+
</div>
|
219 |
+
<?php
|
220 |
+
} catch ( Exception $ex ) {
|
221 |
+
?>
|
222 |
+
<div class="error"><p><?php esc_html_e( 'Error: ', 'wp-security-audit-log' ); ?><?php echo esc_html( $ex->getMessage() ); ?></p></div>
|
223 |
+
<?php
|
224 |
}
|
225 |
}
|
226 |
?>
|
227 |
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
228 |
+
<a href="#tab-general" class="nav-tab"><?php esc_html_e( 'General', 'wp-security-audit-log' ); ?></a>
|
229 |
+
<a href="#tab-audit-log" class="nav-tab"><?php esc_html_e( 'Audit Log', 'wp-security-audit-log' ); ?></a>
|
230 |
+
<a href="#tab-exclude" class="nav-tab"><?php esc_html_e( 'Exclude Objects', 'wp-security-audit-log' ); ?></a>
|
231 |
</h2>
|
232 |
+
|
233 |
<form id="audit-log-settings" method="post">
|
234 |
+
<input type="hidden" name="page" value="<?php echo filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING ); ?>" />
|
235 |
+
<input type="hidden" id="ajaxurl" value="<?php echo esc_attr( admin_url( 'admin-ajax.php' ) ); ?>" />
|
236 |
+
<?php wp_nonce_field( 'wsal-settings' ); ?>
|
237 |
|
238 |
<div id="audit-log-adverts">
|
239 |
</div>
|
243 |
<tbody>
|
244 |
<!-- From Email & Name -->
|
245 |
<tr>
|
246 |
+
<th><label for="FromEmail"><?php esc_html_e( 'From Email & Name', 'wp-security-audit-log' ); ?></label></th>
|
247 |
<td>
|
248 |
<fieldset>
|
249 |
+
<label for="FromEmail"><?php esc_html_e( 'Email Address', 'wp-security-audit-log' ); ?></label>
|
250 |
+
<input type="email" id="FromEmail" name="FromEmail" value="<?php echo esc_attr( $this->_plugin->settings->GetFromEmail() ); ?>" />
|
251 |
|
252 |
+
<label for="DisplayName"><?php esc_html_e( 'Display Name', 'wp-security-audit-log' ); ?></label>
|
253 |
+
<input type="text" id="DisplayName" name="DisplayName" value="<?php echo esc_attr( $this->_plugin->settings->GetDisplayName() ); ?>" />
|
254 |
</fieldset>
|
255 |
<p class="description">
|
256 |
<?php
|
257 |
+
echo sprintf(
|
258 |
+
esc_html__( 'These email address and display name will be used as From details in the emails sent by the %s . Please ensure the mail server can relay emails with the domain of the specified email address.', 'wp-security-audit-log' ),
|
259 |
+
'<a target="_blank" href="https://www.wpsecurityauditlog.com/plugin-extensions/">' . esc_html__( '(premium add-ons)', 'wp-security-audit-log' ) . '</a>'
|
260 |
+
);
|
261 |
?>
|
262 |
</p>
|
263 |
</td>
|
264 |
</tr>
|
265 |
<!-- Alerts Dashboard Widget -->
|
266 |
<tr>
|
267 |
+
<th><label for="dwoption_on"><?php esc_html_e( 'Alerts Dashboard Widget', 'wp-security-audit-log' ); ?></label></th>
|
268 |
<td>
|
269 |
<fieldset>
|
270 |
<?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
|
271 |
<label for="dwoption_on">
|
272 |
+
<input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php checked( $dwe ); ?> value="1">
|
273 |
+
<span><?php esc_html_e( 'On', 'wp-security-audit-log' ); ?></span>
|
274 |
</label>
|
275 |
<br/>
|
276 |
<label for="dwoption_off">
|
277 |
+
<input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php checked( $dwe, false ); ?> value="0">
|
278 |
+
<span><?php esc_html_e( 'Off', 'wp-security-audit-log' ); ?></span>
|
279 |
</label>
|
280 |
<br/>
|
281 |
+
<p class="description">
|
282 |
+
<?php
|
283 |
echo sprintf(
|
284 |
+
esc_html__( 'Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log' ),
|
285 |
+
esc_html( $this->_plugin->settings->GetDashboardWidgetMaxAlerts() )
|
286 |
+
);
|
287 |
+
?>
|
288 |
+
</p>
|
289 |
</fieldset>
|
290 |
</td>
|
291 |
</tr>
|
292 |
<!-- Reverse Proxy / Firewall Options -->
|
293 |
<tr>
|
294 |
+
<th><label for="pioption_on"><?php esc_html_e( 'Reverse Proxy / Firewall Options', 'wp-security-audit-log' ); ?></label></th>
|
295 |
<td>
|
296 |
<fieldset>
|
297 |
<label for="EnableProxyIpCapture">
|
298 |
+
<input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture" <?php checked( $this->_plugin->settings->IsMainIPFromProxy() ); ?> />
|
299 |
+
<?php esc_html_e( 'WordPress running behind firewall or proxy', 'wp-security-audit-log' ); ?>
|
|
|
300 |
</label>
|
301 |
<br/>
|
302 |
+
<span class="description"><?php esc_html_e( 'Enable this option if your WordPress is running behind a firewall or reverse proxy. When this option is enabled the plugin will retrieve the user\'s IP address from the proxy header.', 'wp-security-audit-log' ); ?></span>
|
303 |
<br/>
|
304 |
<label for="EnableIpFiltering">
|
305 |
+
<input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering" <?php checked( $this->_plugin->settings->IsInternalIPsFiltered() ); ?> />
|
306 |
+
<?php esc_html_e( 'Filter Internal IP Addresses', 'wp-security-audit-log' ); ?>
|
|
|
307 |
</label>
|
308 |
<br/>
|
309 |
+
<span class="description"><?php esc_html_e( 'Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log' ); ?></span>
|
310 |
</fieldset>
|
311 |
</td>
|
312 |
</tr>
|
313 |
<!-- Can Manage Plugin -->
|
314 |
<tr>
|
315 |
+
<th><label for="EditorQueryBox"><?php esc_html_e( 'Can Manage Plugin', 'wp-security-audit-log' ); ?></label></th>
|
316 |
<td>
|
317 |
<fieldset>
|
318 |
<input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
|
319 |
<input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
320 |
<br style="clear: both;"/>
|
321 |
+
<p class="description">
|
322 |
+
<?php esc_html_e( 'Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log' ); ?>
|
323 |
+
</p>
|
324 |
+
<div id="EditorList">
|
325 |
+
<?php foreach ( $this->_plugin->settings->GetAllowedPluginEditors() as $item ) : ?>
|
326 |
+
<span class="sectoken-<?php echo esc_attr( $this->GetTokenType( $item ) ); ?>">
|
327 |
+
<input type="hidden" name="Editors[]" value="<?php echo esc_attr( $item ); ?>"/>
|
328 |
+
<?php echo esc_html( $item ); ?>
|
329 |
+
<?php if ( wp_get_current_user()->user_login !== $item ) { ?>
|
330 |
<a href="javascript:;" title="Remove">×</a>
|
331 |
<?php } ?>
|
332 |
+
</span>
|
333 |
+
<?php endforeach; ?>
|
334 |
+
</div>
|
335 |
</fieldset>
|
336 |
</td>
|
337 |
</tr>
|
338 |
<!-- Restrict Plugin Access -->
|
339 |
<tr>
|
340 |
+
<th><label for="RestrictAdmins"><?php esc_html_e( 'Restrict Plugin Access', 'wp-security-audit-log' ); ?></label></th>
|
341 |
<td>
|
342 |
<fieldset>
|
343 |
+
<input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr( wp_get_current_user()->user_login ); ?>"/>
|
344 |
<label for="RestrictAdmins">
|
345 |
<?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
|
346 |
+
<input type="checkbox" name="RestrictAdmins" id="RestrictAdmins" <?php checked( $ira ); ?> />
|
347 |
</label>
|
348 |
<br/>
|
349 |
<span class="description">
|
350 |
+
<?php esc_html_e( 'If this option is disabled all the administrators on this WordPress have access to manage this plugin.', 'wp-security-audit-log' ); ?><br/>
|
351 |
+
<?php echo wp_kses( __( 'By enabling this option only <strong>You</strong> and the users specified in the <strong>Can Manage Plugin</strong> and <strong>Can View Alerts</strong> can configure this plugin or view the alerts in the WordPress audit trail.', 'wp-security-audit-log' ), $this->_plugin->allowed_html_tags ); ?>
|
352 |
</span>
|
353 |
</fieldset>
|
354 |
</td>
|
355 |
</tr>
|
356 |
<!-- Developer Options -->
|
357 |
<tr>
|
358 |
+
<th><label><?php esc_html_e( 'Developer Options', 'wp-security-audit-log' ); ?></label></th>
|
359 |
<td>
|
360 |
<fieldset>
|
361 |
<?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
|
362 |
+
<a href="javascript:;" style="<?php echo ( $any ) ? 'display: none;' : false; ?>"
|
363 |
+
onclick="jQuery(this).hide().next().show();">
|
364 |
+
<?php esc_html_e( 'Show Developer Options', 'wp-security-audit-log' ); ?>
|
365 |
+
</a>
|
366 |
+
<div style="<?php echo ( ! $any ) ? 'display: none;' : false; ?>">
|
367 |
<p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;">
|
368 |
+
<?php esc_html_e( 'Only enable these options on testing, staging and development websites. Enabling any of the settings below on LIVE websites may cause unintended side-effects including degraded performance.', 'wp-security-audit-log' ); ?>
|
369 |
</p>
|
370 |
<?php
|
371 |
+
foreach ( array(
|
372 |
+
WSAL_Settings::OPT_DEV_DATA_INSPECTOR => array(
|
373 |
+
__( 'Data Inspector', 'wp-security-audit-log' ),
|
374 |
+
__( 'View data logged for each triggered alert.', 'wp-security-audit-log' ),
|
375 |
+
),
|
376 |
+
/**
|
377 |
+
WSAL_Settings::OPT_DEV_PHP_ERRORS => array(
|
378 |
+
__('PHP Errors', 'wp-security-audit-log'),
|
379 |
+
__('Enables sensor for alerts generated from PHP.', 'wp-security-audit-log')
|
380 |
+
), */
|
381 |
+
WSAL_Settings::OPT_DEV_REQUEST_LOG => array(
|
382 |
+
__( 'Request Log', 'wp-security-audit-log' ),
|
383 |
+
__( 'Enables logging request to file.', 'wp-security-audit-log' ),
|
384 |
+
),
|
385 |
+
/**
|
386 |
+
WSAL_Settings::OPT_DEV_BACKTRACE_LOG => array(
|
387 |
+
__('Backtrace', 'wp-security-audit-log'),
|
388 |
+
__('Log full backtrace for PHP-generated alerts.', 'wp-security-audit-log')
|
389 |
+
), */
|
390 |
+
) as $opt => $info ) {
|
391 |
+
?>
|
392 |
+
<label for="devoption_<?php echo esc_attr( $opt ); ?>">
|
393 |
+
<input type="checkbox" name="DevOptions[]" id="devoption_<?php echo esc_attr( $opt ); ?>"
|
394 |
+
<?php checked( $this->_plugin->settings->IsDevOptionEnabled( $opt ) ); ?>
|
395 |
+
value="<?php echo esc_attr( $opt ); ?>">
|
396 |
+
<span><?php echo esc_html( $info[0] ); ?></span>
|
397 |
+
<!-- Title -->
|
398 |
+
<?php if ( isset( $info[1] ) && $info[1] ) : ?>
|
399 |
+
<span class="description"> — <?php echo esc_html( $info[1] ); ?></span>
|
400 |
+
<?php endif; ?>
|
401 |
+
<!-- Description -->
|
402 |
+
</label><br/>
|
403 |
+
<?php
|
404 |
+
}
|
405 |
?>
|
406 |
<span class="description">
|
407 |
+
<?php esc_html_e( 'The request log file is saved in the /wp-content/uploads/wp-security-audit-log/ directory.', 'wp-security-audit-log' ); ?>
|
408 |
</span>
|
409 |
</div>
|
410 |
</fieldset>
|
412 |
</tr>
|
413 |
<!-- Hide Plugin in Plugins Page -->
|
414 |
<tr>
|
415 |
+
<th><label for="Incognito"><?php esc_html_e( 'Hide Plugin in Plugins Page', 'wp-security-audit-log' ); ?></label></th>
|
416 |
<td>
|
417 |
<fieldset>
|
418 |
<label for="Incognito">
|
419 |
+
<input type="checkbox" name="Incognito" value="1" id="Incognito" <?php checked( $this->_plugin->settings->IsIncognito() ); ?> />
|
420 |
+
<?php esc_html_e( 'Hide', 'wp-security-audit-log' ); ?>
|
|
|
421 |
</label>
|
422 |
<br/>
|
423 |
<span class="description">
|
424 |
+
<?php esc_html_e( 'To manually revert this setting set the value of option wsal-hide-plugin to 0 in the wp_wsal_options table.', 'wp-security-audit-log' ); ?>
|
425 |
</span>
|
426 |
</fieldset>
|
427 |
</td>
|
428 |
</tr>
|
429 |
<!-- Logging -->
|
430 |
<tr>
|
431 |
+
<th><label for="Logging"><?php esc_html_e( 'Logging', 'wp-security-audit-log' ); ?></label></th>
|
432 |
<td>
|
433 |
<fieldset>
|
434 |
<label for="Logging">
|
442 |
</label>
|
443 |
<br/>
|
444 |
<span class="description">
|
445 |
+
<?php esc_html_e( 'Disable all plugin logging.', 'wp-security-audit-log' ); ?>
|
446 |
</span>
|
447 |
</fieldset>
|
448 |
</td>
|
449 |
</tr>
|
450 |
<!-- Remove Data on Uninstall -->
|
451 |
<tr>
|
452 |
+
<th><label for="DeleteData"><?php esc_html_e( 'Remove Data on Uninstall', 'wp-security-audit-log' ); ?></label></th>
|
453 |
<td>
|
454 |
<fieldset>
|
455 |
<label for="DeleteData">
|
456 |
+
<input type="checkbox" name="DeleteData" value="1" id="DeleteData" onclick="return delete_confirm(this);"
|
457 |
+
<?php checked( $this->_plugin->settings->IsDeleteData() ); ?> />
|
458 |
+
<span class="description">
|
459 |
+
<?php esc_html_e( 'Check this box if you would like remove all data when the plugin is deleted.', 'wp-security-audit-log' ); ?>
|
460 |
+
</span>
|
461 |
</label>
|
462 |
</fieldset>
|
463 |
</td>
|
469 |
<tbody>
|
470 |
<!-- Security Alerts Pruning -->
|
471 |
<?php
|
472 |
+
$disabled = '';
|
473 |
+
if ( $this->_plugin->settings->IsArchivingEnabled() ) {
|
474 |
$disabled = 'disabled';
|
475 |
?>
|
476 |
<tr>
|
477 |
<td colspan="2">
|
478 |
+
<?php esc_html_e( 'The options below are disabled because you enabled archiving of alerts to the archiving table from', 'wp-security-audit-log' ); ?> <a href="<?php echo esc_url( admin_url( 'admin.php?page=wsal-ext-settings#mirroring' ) ); ?>" target="_blank">here</a>
|
479 |
</td>
|
480 |
</tr>
|
481 |
<?php } ?>
|
482 |
<tr>
|
483 |
+
<th><label for="delete1"><?php esc_html_e( 'Security Alerts Pruning', 'wp-security-audit-log' ); ?></label></th>
|
484 |
<td>
|
485 |
<fieldset>
|
486 |
+
<?php $text = __( '(eg: 1 month)', 'wp-security-audit-log' ); ?>
|
487 |
+
<?php $nbld = ! ($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
|
488 |
<label for="delete0">
|
489 |
+
|
|