Version Description
(2016-06-01) =
-
New Add-On Support
- Included code to support the new Users Sessions Management Add-On, which allows you to see who is logged in to your WordPress and WordPress multisite networks.
-
New Alerts in the WordPress Audit Trail
- 1004: A login attempt was blocked because a session with the same username already exists
- 1005: Multiple logged-in sessions for the same WordPress username has been detected
-
Improvement
- Plugin reports changes when an object is moved as a sub object in a menu.
-
Bug fixes
- Fixed a problem where wrong permissions were assigned to the reports directory in the uploads directory for the Reports Add-On.
- Fixed an issue where multiple incorrect changes were reported when changing the structure of a menu Support ticket.
- Fixed a bug in the settings sensor support ticket.
Download this release
Release Info
Developer | WPWhiteSecurity |
Plugin | WP Security Audit Log |
Version | 2.4.3 |
Comparing to | |
See all releases |
Code changes from version 2.4.2 to 2.4.3
- classes/AbstractLogger.php +13 -13
- classes/AbstractSandboxTask.php +68 -68
- classes/AbstractSensor.php +42 -42
- classes/AbstractView.php +180 -180
- classes/Alert.php +98 -98
- classes/AlertManager.php +382 -382
- classes/AuditLogListView.php +452 -445
- classes/Autoloader.php +69 -69
- classes/Connector/AbstractConnector.php +36 -36
- classes/Connector/ConnectorFactory.php +87 -87
- classes/Connector/ConnectorInterface.php +11 -11
- classes/Connector/MySQLDBConnector.php +337 -337
- classes/Connector/wp-db-custom.php +36 -36
- classes/ConstantManager.php +88 -88
- classes/EDD_SL_Plugin_Updater.php +170 -170
- classes/Helpers/DataHelper.php +22 -22
- classes/LicenseManager.php +171 -171
- classes/Models/ActiveRecord.php +280 -267
- classes/Models/Adapters/ActiveRecordInterface.php +15 -15
- classes/Models/Adapters/MetaInterface.php +13 -13
- classes/Models/Adapters/MySQL/ActiveRecordAdapter.php +448 -448
- classes/Models/Adapters/MySQL/MetaAdapter.php +53 -53
- classes/Models/Adapters/MySQL/OccurrenceAdapter.php +187 -187
- classes/Models/Adapters/MySQL/OptionAdapter.php +79 -79
- classes/Models/Adapters/MySQL/QueryAdapter.php +219 -219
- classes/Models/Adapters/OccurrenceInterface.php +11 -11
- classes/Models/Adapters/QueryInterface.php +8 -8
- classes/Models/Meta.php +34 -34
- classes/Models/Occurrence.php +199 -199
- classes/Models/OccurrenceQuery.php +29 -29
- classes/Models/Option.php +80 -80
- classes/Models/Query.php +187 -187
- classes/Nicer.php +289 -289
- classes/SensorManager.php +49 -49
- classes/Sensors/BBPress.php +412 -412
- classes/Sensors/Content.php +635 -635
- classes/Sensors/CustomHooks.php +49 -49
- classes/Sensors/Database.php +132 -132
- classes/Sensors/Files.php +55 -55
- classes/Sensors/LogInOut.php +215 -182
- classes/Sensors/Menus.php +416 -416
- classes/Sensors/MetaData.php +208 -208
- classes/Sensors/Multisite.php +129 -129
- classes/Sensors/PhpErrors.php +104 -104
- classes/Sensors/PluginsThemes.php +215 -215
- classes/Sensors/Request.php +40 -40
- classes/Sensors/System.php +168 -168
- classes/Sensors/UserProfile.php +164 -164
- classes/Sensors/Widgets.php +234 -234
- classes/Settings.php +639 -639
- classes/SimpleProfiler.php +43 -43
- classes/ViewManager.php +214 -214
- classes/Views/About.php +85 -85
- classes/Views/AuditLog.php +177 -177
- classes/Views/Help.php +78 -76
- classes/Views/Licensing.php +87 -87
- classes/Views/Settings.php +682 -682
- classes/Views/ToggleAlerts.php +150 -150
- classes/WidgetManager.php +79 -79
- css/auditlog.css +180 -180
- css/install-error.css +41 -41
- css/nice_r.css +92 -92
- css/settings.css +70 -70
- defaults.php +3 -0
- js/auditlog.js +149 -149
- js/common.js +17 -17
- js/nice_r.js +11 -11
- js/settings.js +73 -73
- readme.txt +55 -42
- uninstall.php +6 -6
- wp-security-audit-log.php +1 -1
classes/AbstractLogger.php
CHANGED
@@ -1,14 +1,14 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
abstract class WSAL_AbstractLogger {
|
4 |
-
/**
|
5 |
-
* @var WpSecurityAuditLog
|
6 |
-
*/
|
7 |
-
protected $plugin;
|
8 |
-
|
9 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
10 |
-
$this->plugin = $plugin;
|
11 |
-
}
|
12 |
-
|
13 |
-
public abstract function Log($type, $data = array(), $date = null, $siteid = null, $migrated = false);
|
14 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class WSAL_AbstractLogger {
|
4 |
+
/**
|
5 |
+
* @var WpSecurityAuditLog
|
6 |
+
*/
|
7 |
+
protected $plugin;
|
8 |
+
|
9 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
10 |
+
$this->plugin = $plugin;
|
11 |
+
}
|
12 |
+
|
13 |
+
public abstract function Log($type, $data = array(), $date = null, $siteid = null, $migrated = false);
|
14 |
}
|
classes/AbstractSandboxTask.php
CHANGED
@@ -1,68 +1,68 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
abstract class WSAL_AbstractSandboxTask {
|
4 |
-
public function __construct() {
|
5 |
-
// remove time limit and clear output buffers
|
6 |
-
set_time_limit(0);
|
7 |
-
ob_implicit_flush(true);
|
8 |
-
while(ob_get_level())ob_end_flush();
|
9 |
-
|
10 |
-
// set up shutdown handler
|
11 |
-
register_shutdown_function(array($this, 'Shutdown'));
|
12 |
-
|
13 |
-
// run event sequence
|
14 |
-
$this->Header();
|
15 |
-
try{
|
16 |
-
$this->Execute();
|
17 |
-
}catch(Exception $ex){
|
18 |
-
$this->Message(get_class($ex) . ' [' . basename($ex->getFile()) . ':' . $ex->getLine() . ']: ' . $ex->getMessage());
|
19 |
-
$this->Message($ex->getTraceAsString(), true);
|
20 |
-
}
|
21 |
-
$this->Footer();
|
22 |
-
|
23 |
-
// shutdown
|
24 |
-
die();
|
25 |
-
}
|
26 |
-
|
27 |
-
protected function Header(){
|
28 |
-
echo '<!DOCTYPE html><html><body style="margin: 0; padding: 8px; font: 12px Arial; color: #333;">';
|
29 |
-
echo '<div style="position: fixed; top: 0; left: 0; right: 0; padding: 8px; background: #F0F0F0;">';
|
30 |
-
echo ' <div id="bar" style=" border-top: 2px solid #0AE; top: 20px; height: 0; width: 0%;"> </div>';
|
31 |
-
echo ' <span id="msg"></span> <span id="prg"></span>';
|
32 |
-
echo '</div>';
|
33 |
-
echo '<div id="msgs" style="font-family: Consolas; margin-top: 30px; white-space: pre;"></div>';
|
34 |
-
echo '<script>';
|
35 |
-
echo ' var bar = document.getElementById("bar");';
|
36 |
-
echo ' var msg = document.getElementById("msg");';
|
37 |
-
echo ' var prg = document.getElementById("prg");';
|
38 |
-
echo ' var msgs = document.getElementById("msgs");';
|
39 |
-
echo '</script>';
|
40 |
-
flush();
|
41 |
-
}
|
42 |
-
|
43 |
-
protected function Footer(){
|
44 |
-
echo '<div style="display: none;">';
|
45 |
-
flush();
|
46 |
-
}
|
47 |
-
|
48 |
-
protected abstract function Execute();
|
49 |
-
|
50 |
-
public function Shutdown(){
|
51 |
-
echo '</div></body></html>';
|
52 |
-
flush();
|
53 |
-
}
|
54 |
-
|
55 |
-
protected function Progress($percent){
|
56 |
-
echo '<script>bar.style.width=prg.innerHTML="' . number_format($percent, 2) . '%";</script>';
|
57 |
-
flush();
|
58 |
-
}
|
59 |
-
|
60 |
-
protected function Message($message, $sticky = false){
|
61 |
-
if($sticky){
|
62 |
-
echo '<script>msgs.appendChild(document.createTextNode(' . json_encode($message . PHP_EOL) . ')); window.scroll(0, document.body.scrollHeight);</script>';
|
63 |
-
}else{
|
64 |
-
echo '<script>msg.innerHTML=' . json_encode($message) . ';</script>';
|
65 |
-
}
|
66 |
-
flush();
|
67 |
-
}
|
68 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class WSAL_AbstractSandboxTask {
|
4 |
+
public function __construct() {
|
5 |
+
// remove time limit and clear output buffers
|
6 |
+
set_time_limit(0);
|
7 |
+
ob_implicit_flush(true);
|
8 |
+
while(ob_get_level())ob_end_flush();
|
9 |
+
|
10 |
+
// set up shutdown handler
|
11 |
+
register_shutdown_function(array($this, 'Shutdown'));
|
12 |
+
|
13 |
+
// run event sequence
|
14 |
+
$this->Header();
|
15 |
+
try{
|
16 |
+
$this->Execute();
|
17 |
+
}catch(Exception $ex){
|
18 |
+
$this->Message(get_class($ex) . ' [' . basename($ex->getFile()) . ':' . $ex->getLine() . ']: ' . $ex->getMessage());
|
19 |
+
$this->Message($ex->getTraceAsString(), true);
|
20 |
+
}
|
21 |
+
$this->Footer();
|
22 |
+
|
23 |
+
// shutdown
|
24 |
+
die();
|
25 |
+
}
|
26 |
+
|
27 |
+
protected function Header(){
|
28 |
+
echo '<!DOCTYPE html><html><body style="margin: 0; padding: 8px; font: 12px Arial; color: #333;">';
|
29 |
+
echo '<div style="position: fixed; top: 0; left: 0; right: 0; padding: 8px; background: #F0F0F0;">';
|
30 |
+
echo ' <div id="bar" style=" border-top: 2px solid #0AE; top: 20px; height: 0; width: 0%;"> </div>';
|
31 |
+
echo ' <span id="msg"></span> <span id="prg"></span>';
|
32 |
+
echo '</div>';
|
33 |
+
echo '<div id="msgs" style="font-family: Consolas; margin-top: 30px; white-space: pre;"></div>';
|
34 |
+
echo '<script>';
|
35 |
+
echo ' var bar = document.getElementById("bar");';
|
36 |
+
echo ' var msg = document.getElementById("msg");';
|
37 |
+
echo ' var prg = document.getElementById("prg");';
|
38 |
+
echo ' var msgs = document.getElementById("msgs");';
|
39 |
+
echo '</script>';
|
40 |
+
flush();
|
41 |
+
}
|
42 |
+
|
43 |
+
protected function Footer(){
|
44 |
+
echo '<div style="display: none;">';
|
45 |
+
flush();
|
46 |
+
}
|
47 |
+
|
48 |
+
protected abstract function Execute();
|
49 |
+
|
50 |
+
public function Shutdown(){
|
51 |
+
echo '</div></body></html>';
|
52 |
+
flush();
|
53 |
+
}
|
54 |
+
|
55 |
+
protected function Progress($percent){
|
56 |
+
echo '<script>bar.style.width=prg.innerHTML="' . number_format($percent, 2) . '%";</script>';
|
57 |
+
flush();
|
58 |
+
}
|
59 |
+
|
60 |
+
protected function Message($message, $sticky = false){
|
61 |
+
if($sticky){
|
62 |
+
echo '<script>msgs.appendChild(document.createTextNode(' . json_encode($message . PHP_EOL) . ')); window.scroll(0, document.body.scrollHeight);</script>';
|
63 |
+
}else{
|
64 |
+
echo '<script>msg.innerHTML=' . json_encode($message) . ';</script>';
|
65 |
+
}
|
66 |
+
flush();
|
67 |
+
}
|
68 |
+
}
|
classes/AbstractSensor.php
CHANGED
@@ -1,43 +1,43 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
abstract class WSAL_AbstractSensor {
|
4 |
-
/**
|
5 |
-
* @var WpSecurityAuditLog
|
6 |
-
*/
|
7 |
-
protected $plugin;
|
8 |
-
|
9 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
10 |
-
$this->plugin = $plugin;
|
11 |
-
}
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @return boolean Whether we are running on multisite or not.
|
15 |
-
*/
|
16 |
-
protected function IsMultisite()
|
17 |
-
{
|
18 |
-
return function_exists('is_multisite') && is_multisite();
|
19 |
-
}
|
20 |
-
|
21 |
-
abstract function HookEvents();
|
22 |
-
|
23 |
-
protected function Log($type, $message, $args){
|
24 |
-
$this->plugin->alerts->Trigger($type, array(
|
25 |
-
'Message' => $message,
|
26 |
-
'Context' => $args,
|
27 |
-
'Trace' => debug_backtrace(),
|
28 |
-
));
|
29 |
-
}
|
30 |
-
|
31 |
-
protected function LogError($message, $args){
|
32 |
-
$this->Log(0001, $message, $args);
|
33 |
-
}
|
34 |
-
|
35 |
-
protected function LogWarn($message, $args){
|
36 |
-
$this->Log(0002, $message, $args);
|
37 |
-
}
|
38 |
-
|
39 |
-
protected function LogInfo($message, $args){
|
40 |
-
$this->Log(0003, $message, $args);
|
41 |
-
}
|
42 |
-
|
43 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class WSAL_AbstractSensor {
|
4 |
+
/**
|
5 |
+
* @var WpSecurityAuditLog
|
6 |
+
*/
|
7 |
+
protected $plugin;
|
8 |
+
|
9 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
10 |
+
$this->plugin = $plugin;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @return boolean Whether we are running on multisite or not.
|
15 |
+
*/
|
16 |
+
protected function IsMultisite()
|
17 |
+
{
|
18 |
+
return function_exists('is_multisite') && is_multisite();
|
19 |
+
}
|
20 |
+
|
21 |
+
abstract function HookEvents();
|
22 |
+
|
23 |
+
protected function Log($type, $message, $args){
|
24 |
+
$this->plugin->alerts->Trigger($type, array(
|
25 |
+
'Message' => $message,
|
26 |
+
'Context' => $args,
|
27 |
+
'Trace' => debug_backtrace(),
|
28 |
+
));
|
29 |
+
}
|
30 |
+
|
31 |
+
protected function LogError($message, $args){
|
32 |
+
$this->Log(0001, $message, $args);
|
33 |
+
}
|
34 |
+
|
35 |
+
protected function LogWarn($message, $args){
|
36 |
+
$this->Log(0002, $message, $args);
|
37 |
+
}
|
38 |
+
|
39 |
+
protected function LogInfo($message, $args){
|
40 |
+
$this->Log(0003, $message, $args);
|
41 |
+
}
|
42 |
+
|
43 |
}
|
classes/AbstractView.php
CHANGED
@@ -1,181 +1,181 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
abstract class WSAL_AbstractView {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var WpSecurityAuditLog
|
7 |
-
*/
|
8 |
-
protected $_plugin;
|
9 |
-
|
10 |
-
protected $_wpversion;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* Contains the result to a call to add_submenu_page().
|
14 |
-
* @var string
|
15 |
-
*/
|
16 |
-
public $hook_suffix = '';
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Tells us whether this view is currently being displayed or not.
|
20 |
-
* @var boolean
|
21 |
-
*/
|
22 |
-
public $is_active = false;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @param WpSecurityAuditLog $plugin
|
26 |
-
*/
|
27 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
28 |
-
$this->_plugin = $plugin;
|
29 |
-
|
30 |
-
// get and store wordpress version
|
31 |
-
global $wp_version;
|
32 |
-
if(!isset($wp_version))
|
33 |
-
$wp_version = get_bloginfo('version');
|
34 |
-
$this->_wpversion = floatval($wp_version);
|
35 |
-
|
36 |
-
// handle admin notices
|
37 |
-
add_action('wp_ajax_AjaxDismissNotice', array($this, 'AjaxDismissNotice'));
|
38 |
-
}
|
39 |
-
|
40 |
-
public static $AllowedNoticeNames = array();
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Dismiss an admin notice through ajax.
|
44 |
-
* @internal
|
45 |
-
*/
|
46 |
-
public function AjaxDismissNotice(){
|
47 |
-
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
48 |
-
die('Access Denied.');
|
49 |
-
|
50 |
-
if(!isset($_REQUEST['notice']))
|
51 |
-
die('Notice name expected as "notice" parameter.');
|
52 |
-
|
53 |
-
$this->DismissNotice($_REQUEST['notice']);
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* @param string $name Name of notice.
|
58 |
-
* @return boolean Whether notice got dismissed or not.
|
59 |
-
*/
|
60 |
-
public function IsNoticeDismissed($name){
|
61 |
-
$user_id = get_current_user_id();
|
62 |
-
$meta_key = 'wsal-notice-' . $name;
|
63 |
-
self::$AllowedNoticeNames[] = $name;
|
64 |
-
return !!get_user_meta($user_id, $meta_key, true);
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* @param string $name Name of notice to dismiss.
|
69 |
-
*/
|
70 |
-
public function DismissNotice($name){
|
71 |
-
$user_id = get_current_user_id();
|
72 |
-
$meta_key = 'wsal-notice-' . $name;
|
73 |
-
$old_value = get_user_meta($user_id, $meta_key, true);
|
74 |
-
if (in_array($name, self::$AllowedNoticeNames) || $old_value === false)
|
75 |
-
update_user_meta($user_id, $meta_key, '1');
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* @param string $name Makes this notice available.
|
80 |
-
*/
|
81 |
-
public function RegisterNotice($name){
|
82 |
-
self::$AllowedNoticeNames[] = $name;
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @return string Return page name (for menu etc).
|
87 |
-
*/
|
88 |
-
abstract public function GetName();
|
89 |
-
|
90 |
-
/**
|
91 |
-
* @return string Return page title.
|
92 |
-
*/
|
93 |
-
abstract public function GetTitle();
|
94 |
-
|
95 |
-
/**
|
96 |
-
* @return string Page icon name.
|
97 |
-
*/
|
98 |
-
abstract public function GetIcon();
|
99 |
-
|
100 |
-
/**
|
101 |
-
* @return int Menu weight, the higher this is, the lower it goes.
|
102 |
-
*/
|
103 |
-
abstract public function GetWeight();
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Renders and outputs the view directly.
|
107 |
-
*/
|
108 |
-
abstract public function Render();
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Renders the view icon (this has been deprecated in newwer WP versions).
|
112 |
-
*/
|
113 |
-
public function RenderIcon(){
|
114 |
-
?><div id="icon-plugins" class="icon32"><br></div><?php
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Renders the view title.
|
119 |
-
*/
|
120 |
-
public function RenderTitle(){
|
121 |
-
?><h2><?php echo esc_html($this->GetTitle()); ?></h2><?php
|
122 |
-
}
|
123 |
-
|
124 |
-
/**
|
125 |
-
* @link self::Render()
|
126 |
-
*/
|
127 |
-
public function RenderContent(){
|
128 |
-
$this->Render();
|
129 |
-
}
|
130 |
-
|
131 |
-
/**
|
132 |
-
* @return boolean Whether page should appear in menu or not.
|
133 |
-
*/
|
134 |
-
public function IsVisible(){ return true; }
|
135 |
-
|
136 |
-
/**
|
137 |
-
* @return boolean Whether page should be accessible or not.
|
138 |
-
*/
|
139 |
-
public function IsAccessible(){ return true; }
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Used for rendering stuff into head tag.
|
143 |
-
*/
|
144 |
-
public function Header(){}
|
145 |
-
|
146 |
-
/**
|
147 |
-
* Used for rendering stuff in page fotoer.
|
148 |
-
*/
|
149 |
-
public function Footer(){}
|
150 |
-
|
151 |
-
/**
|
152 |
-
* @return string Safe view menu name.
|
153 |
-
*/
|
154 |
-
public function GetSafeViewName(){
|
155 |
-
return 'wsal-' . preg_replace('/[^A-Za-z0-9\-]/', '-', $this->GetViewName());
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Override this and make it return true to create a shortcut link in plugin page to the view.
|
160 |
-
* @return boolean
|
161 |
-
*/
|
162 |
-
public function HasPluginShortcutLink(){
|
163 |
-
return false;
|
164 |
-
}
|
165 |
-
|
166 |
-
/**
|
167 |
-
* @return string URL to backend page for displaying view.
|
168 |
-
*/
|
169 |
-
public function GetUrl(){
|
170 |
-
$fn = function_exists('network_admin_url') ? 'network_admin_url' : 'admin_url';
|
171 |
-
return $fn('admin.php?page=' . $this->GetSafeViewName());
|
172 |
-
}
|
173 |
-
|
174 |
-
/**
|
175 |
-
* @return string Generates view name out of class name.
|
176 |
-
*/
|
177 |
-
public function GetViewName(){
|
178 |
-
return strtolower(str_replace(array('WSAL_Views_', 'WSAL_'), '', get_class($this)));
|
179 |
-
}
|
180 |
-
|
181 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class WSAL_AbstractView {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var WpSecurityAuditLog
|
7 |
+
*/
|
8 |
+
protected $_plugin;
|
9 |
+
|
10 |
+
protected $_wpversion;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Contains the result to a call to add_submenu_page().
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
public $hook_suffix = '';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Tells us whether this view is currently being displayed or not.
|
20 |
+
* @var boolean
|
21 |
+
*/
|
22 |
+
public $is_active = false;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @param WpSecurityAuditLog $plugin
|
26 |
+
*/
|
27 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
28 |
+
$this->_plugin = $plugin;
|
29 |
+
|
30 |
+
// get and store wordpress version
|
31 |
+
global $wp_version;
|
32 |
+
if(!isset($wp_version))
|
33 |
+
$wp_version = get_bloginfo('version');
|
34 |
+
$this->_wpversion = floatval($wp_version);
|
35 |
+
|
36 |
+
// handle admin notices
|
37 |
+
add_action('wp_ajax_AjaxDismissNotice', array($this, 'AjaxDismissNotice'));
|
38 |
+
}
|
39 |
+
|
40 |
+
public static $AllowedNoticeNames = array();
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Dismiss an admin notice through ajax.
|
44 |
+
* @internal
|
45 |
+
*/
|
46 |
+
public function AjaxDismissNotice(){
|
47 |
+
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
48 |
+
die('Access Denied.');
|
49 |
+
|
50 |
+
if(!isset($_REQUEST['notice']))
|
51 |
+
die('Notice name expected as "notice" parameter.');
|
52 |
+
|
53 |
+
$this->DismissNotice($_REQUEST['notice']);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @param string $name Name of notice.
|
58 |
+
* @return boolean Whether notice got dismissed or not.
|
59 |
+
*/
|
60 |
+
public function IsNoticeDismissed($name){
|
61 |
+
$user_id = get_current_user_id();
|
62 |
+
$meta_key = 'wsal-notice-' . $name;
|
63 |
+
self::$AllowedNoticeNames[] = $name;
|
64 |
+
return !!get_user_meta($user_id, $meta_key, true);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @param string $name Name of notice to dismiss.
|
69 |
+
*/
|
70 |
+
public function DismissNotice($name){
|
71 |
+
$user_id = get_current_user_id();
|
72 |
+
$meta_key = 'wsal-notice-' . $name;
|
73 |
+
$old_value = get_user_meta($user_id, $meta_key, true);
|
74 |
+
if (in_array($name, self::$AllowedNoticeNames) || $old_value === false)
|
75 |
+
update_user_meta($user_id, $meta_key, '1');
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @param string $name Makes this notice available.
|
80 |
+
*/
|
81 |
+
public function RegisterNotice($name){
|
82 |
+
self::$AllowedNoticeNames[] = $name;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @return string Return page name (for menu etc).
|
87 |
+
*/
|
88 |
+
abstract public function GetName();
|
89 |
+
|
90 |
+
/**
|
91 |
+
* @return string Return page title.
|
92 |
+
*/
|
93 |
+
abstract public function GetTitle();
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @return string Page icon name.
|
97 |
+
*/
|
98 |
+
abstract public function GetIcon();
|
99 |
+
|
100 |
+
/**
|
101 |
+
* @return int Menu weight, the higher this is, the lower it goes.
|
102 |
+
*/
|
103 |
+
abstract public function GetWeight();
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Renders and outputs the view directly.
|
107 |
+
*/
|
108 |
+
abstract public function Render();
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Renders the view icon (this has been deprecated in newwer WP versions).
|
112 |
+
*/
|
113 |
+
public function RenderIcon(){
|
114 |
+
?><div id="icon-plugins" class="icon32"><br></div><?php
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Renders the view title.
|
119 |
+
*/
|
120 |
+
public function RenderTitle(){
|
121 |
+
?><h2><?php echo esc_html($this->GetTitle()); ?></h2><?php
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* @link self::Render()
|
126 |
+
*/
|
127 |
+
public function RenderContent(){
|
128 |
+
$this->Render();
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* @return boolean Whether page should appear in menu or not.
|
133 |
+
*/
|
134 |
+
public function IsVisible(){ return true; }
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return boolean Whether page should be accessible or not.
|
138 |
+
*/
|
139 |
+
public function IsAccessible(){ return true; }
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Used for rendering stuff into head tag.
|
143 |
+
*/
|
144 |
+
public function Header(){}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Used for rendering stuff in page fotoer.
|
148 |
+
*/
|
149 |
+
public function Footer(){}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* @return string Safe view menu name.
|
153 |
+
*/
|
154 |
+
public function GetSafeViewName(){
|
155 |
+
return 'wsal-' . preg_replace('/[^A-Za-z0-9\-]/', '-', $this->GetViewName());
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Override this and make it return true to create a shortcut link in plugin page to the view.
|
160 |
+
* @return boolean
|
161 |
+
*/
|
162 |
+
public function HasPluginShortcutLink(){
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* @return string URL to backend page for displaying view.
|
168 |
+
*/
|
169 |
+
public function GetUrl(){
|
170 |
+
$fn = function_exists('network_admin_url') ? 'network_admin_url' : 'admin_url';
|
171 |
+
return $fn('admin.php?page=' . $this->GetSafeViewName());
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* @return string Generates view name out of class name.
|
176 |
+
*/
|
177 |
+
public function GetViewName(){
|
178 |
+
return strtolower(str_replace(array('WSAL_Views_', 'WSAL_'), '', get_class($this)));
|
179 |
+
}
|
180 |
+
|
181 |
}
|
classes/Alert.php
CHANGED
@@ -1,98 +1,98 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
final class WSAL_Alert {
|
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 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class WSAL_Alert {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Alert type (used when triggering an alert etc).
|
7 |
+
* @var integer
|
8 |
+
*/
|
9 |
+
public $type = 0;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Alert error level (E_* constant).
|
13 |
+
* @var integer
|
14 |
+
*/
|
15 |
+
public $code = 0;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Alert category (alerts are grouped by matching categories).
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
public $catg = '';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Alert description (ie, describes what happens when alert is triggered).
|
25 |
+
* @var string
|
26 |
+
*/
|
27 |
+
public $desc = '';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Alert message (variables between '%' are expanded to values).
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
public $mesg = '';
|
34 |
+
|
35 |
+
public function __construct($type = 0, $code = 0, $catg = '', $desc = '', $mesg = '') {
|
36 |
+
$this->type = $type;
|
37 |
+
$this->code = $code;
|
38 |
+
$this->catg = $catg;
|
39 |
+
$this->desc = $desc;
|
40 |
+
$this->mesg = $mesg;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Retrieves a value for a particular meta variable expression.
|
45 |
+
* @param string $expr Expression, eg: User->Name looks for a Name property for meta named User.
|
46 |
+
* @param array $metaData (Optional) Meta data relevant to expression.
|
47 |
+
* @return mixed The value nearest to the expression.
|
48 |
+
*/
|
49 |
+
protected function GetMetaExprValue($expr, $metaData = array()){
|
50 |
+
// TODO Handle function calls (and methods?)
|
51 |
+
$expr = explode('->', $expr);
|
52 |
+
$meta = array_shift($expr);
|
53 |
+
$meta = isset($metaData[$meta]) ? $metaData[$meta] : null;
|
54 |
+
foreach($expr as $part){
|
55 |
+
if(is_scalar($meta) || is_null($meta))return $meta; // this isn't 100% correct
|
56 |
+
$meta = is_array($meta) ? $meta[$part] : $meta->$part;
|
57 |
+
}
|
58 |
+
return is_scalar($meta) ? (string)$meta : var_export($meta, true);
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Expands a message with variables by replacing variables with meta data values.
|
63 |
+
* @param string $mesg The original message.
|
64 |
+
* @param array $metaData (Optional) Meta data relevant to message.
|
65 |
+
* @param callable|null $metaFormatter (Optional) Callback for formatting meta values.
|
66 |
+
* @param string $afterMeta (Optional) Some text to put after meta values.
|
67 |
+
* @return string The expanded message.
|
68 |
+
*/
|
69 |
+
protected function GetFormattedMesg($origMesg, $metaData = array(), $metaFormatter = null){
|
70 |
+
// tokenize message with regex
|
71 |
+
$mesg = preg_split('/(%.*?%)/', (string)$origMesg, -1, PREG_SPLIT_DELIM_CAPTURE);
|
72 |
+
if(!is_array($mesg))return (string)$origMesg;
|
73 |
+
// handle tokenized message
|
74 |
+
foreach($mesg as $i => $token){
|
75 |
+
// handle escaped percent sign
|
76 |
+
if($token == '%%'){
|
77 |
+
$mesg[$i] = '%';
|
78 |
+
}else
|
79 |
+
// handle complex expressions
|
80 |
+
if(substr($token, 0, 1) == '%' && substr($token, -1, 1) == '%'){
|
81 |
+
$mesg[$i] = $this->GetMetaExprValue(substr($token, 1, -1), $metaData);
|
82 |
+
if($metaFormatter)$mesg[$i] = call_user_func($metaFormatter, $token, $mesg[$i]);
|
83 |
+
}
|
84 |
+
}
|
85 |
+
// compact message and return
|
86 |
+
return implode('', $mesg);
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @param array $metaData (Optional) Meta data relevant to message.
|
91 |
+
* @param callable|null $metaFormatter (Optional) Meta formatter callback.
|
92 |
+
* @param string|null $mesg (Optional) Override message template to use.
|
93 |
+
* @return string Fully formatted message.
|
94 |
+
*/
|
95 |
+
public function GetMessage($metaData = array(), $metaFormatter = null, $mesg = null){
|
96 |
+
return $this->GetFormattedMesg(is_null($mesg) ? $this->mesg : $mesg, $metaData, $metaFormatter);
|
97 |
+
}
|
98 |
+
}
|
classes/AlertManager.php
CHANGED
@@ -1,382 +1,382 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
final class WSAL_AlertManager {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var WSAL_Alert[]
|
7 |
-
*/
|
8 |
-
protected $_alerts = array();
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var WSAL_AbstractLogger[]
|
12 |
-
*/
|
13 |
-
protected $_loggers = array();
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var WpSecurityAuditLog
|
17 |
-
*/
|
18 |
-
protected $plugin;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Create new AlertManager instance.
|
22 |
-
* @param WpSecurityAuditLog $plugin
|
23 |
-
*/
|
24 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
25 |
-
$this->plugin = $plugin;
|
26 |
-
foreach(glob(dirname(__FILE__) . '/Loggers/*.php') as $file)
|
27 |
-
$this->AddFromFile($file);
|
28 |
-
|
29 |
-
add_action('shutdown', array($this, '_CommitPipeline'));
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Add new logger from file inside autoloader path.
|
34 |
-
* @param string $file Path to file.
|
35 |
-
*/
|
36 |
-
public function AddFromFile($file){
|
37 |
-
$this->AddFromClass($this->plugin->GetClassFileClassName($file));
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Add new logger given class name.
|
42 |
-
* @param string $class Class name.
|
43 |
-
*/
|
44 |
-
public function AddFromClass($class){
|
45 |
-
$this->AddInstance(new $class($this->plugin));
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Add newly created logger to list.
|
50 |
-
* @param WSAL_AbstractLogger $logger The new logger.
|
51 |
-
*/
|
52 |
-
public function AddInstance(WSAL_AbstractLogger $logger){
|
53 |
-
$this->_loggers[] = $logger;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Remove logger by class name.
|
58 |
-
* @param string $class The class name.
|
59 |
-
*/
|
60 |
-
public function RemoveByClass($class){
|
61 |
-
foreach($this->_loggers as $i => $inst)
|
62 |
-
if(get_class($inst) == $class)
|
63 |
-
unset($this->_loggers[$i]);
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Contains a list of alerts to trigger.
|
68 |
-
* @var array
|
69 |
-
*/
|
70 |
-
protected $_pipeline = array();
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Contains an array of alerts that have been triggered for this request.
|
74 |
-
* @var int[]
|
75 |
-
*/
|
76 |
-
protected $_triggered_types = array();
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Trigger an alert.
|
80 |
-
* @param integer $type Alert type.
|
81 |
-
* @param array $data Alert data.
|
82 |
-
*/
|
83 |
-
public function Trigger($type, $data = array(), $delayed = false){
|
84 |
-
$username = wp_get_current_user()->user_login;
|
85 |
-
if (empty($username) && !empty($data["Username"])) {
|
86 |
-
$username = $data['Username'];
|
87 |
-
}
|
88 |
-
$roles = $this->plugin->settings->GetCurrentUserRoles();
|
89 |
-
if (empty($roles) && !empty($data["CurrentUserRoles"])) {
|
90 |
-
$roles = $data['CurrentUserRoles'];
|
91 |
-
}
|
92 |
-
if ($this->IsDisabledIP()) {
|
93 |
-
return;
|
94 |
-
}
|
95 |
-
if ($this->CheckEnableUserRoles($username, $roles)) {
|
96 |
-
if ($delayed) {
|
97 |
-
$this->TriggerIf($type, $data, null);
|
98 |
-
} else {
|
99 |
-
$this->_CommitItem($type, $data, null);
|
100 |
-
}
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Check enable user and roles.
|
106 |
-
* @param string user
|
107 |
-
* @param array roles
|
108 |
-
* @return boolean True if enable false otherwise.
|
109 |
-
*/
|
110 |
-
public function CheckEnableUserRoles($user, $roles) {
|
111 |
-
$is_enable = true;
|
112 |
-
if ( $user != "" && $this->IsDisabledUser($user) ) { $is_enable = false; }
|
113 |
-
if ( $roles != "" && $this->IsDisabledRole($roles) ) { $is_enable = false; }
|
114 |
-
return $is_enable;
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Trigger only if a condition is met at the end of request.
|
119 |
-
* @param integer $type Alert type ID.
|
120 |
-
* @param array $data Alert data.
|
121 |
-
* @param callable $cond A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
122 |
-
*/
|
123 |
-
public function TriggerIf($type, $data, $cond = null) {
|
124 |
-
$username = wp_get_current_user()->user_login;
|
125 |
-
$roles = $this->plugin->settings->GetCurrentUserRoles();
|
126 |
-
|
127 |
-
if ($this->CheckEnableUserRoles($username, $roles)) {
|
128 |
-
$this->_pipeline[] = array(
|
129 |
-
'type' => $type,
|
130 |
-
'data' => $data,
|
131 |
-
'cond' => $cond,
|
132 |
-
);
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* @internal Commit an alert now.
|
138 |
-
*/
|
139 |
-
protected function _CommitItem($type, $data, $cond, $_retry = true)
|
140 |
-
{
|
141 |
-
if(!$cond || !!call_user_func($cond, $this)){
|
142 |
-
if($this->IsEnabled($type)) {
|
143 |
-
if(isset($this->_alerts[$type])){
|
144 |
-
// ok, convert alert to a log entry
|
145 |
-
$this->_triggered_types[] = $type;
|
146 |
-
$this->Log($type, $data);
|
147 |
-
}elseif($_retry){
|
148 |
-
// this is the last attempt at loading alerts from default file
|
149 |
-
$this->plugin->LoadDefaults();
|
150 |
-
return $this->_CommitItem($type, $data, $cond, false);
|
151 |
-
}else{
|
152 |
-
// in general this shouldn't happen, but it could, so we handle it here :)
|
153 |
-
throw new Exception('Alert with code "' . $type . '" has not be registered.');
|
154 |
-
}
|
155 |
-
}
|
156 |
-
}
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* @internal Runs over triggered alerts in pipeline and passes them to loggers.
|
161 |
-
*/
|
162 |
-
public function _CommitPipeline(){
|
163 |
-
foreach($this->_pipeline as $item)
|
164 |
-
$this->_CommitItem($item['type'], $item['data'], $item['cond']);
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* @param integer $type Alert type ID.
|
169 |
-
* @return boolean True if at the end of request an alert of this type will be triggered.
|
170 |
-
*/
|
171 |
-
public function WillTrigger($type){
|
172 |
-
foreach($this->_pipeline as $item)
|
173 |
-
if($item['type'] == $type)
|
174 |
-
return true;
|
175 |
-
return false;
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* @param int $type Alert type ID.
|
180 |
-
* @return boolean True if an alert has been or will be triggered in this request, false otherwise.
|
181 |
-
*/
|
182 |
-
public function WillOrHasTriggered($type){
|
183 |
-
return in_array($type, $this->_triggered_types)
|
184 |
-
|| $this->WillTrigger($type);
|
185 |
-
}
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Register an alert type.
|
189 |
-
* @param array $info Array of [type, code, category, description, message] respectively.
|
190 |
-
*/
|
191 |
-
public function Register($info){
|
192 |
-
if(func_num_args() == 1){
|
193 |
-
// handle single item
|
194 |
-
list($type, $code, $catg, $desc, $mesg) = $info;
|
195 |
-
if(isset($this->_alerts[$type]))
|
196 |
-
throw new Exception("Alert $type already registered with Alert Manager.");
|
197 |
-
$this->_alerts[$type] = new WSAL_Alert($type, $code, $catg, $desc, $mesg);
|
198 |
-
}else{
|
199 |
-
// handle multiple items
|
200 |
-
foreach(func_get_args() as $arg)
|
201 |
-
$this->Register($arg);
|
202 |
-
}
|
203 |
-
}
|
204 |
-
|
205 |
-
/**
|
206 |
-
* Register a whole group of items.
|
207 |
-
* @param array $groups An array with group name as the index and an array of group items as the value.
|
208 |
-
* Item values is an array of [type, code, description, message] respectively.
|
209 |
-
*/
|
210 |
-
public function RegisterGroup($groups){
|
211 |
-
foreach($groups as $name => $group){
|
212 |
-
foreach($group as $item){
|
213 |
-
list($type, $code, $desc, $mesg) = $item;
|
214 |
-
$this->Register(array($type, $code, $name, $desc, $mesg));
|
215 |
-
}
|
216 |
-
}
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Returns whether alert of type $type is enabled or not.
|
221 |
-
* @param integer $type Alert type.
|
222 |
-
* @return boolean True if enabled, false otherwise.
|
223 |
-
*/
|
224 |
-
public function IsEnabled($type){
|
225 |
-
return !in_array($type, $this->GetDisabledAlerts());
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* Disables a set of alerts by type.
|
230 |
-
* @param int[] $types Alert type codes to be disabled.
|
231 |
-
*/
|
232 |
-
public function SetDisabledAlerts($types){
|
233 |
-
$this->plugin->settings->SetDisabledAlerts($types);
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* @return int[] Returns an array of disabled alerts' type code.
|
238 |
-
*/
|
239 |
-
public function GetDisabledAlerts(){
|
240 |
-
return $this->plugin->settings->GetDisabledAlerts();
|
241 |
-
}
|
242 |
-
|
243 |
-
/**
|
244 |
-
* @return WSAL_AbstractLogger[] Returns an array of loaded loggers.
|
245 |
-
*/
|
246 |
-
public function GetLoggers(){
|
247 |
-
return $this->_loggers;
|
248 |
-
}
|
249 |
-
|
250 |
-
/**
|
251 |
-
* Converts an Alert into a Log entry (by invoking loggers).
|
252 |
-
* You should not call this method directly.
|
253 |
-
* @param integer $type Alert type.
|
254 |
-
* @param array $data Misc alert data.
|
255 |
-
*/
|
256 |
-
protected function Log($type, $data = array())
|
257 |
-
{
|
258 |
-
if (!isset($data['ClientIP'])) {
|
259 |
-
$clientIP = $this->plugin->settings->GetMainClientIP();
|
260 |
-
if (!empty($clientIP)) {
|
261 |
-
$data['ClientIP'] = $clientIP;
|
262 |
-
}
|
263 |
-
}
|
264 |
-
if (!isset($data['OtherIPs']) && $this->plugin->settings->IsMainIPFromProxy()) {
|
265 |
-
$otherIPs = $this->plugin->settings->GetClientIPs();
|
266 |
-
if (!empty($otherIPs)) {
|
267 |
-
$data['OtherIPs'] = $otherIPs;
|
268 |
-
}
|
269 |
-
}
|
270 |
-
if (!isset($data['UserAgent'])) {
|
271 |
-
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
272 |
-
$data['UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
|
273 |
-
}
|
274 |
-
}
|
275 |
-
if (!isset($data['Username']) && !isset($data['CurrentUserID'])) {
|
276 |
-
if (function_exists('get_current_user_id')) {
|
277 |
-
$data['CurrentUserID'] = get_current_user_id();
|
278 |
-
}
|
279 |
-
}
|
280 |
-
if (!isset($data['CurrentUserRoles']) && function_exists('is_user_logged_in') && is_user_logged_in()) {
|
281 |
-
$currentUserRoles = $this->plugin->settings->GetCurrentUserRoles();
|
282 |
-
if (!empty($currentUserRoles)) {
|
283 |
-
$data['CurrentUserRoles'] = $currentUserRoles;
|
284 |
-
}
|
285 |
-
}
|
286 |
-
//if(isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != $data['ClientIP'])
|
287 |
-
// $data['ClientHost'] = $_SERVER['REMOTE_HOST'];
|
288 |
-
//$data['OtherIPs'] = $_SERVER['REMOTE_HOST'];
|
289 |
-
|
290 |
-
foreach ($this->_loggers as $logger) {
|
291 |
-
$logger->Log($type, $data);
|
292 |
-
}
|
293 |
-
}
|
294 |
-
|
295 |
-
/**
|
296 |
-
* Return alert given alert type.
|
297 |
-
* @param integer $type Alert type.
|
298 |
-
* @param mixed $default Returned if alert is not found.
|
299 |
-
* @return WSAL_Alert
|
300 |
-
*/
|
301 |
-
public function GetAlert($type, $default = null){
|
302 |
-
foreach($this->_alerts as $alert)
|
303 |
-
if($alert->type == $type)
|
304 |
-
return $alert;
|
305 |
-
return $default;
|
306 |
-
}
|
307 |
-
|
308 |
-
/**
|
309 |
-
* Returns all supported alerts.
|
310 |
-
* @return WSAL_Alert[]
|
311 |
-
*/
|
312 |
-
public function GetAlerts(){
|
313 |
-
return $this->_alerts;
|
314 |
-
}
|
315 |
-
|
316 |
-
/**
|
317 |
-
* Returns all supported alerts.
|
318 |
-
* @return array
|
319 |
-
*/
|
320 |
-
public function GetCategorizedAlerts(){
|
321 |
-
$result = array();
|
322 |
-
foreach($this->_alerts as $alert){
|
323 |
-
if(!isset($result[$alert->catg]))
|
324 |
-
$result[$alert->catg] = array();
|
325 |
-
$result[$alert->catg][] = $alert;
|
326 |
-
}
|
327 |
-
ksort($result);
|
328 |
-
return $result;
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* Returns whether user is enabled or not.
|
333 |
-
* @param string user.
|
334 |
-
* @return boolean True if disabled, false otherwise.
|
335 |
-
*/
|
336 |
-
public function IsDisabledUser($user)
|
337 |
-
{
|
338 |
-
return (in_array($user, $this->GetDisabledUsers())) ? true : false;
|
339 |
-
}
|
340 |
-
|
341 |
-
/**
|
342 |
-
* @return Returns an array of disabled users.
|
343 |
-
*/
|
344 |
-
public function GetDisabledUsers()
|
345 |
-
{
|
346 |
-
return $this->plugin->settings->GetExcludedMonitoringUsers();
|
347 |
-
}
|
348 |
-
|
349 |
-
/**
|
350 |
-
* Returns whether user is enabled or not.
|
351 |
-
* @param array roles.
|
352 |
-
* @return boolean True if disabled, false otherwise.
|
353 |
-
*/
|
354 |
-
public function IsDisabledRole($roles)
|
355 |
-
{
|
356 |
-
$is_disabled = false;
|
357 |
-
foreach ($roles as $role) {
|
358 |
-
if(in_array($role, $this->GetDisabledRoles())) $is_disabled = true;
|
359 |
-
}
|
360 |
-
return $is_disabled;
|
361 |
-
}
|
362 |
-
|
363 |
-
/**
|
364 |
-
* @return Returns an array of disabled users.
|
365 |
-
*/
|
366 |
-
public function GetDisabledRoles()
|
367 |
-
{
|
368 |
-
return $this->plugin->settings->GetExcludedMonitoringRoles();
|
369 |
-
}
|
370 |
-
|
371 |
-
private function IsDisabledIP()
|
372 |
-
{
|
373 |
-
$is_disabled = false;
|
374 |
-
$ip = $this->plugin->settings->GetMainClientIP();
|
375 |
-
$excluded_ips = $this->plugin->settings->GetExcludedMonitoringIP();
|
376 |
-
if (in_array($ip, $excluded_ips)) {
|
377 |
-
$is_disabled = true;
|
378 |
-
}
|
379 |
-
return $is_disabled;
|
380 |
-
}
|
381 |
-
|
382 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class WSAL_AlertManager {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var WSAL_Alert[]
|
7 |
+
*/
|
8 |
+
protected $_alerts = array();
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var WSAL_AbstractLogger[]
|
12 |
+
*/
|
13 |
+
protected $_loggers = array();
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var WpSecurityAuditLog
|
17 |
+
*/
|
18 |
+
protected $plugin;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Create new AlertManager instance.
|
22 |
+
* @param WpSecurityAuditLog $plugin
|
23 |
+
*/
|
24 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
25 |
+
$this->plugin = $plugin;
|
26 |
+
foreach(glob(dirname(__FILE__) . '/Loggers/*.php') as $file)
|
27 |
+
$this->AddFromFile($file);
|
28 |
+
|
29 |
+
add_action('shutdown', array($this, '_CommitPipeline'));
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Add new logger from file inside autoloader path.
|
34 |
+
* @param string $file Path to file.
|
35 |
+
*/
|
36 |
+
public function AddFromFile($file){
|
37 |
+
$this->AddFromClass($this->plugin->GetClassFileClassName($file));
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Add new logger given class name.
|
42 |
+
* @param string $class Class name.
|
43 |
+
*/
|
44 |
+
public function AddFromClass($class){
|
45 |
+
$this->AddInstance(new $class($this->plugin));
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Add newly created logger to list.
|
50 |
+
* @param WSAL_AbstractLogger $logger The new logger.
|
51 |
+
*/
|
52 |
+
public function AddInstance(WSAL_AbstractLogger $logger){
|
53 |
+
$this->_loggers[] = $logger;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Remove logger by class name.
|
58 |
+
* @param string $class The class name.
|
59 |
+
*/
|
60 |
+
public function RemoveByClass($class){
|
61 |
+
foreach($this->_loggers as $i => $inst)
|
62 |
+
if(get_class($inst) == $class)
|
63 |
+
unset($this->_loggers[$i]);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Contains a list of alerts to trigger.
|
68 |
+
* @var array
|
69 |
+
*/
|
70 |
+
protected $_pipeline = array();
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Contains an array of alerts that have been triggered for this request.
|
74 |
+
* @var int[]
|
75 |
+
*/
|
76 |
+
protected $_triggered_types = array();
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Trigger an alert.
|
80 |
+
* @param integer $type Alert type.
|
81 |
+
* @param array $data Alert data.
|
82 |
+
*/
|
83 |
+
public function Trigger($type, $data = array(), $delayed = false){
|
84 |
+
$username = wp_get_current_user()->user_login;
|
85 |
+
if (empty($username) && !empty($data["Username"])) {
|
86 |
+
$username = $data['Username'];
|
87 |
+
}
|
88 |
+
$roles = $this->plugin->settings->GetCurrentUserRoles();
|
89 |
+
if (empty($roles) && !empty($data["CurrentUserRoles"])) {
|
90 |
+
$roles = $data['CurrentUserRoles'];
|
91 |
+
}
|
92 |
+
if ($this->IsDisabledIP()) {
|
93 |
+
return;
|
94 |
+
}
|
95 |
+
if ($this->CheckEnableUserRoles($username, $roles)) {
|
96 |
+
if ($delayed) {
|
97 |
+
$this->TriggerIf($type, $data, null);
|
98 |
+
} else {
|
99 |
+
$this->_CommitItem($type, $data, null);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Check enable user and roles.
|
106 |
+
* @param string user
|
107 |
+
* @param array roles
|
108 |
+
* @return boolean True if enable false otherwise.
|
109 |
+
*/
|
110 |
+
public function CheckEnableUserRoles($user, $roles) {
|
111 |
+
$is_enable = true;
|
112 |
+
if ( $user != "" && $this->IsDisabledUser($user) ) { $is_enable = false; }
|
113 |
+
if ( $roles != "" && $this->IsDisabledRole($roles) ) { $is_enable = false; }
|
114 |
+
return $is_enable;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Trigger only if a condition is met at the end of request.
|
119 |
+
* @param integer $type Alert type ID.
|
120 |
+
* @param array $data Alert data.
|
121 |
+
* @param callable $cond A future condition callback (receives an object of type WSAL_AlertManager as parameter).
|
122 |
+
*/
|
123 |
+
public function TriggerIf($type, $data, $cond = null) {
|
124 |
+
$username = wp_get_current_user()->user_login;
|
125 |
+
$roles = $this->plugin->settings->GetCurrentUserRoles();
|
126 |
+
|
127 |
+
if ($this->CheckEnableUserRoles($username, $roles)) {
|
128 |
+
$this->_pipeline[] = array(
|
129 |
+
'type' => $type,
|
130 |
+
'data' => $data,
|
131 |
+
'cond' => $cond,
|
132 |
+
);
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @internal Commit an alert now.
|
138 |
+
*/
|
139 |
+
protected function _CommitItem($type, $data, $cond, $_retry = true)
|
140 |
+
{
|
141 |
+
if(!$cond || !!call_user_func($cond, $this)){
|
142 |
+
if($this->IsEnabled($type)) {
|
143 |
+
if(isset($this->_alerts[$type])){
|
144 |
+
// ok, convert alert to a log entry
|
145 |
+
$this->_triggered_types[] = $type;
|
146 |
+
$this->Log($type, $data);
|
147 |
+
}elseif($_retry){
|
148 |
+
// this is the last attempt at loading alerts from default file
|
149 |
+
$this->plugin->LoadDefaults();
|
150 |
+
return $this->_CommitItem($type, $data, $cond, false);
|
151 |
+
}else{
|
152 |
+
// in general this shouldn't happen, but it could, so we handle it here :)
|
153 |
+
throw new Exception('Alert with code "' . $type . '" has not be registered.');
|
154 |
+
}
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @internal Runs over triggered alerts in pipeline and passes them to loggers.
|
161 |
+
*/
|
162 |
+
public function _CommitPipeline(){
|
163 |
+
foreach($this->_pipeline as $item)
|
164 |
+
$this->_CommitItem($item['type'], $item['data'], $item['cond']);
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param integer $type Alert type ID.
|
169 |
+
* @return boolean True if at the end of request an alert of this type will be triggered.
|
170 |
+
*/
|
171 |
+
public function WillTrigger($type){
|
172 |
+
foreach($this->_pipeline as $item)
|
173 |
+
if($item['type'] == $type)
|
174 |
+
return true;
|
175 |
+
return false;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* @param int $type Alert type ID.
|
180 |
+
* @return boolean True if an alert has been or will be triggered in this request, false otherwise.
|
181 |
+
*/
|
182 |
+
public function WillOrHasTriggered($type){
|
183 |
+
return in_array($type, $this->_triggered_types)
|
184 |
+
|| $this->WillTrigger($type);
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Register an alert type.
|
189 |
+
* @param array $info Array of [type, code, category, description, message] respectively.
|
190 |
+
*/
|
191 |
+
public function Register($info){
|
192 |
+
if(func_num_args() == 1){
|
193 |
+
// handle single item
|
194 |
+
list($type, $code, $catg, $desc, $mesg) = $info;
|
195 |
+
if(isset($this->_alerts[$type]))
|
196 |
+
throw new Exception("Alert $type already registered with Alert Manager.");
|
197 |
+
$this->_alerts[$type] = new WSAL_Alert($type, $code, $catg, $desc, $mesg);
|
198 |
+
}else{
|
199 |
+
// handle multiple items
|
200 |
+
foreach(func_get_args() as $arg)
|
201 |
+
$this->Register($arg);
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Register a whole group of items.
|
207 |
+
* @param array $groups An array with group name as the index and an array of group items as the value.
|
208 |
+
* Item values is an array of [type, code, description, message] respectively.
|
209 |
+
*/
|
210 |
+
public function RegisterGroup($groups){
|
211 |
+
foreach($groups as $name => $group){
|
212 |
+
foreach($group as $item){
|
213 |
+
list($type, $code, $desc, $mesg) = $item;
|
214 |
+
$this->Register(array($type, $code, $name, $desc, $mesg));
|
215 |
+
}
|
216 |
+
}
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Returns whether alert of type $type is enabled or not.
|
221 |
+
* @param integer $type Alert type.
|
222 |
+
* @return boolean True if enabled, false otherwise.
|
223 |
+
*/
|
224 |
+
public function IsEnabled($type){
|
225 |
+
return !in_array($type, $this->GetDisabledAlerts());
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Disables a set of alerts by type.
|
230 |
+
* @param int[] $types Alert type codes to be disabled.
|
231 |
+
*/
|
232 |
+
public function SetDisabledAlerts($types){
|
233 |
+
$this->plugin->settings->SetDisabledAlerts($types);
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* @return int[] Returns an array of disabled alerts' type code.
|
238 |
+
*/
|
239 |
+
public function GetDisabledAlerts(){
|
240 |
+
return $this->plugin->settings->GetDisabledAlerts();
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* @return WSAL_AbstractLogger[] Returns an array of loaded loggers.
|
245 |
+
*/
|
246 |
+
public function GetLoggers(){
|
247 |
+
return $this->_loggers;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Converts an Alert into a Log entry (by invoking loggers).
|
252 |
+
* You should not call this method directly.
|
253 |
+
* @param integer $type Alert type.
|
254 |
+
* @param array $data Misc alert data.
|
255 |
+
*/
|
256 |
+
protected function Log($type, $data = array())
|
257 |
+
{
|
258 |
+
if (!isset($data['ClientIP'])) {
|
259 |
+
$clientIP = $this->plugin->settings->GetMainClientIP();
|
260 |
+
if (!empty($clientIP)) {
|
261 |
+
$data['ClientIP'] = $clientIP;
|
262 |
+
}
|
263 |
+
}
|
264 |
+
if (!isset($data['OtherIPs']) && $this->plugin->settings->IsMainIPFromProxy()) {
|
265 |
+
$otherIPs = $this->plugin->settings->GetClientIPs();
|
266 |
+
if (!empty($otherIPs)) {
|
267 |
+
$data['OtherIPs'] = $otherIPs;
|
268 |
+
}
|
269 |
+
}
|
270 |
+
if (!isset($data['UserAgent'])) {
|
271 |
+
if (isset($_SERVER['HTTP_USER_AGENT'])) {
|
272 |
+
$data['UserAgent'] = $_SERVER['HTTP_USER_AGENT'];
|
273 |
+
}
|
274 |
+
}
|
275 |
+
if (!isset($data['Username']) && !isset($data['CurrentUserID'])) {
|
276 |
+
if (function_exists('get_current_user_id')) {
|
277 |
+
$data['CurrentUserID'] = get_current_user_id();
|
278 |
+
}
|
279 |
+
}
|
280 |
+
if (!isset($data['CurrentUserRoles']) && function_exists('is_user_logged_in') && is_user_logged_in()) {
|
281 |
+
$currentUserRoles = $this->plugin->settings->GetCurrentUserRoles();
|
282 |
+
if (!empty($currentUserRoles)) {
|
283 |
+
$data['CurrentUserRoles'] = $currentUserRoles;
|
284 |
+
}
|
285 |
+
}
|
286 |
+
//if(isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != $data['ClientIP'])
|
287 |
+
// $data['ClientHost'] = $_SERVER['REMOTE_HOST'];
|
288 |
+
//$data['OtherIPs'] = $_SERVER['REMOTE_HOST'];
|
289 |
+
|
290 |
+
foreach ($this->_loggers as $logger) {
|
291 |
+
$logger->Log($type, $data);
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Return alert given alert type.
|
297 |
+
* @param integer $type Alert type.
|
298 |
+
* @param mixed $default Returned if alert is not found.
|
299 |
+
* @return WSAL_Alert
|
300 |
+
*/
|
301 |
+
public function GetAlert($type, $default = null){
|
302 |
+
foreach($this->_alerts as $alert)
|
303 |
+
if($alert->type == $type)
|
304 |
+
return $alert;
|
305 |
+
return $default;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Returns all supported alerts.
|
310 |
+
* @return WSAL_Alert[]
|
311 |
+
*/
|
312 |
+
public function GetAlerts(){
|
313 |
+
return $this->_alerts;
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Returns all supported alerts.
|
318 |
+
* @return array
|
319 |
+
*/
|
320 |
+
public function GetCategorizedAlerts(){
|
321 |
+
$result = array();
|
322 |
+
foreach($this->_alerts as $alert){
|
323 |
+
if(!isset($result[$alert->catg]))
|
324 |
+
$result[$alert->catg] = array();
|
325 |
+
$result[$alert->catg][] = $alert;
|
326 |
+
}
|
327 |
+
ksort($result);
|
328 |
+
return $result;
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Returns whether user is enabled or not.
|
333 |
+
* @param string user.
|
334 |
+
* @return boolean True if disabled, false otherwise.
|
335 |
+
*/
|
336 |
+
public function IsDisabledUser($user)
|
337 |
+
{
|
338 |
+
return (in_array($user, $this->GetDisabledUsers())) ? true : false;
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* @return Returns an array of disabled users.
|
343 |
+
*/
|
344 |
+
public function GetDisabledUsers()
|
345 |
+
{
|
346 |
+
return $this->plugin->settings->GetExcludedMonitoringUsers();
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Returns whether user is enabled or not.
|
351 |
+
* @param array roles.
|
352 |
+
* @return boolean True if disabled, false otherwise.
|
353 |
+
*/
|
354 |
+
public function IsDisabledRole($roles)
|
355 |
+
{
|
356 |
+
$is_disabled = false;
|
357 |
+
foreach ($roles as $role) {
|
358 |
+
if(in_array($role, $this->GetDisabledRoles())) $is_disabled = true;
|
359 |
+
}
|
360 |
+
return $is_disabled;
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* @return Returns an array of disabled users.
|
365 |
+
*/
|
366 |
+
public function GetDisabledRoles()
|
367 |
+
{
|
368 |
+
return $this->plugin->settings->GetExcludedMonitoringRoles();
|
369 |
+
}
|
370 |
+
|
371 |
+
private function IsDisabledIP()
|
372 |
+
{
|
373 |
+
$is_disabled = false;
|
374 |
+
$ip = $this->plugin->settings->GetMainClientIP();
|
375 |
+
$excluded_ips = $this->plugin->settings->GetExcludedMonitoringIP();
|
376 |
+
if (in_array($ip, $excluded_ips)) {
|
377 |
+
$is_disabled = true;
|
378 |
+
}
|
379 |
+
return $is_disabled;
|
380 |
+
}
|
381 |
+
|
382 |
+
}
|
classes/AuditLogListView.php
CHANGED
@@ -1,445 +1,452 @@
|
|
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 |
-
class WSAL_AuditLogListView extends WP_List_Table
|
7 |
-
{
|
8 |
-
|
9 |
-
/**
|
10 |
-
* @var WpSecurityAuditLog
|
11 |
-
*/
|
12 |
-
protected $_plugin;
|
13 |
-
protected $_gmt_offset_sec = 0;
|
14 |
-
|
15 |
-
public function __construct($plugin)
|
16 |
-
{
|
17 |
-
$this->_plugin = $plugin;
|
18 |
-
|
19 |
-
$timezone = $this->_plugin->settings->GetTimezone();
|
20 |
-
if ($timezone) {
|
21 |
-
$this->_gmt_offset_sec = get_option('gmt_offset') * HOUR_IN_SECONDS;
|
22 |
-
} else {
|
23 |
-
$this->_gmt_offset_sec = date('Z');
|
24 |
-
}
|
25 |
-
|
26 |
-
parent::__construct(array(
|
27 |
-
'singular' => 'log',
|
28 |
-
'plural' => 'logs',
|
29 |
-
'ajax' => true,
|
30 |
-
'screen' => 'interval-list',
|
31 |
-
));
|
32 |
-
}
|
33 |
-
|
34 |
-
public function no_items()
|
35 |
-
{
|
36 |
-
_e('No events so far.', 'wp-security-audit-log');
|
37 |
-
}
|
38 |
-
|
39 |
-
public function extra_tablenav($which)
|
40 |
-
{
|
41 |
-
// items-per-page widget
|
42 |
-
$o = __('Other', 'wp-security-audit-log');
|
43 |
-
$p = $this->_plugin->settings->GetViewPerPage();
|
44 |
-
$items = array($o, 5, 10, 15, 30, 50);
|
45 |
-
if (!in_array($p, $items)) $items[] = $p;
|
46 |
-
if ($p == $o || $p == 0) $p = $o[1]; // a sane default if things goes bust
|
47 |
-
|
48 |
-
?><div class="wsal-ipp wsal-ipp-<?php echo $which; ?>">
|
49 |
-
<?php _e('Show ', 'wp-security-audit-log'); ?>
|
50 |
-
<select class="wsal-ipps" onfocus="WsalIppsFocus(value);" onchange="WsalIppsChange(value);">
|
51 |
-
<?php foreach ($items as $item) { ?>
|
52 |
-
<option
|
53 |
-
value="<?php echo is_string($item) ? '' : $item; ?>"
|
54 |
-
<?php if ($item == $p) echo 'selected="selected"'; ?>><?php
|
55 |
-
echo $item;
|
56 |
-
?></option>
|
57 |
-
<?php } ?>
|
58 |
-
</select>
|
59 |
-
<?php _e(' Items', 'wp-security-audit-log'); ?>
|
60 |
-
</div><?php
|
61 |
-
|
62 |
-
// show site alerts widget
|
63 |
-
if ($this->is_multisite() && $this->is_main_blog()) {
|
64 |
-
$curr = $this->get_view_site_id();
|
65 |
-
?><div class="wsal-ssa wsal-ssa-<?php echo $which; ?>">
|
66 |
-
<?php if ($this->get_site_count() > 15) { ?>
|
67 |
-
<?php $curr = $curr ? get_blog_details($curr) : null; ?>
|
68 |
-
<?php $curr = $curr ? ($curr->blogname . ' (' . $curr->domain . ')') : 'All Sites'; ?>
|
69 |
-
<input type="text" class="wsal-ssas" value="<?php echo esc_attr($curr); ?>"/>
|
70 |
-
<?php } else { ?>
|
71 |
-
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
72 |
-
<option value="0"><?php _e('All Sites', 'wp-security-audit-log'); ?></option>
|
73 |
-
<?php foreach ($this->get_sites() as $info) { ?>
|
74 |
-
<option value="<?php echo $info->blog_id; ?>"
|
75 |
-
<?php if ($info->blog_id == $curr) echo 'selected="selected"'; ?>><?php
|
76 |
-
echo esc_html($info->blogname) . ' (' . esc_html($info->domain) . ')';
|
77 |
-
?></option>
|
78 |
-
<?php } ?>
|
79 |
-
</select>
|
80 |
-
<?php } ?>
|
81 |
-
</div><?php
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @param int|null $limit Maximum number of sites to return (null = no limit).
|
87 |
-
* @return object Object with keys: blog_id, blogname, domain
|
88 |
-
*/
|
89 |
-
public function get_sites($limit = null)
|
90 |
-
{
|
91 |
-
global $wpdb;
|
92 |
-
|
93 |
-
// build query
|
94 |
-
$sql = 'SELECT blog_id, domain FROM ' . $wpdb->blogs;
|
95 |
-
if (!is_null($limit)) $sql .= ' LIMIT ' . $limit;
|
96 |
-
|
97 |
-
// execute query
|
98 |
-
$res = $wpdb->get_results($sql);
|
99 |
-
|
100 |
-
// modify result
|
101 |
-
foreach ($res as $row) {
|
102 |
-
$row->blogname = get_blog_option($row->blog_id, 'blogname');
|
103 |
-
}
|
104 |
-
// return result
|
105 |
-
return $res;
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* @return int The number of sites on the network.
|
110 |
-
*/
|
111 |
-
public function get_site_count()
|
112 |
-
{
|
113 |
-
global $wpdb;
|
114 |
-
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
115 |
-
return (int)$wpdb->get_var($sql);
|
116 |
-
}
|
117 |
-
|
118 |
-
public function get_columns()
|
119 |
-
{
|
120 |
-
$cols = array(
|
121 |
-
//'cb' => '<input type="checkbox" />',
|
122 |
-
//'read' => __('Read', 'wp-security-audit-log'),
|
123 |
-
'type' => __('Code', 'wp-security-audit-log'),
|
124 |
-
'code' => __('Type', 'wp-security-audit-log'),
|
125 |
-
'crtd' => __('Date', 'wp-security-audit-log'),
|
126 |
-
'user' => __('Username', 'wp-security-audit-log'),
|
127 |
-
'scip' => __('Source IP', 'wp-security-audit-log'),
|
128 |
-
);
|
129 |
-
if ($this->is_multisite() && $this->is_main_blog() && !$this->is_specific_view()) {
|
130 |
-
$cols['site'] = __('Site', 'wp-security-audit-log');
|
131 |
-
}
|
132 |
-
$cols['mesg'] = __('Message', 'wp-security-audit-log');
|
133 |
-
if ($this->_plugin->settings->IsDataInspectorEnabled()) {
|
134 |
-
$cols['data'] = '';
|
135 |
-
}
|
136 |
-
$sel_columns = $this->_plugin->settings->GetColumnsSelected();
|
137 |
-
if (!empty($sel_columns)) {
|
138 |
-
unset($cols);
|
139 |
-
$sel_columns = (array)json_decode($sel_columns);
|
140 |
-
foreach ($sel_columns as $key => $value) {
|
141 |
-
switch ($key) {
|
142 |
-
case 'alert_code':
|
143 |
-
$cols['type'] = __('Code', 'wp-security-audit-log');
|
144 |
-
break;
|
145 |
-
case 'type':
|
146 |
-
$cols['code'] = __('Type', 'wp-security-audit-log');
|
147 |
-
break;
|
148 |
-
case 'date':
|
149 |
-
$cols['crtd'] = __('Date', 'wp-security-audit-log');
|
150 |
-
break;
|
151 |
-
case 'username':
|
152 |
-
$cols['user'] = __('Username', 'wp-security-audit-log');
|
153 |
-
break;
|
154 |
-
case 'source_ip':
|
155 |
-
$cols['scip'] = __('Source IP', 'wp-security-audit-log');
|
156 |
-
break;
|
157 |
-
case 'site':
|
158 |
-
$cols['site'] = __('Site', 'wp-security-audit-log');
|
159 |
-
break;
|
160 |
-
case 'message':
|
161 |
-
$cols['mesg'] = __('Message', 'wp-security-audit-log');
|
162 |
-
break;
|
163 |
-
}
|
164 |
-
}
|
165 |
-
}
|
166 |
-
return $cols;
|
167 |
-
}
|
168 |
-
|
169 |
-
public function column_cb($item)
|
170 |
-
{
|
171 |
-
return '<input type="checkbox" value="'.$item->id.'" '
|
172 |
-
. 'name="'.esc_attr($this->_args['singular']).'[]"/>';
|
173 |
-
}
|
174 |
-
|
175 |
-
public function get_sortable_columns()
|
176 |
-
{
|
177 |
-
return array(
|
178 |
-
'read' => array('is_read', false),
|
179 |
-
//'code' => array('code', false),
|
180 |
-
'type' => array('alert_id', false),
|
181 |
-
'crtd' => array('created_on', true),
|
182 |
-
'user' => array('user', true),
|
183 |
-
'scip' => array('scip', false)
|
184 |
-
);
|
185 |
-
}
|
186 |
-
|
187 |
-
public function column_default($item, $column_name)
|
188 |
-
{
|
189 |
-
//example: $item->getMetaValue('CurrentUserID')
|
190 |
-
|
191 |
-
if (!$this->_plugin->settings->GetDatetimeFormat()) $datetimeFormat = 'h:i:s.$$$&\n\b\s\p;A';
|
192 |
-
else $datetimeFormat = 'H:i:s.$$$';
|
193 |
-
switch ($column_name) {
|
194 |
-
case 'read':
|
195 |
-
return '<span class="log-read log-read-'
|
196 |
-
. ($item->is_read ? 'old' : 'new')
|
197 |
-
. '" title="' . __('Click to toggle.', 'wp-security-audit-log') . '"></span>';
|
198 |
-
case 'type':
|
199 |
-
return str_pad($item->alert_id, 4, '0', STR_PAD_LEFT);
|
200 |
-
case 'code':
|
201 |
-
$code = $this->_plugin->alerts->GetAlert($item->alert_id);
|
202 |
-
$code = $code ? $code->code : 0;
|
203 |
-
$const = (object)array('name' => 'E_UNKNOWN', 'value' => 0, 'description' => __('Unknown error code.', 'wp-security-audit-log'));
|
204 |
-
$const = $this->_plugin->constants->GetConstantBy('value', $code, $const);
|
205 |
-
return '<span class="log-type log-type-' . $const->value
|
206 |
-
. '" title="' . esc_html($const->name . ': ' . $const->description) . '"></span>';
|
207 |
-
case 'crtd':
|
208 |
-
return $item->created_on ? (
|
209 |
-
str_replace(
|
210 |
-
'$$$',
|
211 |
-
substr(number_format(fmod($item->created_on + $this->_gmt_offset_sec, 1), 3), 2),
|
212 |
-
date('Y-m-d<\b\r>'.$datetimeFormat, $item->created_on + $this->_gmt_offset_sec)
|
213 |
-
)
|
214 |
-
) : '<i>unknown</i>';
|
215 |
-
case 'user':
|
216 |
-
$username = $item->GetUsername();
|
217 |
-
if ($username && ($user = get_user_by('login', $username))) {
|
218 |
-
$image = get_avatar($user->ID, 32);
|
219 |
-
$uhtml = '<a href="' . admin_url('user-edit.php?user_id=' . $user->ID)
|
220 |
-
. '" target="_blank">' . esc_html($user->display_name) . '</a>';
|
221 |
-
$roles = $item->GetUserRoles();
|
222 |
-
if (is_array($roles) && count($roles)) {
|
223 |
-
$roles = __(esc_html(ucwords(implode(', ', $roles))));
|
224 |
-
} else if (is_string($roles) && $roles != '') {
|
225 |
-
$roles = __(esc_html(ucwords(str_replace(array("\"", "[", "]"), " ", $roles))));
|
226 |
-
} else {
|
227 |
-
$roles = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
|
228 |
-
}
|
229 |
-
} elseif ($username == 'Plugin') {
|
230 |
-
$image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/plugin-logo.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
231 |
-
$uhtml = '<i>' . __('Plugin', 'wp-security-audit-log') . '</i>';
|
232 |
-
$roles = '';
|
233 |
-
} else {
|
234 |
-
$image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
235 |
-
$uhtml = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
|
236 |
-
$roles = '';
|
237 |
-
}
|
238 |
-
return $image . $uhtml . '<br/>' . $roles;
|
239 |
-
case 'scip':
|
240 |
-
$scip = $item->GetSourceIP();
|
241 |
-
if (is_string($scip)) {
|
242 |
-
$scip = str_replace(array("\"", "[", "]"), "", $scip);
|
243 |
-
}
|
244 |
-
$oips = array(); //$item->GetOtherIPs();
|
245 |
-
// if there's no IP...
|
246 |
-
if (is_null($scip) || $scip == '') return '<i>unknown</i>';
|
247 |
-
// if there's only one IP...
|
248 |
-
$link = "http://whatismyipaddress.com/ip/" . $scip ."?utm_source=plugin&utm_medium=referral&utm_campaign=WPSAL";
|
249 |
-
if (count($oips) < 2) return "<a target='_blank' href='$link'>". esc_html($scip) .'</a>';
|
250 |
-
// if there are many IPs...
|
251 |
-
$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;">';
|
252 |
-
foreach ($oips as $ip) if($scip != $ip) $html .= '<div>' . $ip . '</div>';
|
253 |
-
$html .= '</div>';
|
254 |
-
return $html;
|
255 |
-
case 'site':
|
256 |
-
$info = get_blog_details($item->site_id, true);
|
257 |
-
return !$info ? ('Unknown Site '.$item->site_id)
|
258 |
-
: ('<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>');
|
259 |
-
case 'mesg':
|
260 |
-
return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>';
|
261 |
-
case 'data':
|
262 |
-
$url = admin_url('admin-ajax.php') . '?action=AjaxInspector&occurrence=' . $item->id;
|
263 |
-
return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
|
264 |
-
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
265 |
-
default:
|
266 |
-
return isset($item->$column_name)
|
267 |
-
? esc_html($item->$column_name)
|
268 |
-
: 'Column "' . esc_html($column_name) . '" not found';
|
269 |
-
}
|
270 |
-
}
|
271 |
-
|
272 |
-
public function reorder_items_str($a, $b)
|
273 |
-
{
|
274 |
-
$result = strcmp($a->{$this->_orderby}, $b->{$this->_orderby});
|
275 |
-
return ($this->_order === 'asc') ? $result : -$result;
|
276 |
-
}
|
277 |
-
|
278 |
-
public function reorder_items_int($a, $b)
|
279 |
-
{
|
280 |
-
$result = $a->{$this->_orderby} - $b->{$this->_orderby};
|
281 |
-
return ($this->_order === 'asc') ? $result : -$result;
|
282 |
-
}
|
283 |
-
|
284 |
-
public function meta_formatter($name, $value)
|
285 |
-
{
|
286 |
-
switch (true) {
|
287 |
-
case $name == '%Message%':
|
288 |
-
return esc_html($value);
|
289 |
-
|
290 |
-
case $name == '%PromoMessage%':
|
291 |
-
return '<p class="promo-alert">' . $value .'</p>';
|
292 |
-
|
293 |
-
case $name == '%PromoLink%':
|
294 |
-
return $value;
|
295 |
-
|
296 |
-
case $name == '%MetaLink%':
|
297 |
-
if (!empty($value)) {
|
298 |
-
return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
|
299 |
-
} else {
|
300 |
-
return "";
|
301 |
-
}
|
302 |
-
|
303 |
-
case $name == '%RevisionLink%':
|
304 |
-
if (!empty($value) && $value != 'NULL') {
|
305 |
-
return ' Click <a target="_blank" href="'.$value.'">here</a> to see the content changes.';
|
306 |
-
} else {
|
307 |
-
return "";
|
308 |
-
}
|
309 |
-
|
310 |
-
case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
|
311 |
-
return '<strong>' . (
|
312 |
-
strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '…') : esc_html($value)
|
313 |
-
) . '</strong>';
|
314 |
-
|
315 |
-
case
|
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 |
-
$query =
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
class WSAL_AuditLogListView extends WP_List_Table
|
7 |
+
{
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var WpSecurityAuditLog
|
11 |
+
*/
|
12 |
+
protected $_plugin;
|
13 |
+
protected $_gmt_offset_sec = 0;
|
14 |
+
|
15 |
+
public function __construct($plugin)
|
16 |
+
{
|
17 |
+
$this->_plugin = $plugin;
|
18 |
+
|
19 |
+
$timezone = $this->_plugin->settings->GetTimezone();
|
20 |
+
if ($timezone) {
|
21 |
+
$this->_gmt_offset_sec = get_option('gmt_offset') * HOUR_IN_SECONDS;
|
22 |
+
} else {
|
23 |
+
$this->_gmt_offset_sec = date('Z');
|
24 |
+
}
|
25 |
+
|
26 |
+
parent::__construct(array(
|
27 |
+
'singular' => 'log',
|
28 |
+
'plural' => 'logs',
|
29 |
+
'ajax' => true,
|
30 |
+
'screen' => 'interval-list',
|
31 |
+
));
|
32 |
+
}
|
33 |
+
|
34 |
+
public function no_items()
|
35 |
+
{
|
36 |
+
_e('No events so far.', 'wp-security-audit-log');
|
37 |
+
}
|
38 |
+
|
39 |
+
public function extra_tablenav($which)
|
40 |
+
{
|
41 |
+
// items-per-page widget
|
42 |
+
$o = __('Other', 'wp-security-audit-log');
|
43 |
+
$p = $this->_plugin->settings->GetViewPerPage();
|
44 |
+
$items = array($o, 5, 10, 15, 30, 50);
|
45 |
+
if (!in_array($p, $items)) $items[] = $p;
|
46 |
+
if ($p == $o || $p == 0) $p = $o[1]; // a sane default if things goes bust
|
47 |
+
|
48 |
+
?><div class="wsal-ipp wsal-ipp-<?php echo $which; ?>">
|
49 |
+
<?php _e('Show ', 'wp-security-audit-log'); ?>
|
50 |
+
<select class="wsal-ipps" onfocus="WsalIppsFocus(value);" onchange="WsalIppsChange(value);">
|
51 |
+
<?php foreach ($items as $item) { ?>
|
52 |
+
<option
|
53 |
+
value="<?php echo is_string($item) ? '' : $item; ?>"
|
54 |
+
<?php if ($item == $p) echo 'selected="selected"'; ?>><?php
|
55 |
+
echo $item;
|
56 |
+
?></option>
|
57 |
+
<?php } ?>
|
58 |
+
</select>
|
59 |
+
<?php _e(' Items', 'wp-security-audit-log'); ?>
|
60 |
+
</div><?php
|
61 |
+
|
62 |
+
// show site alerts widget
|
63 |
+
if ($this->is_multisite() && $this->is_main_blog()) {
|
64 |
+
$curr = $this->get_view_site_id();
|
65 |
+
?><div class="wsal-ssa wsal-ssa-<?php echo $which; ?>">
|
66 |
+
<?php if ($this->get_site_count() > 15) { ?>
|
67 |
+
<?php $curr = $curr ? get_blog_details($curr) : null; ?>
|
68 |
+
<?php $curr = $curr ? ($curr->blogname . ' (' . $curr->domain . ')') : 'All Sites'; ?>
|
69 |
+
<input type="text" class="wsal-ssas" value="<?php echo esc_attr($curr); ?>"/>
|
70 |
+
<?php } else { ?>
|
71 |
+
<select class="wsal-ssas" onchange="WsalSsasChange(value);">
|
72 |
+
<option value="0"><?php _e('All Sites', 'wp-security-audit-log'); ?></option>
|
73 |
+
<?php foreach ($this->get_sites() as $info) { ?>
|
74 |
+
<option value="<?php echo $info->blog_id; ?>"
|
75 |
+
<?php if ($info->blog_id == $curr) echo 'selected="selected"'; ?>><?php
|
76 |
+
echo esc_html($info->blogname) . ' (' . esc_html($info->domain) . ')';
|
77 |
+
?></option>
|
78 |
+
<?php } ?>
|
79 |
+
</select>
|
80 |
+
<?php } ?>
|
81 |
+
</div><?php
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* @param int|null $limit Maximum number of sites to return (null = no limit).
|
87 |
+
* @return object Object with keys: blog_id, blogname, domain
|
88 |
+
*/
|
89 |
+
public function get_sites($limit = null)
|
90 |
+
{
|
91 |
+
global $wpdb;
|
92 |
+
|
93 |
+
// build query
|
94 |
+
$sql = 'SELECT blog_id, domain FROM ' . $wpdb->blogs;
|
95 |
+
if (!is_null($limit)) $sql .= ' LIMIT ' . $limit;
|
96 |
+
|
97 |
+
// execute query
|
98 |
+
$res = $wpdb->get_results($sql);
|
99 |
+
|
100 |
+
// modify result
|
101 |
+
foreach ($res as $row) {
|
102 |
+
$row->blogname = get_blog_option($row->blog_id, 'blogname');
|
103 |
+
}
|
104 |
+
// return result
|
105 |
+
return $res;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return int The number of sites on the network.
|
110 |
+
*/
|
111 |
+
public function get_site_count()
|
112 |
+
{
|
113 |
+
global $wpdb;
|
114 |
+
$sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
|
115 |
+
return (int)$wpdb->get_var($sql);
|
116 |
+
}
|
117 |
+
|
118 |
+
public function get_columns()
|
119 |
+
{
|
120 |
+
$cols = array(
|
121 |
+
//'cb' => '<input type="checkbox" />',
|
122 |
+
//'read' => __('Read', 'wp-security-audit-log'),
|
123 |
+
'type' => __('Code', 'wp-security-audit-log'),
|
124 |
+
'code' => __('Type', 'wp-security-audit-log'),
|
125 |
+
'crtd' => __('Date', 'wp-security-audit-log'),
|
126 |
+
'user' => __('Username', 'wp-security-audit-log'),
|
127 |
+
'scip' => __('Source IP', 'wp-security-audit-log'),
|
128 |
+
);
|
129 |
+
if ($this->is_multisite() && $this->is_main_blog() && !$this->is_specific_view()) {
|
130 |
+
$cols['site'] = __('Site', 'wp-security-audit-log');
|
131 |
+
}
|
132 |
+
$cols['mesg'] = __('Message', 'wp-security-audit-log');
|
133 |
+
if ($this->_plugin->settings->IsDataInspectorEnabled()) {
|
134 |
+
$cols['data'] = '';
|
135 |
+
}
|
136 |
+
$sel_columns = $this->_plugin->settings->GetColumnsSelected();
|
137 |
+
if (!empty($sel_columns)) {
|
138 |
+
unset($cols);
|
139 |
+
$sel_columns = (array)json_decode($sel_columns);
|
140 |
+
foreach ($sel_columns as $key => $value) {
|
141 |
+
switch ($key) {
|
142 |
+
case 'alert_code':
|
143 |
+
$cols['type'] = __('Code', 'wp-security-audit-log');
|
144 |
+
break;
|
145 |
+
case 'type':
|
146 |
+
$cols['code'] = __('Type', 'wp-security-audit-log');
|
147 |
+
break;
|
148 |
+
case 'date':
|
149 |
+
$cols['crtd'] = __('Date', 'wp-security-audit-log');
|
150 |
+
break;
|
151 |
+
case 'username':
|
152 |
+
$cols['user'] = __('Username', 'wp-security-audit-log');
|
153 |
+
break;
|
154 |
+
case 'source_ip':
|
155 |
+
$cols['scip'] = __('Source IP', 'wp-security-audit-log');
|
156 |
+
break;
|
157 |
+
case 'site':
|
158 |
+
$cols['site'] = __('Site', 'wp-security-audit-log');
|
159 |
+
break;
|
160 |
+
case 'message':
|
161 |
+
$cols['mesg'] = __('Message', 'wp-security-audit-log');
|
162 |
+
break;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
}
|
166 |
+
return $cols;
|
167 |
+
}
|
168 |
+
|
169 |
+
public function column_cb($item)
|
170 |
+
{
|
171 |
+
return '<input type="checkbox" value="'.$item->id.'" '
|
172 |
+
. 'name="'.esc_attr($this->_args['singular']).'[]"/>';
|
173 |
+
}
|
174 |
+
|
175 |
+
public function get_sortable_columns()
|
176 |
+
{
|
177 |
+
return array(
|
178 |
+
'read' => array('is_read', false),
|
179 |
+
//'code' => array('code', false),
|
180 |
+
'type' => array('alert_id', false),
|
181 |
+
'crtd' => array('created_on', true),
|
182 |
+
'user' => array('user', true),
|
183 |
+
'scip' => array('scip', false)
|
184 |
+
);
|
185 |
+
}
|
186 |
+
|
187 |
+
public function column_default($item, $column_name)
|
188 |
+
{
|
189 |
+
//example: $item->getMetaValue('CurrentUserID')
|
190 |
+
|
191 |
+
if (!$this->_plugin->settings->GetDatetimeFormat()) $datetimeFormat = 'h:i:s.$$$&\n\b\s\p;A';
|
192 |
+
else $datetimeFormat = 'H:i:s.$$$';
|
193 |
+
switch ($column_name) {
|
194 |
+
case 'read':
|
195 |
+
return '<span class="log-read log-read-'
|
196 |
+
. ($item->is_read ? 'old' : 'new')
|
197 |
+
. '" title="' . __('Click to toggle.', 'wp-security-audit-log') . '"></span>';
|
198 |
+
case 'type':
|
199 |
+
return str_pad($item->alert_id, 4, '0', STR_PAD_LEFT);
|
200 |
+
case 'code':
|
201 |
+
$code = $this->_plugin->alerts->GetAlert($item->alert_id);
|
202 |
+
$code = $code ? $code->code : 0;
|
203 |
+
$const = (object)array('name' => 'E_UNKNOWN', 'value' => 0, 'description' => __('Unknown error code.', 'wp-security-audit-log'));
|
204 |
+
$const = $this->_plugin->constants->GetConstantBy('value', $code, $const);
|
205 |
+
return '<span class="log-type log-type-' . $const->value
|
206 |
+
. '" title="' . esc_html($const->name . ': ' . $const->description) . '"></span>';
|
207 |
+
case 'crtd':
|
208 |
+
return $item->created_on ? (
|
209 |
+
str_replace(
|
210 |
+
'$$$',
|
211 |
+
substr(number_format(fmod($item->created_on + $this->_gmt_offset_sec, 1), 3), 2),
|
212 |
+
date('Y-m-d<\b\r>'.$datetimeFormat, $item->created_on + $this->_gmt_offset_sec)
|
213 |
+
)
|
214 |
+
) : '<i>unknown</i>';
|
215 |
+
case 'user':
|
216 |
+
$username = $item->GetUsername();
|
217 |
+
if ($username && ($user = get_user_by('login', $username))) {
|
218 |
+
$image = get_avatar($user->ID, 32);
|
219 |
+
$uhtml = '<a href="' . admin_url('user-edit.php?user_id=' . $user->ID)
|
220 |
+
. '" target="_blank">' . esc_html($user->display_name) . '</a>';
|
221 |
+
$roles = $item->GetUserRoles();
|
222 |
+
if (is_array($roles) && count($roles)) {
|
223 |
+
$roles = __(esc_html(ucwords(implode(', ', $roles))));
|
224 |
+
} else if (is_string($roles) && $roles != '') {
|
225 |
+
$roles = __(esc_html(ucwords(str_replace(array("\"", "[", "]"), " ", $roles))));
|
226 |
+
} else {
|
227 |
+
$roles = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
|
228 |
+
}
|
229 |
+
} elseif ($username == 'Plugin') {
|
230 |
+
$image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/plugin-logo.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
231 |
+
$uhtml = '<i>' . __('Plugin', 'wp-security-audit-log') . '</i>';
|
232 |
+
$roles = '';
|
233 |
+
} else {
|
234 |
+
$image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
|
235 |
+
$uhtml = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
|
236 |
+
$roles = '';
|
237 |
+
}
|
238 |
+
return $image . $uhtml . '<br/>' . $roles;
|
239 |
+
case 'scip':
|
240 |
+
$scip = $item->GetSourceIP();
|
241 |
+
if (is_string($scip)) {
|
242 |
+
$scip = str_replace(array("\"", "[", "]"), "", $scip);
|
243 |
+
}
|
244 |
+
$oips = array(); //$item->GetOtherIPs();
|
245 |
+
// if there's no IP...
|
246 |
+
if (is_null($scip) || $scip == '') return '<i>unknown</i>';
|
247 |
+
// if there's only one IP...
|
248 |
+
$link = "http://whatismyipaddress.com/ip/" . $scip ."?utm_source=plugin&utm_medium=referral&utm_campaign=WPSAL";
|
249 |
+
if (count($oips) < 2) return "<a target='_blank' href='$link'>". esc_html($scip) .'</a>';
|
250 |
+
// if there are many IPs...
|
251 |
+
$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;">';
|
252 |
+
foreach ($oips as $ip) if($scip != $ip) $html .= '<div>' . $ip . '</div>';
|
253 |
+
$html .= '</div>';
|
254 |
+
return $html;
|
255 |
+
case 'site':
|
256 |
+
$info = get_blog_details($item->site_id, true);
|
257 |
+
return !$info ? ('Unknown Site '.$item->site_id)
|
258 |
+
: ('<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>');
|
259 |
+
case 'mesg':
|
260 |
+
return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>';
|
261 |
+
case 'data':
|
262 |
+
$url = admin_url('admin-ajax.php') . '?action=AjaxInspector&occurrence=' . $item->id;
|
263 |
+
return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
|
264 |
+
. ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>';
|
265 |
+
default:
|
266 |
+
return isset($item->$column_name)
|
267 |
+
? esc_html($item->$column_name)
|
268 |
+
: 'Column "' . esc_html($column_name) . '" not found';
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
public function reorder_items_str($a, $b)
|
273 |
+
{
|
274 |
+
$result = strcmp($a->{$this->_orderby}, $b->{$this->_orderby});
|
275 |
+
return ($this->_order === 'asc') ? $result : -$result;
|
276 |
+
}
|
277 |
+
|
278 |
+
public function reorder_items_int($a, $b)
|
279 |
+
{
|
280 |
+
$result = $a->{$this->_orderby} - $b->{$this->_orderby};
|
281 |
+
return ($this->_order === 'asc') ? $result : -$result;
|
282 |
+
}
|
283 |
+
|
284 |
+
public function meta_formatter($name, $value)
|
285 |
+
{
|
286 |
+
switch (true) {
|
287 |
+
case $name == '%Message%':
|
288 |
+
return esc_html($value);
|
289 |
+
|
290 |
+
case $name == '%PromoMessage%':
|
291 |
+
return '<p class="promo-alert">' . $value .'</p>';
|
292 |
+
|
293 |
+
case $name == '%PromoLink%':
|
294 |
+
return $value;
|
295 |
+
|
296 |
+
case $name == '%MetaLink%':
|
297 |
+
if (!empty($value)) {
|
298 |
+
return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
|
299 |
+
} else {
|
300 |
+
return "";
|
301 |
+
}
|
302 |
+
|
303 |
+
case $name == '%RevisionLink%':
|
304 |
+
if (!empty($value) && $value != 'NULL') {
|
305 |
+
return ' Click <a target="_blank" href="'.$value.'">here</a> to see the content changes.';
|
306 |
+
} else {
|
307 |
+
return "";
|
308 |
+
}
|
309 |
+
|
310 |
+
case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
|
311 |
+
return '<strong>' . (
|
312 |
+
strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '…') : esc_html($value)
|
313 |
+
) . '</strong>';
|
314 |
+
|
315 |
+
case $name == '%ClientIP%':
|
316 |
+
if (is_string($value)) {
|
317 |
+
return '<strong>' . str_replace(array("\"", "[", "]"), "", $value) . '</strong>';
|
318 |
+
} else {
|
319 |
+
return '<i>unknown</i>';
|
320 |
+
}
|
321 |
+
|
322 |
+
case strncmp($value, 'http://', 7) === 0:
|
323 |
+
case strncmp($value, 'https://', 7) === 0:
|
324 |
+
return '<a href="' . esc_html($value) . '"'
|
325 |
+
. ' title="' . esc_html($value) . '"'
|
326 |
+
. ' target="_blank">'
|
327 |
+
. esc_html(parse_url($value, PHP_URL_HOST)) . '/…/'
|
328 |
+
. esc_html(basename(parse_url($value, PHP_URL_PATH)))
|
329 |
+
. '</a>';
|
330 |
+
|
331 |
+
default:
|
332 |
+
return '<strong>' . esc_html($value) . '</strong>';
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
protected function is_multisite()
|
337 |
+
{
|
338 |
+
return $this->_plugin->IsMultisite();
|
339 |
+
}
|
340 |
+
|
341 |
+
protected function is_main_blog()
|
342 |
+
{
|
343 |
+
return get_current_blog_id() == 1;
|
344 |
+
}
|
345 |
+
|
346 |
+
protected function is_specific_view()
|
347 |
+
{
|
348 |
+
return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
|
349 |
+
}
|
350 |
+
|
351 |
+
protected function get_specific_view()
|
352 |
+
{
|
353 |
+
return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
|
354 |
+
}
|
355 |
+
|
356 |
+
protected function get_view_site_id()
|
357 |
+
{
|
358 |
+
switch (true) {
|
359 |
+
// non-multisite
|
360 |
+
case !$this->is_multisite():
|
361 |
+
return 0;
|
362 |
+
// multisite + main site view
|
363 |
+
case $this->is_main_blog() && !$this->is_specific_view():
|
364 |
+
return 0;
|
365 |
+
// multisite + switched site view
|
366 |
+
case $this->is_main_blog() && $this->is_specific_view():
|
367 |
+
return $this->get_specific_view();
|
368 |
+
// multisite + local site view
|
369 |
+
default:
|
370 |
+
return get_current_blog_id();
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
public function prepare_items()
|
375 |
+
{
|
376 |
+
$per_page = $this->_plugin->settings->GetViewPerPage();
|
377 |
+
|
378 |
+
$columns = $this->get_columns();
|
379 |
+
$hidden = array();
|
380 |
+
$sortable = $this->get_sortable_columns();
|
381 |
+
|
382 |
+
$this->_column_headers = array($columns, $hidden, $sortable);
|
383 |
+
|
384 |
+
//$this->process_bulk_action();
|
385 |
+
//TO DO: Get rid of OccurrenceQuery and use the Occurence Model
|
386 |
+
$query = new WSAL_Models_OccurrenceQuery();
|
387 |
+
|
388 |
+
$bid = (int)$this->get_view_site_id();
|
389 |
+
if ($bid) {
|
390 |
+
$query->addCondition("site_id = %s ", $bid);
|
391 |
+
}
|
392 |
+
|
393 |
+
$query = apply_filters('wsal_auditlog_query', $query);
|
394 |
+
|
395 |
+
$total_items = $query->getAdapter()->Count($query);
|
396 |
+
|
397 |
+
if (empty($_REQUEST["orderby"])) {
|
398 |
+
$query->addOrderBy("created_on", true);
|
399 |
+
} else {
|
400 |
+
$orderByField = $_REQUEST["orderby"];
|
401 |
+
|
402 |
+
$isDescending = true;
|
403 |
+
if (!empty($_REQUEST['order']) && $_REQUEST["order"] == "asc") {
|
404 |
+
$isDescending = false;
|
405 |
+
}
|
406 |
+
|
407 |
+
//TO DO: Allow order by meta values
|
408 |
+
if ($orderByField == "scip") {
|
409 |
+
$query->addMetaJoin();
|
410 |
+
$query->addOrderBy('CASE WHEN meta.name = "ClientIP" THEN meta.value END', $isDescending);
|
411 |
+
} else if ($orderByField == "user") {
|
412 |
+
$query->addMetaJoin();
|
413 |
+
$query->addOrderBy('CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $isDescending);
|
414 |
+
} else {
|
415 |
+
$tmp = new WSAL_Models_Occurrence();
|
416 |
+
//Making sure the field exists to order by
|
417 |
+
if (isset($tmp->{$orderByField})) {
|
418 |
+
// TODO we used to use a custom comparator ... is it safe to let MySQL do the ordering now?
|
419 |
+
$query->addOrderBy($_REQUEST["orderby"], $isDescending);
|
420 |
+
|
421 |
+
} else {
|
422 |
+
$query->addOrderBy("created_on", true);
|
423 |
+
}
|
424 |
+
}
|
425 |
+
}
|
426 |
+
|
427 |
+
/** @todo Modify $query instead */
|
428 |
+
/** @deprecated */
|
429 |
+
//$data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
|
430 |
+
$query->setOffset(($this->get_pagenum() - 1) * $per_page);
|
431 |
+
$query->setLimit($per_page);
|
432 |
+
|
433 |
+
$this->items = $query->getAdapter()->Execute($query);
|
434 |
+
|
435 |
+
$this->set_pagination_args(array(
|
436 |
+
'total_items' => $total_items,
|
437 |
+
'per_page' => $per_page,
|
438 |
+
'total_pages' => ceil($total_items / $per_page)
|
439 |
+
));
|
440 |
+
}
|
441 |
+
|
442 |
+
public function single_row($item)
|
443 |
+
{
|
444 |
+
if ($item->alert_id == 9999) {
|
445 |
+
echo '<tr style="background-color: #D5E46E">';
|
446 |
+
$this->single_row_columns($item);
|
447 |
+
echo '</tr>';
|
448 |
+
} else {
|
449 |
+
parent::single_row($item);
|
450 |
+
}
|
451 |
+
}
|
452 |
+
}
|
classes/Autoloader.php
CHANGED
@@ -1,69 +1,69 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Autoloader {
|
4 |
-
/**
|
5 |
-
* @var WpSecurityAuditLog
|
6 |
-
*/
|
7 |
-
protected $plugin;
|
8 |
-
|
9 |
-
protected $paths = array();
|
10 |
-
|
11 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
12 |
-
$this->plugin = $plugin;
|
13 |
-
|
14 |
-
// register autoloader
|
15 |
-
spl_autoload_register(array($this, 'LoadClass'));
|
16 |
-
}
|
17 |
-
|
18 |
-
public function Register($prefix, $path){
|
19 |
-
if(!isset($this->paths[$prefix]))
|
20 |
-
$this->paths[$prefix] = array();
|
21 |
-
$this->paths[$prefix][] = rtrim(str_replace('\\', '/', $path), '/') . '/';
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* This is the class autoloader. You should not call this directly.
|
26 |
-
* @param string $class Class name.
|
27 |
-
* @return boolean True if class is found and loaded, false otherwise.
|
28 |
-
*/
|
29 |
-
public function LoadClass($class){
|
30 |
-
foreach($this->paths as $prefix => $paths){
|
31 |
-
foreach($paths as $path){
|
32 |
-
if(strstr($class, $prefix) !== false){
|
33 |
-
$file = $path . str_replace('_', DIRECTORY_SEPARATOR, substr($class, strlen($prefix))) . '.php';
|
34 |
-
if(file_exists($file)){
|
35 |
-
$s = $this->plugin->profiler->Start('Autoload ' . basename($file));
|
36 |
-
require_once($file);
|
37 |
-
$s->Stop();
|
38 |
-
return class_exists($class, false) || interface_exists($class, false);
|
39 |
-
}
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
|
44 |
-
return false;
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Returns the class name of a particular file that contains the class.
|
49 |
-
* @param string $file File name.
|
50 |
-
* @return string|false Class name or false on error.
|
51 |
-
*/
|
52 |
-
public function GetClassFileClassName($file){
|
53 |
-
$file = str_replace('\\', '/', $file); // win/dos hotfix
|
54 |
-
|
55 |
-
foreach($this->paths as $prefix => $paths){
|
56 |
-
foreach($paths as $path){
|
57 |
-
if(strstr($file, $path) !== false){
|
58 |
-
return str_replace(
|
59 |
-
array($path, '/'),
|
60 |
-
array($prefix, '_'),
|
61 |
-
substr($file, 0, -4) // remove '.php'
|
62 |
-
);
|
63 |
-
}
|
64 |
-
}
|
65 |
-
}
|
66 |
-
|
67 |
-
return false;
|
68 |
-
}
|
69 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Autoloader {
|
4 |
+
/**
|
5 |
+
* @var WpSecurityAuditLog
|
6 |
+
*/
|
7 |
+
protected $plugin;
|
8 |
+
|
9 |
+
protected $paths = array();
|
10 |
+
|
11 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
12 |
+
$this->plugin = $plugin;
|
13 |
+
|
14 |
+
// register autoloader
|
15 |
+
spl_autoload_register(array($this, 'LoadClass'));
|
16 |
+
}
|
17 |
+
|
18 |
+
public function Register($prefix, $path){
|
19 |
+
if(!isset($this->paths[$prefix]))
|
20 |
+
$this->paths[$prefix] = array();
|
21 |
+
$this->paths[$prefix][] = rtrim(str_replace('\\', '/', $path), '/') . '/';
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This is the class autoloader. You should not call this directly.
|
26 |
+
* @param string $class Class name.
|
27 |
+
* @return boolean True if class is found and loaded, false otherwise.
|
28 |
+
*/
|
29 |
+
public function LoadClass($class){
|
30 |
+
foreach($this->paths as $prefix => $paths){
|
31 |
+
foreach($paths as $path){
|
32 |
+
if(strstr($class, $prefix) !== false){
|
33 |
+
$file = $path . str_replace('_', DIRECTORY_SEPARATOR, substr($class, strlen($prefix))) . '.php';
|
34 |
+
if(file_exists($file)){
|
35 |
+
$s = $this->plugin->profiler->Start('Autoload ' . basename($file));
|
36 |
+
require_once($file);
|
37 |
+
$s->Stop();
|
38 |
+
return class_exists($class, false) || interface_exists($class, false);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Returns the class name of a particular file that contains the class.
|
49 |
+
* @param string $file File name.
|
50 |
+
* @return string|false Class name or false on error.
|
51 |
+
*/
|
52 |
+
public function GetClassFileClassName($file){
|
53 |
+
$file = str_replace('\\', '/', $file); // win/dos hotfix
|
54 |
+
|
55 |
+
foreach($this->paths as $prefix => $paths){
|
56 |
+
foreach($paths as $path){
|
57 |
+
if(strstr($file, $path) !== false){
|
58 |
+
return str_replace(
|
59 |
+
array($path, '/'),
|
60 |
+
array($prefix, '_'),
|
61 |
+
substr($file, 0, -4) // remove '.php'
|
62 |
+
);
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
}
|
classes/Connector/AbstractConnector.php
CHANGED
@@ -1,36 +1,36 @@
|
|
1 |
-
<?php
|
2 |
-
require_once('ConnectorInterface.php');
|
3 |
-
|
4 |
-
abstract class WSAL_Connector_AbstractConnector
|
5 |
-
{
|
6 |
-
protected $connection = null;
|
7 |
-
protected $adaptersBasePath = null;
|
8 |
-
protected $adaptersDirName = null;
|
9 |
-
|
10 |
-
public function __construct($adaptersDirName = null)
|
11 |
-
{
|
12 |
-
$this->adaptersBasePath = __DIR__ . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'Models'. DIRECTORY_SEPARATOR .'Adapters'. DIRECTORY_SEPARATOR;
|
13 |
-
|
14 |
-
require_once($this->adaptersBasePath . 'ActiveRecordInterface.php');
|
15 |
-
require_once($this->adaptersBasePath . 'MetaInterface.php');
|
16 |
-
require_once($this->adaptersBasePath . 'OccurrenceInterface.php');
|
17 |
-
require_once($this->adaptersBasePath . 'QueryInterface.php');
|
18 |
-
|
19 |
-
if (!empty($adaptersDirName)) {
|
20 |
-
$this->adaptersDirName = $adaptersDirName;
|
21 |
-
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'ActiveRecordAdapter.php');
|
22 |
-
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'MetaAdapter.php');
|
23 |
-
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'OccurrenceAdapter.php');
|
24 |
-
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'QueryAdapter.php');
|
25 |
-
}
|
26 |
-
}
|
27 |
-
|
28 |
-
public function getAdaptersDirectory()
|
29 |
-
{
|
30 |
-
if (!empty($this->adaptersBasePath) && !empty($this->adaptersDirName)) {
|
31 |
-
return $this->adaptersBasePath . $this->adaptersDirName;
|
32 |
-
} else {
|
33 |
-
return false;
|
34 |
-
}
|
35 |
-
}
|
36 |
-
}
|
1 |
+
<?php
|
2 |
+
require_once('ConnectorInterface.php');
|
3 |
+
|
4 |
+
abstract class WSAL_Connector_AbstractConnector
|
5 |
+
{
|
6 |
+
protected $connection = null;
|
7 |
+
protected $adaptersBasePath = null;
|
8 |
+
protected $adaptersDirName = null;
|
9 |
+
|
10 |
+
public function __construct($adaptersDirName = null)
|
11 |
+
{
|
12 |
+
$this->adaptersBasePath = __DIR__ . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'Models'. DIRECTORY_SEPARATOR .'Adapters'. DIRECTORY_SEPARATOR;
|
13 |
+
|
14 |
+
require_once($this->adaptersBasePath . 'ActiveRecordInterface.php');
|
15 |
+
require_once($this->adaptersBasePath . 'MetaInterface.php');
|
16 |
+
require_once($this->adaptersBasePath . 'OccurrenceInterface.php');
|
17 |
+
require_once($this->adaptersBasePath . 'QueryInterface.php');
|
18 |
+
|
19 |
+
if (!empty($adaptersDirName)) {
|
20 |
+
$this->adaptersDirName = $adaptersDirName;
|
21 |
+
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'ActiveRecordAdapter.php');
|
22 |
+
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'MetaAdapter.php');
|
23 |
+
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'OccurrenceAdapter.php');
|
24 |
+
require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'QueryAdapter.php');
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
public function getAdaptersDirectory()
|
29 |
+
{
|
30 |
+
if (!empty($this->adaptersBasePath) && !empty($this->adaptersDirName)) {
|
31 |
+
return $this->adaptersBasePath . $this->adaptersDirName;
|
32 |
+
} else {
|
33 |
+
return false;
|
34 |
+
}
|
35 |
+
}
|
36 |
+
}
|
classes/Connector/ConnectorFactory.php
CHANGED
@@ -1,87 +1,87 @@
|
|
1 |
-
<?php
|
2 |
-
require_once(__DIR__ . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'Settings.php');
|
3 |
-
require_once('MySQLDBConnector.php');
|
4 |
-
|
5 |
-
abstract class WSAL_Connector_ConnectorFactory
|
6 |
-
{
|
7 |
-
public static $connector;
|
8 |
-
public static $defaultConnector;
|
9 |
-
public static $adapter;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Returns the a default WPDB connector for saving options
|
13 |
-
*/
|
14 |
-
public static function GetDefaultConnector()
|
15 |
-
{
|
16 |
-
return new WSAL_Connector_MySQLDB();
|
17 |
-
}
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Returns a connector singleton
|
21 |
-
* @return WSAL_Connector_ConnectorInterface
|
22 |
-
*/
|
23 |
-
public static function GetConnector($config = null)
|
24 |
-
{
|
25 |
-
if (!empty($config)) {
|
26 |
-
$connectionConfig = $config;
|
27 |
-
} else {
|
28 |
-
$connectionConfig = self::GetConfig();
|
29 |
-
}
|
30 |
-
|
31 |
-
//TO DO: Load connection config
|
32 |
-
if (self::$connector == null || !empty($config)) {
|
33 |
-
switch (strtolower($connectionConfig['type'])) {
|
34 |
-
//TO DO: Add other connectors
|
35 |
-
case 'mysql':
|
36 |
-
default:
|
37 |
-
//use config
|
38 |
-
self::$connector = new WSAL_Connector_MySQLDB($connectionConfig);
|
39 |
-
}
|
40 |
-
}
|
41 |
-
return self::$connector;
|
42 |
-
}
|
43 |
-
|
44 |
-
public static function GetConfig()
|
45 |
-
{
|
46 |
-
$conf = new WSAL_Settings(WpSecurityAuditLog::GetInstance());
|
47 |
-
$type = $conf->GetAdapterConfig('adapter-type');
|
48 |
-
if (empty($type)) {
|
49 |
-
return null;
|
50 |
-
} else {
|
51 |
-
return array(
|
52 |
-
'type' => $conf->GetAdapterConfig('adapter-type'),
|
53 |
-
'user' => $conf->GetAdapterConfig('adapter-user'),
|
54 |
-
'password' => $conf->GetAdapterConfig('adapter-password'),
|
55 |
-
'name' => $conf->GetAdapterConfig('adapter-name'),
|
56 |
-
'hostname' => $conf->GetAdapterConfig('adapter-hostname'),
|
57 |
-
'base_prefix' => $conf->GetAdapterConfig('adapter-base-prefix')
|
58 |
-
);
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
-
public static function CheckConfig($type, $user, $password, $name, $hostname, $base_prefix)
|
63 |
-
{
|
64 |
-
$result = false;
|
65 |
-
$config = self::GetConfigArray($type, $user, $password, $name, $hostname, $base_prefix);
|
66 |
-
switch (strtolower($type)) {
|
67 |
-
//TO DO: Add other connectors
|
68 |
-
case 'mysql':
|
69 |
-
default:
|
70 |
-
$test = new WSAL_Connector_MySQLDB($config);
|
71 |
-
$result = $test->TestConnection();
|
72 |
-
}
|
73 |
-
return $result;
|
74 |
-
}
|
75 |
-
|
76 |
-
public static function GetConfigArray($type, $user, $password, $name, $hostname, $base_prefix)
|
77 |
-
{
|
78 |
-
return array(
|
79 |
-
'type' => $type,
|
80 |
-
'user' => $user,
|
81 |
-
'password' => $password,
|
82 |
-
'name' => $name,
|
83 |
-
'hostname' => $hostname,
|
84 |
-
'base_prefix' => $base_prefix
|
85 |
-
);
|
86 |
-
}
|
87 |
-
}
|
1 |
+
<?php
|
2 |
+
require_once(__DIR__ . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'Settings.php');
|
3 |
+
require_once('MySQLDBConnector.php');
|
4 |
+
|
5 |
+
abstract class WSAL_Connector_ConnectorFactory
|
6 |
+
{
|
7 |
+
public static $connector;
|
8 |
+
public static $defaultConnector;
|
9 |
+
public static $adapter;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Returns the a default WPDB connector for saving options
|
13 |
+
*/
|
14 |
+
public static function GetDefaultConnector()
|
15 |
+
{
|
16 |
+
return new WSAL_Connector_MySQLDB();
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Returns a connector singleton
|
21 |
+
* @return WSAL_Connector_ConnectorInterface
|
22 |
+
*/
|
23 |
+
public static function GetConnector($config = null)
|
24 |
+
{
|
25 |
+
if (!empty($config)) {
|
26 |
+
$connectionConfig = $config;
|
27 |
+
} else {
|
28 |
+
$connectionConfig = self::GetConfig();
|
29 |
+
}
|
30 |
+
|
31 |
+
//TO DO: Load connection config
|
32 |
+
if (self::$connector == null || !empty($config)) {
|
33 |
+
switch (strtolower($connectionConfig['type'])) {
|
34 |
+
//TO DO: Add other connectors
|
35 |
+
case 'mysql':
|
36 |
+
default:
|
37 |
+
//use config
|
38 |
+
self::$connector = new WSAL_Connector_MySQLDB($connectionConfig);
|
39 |
+
}
|
40 |
+
}
|
41 |
+
return self::$connector;
|
42 |
+
}
|
43 |
+
|
44 |
+
public static function GetConfig()
|
45 |
+
{
|
46 |
+
$conf = new WSAL_Settings(WpSecurityAuditLog::GetInstance());
|
47 |
+
$type = $conf->GetAdapterConfig('adapter-type');
|
48 |
+
if (empty($type)) {
|
49 |
+
return null;
|
50 |
+
} else {
|
51 |
+
return array(
|
52 |
+
'type' => $conf->GetAdapterConfig('adapter-type'),
|
53 |
+
'user' => $conf->GetAdapterConfig('adapter-user'),
|
54 |
+
'password' => $conf->GetAdapterConfig('adapter-password'),
|
55 |
+
'name' => $conf->GetAdapterConfig('adapter-name'),
|
56 |
+
'hostname' => $conf->GetAdapterConfig('adapter-hostname'),
|
57 |
+
'base_prefix' => $conf->GetAdapterConfig('adapter-base-prefix')
|
58 |
+
);
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
public static function CheckConfig($type, $user, $password, $name, $hostname, $base_prefix)
|
63 |
+
{
|
64 |
+
$result = false;
|
65 |
+
$config = self::GetConfigArray($type, $user, $password, $name, $hostname, $base_prefix);
|
66 |
+
switch (strtolower($type)) {
|
67 |
+
//TO DO: Add other connectors
|
68 |
+
case 'mysql':
|
69 |
+
default:
|
70 |
+
$test = new WSAL_Connector_MySQLDB($config);
|
71 |
+
$result = $test->TestConnection();
|
72 |
+
}
|
73 |
+
return $result;
|
74 |
+
}
|
75 |
+
|
76 |
+
public static function GetConfigArray($type, $user, $password, $name, $hostname, $base_prefix)
|
77 |
+
{
|
78 |
+
return array(
|
79 |
+
'type' => $type,
|
80 |
+
'user' => $user,
|
81 |
+
'password' => $password,
|
82 |
+
'name' => $name,
|
83 |
+
'hostname' => $hostname,
|
84 |
+
'base_prefix' => $base_prefix
|
85 |
+
);
|
86 |
+
}
|
87 |
+
}
|
classes/Connector/ConnectorInterface.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
interface WSAL_Connector_ConnectorInterface
|
4 |
-
{
|
5 |
-
public function getAdapter($class_name);
|
6 |
-
public function getConnection();
|
7 |
-
public function isInstalled();
|
8 |
-
public function canMigrate();
|
9 |
-
public function installAll();
|
10 |
-
public function uninstallAll();
|
11 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface WSAL_Connector_ConnectorInterface
|
4 |
+
{
|
5 |
+
public function getAdapter($class_name);
|
6 |
+
public function getConnection();
|
7 |
+
public function isInstalled();
|
8 |
+
public function canMigrate();
|
9 |
+
public function installAll();
|
10 |
+
public function uninstallAll();
|
11 |
+
}
|
classes/Connector/MySQLDBConnector.php
CHANGED
@@ -1,337 +1,337 @@
|
|
1 |
-
<?php
|
2 |
-
require_once('ConnectorInterface.php');
|
3 |
-
require_once('AbstractConnector.php');
|
4 |
-
require_once('wp-db-custom.php');
|
5 |
-
|
6 |
-
class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface
|
7 |
-
{
|
8 |
-
protected $connectionConfig = null;
|
9 |
-
|
10 |
-
public function __construct($connectionConfig = null)
|
11 |
-
{
|
12 |
-
$this->connectionConfig = $connectionConfig;
|
13 |
-
parent::__construct("MySQL");
|
14 |
-
require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
|
15 |
-
}
|
16 |
-
|
17 |
-
public function TestConnection()
|
18 |
-
{
|
19 |
-
error_reporting(E_ALL ^ E_WARNING);
|
20 |
-
$connectionConfig = $this->connectionConfig;
|
21 |
-
$password = $this->decryptString($connectionConfig['password']);
|
22 |
-
$newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
|
23 |
-
if (!$newWpdb->has_connected) { // Database Error
|
24 |
-
throw new Exception("Connection failed. Please check your connection details.");
|
25 |
-
}
|
26 |
-
}
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Creates a connection and returns it
|
30 |
-
* @return Instance of WPDB
|
31 |
-
*/
|
32 |
-
private function createConnection()
|
33 |
-
{
|
34 |
-
if (!empty($this->connectionConfig)) {
|
35 |
-
//TO DO: Use the provided connection config
|
36 |
-
$connectionConfig = $this->connectionConfig;
|
37 |
-
$password = $this->decryptString($connectionConfig['password']);
|
38 |
-
$newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
|
39 |
-
$newWpdb->set_prefix($connectionConfig['base_prefix']);
|
40 |
-
return $newWpdb;
|
41 |
-
} else {
|
42 |
-
global $wpdb;
|
43 |
-
return $wpdb;
|
44 |
-
}
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Returns a wpdb instance
|
49 |
-
*/
|
50 |
-
public function getConnection()
|
51 |
-
{
|
52 |
-
if (!empty($this->connection)) {
|
53 |
-
return $this->connection;
|
54 |
-
} else {
|
55 |
-
$this->connection = $this->createConnection();
|
56 |
-
return $this->connection;
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Gets an adapter for the specified model
|
62 |
-
*/
|
63 |
-
public function getAdapter($class_name)
|
64 |
-
{
|
65 |
-
$objName = $this->getAdapterClassName($class_name);
|
66 |
-
return new $objName($this->getConnection());
|
67 |
-
}
|
68 |
-
|
69 |
-
protected function getAdapterClassName($class_name)
|
70 |
-
{
|
71 |
-
return 'WSAL_Adapters_MySQL_'.$class_name;
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Checks if the necessary tables are available
|
76 |
-
*/
|
77 |
-
public function isInstalled()
|
78 |
-
{
|
79 |
-
global $wpdb;
|
80 |
-
$table = $wpdb->base_prefix . 'wsal_occurrences';
|
81 |
-
return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Checks if old version tables are available
|
86 |
-
*/
|
87 |
-
public function canMigrate()
|
88 |
-
{
|
89 |
-
$wpdb = $this->getConnection();
|
90 |
-
$table = $wpdb->base_prefix . 'wordpress_auditlog_events';
|
91 |
-
return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Install all DB tables.
|
96 |
-
*/
|
97 |
-
public function installAll($excludeOptions = false)
|
98 |
-
{
|
99 |
-
$plugin = WpSecurityAuditLog::GetInstance();
|
100 |
-
|
101 |
-
foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
|
102 |
-
$filePath = explode(DIRECTORY_SEPARATOR, $file);
|
103 |
-
$fileName = $filePath[count($filePath) - 1];
|
104 |
-
$className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
|
105 |
-
|
106 |
-
$class = new $className($this->getConnection());
|
107 |
-
if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
|
108 |
-
continue;
|
109 |
-
}
|
110 |
-
|
111 |
-
if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
|
112 |
-
$class->Install();
|
113 |
-
}
|
114 |
-
}
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Uninstall all DB tables.
|
119 |
-
*/
|
120 |
-
public function uninstallAll()
|
121 |
-
{
|
122 |
-
$plugin = WpSecurityAuditLog::GetInstance();
|
123 |
-
|
124 |
-
foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
|
125 |
-
$filePath = explode(DIRECTORY_SEPARATOR, $file);
|
126 |
-
$fileName = $filePath[count($filePath) - 1];
|
127 |
-
$className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
|
128 |
-
|
129 |
-
$class = new $className($this->getConnection());
|
130 |
-
if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
|
131 |
-
$class->Uninstall();
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
private function GetIncreaseOccurrence()
|
137 |
-
{
|
138 |
-
$_wpdb = $this->getConnection();
|
139 |
-
$occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
|
140 |
-
$sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
|
141 |
-
return (int)$_wpdb->get_var($sql);
|
142 |
-
}
|
143 |
-
|
144 |
-
public function MigrateMeta($index, $limit)
|
145 |
-
{
|
146 |
-
$result = null;
|
147 |
-
$offset = ($index * $limit);
|
148 |
-
global $wpdb;
|
149 |
-
$_wpdb = $this->getConnection();
|
150 |
-
// Add +1 because an alert is generated after delete the metadata table
|
151 |
-
$increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
|
152 |
-
|
153 |
-
// Load data Meta from WP
|
154 |
-
$meta = new WSAL_Adapters_MySQL_Meta($wpdb);
|
155 |
-
if (!$meta->IsInstalled()) {
|
156 |
-
$result['empty'] = true;
|
157 |
-
return $result;
|
158 |
-
}
|
159 |
-
$sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
160 |
-
$metadata = $wpdb->get_results($sql, ARRAY_A);
|
161 |
-
|
162 |
-
// Insert data to External DB
|
163 |
-
if (!empty($metadata)) {
|
164 |
-
$metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
|
165 |
-
|
166 |
-
$index++;
|
167 |
-
$sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
|
168 |
-
foreach ($metadata as $entry) {
|
169 |
-
$occurrence_id = intval($entry['occurrence_id']) + $increase_occurrence_id;
|
170 |
-
$sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
|
171 |
-
}
|
172 |
-
$sql = rtrim($sql, ", ");
|
173 |
-
$_wpdb->query($sql);
|
174 |
-
|
175 |
-
$result['complete'] = false;
|
176 |
-
} else {
|
177 |
-
$result['complete'] = true;
|
178 |
-
$this->DeleteAfterMigrate($meta);
|
179 |
-
}
|
180 |
-
$result['index'] = $index;
|
181 |
-
return $result;
|
182 |
-
}
|
183 |
-
|
184 |
-
public function MigrateOccurrence($index, $limit)
|
185 |
-
{
|
186 |
-
$result = null;
|
187 |
-
$offset = ($index * $limit);
|
188 |
-
global $wpdb;
|
189 |
-
$_wpdb = $this->getConnection();
|
190 |
-
|
191 |
-
// Load data Occurrences from WP
|
192 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
|
193 |
-
if (!$occurrence->IsInstalled()) {
|
194 |
-
$result['empty'] = true;
|
195 |
-
return $result;
|
196 |
-
}
|
197 |
-
$sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
198 |
-
$occurrences = $wpdb->get_results($sql, ARRAY_A);
|
199 |
-
|
200 |
-
// Insert data to External DB
|
201 |
-
if (!empty($occurrences)) {
|
202 |
-
$occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
|
203 |
-
|
204 |
-
$index++;
|
205 |
-
$sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
|
206 |
-
foreach ($occurrences as $entry) {
|
207 |
-
$sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
|
208 |
-
}
|
209 |
-
$sql = rtrim($sql, ", ");
|
210 |
-
$_wpdb->query($sql);
|
211 |
-
|
212 |
-
$result['complete'] = false;
|
213 |
-
} else {
|
214 |
-
$result['complete'] = true;
|
215 |
-
$this->DeleteAfterMigrate($occurrence);
|
216 |
-
}
|
217 |
-
$result['index'] = $index;
|
218 |
-
return $result;
|
219 |
-
}
|
220 |
-
|
221 |
-
public function MigrateBackOccurrence($index, $limit)
|
222 |
-
{
|
223 |
-
$result = null;
|
224 |
-
$offset = ($index * $limit);
|
225 |
-
global $wpdb;
|
226 |
-
$_wpdb = $this->getConnection();
|
227 |
-
|
228 |
-
// Load data Occurrences from External DB
|
229 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
|
230 |
-
if (!$occurrence->IsInstalled()) {
|
231 |
-
$result['empty'] = true;
|
232 |
-
return $result;
|
233 |
-
}
|
234 |
-
$sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
235 |
-
$occurrences = $_wpdb->get_results($sql, ARRAY_A);
|
236 |
-
|
237 |
-
// Insert data to WP
|
238 |
-
if (!empty($occurrences)) {
|
239 |
-
$occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
|
240 |
-
|
241 |
-
$index++;
|
242 |
-
$sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
|
243 |
-
foreach ($occurrences as $entry) {
|
244 |
-
$sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
|
245 |
-
}
|
246 |
-
$sql = rtrim($sql, ", ");
|
247 |
-
$wpdb->query($sql);
|
248 |
-
|
249 |
-
$result['complete'] = false;
|
250 |
-
} else {
|
251 |
-
$result['complete'] = true;
|
252 |
-
}
|
253 |
-
$result['index'] = $index;
|
254 |
-
return $result;
|
255 |
-
}
|
256 |
-
|
257 |
-
public function MigrateBackMeta($index, $limit)
|
258 |
-
{
|
259 |
-
$result = null;
|
260 |
-
$offset = ($index * $limit);
|
261 |
-
global $wpdb;
|
262 |
-
$_wpdb = $this->getConnection();
|
263 |
-
|
264 |
-
// Load data Meta from External DB
|
265 |
-
$meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
|
266 |
-
if (!$meta->IsInstalled()) {
|
267 |
-
$result['empty'] = true;
|
268 |
-
return $result;
|
269 |
-
}
|
270 |
-
$sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
271 |
-
$metadata = $_wpdb->get_results($sql, ARRAY_A);
|
272 |
-
|
273 |
-
// Insert data to WP
|
274 |
-
if (!empty($metadata)) {
|
275 |
-
$metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
|
276 |
-
|
277 |
-
$index++;
|
278 |
-
$sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
|
279 |
-
foreach ($metadata as $entry) {
|
280 |
-
$sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
|
281 |
-
}
|
282 |
-
$sql = rtrim($sql, ", ");
|
283 |
-
$wpdb->query($sql);
|
284 |
-
|
285 |
-
$result['complete'] = false;
|
286 |
-
} else {
|
287 |
-
$result['complete'] = true;
|
288 |
-
}
|
289 |
-
$result['index'] = $index;
|
290 |
-
return $result;
|
291 |
-
}
|
292 |
-
|
293 |
-
private function DeleteAfterMigrate($record)
|
294 |
-
{
|
295 |
-
global $wpdb;
|
296 |
-
$sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
|
297 |
-
$wpdb->query($sql);
|
298 |
-
}
|
299 |
-
|
300 |
-
public function encryptString($plaintext)
|
301 |
-
{
|
302 |
-
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
|
303 |
-
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
304 |
-
$key = $this->truncateKey();
|
305 |
-
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
|
306 |
-
$ciphertext = $iv . $ciphertext;
|
307 |
-
$ciphertext_base64 = base64_encode($ciphertext);
|
308 |
-
|
309 |
-
return $ciphertext_base64;
|
310 |
-
}
|
311 |
-
|
312 |
-
private function decryptString($ciphertext_base64)
|
313 |
-
{
|
314 |
-
$ciphertext_dec = base64_decode($ciphertext_base64);
|
315 |
-
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
|
316 |
-
|
317 |
-
$iv_dec = substr($ciphertext_dec, 0, $iv_size);
|
318 |
-
$ciphertext_dec = substr($ciphertext_dec, $iv_size);
|
319 |
-
$key = $this->truncateKey();
|
320 |
-
$plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
|
321 |
-
|
322 |
-
return rtrim($plaintext_dec, "\0");
|
323 |
-
}
|
324 |
-
|
325 |
-
private function truncateKey()
|
326 |
-
{
|
327 |
-
if (!defined('AUTH_KEY')) {
|
328 |
-
return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
|
329 |
-
}
|
330 |
-
$key_size = strlen(AUTH_KEY);
|
331 |
-
if ($key_size > 32) {
|
332 |
-
return substr(AUTH_KEY, 0, 32);
|
333 |
-
} else {
|
334 |
-
return AUTH_KEY;
|
335 |
-
}
|
336 |
-
}
|
337 |
-
}
|
1 |
+
<?php
|
2 |
+
require_once('ConnectorInterface.php');
|
3 |
+
require_once('AbstractConnector.php');
|
4 |
+
require_once('wp-db-custom.php');
|
5 |
+
|
6 |
+
class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface
|
7 |
+
{
|
8 |
+
protected $connectionConfig = null;
|
9 |
+
|
10 |
+
public function __construct($connectionConfig = null)
|
11 |
+
{
|
12 |
+
$this->connectionConfig = $connectionConfig;
|
13 |
+
parent::__construct("MySQL");
|
14 |
+
require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function TestConnection()
|
18 |
+
{
|
19 |
+
error_reporting(E_ALL ^ E_WARNING);
|
20 |
+
$connectionConfig = $this->connectionConfig;
|
21 |
+
$password = $this->decryptString($connectionConfig['password']);
|
22 |
+
$newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
|
23 |
+
if (!$newWpdb->has_connected) { // Database Error
|
24 |
+
throw new Exception("Connection failed. Please check your connection details.");
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Creates a connection and returns it
|
30 |
+
* @return Instance of WPDB
|
31 |
+
*/
|
32 |
+
private function createConnection()
|
33 |
+
{
|
34 |
+
if (!empty($this->connectionConfig)) {
|
35 |
+
//TO DO: Use the provided connection config
|
36 |
+
$connectionConfig = $this->connectionConfig;
|
37 |
+
$password = $this->decryptString($connectionConfig['password']);
|
38 |
+
$newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
|
39 |
+
$newWpdb->set_prefix($connectionConfig['base_prefix']);
|
40 |
+
return $newWpdb;
|
41 |
+
} else {
|
42 |
+
global $wpdb;
|
43 |
+
return $wpdb;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Returns a wpdb instance
|
49 |
+
*/
|
50 |
+
public function getConnection()
|
51 |
+
{
|
52 |
+
if (!empty($this->connection)) {
|
53 |
+
return $this->connection;
|
54 |
+
} else {
|
55 |
+
$this->connection = $this->createConnection();
|
56 |
+
return $this->connection;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Gets an adapter for the specified model
|
62 |
+
*/
|
63 |
+
public function getAdapter($class_name)
|
64 |
+
{
|
65 |
+
$objName = $this->getAdapterClassName($class_name);
|
66 |
+
return new $objName($this->getConnection());
|
67 |
+
}
|
68 |
+
|
69 |
+
protected function getAdapterClassName($class_name)
|
70 |
+
{
|
71 |
+
return 'WSAL_Adapters_MySQL_'.$class_name;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Checks if the necessary tables are available
|
76 |
+
*/
|
77 |
+
public function isInstalled()
|
78 |
+
{
|
79 |
+
global $wpdb;
|
80 |
+
$table = $wpdb->base_prefix . 'wsal_occurrences';
|
81 |
+
return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Checks if old version tables are available
|
86 |
+
*/
|
87 |
+
public function canMigrate()
|
88 |
+
{
|
89 |
+
$wpdb = $this->getConnection();
|
90 |
+
$table = $wpdb->base_prefix . 'wordpress_auditlog_events';
|
91 |
+
return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Install all DB tables.
|
96 |
+
*/
|
97 |
+
public function installAll($excludeOptions = false)
|
98 |
+
{
|
99 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
100 |
+
|
101 |
+
foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
|
102 |
+
$filePath = explode(DIRECTORY_SEPARATOR, $file);
|
103 |
+
$fileName = $filePath[count($filePath) - 1];
|
104 |
+
$className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
|
105 |
+
|
106 |
+
$class = new $className($this->getConnection());
|
107 |
+
if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
|
108 |
+
continue;
|
109 |
+
}
|
110 |
+
|
111 |
+
if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
|
112 |
+
$class->Install();
|
113 |
+
}
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Uninstall all DB tables.
|
119 |
+
*/
|
120 |
+
public function uninstallAll()
|
121 |
+
{
|
122 |
+
$plugin = WpSecurityAuditLog::GetInstance();
|
123 |
+
|
124 |
+
foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
|
125 |
+
$filePath = explode(DIRECTORY_SEPARATOR, $file);
|
126 |
+
$fileName = $filePath[count($filePath) - 1];
|
127 |
+
$className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
|
128 |
+
|
129 |
+
$class = new $className($this->getConnection());
|
130 |
+
if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
|
131 |
+
$class->Uninstall();
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
private function GetIncreaseOccurrence()
|
137 |
+
{
|
138 |
+
$_wpdb = $this->getConnection();
|
139 |
+
$occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
|
140 |
+
$sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
|
141 |
+
return (int)$_wpdb->get_var($sql);
|
142 |
+
}
|
143 |
+
|
144 |
+
public function MigrateMeta($index, $limit)
|
145 |
+
{
|
146 |
+
$result = null;
|
147 |
+
$offset = ($index * $limit);
|
148 |
+
global $wpdb;
|
149 |
+
$_wpdb = $this->getConnection();
|
150 |
+
// Add +1 because an alert is generated after delete the metadata table
|
151 |
+
$increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
|
152 |
+
|
153 |
+
// Load data Meta from WP
|
154 |
+
$meta = new WSAL_Adapters_MySQL_Meta($wpdb);
|
155 |
+
if (!$meta->IsInstalled()) {
|
156 |
+
$result['empty'] = true;
|
157 |
+
return $result;
|
158 |
+
}
|
159 |
+
$sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
160 |
+
$metadata = $wpdb->get_results($sql, ARRAY_A);
|
161 |
+
|
162 |
+
// Insert data to External DB
|
163 |
+
if (!empty($metadata)) {
|
164 |
+
$metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
|
165 |
+
|
166 |
+
$index++;
|
167 |
+
$sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
|
168 |
+
foreach ($metadata as $entry) {
|
169 |
+
$occurrence_id = intval($entry['occurrence_id']) + $increase_occurrence_id;
|
170 |
+
$sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
|
171 |
+
}
|
172 |
+
$sql = rtrim($sql, ", ");
|
173 |
+
$_wpdb->query($sql);
|
174 |
+
|
175 |
+
$result['complete'] = false;
|
176 |
+
} else {
|
177 |
+
$result['complete'] = true;
|
178 |
+
$this->DeleteAfterMigrate($meta);
|
179 |
+
}
|
180 |
+
$result['index'] = $index;
|
181 |
+
return $result;
|
182 |
+
}
|
183 |
+
|
184 |
+
public function MigrateOccurrence($index, $limit)
|
185 |
+
{
|
186 |
+
$result = null;
|
187 |
+
$offset = ($index * $limit);
|
188 |
+
global $wpdb;
|
189 |
+
$_wpdb = $this->getConnection();
|
190 |
+
|
191 |
+
// Load data Occurrences from WP
|
192 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
|
193 |
+
if (!$occurrence->IsInstalled()) {
|
194 |
+
$result['empty'] = true;
|
195 |
+
return $result;
|
196 |
+
}
|
197 |
+
$sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
198 |
+
$occurrences = $wpdb->get_results($sql, ARRAY_A);
|
199 |
+
|
200 |
+
// Insert data to External DB
|
201 |
+
if (!empty($occurrences)) {
|
202 |
+
$occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
|
203 |
+
|
204 |
+
$index++;
|
205 |
+
$sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
|
206 |
+
foreach ($occurrences as $entry) {
|
207 |
+
$sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
|
208 |
+
}
|
209 |
+
$sql = rtrim($sql, ", ");
|
210 |
+
$_wpdb->query($sql);
|
211 |
+
|
212 |
+
$result['complete'] = false;
|
213 |
+
} else {
|
214 |
+
$result['complete'] = true;
|
215 |
+
$this->DeleteAfterMigrate($occurrence);
|
216 |
+
}
|
217 |
+
$result['index'] = $index;
|
218 |
+
return $result;
|
219 |
+
}
|
220 |
+
|
221 |
+
public function MigrateBackOccurrence($index, $limit)
|
222 |
+
{
|
223 |
+
$result = null;
|
224 |
+
$offset = ($index * $limit);
|
225 |
+
global $wpdb;
|
226 |
+
$_wpdb = $this->getConnection();
|
227 |
+
|
228 |
+
// Load data Occurrences from External DB
|
229 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
|
230 |
+
if (!$occurrence->IsInstalled()) {
|
231 |
+
$result['empty'] = true;
|
232 |
+
return $result;
|
233 |
+
}
|
234 |
+
$sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
235 |
+
$occurrences = $_wpdb->get_results($sql, ARRAY_A);
|
236 |
+
|
237 |
+
// Insert data to WP
|
238 |
+
if (!empty($occurrences)) {
|
239 |
+
$occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
|
240 |
+
|
241 |
+
$index++;
|
242 |
+
$sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
|
243 |
+
foreach ($occurrences as $entry) {
|
244 |
+
$sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
|
245 |
+
}
|
246 |
+
$sql = rtrim($sql, ", ");
|
247 |
+
$wpdb->query($sql);
|
248 |
+
|
249 |
+
$result['complete'] = false;
|
250 |
+
} else {
|
251 |
+
$result['complete'] = true;
|
252 |
+
}
|
253 |
+
$result['index'] = $index;
|
254 |
+
return $result;
|
255 |
+
}
|
256 |
+
|
257 |
+
public function MigrateBackMeta($index, $limit)
|
258 |
+
{
|
259 |
+
$result = null;
|
260 |
+
$offset = ($index * $limit);
|
261 |
+
global $wpdb;
|
262 |
+
$_wpdb = $this->getConnection();
|
263 |
+
|
264 |
+
// Load data Meta from External DB
|
265 |
+
$meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
|
266 |
+
if (!$meta->IsInstalled()) {
|
267 |
+
$result['empty'] = true;
|
268 |
+
return $result;
|
269 |
+
}
|
270 |
+
$sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
|
271 |
+
$metadata = $_wpdb->get_results($sql, ARRAY_A);
|
272 |
+
|
273 |
+
// Insert data to WP
|
274 |
+
if (!empty($metadata)) {
|
275 |
+
$metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
|
276 |
+
|
277 |
+
$index++;
|
278 |
+
$sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
|
279 |
+
foreach ($metadata as $entry) {
|
280 |
+
$sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
|
281 |
+
}
|
282 |
+
$sql = rtrim($sql, ", ");
|
283 |
+
$wpdb->query($sql);
|
284 |
+
|
285 |
+
$result['complete'] = false;
|
286 |
+
} else {
|
287 |
+
$result['complete'] = true;
|
288 |
+
}
|
289 |
+
$result['index'] = $index;
|
290 |
+
return $result;
|
291 |
+
}
|
292 |
+
|
293 |
+
private function DeleteAfterMigrate($record)
|
294 |
+
{
|
295 |
+
global $wpdb;
|
296 |
+
$sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
|
297 |
+
$wpdb->query($sql);
|
298 |
+
}
|
299 |
+
|
300 |
+
public function encryptString($plaintext)
|
301 |
+
{
|
302 |
+
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
|
303 |
+
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
304 |
+
$key = $this->truncateKey();
|
305 |
+
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
|
306 |
+
$ciphertext = $iv . $ciphertext;
|
307 |
+
$ciphertext_base64 = base64_encode($ciphertext);
|
308 |
+
|
309 |
+
return $ciphertext_base64;
|
310 |
+
}
|
311 |
+
|
312 |
+
private function decryptString($ciphertext_base64)
|
313 |
+
{
|
314 |
+
$ciphertext_dec = base64_decode($ciphertext_base64);
|
315 |
+
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
|
316 |
+
|
317 |
+
$iv_dec = substr($ciphertext_dec, 0, $iv_size);
|
318 |
+
$ciphertext_dec = substr($ciphertext_dec, $iv_size);
|
319 |
+
$key = $this->truncateKey();
|
320 |
+
$plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
|
321 |
+
|
322 |
+
return rtrim($plaintext_dec, "\0");
|
323 |
+
}
|
324 |
+
|
325 |
+
private function truncateKey()
|
326 |
+
{
|
327 |
+
if (!defined('AUTH_KEY')) {
|
328 |
+
return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
|
329 |
+
}
|
330 |
+
$key_size = strlen(AUTH_KEY);
|
331 |
+
if ($key_size > 32) {
|
332 |
+
return substr(AUTH_KEY, 0, 32);
|
333 |
+
} else {
|
334 |
+
return AUTH_KEY;
|
335 |
+
}
|
336 |
+
}
|
337 |
+
}
|
classes/Connector/wp-db-custom.php
CHANGED
@@ -1,36 +1,36 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class wpdbCustom extends wpdb
|
4 |
-
{
|
5 |
-
/*
|
6 |
-
* overwrite wpdb class for set $allow_bail to false
|
7 |
-
* and hide the print of the error
|
8 |
-
*/
|
9 |
-
public function __construct($dbuser, $dbpassword, $dbname, $dbhost)
|
10 |
-
{
|
11 |
-
register_shutdown_function(array($this, '__destruct'));
|
12 |
-
if (WP_DEBUG && WP_DEBUG_DISPLAY) {
|
13 |
-
$this->show_errors();
|
14 |
-
}
|
15 |
-
if (function_exists('mysqli_connect')) {
|
16 |
-
if (defined('WP_USE_EXT_MYSQL')) {
|
17 |
-
$this->use_mysqli = ! WP_USE_EXT_MYSQL;
|
18 |
-
} elseif (version_compare(phpversion(), '5.5', '>=') || !function_exists('mysql_connect')) {
|
19 |
-
$this->use_mysqli = true;
|
20 |
-
} elseif (false !== strpos($GLOBALS['wp_version'], '-')) {
|
21 |
-
$this->use_mysqli = true;
|
22 |
-
}
|
23 |
-
}
|
24 |
-
$this->dbuser = $dbuser;
|
25 |
-
$this->dbpassword = $dbpassword;
|
26 |
-
$this->dbname = $dbname;
|
27 |
-
$this->dbhost = $dbhost;
|
28 |
-
// wp-config.php creation will manually connect when ready.
|
29 |
-
if (defined('WP_SETUP_CONFIG')) {
|
30 |
-
return;
|
31 |
-
}
|
32 |
-
|
33 |
-
$this->db_connect(false);
|
34 |
-
}
|
35 |
-
|
36 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class wpdbCustom extends wpdb
|
4 |
+
{
|
5 |
+
/*
|
6 |
+
* overwrite wpdb class for set $allow_bail to false
|
7 |
+
* and hide the print of the error
|
8 |
+
*/
|
9 |
+
public function __construct($dbuser, $dbpassword, $dbname, $dbhost)
|
10 |
+
{
|
11 |
+
register_shutdown_function(array($this, '__destruct'));
|
12 |
+
if (WP_DEBUG && WP_DEBUG_DISPLAY) {
|
13 |
+
$this->show_errors();
|
14 |
+
}
|
15 |
+
if (function_exists('mysqli_connect')) {
|
16 |
+
if (defined('WP_USE_EXT_MYSQL')) {
|
17 |
+
$this->use_mysqli = ! WP_USE_EXT_MYSQL;
|
18 |
+
} elseif (version_compare(phpversion(), '5.5', '>=') || !function_exists('mysql_connect')) {
|
19 |
+
$this->use_mysqli = true;
|
20 |
+
} elseif (false !== strpos($GLOBALS['wp_version'], '-')) {
|
21 |
+
$this->use_mysqli = true;
|
22 |
+
}
|
23 |
+
}
|
24 |
+
$this->dbuser = $dbuser;
|
25 |
+
$this->dbpassword = $dbpassword;
|
26 |
+
$this->dbname = $dbname;
|
27 |
+
$this->dbhost = $dbhost;
|
28 |
+
// wp-config.php creation will manually connect when ready.
|
29 |
+
if (defined('WP_SETUP_CONFIG')) {
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
|
33 |
+
$this->db_connect(false);
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
classes/ConstantManager.php
CHANGED
@@ -1,89 +1,89 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_ConstantManager {
|
4 |
-
|
5 |
-
protected $_constants = array();
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Use an existing PHP constant.
|
9 |
-
* @param string $name Constant name.
|
10 |
-
* @param string $description Constant description.
|
11 |
-
*/
|
12 |
-
public function UseConstant($name, $description = ''){
|
13 |
-
$this->_constants[] = (object)array(
|
14 |
-
'name' => $name,
|
15 |
-
'value' => constant($name),
|
16 |
-
'description' => $description,
|
17 |
-
);
|
18 |
-
}
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Add new PHP constant.
|
22 |
-
* @param string $name Constant name.
|
23 |
-
* @param integer|string $value Constant value.
|
24 |
-
* @param string $description Constant description.
|
25 |
-
*/
|
26 |
-
public function AddConstant($name, $value, $description = ''){
|
27 |
-
|
28 |
-
// check for constant conflict and define new one if required
|
29 |
-
if(defined($name) && constant($name) !== $value){
|
30 |
-
throw new Exception('Constant already defined with a different value.');
|
31 |
-
}else{
|
32 |
-
define($name, $value);
|
33 |
-
}
|
34 |
-
|
35 |
-
// add constant to da list.
|
36 |
-
$this->UseConstant($name, $description);
|
37 |
-
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Add multiple constants in one go.
|
42 |
-
* @param array $items Array of arrays with name, value, description pairs.
|
43 |
-
*/
|
44 |
-
public function AddConstants($items){
|
45 |
-
foreach($items as $item)
|
46 |
-
$this->AddConstant(
|
47 |
-
$item['name'],
|
48 |
-
$item['value'],
|
49 |
-
$item['description']
|
50 |
-
);
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Use multiple constants in one go.
|
55 |
-
* @param array $items Array of arrays with name, description pairs.
|
56 |
-
*/
|
57 |
-
public function UseConstants($items){
|
58 |
-
foreach($items as $item)
|
59 |
-
$this->UseConstant(
|
60 |
-
$item['name'],
|
61 |
-
$item['description']
|
62 |
-
);
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Get constant details by a particular detail.
|
67 |
-
* @param string $what The type of detail: 'name', 'value'
|
68 |
-
* @param mixed $value The detail expected value.
|
69 |
-
* @return mixed Either constant details (props: name, value, description) or $default if not found.
|
70 |
-
*/
|
71 |
-
public function GetConstantBy($what, $value, $default = null){
|
72 |
-
|
73 |
-
// make sure we do have some constants...
|
74 |
-
if(count($this->_constants)){
|
75 |
-
|
76 |
-
// make sure that constants do have a $what property
|
77 |
-
if(!isset($this->_constants[0]->$what))
|
78 |
-
throw new Exception('Unexpected detail type "' . $what . '".');
|
79 |
-
|
80 |
-
// return constant match the property value
|
81 |
-
foreach($this->_constants as $constant)
|
82 |
-
if($constant->$what == $value)
|
83 |
-
return $constant;
|
84 |
-
|
85 |
-
}
|
86 |
-
|
87 |
-
return $default;
|
88 |
-
}
|
89 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_ConstantManager {
|
4 |
+
|
5 |
+
protected $_constants = array();
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Use an existing PHP constant.
|
9 |
+
* @param string $name Constant name.
|
10 |
+
* @param string $description Constant description.
|
11 |
+
*/
|
12 |
+
public function UseConstant($name, $description = ''){
|
13 |
+
$this->_constants[] = (object)array(
|
14 |
+
'name' => $name,
|
15 |
+
'value' => constant($name),
|
16 |
+
'description' => $description,
|
17 |
+
);
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Add new PHP constant.
|
22 |
+
* @param string $name Constant name.
|
23 |
+
* @param integer|string $value Constant value.
|
24 |
+
* @param string $description Constant description.
|
25 |
+
*/
|
26 |
+
public function AddConstant($name, $value, $description = ''){
|
27 |
+
|
28 |
+
// check for constant conflict and define new one if required
|
29 |
+
if(defined($name) && constant($name) !== $value){
|
30 |
+
throw new Exception('Constant already defined with a different value.');
|
31 |
+
}else{
|
32 |
+
define($name, $value);
|
33 |
+
}
|
34 |
+
|
35 |
+
// add constant to da list.
|
36 |
+
$this->UseConstant($name, $description);
|
37 |
+
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Add multiple constants in one go.
|
42 |
+
* @param array $items Array of arrays with name, value, description pairs.
|
43 |
+
*/
|
44 |
+
public function AddConstants($items){
|
45 |
+
foreach($items as $item)
|
46 |
+
$this->AddConstant(
|
47 |
+
$item['name'],
|
48 |
+
$item['value'],
|
49 |
+
$item['description']
|
50 |
+
);
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Use multiple constants in one go.
|
55 |
+
* @param array $items Array of arrays with name, description pairs.
|
56 |
+
*/
|
57 |
+
public function UseConstants($items){
|
58 |
+
foreach($items as $item)
|
59 |
+
$this->UseConstant(
|
60 |
+
$item['name'],
|
61 |
+
$item['description']
|
62 |
+
);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get constant details by a particular detail.
|
67 |
+
* @param string $what The type of detail: 'name', 'value'
|
68 |
+
* @param mixed $value The detail expected value.
|
69 |
+
* @return mixed Either constant details (props: name, value, description) or $default if not found.
|
70 |
+
*/
|
71 |
+
public function GetConstantBy($what, $value, $default = null){
|
72 |
+
|
73 |
+
// make sure we do have some constants...
|
74 |
+
if(count($this->_constants)){
|
75 |
+
|
76 |
+
// make sure that constants do have a $what property
|
77 |
+
if(!isset($this->_constants[0]->$what))
|
78 |
+
throw new Exception('Unexpected detail type "' . $what . '".');
|
79 |
+
|
80 |
+
// return constant match the property value
|
81 |
+
foreach($this->_constants as $constant)
|
82 |
+
if($constant->$what == $value)
|
83 |
+
return $constant;
|
84 |
+
|
85 |
+
}
|
86 |
+
|
87 |
+
return $default;
|
88 |
+
}
|
89 |
}
|
classes/EDD_SL_Plugin_Updater.php
CHANGED
@@ -1,170 +1,170 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// uncomment this line for testing
|
4 |
-
//set_site_transient( 'update_plugins', null );
|
5 |
-
|
6 |
-
/**
|
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 |
-
private $api_url = '';
|
14 |
-
private $api_data = array();
|
15 |
-
private $name = '';
|
16 |
-
private $slug = '';
|
17 |
-
private $do_check = false;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Class constructor.
|
21 |
-
*
|
22 |
-
* @uses plugin_basename()
|
23 |
-
* @uses hook()
|
24 |
-
*
|
25 |
-
* @param string $_api_url The URL pointing to the custom API endpoint.
|
26 |
-
* @param string $_plugin_file Path to the plugin file.
|
27 |
-
* @param array $_api_data Optional data to send with API calls.
|
28 |
-
* @return void
|
29 |
-
*/
|
30 |
-
function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
31 |
-
$this->api_url = trailingslashit( $_api_url );
|
32 |
-
$this->api_data = urlencode_deep( $_api_data );
|
33 |
-
$this->name = plugin_basename( $_plugin_file );
|
34 |
-
$this->slug = basename( $_plugin_file, '.php');
|
35 |
-
$this->version = $_api_data['version'];
|
36 |
-
|
37 |
-
// Set up hooks.
|
38 |
-
$this->hook();
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Set up WordPress filters to hook into WP's update process.
|
43 |
-
*
|
44 |
-
* @uses add_filter()
|
45 |
-
*
|
46 |
-
* @return void
|
47 |
-
*/
|
48 |
-
private function hook() {
|
49 |
-
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
|
50 |
-
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
51 |
-
add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Check for Updates at the defined API endpoint and modify the update array.
|
56 |
-
*
|
57 |
-
* This function dives into the update API just when WordPress creates its update array,
|
58 |
-
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
59 |
-
* It is reassembled from parts of the native WordPress plugin update code.
|
60 |
-
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
61 |
-
*
|
62 |
-
* @uses api_request()
|
63 |
-
*
|
64 |
-
* @param array $_transient_data Update array build by WordPress.
|
65 |
-
* @return array Modified update array with custom plugin data.
|
66 |
-
*/
|
67 |
-
function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
|
68 |
-
|
69 |
-
if( empty( $_transient_data ) || ! $this->do_check ) {
|
70 |
-
|
71 |
-
// This ensures that the custom API request only runs on the second time that WP fires the update check
|
72 |
-
$this->do_check = true;
|
73 |
-
|
74 |
-
return $_transient_data;
|
75 |
-
}
|
76 |
-
|
77 |
-
$to_send = array( 'slug' => $this->slug );
|
78 |
-
|
79 |
-
$api_response = $this->api_request( 'plugin_latest_version', $to_send );
|
80 |
-
|
81 |
-
if( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
|
82 |
-
|
83 |
-
if( version_compare( $this->version, $api_response->new_version, '<' ) ) {
|
84 |
-
$_transient_data->response[$this->name] = $api_response;
|
85 |
-
}
|
86 |
-
}
|
87 |
-
return $_transient_data;
|
88 |
-
}
|
89 |
-
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Updates information on the "View version x.x details" page with custom data.
|
93 |
-
*
|
94 |
-
* @uses api_request()
|
95 |
-
*
|
96 |
-
* @param mixed $_data
|
97 |
-
* @param string $_action
|
98 |
-
* @param object $_args
|
99 |
-
* @return object $_data
|
100 |
-
*/
|
101 |
-
function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
102 |
-
if ( ( $_action != 'plugin_information' ) || !isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) return $_data;
|
103 |
-
|
104 |
-
$to_send = array( 'slug' => $this->slug );
|
105 |
-
|
106 |
-
$api_response = $this->api_request( 'plugin_information', $to_send );
|
107 |
-
if ( false !== $api_response ) $_data = $api_response;
|
108 |
-
|
109 |
-
return $_data;
|
110 |
-
}
|
111 |
-
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Disable SSL verification in order to prevent download update failures
|
115 |
-
*
|
116 |
-
* @param array $args
|
117 |
-
* @param string $url
|
118 |
-
* @return object $array
|
119 |
-
*/
|
120 |
-
function http_request_args( $args, $url ) {
|
121 |
-
// If it is an https request and we are performing a package download, disable ssl verification
|
122 |
-
if( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
|
123 |
-
$args['sslverify'] = false;
|
124 |
-
}
|
125 |
-
return $args;
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Calls the API and, if successfull, returns the object delivered by the API.
|
130 |
-
*
|
131 |
-
* @uses get_bloginfo()
|
132 |
-
* @uses wp_remote_post()
|
133 |
-
* @uses is_wp_error()
|
134 |
-
*
|
135 |
-
* @param string $_action The requested action.
|
136 |
-
* @param array $_data Parameters for the API action.
|
137 |
-
* @return false||object
|
138 |
-
*/
|
139 |
-
private function api_request( $_action, $_data ) {
|
140 |
-
|
141 |
-
global $wp_version;
|
142 |
-
|
143 |
-
$data = array_merge( $this->api_data, $_data );
|
144 |
-
|
145 |
-
if( $data['slug'] != $this->slug )
|
146 |
-
return;
|
147 |
-
|
148 |
-
if( empty( $data['license'] ) )
|
149 |
-
return;
|
150 |
-
|
151 |
-
$api_params = array(
|
152 |
-
'edd_action' => 'get_version',
|
153 |
-
'license' => $data['license'],
|
154 |
-
'name' => $data['item_name'],
|
155 |
-
'slug' => $this->slug,
|
156 |
-
'author' => $data['author'],
|
157 |
-
'url' => home_url()
|
158 |
-
);
|
159 |
-
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
|
160 |
-
|
161 |
-
if ( ! is_wp_error( $request ) ):
|
162 |
-
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
163 |
-
if( $request && isset( $request->sections ) )
|
164 |
-
$request->sections = maybe_unserialize( $request->sections );
|
165 |
-
return $request;
|
166 |
-
else:
|
167 |
-
return false;
|
168 |
-
endif;
|
169 |
-
}
|
170 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// uncomment this line for testing
|
4 |
+
//set_site_transient( 'update_plugins', null );
|
5 |
+
|
6 |
+
/**
|
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 |
+
private $api_url = '';
|
14 |
+
private $api_data = array();
|
15 |
+
private $name = '';
|
16 |
+
private $slug = '';
|
17 |
+
private $do_check = false;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Class constructor.
|
21 |
+
*
|
22 |
+
* @uses plugin_basename()
|
23 |
+
* @uses hook()
|
24 |
+
*
|
25 |
+
* @param string $_api_url The URL pointing to the custom API endpoint.
|
26 |
+
* @param string $_plugin_file Path to the plugin file.
|
27 |
+
* @param array $_api_data Optional data to send with API calls.
|
28 |
+
* @return void
|
29 |
+
*/
|
30 |
+
function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
31 |
+
$this->api_url = trailingslashit( $_api_url );
|
32 |
+
$this->api_data = urlencode_deep( $_api_data );
|
33 |
+
$this->name = plugin_basename( $_plugin_file );
|
34 |
+
$this->slug = basename( $_plugin_file, '.php');
|
35 |
+
$this->version = $_api_data['version'];
|
36 |
+
|
37 |
+
// Set up hooks.
|
38 |
+
$this->hook();
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Set up WordPress filters to hook into WP's update process.
|
43 |
+
*
|
44 |
+
* @uses add_filter()
|
45 |
+
*
|
46 |
+
* @return void
|
47 |
+
*/
|
48 |
+
private function hook() {
|
49 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
|
50 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
51 |
+
add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Check for Updates at the defined API endpoint and modify the update array.
|
56 |
+
*
|
57 |
+
* This function dives into the update API just when WordPress creates its update array,
|
58 |
+
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
59 |
+
* It is reassembled from parts of the native WordPress plugin update code.
|
60 |
+
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
61 |
+
*
|
62 |
+
* @uses api_request()
|
63 |
+
*
|
64 |
+
* @param array $_transient_data Update array build by WordPress.
|
65 |
+
* @return array Modified update array with custom plugin data.
|
66 |
+
*/
|
67 |
+
function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
|
68 |
+
|
69 |
+
if( empty( $_transient_data ) || ! $this->do_check ) {
|
70 |
+
|
71 |
+
// This ensures that the custom API request only runs on the second time that WP fires the update check
|
72 |
+
$this->do_check = true;
|
73 |
+
|
74 |
+
return $_transient_data;
|
75 |
+
}
|
76 |
+
|
77 |
+
$to_send = array( 'slug' => $this->slug );
|
78 |
+
|
79 |
+
$api_response = $this->api_request( 'plugin_latest_version', $to_send );
|
80 |
+
|
81 |
+
if( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
|
82 |
+
|
83 |
+
if( version_compare( $this->version, $api_response->new_version, '<' ) ) {
|
84 |
+
$_transient_data->response[$this->name] = $api_response;
|
85 |
+
}
|
86 |
+
}
|
87 |
+
return $_transient_data;
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Updates information on the "View version x.x details" page with custom data.
|
93 |
+
*
|
94 |
+
* @uses api_request()
|
95 |
+
*
|
96 |
+
* @param mixed $_data
|
97 |
+
* @param string $_action
|
98 |
+
* @param object $_args
|
99 |
+
* @return object $_data
|
100 |
+
*/
|
101 |
+
function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
102 |
+
if ( ( $_action != 'plugin_information' ) || !isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) return $_data;
|
103 |
+
|
104 |
+
$to_send = array( 'slug' => $this->slug );
|
105 |
+
|
106 |
+
$api_response = $this->api_request( 'plugin_information', $to_send );
|
107 |
+
if ( false !== $api_response ) $_data = $api_response;
|
108 |
+
|
109 |
+
return $_data;
|
110 |
+
}
|
111 |
+
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Disable SSL verification in order to prevent download update failures
|
115 |
+
*
|
116 |
+
* @param array $args
|
117 |
+
* @param string $url
|
118 |
+
* @return object $array
|
119 |
+
*/
|
120 |
+
function http_request_args( $args, $url ) {
|
121 |
+
// If it is an https request and we are performing a package download, disable ssl verification
|
122 |
+
if( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
|
123 |
+
$args['sslverify'] = false;
|
124 |
+
}
|
125 |
+
return $args;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
130 |
+
*
|
131 |
+
* @uses get_bloginfo()
|
132 |
+
* @uses wp_remote_post()
|
133 |
+
* @uses is_wp_error()
|
134 |
+
*
|
135 |
+
* @param string $_action The requested action.
|
136 |
+
* @param array $_data Parameters for the API action.
|
137 |
+
* @return false||object
|
138 |
+
*/
|
139 |
+
private function api_request( $_action, $_data ) {
|
140 |
+
|
141 |
+
global $wp_version;
|
142 |
+
|
143 |
+
$data = array_merge( $this->api_data, $_data );
|
144 |
+
|
145 |
+
if( $data['slug'] != $this->slug )
|
146 |
+
return;
|
147 |
+
|
148 |
+
if( empty( $data['license'] ) )
|
149 |
+
return;
|
150 |
+
|
151 |
+
$api_params = array(
|
152 |
+
'edd_action' => 'get_version',
|
153 |
+
'license' => $data['license'],
|
154 |
+
'name' => $data['item_name'],
|
155 |
+
'slug' => $this->slug,
|
156 |
+
'author' => $data['author'],
|
157 |
+
'url' => home_url()
|
158 |
+
);
|
159 |
+
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
|
160 |
+
|
161 |
+
if ( ! is_wp_error( $request ) ):
|
162 |
+
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
163 |
+
if( $request && isset( $request->sections ) )
|
164 |
+
$request->sections = maybe_unserialize( $request->sections );
|
165 |
+
return $request;
|
166 |
+
else:
|
167 |
+
return false;
|
168 |
+
endif;
|
169 |
+
}
|
170 |
+
}
|
classes/Helpers/DataHelper.php
CHANGED
@@ -1,23 +1,23 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Helpers_DataHelper
|
4 |
-
{
|
5 |
-
|
6 |
-
/**
|
7 |
-
* A wrapper for JSON encoding that fixes potential issues.
|
8 |
-
* @param mixed $data The data to encode.
|
9 |
-
* @return string JSON string.
|
10 |
-
*/
|
11 |
-
public static function JsonEncode($data){
|
12 |
-
return @json_encode($data);
|
13 |
-
}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* A wrapper for JSON encoding that fixes potential issues.
|
17 |
-
* @param string $data The JSON string to decode.
|
18 |
-
* @return mixed Decoded data.
|
19 |
-
*/
|
20 |
-
public static function JsonDecode($data){
|
21 |
-
return @json_decode($data);
|
22 |
-
}
|
23 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Helpers_DataHelper
|
4 |
+
{
|
5 |
+
|
6 |
+
/**
|
7 |
+
* A wrapper for JSON encoding that fixes potential issues.
|
8 |
+
* @param mixed $data The data to encode.
|
9 |
+
* @return string JSON string.
|
10 |
+
*/
|
11 |
+
public static function JsonEncode($data){
|
12 |
+
return @json_encode($data);
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* A wrapper for JSON encoding that fixes potential issues.
|
17 |
+
* @param string $data The JSON string to decode.
|
18 |
+
* @return mixed Decoded data.
|
19 |
+
*/
|
20 |
+
public static function JsonDecode($data){
|
21 |
+
return @json_decode($data);
|
22 |
+
}
|
23 |
}
|
classes/LicenseManager.php
CHANGED
@@ -1,171 +1,171 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// since other plugins might use this class
|
4 |
-
if(!class_exists('EDD_SL_Plugin_Updater')){
|
5 |
-
require_once('EDD_SL_Plugin_Updater.php');
|
6 |
-
}
|
7 |
-
|
8 |
-
class WSAL_LicenseManager {
|
9 |
-
/**
|
10 |
-
* @var WpSecurityAuditLog
|
11 |
-
*/
|
12 |
-
protected $plugin;
|
13 |
-
|
14 |
-
protected $plugins = array();
|
15 |
-
|
16 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
17 |
-
$this->plugin = $plugin;
|
18 |
-
add_action('plugins_loaded', array($this, 'LoadPlugins'));
|
19 |
-
}
|
20 |
-
|
21 |
-
protected function GetStoreUrl(){
|
22 |
-
return 'http://www.wpsecurityauditlog.com/';
|
23 |
-
}
|
24 |
-
|
25 |
-
public function CountPlugins(){
|
26 |
-
return count($this->plugins);
|
27 |
-
}
|
28 |
-
|
29 |
-
public function Plugins(){
|
30 |
-
return $this->plugins;
|
31 |
-
}
|
32 |
-
|
33 |
-
public function LoadPlugins(){
|
34 |
-
foreach(apply_filters('wsal_register', array()) as $pluginFile)
|
35 |
-
$this->AddPremiumPlugin($pluginFile);
|
36 |
-
}
|
37 |
-
|
38 |
-
protected function GetPluginData($pluginFile, $license){
|
39 |
-
// A hack since get_plugin_data() is not available now
|
40 |
-
$pluginData = get_file_data($pluginFile, array(
|
41 |
-
'Name' => 'Plugin Name',
|
42 |
-
'PluginURI' => 'Plugin URI',
|
43 |
-
'Version' => 'Version',
|
44 |
-
'Description' => 'Description',
|
45 |
-
'Author' => 'Author',
|
46 |
-
'TextDomain' => 'Text Domain',
|
47 |
-
'DomainPath' => 'Domain Path',
|
48 |
-
), 'plugin' );
|
49 |
-
|
50 |
-
$pluginUpdater = is_null($license)
|
51 |
-
? null
|
52 |
-
: new EDD_SL_Plugin_Updater(
|
53 |
-
$this->GetStoreUrl(),
|
54 |
-
$pluginFile,
|
55 |
-
array(
|
56 |
-
'license' => $license,
|
57 |
-
'item_name' => $pluginData['Name'],
|
58 |
-
'author' => $pluginData['Author'],
|
59 |
-
'version' => $pluginData['Version'],
|
60 |
-
)
|
61 |
-
);
|
62 |
-
|
63 |
-
return array(
|
64 |
-
'PluginData' => $pluginData,
|
65 |
-
'EddUpdater' => $pluginUpdater,
|
66 |
-
);
|
67 |
-
}
|
68 |
-
|
69 |
-
public function AddPremiumPlugin($pluginFile){
|
70 |
-
$name = sanitize_key(basename($pluginFile));
|
71 |
-
$license = $this->plugin->settings->GetLicenseKey($name);
|
72 |
-
$this->plugins[$name] = $this->GetPluginData($pluginFile, $license);
|
73 |
-
}
|
74 |
-
|
75 |
-
public function AddPlugin($pluginFile){
|
76 |
-
$name = sanitize_key(basename($pluginFile));
|
77 |
-
$this->plugins[$name] = $this->GetPluginData($pluginFile, null);
|
78 |
-
}
|
79 |
-
|
80 |
-
protected function GetBlogIds(){
|
81 |
-
global $wpdb;
|
82 |
-
$sql = 'SELECT blog_id FROM ' . $wpdb->blogs;
|
83 |
-
return $wpdb->get_col($sql);
|
84 |
-
}
|
85 |
-
|
86 |
-
public function ActivateLicense($name, $license){
|
87 |
-
$this->plugin->settings->SetLicenseKey($name, $license);
|
88 |
-
|
89 |
-
$plugins = $this->Plugins();
|
90 |
-
$api_params = array(
|
91 |
-
'edd_action'=> 'activate_license',
|
92 |
-
'license' => urlencode($license),
|
93 |
-
'item_name' => urlencode($plugins[$name]['PluginData']['Name']),
|
94 |
-
'url' => urlencode(home_url()),
|
95 |
-
);
|
96 |
-
|
97 |
-
$blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array(1);
|
98 |
-
|
99 |
-
foreach($blog_ids as $blog_id){
|
100 |
-
|
101 |
-
if($this->plugin->IsMultisite())
|
102 |
-
$api_params['url'] = urlencode(get_home_url($blog_id));
|
103 |
-
|
104 |
-
$response = wp_remote_get(
|
105 |
-
esc_url_raw(add_query_arg($api_params, $this->GetStoreUrl())),
|
106 |
-
array('timeout' => 15, 'sslverify' => false)
|
107 |
-
);
|
108 |
-
|
109 |
-
if (is_wp_error($response)) {
|
110 |
-
$this->plugin->settings->SetLicenseErrors($name, 'Invalid Licensing Server Response: ' . $response->get_error_message());
|
111 |
-
$this->DeactivateLicense($name, $license);
|
112 |
-
return false;
|
113 |
-
}
|
114 |
-
|
115 |
-
$license_data = json_decode(wp_remote_retrieve_body($response));
|
116 |
-
|
117 |
-
if(is_object($license_data)){
|
118 |
-
$this->plugin->settings->SetLicenseStatus($name, $license_data->license);
|
119 |
-
if($license_data->license !== 'valid'){
|
120 |
-
$error = 'License Not Valid';
|
121 |
-
if (isset($license_data->error)) $error .= ': ' . ucfirst(str_replace('_', ' ', $license_data->error));
|
122 |
-
$this->plugin->settings->SetLicenseErrors($name, $error);
|
123 |
-
$this->DeactivateLicense($name, $license);
|
124 |
-
return false;
|
125 |
-
}
|
126 |
-
}else{
|
127 |
-
$this->plugin->settings->SetLicenseErrors($name, 'Unexpected Licensing Server Response');
|
128 |
-
$this->DeactivateLicense($name, $license);
|
129 |
-
return false;
|
130 |
-
}
|
131 |
-
}
|
132 |
-
|
133 |
-
return true;
|
134 |
-
}
|
135 |
-
|
136 |
-
public function IsLicenseValid($name){
|
137 |
-
return trim(strtolower($this->plugin->settings->GetLicenseStatus($name))) === 'valid';
|
138 |
-
}
|
139 |
-
|
140 |
-
public function DeactivateLicense($name, $license = null){
|
141 |
-
$this->plugin->settings->SetLicenseStatus($name, '');
|
142 |
-
|
143 |
-
// deactivate it on the server (if license was given)
|
144 |
-
if(!is_null($license)){
|
145 |
-
$plugins = $this->Plugins();
|
146 |
-
$api_params = array(
|
147 |
-
'edd_action'=> 'deactivate_license',
|
148 |
-
'license' => urlencode($license),
|
149 |
-
'item_name' => urlencode($plugins[$name]['PluginData']['Name']),
|
150 |
-
'url' => urlencode(home_url()),
|
151 |
-
);
|
152 |
-
|
153 |
-
$blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array(1);
|
154 |
-
|
155 |
-
foreach($blog_ids as $blog_id){
|
156 |
-
|
157 |
-
if($this->plugin->IsMultisite())
|
158 |
-
$api_params['url'] = urlencode(get_home_url($blog_id));
|
159 |
-
|
160 |
-
$response = wp_remote_get(
|
161 |
-
esc_url_raw(add_query_arg($api_params, $this->GetStoreUrl())),
|
162 |
-
array('timeout' => 15, 'sslverify' => false)
|
163 |
-
);
|
164 |
-
|
165 |
-
if (is_wp_error($response)) return false;
|
166 |
-
|
167 |
-
wp_remote_retrieve_body($response);
|
168 |
-
}
|
169 |
-
}
|
170 |
-
}
|
171 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// since other plugins might use this class
|
4 |
+
if(!class_exists('EDD_SL_Plugin_Updater')){
|
5 |
+
require_once('EDD_SL_Plugin_Updater.php');
|
6 |
+
}
|
7 |
+
|
8 |
+
class WSAL_LicenseManager {
|
9 |
+
/**
|
10 |
+
* @var WpSecurityAuditLog
|
11 |
+
*/
|
12 |
+
protected $plugin;
|
13 |
+
|
14 |
+
protected $plugins = array();
|
15 |
+
|
16 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
17 |
+
$this->plugin = $plugin;
|
18 |
+
add_action('plugins_loaded', array($this, 'LoadPlugins'));
|
19 |
+
}
|
20 |
+
|
21 |
+
protected function GetStoreUrl(){
|
22 |
+
return 'http://www.wpsecurityauditlog.com/';
|
23 |
+
}
|
24 |
+
|
25 |
+
public function CountPlugins(){
|
26 |
+
return count($this->plugins);
|
27 |
+
}
|
28 |
+
|
29 |
+
public function Plugins(){
|
30 |
+
return $this->plugins;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function LoadPlugins(){
|
34 |
+
foreach(apply_filters('wsal_register', array()) as $pluginFile)
|
35 |
+
$this->AddPremiumPlugin($pluginFile);
|
36 |
+
}
|
37 |
+
|
38 |
+
protected function GetPluginData($pluginFile, $license){
|
39 |
+
// A hack since get_plugin_data() is not available now
|
40 |
+
$pluginData = get_file_data($pluginFile, array(
|
41 |
+
'Name' => 'Plugin Name',
|
42 |
+
'PluginURI' => 'Plugin URI',
|
43 |
+
'Version' => 'Version',
|
44 |
+
'Description' => 'Description',
|
45 |
+
'Author' => 'Author',
|
46 |
+
'TextDomain' => 'Text Domain',
|
47 |
+
'DomainPath' => 'Domain Path',
|
48 |
+
), 'plugin' );
|
49 |
+
|
50 |
+
$pluginUpdater = is_null($license)
|
51 |
+
? null
|
52 |
+
: new EDD_SL_Plugin_Updater(
|
53 |
+
$this->GetStoreUrl(),
|
54 |
+
$pluginFile,
|
55 |
+
array(
|
56 |
+
'license' => $license,
|
57 |
+
'item_name' => $pluginData['Name'],
|
58 |
+
'author' => $pluginData['Author'],
|
59 |
+
'version' => $pluginData['Version'],
|
60 |
+
)
|
61 |
+
);
|
62 |
+
|
63 |
+
return array(
|
64 |
+
'PluginData' => $pluginData,
|
65 |
+
'EddUpdater' => $pluginUpdater,
|
66 |
+
);
|
67 |
+
}
|
68 |
+
|
69 |
+
public function AddPremiumPlugin($pluginFile){
|
70 |
+
$name = sanitize_key(basename($pluginFile));
|
71 |
+
$license = $this->plugin->settings->GetLicenseKey($name);
|
72 |
+
$this->plugins[$name] = $this->GetPluginData($pluginFile, $license);
|
73 |
+
}
|
74 |
+
|
75 |
+
public function AddPlugin($pluginFile){
|
76 |
+
$name = sanitize_key(basename($pluginFile));
|
77 |
+
$this->plugins[$name] = $this->GetPluginData($pluginFile, null);
|
78 |
+
}
|
79 |
+
|
80 |
+
protected function GetBlogIds(){
|
81 |
+
global $wpdb;
|
82 |
+
$sql = 'SELECT blog_id FROM ' . $wpdb->blogs;
|
83 |
+
return $wpdb->get_col($sql);
|
84 |
+
}
|
85 |
+
|
86 |
+
public function ActivateLicense($name, $license){
|
87 |
+
$this->plugin->settings->SetLicenseKey($name, $license);
|
88 |
+
|
89 |
+
$plugins = $this->Plugins();
|
90 |
+
$api_params = array(
|
91 |
+
'edd_action'=> 'activate_license',
|
92 |
+
'license' => urlencode($license),
|
93 |
+
'item_name' => urlencode($plugins[$name]['PluginData']['Name']),
|
94 |
+
'url' => urlencode(home_url()),
|
95 |
+
);
|
96 |
+
|
97 |
+
$blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array(1);
|
98 |
+
|
99 |
+
foreach($blog_ids as $blog_id){
|
100 |
+
|
101 |
+
if($this->plugin->IsMultisite())
|
102 |
+
$api_params['url'] = urlencode(get_home_url($blog_id));
|
103 |
+
|
104 |
+
$response = wp_remote_get(
|
105 |
+
esc_url_raw(add_query_arg($api_params, $this->GetStoreUrl())),
|
106 |
+
array('timeout' => 15, 'sslverify' => false)
|
107 |
+
);
|
108 |
+
|
109 |
+
if (is_wp_error($response)) {
|
110 |
+
$this->plugin->settings->SetLicenseErrors($name, 'Invalid Licensing Server Response: ' . $response->get_error_message());
|
111 |
+
$this->DeactivateLicense($name, $license);
|
112 |
+
return false;
|
113 |
+
}
|
114 |
+
|
115 |
+
$license_data = json_decode(wp_remote_retrieve_body($response));
|
116 |
+
|
117 |
+
if(is_object($license_data)){
|
118 |
+
$this->plugin->settings->SetLicenseStatus($name, $license_data->license);
|
119 |
+
if($license_data->license !== 'valid'){
|
120 |
+
$error = 'License Not Valid';
|
121 |
+
if (isset($license_data->error)) $error .= ': ' . ucfirst(str_replace('_', ' ', $license_data->error));
|
122 |
+
$this->plugin->settings->SetLicenseErrors($name, $error);
|
123 |
+
$this->DeactivateLicense($name, $license);
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
}else{
|
127 |
+
$this->plugin->settings->SetLicenseErrors($name, 'Unexpected Licensing Server Response');
|
128 |
+
$this->DeactivateLicense($name, $license);
|
129 |
+
return false;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
return true;
|
134 |
+
}
|
135 |
+
|
136 |
+
public function IsLicenseValid($name){
|
137 |
+
return trim(strtolower($this->plugin->settings->GetLicenseStatus($name))) === 'valid';
|
138 |
+
}
|
139 |
+
|
140 |
+
public function DeactivateLicense($name, $license = null){
|
141 |
+
$this->plugin->settings->SetLicenseStatus($name, '');
|
142 |
+
|
143 |
+
// deactivate it on the server (if license was given)
|
144 |
+
if(!is_null($license)){
|
145 |
+
$plugins = $this->Plugins();
|
146 |
+
$api_params = array(
|
147 |
+
'edd_action'=> 'deactivate_license',
|
148 |
+
'license' => urlencode($license),
|
149 |
+
'item_name' => urlencode($plugins[$name]['PluginData']['Name']),
|
150 |
+
'url' => urlencode(home_url()),
|
151 |
+
);
|
152 |
+
|
153 |
+
$blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array(1);
|
154 |
+
|
155 |
+
foreach($blog_ids as $blog_id){
|
156 |
+
|
157 |
+
if($this->plugin->IsMultisite())
|
158 |
+
$api_params['url'] = urlencode(get_home_url($blog_id));
|
159 |
+
|
160 |
+
$response = wp_remote_get(
|
161 |
+
esc_url_raw(add_query_arg($api_params, $this->GetStoreUrl())),
|
162 |
+
array('timeout' => 15, 'sslverify' => false)
|
163 |
+
);
|
164 |
+
|
165 |
+
if (is_wp_error($response)) return false;
|
166 |
+
|
167 |
+
wp_remote_retrieve_body($response);
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
classes/Models/ActiveRecord.php
CHANGED
@@ -1,267 +1,280 @@
|
|
1 |
-
<?php
|
2 |
-
require_once(__DIR__ . '/../Connector/ConnectorFactory.php');
|
3 |
-
|
4 |
-
abstract class WSAL_Models_ActiveRecord
|
5 |
-
{
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var_$connector Data connector;
|
9 |
-
*/
|
10 |
-
protected $connector;
|
11 |
-
|
12 |
-
protected $id = false;
|
13 |
-
|
14 |
-
protected $adapterName = null;
|
15 |
-
|
16 |
-
protected $useDefaultAdapter = false;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @return array Returns this records' fields.
|
20 |
-
*/
|
21 |
-
public function GetFields()
|
22 |
-
{
|
23 |
-
if(!isset($this->_column_cache)){
|
24 |
-
$this->_column_cache = array();
|
25 |
-
foreach(array_keys(get_object_vars($this)) as $col)
|
26 |
-
if(trim($col) && $col[0] != '_')
|
27 |
-
$this->_column_cache[] = $col;
|
28 |
-
}
|
29 |
-
return $this->_column_cache;
|
30 |
-
}
|
31 |
-
|
32 |
-
public function setId($id)
|
33 |
-
{
|
34 |
-
$this->id = $id;
|
35 |
-
}
|
36 |
-
|
37 |
-
public function getId()
|
38 |
-
{
|
39 |
-
return $this->id;
|
40 |
-
}
|
41 |
-
|
42 |
-
const STATE_UNKNOWN = 'unknown';
|
43 |
-
const STATE_CREATED = 'created';
|
44 |
-
const STATE_UPDATED = 'updated';
|
45 |
-
const STATE_DELETED = 'deleted';
|
46 |
-
const STATE_LOADED = 'loaded';
|
47 |
-
|
48 |
-
protected $_state = self::STATE_UNKNOWN;
|
49 |
-
|
50 |
-
public function __construct($data = null)
|
51 |
-
{
|
52 |
-
if (!$this->adapterName) {
|
53 |
-
throw new Exception('Class "' . __CLASS__ . '" requires "adapterName" to be set.');
|
54 |
-
}
|
55 |
-
if (!is_null($data)) {
|
56 |
-
$this->LoadData($data);
|
57 |
-
$this->_state = self::STATE_LOADED;
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
protected function getConnector()
|
62 |
-
{
|
63 |
-
if (!empty($this->connector)) {
|
64 |
-
return $this->connector;
|
65 |
-
}
|
66 |
-
if ($this->useDefaultAdapter) {
|
67 |
-
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
68 |
-
} else {
|
69 |
-
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
70 |
-
}
|
71 |
-
return $this->connector;
|
72 |
-
}
|
73 |
-
|
74 |
-
public function getAdapter()
|
75 |
-
{
|
76 |
-
return $this->getConnector()->getAdapter($this->adapterName);
|
77 |
-
}
|
78 |
-
|
79 |
-
|
80 |
-
/**
|
81 |
-
* Load record from DB.
|
82 |
-
* @param string $cond (Optional) Load condition.
|
83 |
-
* @param array $args (Optional) Load condition arguments.
|
84 |
-
*/
|
85 |
-
public function Load($cond = '%d', $args = array(1)){
|
86 |
-
$this->_state = self::STATE_UNKNOWN;
|
87 |
-
|
88 |
-
$data = $this->getAdapter()->Load($cond, $args);
|
89 |
-
if(!is_null($data)){
|
90 |
-
$this->LoadData($data);
|
91 |
-
$this->_state = self::STATE_LOADED;
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Load object data from variable.
|
97 |
-
* @param array|object $data Data array or object.
|
98 |
-
*/
|
99 |
-
public function LoadData($data){
|
100 |
-
$copy = get_class($this);
|
101 |
-
$copy = new $copy;
|
102 |
-
foreach((array)$data as $key => $val){
|
103 |
-
if(isset($copy->$key)){
|
104 |
-
switch(true){
|
105 |
-
case
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
$this->$key = (
|
112 |
-
break;
|
113 |
-
case
|
114 |
-
$this->$key = (
|
115 |
-
break;
|
116 |
-
case
|
117 |
-
$this->$key = (
|
118 |
-
break;
|
119 |
-
case
|
120 |
-
$this->$key = (
|
121 |
-
break;
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once(__DIR__ . '/../Connector/ConnectorFactory.php');
|
3 |
+
|
4 |
+
abstract class WSAL_Models_ActiveRecord
|
5 |
+
{
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var_$connector Data connector;
|
9 |
+
*/
|
10 |
+
protected $connector;
|
11 |
+
|
12 |
+
protected $id = false;
|
13 |
+
|
14 |
+
protected $adapterName = null;
|
15 |
+
|
16 |
+
protected $useDefaultAdapter = false;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return array Returns this records' fields.
|
20 |
+
*/
|
21 |
+
public function GetFields()
|
22 |
+
{
|
23 |
+
if(!isset($this->_column_cache)){
|
24 |
+
$this->_column_cache = array();
|
25 |
+
foreach(array_keys(get_object_vars($this)) as $col)
|
26 |
+
if(trim($col) && $col[0] != '_')
|
27 |
+
$this->_column_cache[] = $col;
|
28 |
+
}
|
29 |
+
return $this->_column_cache;
|
30 |
+
}
|
31 |
+
|
32 |
+
public function setId($id)
|
33 |
+
{
|
34 |
+
$this->id = $id;
|
35 |
+
}
|
36 |
+
|
37 |
+
public function getId()
|
38 |
+
{
|
39 |
+
return $this->id;
|
40 |
+
}
|
41 |
+
|
42 |
+
const STATE_UNKNOWN = 'unknown';
|
43 |
+
const STATE_CREATED = 'created';
|
44 |
+
const STATE_UPDATED = 'updated';
|
45 |
+
const STATE_DELETED = 'deleted';
|
46 |
+
const STATE_LOADED = 'loaded';
|
47 |
+
|
48 |
+
protected $_state = self::STATE_UNKNOWN;
|
49 |
+
|
50 |
+
public function __construct($data = null)
|
51 |
+
{
|
52 |
+
if (!$this->adapterName) {
|
53 |
+
throw new Exception('Class "' . __CLASS__ . '" requires "adapterName" to be set.');
|
54 |
+
}
|
55 |
+
if (!is_null($data)) {
|
56 |
+
$this->LoadData($data);
|
57 |
+
$this->_state = self::STATE_LOADED;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
protected function getConnector()
|
62 |
+
{
|
63 |
+
if (!empty($this->connector)) {
|
64 |
+
return $this->connector;
|
65 |
+
}
|
66 |
+
if ($this->useDefaultAdapter) {
|
67 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
68 |
+
} else {
|
69 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
70 |
+
}
|
71 |
+
return $this->connector;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getAdapter()
|
75 |
+
{
|
76 |
+
return $this->getConnector()->getAdapter($this->adapterName);
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Load record from DB.
|
82 |
+
* @param string $cond (Optional) Load condition.
|
83 |
+
* @param array $args (Optional) Load condition arguments.
|
84 |
+
*/
|
85 |
+
public function Load($cond = '%d', $args = array(1)){
|
86 |
+
$this->_state = self::STATE_UNKNOWN;
|
87 |
+
|
88 |
+
$data = $this->getAdapter()->Load($cond, $args);
|
89 |
+
if(!is_null($data)){
|
90 |
+
$this->LoadData($data);
|
91 |
+
$this->_state = self::STATE_LOADED;
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Load object data from variable.
|
97 |
+
* @param array|object $data Data array or object.
|
98 |
+
*/
|
99 |
+
public function LoadData($data){
|
100 |
+
$copy = get_class($this);
|
101 |
+
$copy = new $copy;
|
102 |
+
foreach ((array)$data as $key => $val) {
|
103 |
+
if (isset($copy->$key)) {
|
104 |
+
switch (true) {
|
105 |
+
case $this->is_ip_address($val):
|
106 |
+
$this->$key = (string)$val;
|
107 |
+
break;
|
108 |
+
case is_array($copy->$key):
|
109 |
+
case is_object($copy->$key):
|
110 |
+
$jsonDecodedVal = WSAL_Helpers_DataHelper::JsonDecode($val);
|
111 |
+
$this->$key = ($jsonDecodedVal == null) ? $val : $jsonDecodedVal;
|
112 |
+
break;
|
113 |
+
case is_int($copy->$key):
|
114 |
+
$this->$key = (int)$val;
|
115 |
+
break;
|
116 |
+
case is_float($copy->$key):
|
117 |
+
$this->$key = (float)$val;
|
118 |
+
break;
|
119 |
+
case is_bool($copy->$key):
|
120 |
+
$this->$key = (bool)$val;
|
121 |
+
break;
|
122 |
+
case is_string($copy->$key):
|
123 |
+
$this->$key = (string)$val;
|
124 |
+
break;
|
125 |
+
default:
|
126 |
+
throw new Exception('Unsupported type "'.gettype($copy->$key).'"');
|
127 |
+
}
|
128 |
+
}
|
129 |
+
}
|
130 |
+
return $this;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Save this active record
|
135 |
+
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
136 |
+
*/
|
137 |
+
public function Save()
|
138 |
+
{
|
139 |
+
$this->_state = self::STATE_UNKNOWN;
|
140 |
+
|
141 |
+
// use today's date if not set up
|
142 |
+
if (is_null($this->created_on)) {
|
143 |
+
$this->created_on = $this->GetMicrotime();
|
144 |
+
}
|
145 |
+
$updateId = $this->getId();
|
146 |
+
$result = $this->getAdapter()->Save($this);
|
147 |
+
|
148 |
+
if ($result !== false) {
|
149 |
+
$this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
|
150 |
+
}
|
151 |
+
return $result;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Deletes this active record
|
156 |
+
*/
|
157 |
+
public function Delete()
|
158 |
+
{
|
159 |
+
$this->_state = self::STATE_UNKNOWN;
|
160 |
+
$result = $this->getAdapter()->Delete($this);
|
161 |
+
if($result !== false)
|
162 |
+
$this->_state = self::STATE_DELETED;
|
163 |
+
|
164 |
+
return $result;
|
165 |
+
}
|
166 |
+
|
167 |
+
public function Count($cond = '%d', $args = array(1)) {
|
168 |
+
$result = $this->getAdapter()->Count($cond, $args);
|
169 |
+
return $result;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* @return boolean
|
174 |
+
*/
|
175 |
+
public function IsLoaded(){
|
176 |
+
return $this->_state == self::STATE_LOADED;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @return boolean
|
181 |
+
*/
|
182 |
+
public function IsSaved(){
|
183 |
+
return $this->_state == self::STATE_CREATED
|
184 |
+
|| $this->_state == self::STATE_UPDATED;
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @return boolean
|
189 |
+
*/
|
190 |
+
public function IsCreated(){
|
191 |
+
return $this->_state == self::STATE_CREATED;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* @return boolean
|
196 |
+
*/
|
197 |
+
public function IsUpdated()
|
198 |
+
{
|
199 |
+
return $this->_state == self::STATE_UPDATED;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @return boolean
|
204 |
+
*/
|
205 |
+
public function IsInstalled()
|
206 |
+
{
|
207 |
+
return $this->getAdapter()->IsInstalled();
|
208 |
+
}
|
209 |
+
|
210 |
+
public function Install()
|
211 |
+
{
|
212 |
+
return $this->getAdapter()->Install();
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* @return boolean
|
217 |
+
*/
|
218 |
+
public function IsDeleted()
|
219 |
+
{
|
220 |
+
return $this->_state == self::STATE_DELETED;
|
221 |
+
}
|
222 |
+
|
223 |
+
protected static $_cache = array();
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Load ActiveRecord from DB or cache.
|
227 |
+
* @param string $target ActiveRecord class name.
|
228 |
+
* @param string $query Load condition.
|
229 |
+
* @param array $args Arguments used in condition.
|
230 |
+
* @return WSAL_Models_ActiveRecord
|
231 |
+
*/
|
232 |
+
protected static function CacheLoad($target, $query, $args){
|
233 |
+
$index = $target . '::' . vsprintf($query, $args);
|
234 |
+
if(!isset(self::$_cache[$index])){
|
235 |
+
self::$_cache[$index] = new $target();
|
236 |
+
self::$_cache[$index]->Load($query, $args);
|
237 |
+
}
|
238 |
+
return self::$_cache[$index];
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Remove ActiveRecord cache.
|
243 |
+
* @param string $target ActiveRecord class name.
|
244 |
+
* @param string $query Load condition.
|
245 |
+
* @param array $args Arguments used in condition.
|
246 |
+
*/
|
247 |
+
protected static function CacheRemove($target, $query, $args){
|
248 |
+
$index = $target . '::' . sprintf($query, $args);
|
249 |
+
if(!isset(self::$_cache[$index])){
|
250 |
+
unset(self::$_cache[$index]);
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Clear the cache.
|
256 |
+
*/
|
257 |
+
protected static function CacheClear()
|
258 |
+
{
|
259 |
+
self::$_cache = array();
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Function used in WSAL reporting extension
|
264 |
+
*/
|
265 |
+
public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp)
|
266 |
+
{
|
267 |
+
return $this->getAdapter()->GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp);
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Check if the float is IPv4 instead
|
272 |
+
*/
|
273 |
+
private function is_ip_address($ip_address)
|
274 |
+
{
|
275 |
+
if (filter_var($ip_address, FILTER_VALIDATE_IP) !== false) {
|
276 |
+
return true;
|
277 |
+
}
|
278 |
+
return false;
|
279 |
+
}
|
280 |
+
}
|
classes/Models/Adapters/ActiveRecordInterface.php
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
interface WSAL_Adapters_ActiveRecordInterface {
|
4 |
-
|
5 |
-
public function IsInstalled();
|
6 |
-
public function Install();
|
7 |
-
public function Uninstall();
|
8 |
-
public function Load($cond = '%d', $args = array(1));
|
9 |
-
public function Save($activeRecord);
|
10 |
-
public function Delete($activeRecord);
|
11 |
-
public function LoadMulti($cond, $args = array());
|
12 |
-
public function LoadAndCallForEach($callback, $cond = '%d', $args = array(1));
|
13 |
-
public function Count($cond = '%d', $args = array(1));
|
14 |
-
public function LoadMultiQuery($query, $args = array());
|
15 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface WSAL_Adapters_ActiveRecordInterface {
|
4 |
+
|
5 |
+
public function IsInstalled();
|
6 |
+
public function Install();
|
7 |
+
public function Uninstall();
|
8 |
+
public function Load($cond = '%d', $args = array(1));
|
9 |
+
public function Save($activeRecord);
|
10 |
+
public function Delete($activeRecord);
|
11 |
+
public function LoadMulti($cond, $args = array());
|
12 |
+
public function LoadAndCallForEach($callback, $cond = '%d', $args = array(1));
|
13 |
+
public function Count($cond = '%d', $args = array(1));
|
14 |
+
public function LoadMultiQuery($query, $args = array());
|
15 |
+
}
|
classes/Models/Adapters/MetaInterface.php
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
interface WSAL_Adapters_MetaInterface {
|
4 |
-
/**
|
5 |
-
* Create a meta object
|
6 |
-
* @param $metaData Array of meta data
|
7 |
-
* @return int ID of the new meta data
|
8 |
-
*/
|
9 |
-
public function deleteByOccurenceIds($occurenceIds);
|
10 |
-
|
11 |
-
public function loadByNameAndOccurenceId($metaName, $occurenceId);
|
12 |
-
|
13 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface WSAL_Adapters_MetaInterface {
|
4 |
+
/**
|
5 |
+
* Create a meta object
|
6 |
+
* @param $metaData Array of meta data
|
7 |
+
* @return int ID of the new meta data
|
8 |
+
*/
|
9 |
+
public function deleteByOccurenceIds($occurenceIds);
|
10 |
+
|
11 |
+
public function loadByNameAndOccurenceId($metaName, $occurenceId);
|
12 |
+
|
13 |
+
}
|
classes/Models/Adapters/MySQL/ActiveRecordAdapter.php
CHANGED
@@ -1,448 +1,448 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInterface
|
4 |
-
{
|
5 |
-
protected $connection;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Contains the table name
|
9 |
-
* @var string
|
10 |
-
*/
|
11 |
-
protected $_table;
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Contains primary key column name, override as required.
|
15 |
-
* @var string
|
16 |
-
*/
|
17 |
-
protected $_idkey = '';
|
18 |
-
|
19 |
-
public function __construct($conn)
|
20 |
-
{
|
21 |
-
$this->connection = $conn;
|
22 |
-
}
|
23 |
-
|
24 |
-
public function GetModel()
|
25 |
-
{
|
26 |
-
return new WSAL_Models_ActiveRecord();
|
27 |
-
}
|
28 |
-
|
29 |
-
/**
|
30 |
-
* @return string Returns table name.
|
31 |
-
*/
|
32 |
-
public function GetTable()
|
33 |
-
{
|
34 |
-
$_wpdb = $this->connection;
|
35 |
-
return $_wpdb->base_prefix . $this->_table;
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Used for WordPress prefix
|
40 |
-
* @return string Returns table name of WordPress.
|
41 |
-
*/
|
42 |
-
public function GetWPTable()
|
43 |
-
{
|
44 |
-
global $wpdb;
|
45 |
-
return $wpdb->base_prefix . $this->_table;
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @return string SQL table options (constraints, foreign keys, indexes etc).
|
50 |
-
*/
|
51 |
-
protected function GetTableOptions()
|
52 |
-
{
|
53 |
-
return ' PRIMARY KEY (' . $this->_idkey . ')';
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* @return array Returns this records' columns.
|
58 |
-
*/
|
59 |
-
public function GetColumns()
|
60 |
-
{
|
61 |
-
$model = $this->GetModel();
|
62 |
-
|
63 |
-
if (!isset($this->_column_cache)) {
|
64 |
-
$this->_column_cache = array();
|
65 |
-
foreach (array_keys(get_object_vars($model)) as $col)
|
66 |
-
if (trim($col) && $col[0] != '_')
|
67 |
-
$this->_column_cache[] = $col;
|
68 |
-
}
|
69 |
-
return $this->_column_cache;
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* @deprecated
|
74 |
-
* @return boolean Returns whether table structure is installed or not.
|
75 |
-
*/
|
76 |
-
public function IsInstalled(){
|
77 |
-
//global $wpdb;
|
78 |
-
$_wpdb = $this->connection;
|
79 |
-
$sql = 'SHOW TABLES LIKE "' . $this->GetTable() . '"';
|
80 |
-
return strtolower($_wpdb->get_var($sql)) == strtolower($this->GetTable());
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Install this ActiveRecord structure into DB.
|
85 |
-
*/
|
86 |
-
public function Install(){
|
87 |
-
$_wpdb = $this->connection;
|
88 |
-
$_wpdb->query($this->_GetInstallQuery());
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Install this ActiveRecord structure into DB WordPress.
|
93 |
-
*/
|
94 |
-
public function InstallOriginal(){
|
95 |
-
global $wpdb;
|
96 |
-
$wpdb->query($this->_GetInstallQuery(true));
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Remove this ActiveRecord structure into DB.
|
101 |
-
*/
|
102 |
-
public function Uninstall()
|
103 |
-
{
|
104 |
-
//global $wpdb;
|
105 |
-
$_wpdb = $this->connection;
|
106 |
-
$_wpdb->query($this->_GetUninstallQuery());
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Save an active record to DB.
|
111 |
-
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
112 |
-
*/
|
113 |
-
public function Save($activeRecord)
|
114 |
-
{
|
115 |
-
//global $wpdb;
|
116 |
-
$_wpdb = $this->connection;
|
117 |
-
$copy = $activeRecord;
|
118 |
-
$data = array();
|
119 |
-
$format = array();
|
120 |
-
|
121 |
-
foreach ($this->GetColumns() as $index => $key) {
|
122 |
-
if ($key == $this->_idkey) {
|
123 |
-
$_idIndex = $index;
|
124 |
-
}
|
125 |
-
|
126 |
-
$val = $copy->$key;
|
127 |
-
$deffmt = '%s';
|
128 |
-
if (is_int($copy->$key)) {
|
129 |
-
$deffmt = '%d';
|
130 |
-
}
|
131 |
-
if (is_float($copy->$key)) {
|
132 |
-
$deffmt = '%f';
|
133 |
-
}
|
134 |
-
if (is_array($copy->$key) || is_object($copy->$key)) {
|
135 |
-
$data[$key] = WSAL_Helpers_DataHelper::JsonEncode($val);
|
136 |
-
} else {
|
137 |
-
$data[$key] = $val;
|
138 |
-
}
|
139 |
-
$format[] = $deffmt;
|
140 |
-
}
|
141 |
-
|
142 |
-
if (isset($data[$this->_idkey]) && empty($data[$this->_idkey])) {
|
143 |
-
unset($data[$this->_idkey]);
|
144 |
-
unset($format[$_idIndex]);
|
145 |
-
}
|
146 |
-
|
147 |
-
$result = $_wpdb->replace($this->GetTable(), $data, $format);
|
148 |
-
|
149 |
-
if ($result !== false) {
|
150 |
-
if ($_wpdb->insert_id) {
|
151 |
-
$copy->setId($_wpdb->insert_id);
|
152 |
-
}
|
153 |
-
}
|
154 |
-
return $result;
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Load record from DB.
|
159 |
-
* @param string $cond (Optional) Load condition.
|
160 |
-
* @param array $args (Optional) Load condition arguments.
|
161 |
-
*/
|
162 |
-
public function Load($cond = '%d', $args = array(1))
|
163 |
-
{
|
164 |
-
//global $wpdb;
|
165 |
-
$_wpdb = $this->connection;
|
166 |
-
|
167 |
-
$sql = $_wpdb->prepare('SELECT * FROM '.$this->GetTable().' WHERE '. $cond, $args);
|
168 |
-
$data = $_wpdb->get_row($sql, ARRAY_A);
|
169 |
-
|
170 |
-
return $data;
|
171 |
-
}
|
172 |
-
|
173 |
-
public function LoadArray($cond, $args = array())
|
174 |
-
{
|
175 |
-
//global $wpdb;
|
176 |
-
$_wpdb = $this->connection;
|
177 |
-
$result = array();
|
178 |
-
$sql = $_wpdb->prepare('SELECT * FROM '.$this->GetTable().' WHERE '. $cond, $args);
|
179 |
-
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
180 |
-
$result[] = $this->getModel()->LoadData($data);
|
181 |
-
}
|
182 |
-
return $result;
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* Delete DB record.
|
187 |
-
* @return int|boolean Either the amount of deleted rows or False on error.
|
188 |
-
*/
|
189 |
-
public function Delete($activeRecord)
|
190 |
-
{
|
191 |
-
//global $wpdb;
|
192 |
-
$_wpdb = $this->connection;
|
193 |
-
$result = $_wpdb->delete(
|
194 |
-
$this->GetTable(),
|
195 |
-
$activeRecord->getId()
|
196 |
-
);
|
197 |
-
return $result;
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* Delete records in DB matching a query.
|
202 |
-
* @param string $query Full SQL query.
|
203 |
-
* @param array $args (Optional) Query arguments.
|
204 |
-
*/
|
205 |
-
public function DeleteQuery($query, $args = array())
|
206 |
-
{
|
207 |
-
$_wpdb = $this->connection;
|
208 |
-
$sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
|
209 |
-
$result = $_wpdb->query($sql);
|
210 |
-
return $result;
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Load multiple records from DB.
|
215 |
-
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
216 |
-
* @param array $args (Optional) Load condition arguments (rg: array(45) ).
|
217 |
-
* @return self[] List of loaded records.
|
218 |
-
*/
|
219 |
-
public function LoadMulti($cond, $args = array())
|
220 |
-
{
|
221 |
-
//global $wpdb;
|
222 |
-
$_wpdb = $this->connection;
|
223 |
-
$result = array();
|
224 |
-
$sql = (!is_array($args) || !count($args)) // do we really need to prepare() or not?
|
225 |
-
? ($cond)
|
226 |
-
: $_wpdb->prepare($cond, $args)
|
227 |
-
;
|
228 |
-
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
229 |
-
$result[] = $this->getModel()->LoadData($data);
|
230 |
-
}
|
231 |
-
return $result;
|
232 |
-
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* Load multiple records from DB and call a callback for each record.
|
237 |
-
* This function is very memory-efficient, it doesn't load records in bulk.
|
238 |
-
* @param callable $callback The callback to invoke.
|
239 |
-
* @param string $cond (Optional) Load condition.
|
240 |
-
* @param array $args (Optional) Load condition arguments.
|
241 |
-
*/
|
242 |
-
public function LoadAndCallForEach($callback, $cond = '%d', $args = array(1))
|
243 |
-
{
|
244 |
-
//global $wpdb;
|
245 |
-
$_wpdb = $this->connection;
|
246 |
-
$class = get_called_class();
|
247 |
-
$sql = $_wpdb->prepare('SELECT * FROM ' . $this->GetTable() . ' WHERE '.$cond, $args);
|
248 |
-
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
249 |
-
call_user_func($callback, new $class($data));
|
250 |
-
}
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Count records in the DB matching a condition.
|
255 |
-
* If no parameters are given, this counts the number of records in the DB table.
|
256 |
-
* @param string $cond (Optional) Query condition.
|
257 |
-
* @param array $args (Optional) Condition arguments.
|
258 |
-
* @return int Number of matching records.
|
259 |
-
*/
|
260 |
-
public function Count($cond = '%d', $args = array(1))
|
261 |
-
{
|
262 |
-
//global $wpdb;
|
263 |
-
$_wpdb = $this->connection;
|
264 |
-
$class = get_called_class();
|
265 |
-
$sql = $_wpdb->prepare('SELECT COUNT(*) FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args);
|
266 |
-
return (int)$_wpdb->get_var($sql);
|
267 |
-
}
|
268 |
-
|
269 |
-
/**
|
270 |
-
* Count records in the DB matching a query.
|
271 |
-
* @param string $query Full SQL query.
|
272 |
-
* @param array $args (Optional) Query arguments.
|
273 |
-
* @return int Number of matching records.
|
274 |
-
*/
|
275 |
-
public function CountQuery($query, $args = array())
|
276 |
-
{
|
277 |
-
//global $wpdb;
|
278 |
-
$_wpdb = $this->connection;
|
279 |
-
$sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
|
280 |
-
return (int)$_wpdb->get_var($sql);
|
281 |
-
}
|
282 |
-
|
283 |
-
/**
|
284 |
-
* Similar to LoadMulti but allows the use of a full SQL query.
|
285 |
-
* @param string $query Full SQL query.
|
286 |
-
* @param array $args (Optional) Query arguments.
|
287 |
-
* @return self[] List of loaded records.
|
288 |
-
*/
|
289 |
-
public function LoadMultiQuery($query, $args = array())
|
290 |
-
{
|
291 |
-
//global $wpdb;
|
292 |
-
$_wpdb = $this->connection;
|
293 |
-
$class = get_called_class();
|
294 |
-
$result = array();
|
295 |
-
$sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
|
296 |
-
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
297 |
-
$result[] = $this->getModel()->LoadData($data);
|
298 |
-
}
|
299 |
-
return $result;
|
300 |
-
}
|
301 |
-
|
302 |
-
/**
|
303 |
-
* @return string Must return SQL for creating table.
|
304 |
-
*/
|
305 |
-
protected function _GetInstallQuery($prefix = false)
|
306 |
-
{
|
307 |
-
$_wpdb = $this->connection;
|
308 |
-
|
309 |
-
$class = get_class($this);
|
310 |
-
$copy = new $class($this->connection);
|
311 |
-
$table_name = ($prefix) ? $this->GetWPTable() : $this->GetTable();
|
312 |
-
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
313 |
-
|
314 |
-
foreach ($this->GetColumns() as $key) {
|
315 |
-
$sql .= ' ';
|
316 |
-
switch (true) {
|
317 |
-
case $key == $copy->_idkey:
|
318 |
-
$sql .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
|
319 |
-
break;
|
320 |
-
case is_integer($copy->$key):
|
321 |
-
$sql .= $key . ' BIGINT NOT NULL,' . PHP_EOL;
|
322 |
-
break;
|
323 |
-
case is_float($copy->$key):
|
324 |
-
$sql .= $key . ' DOUBLE NOT NULL,' . PHP_EOL;
|
325 |
-
break;
|
326 |
-
case is_string($copy->$key):
|
327 |
-
$maxlength = $key . '_maxlength';
|
328 |
-
if (property_exists($class, $maxlength)) {
|
329 |
-
$sql .= $key . ' VARCHAR(' . intval($class::$$maxlength) . ') NOT NULL,' . PHP_EOL;
|
330 |
-
} else {
|
331 |
-
$sql .= $key . ' TEXT NOT NULL,' . PHP_EOL;
|
332 |
-
}
|
333 |
-
break;
|
334 |
-
case is_bool($copy->$key):
|
335 |
-
$sql .= $key . ' BIT NOT NULL,' . PHP_EOL;
|
336 |
-
break;
|
337 |
-
case is_array($copy->$key):
|
338 |
-
case is_object($copy->$key):
|
339 |
-
$sql .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
340 |
-
break;
|
341 |
-
}
|
342 |
-
}
|
343 |
-
|
344 |
-
$sql .= $this->GetTableOptions() . PHP_EOL;
|
345 |
-
|
346 |
-
$sql .= ')';
|
347 |
-
|
348 |
-
if (! empty($_wpdb->charset)) {
|
349 |
-
$sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
|
350 |
-
}
|
351 |
-
|
352 |
-
return $sql;
|
353 |
-
|
354 |
-
}
|
355 |
-
|
356 |
-
/**
|
357 |
-
* @return string Must return SQL for removing table (at a minimum, it should be ` 'DROP TABLE ' . $this->_table `).
|
358 |
-
*/
|
359 |
-
protected function _GetUninstallQuery()
|
360 |
-
{
|
361 |
-
return 'DROP TABLE ' . $this->GetTable();
|
362 |
-
}
|
363 |
-
|
364 |
-
/**
|
365 |
-
* Function used in WSAL reporting extension
|
366 |
-
*/
|
367 |
-
public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp, $_nextDate = null, $_limit = 0)
|
368 |
-
{
|
369 |
-
global $wpdb;
|
370 |
-
$tableUsers = $wpdb->users;
|
371 |
-
$_wpdb = $this->connection;
|
372 |
-
// tables
|
373 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
374 |
-
$tableMeta = $meta->GetTable(); // metadata
|
375 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
|
376 |
-
$tableOcc = $occurrence->GetTable(); // occurrences
|
377 |
-
|
378 |
-
$user_names = '0';
|
379 |
-
if (!empty($_userId) && $_userId != "null") {
|
380 |
-
$sql = 'SELECT user_login FROM '.$tableUsers.' WHERE find_in_set(ID, @userId) > 0';
|
381 |
-
$wpdb->query("SET @userId = $_userId");
|
382 |
-
$result = $wpdb->get_results($sql, ARRAY_A);
|
383 |
-
$aUsers = array();
|
384 |
-
foreach ($result as $item) {
|
385 |
-
$aUsers[] = '"'.$item['user_login'].'"';
|
386 |
-
}
|
387 |
-
$user_names = implode(', ', $aUsers);
|
388 |
-
}
|
389 |
-
$conditionDate = !empty($_nextDate) ? ' AND occ.created_on < '.$_nextDate : '';
|
390 |
-
|
391 |
-
$sql = "SELECT DISTINCT
|
392 |
-
occ.id,
|
393 |
-
occ.alert_id,
|
394 |
-
occ.site_id,
|
395 |
-
occ.created_on,
|
396 |
-
replace(replace(replace((
|
397 |
-
SELECT t1.value FROM $tableMeta AS t1 WHERE t1.name = 'CurrentUserRoles' AND t1.occurrence_id = occ.id), '[', ''), ']', ''), '\\'', '') AS roles,
|
398 |
-
(SELECT replace(t2.value, '\"','') FROM $tableMeta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id) AS ip,
|
399 |
-
(SELECT replace(t3.value, '\"', '') FROM $tableMeta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id) AS ua,
|
400 |
-
COALESCE(
|
401 |
-
(SELECT replace(t4.value, '\"', '') FROM $tableMeta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id),
|
402 |
-
(SELECT replace(t5.value, '\"', '') FROM $tableMeta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id)
|
403 |
-
) as user_id
|
404 |
-
FROM $tableOcc AS occ
|
405 |
-
JOIN $tableMeta AS meta ON meta.occurrence_id = occ.id
|
406 |
-
WHERE
|
407 |
-
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
408 |
-
AND (@userId is NULL OR (
|
409 |
-
(meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
410 |
-
OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
411 |
-
))
|
412 |
-
AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
|
413 |
-
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
414 |
-
))
|
415 |
-
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
416 |
-
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
417 |
-
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
418 |
-
{$conditionDate}
|
419 |
-
ORDER BY
|
420 |
-
created_on DESC
|
421 |
-
";
|
422 |
-
|
423 |
-
$_wpdb->query("SET @siteId = $_siteId");
|
424 |
-
$_wpdb->query("SET @userId = $_userId");
|
425 |
-
$_wpdb->query("SET @roleName = $_roleName");
|
426 |
-
$_wpdb->query("SET @alertCode = $_alertCode");
|
427 |
-
$_wpdb->query("SET @startTimestamp = $_startTimestamp");
|
428 |
-
$_wpdb->query("SET @endTimestamp = $_endTimestamp");
|
429 |
-
|
430 |
-
if (!empty($_limit)) {
|
431 |
-
$sql .= " LIMIT {$_limit}";
|
432 |
-
}
|
433 |
-
$results = $_wpdb->get_results($sql);
|
434 |
-
|
435 |
-
foreach ($results as $row) {
|
436 |
-
$sql = "SELECT t6.ID FROM $tableUsers AS t6 WHERE t6.user_login = \"$row->user_id\"";
|
437 |
-
$userId = $wpdb->get_var($sql);
|
438 |
-
if ($userId == null) {
|
439 |
-
$sql = "SELECT t4.ID FROM $tableUsers AS t4 WHERE t4.ID = \"$row->user_id\"";
|
440 |
-
$userId = $wpdb->get_var($sql);
|
441 |
-
}
|
442 |
-
$row->user_id = $userId;
|
443 |
-
$results['lastDate'] = $row->created_on;
|
444 |
-
}
|
445 |
-
|
446 |
-
return $results;
|
447 |
-
}
|
448 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInterface
|
4 |
+
{
|
5 |
+
protected $connection;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Contains the table name
|
9 |
+
* @var string
|
10 |
+
*/
|
11 |
+
protected $_table;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Contains primary key column name, override as required.
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
protected $_idkey = '';
|
18 |
+
|
19 |
+
public function __construct($conn)
|
20 |
+
{
|
21 |
+
$this->connection = $conn;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function GetModel()
|
25 |
+
{
|
26 |
+
return new WSAL_Models_ActiveRecord();
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @return string Returns table name.
|
31 |
+
*/
|
32 |
+
public function GetTable()
|
33 |
+
{
|
34 |
+
$_wpdb = $this->connection;
|
35 |
+
return $_wpdb->base_prefix . $this->_table;
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Used for WordPress prefix
|
40 |
+
* @return string Returns table name of WordPress.
|
41 |
+
*/
|
42 |
+
public function GetWPTable()
|
43 |
+
{
|
44 |
+
global $wpdb;
|
45 |
+
return $wpdb->base_prefix . $this->_table;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @return string SQL table options (constraints, foreign keys, indexes etc).
|
50 |
+
*/
|
51 |
+
protected function GetTableOptions()
|
52 |
+
{
|
53 |
+
return ' PRIMARY KEY (' . $this->_idkey . ')';
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return array Returns this records' columns.
|
58 |
+
*/
|
59 |
+
public function GetColumns()
|
60 |
+
{
|
61 |
+
$model = $this->GetModel();
|
62 |
+
|
63 |
+
if (!isset($this->_column_cache)) {
|
64 |
+
$this->_column_cache = array();
|
65 |
+
foreach (array_keys(get_object_vars($model)) as $col)
|
66 |
+
if (trim($col) && $col[0] != '_')
|
67 |
+
$this->_column_cache[] = $col;
|
68 |
+
}
|
69 |
+
return $this->_column_cache;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @deprecated
|
74 |
+
* @return boolean Returns whether table structure is installed or not.
|
75 |
+
*/
|
76 |
+
public function IsInstalled(){
|
77 |
+
//global $wpdb;
|
78 |
+
$_wpdb = $this->connection;
|
79 |
+
$sql = 'SHOW TABLES LIKE "' . $this->GetTable() . '"';
|
80 |
+
return strtolower($_wpdb->get_var($sql)) == strtolower($this->GetTable());
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Install this ActiveRecord structure into DB.
|
85 |
+
*/
|
86 |
+
public function Install(){
|
87 |
+
$_wpdb = $this->connection;
|
88 |
+
$_wpdb->query($this->_GetInstallQuery());
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Install this ActiveRecord structure into DB WordPress.
|
93 |
+
*/
|
94 |
+
public function InstallOriginal(){
|
95 |
+
global $wpdb;
|
96 |
+
$wpdb->query($this->_GetInstallQuery(true));
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Remove this ActiveRecord structure into DB.
|
101 |
+
*/
|
102 |
+
public function Uninstall()
|
103 |
+
{
|
104 |
+
//global $wpdb;
|
105 |
+
$_wpdb = $this->connection;
|
106 |
+
$_wpdb->query($this->_GetUninstallQuery());
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Save an active record to DB.
|
111 |
+
* @return integer|boolean Either the number of modified/inserted rows or false on failure.
|
112 |
+
*/
|
113 |
+
public function Save($activeRecord)
|
114 |
+
{
|
115 |
+
//global $wpdb;
|
116 |
+
$_wpdb = $this->connection;
|
117 |
+
$copy = $activeRecord;
|
118 |
+
$data = array();
|
119 |
+
$format = array();
|
120 |
+
|
121 |
+
foreach ($this->GetColumns() as $index => $key) {
|
122 |
+
if ($key == $this->_idkey) {
|
123 |
+
$_idIndex = $index;
|
124 |
+
}
|
125 |
+
|
126 |
+
$val = $copy->$key;
|
127 |
+
$deffmt = '%s';
|
128 |
+
if (is_int($copy->$key)) {
|
129 |
+
$deffmt = '%d';
|
130 |
+
}
|
131 |
+
if (is_float($copy->$key)) {
|
132 |
+
$deffmt = '%f';
|
133 |
+
}
|
134 |
+
if (is_array($copy->$key) || is_object($copy->$key)) {
|
135 |
+
$data[$key] = WSAL_Helpers_DataHelper::JsonEncode($val);
|
136 |
+
} else {
|
137 |
+
$data[$key] = $val;
|
138 |
+
}
|
139 |
+
$format[] = $deffmt;
|
140 |
+
}
|
141 |
+
|
142 |
+
if (isset($data[$this->_idkey]) && empty($data[$this->_idkey])) {
|
143 |
+
unset($data[$this->_idkey]);
|
144 |
+
unset($format[$_idIndex]);
|
145 |
+
}
|
146 |
+
|
147 |
+
$result = $_wpdb->replace($this->GetTable(), $data, $format);
|
148 |
+
|
149 |
+
if ($result !== false) {
|
150 |
+
if ($_wpdb->insert_id) {
|
151 |
+
$copy->setId($_wpdb->insert_id);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
return $result;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Load record from DB.
|
159 |
+
* @param string $cond (Optional) Load condition.
|
160 |
+
* @param array $args (Optional) Load condition arguments.
|
161 |
+
*/
|
162 |
+
public function Load($cond = '%d', $args = array(1))
|
163 |
+
{
|
164 |
+
//global $wpdb;
|
165 |
+
$_wpdb = $this->connection;
|
166 |
+
|
167 |
+
$sql = $_wpdb->prepare('SELECT * FROM '.$this->GetTable().' WHERE '. $cond, $args);
|
168 |
+
$data = $_wpdb->get_row($sql, ARRAY_A);
|
169 |
+
|
170 |
+
return $data;
|
171 |
+
}
|
172 |
+
|
173 |
+
public function LoadArray($cond, $args = array())
|
174 |
+
{
|
175 |
+
//global $wpdb;
|
176 |
+
$_wpdb = $this->connection;
|
177 |
+
$result = array();
|
178 |
+
$sql = $_wpdb->prepare('SELECT * FROM '.$this->GetTable().' WHERE '. $cond, $args);
|
179 |
+
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
180 |
+
$result[] = $this->getModel()->LoadData($data);
|
181 |
+
}
|
182 |
+
return $result;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Delete DB record.
|
187 |
+
* @return int|boolean Either the amount of deleted rows or False on error.
|
188 |
+
*/
|
189 |
+
public function Delete($activeRecord)
|
190 |
+
{
|
191 |
+
//global $wpdb;
|
192 |
+
$_wpdb = $this->connection;
|
193 |
+
$result = $_wpdb->delete(
|
194 |
+
$this->GetTable(),
|
195 |
+
$activeRecord->getId()
|
196 |
+
);
|
197 |
+
return $result;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Delete records in DB matching a query.
|
202 |
+
* @param string $query Full SQL query.
|
203 |
+
* @param array $args (Optional) Query arguments.
|
204 |
+
*/
|
205 |
+
public function DeleteQuery($query, $args = array())
|
206 |
+
{
|
207 |
+
$_wpdb = $this->connection;
|
208 |
+
$sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
|
209 |
+
$result = $_wpdb->query($sql);
|
210 |
+
return $result;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Load multiple records from DB.
|
215 |
+
* @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
|
216 |
+
* @param array $args (Optional) Load condition arguments (rg: array(45) ).
|
217 |
+
* @return self[] List of loaded records.
|
218 |
+
*/
|
219 |
+
public function LoadMulti($cond, $args = array())
|
220 |
+
{
|
221 |
+
//global $wpdb;
|
222 |
+
$_wpdb = $this->connection;
|
223 |
+
$result = array();
|
224 |
+
$sql = (!is_array($args) || !count($args)) // do we really need to prepare() or not?
|
225 |
+
? ($cond)
|
226 |
+
: $_wpdb->prepare($cond, $args)
|
227 |
+
;
|
228 |
+
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
229 |
+
$result[] = $this->getModel()->LoadData($data);
|
230 |
+
}
|
231 |
+
return $result;
|
232 |
+
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Load multiple records from DB and call a callback for each record.
|
237 |
+
* This function is very memory-efficient, it doesn't load records in bulk.
|
238 |
+
* @param callable $callback The callback to invoke.
|
239 |
+
* @param string $cond (Optional) Load condition.
|
240 |
+
* @param array $args (Optional) Load condition arguments.
|
241 |
+
*/
|
242 |
+
public function LoadAndCallForEach($callback, $cond = '%d', $args = array(1))
|
243 |
+
{
|
244 |
+
//global $wpdb;
|
245 |
+
$_wpdb = $this->connection;
|
246 |
+
$class = get_called_class();
|
247 |
+
$sql = $_wpdb->prepare('SELECT * FROM ' . $this->GetTable() . ' WHERE '.$cond, $args);
|
248 |
+
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
249 |
+
call_user_func($callback, new $class($data));
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Count records in the DB matching a condition.
|
255 |
+
* If no parameters are given, this counts the number of records in the DB table.
|
256 |
+
* @param string $cond (Optional) Query condition.
|
257 |
+
* @param array $args (Optional) Condition arguments.
|
258 |
+
* @return int Number of matching records.
|
259 |
+
*/
|
260 |
+
public function Count($cond = '%d', $args = array(1))
|
261 |
+
{
|
262 |
+
//global $wpdb;
|
263 |
+
$_wpdb = $this->connection;
|
264 |
+
$class = get_called_class();
|
265 |
+
$sql = $_wpdb->prepare('SELECT COUNT(*) FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args);
|
266 |
+
return (int)$_wpdb->get_var($sql);
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Count records in the DB matching a query.
|
271 |
+
* @param string $query Full SQL query.
|
272 |
+
* @param array $args (Optional) Query arguments.
|
273 |
+
* @return int Number of matching records.
|
274 |
+
*/
|
275 |
+
public function CountQuery($query, $args = array())
|
276 |
+
{
|
277 |
+
//global $wpdb;
|
278 |
+
$_wpdb = $this->connection;
|
279 |
+
$sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
|
280 |
+
return (int)$_wpdb->get_var($sql);
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Similar to LoadMulti but allows the use of a full SQL query.
|
285 |
+
* @param string $query Full SQL query.
|
286 |
+
* @param array $args (Optional) Query arguments.
|
287 |
+
* @return self[] List of loaded records.
|
288 |
+
*/
|
289 |
+
public function LoadMultiQuery($query, $args = array())
|
290 |
+
{
|
291 |
+
//global $wpdb;
|
292 |
+
$_wpdb = $this->connection;
|
293 |
+
$class = get_called_class();
|
294 |
+
$result = array();
|
295 |
+
$sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
|
296 |
+
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
297 |
+
$result[] = $this->getModel()->LoadData($data);
|
298 |
+
}
|
299 |
+
return $result;
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* @return string Must return SQL for creating table.
|
304 |
+
*/
|
305 |
+
protected function _GetInstallQuery($prefix = false)
|
306 |
+
{
|
307 |
+
$_wpdb = $this->connection;
|
308 |
+
|
309 |
+
$class = get_class($this);
|
310 |
+
$copy = new $class($this->connection);
|
311 |
+
$table_name = ($prefix) ? $this->GetWPTable() : $this->GetTable();
|
312 |
+
$sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
|
313 |
+
|
314 |
+
foreach ($this->GetColumns() as $key) {
|
315 |
+
$sql .= ' ';
|
316 |
+
switch (true) {
|
317 |
+
case $key == $copy->_idkey:
|
318 |
+
$sql .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
|
319 |
+
break;
|
320 |
+
case is_integer($copy->$key):
|
321 |
+
$sql .= $key . ' BIGINT NOT NULL,' . PHP_EOL;
|
322 |
+
break;
|
323 |
+
case is_float($copy->$key):
|
324 |
+
$sql .= $key . ' DOUBLE NOT NULL,' . PHP_EOL;
|
325 |
+
break;
|
326 |
+
case is_string($copy->$key):
|
327 |
+
$maxlength = $key . '_maxlength';
|
328 |
+
if (property_exists($class, $maxlength)) {
|
329 |
+
$sql .= $key . ' VARCHAR(' . intval($class::$$maxlength) . ') NOT NULL,' . PHP_EOL;
|
330 |
+
} else {
|
331 |
+
$sql .= $key . ' TEXT NOT NULL,' . PHP_EOL;
|
332 |
+
}
|
333 |
+
break;
|
334 |
+
case is_bool($copy->$key):
|
335 |
+
$sql .= $key . ' BIT NOT NULL,' . PHP_EOL;
|
336 |
+
break;
|
337 |
+
case is_array($copy->$key):
|
338 |
+
case is_object($copy->$key):
|
339 |
+
$sql .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
|
340 |
+
break;
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
$sql .= $this->GetTableOptions() . PHP_EOL;
|
345 |
+
|
346 |
+
$sql .= ')';
|
347 |
+
|
348 |
+
if (! empty($_wpdb->charset)) {
|
349 |
+
$sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
|
350 |
+
}
|
351 |
+
|
352 |
+
return $sql;
|
353 |
+
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* @return string Must return SQL for removing table (at a minimum, it should be ` 'DROP TABLE ' . $this->_table `).
|
358 |
+
*/
|
359 |
+
protected function _GetUninstallQuery()
|
360 |
+
{
|
361 |
+
return 'DROP TABLE ' . $this->GetTable();
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* Function used in WSAL reporting extension
|
366 |
+
*/
|
367 |
+
public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp, $_nextDate = null, $_limit = 0)
|
368 |
+
{
|
369 |
+
global $wpdb;
|
370 |
+
$tableUsers = $wpdb->users;
|
371 |
+
$_wpdb = $this->connection;
|
372 |
+
// tables
|
373 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
374 |
+
$tableMeta = $meta->GetTable(); // metadata
|
375 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
|
376 |
+
$tableOcc = $occurrence->GetTable(); // occurrences
|
377 |
+
|
378 |
+
$user_names = '0';
|
379 |
+
if (!empty($_userId) && $_userId != "null") {
|
380 |
+
$sql = 'SELECT user_login FROM '.$tableUsers.' WHERE find_in_set(ID, @userId) > 0';
|
381 |
+
$wpdb->query("SET @userId = $_userId");
|
382 |
+
$result = $wpdb->get_results($sql, ARRAY_A);
|
383 |
+
$aUsers = array();
|
384 |
+
foreach ($result as $item) {
|
385 |
+
$aUsers[] = '"'.$item['user_login'].'"';
|
386 |
+
}
|
387 |
+
$user_names = implode(', ', $aUsers);
|
388 |
+
}
|
389 |
+
$conditionDate = !empty($_nextDate) ? ' AND occ.created_on < '.$_nextDate : '';
|
390 |
+
|
391 |
+
$sql = "SELECT DISTINCT
|
392 |
+
occ.id,
|
393 |
+
occ.alert_id,
|
394 |
+
occ.site_id,
|
395 |
+
occ.created_on,
|
396 |
+
replace(replace(replace((
|
397 |
+
SELECT t1.value FROM $tableMeta AS t1 WHERE t1.name = 'CurrentUserRoles' AND t1.occurrence_id = occ.id LIMIT 1), '[', ''), ']', ''), '\\'', '') AS roles,
|
398 |
+
(SELECT replace(t2.value, '\"','') FROM $tableMeta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id LIMIT 1) AS ip,
|
399 |
+
(SELECT replace(t3.value, '\"', '') FROM $tableMeta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id LIMIT 1) AS ua,
|
400 |
+
COALESCE(
|
401 |
+
(SELECT replace(t4.value, '\"', '') FROM $tableMeta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id LIMIT 1),
|
402 |
+
(SELECT replace(t5.value, '\"', '') FROM $tableMeta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id LIMIT 1)
|
403 |
+
) as user_id
|
404 |
+
FROM $tableOcc AS occ
|
405 |
+
JOIN $tableMeta AS meta ON meta.occurrence_id = occ.id
|
406 |
+
WHERE
|
407 |
+
(@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
|
408 |
+
AND (@userId is NULL OR (
|
409 |
+
(meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
|
410 |
+
OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
|
411 |
+
))
|
412 |
+
AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
|
413 |
+
AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
|
414 |
+
))
|
415 |
+
AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
|
416 |
+
AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
|
417 |
+
AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
|
418 |
+
{$conditionDate}
|
419 |
+
ORDER BY
|
420 |
+
created_on DESC
|
421 |
+
";
|
422 |
+
|
423 |
+
$_wpdb->query("SET @siteId = $_siteId");
|
424 |
+
$_wpdb->query("SET @userId = $_userId");
|
425 |
+
$_wpdb->query("SET @roleName = $_roleName");
|
426 |
+
$_wpdb->query("SET @alertCode = $_alertCode");
|
427 |
+
$_wpdb->query("SET @startTimestamp = $_startTimestamp");
|
428 |
+
$_wpdb->query("SET @endTimestamp = $_endTimestamp");
|
429 |
+
|
430 |
+
if (!empty($_limit)) {
|
431 |
+
$sql .= " LIMIT {$_limit}";
|
432 |
+
}
|
433 |
+
$results = $_wpdb->get_results($sql);
|
434 |
+
|
435 |
+
foreach ($results as $row) {
|
436 |
+
$sql = "SELECT t6.ID FROM $tableUsers AS t6 WHERE t6.user_login = \"$row->user_id\"";
|
437 |
+
$userId = $wpdb->get_var($sql);
|
438 |
+
if ($userId == null) {
|
439 |
+
$sql = "SELECT t4.ID FROM $tableUsers AS t4 WHERE t4.ID = \"$row->user_id\"";
|
440 |
+
$userId = $wpdb->get_var($sql);
|
441 |
+
}
|
442 |
+
$row->user_id = $userId;
|
443 |
+
$results['lastDate'] = $row->created_on;
|
444 |
+
}
|
445 |
+
|
446 |
+
return $results;
|
447 |
+
}
|
448 |
+
}
|
classes/Models/Adapters/MySQL/MetaAdapter.php
CHANGED
@@ -1,53 +1,53 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_MetaInterface {
|
4 |
-
|
5 |
-
protected $_table = 'wsal_metadata';
|
6 |
-
protected $_idkey = 'id';
|
7 |
-
|
8 |
-
public $id = 0;
|
9 |
-
public $occurrence_id = 0;
|
10 |
-
public $name = '';
|
11 |
-
public static $name_maxlength = 100;
|
12 |
-
public $value = array(); // force mixed type
|
13 |
-
|
14 |
-
public function GetModel()
|
15 |
-
{
|
16 |
-
return new WSAL_Models_Meta();
|
17 |
-
}
|
18 |
-
|
19 |
-
public function __construct($conn)
|
20 |
-
{
|
21 |
-
parent::__construct($conn);
|
22 |
-
}
|
23 |
-
|
24 |
-
protected function GetTableOptions(){
|
25 |
-
return parent::GetTableOptions() . ',' . PHP_EOL
|
26 |
-
. ' KEY occurrence_name (occurrence_id,name)';
|
27 |
-
}
|
28 |
-
|
29 |
-
public function DeleteByOccurenceIds($occurenceIds)
|
30 |
-
{
|
31 |
-
if (!empty($occurenceIds)) {
|
32 |
-
$sql = 'DELETE FROM ' . $this->GetTable() . ' WHERE occurrence_id IN (' . implode(',', $occurenceIds) . ')';
|
33 |
-
// execute query
|
34 |
-
parent::DeleteQuery($sql);
|
35 |
-
}
|
36 |
-
}
|
37 |
-
|
38 |
-
public function LoadByNameAndOccurenceId($metaName, $occurenceId)
|
39 |
-
{
|
40 |
-
return $this->Load('occurrence_id = %d AND name = %s', array($occurenceId, $metaName));
|
41 |
-
}
|
42 |
-
|
43 |
-
public function GetMatchingIPs()
|
44 |
-
{
|
45 |
-
$_wpdb = $this->connection;
|
46 |
-
$ips = $_wpdb->get_col("SELECT DISTINCT value FROM {$this->GetTable()} WHERE name = \"ClientIP\"");
|
47 |
-
foreach ($ips as $key => $ip) {
|
48 |
-
$ips[$key] = str_replace('"', '', $ip);
|
49 |
-
}
|
50 |
-
return array_unique($ips);
|
51 |
-
}
|
52 |
-
|
53 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Adapters_MySQL_Meta extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_MetaInterface {
|
4 |
+
|
5 |
+
protected $_table = 'wsal_metadata';
|
6 |
+
protected $_idkey = 'id';
|
7 |
+
|
8 |
+
public $id = 0;
|
9 |
+
public $occurrence_id = 0;
|
10 |
+
public $name = '';
|
11 |
+
public static $name_maxlength = 100;
|
12 |
+
public $value = array(); // force mixed type
|
13 |
+
|
14 |
+
public function GetModel()
|
15 |
+
{
|
16 |
+
return new WSAL_Models_Meta();
|
17 |
+
}
|
18 |
+
|
19 |
+
public function __construct($conn)
|
20 |
+
{
|
21 |
+
parent::__construct($conn);
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function GetTableOptions(){
|
25 |
+
return parent::GetTableOptions() . ',' . PHP_EOL
|
26 |
+
. ' KEY occurrence_name (occurrence_id,name)';
|
27 |
+
}
|
28 |
+
|
29 |
+
public function DeleteByOccurenceIds($occurenceIds)
|
30 |
+
{
|
31 |
+
if (!empty($occurenceIds)) {
|
32 |
+
$sql = 'DELETE FROM ' . $this->GetTable() . ' WHERE occurrence_id IN (' . implode(',', $occurenceIds) . ')';
|
33 |
+
// execute query
|
34 |
+
parent::DeleteQuery($sql);
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
public function LoadByNameAndOccurenceId($metaName, $occurenceId)
|
39 |
+
{
|
40 |
+
return $this->Load('occurrence_id = %d AND name = %s', array($occurenceId, $metaName));
|
41 |
+
}
|
42 |
+
|
43 |
+
public function GetMatchingIPs()
|
44 |
+
{
|
45 |
+
$_wpdb = $this->connection;
|
46 |
+
$ips = $_wpdb->get_col("SELECT DISTINCT value FROM {$this->GetTable()} WHERE name = \"ClientIP\"");
|
47 |
+
foreach ($ips as $key => $ip) {
|
48 |
+
$ips[$key] = str_replace('"', '', $ip);
|
49 |
+
}
|
50 |
+
return array_unique($ips);
|
51 |
+
}
|
52 |
+
|
53 |
+
}
|
classes/Models/Adapters/MySQL/OccurrenceAdapter.php
CHANGED
@@ -1,187 +1,187 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface {
|
4 |
-
|
5 |
-
protected $_table = 'wsal_occurrences';
|
6 |
-
protected $_idkey = 'id';
|
7 |
-
protected $_meta;
|
8 |
-
|
9 |
-
public $id = 0;
|
10 |
-
public $site_id = 0;
|
11 |
-
public $alert_id = 0;
|
12 |
-
public $created_on = 0.0;
|
13 |
-
public $is_read = false;
|
14 |
-
public $is_migrated = false;
|
15 |
-
|
16 |
-
public function __construct($conn) {
|
17 |
-
parent::__construct($conn);
|
18 |
-
}
|
19 |
-
|
20 |
-
protected function GetTableOptions(){
|
21 |
-
return parent::GetTableOptions() . ',' . PHP_EOL
|
22 |
-
. ' KEY site_alert_created (site_id,alert_id,created_on)';
|
23 |
-
}
|
24 |
-
|
25 |
-
public function GetModel()
|
26 |
-
{
|
27 |
-
return new WSAL_Models_Occurrence();
|
28 |
-
}
|
29 |
-
/**
|
30 |
-
* Returns all meta data related to this event.
|
31 |
-
* @return WSAL_Meta[]
|
32 |
-
*/
|
33 |
-
public function GetMeta($occurence){
|
34 |
-
if(!isset($this->_meta)){
|
35 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
36 |
-
$this->_meta = $meta->Load('occurrence_id = %d', array($occurence->id));
|
37 |
-
}
|
38 |
-
return $this->_meta;
|
39 |
-
}
|
40 |
-
|
41 |
-
public function GetMultiMeta($occurence){
|
42 |
-
if(!isset($this->_meta)){
|
43 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
44 |
-
$this->_meta = $meta->LoadArray('occurrence_id = %d', array($occurence->id));
|
45 |
-
}
|
46 |
-
return $this->_meta;
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Loads a meta item given its name.
|
51 |
-
* @param string $name Meta name.
|
52 |
-
* @return WSAL_Meta The meta item, be sure to checked if it was loaded successfully.
|
53 |
-
*/
|
54 |
-
public function GetNamedMeta($occurence, $name){
|
55 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
56 |
-
$this->_meta = $meta->Load('occurrence_id = %d AND name = %s', array($occurence->id, $name));
|
57 |
-
|
58 |
-
return $this->_meta;
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* 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.
|
63 |
-
* @param array $names List of meta names.
|
64 |
-
* @return WSAL_Meta The first meta item that exists.
|
65 |
-
*/
|
66 |
-
public function GetFirstNamedMeta($occurence, $names){
|
67 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
68 |
-
$query = '(' . str_repeat('name = %s OR ', count($names)).'0)';
|
69 |
-
$query = 'occurrence_id = %d AND ' . $query . ' ORDER BY name DESC LIMIT 1';
|
70 |
-
array_unshift($names, $occurence->id); // prepend args with occurrence id
|
71 |
-
|
72 |
-
$this->_meta = $meta->Load($query, $names);
|
73 |
-
return $meta->getModel()->LoadData($this->_meta);
|
74 |
-
|
75 |
-
//TO DO: Do we want to reintroduce is loaded check/logic?
|
76 |
-
//return $meta->IsLoaded() ? $meta : null;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Returns newest unique occurrences.
|
81 |
-
* @param integer $limit Maximum limit.
|
82 |
-
* @return WSAL_Occurrence[]
|
83 |
-
*/
|
84 |
-
public static function GetNewestUnique($limit = PHP_INT_MAX){
|
85 |
-
$temp = new self();
|
86 |
-
return self::LoadMultiQuery('
|
87 |
-
SELECT *, COUNT(alert_id) as count
|
88 |
-
FROM (
|
89 |
-
SELECT *
|
90 |
-
FROM ' . $temp->GetTable() . '
|
91 |
-
ORDER BY created_on DESC
|
92 |
-
) AS temp_table
|
93 |
-
GROUP BY alert_id
|
94 |
-
LIMIT %d
|
95 |
-
', array($limit));
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Gets occurences of the same type by IP and Username within specified time frame
|
100 |
-
* @param string $ipAddress
|
101 |
-
* @param string $username
|
102 |
-
* @param int $alertId Alert type we are lookign for
|
103 |
-
* @param int $siteId
|
104 |
-
* @param $startTime mktime
|
105 |
-
* @param $endTime mktime
|
106 |
-
*/
|
107 |
-
public function CheckKnownUsers($args = array())
|
108 |
-
{
|
109 |
-
$tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
|
110 |
-
return self::LoadMultiQuery(
|
111 |
-
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
112 |
-
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
113 |
-
and ipMeta.name = "ClientIP"
|
114 |
-
and ipMeta.value = %s
|
115 |
-
INNER JOIN `' . $tt2->GetTable() . '` usernameMeta on usernameMeta.occurrence_id = occurrence.id
|
116 |
-
and usernameMeta.name = "Username"
|
117 |
-
and usernameMeta.value = %s
|
118 |
-
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
119 |
-
AND (created_on BETWEEN %d AND %d)
|
120 |
-
GROUP BY occurrence.id',
|
121 |
-
$args
|
122 |
-
);
|
123 |
-
}
|
124 |
-
|
125 |
-
public function CheckUnKnownUsers($args = array())
|
126 |
-
{
|
127 |
-
$tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
|
128 |
-
return self::LoadMultiQuery(
|
129 |
-
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
130 |
-
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
131 |
-
and ipMeta.name = "ClientIP" and ipMeta.value = %s
|
132 |
-
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
133 |
-
AND (created_on BETWEEN %d AND %d)
|
134 |
-
GROUP BY occurrence.id',
|
135 |
-
$args
|
136 |
-
);
|
137 |
-
}
|
138 |
-
|
139 |
-
protected function prepareOccurrenceQuery($query)
|
140 |
-
{
|
141 |
-
$searchQueryParameters = array();
|
142 |
-
$searchConditions = array();
|
143 |
-
$conditions = $query->getConditions();
|
144 |
-
|
145 |
-
//BUG: not all conditions are occurence related. maybe it's just a field site_id. need seperate arrays
|
146 |
-
if (!empty($conditions)) {
|
147 |
-
$tmp = new WSAL_Adapters_MySQL_Meta($this->connection);
|
148 |
-
$sWhereClause = "";
|
149 |
-
foreach ($conditions as $field => $value) {
|
150 |
-
if (!empty($sWhereClause)) {
|
151 |
-
$sWhereClause .= " AND ";
|
152 |
-
}
|
153 |
-
$sWhereClause .= "name = %s AND value = %s";
|
154 |
-
$searchQueryParameters[] = $field;
|
155 |
-
$searchQueryParameters[] = $value;
|
156 |
-
}
|
157 |
-
|
158 |
-
$searchConditions[] = 'id IN (
|
159 |
-
SELECT DISTINCT occurrence_id
|
160 |
-
FROM ' . $tmp->GetTable() . '
|
161 |
-
WHERE ' . $sWhereClause . '
|
162 |
-
)';
|
163 |
-
}
|
164 |
-
|
165 |
-
//do something with search query parameters and search conditions - give them to the query adapter?
|
166 |
-
return $searchConditions;
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* Gets occurrence by Post_id
|
171 |
-
* @param int $post_id
|
172 |
-
*/
|
173 |
-
public function GetByPostID($post_id)
|
174 |
-
{
|
175 |
-
$tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
|
176 |
-
return self::LoadMultiQuery(
|
177 |
-
'SELECT occurrence.* FROM `' . $this->GetTable() . '`AS occurrence
|
178 |
-
INNER JOIN `' . $tt2->GetTable() . '`AS postMeta ON postMeta.occurrence_id = occurrence.id
|
179 |
-
and postMeta.name = "PostID"
|
180 |
-
and postMeta.value = %d
|
181 |
-
GROUP BY occurrence.id
|
182 |
-
ORDER BY created_on DESC',
|
183 |
-
array($post_id)
|
184 |
-
);
|
185 |
-
}
|
186 |
-
|
187 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_OccurrenceInterface {
|
4 |
+
|
5 |
+
protected $_table = 'wsal_occurrences';
|
6 |
+
protected $_idkey = 'id';
|
7 |
+
protected $_meta;
|
8 |
+
|
9 |
+
public $id = 0;
|
10 |
+
public $site_id = 0;
|
11 |
+
public $alert_id = 0;
|
12 |
+
public $created_on = 0.0;
|
13 |
+
public $is_read = false;
|
14 |
+
public $is_migrated = false;
|
15 |
+
|
16 |
+
public function __construct($conn) {
|
17 |
+
parent::__construct($conn);
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function GetTableOptions(){
|
21 |
+
return parent::GetTableOptions() . ',' . PHP_EOL
|
22 |
+
. ' KEY site_alert_created (site_id,alert_id,created_on)';
|
23 |
+
}
|
24 |
+
|
25 |
+
public function GetModel()
|
26 |
+
{
|
27 |
+
return new WSAL_Models_Occurrence();
|
28 |
+
}
|
29 |
+
/**
|
30 |
+
* Returns all meta data related to this event.
|
31 |
+
* @return WSAL_Meta[]
|
32 |
+
*/
|
33 |
+
public function GetMeta($occurence){
|
34 |
+
if(!isset($this->_meta)){
|
35 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
36 |
+
$this->_meta = $meta->Load('occurrence_id = %d', array($occurence->id));
|
37 |
+
}
|
38 |
+
return $this->_meta;
|
39 |
+
}
|
40 |
+
|
41 |
+
public function GetMultiMeta($occurence){
|
42 |
+
if(!isset($this->_meta)){
|
43 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
44 |
+
$this->_meta = $meta->LoadArray('occurrence_id = %d', array($occurence->id));
|
45 |
+
}
|
46 |
+
return $this->_meta;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Loads a meta item given its name.
|
51 |
+
* @param string $name Meta name.
|
52 |
+
* @return WSAL_Meta The meta item, be sure to checked if it was loaded successfully.
|
53 |
+
*/
|
54 |
+
public function GetNamedMeta($occurence, $name){
|
55 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
56 |
+
$this->_meta = $meta->Load('occurrence_id = %d AND name = %s', array($occurence->id, $name));
|
57 |
+
|
58 |
+
return $this->_meta;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* 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.
|
63 |
+
* @param array $names List of meta names.
|
64 |
+
* @return WSAL_Meta The first meta item that exists.
|
65 |
+
*/
|
66 |
+
public function GetFirstNamedMeta($occurence, $names){
|
67 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
68 |
+
$query = '(' . str_repeat('name = %s OR ', count($names)).'0)';
|
69 |
+
$query = 'occurrence_id = %d AND ' . $query . ' ORDER BY name DESC LIMIT 1';
|
70 |
+
array_unshift($names, $occurence->id); // prepend args with occurrence id
|
71 |
+
|
72 |
+
$this->_meta = $meta->Load($query, $names);
|
73 |
+
return $meta->getModel()->LoadData($this->_meta);
|
74 |
+
|
75 |
+
//TO DO: Do we want to reintroduce is loaded check/logic?
|
76 |
+
//return $meta->IsLoaded() ? $meta : null;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Returns newest unique occurrences.
|
81 |
+
* @param integer $limit Maximum limit.
|
82 |
+
* @return WSAL_Occurrence[]
|
83 |
+
*/
|
84 |
+
public static function GetNewestUnique($limit = PHP_INT_MAX){
|
85 |
+
$temp = new self();
|
86 |
+
return self::LoadMultiQuery('
|
87 |
+
SELECT *, COUNT(alert_id) as count
|
88 |
+
FROM (
|
89 |
+
SELECT *
|
90 |
+
FROM ' . $temp->GetTable() . '
|
91 |
+
ORDER BY created_on DESC
|
92 |
+
) AS temp_table
|
93 |
+
GROUP BY alert_id
|
94 |
+
LIMIT %d
|
95 |
+
', array($limit));
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Gets occurences of the same type by IP and Username within specified time frame
|
100 |
+
* @param string $ipAddress
|
101 |
+
* @param string $username
|
102 |
+
* @param int $alertId Alert type we are lookign for
|
103 |
+
* @param int $siteId
|
104 |
+
* @param $startTime mktime
|
105 |
+
* @param $endTime mktime
|
106 |
+
*/
|
107 |
+
public function CheckKnownUsers($args = array())
|
108 |
+
{
|
109 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
|
110 |
+
return self::LoadMultiQuery(
|
111 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
112 |
+
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
113 |
+
and ipMeta.name = "ClientIP"
|
114 |
+
and ipMeta.value = %s
|
115 |
+
INNER JOIN `' . $tt2->GetTable() . '` usernameMeta on usernameMeta.occurrence_id = occurrence.id
|
116 |
+
and usernameMeta.name = "Username"
|
117 |
+
and usernameMeta.value = %s
|
118 |
+
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
119 |
+
AND (created_on BETWEEN %d AND %d)
|
120 |
+
GROUP BY occurrence.id',
|
121 |
+
$args
|
122 |
+
);
|
123 |
+
}
|
124 |
+
|
125 |
+
public function CheckUnKnownUsers($args = array())
|
126 |
+
{
|
127 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
|
128 |
+
return self::LoadMultiQuery(
|
129 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
|
130 |
+
INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
|
131 |
+
and ipMeta.name = "ClientIP" and ipMeta.value = %s
|
132 |
+
WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
|
133 |
+
AND (created_on BETWEEN %d AND %d)
|
134 |
+
GROUP BY occurrence.id',
|
135 |
+
$args
|
136 |
+
);
|
137 |
+
}
|
138 |
+
|
139 |
+
protected function prepareOccurrenceQuery($query)
|
140 |
+
{
|
141 |
+
$searchQueryParameters = array();
|
142 |
+
$searchConditions = array();
|
143 |
+
$conditions = $query->getConditions();
|
144 |
+
|
145 |
+
//BUG: not all conditions are occurence related. maybe it's just a field site_id. need seperate arrays
|
146 |
+
if (!empty($conditions)) {
|
147 |
+
$tmp = new WSAL_Adapters_MySQL_Meta($this->connection);
|
148 |
+
$sWhereClause = "";
|
149 |
+
foreach ($conditions as $field => $value) {
|
150 |
+
if (!empty($sWhereClause)) {
|
151 |
+
$sWhereClause .= " AND ";
|
152 |
+
}
|
153 |
+
$sWhereClause .= "name = %s AND value = %s";
|
154 |
+
$searchQueryParameters[] = $field;
|
155 |
+
$searchQueryParameters[] = $value;
|
156 |
+
}
|
157 |
+
|
158 |
+
$searchConditions[] = 'id IN (
|
159 |
+
SELECT DISTINCT occurrence_id
|
160 |
+
FROM ' . $tmp->GetTable() . '
|
161 |
+
WHERE ' . $sWhereClause . '
|
162 |
+
)';
|
163 |
+
}
|
164 |
+
|
165 |
+
//do something with search query parameters and search conditions - give them to the query adapter?
|
166 |
+
return $searchConditions;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Gets occurrence by Post_id
|
171 |
+
* @param int $post_id
|
172 |
+
*/
|
173 |
+
public function GetByPostID($post_id)
|
174 |
+
{
|
175 |
+
$tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
|
176 |
+
return self::LoadMultiQuery(
|
177 |
+
'SELECT occurrence.* FROM `' . $this->GetTable() . '`AS occurrence
|
178 |
+
INNER JOIN `' . $tt2->GetTable() . '`AS postMeta ON postMeta.occurrence_id = occurrence.id
|
179 |
+
and postMeta.name = "PostID"
|
180 |
+
and postMeta.value = %d
|
181 |
+
GROUP BY occurrence.id
|
182 |
+
ORDER BY created_on DESC',
|
183 |
+
array($post_id)
|
184 |
+
);
|
185 |
+
}
|
186 |
+
|
187 |
+
}
|
classes/Models/Adapters/MySQL/OptionAdapter.php
CHANGED
@@ -1,79 +1,79 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Adapters_MySQL_Option extends WSAL_Adapters_MySQL_ActiveRecord
|
4 |
-
{
|
5 |
-
|
6 |
-
protected $_table = 'wsal_options';
|
7 |
-
protected $_idkey = 'id';
|
8 |
-
|
9 |
-
public $id = 0;
|
10 |
-
public $option_name = '';
|
11 |
-
public static $option_name_maxlength = 100;
|
12 |
-
public $option_value = '';
|
13 |
-
|
14 |
-
public function __construct($conn)
|
15 |
-
{
|
16 |
-
parent::__construct($conn);
|
17 |
-
}
|
18 |
-
|
19 |
-
public function GetModel()
|
20 |
-
{
|
21 |
-
return new WSAL_Models_Option();
|
22 |
-
}
|
23 |
-
|
24 |
-
public function GetNamedOption($name)
|
25 |
-
{ if ($this->IsInstalled()) {
|
26 |
-
return $this->Load('option_name = %s', array($name));
|
27 |
-
} else {
|
28 |
-
return null;
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
public function GetNotificationsSetting($opt_prefix)
|
33 |
-
{
|
34 |
-
if ($this->IsInstalled()) {
|
35 |
-
return $this->LoadArray('option_name LIKE %s', array($opt_prefix."%"));
|
36 |
-
} else {
|
37 |
-
return null;
|
38 |
-
}
|
39 |
-
}
|
40 |
-
|
41 |
-
public function GetNotification($id)
|
42 |
-
{
|
43 |
-
if ($this->IsInstalled()) {
|
44 |
-
return $this->Load('id = %d', array($id));
|
45 |
-
} else {
|
46 |
-
return null;
|
47 |
-
}
|
48 |
-
}
|
49 |
-
|
50 |
-
public function DeleteByName($name)
|
51 |
-
{
|
52 |
-
if (!empty($name)) {
|
53 |
-
$sql = "DELETE FROM " . $this->GetTable() . " WHERE option_name = '". $name ."'";
|
54 |
-
// execute query
|
55 |
-
return parent::DeleteQuery($sql);
|
56 |
-
} else {
|
57 |
-
return false;
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
public function DeleteByPrefix($opt_prefix)
|
62 |
-
{
|
63 |
-
if (!empty($opt_prefix)) {
|
64 |
-
$sql = "DELETE FROM " . $this->GetTable() . " WHERE option_name LIKE '". $opt_prefix ."%'";
|
65 |
-
// execute query
|
66 |
-
return parent::DeleteQuery($sql);
|
67 |
-
} else {
|
68 |
-
return false;
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
public function CountNotifications($opt_prefix)
|
73 |
-
{
|
74 |
-
$_wpdb = $this->connection;
|
75 |
-
$sql = "SELECT COUNT(id) FROM " . $this->GetTable() . " WHERE option_name LIKE '". $opt_prefix ."%'";
|
76 |
-
return (int)$_wpdb->get_var($sql);
|
77 |
-
}
|
78 |
-
|
79 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Adapters_MySQL_Option extends WSAL_Adapters_MySQL_ActiveRecord
|
4 |
+
{
|
5 |
+
|
6 |
+
protected $_table = 'wsal_options';
|
7 |
+
protected $_idkey = 'id';
|
8 |
+
|
9 |
+
public $id = 0;
|
10 |
+
public $option_name = '';
|
11 |
+
public static $option_name_maxlength = 100;
|
12 |
+
public $option_value = '';
|
13 |
+
|
14 |
+
public function __construct($conn)
|
15 |
+
{
|
16 |
+
parent::__construct($conn);
|
17 |
+
}
|
18 |
+
|
19 |
+
public function GetModel()
|
20 |
+
{
|
21 |
+
return new WSAL_Models_Option();
|
22 |
+
}
|
23 |
+
|
24 |
+
public function GetNamedOption($name)
|
25 |
+
{ if ($this->IsInstalled()) {
|
26 |
+
return $this->Load('option_name = %s', array($name));
|
27 |
+
} else {
|
28 |
+
return null;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
public function GetNotificationsSetting($opt_prefix)
|
33 |
+
{
|
34 |
+
if ($this->IsInstalled()) {
|
35 |
+
return $this->LoadArray('option_name LIKE %s', array($opt_prefix."%"));
|
36 |
+
} else {
|
37 |
+
return null;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
public function GetNotification($id)
|
42 |
+
{
|
43 |
+
if ($this->IsInstalled()) {
|
44 |
+
return $this->Load('id = %d', array($id));
|
45 |
+
} else {
|
46 |
+
return null;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
public function DeleteByName($name)
|
51 |
+
{
|
52 |
+
if (!empty($name)) {
|
53 |
+
$sql = "DELETE FROM " . $this->GetTable() . " WHERE option_name = '". $name ."'";
|
54 |
+
// execute query
|
55 |
+
return parent::DeleteQuery($sql);
|
56 |
+
} else {
|
57 |
+
return false;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
public function DeleteByPrefix($opt_prefix)
|
62 |
+
{
|
63 |
+
if (!empty($opt_prefix)) {
|
64 |
+
$sql = "DELETE FROM " . $this->GetTable() . " WHERE option_name LIKE '". $opt_prefix ."%'";
|
65 |
+
// execute query
|
66 |
+
return parent::DeleteQuery($sql);
|
67 |
+
} else {
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
public function CountNotifications($opt_prefix)
|
73 |
+
{
|
74 |
+
$_wpdb = $this->connection;
|
75 |
+
$sql = "SELECT COUNT(id) FROM " . $this->GetTable() . " WHERE option_name LIKE '". $opt_prefix ."%'";
|
76 |
+
return (int)$_wpdb->get_var($sql);
|
77 |
+
}
|
78 |
+
|
79 |
+
}
|
classes/Models/Adapters/MySQL/QueryAdapter.php
CHANGED
@@ -1,219 +1,219 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface
|
4 |
-
{
|
5 |
-
protected $connection;
|
6 |
-
|
7 |
-
public function __construct($conn)
|
8 |
-
{
|
9 |
-
$this->connection = $conn;
|
10 |
-
}
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @return string Generated sql.
|
14 |
-
*/
|
15 |
-
protected function GetSql($query, &$args = array())
|
16 |
-
{
|
17 |
-
$conditions = $query->getConditions();
|
18 |
-
$searchCondition = $this->SearchCondition($query);
|
19 |
-
|
20 |
-
$sWhereClause = "";
|
21 |
-
foreach ($conditions as $fieldName => $fieldValue) {
|
22 |
-
if (empty($sWhereClause)) {
|
23 |
-
$sWhereClause .= " WHERE ";
|
24 |
-
} else {
|
25 |
-
$sWhereClause .= " AND ";
|
26 |
-
}
|
27 |
-
|
28 |
-
if (is_array($fieldValue)) {
|
29 |
-
$subWhereClause = "(";
|
30 |
-
foreach($fieldValue as $orFieldName => $orFieldValue) {
|
31 |
-
if ($subWhereClause != '(') {
|
32 |
-
$subWhereClause .= " OR ";
|
33 |
-
}
|
34 |
-
$subWhereClause .= $orFieldName;
|
35 |
-
$args[] = $orFieldValue;
|
36 |
-
}
|
37 |
-
$subWhereClause .= ")";
|
38 |
-
$sWhereClause .= $subWhereClause;
|
39 |
-
} else {
|
40 |
-
$sWhereClause .= $fieldName;
|
41 |
-
$args[] = $fieldValue;
|
42 |
-
}
|
43 |
-
}
|
44 |
-
|
45 |
-
$fromDataSets = $query->getFrom();
|
46 |
-
$columns = $query->getColumns();
|
47 |
-
$orderBys = $query->getOrderBy();
|
48 |
-
|
49 |
-
$sLimitClause = "";
|
50 |
-
if ($query->getLimit()) {
|
51 |
-
$sLimitClause .= " LIMIT ";
|
52 |
-
if ($query->getOffset()) {
|
53 |
-
$sLimitClause .= $query->getOffset() . ", ";
|
54 |
-
}
|
55 |
-
$sLimitClause .= $query->getLimit();
|
56 |
-
}
|
57 |
-
$joinClause = '';
|
58 |
-
if ($query->hasMetaJoin()) {
|
59 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
60 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
|
61 |
-
$joinClause = ' LEFT JOIN '. $meta->GetTable() .' AS meta ON meta.occurrence_id = '. $occurrence->GetTable() .'.id ';
|
62 |
-
}
|
63 |
-
$fields = (empty($columns))? $fromDataSets[0] . '.*' : implode(',', $columns);
|
64 |
-
if (!empty($searchCondition)) {
|
65 |
-
$args[] = $searchCondition['args'];
|
66 |
-
}
|
67 |
-
return 'SELECT ' . $fields
|
68 |
-
. ' FROM ' . implode(',', $fromDataSets)
|
69 |
-
. $joinClause
|
70 |
-
. $sWhereClause
|
71 |
-
. (!empty($searchCondition) ? (empty($sWhereClause) ? " WHERE ".$searchCondition['sql'] : " AND ".$searchCondition['sql']) : '')
|
72 |
-
// @todo GROUP BY goes here
|
73 |
-
. (!empty($orderBys) ? (' ORDER BY ' . implode(', ', array_keys($orderBys)) . ' ' . implode(', ', array_values($orderBys))) : '')
|
74 |
-
. $sLimitClause;
|
75 |
-
}
|
76 |
-
|
77 |
-
protected function getActiveRecordAdapter()
|
78 |
-
{
|
79 |
-
return new WSAL_Adapters_MySQL_ActiveRecord($this->connection);
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* @return WSAL_Models_ActiveRecord[] Execute query and return data as $ar_cls objects.
|
84 |
-
*/
|
85 |
-
public function Execute($query)
|
86 |
-
{
|
87 |
-
$args = array();
|
88 |
-
$sql = $this->GetSql($query, $args);
|
89 |
-
|
90 |
-
$occurenceAdapter = $query->getConnector()->getAdapter("Occurrence");
|
91 |
-
|
92 |
-
if (in_array($occurenceAdapter->GetTable(), $query->getFrom())) {
|
93 |
-
return $occurenceAdapter->LoadMulti($sql, $args);
|
94 |
-
} else {
|
95 |
-
return $this->getActiveRecordAdapter()->LoadMulti($sql, $args);
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* @return int Use query for counting records.
|
101 |
-
*/
|
102 |
-
public function Count($query)
|
103 |
-
{
|
104 |
-
// back up columns, use COUNT as default column and generate sql
|
105 |
-
$cols = $query->getColumns();
|
106 |
-
$query->clearColumns();
|
107 |
-
$query->addColumn('COUNT(*)');
|
108 |
-
|
109 |
-
$args = array();
|
110 |
-
$sql = $this->GetSql($query, $args);
|
111 |
-
|
112 |
-
// restore columns
|
113 |
-
$query->setColumns($cols);
|
114 |
-
// execute query and return result
|
115 |
-
return $this->getActiveRecordAdapter()->CountQuery($sql, $args);
|
116 |
-
}
|
117 |
-
|
118 |
-
public function CountDelete($query)
|
119 |
-
{
|
120 |
-
$result = $this->GetSqlDelete($query, true);
|
121 |
-
// execute query and return result
|
122 |
-
return $this->getActiveRecordAdapter()->CountQuery($result['sql'], $result['args']);
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Use query for deleting records.
|
127 |
-
*/
|
128 |
-
public function Delete($query)
|
129 |
-
{
|
130 |
-
$result = $this->GetSqlDelete($query);
|
131 |
-
$this->DeleteMetas($query, $result['args']);
|
132 |
-
return $this->getActiveRecordAdapter()->DeleteQuery($result['sql'], $result['args']);
|
133 |
-
}
|
134 |
-
|
135 |
-
public function DeleteMetas($query, $args)
|
136 |
-
{
|
137 |
-
// back up columns, use COUNT as default column and generate sql
|
138 |
-
$cols = $query->getColumns();
|
139 |
-
$query->clearColumns();
|
140 |
-
$query->addColumn('id');
|
141 |
-
$sql = $this->GetSql($query);
|
142 |
-
// restore columns
|
143 |
-
$query->setColumns($cols);
|
144 |
-
|
145 |
-
$_wpdb = $this->connection;
|
146 |
-
$occ_ids = array();
|
147 |
-
$sql = (!empty($args) ? $_wpdb->prepare($sql, $args) : $sql);
|
148 |
-
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
149 |
-
$occ_ids[] = $data['id'];
|
150 |
-
}
|
151 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
152 |
-
$meta->DeleteByOccurenceIds($occ_ids);
|
153 |
-
}
|
154 |
-
|
155 |
-
public function GetSqlDelete($query, $getCount = false)
|
156 |
-
{
|
157 |
-
$result = array();
|
158 |
-
$args = array();
|
159 |
-
// back up columns, remove them for DELETE and generate sql
|
160 |
-
$cols = $query->getColumns();
|
161 |
-
$query->clearColumns();
|
162 |
-
|
163 |
-
$conditions = $query->getConditions();
|
164 |
-
|
165 |
-
$sWhereClause = "";
|
166 |
-
foreach ($conditions as $fieldName => $fieldValue) {
|
167 |
-
if (empty($sWhereClause)) {
|
168 |
-
$sWhereClause .= " WHERE ";
|
169 |
-
} else {
|
170 |
-
$sWhereClause .= " AND ";
|
171 |
-
}
|
172 |
-
$sWhereClause .= $fieldName;
|
173 |
-
$args[] = $fieldValue;
|
174 |
-
}
|
175 |
-
|
176 |
-
$fromDataSets = $query->getFrom();
|
177 |
-
$orderBys = $query->getOrderBy();
|
178 |
-
|
179 |
-
$sLimitClause = "";
|
180 |
-
if ($query->getLimit()) {
|
181 |
-
$sLimitClause .= " LIMIT ";
|
182 |
-
if ($query->getOffset()) {
|
183 |
-
$sLimitClause .= $query->getOffset() . ", ";
|
184 |
-
}
|
185 |
-
$sLimitClause .= $query->getLimit();
|
186 |
-
}
|
187 |
-
$result['sql'] = ($getCount ? 'SELECT COUNT(*) FROM ' : 'DELETE FROM ')
|
188 |
-
. implode(',', $fromDataSets)
|
189 |
-
. $sWhereClause
|
190 |
-
. (!empty($orderBys) ? (' ORDER BY ' . implode(', ', array_keys($orderBys)) . ' ' . implode(', ', array_values($orderBys))) : '')
|
191 |
-
. $sLimitClause;
|
192 |
-
$result['args'] = $args;
|
193 |
-
//restore columns
|
194 |
-
$query->setColumns($cols);
|
195 |
-
|
196 |
-
return $result;
|
197 |
-
}
|
198 |
-
|
199 |
-
public function SearchCondition($query)
|
200 |
-
{
|
201 |
-
$condition = $query->getSearchCondition();
|
202 |
-
if (empty($condition)) return null;
|
203 |
-
$searchConditions = array();
|
204 |
-
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
205 |
-
$occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
|
206 |
-
if (is_numeric($condition) && strlen($condition) == 4) {
|
207 |
-
$searchConditions['sql'] = $occurrence->GetTable() .'.alert_id LIKE %s';
|
208 |
-
} else {
|
209 |
-
$searchConditions['sql'] = $occurrence->GetTable() .'.id IN (
|
210 |
-
SELECT DISTINCT occurrence_id
|
211 |
-
FROM ' . $meta->GetTable() . '
|
212 |
-
WHERE TRIM(BOTH "\"" FROM value) LIKE %s
|
213 |
-
)';
|
214 |
-
}
|
215 |
-
$searchConditions['args'] = "%". $condition. "%";
|
216 |
-
return $searchConditions;
|
217 |
-
}
|
218 |
-
|
219 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Adapters_MySQL_Query implements WSAL_Adapters_QueryInterface
|
4 |
+
{
|
5 |
+
protected $connection;
|
6 |
+
|
7 |
+
public function __construct($conn)
|
8 |
+
{
|
9 |
+
$this->connection = $conn;
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @return string Generated sql.
|
14 |
+
*/
|
15 |
+
protected function GetSql($query, &$args = array())
|
16 |
+
{
|
17 |
+
$conditions = $query->getConditions();
|
18 |
+
$searchCondition = $this->SearchCondition($query);
|
19 |
+
|
20 |
+
$sWhereClause = "";
|
21 |
+
foreach ($conditions as $fieldName => $fieldValue) {
|
22 |
+
if (empty($sWhereClause)) {
|
23 |
+
$sWhereClause .= " WHERE ";
|
24 |
+
} else {
|
25 |
+
$sWhereClause .= " AND ";
|
26 |
+
}
|
27 |
+
|
28 |
+
if (is_array($fieldValue)) {
|
29 |
+
$subWhereClause = "(";
|
30 |
+
foreach($fieldValue as $orFieldName => $orFieldValue) {
|
31 |
+
if ($subWhereClause != '(') {
|
32 |
+
$subWhereClause .= " OR ";
|
33 |
+
}
|
34 |
+
$subWhereClause .= $orFieldName;
|
35 |
+
$args[] = $orFieldValue;
|
36 |
+
}
|
37 |
+
$subWhereClause .= ")";
|
38 |
+
$sWhereClause .= $subWhereClause;
|
39 |
+
} else {
|
40 |
+
$sWhereClause .= $fieldName;
|
41 |
+
$args[] = $fieldValue;
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
$fromDataSets = $query->getFrom();
|
46 |
+
$columns = $query->getColumns();
|
47 |
+
$orderBys = $query->getOrderBy();
|
48 |
+
|
49 |
+
$sLimitClause = "";
|
50 |
+
if ($query->getLimit()) {
|
51 |
+
$sLimitClause .= " LIMIT ";
|
52 |
+
if ($query->getOffset()) {
|
53 |
+
$sLimitClause .= $query->getOffset() . ", ";
|
54 |
+
}
|
55 |
+
$sLimitClause .= $query->getLimit();
|
56 |
+
}
|
57 |
+
$joinClause = '';
|
58 |
+
if ($query->hasMetaJoin()) {
|
59 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
60 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
|
61 |
+
$joinClause = ' LEFT JOIN '. $meta->GetTable() .' AS meta ON meta.occurrence_id = '. $occurrence->GetTable() .'.id ';
|
62 |
+
}
|
63 |
+
$fields = (empty($columns))? $fromDataSets[0] . '.*' : implode(',', $columns);
|
64 |
+
if (!empty($searchCondition)) {
|
65 |
+
$args[] = $searchCondition['args'];
|
66 |
+
}
|
67 |
+
return 'SELECT ' . $fields
|
68 |
+
. ' FROM ' . implode(',', $fromDataSets)
|
69 |
+
. $joinClause
|
70 |
+
. $sWhereClause
|
71 |
+
. (!empty($searchCondition) ? (empty($sWhereClause) ? " WHERE ".$searchCondition['sql'] : " AND ".$searchCondition['sql']) : '')
|
72 |
+
// @todo GROUP BY goes here
|
73 |
+
. (!empty($orderBys) ? (' ORDER BY ' . implode(', ', array_keys($orderBys)) . ' ' . implode(', ', array_values($orderBys))) : '')
|
74 |
+
. $sLimitClause;
|
75 |
+
}
|
76 |
+
|
77 |
+
protected function getActiveRecordAdapter()
|
78 |
+
{
|
79 |
+
return new WSAL_Adapters_MySQL_ActiveRecord($this->connection);
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @return WSAL_Models_ActiveRecord[] Execute query and return data as $ar_cls objects.
|
84 |
+
*/
|
85 |
+
public function Execute($query)
|
86 |
+
{
|
87 |
+
$args = array();
|
88 |
+
$sql = $this->GetSql($query, $args);
|
89 |
+
|
90 |
+
$occurenceAdapter = $query->getConnector()->getAdapter("Occurrence");
|
91 |
+
|
92 |
+
if (in_array($occurenceAdapter->GetTable(), $query->getFrom())) {
|
93 |
+
return $occurenceAdapter->LoadMulti($sql, $args);
|
94 |
+
} else {
|
95 |
+
return $this->getActiveRecordAdapter()->LoadMulti($sql, $args);
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @return int Use query for counting records.
|
101 |
+
*/
|
102 |
+
public function Count($query)
|
103 |
+
{
|
104 |
+
// back up columns, use COUNT as default column and generate sql
|
105 |
+
$cols = $query->getColumns();
|
106 |
+
$query->clearColumns();
|
107 |
+
$query->addColumn('COUNT(*)');
|
108 |
+
|
109 |
+
$args = array();
|
110 |
+
$sql = $this->GetSql($query, $args);
|
111 |
+
|
112 |
+
// restore columns
|
113 |
+
$query->setColumns($cols);
|
114 |
+
// execute query and return result
|
115 |
+
return $this->getActiveRecordAdapter()->CountQuery($sql, $args);
|
116 |
+
}
|
117 |
+
|
118 |
+
public function CountDelete($query)
|
119 |
+
{
|
120 |
+
$result = $this->GetSqlDelete($query, true);
|
121 |
+
// execute query and return result
|
122 |
+
return $this->getActiveRecordAdapter()->CountQuery($result['sql'], $result['args']);
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Use query for deleting records.
|
127 |
+
*/
|
128 |
+
public function Delete($query)
|
129 |
+
{
|
130 |
+
$result = $this->GetSqlDelete($query);
|
131 |
+
$this->DeleteMetas($query, $result['args']);
|
132 |
+
return $this->getActiveRecordAdapter()->DeleteQuery($result['sql'], $result['args']);
|
133 |
+
}
|
134 |
+
|
135 |
+
public function DeleteMetas($query, $args)
|
136 |
+
{
|
137 |
+
// back up columns, use COUNT as default column and generate sql
|
138 |
+
$cols = $query->getColumns();
|
139 |
+
$query->clearColumns();
|
140 |
+
$query->addColumn('id');
|
141 |
+
$sql = $this->GetSql($query);
|
142 |
+
// restore columns
|
143 |
+
$query->setColumns($cols);
|
144 |
+
|
145 |
+
$_wpdb = $this->connection;
|
146 |
+
$occ_ids = array();
|
147 |
+
$sql = (!empty($args) ? $_wpdb->prepare($sql, $args) : $sql);
|
148 |
+
foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
|
149 |
+
$occ_ids[] = $data['id'];
|
150 |
+
}
|
151 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
152 |
+
$meta->DeleteByOccurenceIds($occ_ids);
|
153 |
+
}
|
154 |
+
|
155 |
+
public function GetSqlDelete($query, $getCount = false)
|
156 |
+
{
|
157 |
+
$result = array();
|
158 |
+
$args = array();
|
159 |
+
// back up columns, remove them for DELETE and generate sql
|
160 |
+
$cols = $query->getColumns();
|
161 |
+
$query->clearColumns();
|
162 |
+
|
163 |
+
$conditions = $query->getConditions();
|
164 |
+
|
165 |
+
$sWhereClause = "";
|
166 |
+
foreach ($conditions as $fieldName => $fieldValue) {
|
167 |
+
if (empty($sWhereClause)) {
|
168 |
+
$sWhereClause .= " WHERE ";
|
169 |
+
} else {
|
170 |
+
$sWhereClause .= " AND ";
|
171 |
+
}
|
172 |
+
$sWhereClause .= $fieldName;
|
173 |
+
$args[] = $fieldValue;
|
174 |
+
}
|
175 |
+
|
176 |
+
$fromDataSets = $query->getFrom();
|
177 |
+
$orderBys = $query->getOrderBy();
|
178 |
+
|
179 |
+
$sLimitClause = "";
|
180 |
+
if ($query->getLimit()) {
|
181 |
+
$sLimitClause .= " LIMIT ";
|
182 |
+
if ($query->getOffset()) {
|
183 |
+
$sLimitClause .= $query->getOffset() . ", ";
|
184 |
+
}
|
185 |
+
$sLimitClause .= $query->getLimit();
|
186 |
+
}
|
187 |
+
$result['sql'] = ($getCount ? 'SELECT COUNT(*) FROM ' : 'DELETE FROM ')
|
188 |
+
. implode(',', $fromDataSets)
|
189 |
+
. $sWhereClause
|
190 |
+
. (!empty($orderBys) ? (' ORDER BY ' . implode(', ', array_keys($orderBys)) . ' ' . implode(', ', array_values($orderBys))) : '')
|
191 |
+
. $sLimitClause;
|
192 |
+
$result['args'] = $args;
|
193 |
+
//restore columns
|
194 |
+
$query->setColumns($cols);
|
195 |
+
|
196 |
+
return $result;
|
197 |
+
}
|
198 |
+
|
199 |
+
public function SearchCondition($query)
|
200 |
+
{
|
201 |
+
$condition = $query->getSearchCondition();
|
202 |
+
if (empty($condition)) return null;
|
203 |
+
$searchConditions = array();
|
204 |
+
$meta = new WSAL_Adapters_MySQL_Meta($this->connection);
|
205 |
+
$occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
|
206 |
+
if (is_numeric($condition) && strlen($condition) == 4) {
|
207 |
+
$searchConditions['sql'] = $occurrence->GetTable() .'.alert_id LIKE %s';
|
208 |
+
} else {
|
209 |
+
$searchConditions['sql'] = $occurrence->GetTable() .'.id IN (
|
210 |
+
SELECT DISTINCT occurrence_id
|
211 |
+
FROM ' . $meta->GetTable() . '
|
212 |
+
WHERE TRIM(BOTH "\"" FROM value) LIKE %s
|
213 |
+
)';
|
214 |
+
}
|
215 |
+
$searchConditions['args'] = "%". $condition. "%";
|
216 |
+
return $searchConditions;
|
217 |
+
}
|
218 |
+
|
219 |
+
}
|
classes/Models/Adapters/OccurrenceInterface.php
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
interface WSAL_Adapters_OccurrenceInterface
|
4 |
-
{
|
5 |
-
public function GetMeta($occurence);
|
6 |
-
public function GetNamedMeta($occurence, $name);
|
7 |
-
public function GetFirstNamedMeta($occurence, $names);
|
8 |
-
public static function GetNewestUnique($limit = PHP_INT_MAX);
|
9 |
-
public function CheckKnownUsers($args = array());
|
10 |
-
public function CheckUnKnownUsers($args = array());
|
11 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface WSAL_Adapters_OccurrenceInterface
|
4 |
+
{
|
5 |
+
public function GetMeta($occurence);
|
6 |
+
public function GetNamedMeta($occurence, $name);
|
7 |
+
public function GetFirstNamedMeta($occurence, $names);
|
8 |
+
public static function GetNewestUnique($limit = PHP_INT_MAX);
|
9 |
+
public function CheckKnownUsers($args = array());
|
10 |
+
public function CheckUnKnownUsers($args = array());
|
11 |
+
}
|
classes/Models/Adapters/QueryInterface.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
interface WSAL_Adapters_QueryInterface
|
4 |
-
{
|
5 |
-
public function Execute($query);
|
6 |
-
public function Count($query);
|
7 |
-
public function Delete($query);
|
8 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
interface WSAL_Adapters_QueryInterface
|
4 |
+
{
|
5 |
+
public function Execute($query);
|
6 |
+
public function Count($query);
|
7 |
+
public function Delete($query);
|
8 |
+
}
|
classes/Models/Meta.php
CHANGED
@@ -1,34 +1,34 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
4 |
-
|
5 |
-
protected $adapterName = "Meta";
|
6 |
-
|
7 |
-
public $id = 0;
|
8 |
-
public $occurrence_id = 0;
|
9 |
-
public $name = '';
|
10 |
-
public $value = array(); // force mixed type
|
11 |
-
|
12 |
-
public function SaveMeta()
|
13 |
-
{
|
14 |
-
$this->_state = self::STATE_UNKNOWN;
|
15 |
-
$updateId = $this->getId();
|
16 |
-
$result = $this->getAdapter()->Save($this);
|
17 |
-
|
18 |
-
if ($result !== false) {
|
19 |
-
$this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
|
20 |
-
}
|
21 |
-
return $result;
|
22 |
-
}
|
23 |
-
|
24 |
-
public function UpdateByNameAndOccurenceId($name, $value, $occurrenceId)
|
25 |
-
{
|
26 |
-
$meta = $this->getAdapter()->LoadByNameAndOccurenceId($name, $occurrenceId);
|
27 |
-
$this->id = $meta['id'];
|
28 |
-
$this->occurrence_id = $meta['occurrence_id'];
|
29 |
-
$this->name = $meta['name'];
|
30 |
-
$this->value = $value;
|
31 |
-
$this->saveMeta();
|
32 |
-
}
|
33 |
-
|
34 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Models_Meta extends WSAL_Models_ActiveRecord {
|
4 |
+
|
5 |
+
protected $adapterName = "Meta";
|
6 |
+
|
7 |
+
public $id = 0;
|
8 |
+
public $occurrence_id = 0;
|
9 |
+
public $name = '';
|
10 |
+
public $value = array(); // force mixed type
|
11 |
+
|
12 |
+
public function SaveMeta()
|
13 |
+
{
|
14 |
+
$this->_state = self::STATE_UNKNOWN;
|
15 |
+
$updateId = $this->getId();
|
16 |
+
$result = $this->getAdapter()->Save($this);
|
17 |
+
|
18 |
+
if ($result !== false) {
|
19 |
+
$this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
|
20 |
+
}
|
21 |
+
return $result;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function UpdateByNameAndOccurenceId($name, $value, $occurrenceId)
|
25 |
+
{
|
26 |
+
$meta = $this->getAdapter()->LoadByNameAndOccurenceId($name, $occurrenceId);
|
27 |
+
$this->id = $meta['id'];
|
28 |
+
$this->occurrence_id = $meta['occurrence_id'];
|
29 |
+
$this->name = $meta['name'];
|
30 |
+
$this->value = $value;
|
31 |
+
$this->saveMeta();
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
classes/Models/Occurrence.php
CHANGED
@@ -1,199 +1,199 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord
|
4 |
-
{
|
5 |
-
public $id = 0;
|
6 |
-
public $site_id = 0;
|
7 |
-
public $alert_id = 0;
|
8 |
-
public $created_on = 0.0;
|
9 |
-
public $is_read = false;
|
10 |
-
public $is_migrated = false;
|
11 |
-
protected $adapterName = "Occurrence";
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Returns the alert related to this occurrence.
|
15 |
-
* @return WSAL_Alert
|
16 |
-
*/
|
17 |
-
public function GetAlert()
|
18 |
-
{
|
19 |
-
return WpSecurityAuditLog::GetInstance()->alerts->GetAlert($this->alert_id);
|
20 |
-
}
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Returns the value of a meta item.
|
24 |
-
* @param string $name Name of meta item.
|
25 |
-
* @param mixed $default Default value returned when meta does not exist.
|
26 |
-
* @return mixed The value, if meta item does not exist $default returned.
|
27 |
-
*/
|
28 |
-
public function GetMetaValue($name, $default = array())
|
29 |
-
{
|
30 |
-
//get meta adapter
|
31 |
-
//call the function ($name, $this->getId())
|
32 |
-
$meta = $this->getAdapter()->GetNamedMeta($this, $name);
|
33 |
-
return maybe_unserialize($meta['value']);
|
34 |
-
|
35 |
-
//TO DO: re-introduce add is loaded check before running query
|
36 |
-
//return $meta->IsLoaded() ? $meta->value : $default;
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Set the value of a meta item (creates or updates meta item).
|
41 |
-
* @param string $name Meta name.
|
42 |
-
* @param mixed $value Meta value.
|
43 |
-
*/
|
44 |
-
public function SetMetaValue($name, $value)
|
45 |
-
{
|
46 |
-
if (!empty($value)) {
|
47 |
-
// get meta adapter
|
48 |
-
$model = new WSAL_Models_Meta();
|
49 |
-
$model->occurrence_id = $this->getId();
|
50 |
-
$model->name = $name;
|
51 |
-
$model->value = maybe_serialize($value);
|
52 |
-
$model->SaveMeta();
|
53 |
-
}
|
54 |
-
}
|
55 |
-
|
56 |
-
public function UpdateMetaValue($name, $value)
|
57 |
-
{
|
58 |
-
$model = new WSAL_Models_Meta();
|
59 |
-
$model->UpdateByNameAndOccurenceId($name, $value, $this->getId());
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Returns a key-value pair of meta data.
|
64 |
-
* @return array
|
65 |
-
*/
|
66 |
-
public function GetMetaArray()
|
67 |
-
{
|
68 |
-
$result = array();
|
69 |
-
$metas = $this->getAdapter()->GetMultiMeta($this);
|
70 |
-
foreach ($metas as $meta) {
|
71 |
-
$result[$meta->name] = maybe_unserialize($meta->value);
|
72 |
-
}
|
73 |
-
return $result;
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Creates or updates all meta data passed as an array of meta-key/meta-value pairs.
|
78 |
-
* @param array $data New meta data.
|
79 |
-
*/
|
80 |
-
public function SetMeta($data)
|
81 |
-
{
|
82 |
-
foreach ((array)$data as $key => $val) {
|
83 |
-
$this->SetMetaValue($key, $val);
|
84 |
-
}
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* @param callable|null $metaFormatter (Optional) Meta formatter callback.
|
89 |
-
* @return string Full-formatted message.
|
90 |
-
*/
|
91 |
-
public function GetMessage($metaFormatter = null)
|
92 |
-
{
|
93 |
-
if (!isset($this->_cachedmessage)) {
|
94 |
-
// get correct message entry
|
95 |
-
if ($this->is_migrated) {
|
96 |
-
$this->_cachedmessage = $this->GetMetaValue('MigratedMesg', false);
|
97 |
-
}
|
98 |
-
if (!$this->is_migrated || !$this->_cachedmessage) {
|
99 |
-
$this->_cachedmessage = $this->GetAlert()->mesg;
|
100 |
-
}
|
101 |
-
// fill variables in message
|
102 |
-
$this->_cachedmessage = $this->GetAlert()->GetMessage($this->GetMetaArray(), $metaFormatter, $this->_cachedmessage);
|
103 |
-
}
|
104 |
-
return $this->_cachedmessage;
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Delete occurrence as well as associated meta data.
|
109 |
-
* @return boolean True on success, false on failure.
|
110 |
-
*/
|
111 |
-
public function Delete()
|
112 |
-
{
|
113 |
-
foreach ($this->getAdapter()->GetMeta() as $meta) {
|
114 |
-
$meta->Delete();
|
115 |
-
}
|
116 |
-
return parent::Delete();
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* @return string User's username.
|
121 |
-
*/
|
122 |
-
public function GetUsername()
|
123 |
-
{
|
124 |
-
$meta = $this->getAdapter()->GetFirstNamedMeta($this, array('Username', 'CurrentUserID'));
|
125 |
-
if ($meta) {
|
126 |
-
switch (true) {
|
127 |
-
case $meta->name == 'Username':
|
128 |
-
return $meta->value;
|
129 |
-
case $meta->name == 'CurrentUserID':
|
130 |
-
return ($data = get_userdata($meta->value)) ? $data->user_login : null;
|
131 |
-
}
|
132 |
-
}
|
133 |
-
return null;
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* @return string IP address of request.
|
138 |
-
*/
|
139 |
-
public function GetSourceIP()
|
140 |
-
{
|
141 |
-
return $this->GetMetaValue('ClientIP', '');
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* @return string IP address of request (from proxies etc).
|
146 |
-
*/
|
147 |
-
public function GetOtherIPs()
|
148 |
-
{
|
149 |
-
$result = array();
|
150 |
-
$data = (array)$this->GetMetaValue('OtherIPs', array());
|
151 |
-
foreach ($data as $ips) {
|
152 |
-
foreach ($ips as $ip) {
|
153 |
-
$result[] = $ip;
|
154 |
-
}
|
155 |
-
}
|
156 |
-
return array_unique($result);
|
157 |
-
}
|
158 |
-
|
159 |
-
/**
|
160 |
-
* @return array Array of user roles.
|
161 |
-
*/
|
162 |
-
public function GetUserRoles()
|
163 |
-
{
|
164 |
-
return $this->GetMetaValue('CurrentUserRoles', array());
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* @return float Number of seconds (and microseconds as fraction) since unix Day 0.
|
169 |
-
* @todo This needs some caching.
|
170 |
-
*/
|
171 |
-
protected function GetMicrotime()
|
172 |
-
{
|
173 |
-
return microtime(true);// + get_option('gmt_offset') * HOUR_IN_SECONDS;
|
174 |
-
}
|
175 |
-
|
176 |
-
/**
|
177 |
-
* Finds occurences of the same type by IP and Username within specified time frame
|
178 |
-
* @param string $ipAddress
|
179 |
-
* @param string $username
|
180 |
-
* @param int $alertId Alert type we are lookign for
|
181 |
-
* @param int $siteId
|
182 |
-
* @param $startTime mktime
|
183 |
-
* @param $endTime mktime
|
184 |
-
*/
|
185 |
-
public function CheckKnownUsers($args = array())
|
186 |
-
{
|
187 |
-
return $this->getAdapter()->CheckKnownUsers($args);
|
188 |
-
}
|
189 |
-
|
190 |
-
public function CheckUnKnownUsers($args = array())
|
191 |
-
{
|
192 |
-
return $this->getAdapter()->CheckUnKnownUsers($args);
|
193 |
-
}
|
194 |
-
|
195 |
-
public function GetByPostID($post_id)
|
196 |
-
{
|
197 |
-
return $this->getAdapter()->GetByPostID($post_id);
|
198 |
-
}
|
199 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord
|
4 |
+
{
|
5 |
+
public $id = 0;
|
6 |
+
public $site_id = 0;
|
7 |
+
public $alert_id = 0;
|
8 |
+
public $created_on = 0.0;
|
9 |
+
public $is_read = false;
|
10 |
+
public $is_migrated = false;
|
11 |
+
protected $adapterName = "Occurrence";
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Returns the alert related to this occurrence.
|
15 |
+
* @return WSAL_Alert
|
16 |
+
*/
|
17 |
+
public function GetAlert()
|
18 |
+
{
|
19 |
+
return WpSecurityAuditLog::GetInstance()->alerts->GetAlert($this->alert_id);
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Returns the value of a meta item.
|
24 |
+
* @param string $name Name of meta item.
|
25 |
+
* @param mixed $default Default value returned when meta does not exist.
|
26 |
+
* @return mixed The value, if meta item does not exist $default returned.
|
27 |
+
*/
|
28 |
+
public function GetMetaValue($name, $default = array())
|
29 |
+
{
|
30 |
+
//get meta adapter
|
31 |
+
//call the function ($name, $this->getId())
|
32 |
+
$meta = $this->getAdapter()->GetNamedMeta($this, $name);
|
33 |
+
return maybe_unserialize($meta['value']);
|
34 |
+
|
35 |
+
//TO DO: re-introduce add is loaded check before running query
|
36 |
+
//return $meta->IsLoaded() ? $meta->value : $default;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Set the value of a meta item (creates or updates meta item).
|
41 |
+
* @param string $name Meta name.
|
42 |
+
* @param mixed $value Meta value.
|
43 |
+
*/
|
44 |
+
public function SetMetaValue($name, $value)
|
45 |
+
{
|
46 |
+
if (!empty($value)) {
|
47 |
+
// get meta adapter
|
48 |
+
$model = new WSAL_Models_Meta();
|
49 |
+
$model->occurrence_id = $this->getId();
|
50 |
+
$model->name = $name;
|
51 |
+
$model->value = maybe_serialize($value);
|
52 |
+
$model->SaveMeta();
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
public function UpdateMetaValue($name, $value)
|
57 |
+
{
|
58 |
+
$model = new WSAL_Models_Meta();
|
59 |
+
$model->UpdateByNameAndOccurenceId($name, $value, $this->getId());
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Returns a key-value pair of meta data.
|
64 |
+
* @return array
|
65 |
+
*/
|
66 |
+
public function GetMetaArray()
|
67 |
+
{
|
68 |
+
$result = array();
|
69 |
+
$metas = $this->getAdapter()->GetMultiMeta($this);
|
70 |
+
foreach ($metas as $meta) {
|
71 |
+
$result[$meta->name] = maybe_unserialize($meta->value);
|
72 |
+
}
|
73 |
+
return $result;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Creates or updates all meta data passed as an array of meta-key/meta-value pairs.
|
78 |
+
* @param array $data New meta data.
|
79 |
+
*/
|
80 |
+
public function SetMeta($data)
|
81 |
+
{
|
82 |
+
foreach ((array)$data as $key => $val) {
|
83 |
+
$this->SetMetaValue($key, $val);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param callable|null $metaFormatter (Optional) Meta formatter callback.
|
89 |
+
* @return string Full-formatted message.
|
90 |
+
*/
|
91 |
+
public function GetMessage($metaFormatter = null)
|
92 |
+
{
|
93 |
+
if (!isset($this->_cachedmessage)) {
|
94 |
+
// get correct message entry
|
95 |
+
if ($this->is_migrated) {
|
96 |
+
$this->_cachedmessage = $this->GetMetaValue('MigratedMesg', false);
|
97 |
+
}
|
98 |
+
if (!$this->is_migrated || !$this->_cachedmessage) {
|
99 |
+
$this->_cachedmessage = $this->GetAlert()->mesg;
|
100 |
+
}
|
101 |
+
// fill variables in message
|
102 |
+
$this->_cachedmessage = $this->GetAlert()->GetMessage($this->GetMetaArray(), $metaFormatter, $this->_cachedmessage);
|
103 |
+
}
|
104 |
+
return $this->_cachedmessage;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Delete occurrence as well as associated meta data.
|
109 |
+
* @return boolean True on success, false on failure.
|
110 |
+
*/
|
111 |
+
public function Delete()
|
112 |
+
{
|
113 |
+
foreach ($this->getAdapter()->GetMeta() as $meta) {
|
114 |
+
$meta->Delete();
|
115 |
+
}
|
116 |
+
return parent::Delete();
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* @return string User's username.
|
121 |
+
*/
|
122 |
+
public function GetUsername()
|
123 |
+
{
|
124 |
+
$meta = $this->getAdapter()->GetFirstNamedMeta($this, array('Username', 'CurrentUserID'));
|
125 |
+
if ($meta) {
|
126 |
+
switch (true) {
|
127 |
+
case $meta->name == 'Username':
|
128 |
+
return $meta->value;
|
129 |
+
case $meta->name == 'CurrentUserID':
|
130 |
+
return ($data = get_userdata($meta->value)) ? $data->user_login : null;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
return null;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return string IP address of request.
|
138 |
+
*/
|
139 |
+
public function GetSourceIP()
|
140 |
+
{
|
141 |
+
return $this->GetMetaValue('ClientIP', '');
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @return string IP address of request (from proxies etc).
|
146 |
+
*/
|
147 |
+
public function GetOtherIPs()
|
148 |
+
{
|
149 |
+
$result = array();
|
150 |
+
$data = (array)$this->GetMetaValue('OtherIPs', array());
|
151 |
+
foreach ($data as $ips) {
|
152 |
+
foreach ($ips as $ip) {
|
153 |
+
$result[] = $ip;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
return array_unique($result);
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @return array Array of user roles.
|
161 |
+
*/
|
162 |
+
public function GetUserRoles()
|
163 |
+
{
|
164 |
+
return $this->GetMetaValue('CurrentUserRoles', array());
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @return float Number of seconds (and microseconds as fraction) since unix Day 0.
|
169 |
+
* @todo This needs some caching.
|
170 |
+
*/
|
171 |
+
protected function GetMicrotime()
|
172 |
+
{
|
173 |
+
return microtime(true);// + get_option('gmt_offset') * HOUR_IN_SECONDS;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Finds occurences of the same type by IP and Username within specified time frame
|
178 |
+
* @param string $ipAddress
|
179 |
+
* @param string $username
|
180 |
+
* @param int $alertId Alert type we are lookign for
|
181 |
+
* @param int $siteId
|
182 |
+
* @param $startTime mktime
|
183 |
+
* @param $endTime mktime
|
184 |
+
*/
|
185 |
+
public function CheckKnownUsers($args = array())
|
186 |
+
{
|
187 |
+
return $this->getAdapter()->CheckKnownUsers($args);
|
188 |
+
}
|
189 |
+
|
190 |
+
public function CheckUnKnownUsers($args = array())
|
191 |
+
{
|
192 |
+
return $this->getAdapter()->CheckUnKnownUsers($args);
|
193 |
+
}
|
194 |
+
|
195 |
+
public function GetByPostID($post_id)
|
196 |
+
{
|
197 |
+
return $this->getAdapter()->GetByPostID($post_id);
|
198 |
+
}
|
199 |
+
}
|
classes/Models/OccurrenceQuery.php
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Models_OccurrenceQuery extends WSAL_Models_Query
|
4 |
-
{
|
5 |
-
protected $arguments = array();
|
6 |
-
|
7 |
-
public function addArgument($field, $value)
|
8 |
-
{
|
9 |
-
$this->arguments[$field] = $value;
|
10 |
-
return $this;
|
11 |
-
}
|
12 |
-
|
13 |
-
public function clearArguments()
|
14 |
-
{
|
15 |
-
$this->arguments = array();
|
16 |
-
return $this;
|
17 |
-
}
|
18 |
-
|
19 |
-
public function __construct()
|
20 |
-
{
|
21 |
-
parent::__construct();
|
22 |
-
|
23 |
-
//TO DO: Consider if Get Table is the right method to call given that this is mysql specific
|
24 |
-
$this->addFrom(
|
25 |
-
$this->getConnector()->getAdapter("Occurrence")->GetTable()
|
26 |
-
);
|
27 |
-
}
|
28 |
-
|
29 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Models_OccurrenceQuery extends WSAL_Models_Query
|
4 |
+
{
|
5 |
+
protected $arguments = array();
|
6 |
+
|
7 |
+
public function addArgument($field, $value)
|
8 |
+
{
|
9 |
+
$this->arguments[$field] = $value;
|
10 |
+
return $this;
|
11 |
+
}
|
12 |
+
|
13 |
+
public function clearArguments()
|
14 |
+
{
|
15 |
+
$this->arguments = array();
|
16 |
+
return $this;
|
17 |
+
}
|
18 |
+
|
19 |
+
public function __construct()
|
20 |
+
{
|
21 |
+
parent::__construct();
|
22 |
+
|
23 |
+
//TO DO: Consider if Get Table is the right method to call given that this is mysql specific
|
24 |
+
$this->addFrom(
|
25 |
+
$this->getConnector()->getAdapter("Occurrence")->GetTable()
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
}
|
classes/Models/Option.php
CHANGED
@@ -1,80 +1,80 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Wordpress options are always loaded from the default wordpress database.
|
5 |
-
*/
|
6 |
-
class WSAL_Models_Option extends WSAL_Models_ActiveRecord
|
7 |
-
{
|
8 |
-
|
9 |
-
protected $adapterName = "Option";
|
10 |
-
public $id = '';
|
11 |
-
public $option_name = '';
|
12 |
-
public $option_value = '';
|
13 |
-
/**
|
14 |
-
* Options are always stored in WPDB. This setting ensures that
|
15 |
-
*/
|
16 |
-
protected $useDefaultAdapter = true;
|
17 |
-
|
18 |
-
public function SetOptionValue($name, $value)
|
19 |
-
{
|
20 |
-
$option = $this->getAdapter()->GetNamedOption($name);
|
21 |
-
$this->id = $option['id'];
|
22 |
-
$this->option_name = $name;
|
23 |
-
// Serialize if $value is array or object
|
24 |
-
$value = maybe_serialize($value);
|
25 |
-
$this->option_value = $value;
|
26 |
-
return $this->Save();
|
27 |
-
}
|
28 |
-
|
29 |
-
public function GetOptionValue($name, $default = array())
|
30 |
-
{
|
31 |
-
$option = $this->getAdapter()->GetNamedOption($name);
|
32 |
-
$this->option_value = (!empty($option)) ? $option['option_value'] : null;
|
33 |
-
if (!empty($this->option_value)) {
|
34 |
-
$this->_state = self::STATE_LOADED;
|
35 |
-
}
|
36 |
-
// Unerialize if $value is array or object
|
37 |
-
$this->option_value = maybe_unserialize($this->option_value);
|
38 |
-
return $this->IsLoaded() ? $this->option_value : $default;
|
39 |
-
}
|
40 |
-
|
41 |
-
public function Save()
|
42 |
-
{
|
43 |
-
$this->_state = self::STATE_UNKNOWN;
|
44 |
-
|
45 |
-
$updateId = $this->getId();
|
46 |
-
$result = $this->getAdapter()->Save($this);
|
47 |
-
|
48 |
-
if ($result !== false) {
|
49 |
-
$this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
|
50 |
-
}
|
51 |
-
return $result;
|
52 |
-
}
|
53 |
-
|
54 |
-
public function GetNotificationsSetting($opt_prefix)
|
55 |
-
{
|
56 |
-
return $this->getAdapter()->GetNotificationsSetting($opt_prefix);
|
57 |
-
}
|
58 |
-
|
59 |
-
public function GetNotification($id)
|
60 |
-
{
|
61 |
-
return $this->LoadData(
|
62 |
-
$this->getAdapter()->GetNotification($id)
|
63 |
-
);
|
64 |
-
}
|
65 |
-
|
66 |
-
public function DeleteByName($name)
|
67 |
-
{
|
68 |
-
return $this->getAdapter()->DeleteByName($name);
|
69 |
-
}
|
70 |
-
|
71 |
-
public function DeleteByPrefix($opt_prefix)
|
72 |
-
{
|
73 |
-
return $this->getAdapter()->DeleteByPrefix($opt_prefix);
|
74 |
-
}
|
75 |
-
|
76 |
-
public function CountNotifications($opt_prefix)
|
77 |
-
{
|
78 |
-
return $this->getAdapter()->CountNotifications($opt_prefix);
|
79 |
-
}
|
80 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Wordpress options are always loaded from the default wordpress database.
|
5 |
+
*/
|
6 |
+
class WSAL_Models_Option extends WSAL_Models_ActiveRecord
|
7 |
+
{
|
8 |
+
|
9 |
+
protected $adapterName = "Option";
|
10 |
+
public $id = '';
|
11 |
+
public $option_name = '';
|
12 |
+
public $option_value = '';
|
13 |
+
/**
|
14 |
+
* Options are always stored in WPDB. This setting ensures that
|
15 |
+
*/
|
16 |
+
protected $useDefaultAdapter = true;
|
17 |
+
|
18 |
+
public function SetOptionValue($name, $value)
|
19 |
+
{
|
20 |
+
$option = $this->getAdapter()->GetNamedOption($name);
|
21 |
+
$this->id = $option['id'];
|
22 |
+
$this->option_name = $name;
|
23 |
+
// Serialize if $value is array or object
|
24 |
+
$value = maybe_serialize($value);
|
25 |
+
$this->option_value = $value;
|
26 |
+
return $this->Save();
|
27 |
+
}
|
28 |
+
|
29 |
+
public function GetOptionValue($name, $default = array())
|
30 |
+
{
|
31 |
+
$option = $this->getAdapter()->GetNamedOption($name);
|
32 |
+
$this->option_value = (!empty($option)) ? $option['option_value'] : null;
|
33 |
+
if (!empty($this->option_value)) {
|
34 |
+
$this->_state = self::STATE_LOADED;
|
35 |
+
}
|
36 |
+
// Unerialize if $value is array or object
|
37 |
+
$this->option_value = maybe_unserialize($this->option_value);
|
38 |
+
return $this->IsLoaded() ? $this->option_value : $default;
|
39 |
+
}
|
40 |
+
|
41 |
+
public function Save()
|
42 |
+
{
|
43 |
+
$this->_state = self::STATE_UNKNOWN;
|
44 |
+
|
45 |
+
$updateId = $this->getId();
|
46 |
+
$result = $this->getAdapter()->Save($this);
|
47 |
+
|
48 |
+
if ($result !== false) {
|
49 |
+
$this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
|
50 |
+
}
|
51 |
+
return $result;
|
52 |
+
}
|
53 |
+
|
54 |
+
public function GetNotificationsSetting($opt_prefix)
|
55 |
+
{
|
56 |
+
return $this->getAdapter()->GetNotificationsSetting($opt_prefix);
|
57 |
+
}
|
58 |
+
|
59 |
+
public function GetNotification($id)
|
60 |
+
{
|
61 |
+
return $this->LoadData(
|
62 |
+
$this->getAdapter()->GetNotification($id)
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
public function DeleteByName($name)
|
67 |
+
{
|
68 |
+
return $this->getAdapter()->DeleteByName($name);
|
69 |
+
}
|
70 |
+
|
71 |
+
public function DeleteByPrefix($opt_prefix)
|
72 |
+
{
|
73 |
+
return $this->getAdapter()->DeleteByPrefix($opt_prefix);
|
74 |
+
}
|
75 |
+
|
76 |
+
public function CountNotifications($opt_prefix)
|
77 |
+
{
|
78 |
+
return $this->getAdapter()->CountNotifications($opt_prefix);
|
79 |
+
}
|
80 |
+
}
|
classes/Models/Query.php
CHANGED
@@ -1,187 +1,187 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Models_Query
|
4 |
-
{
|
5 |
-
protected $columns = array();
|
6 |
-
protected $conditions = array();
|
7 |
-
protected $orderBy = array();
|
8 |
-
protected $offset = null;
|
9 |
-
protected $limit = null;
|
10 |
-
protected $from = array();
|
11 |
-
protected $meta_join = false;
|
12 |
-
protected $searchCondition = null;
|
13 |
-
protected $useDefaultAdapter = false;
|
14 |
-
|
15 |
-
public function __construct()
|
16 |
-
{
|
17 |
-
|
18 |
-
}
|
19 |
-
|
20 |
-
public function getConnector()
|
21 |
-
{
|
22 |
-
if (!empty($this->connector)) {
|
23 |
-
return $this->connector;
|
24 |
-
}
|
25 |
-
if ($this->useDefaultAdapter) {
|
26 |
-
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
27 |
-
} else {
|
28 |
-
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
29 |
-
}
|
30 |
-
return $this->connector;
|
31 |
-
}
|
32 |
-
|
33 |
-
public function getAdapter()
|
34 |
-
{
|
35 |
-
return $this->getConnector()->getAdapter('Query');
|
36 |
-
}
|
37 |
-
|
38 |
-
public function addColumn($column)
|
39 |
-
{
|
40 |
-
$this->columns[] = $column;
|
41 |
-
return $this;
|
42 |
-
}
|
43 |
-
|
44 |
-
public function clearColumns()
|
45 |
-
{
|
46 |
-
$this->columns = array();
|
47 |
-
return $this;
|
48 |
-
}
|
49 |
-
|
50 |
-
public function getColumns()
|
51 |
-
{
|
52 |
-
return $this->columns;
|
53 |
-
}
|
54 |
-
|
55 |
-
public function setColumns($columns)
|
56 |
-
{
|
57 |
-
$this->columns = $columns;
|
58 |
-
return $this;
|
59 |
-
}
|
60 |
-
|
61 |
-
public function addCondition($field, $value)
|
62 |
-
{
|
63 |
-
$this->conditions[$field] = $value;
|
64 |
-
return $this;
|
65 |
-
}
|
66 |
-
|
67 |
-
public function addORCondition($aConditions)
|
68 |
-
{
|
69 |
-
$this->conditions[] = $aConditions;
|
70 |
-
}
|
71 |
-
|
72 |
-
public function clearConditions()
|
73 |
-
{
|
74 |
-
$this->conditions = array();
|
75 |
-
return $this;
|
76 |
-
}
|
77 |
-
|
78 |
-
public function getConditions()
|
79 |
-
{
|
80 |
-
return $this->conditions;
|
81 |
-
}
|
82 |
-
|
83 |
-
public function addOrderBy($field, $isDescending = false)
|
84 |
-
{
|
85 |
-
$order = ($isDescending) ? 'DESC' : 'ASC';
|
86 |
-
$this->orderBy[$field] = $order;
|
87 |
-
return $this;
|
88 |
-
}
|
89 |
-
|
90 |
-
public function clearOrderBy()
|
91 |
-
{
|
92 |
-
$this->orderBy = array();
|
93 |
-
return $this;
|
94 |
-
}
|
95 |
-
|
96 |
-
public function getOrderBy()
|
97 |
-
{
|
98 |
-
return $this->orderBy;
|
99 |
-
}
|
100 |
-
|
101 |
-
public function addFrom($fromDataSet)
|
102 |
-
{
|
103 |
-
$this->from[] = $fromDataSet;
|
104 |
-
return $this;
|
105 |
-
}
|
106 |
-
|
107 |
-
public function clearFrom()
|
108 |
-
{
|
109 |
-
$this->from = array();
|
110 |
-
return $this;
|
111 |
-
}
|
112 |
-
|
113 |
-
public function getFrom()
|
114 |
-
{
|
115 |
-
return $this->from;
|
116 |
-
}
|
117 |
-
|
118 |
-
/**
|
119 |
-
* Gets the value of limit.
|
120 |
-
*
|
121 |
-
* @return mixed
|
122 |
-
*/
|
123 |
-
public function getLimit()
|
124 |
-
{
|
125 |
-
return $this->limit;
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Sets the value of limit.
|
130 |
-
*
|
131 |
-
* @param mixed $limit the limit
|
132 |
-
*
|
133 |
-
* @return self
|
134 |
-
*/
|
135 |
-
public function setLimit($limit)
|
136 |
-
{
|
137 |
-
$this->limit = $limit;
|
138 |
-
|
139 |
-
return $this;
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Gets the value of offset.
|
144 |
-
*
|
145 |
-
* @return mixed
|
146 |
-
*/
|
147 |
-
public function getOffset()
|
148 |
-
{
|
149 |
-
return $this->offset;
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Sets the value of offset.
|
154 |
-
*
|
155 |
-
* @param mixed $offset the offset
|
156 |
-
*
|
157 |
-
* @return self
|
158 |
-
*/
|
159 |
-
public function setOffset($offset)
|
160 |
-
{
|
161 |
-
$this->offset = $offset;
|
162 |
-
|
163 |
-
return $this;
|
164 |
-
}
|
165 |
-
|
166 |
-
public function addSearchCondition($value)
|
167 |
-
{
|
168 |
-
$this->searchCondition = $value;
|
169 |
-
return $this;
|
170 |
-
}
|
171 |
-
|
172 |
-
public function getSearchCondition()
|
173 |
-
{
|
174 |
-
return $this->searchCondition;
|
175 |
-
}
|
176 |
-
|
177 |
-
public function hasMetaJoin()
|
178 |
-
{
|
179 |
-
return $this->meta_join;
|
180 |
-
}
|
181 |
-
|
182 |
-
public function addMetaJoin()
|
183 |
-
{
|
184 |
-
$this->meta_join = true;
|
185 |
-
return $this;
|
186 |
-
}
|
187 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Models_Query
|
4 |
+
{
|
5 |
+
protected $columns = array();
|
6 |
+
protected $conditions = array();
|
7 |
+
protected $orderBy = array();
|
8 |
+
protected $offset = null;
|
9 |
+
protected $limit = null;
|
10 |
+
protected $from = array();
|
11 |
+
protected $meta_join = false;
|
12 |
+
protected $searchCondition = null;
|
13 |
+
protected $useDefaultAdapter = false;
|
14 |
+
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
|
18 |
+
}
|
19 |
+
|
20 |
+
public function getConnector()
|
21 |
+
{
|
22 |
+
if (!empty($this->connector)) {
|
23 |
+
return $this->connector;
|
24 |
+
}
|
25 |
+
if ($this->useDefaultAdapter) {
|
26 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
|
27 |
+
} else {
|
28 |
+
$this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
|
29 |
+
}
|
30 |
+
return $this->connector;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function getAdapter()
|
34 |
+
{
|
35 |
+
return $this->getConnector()->getAdapter('Query');
|
36 |
+
}
|
37 |
+
|
38 |
+
public function addColumn($column)
|
39 |
+
{
|
40 |
+
$this->columns[] = $column;
|
41 |
+
return $this;
|
42 |
+
}
|
43 |
+
|
44 |
+
public function clearColumns()
|
45 |
+
{
|
46 |
+
$this->columns = array();
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
|
50 |
+
public function getColumns()
|
51 |
+
{
|
52 |
+
return $this->columns;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function setColumns($columns)
|
56 |
+
{
|
57 |
+
$this->columns = $columns;
|
58 |
+
return $this;
|
59 |
+
}
|
60 |
+
|
61 |
+
public function addCondition($field, $value)
|
62 |
+
{
|
63 |
+
$this->conditions[$field] = $value;
|
64 |
+
return $this;
|
65 |
+
}
|
66 |
+
|
67 |
+
public function addORCondition($aConditions)
|
68 |
+
{
|
69 |
+
$this->conditions[] = $aConditions;
|
70 |
+
}
|
71 |
+
|
72 |
+
public function clearConditions()
|
73 |
+
{
|
74 |
+
$this->conditions = array();
|
75 |
+
return $this;
|
76 |
+
}
|
77 |
+
|
78 |
+
public function getConditions()
|
79 |
+
{
|
80 |
+
return $this->conditions;
|
81 |
+
}
|
82 |
+
|
83 |
+
public function addOrderBy($field, $isDescending = false)
|
84 |
+
{
|
85 |
+
$order = ($isDescending) ? 'DESC' : 'ASC';
|
86 |
+
$this->orderBy[$field] = $order;
|
87 |
+
return $this;
|
88 |
+
}
|
89 |
+
|
90 |
+
public function clearOrderBy()
|
91 |
+
{
|
92 |
+
$this->orderBy = array();
|
93 |
+
return $this;
|
94 |
+
}
|
95 |
+
|
96 |
+
public function getOrderBy()
|
97 |
+
{
|
98 |
+
return $this->orderBy;
|
99 |
+
}
|
100 |
+
|
101 |
+
public function addFrom($fromDataSet)
|
102 |
+
{
|
103 |
+
$this->from[] = $fromDataSet;
|
104 |
+
return $this;
|
105 |
+
}
|
106 |
+
|
107 |
+
public function clearFrom()
|
108 |
+
{
|
109 |
+
$this->from = array();
|
110 |
+
return $this;
|
111 |
+
}
|
112 |
+
|
113 |
+
public function getFrom()
|
114 |
+
{
|
115 |
+
return $this->from;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Gets the value of limit.
|
120 |
+
*
|
121 |
+
* @return mixed
|
122 |
+
*/
|
123 |
+
public function getLimit()
|
124 |
+
{
|
125 |
+
return $this->limit;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Sets the value of limit.
|
130 |
+
*
|
131 |
+
* @param mixed $limit the limit
|
132 |
+
*
|
133 |
+
* @return self
|
134 |
+
*/
|
135 |
+
public function setLimit($limit)
|
136 |
+
{
|
137 |
+
$this->limit = $limit;
|
138 |
+
|
139 |
+
return $this;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Gets the value of offset.
|
144 |
+
*
|
145 |
+
* @return mixed
|
146 |
+
*/
|
147 |
+
public function getOffset()
|
148 |
+
{
|
149 |
+
return $this->offset;
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Sets the value of offset.
|
154 |
+
*
|
155 |
+
* @param mixed $offset the offset
|
156 |
+
*
|
157 |
+
* @return self
|
158 |
+
*/
|
159 |
+
public function setOffset($offset)
|
160 |
+
{
|
161 |
+
$this->offset = $offset;
|
162 |
+
|
163 |
+
return $this;
|
164 |
+
}
|
165 |
+
|
166 |
+
public function addSearchCondition($value)
|
167 |
+
{
|
168 |
+
$this->searchCondition = $value;
|
169 |
+
return $this;
|
170 |
+
}
|
171 |
+
|
172 |
+
public function getSearchCondition()
|
173 |
+
{
|
174 |
+
return $this->searchCondition;
|
175 |
+
}
|
176 |
+
|
177 |
+
public function hasMetaJoin()
|
178 |
+
{
|
179 |
+
return $this->meta_join;
|
180 |
+
}
|
181 |
+
|
182 |
+
public function addMetaJoin()
|
183 |
+
{
|
184 |
+
$this->meta_join = true;
|
185 |
+
return $this;
|
186 |
+
}
|
187 |
+
}
|
classes/Nicer.php
CHANGED
@@ -1,289 +1,289 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
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 |
-
protected $value;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Allows modification of CSS class prefix.
|
17 |
-
* @var string
|
18 |
-
*/
|
19 |
-
public $css_class = 'nice_r';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Allows modification of HTML id prefix.
|
23 |
-
* @var string
|
24 |
-
*/
|
25 |
-
public $html_id = 'nice_r_v';
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Allows modification of JS function used to toggle sections.
|
29 |
-
* @var string
|
30 |
-
*/
|
31 |
-
public $js_func = 'nice_r_toggle';
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Whether to inspect and output methods for objects or not.
|
35 |
-
* @var boolean
|
36 |
-
*/
|
37 |
-
public $inspect_methods = false;
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Since PHP does not support private constants, we'll have to settle for private static fields.
|
41 |
-
* @var string
|
42 |
-
*/
|
43 |
-
protected static $BEEN_THERE = '__NICE_R_INFINITE_RECURSION_PROTECT__';
|
44 |
-
|
45 |
-
protected $_has_reflection = null;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Constructs new renderer instance.
|
49 |
-
* @param mixed $value The value to inspect and render.
|
50 |
-
* @param boolean $inspectMethods Whether to inspect and output methods for objects or not.
|
51 |
-
*/
|
52 |
-
public function __construct($value, $inspectMethods = false){
|
53 |
-
$this->value = $value;
|
54 |
-
$this->inspect_methods = $inspectMethods;
|
55 |
-
|
56 |
-
if(is_null($this->_has_reflection))
|
57 |
-
$this->_has_reflection = class_exists('ReflectionClass');
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Generates the inspector HTML and returns it as a string.
|
62 |
-
* @return string Generated HTML.
|
63 |
-
*/
|
64 |
-
public function generate(){
|
65 |
-
return $this->_generate_value($this->value, $this->css_class);
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Renders the inspector HTML directly to the browser.
|
70 |
-
*/
|
71 |
-
public function render(){
|
72 |
-
echo $this->generate();
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Converts a string to HTML, encoding any special characters.
|
77 |
-
* @param string $text The original string.
|
78 |
-
* @return string The string as HTML.
|
79 |
-
*/
|
80 |
-
protected function _esc_html($text){
|
81 |
-
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
|
82 |
-
}
|
83 |
-
|
84 |
-
protected function _inspect_array(&$html, &$var){
|
85 |
-
$has_subitems = false;
|
86 |
-
|
87 |
-
foreach($var as $k => $v){
|
88 |
-
if($k !== self::$BEEN_THERE){
|
89 |
-
$html .= $this->_generate_keyvalue($k, $v);
|
90 |
-
$has_subitems = true;
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
if(!$has_subitems){
|
95 |
-
$html .= '<span class="'.$this->css_class.'_ni">Empty Array</span>';
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
protected function _inspect_object(&$html, &$var){
|
100 |
-
// render properties
|
101 |
-
$has_subitems = false;
|
102 |
-
|
103 |
-
foreach((array)$var as $k=>$v){
|
104 |
-
if($k !== self::$BEEN_THERE){
|
105 |
-
$html .= $this->_generate_keyvalue($k, $v);
|
106 |
-
$has_subitems = true;
|
107 |
-
}
|
108 |
-
}
|
109 |
-
|
110 |
-
if(!$has_subitems){
|
111 |
-
$html .= '<span class="'.$this->css_class.'_ni">No Properties</span>';
|
112 |
-
}
|
113 |
-
|
114 |
-
// render methods (if enabled)
|
115 |
-
if($this->inspect_methods){
|
116 |
-
$has_subitems = false;
|
117 |
-
|
118 |
-
foreach((array)get_class_methods($var) as $method){
|
119 |
-
$html .= $this->_generate_callable($var, $method);
|
120 |
-
$has_subitems = true;
|
121 |
-
}
|
122 |
-
|
123 |
-
if(!$has_subitems){
|
124 |
-
$html .= '<span class="'.$this->css_class.'_ni">No Methods</span>';
|
125 |
-
}
|
126 |
-
}
|
127 |
-
}
|
128 |
-
|
129 |
-
/**
|
130 |
-
* Render a single particular value.
|
131 |
-
* @param mixed $var The value to render
|
132 |
-
* @param string $class Parent CSS class.
|
133 |
-
* @param string $id Item HTML id.
|
134 |
-
*/
|
135 |
-
protected function _generate_value($var, $class = '', $id = ''){
|
136 |
-
$BEENTHERE = self::$BEEN_THERE;
|
137 |
-
$class .= ' '.$this->css_class.'_t_'.gettype($var);
|
138 |
-
|
139 |
-
$html = '<div id="'.$id.'" class="'.$class.'">';
|
140 |
-
|
141 |
-
switch(true){
|
142 |
-
|
143 |
-
// handle arrays
|
144 |
-
case is_array($var):
|
145 |
-
if(isset($var[$BEENTHERE])){
|
146 |
-
$html .= '<span class="'.$this->css_class.'_ir">Infinite Recursion Detected!</span>';
|
147 |
-
}else{
|
148 |
-
$var[$BEENTHERE] = true;
|
149 |
-
$this->_inspect_array($html, $var);
|
150 |
-
unset($var[$BEENTHERE]);
|
151 |
-
}
|
152 |
-
break;
|
153 |
-
|
154 |
-
// handle objects
|
155 |
-
case is_object($var):
|
156 |
-
if(isset($var->$BEENTHERE)){
|
157 |
-
$html .= '<span class="'.$this->css_class.'_ir">Infinite Recursion Detected!</span>';
|
158 |
-
}else{
|
159 |
-
$var->$BEENTHERE = true;
|
160 |
-
$this->_inspect_object($html, $var);
|
161 |
-
unset($var->$BEENTHERE);
|
162 |
-
}
|
163 |
-
break;
|
164 |
-
|
165 |
-
// handle simple types
|
166 |
-
default:
|
167 |
-
$html .= $this->_generate_keyvalue('', $var);
|
168 |
-
break;
|
169 |
-
}
|
170 |
-
|
171 |
-
return $html . '</div>';
|
172 |
-
}
|
173 |
-
|
174 |
-
/**
|
175 |
-
* Generates a new unique ID for tagging elements.
|
176 |
-
* @staticvar int $id
|
177 |
-
* @return integer An ID unique per request.
|
178 |
-
*/
|
179 |
-
protected function _generate_dropid(){
|
180 |
-
static $id = 0;
|
181 |
-
return ++$id;
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Render a key-value pair.
|
186 |
-
* @staticvar int $id Specifies element id.
|
187 |
-
* @param string $key Key name.
|
188 |
-
* @param mixed $val Key value.
|
189 |
-
*/
|
190 |
-
protected function _generate_keyvalue($key, $val){
|
191 |
-
$id = $this->_generate_dropid();
|
192 |
-
$p = ''; // preview
|
193 |
-
$d = ''; // description
|
194 |
-
$t = gettype($val); // get data type
|
195 |
-
$is_hash = ($t=='array') || ($t=='object');
|
196 |
-
|
197 |
-
switch($t){
|
198 |
-
case 'boolean':
|
199 |
-
$p = $val ? 'TRUE' : 'FALSE';
|
200 |
-
break;
|
201 |
-
case 'integer':
|
202 |
-
case 'double':
|
203 |
-
$p = (string)$val;
|
204 |
-
break;
|
205 |
-
case 'string':
|
206 |
-
$d .= ', '.strlen($val).' characters';
|
207 |
-
$p = $val;
|
208 |
-
break;
|
209 |
-
case 'resource':
|
210 |
-
$d .= ', '.get_resource_type($val).' type';
|
211 |
-
$p = (string)$val;
|
212 |
-
break;
|
213 |
-
case 'array':
|
214 |
-
$d .= ', '.count($val).' elements';
|
215 |
-
break;
|
216 |
-
case 'object':
|
217 |
-
$d .= ', '.get_class($val).', '.count(get_object_vars($val)).' properties';
|
218 |
-
break;
|
219 |
-
}
|
220 |
-
|
221 |
-
$cls = $this->css_class;
|
222 |
-
$xcls = !$is_hash ? $cls.'_ad' : '';
|
223 |
-
$html = '<a '.($is_hash?'href="javascript:;"':'').' onclick="'.$this->js_func.'(\''.$this->html_id.'\',\''.$id.'\');">';
|
224 |
-
$html .= ' <span class="'.$cls.'_a '.$xcls.'" id="'.$this->html_id.'_a'.$id.'">►</span>';
|
225 |
-
$html .= ' <span class="'.$cls.'_k">'.$this->_esc_html($key).'</span>';
|
226 |
-
$html .= ' <span class="'.$cls.'_d">(<span>'.ucwords($t).'</span>'.$d.')</span>';
|
227 |
-
$html .= ' <span class="'.$cls.'_p '.$cls.'_t_'.$t.'">'.$this->_esc_html($p).'</span>';
|
228 |
-
$html .= '</a>';
|
229 |
-
|
230 |
-
if($is_hash){
|
231 |
-
$html .= $this->_generate_value($val, $cls.'_v', $this->html_id.'_v'.$id);
|
232 |
-
}
|
233 |
-
|
234 |
-
return $html;
|
235 |
-
}
|
236 |
-
|
237 |
-
protected function _generate_callable($context, $callback){
|
238 |
-
$id = $this->_generate_dropid();
|
239 |
-
$ref = null;
|
240 |
-
$name = 'Anonymous';
|
241 |
-
$cls = $this->css_class;
|
242 |
-
|
243 |
-
if($this->_has_reflection){
|
244 |
-
if(is_null($context)){
|
245 |
-
$ref = new ReflectionFunction($callback);
|
246 |
-
}else{
|
247 |
-
$ref = new ReflectionMethod($context, $callback);
|
248 |
-
}
|
249 |
-
$name = $ref->getName();
|
250 |
-
}elseif(is_string($callback)){
|
251 |
-
$name = $callback;
|
252 |
-
}
|
253 |
-
|
254 |
-
if(!is_null($ref)){
|
255 |
-
$doc = $ref->getDocComment();
|
256 |
-
$prms = array();
|
257 |
-
foreach($ref->getParameters() as $p){
|
258 |
-
$prms[] = '$' . $p->getName() . (
|
259 |
-
$p->isDefaultValueAvailable()
|
260 |
-
? (
|
261 |
-
' = <span class="'.$cls.'_mv">' . (
|
262 |
-
$p->isDefaultValueConstant()
|
263 |
-
? $p->getDefaultValueConstantName()
|
264 |
-
: var_export($p->getDefaultValue(), true)
|
265 |
-
) . '</span>'
|
266 |
-
)
|
267 |
-
: ''
|
268 |
-
);
|
269 |
-
}
|
270 |
-
}else{
|
271 |
-
$doc = null;
|
272 |
-
$prms = array('???');
|
273 |
-
}
|
274 |
-
|
275 |
-
$xcls = !$doc ? $cls.'_ad' : '';
|
276 |
-
$html = '<a class="'.$cls.'_c" '.($doc?'href="javascript:;"':'').' onclick="'.$this->js_func.'(\''.$this->html_id.'\',\''.$id.'\');">';
|
277 |
-
$html .= ' <span class="'.$cls.'_a '.$xcls.'">►</span>';
|
278 |
-
$html .= ' <span class="'.$cls.'_k">'.$this->_esc_html($name).'<span class="'.$cls.'_ma">(<span>'.implode(', ', $prms).'</span>)</span></span>';
|
279 |
-
$html .= '</a>';
|
280 |
-
|
281 |
-
if($doc){
|
282 |
-
$html .= '<div id="'.$this->html_id.'_v'.$id.'" class="nice_r_v '.$this->css_class.'_t_comment">';
|
283 |
-
$html .= nl2br(str_replace(' ', ' ', $this->_esc_html($doc)));
|
284 |
-
$html .= '</div>';
|
285 |
-
}
|
286 |
-
|
287 |
-
return $html;
|
288 |
-
}
|
289 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
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 |
+
protected $value;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Allows modification of CSS class prefix.
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
public $css_class = 'nice_r';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Allows modification of HTML id prefix.
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
public $html_id = 'nice_r_v';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Allows modification of JS function used to toggle sections.
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $js_func = 'nice_r_toggle';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Whether to inspect and output methods for objects or not.
|
35 |
+
* @var boolean
|
36 |
+
*/
|
37 |
+
public $inspect_methods = false;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Since PHP does not support private constants, we'll have to settle for private static fields.
|
41 |
+
* @var string
|
42 |
+
*/
|
43 |
+
protected static $BEEN_THERE = '__NICE_R_INFINITE_RECURSION_PROTECT__';
|
44 |
+
|
45 |
+
protected $_has_reflection = null;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Constructs new renderer instance.
|
49 |
+
* @param mixed $value The value to inspect and render.
|
50 |
+
* @param boolean $inspectMethods Whether to inspect and output methods for objects or not.
|
51 |
+
*/
|
52 |
+
public function __construct($value, $inspectMethods = false){
|
53 |
+
$this->value = $value;
|
54 |
+
$this->inspect_methods = $inspectMethods;
|
55 |
+
|
56 |
+
if(is_null($this->_has_reflection))
|
57 |
+
$this->_has_reflection = class_exists('ReflectionClass');
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Generates the inspector HTML and returns it as a string.
|
62 |
+
* @return string Generated HTML.
|
63 |
+
*/
|
64 |
+
public function generate(){
|
65 |
+
return $this->_generate_value($this->value, $this->css_class);
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Renders the inspector HTML directly to the browser.
|
70 |
+
*/
|
71 |
+
public function render(){
|
72 |
+
echo $this->generate();
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Converts a string to HTML, encoding any special characters.
|
77 |
+
* @param string $text The original string.
|
78 |
+
* @return string The string as HTML.
|
79 |
+
*/
|
80 |
+
protected function _esc_html($text){
|
81 |
+
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
|
82 |
+
}
|
83 |
+
|
84 |
+
protected function _inspect_array(&$html, &$var){
|
85 |
+
$has_subitems = false;
|
86 |
+
|
87 |
+
foreach($var as $k => $v){
|
88 |
+
if($k !== self::$BEEN_THERE){
|
89 |
+
$html .= $this->_generate_keyvalue($k, $v);
|
90 |
+
$has_subitems = true;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
if(!$has_subitems){
|
95 |
+
$html .= '<span class="'.$this->css_class.'_ni">Empty Array</span>';
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
protected function _inspect_object(&$html, &$var){
|
100 |
+
// render properties
|
101 |
+
$has_subitems = false;
|
102 |
+
|
103 |
+
foreach((array)$var as $k=>$v){
|
104 |
+
if($k !== self::$BEEN_THERE){
|
105 |
+
$html .= $this->_generate_keyvalue($k, $v);
|
106 |
+
$has_subitems = true;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
if(!$has_subitems){
|
111 |
+
$html .= '<span class="'.$this->css_class.'_ni">No Properties</span>';
|
112 |
+
}
|
113 |
+
|
114 |
+
// render methods (if enabled)
|
115 |
+
if($this->inspect_methods){
|
116 |
+
$has_subitems = false;
|
117 |
+
|
118 |
+
foreach((array)get_class_methods($var) as $method){
|
119 |
+
$html .= $this->_generate_callable($var, $method);
|
120 |
+
$has_subitems = true;
|
121 |
+
}
|
122 |
+
|
123 |
+
if(!$has_subitems){
|
124 |
+
$html .= '<span class="'.$this->css_class.'_ni">No Methods</span>';
|
125 |
+
}
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Render a single particular value.
|
131 |
+
* @param mixed $var The value to render
|
132 |
+
* @param string $class Parent CSS class.
|
133 |
+
* @param string $id Item HTML id.
|
134 |
+
*/
|
135 |
+
protected function _generate_value($var, $class = '', $id = ''){
|
136 |
+
$BEENTHERE = self::$BEEN_THERE;
|
137 |
+
$class .= ' '.$this->css_class.'_t_'.gettype($var);
|
138 |
+
|
139 |
+
$html = '<div id="'.$id.'" class="'.$class.'">';
|
140 |
+
|
141 |
+
switch(true){
|
142 |
+
|
143 |
+
// handle arrays
|
144 |
+
case is_array($var):
|
145 |
+
if(isset($var[$BEENTHERE])){
|
146 |
+
$html .= '<span class="'.$this->css_class.'_ir">Infinite Recursion Detected!</span>';
|
147 |
+
}else{
|
148 |
+
$var[$BEENTHERE] = true;
|
149 |
+
$this->_inspect_array($html, $var);
|
150 |
+
unset($var[$BEENTHERE]);
|
151 |
+
}
|
152 |
+
break;
|
153 |
+
|
154 |
+
// handle objects
|
155 |
+
case is_object($var):
|
156 |
+
if(isset($var->$BEENTHERE)){
|
157 |
+
$html .= '<span class="'.$this->css_class.'_ir">Infinite Recursion Detected!</span>';
|
158 |
+
}else{
|
159 |
+
$var->$BEENTHERE = true;
|
160 |
+
$this->_inspect_object($html, $var);
|
161 |
+
unset($var->$BEENTHERE);
|
162 |
+
}
|
163 |
+
break;
|
164 |
+
|
165 |
+
// handle simple types
|
166 |
+
default:
|
167 |
+
$html .= $this->_generate_keyvalue('', $var);
|
168 |
+
break;
|
169 |
+
}
|
170 |
+
|
171 |
+
return $html . '</div>';
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Generates a new unique ID for tagging elements.
|
176 |
+
* @staticvar int $id
|
177 |
+
* @return integer An ID unique per request.
|
178 |
+
*/
|
179 |
+
protected function _generate_dropid(){
|
180 |
+
static $id = 0;
|
181 |
+
return ++$id;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Render a key-value pair.
|
186 |
+
* @staticvar int $id Specifies element id.
|
187 |
+
* @param string $key Key name.
|
188 |
+
* @param mixed $val Key value.
|
189 |
+
*/
|
190 |
+
protected function _generate_keyvalue($key, $val){
|
191 |
+
$id = $this->_generate_dropid();
|
192 |
+
$p = ''; // preview
|
193 |
+
$d = ''; // description
|
194 |
+
$t = gettype($val); // get data type
|
195 |
+
$is_hash = ($t=='array') || ($t=='object');
|
196 |
+
|
197 |
+
switch($t){
|
198 |
+
case 'boolean':
|
199 |
+
$p = $val ? 'TRUE' : 'FALSE';
|
200 |
+
break;
|
201 |
+
case 'integer':
|
202 |
+
case 'double':
|
203 |
+
$p = (string)$val;
|
204 |
+
break;
|
205 |
+
case 'string':
|
206 |
+
$d .= ', '.strlen($val).' characters';
|
207 |
+
$p = $val;
|
208 |
+
break;
|
209 |
+
case 'resource':
|
210 |
+
$d .= ', '.get_resource_type($val).' type';
|
211 |
+
$p = (string)$val;
|
212 |
+
break;
|
213 |
+
case 'array':
|
214 |
+
$d .= ', '.count($val).' elements';
|
215 |
+
break;
|
216 |
+
case 'object':
|
217 |
+
$d .= ', '.get_class($val).', '.count(get_object_vars($val)).' properties';
|
218 |
+
break;
|
219 |
+
}
|
220 |
+
|
221 |
+
$cls = $this->css_class;
|
222 |
+
$xcls = !$is_hash ? $cls.'_ad' : '';
|
223 |
+
$html = '<a '.($is_hash?'href="javascript:;"':'').' onclick="'.$this->js_func.'(\''.$this->html_id.'\',\''.$id.'\');">';
|
224 |
+
$html .= ' <span class="'.$cls.'_a '.$xcls.'" id="'.$this->html_id.'_a'.$id.'">►</span>';
|
225 |
+
$html .= ' <span class="'.$cls.'_k">'.$this->_esc_html($key).'</span>';
|
226 |
+
$html .= ' <span class="'.$cls.'_d">(<span>'.ucwords($t).'</span>'.$d.')</span>';
|
227 |
+
$html .= ' <span class="'.$cls.'_p '.$cls.'_t_'.$t.'">'.$this->_esc_html($p).'</span>';
|
228 |
+
$html .= '</a>';
|
229 |
+
|
230 |
+
if($is_hash){
|
231 |
+
$html .= $this->_generate_value($val, $cls.'_v', $this->html_id.'_v'.$id);
|
232 |
+
}
|
233 |
+
|
234 |
+
return $html;
|
235 |
+
}
|
236 |
+
|
237 |
+
protected function _generate_callable($context, $callback){
|
238 |
+
$id = $this->_generate_dropid();
|
239 |
+
$ref = null;
|
240 |
+
$name = 'Anonymous';
|
241 |
+
$cls = $this->css_class;
|
242 |
+
|
243 |
+
if($this->_has_reflection){
|
244 |
+
if(is_null($context)){
|
245 |
+
$ref = new ReflectionFunction($callback);
|
246 |
+
}else{
|
247 |
+
$ref = new ReflectionMethod($context, $callback);
|
248 |
+
}
|
249 |
+
$name = $ref->getName();
|
250 |
+
}elseif(is_string($callback)){
|
251 |
+
$name = $callback;
|
252 |
+
}
|
253 |
+
|
254 |
+
if(!is_null($ref)){
|
255 |
+
$doc = $ref->getDocComment();
|
256 |
+
$prms = array();
|
257 |
+
foreach($ref->getParameters() as $p){
|
258 |
+
$prms[] = '$' . $p->getName() . (
|
259 |
+
$p->isDefaultValueAvailable()
|
260 |
+
? (
|
261 |
+
' = <span class="'.$cls.'_mv">' . (
|
262 |
+
$p->isDefaultValueConstant()
|
263 |
+
? $p->getDefaultValueConstantName()
|
264 |
+
: var_export($p->getDefaultValue(), true)
|
265 |
+
) . '</span>'
|
266 |
+
)
|
267 |
+
: ''
|
268 |
+
);
|
269 |
+
}
|
270 |
+
}else{
|
271 |
+
$doc = null;
|
272 |
+
$prms = array('???');
|
273 |
+
}
|
274 |
+
|
275 |
+
$xcls = !$doc ? $cls.'_ad' : '';
|
276 |
+
$html = '<a class="'.$cls.'_c" '.($doc?'href="javascript:;"':'').' onclick="'.$this->js_func.'(\''.$this->html_id.'\',\''.$id.'\');">';
|
277 |
+
$html .= ' <span class="'.$cls.'_a '.$xcls.'">►</span>';
|
278 |
+
$html .= ' <span class="'.$cls.'_k">'.$this->_esc_html($name).'<span class="'.$cls.'_ma">(<span>'.implode(', ', $prms).'</span>)</span></span>';
|
279 |
+
$html .= '</a>';
|
280 |
+
|
281 |
+
if($doc){
|
282 |
+
$html .= '<div id="'.$this->html_id.'_v'.$id.'" class="nice_r_v '.$this->css_class.'_t_comment">';
|
283 |
+
$html .= nl2br(str_replace(' ', ' ', $this->_esc_html($doc)));
|
284 |
+
$html .= '</div>';
|
285 |
+
}
|
286 |
+
|
287 |
+
return $html;
|
288 |
+
}
|
289 |
+
}
|
classes/SensorManager.php
CHANGED
@@ -1,50 +1,50 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var WSAL_AbstractSensor[]
|
7 |
-
*/
|
8 |
-
protected $sensors = array();
|
9 |
-
|
10 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
11 |
-
parent::__construct($plugin);
|
12 |
-
|
13 |
-
foreach(glob(dirname(__FILE__) . '/Sensors/*.php') as $file)
|
14 |
-
$this->AddFromFile ($file);
|
15 |
-
}
|
16 |
-
|
17 |
-
public function HookEvents() {
|
18 |
-
foreach($this->sensors as $sensor)
|
19 |
-
$sensor->HookEvents();
|
20 |
-
}
|
21 |
-
|
22 |
-
public function GetSensors(){
|
23 |
-
return $this->sensors;
|
24 |
-
}
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Add new sensor from file inside autoloader path.
|
28 |
-
* @param string $file Path to file.
|
29 |
-
*/
|
30 |
-
public function AddFromFile($file){
|
31 |
-
$this->AddFromClass($this->plugin->GetClassFileClassName($file));
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Add new sensor given class name.
|
36 |
-
* @param string $class Class name.
|
37 |
-
*/
|
38 |
-
public function AddFromClass($class){
|
39 |
-
$this->AddInstance(new $class($this->plugin));
|
40 |
-
}
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Add newly created sensor to list.
|
44 |
-
* @param WSAL_AbstractSensor $sensor The new sensor.
|
45 |
-
*/
|
46 |
-
public function AddInstance(WSAL_AbstractSensor $sensor){
|
47 |
-
$this->sensors[] = $sensor;
|
48 |
-
}
|
49 |
-
|
50 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
final class WSAL_SensorManager extends WSAL_AbstractSensor {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var WSAL_AbstractSensor[]
|
7 |
+
*/
|
8 |
+
protected $sensors = array();
|
9 |
+
|
10 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
11 |
+
parent::__construct($plugin);
|
12 |
+
|
13 |
+
foreach(glob(dirname(__FILE__) . '/Sensors/*.php') as $file)
|
14 |
+
$this->AddFromFile ($file);
|
15 |
+
}
|
16 |
+
|
17 |
+
public function HookEvents() {
|
18 |
+
foreach($this->sensors as $sensor)
|
19 |
+
$sensor->HookEvents();
|
20 |
+
}
|
21 |
+
|
22 |
+
public function GetSensors(){
|
23 |
+
return $this->sensors;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Add new sensor from file inside autoloader path.
|
28 |
+
* @param string $file Path to file.
|
29 |
+
*/
|
30 |
+
public function AddFromFile($file){
|
31 |
+
$this->AddFromClass($this->plugin->GetClassFileClassName($file));
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Add new sensor given class name.
|
36 |
+
* @param string $class Class name.
|
37 |
+
*/
|
38 |
+
public function AddFromClass($class){
|
39 |
+
$this->AddInstance(new $class($this->plugin));
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Add newly created sensor to list.
|
44 |
+
* @param WSAL_AbstractSensor $sensor The new sensor.
|
45 |
+
*/
|
46 |
+
public function AddInstance(WSAL_AbstractSensor $sensor){
|
47 |
+
$this->sensors[] = $sensor;
|
48 |
+
}
|
49 |
+
|
50 |
}
|
classes/Sensors/BBPress.php
CHANGED
@@ -1,412 +1,412 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Support for BBPress Forum Plugin
|
4 |
-
*/
|
5 |
-
class WSAL_Sensors_BBPress extends WSAL_AbstractSensor
|
6 |
-
{
|
7 |
-
protected $_OldPost = null;
|
8 |
-
protected $_OldLink = null;
|
9 |
-
|
10 |
-
public function HookEvents()
|
11 |
-
{
|
12 |
-
if (current_user_can("edit_posts")) {
|
13 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
14 |
-
}
|
15 |
-
add_action('post_updated', array($this, 'CheckForumChange'), 10, 3);
|
16 |
-
add_action('delete_post', array($this, 'EventForumDeleted'), 10, 1);
|
17 |
-
add_action('wp_trash_post', array($this, 'EventForumTrashed'), 10, 1);
|
18 |
-
add_action('untrash_post', array($this, 'EventForumUntrashed'));
|
19 |
-
}
|
20 |
-
|
21 |
-
public function EventAdminInit()
|
22 |
-
{
|
23 |
-
// load old data, if applicable
|
24 |
-
$this->RetrieveOldData();
|
25 |
-
// check for Ajax changes
|
26 |
-
$this->TriggerAjaxChange();
|
27 |
-
}
|
28 |
-
|
29 |
-
protected function RetrieveOldData()
|
30 |
-
{
|
31 |
-
if (isset($_POST) && isset($_POST['post_ID'])
|
32 |
-
&& !(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
|
33 |
-
&& !(isset($_POST['action']) && $_POST['action'] == 'autosave')
|
34 |
-
) {
|
35 |
-
$postID = intval($_POST['post_ID']);
|
36 |
-
$this->_OldPost = get_post($postID);
|
37 |
-
$this->_OldLink = get_permalink($postID);
|
38 |
-
}
|
39 |
-
}
|
40 |
-
|
41 |
-
public function CheckForumChange($post_ID, $newpost, $oldpost)
|
42 |
-
{
|
43 |
-
if ($this->CheckBBPress($oldpost)) {
|
44 |
-
$changes = 0 + $this->EventForumCreation($oldpost, $newpost);
|
45 |
-
// Change Visibility
|
46 |
-
if (!$changes) {
|
47 |
-
$changes = $this->EventForumChangedVisibility($oldpost);
|
48 |
-
}
|
49 |
-
// Change Type
|
50 |
-
if (!$changes) {
|
51 |
-
$changes = $this->EventForumChangedType($oldpost);
|
52 |
-
}
|
53 |
-
// Change status
|
54 |
-
if (!$changes) {
|
55 |
-
$changes = $this->EventForumChangedStatus($oldpost);
|
56 |
-
}
|
57 |
-
// Change Order, Parent or URL
|
58 |
-
if (!$changes) {
|
59 |
-
$changes = $this->EventForumChanged($oldpost, $newpost);
|
60 |
-
}
|
61 |
-
}
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Permanently deleted
|
66 |
-
*/
|
67 |
-
public function EventForumDeleted($post_id)
|
68 |
-
{
|
69 |
-
$post = get_post($post_id);
|
70 |
-
if ($this->CheckBBPress($post)) {
|
71 |
-
switch ($post->post_type) {
|
72 |
-
case 'forum':
|
73 |
-
$this->EventForumByCode($post, 8006);
|
74 |
-
break;
|
75 |
-
case 'topic':
|
76 |
-
$this->EventTopicByCode($post, 8020);
|
77 |
-
break;
|
78 |
-
}
|
79 |
-
}
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Moved to Trash
|
84 |
-
*/
|
85 |
-
public function EventForumTrashed($post_id)
|
86 |
-
{
|
87 |
-
$post = get_post($post_id);
|
88 |
-
if ($this->CheckBBPress($post)) {
|
89 |
-
switch ($post->post_type) {
|
90 |
-
case 'forum':
|
91 |
-
$this->EventForumByCode($post, 8005);
|
92 |
-
break;
|
93 |
-
case 'topic':
|
94 |
-
$this->EventTopicByCode($post, 8019);
|
95 |
-
break;
|
96 |
-
}
|
97 |
-
}
|
98 |
-
}
|
99 |
-
|
100 |
-
/**
|
101 |
-
* Restored from Trash
|
102 |
-
*/
|
103 |
-
public function EventForumUntrashed($post_id)
|
104 |
-
{
|
105 |
-
$post = get_post($post_id);
|
106 |
-
if ($this->CheckBBPress($post)) {
|
107 |
-
switch ($post->post_type) {
|
108 |
-
case 'forum':
|
109 |
-
$this->EventForumByCode($post, 8007);
|
110 |
-
break;
|
111 |
-
case 'topic':
|
112 |
-
$this->EventTopicByCode($post, 8021);
|
113 |
-
break;
|
114 |
-
}
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
private function CheckBBPress($post)
|
119 |
-
{
|
120 |
-
switch ($post->post_type) {
|
121 |
-
case 'forum':
|
122 |
-
case 'topic':
|
123 |
-
case 'reply':
|
124 |
-
return true;
|
125 |
-
default:
|
126 |
-
return false;
|
127 |
-
}
|
128 |
-
}
|
129 |
-
|
130 |
-
private function EventForumCreation($old_post, $new_post)
|
131 |
-
{
|
132 |
-
$original = isset($_POST['original_post_status']) ? $_POST['original_post_status'] : '';
|
133 |
-
if ($old_post->post_status == 'draft' || $original == 'auto-draft') {
|
134 |
-
if ($new_post->post_status == 'publish') {
|
135 |
-
switch ($old_post->post_type) {
|
136 |
-
case 'forum':
|
137 |
-
$this->plugin->alerts->Trigger(8000, array(
|
138 |
-
'ForumName' => $new_post->post_title,
|
139 |
-
'ForumURL' => get_permalink($new_post->ID)
|
140 |
-
));
|
141 |
-
break;
|
142 |
-
case 'topic':
|
143 |
-
$this->plugin->alerts->Trigger(8014, array(
|
144 |
-
'TopicName' => $new_post->post_title,
|
145 |
-
'TopicURL' => get_permalink($new_post->ID)
|
146 |
-
));
|
147 |
-
break;
|
148 |
-
}
|
149 |
-
return 1;
|
150 |
-
}
|
151 |
-
}
|
152 |
-
return 0;
|
153 |
-
}
|
154 |
-
|
155 |
-
private function EventForumChangedVisibility($post)
|
156 |
-
{
|
157 |
-
$result = 0;
|
158 |
-
switch ($post->post_type) {
|
159 |
-
case 'forum':
|
160 |
-
$oldVisibility = !empty($_REQUEST['visibility']) ? $_REQUEST['visibility'] : '';
|
161 |
-
$newVisibility = !empty($_REQUEST['bbp_forum_visibility']) ? $_REQUEST['bbp_forum_visibility'] : '';
|
162 |
-
$newVisibility = ($newVisibility == 'publish') ? 'public' : $newVisibility;
|
163 |
-
|
164 |
-
if (!empty($newVisibility) && $oldVisibility != 'auto-draft' && $oldVisibility != $newVisibility) {
|
165 |
-
$this->plugin->alerts->Trigger(8002, array(
|
166 |
-
'ForumName' => $post->post_title,
|
167 |
-
'OldVisibility' => $oldVisibility,
|
168 |
-
'NewVisibility' => $newVisibility
|
169 |
-
));
|
170 |
-
$result = 1;
|
171 |
-
}
|
172 |
-
break;
|
173 |
-
case 'topic':
|
174 |
-
$oldVisibility = !empty($_REQUEST['hidden_post_visibility']) ? $_REQUEST['hidden_post_visibility'] : '';
|
175 |
-
$newVisibility = !empty($_REQUEST['visibility']) ? $_REQUEST['visibility'] : '';
|
176 |
-
$newVisibility = ($newVisibility == 'password') ? 'password protected' : $newVisibility;
|
177 |
-
|
178 |
-
if (!empty($newVisibility) && $oldVisibility != 'auto-draft' && $oldVisibility != $newVisibility) {
|
179 |
-
$this->plugin->alerts->Trigger(8022, array(
|
180 |
-
'TopicName' => $post->post_title,
|
181 |
-
'OldVisibility' => $oldVisibility,
|
182 |
-
'NewVisibility' => $newVisibility
|
183 |
-
));
|
184 |
-
$result = 1;
|
185 |
-
}
|
186 |
-
break;
|
187 |
-
}
|
188 |
-
return $result;
|
189 |
-
}
|
190 |
-
|
191 |
-
private function EventForumChangedType($post)
|
192 |
-
{
|
193 |
-
$result = 0;
|
194 |
-
switch ($post->post_type) {
|
195 |
-
case 'forum':
|
196 |
-
$bbp_forum_type = get_post_meta($post->ID, '_bbp_forum_type', true);
|
197 |
-
$oldType = !empty($bbp_forum_type) ? $bbp_forum_type : 'forum';
|
198 |
-
$newType = !empty($_POST['bbp_forum_type']) ? $_POST['bbp_forum_type'] : '';
|
199 |
-
if (!empty($newType) && $oldType != $newType) {
|
200 |
-
$this->plugin->alerts->Trigger(8011, array(
|
201 |
-
'ForumName' => $post->post_title,
|
202 |
-
'OldType' => $oldType,
|
203 |
-
'NewType' => $newType
|
204 |
-
));
|
205 |
-
$result = 1;
|
206 |
-
}
|
207 |
-
break;
|
208 |
-
case 'topic':
|
209 |
-
if (!empty($_POST['parent_id'])) {
|
210 |
-
$post_id = $_POST['parent_id'];
|
211 |
-
} else {
|
212 |
-
$post_id = $post->ID;
|
213 |
-
}
|
214 |
-
$bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
|
215 |
-
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
216 |
-
$bbp_super_sticky_topics = maybe_unserialize($fn('_bbp_super_sticky_topics'));
|
217 |
-
if (!empty($bbp_sticky_topics) && in_array($post->ID, $bbp_sticky_topics)) {
|
218 |
-
$oldType = 'sticky';
|
219 |
-
} elseif (!empty($bbp_super_sticky_topics) && in_array($post->ID, $bbp_super_sticky_topics)) {
|
220 |
-
$oldType = 'super';
|
221 |
-
} else {
|
222 |
-
$oldType = 'unstick';
|
223 |
-
}
|
224 |
-
$newType = !empty($_POST['bbp_stick_topic']) ? $_POST['bbp_stick_topic'] : '';
|
225 |
-
if (!empty($newType) && $oldType != $newType) {
|
226 |
-
$this->plugin->alerts->Trigger(8016, array(
|
227 |
-
'TopicName' => $post->post_title,
|
228 |
-
'OldType' => ($oldType == 'unstick') ? 'normal' : (($oldType == 'super') ? 'super sticky' : $oldType),
|
229 |
-
'NewType' => ($newType == 'unstick') ? 'normal' : (($newType == 'super') ? 'super sticky' : $newType)
|
230 |
-
));
|
231 |
-
$result = 1;
|
232 |
-
}
|
233 |
-
break;
|
234 |
-
}
|
235 |
-
return $result;
|
236 |
-
}
|
237 |
-
|
238 |
-
private function EventForumChangedStatus($post)
|
239 |
-
{
|
240 |
-
$result = 0;
|
241 |
-
switch ($post->post_type) {
|
242 |
-
case 'forum':
|
243 |
-
$bbp_status = get_post_meta($post->ID, '_bbp_status', true);
|
244 |
-
$oldStatus = !empty($bbp_status) ? $bbp_status : 'open';
|
245 |
-
$newStatus = !empty($_REQUEST['bbp_forum_status']) ? $_REQUEST['bbp_forum_status'] : '';
|
246 |
-
if (!empty($newStatus) && $oldStatus != $newStatus) {
|
247 |
-
$this->plugin->alerts->Trigger(8001, array(
|
248 |
-
'ForumName' => $post->post_title,
|
249 |
-
'OldStatus' => $oldStatus,
|
250 |
-
'NewStatus' => $newStatus
|
251 |
-
));
|
252 |
-
$result = 1;
|
253 |
-
}
|
254 |
-
break;
|
255 |
-
case 'topic':
|
256 |
-
$oldStatus = !empty($_REQUEST['original_post_status']) ? $_REQUEST['original_post_status'] : '';
|
257 |
-
$newStatus = !empty($_REQUEST['post_status']) ? $_REQUEST['post_status'] : '';
|
258 |
-
// In case of Ajax request Spam/Not spam
|
259 |
-
if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_spam') {
|
260 |
-
$oldStatus = $post->post_status;
|
261 |
-
$newStatus = 'spam';
|
262 |
-
if (isset($_GET['post_status']) && $_GET['post_status'] == 'spam') {
|
263 |
-
$newStatus = 'publish';
|
264 |
-
}
|
265 |
-
}
|
266 |
-
// In case of Ajax request Close/Open
|
267 |
-
if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_close') {
|
268 |
-
$oldStatus = $post->post_status;
|
269 |
-
$newStatus = 'closed';
|
270 |
-
if (isset($_GET['post_status']) && $_GET['post_status'] == 'closed') {
|
271 |
-
$newStatus = 'publish';
|
272 |
-
}
|
273 |
-
}
|
274 |
-
if (!empty($newStatus) && $oldStatus != $newStatus) {
|
275 |
-
$this->plugin->alerts->Trigger(8015, array(
|
276 |
-
'TopicName' => $post->post_title,
|
277 |
-
'OldStatus' => ($oldStatus == 'publish') ? 'open' : $oldStatus,
|
278 |
-
'NewStatus' => ($newStatus == 'publish') ? 'open' : $newStatus
|
279 |
-
));
|
280 |
-
$result = 1;
|
281 |
-
}
|
282 |
-
break;
|
283 |
-
}
|
284 |
-
return $result;
|
285 |
-
}
|
286 |
-
|
287 |
-
private function EventForumChanged($old_post, $new_post)
|
288 |
-
{
|
289 |
-
// Changed Order
|
290 |
-
if ($old_post->menu_order != $new_post->menu_order) {
|
291 |
-
$this->plugin->alerts->Trigger(8004, array(
|
292 |
-
'ForumName' => $new_post->post_title,
|
293 |
-
'OldOrder' => $old_post->menu_order,
|
294 |
-
'NewOrder' => $new_post->menu_order
|
295 |
-
));
|
296 |
-
return 1;
|
297 |
-
}
|
298 |
-
// Changed Parent
|
299 |
-
if ($old_post->post_parent != $new_post->post_parent) {
|
300 |
-
switch ($old_post->post_type) {
|
301 |
-
case 'forum':
|
302 |
-
$this->plugin->alerts->Trigger(8008, array(
|
303 |
-
'ForumName' => $new_post->post_title,
|
304 |
-
'OldParent' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
|
305 |
-
'NewParent' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent'
|
306 |
-
));
|
307 |
-
break;
|
308 |
-
case 'topic':
|
309 |
-
$this->plugin->alerts->Trigger(8018, array(
|
310 |
-
'TopicName' => $new_post->post_title,
|
311 |
-
'OldForum' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
|
312 |
-
'NewForum' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent'
|
313 |
-
));
|
314 |
-
break;
|
315 |
-
}
|
316 |
-
return 1;
|
317 |
-
}
|
318 |
-
// Changed URL
|
319 |
-
$oldLink = $this->_OldLink;
|
320 |
-
$newLink = get_permalink($new_post->ID);
|
321 |
-
if (!empty($oldLink) && $oldLink != $newLink) {
|
322 |
-
switch ($old_post->post_type) {
|
323 |
-
case 'forum':
|
324 |
-
$this->plugin->alerts->Trigger(8003, array(
|
325 |
-
'ForumName' => $new_post->post_title,
|
326 |
-
'OldUrl' => $oldLink,
|
327 |
-
'NewUrl' => $newLink
|
328 |
-
));
|
329 |
-
break;
|
330 |
-
case 'topic':
|
331 |
-
$this->plugin->alerts->Trigger(8017, array(
|
332 |
-
'TopicName' => $new_post->post_title,
|
333 |
-
'OldUrl' => $oldLink,
|
334 |
-
'NewUrl' => $newLink
|
335 |
-
));
|
336 |
-
break;
|
337 |
-
}
|
338 |
-
return 1;
|
339 |
-
}
|
340 |
-
return 0;
|
341 |
-
}
|
342 |
-
|
343 |
-
private function EventForumByCode($post, $event)
|
344 |
-
{
|
345 |
-
$this->plugin->alerts->Trigger($event, array(
|
346 |
-
'ForumID' => $post->ID,
|
347 |
-
'ForumName' => $post->post_title
|
348 |
-
));
|
349 |
-
}
|
350 |
-
|
351 |
-
private function EventTopicByCode($post, $event)
|
352 |
-
{
|
353 |
-
$this->plugin->alerts->Trigger($event, array(
|
354 |
-
'TopicID' => $post->ID,
|
355 |
-
'TopicName' => $post->post_title
|
356 |
-
));
|
357 |
-
}
|
358 |
-
|
359 |
-
/**
|
360 |
-
* Trigger of ajax events generated in the Topic Grid
|
361 |
-
*/
|
362 |
-
public function TriggerAjaxChange()
|
363 |
-
{
|
364 |
-
if (!empty($_GET['post_type']) && !empty($_GET['topic_id'])) {
|
365 |
-
if ($_GET['post_type'] == 'topic') {
|
366 |
-
$post = get_post($_GET['topic_id']);
|
367 |
-
|
368 |
-
// Topic type
|
369 |
-
if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_stick') {
|
370 |
-
if (!empty($post->post_parent)) {
|
371 |
-
$post_id = $post->post_parent;
|
372 |
-
} else {
|
373 |
-
$post_id = $_GET['topic_id'];
|
374 |
-
}
|
375 |
-
|
376 |
-
$bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
|
377 |
-
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
378 |
-
$bbp_super_sticky_topics = maybe_unserialize($fn('_bbp_super_sticky_topics'));
|
379 |
-
if (!empty($bbp_sticky_topics) && in_array($_GET['topic_id'], $bbp_sticky_topics)) {
|
380 |
-
$oldType = 'sticky';
|
381 |
-
} elseif (!empty($bbp_super_sticky_topics) && in_array($_GET['topic_id'], $bbp_super_sticky_topics)) {
|
382 |
-
$oldType = 'super sticky';
|
383 |
-
} else {
|
384 |
-
$oldType = 'normal';
|
385 |
-
}
|
386 |
-
|
387 |
-
switch ($oldType) {
|
388 |
-
case 'sticky':
|
389 |
-
case 'super sticky':
|
390 |
-
$newType = 'normal';
|
391 |
-
break;
|
392 |
-
case 'normal':
|
393 |
-
if (isset($_GET['super']) && $_GET['super'] == 1) {
|
394 |
-
$newType = 'super sticky';
|
395 |
-
} else {
|
396 |
-
$newType = 'sticky';
|
397 |
-
}
|
398 |
-
break;
|
399 |
-
}
|
400 |
-
|
401 |
-
if (!empty($newType) && $oldType != $newType) {
|
402 |
-
$this->plugin->alerts->Trigger(8016, array(
|
403 |
-
'TopicName' => $post->post_title,
|
404 |
-
'OldType' => $oldType,
|
405 |
-
'NewType' => $newType
|
406 |
-
));
|
407 |
-
}
|
408 |
-
}
|
409 |
-
}
|
410 |
-
}
|
411 |
-
}
|
412 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Support for BBPress Forum Plugin
|
4 |
+
*/
|
5 |
+
class WSAL_Sensors_BBPress extends WSAL_AbstractSensor
|
6 |
+
{
|
7 |
+
protected $_OldPost = null;
|
8 |
+
protected $_OldLink = null;
|
9 |
+
|
10 |
+
public function HookEvents()
|
11 |
+
{
|
12 |
+
if (current_user_can("edit_posts")) {
|
13 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
14 |
+
}
|
15 |
+
add_action('post_updated', array($this, 'CheckForumChange'), 10, 3);
|
16 |
+
add_action('delete_post', array($this, 'EventForumDeleted'), 10, 1);
|
17 |
+
add_action('wp_trash_post', array($this, 'EventForumTrashed'), 10, 1);
|
18 |
+
add_action('untrash_post', array($this, 'EventForumUntrashed'));
|
19 |
+
}
|
20 |
+
|
21 |
+
public function EventAdminInit()
|
22 |
+
{
|
23 |
+
// load old data, if applicable
|
24 |
+
$this->RetrieveOldData();
|
25 |
+
// check for Ajax changes
|
26 |
+
$this->TriggerAjaxChange();
|
27 |
+
}
|
28 |
+
|
29 |
+
protected function RetrieveOldData()
|
30 |
+
{
|
31 |
+
if (isset($_POST) && isset($_POST['post_ID'])
|
32 |
+
&& !(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
|
33 |
+
&& !(isset($_POST['action']) && $_POST['action'] == 'autosave')
|
34 |
+
) {
|
35 |
+
$postID = intval($_POST['post_ID']);
|
36 |
+
$this->_OldPost = get_post($postID);
|
37 |
+
$this->_OldLink = get_permalink($postID);
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
public function CheckForumChange($post_ID, $newpost, $oldpost)
|
42 |
+
{
|
43 |
+
if ($this->CheckBBPress($oldpost)) {
|
44 |
+
$changes = 0 + $this->EventForumCreation($oldpost, $newpost);
|
45 |
+
// Change Visibility
|
46 |
+
if (!$changes) {
|
47 |
+
$changes = $this->EventForumChangedVisibility($oldpost);
|
48 |
+
}
|
49 |
+
// Change Type
|
50 |
+
if (!$changes) {
|
51 |
+
$changes = $this->EventForumChangedType($oldpost);
|
52 |
+
}
|
53 |
+
// Change status
|
54 |
+
if (!$changes) {
|
55 |
+
$changes = $this->EventForumChangedStatus($oldpost);
|
56 |
+
}
|
57 |
+
// Change Order, Parent or URL
|
58 |
+
if (!$changes) {
|
59 |
+
$changes = $this->EventForumChanged($oldpost, $newpost);
|
60 |
+
}
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Permanently deleted
|
66 |
+
*/
|
67 |
+
public function EventForumDeleted($post_id)
|
68 |
+
{
|
69 |
+
$post = get_post($post_id);
|
70 |
+
if ($this->CheckBBPress($post)) {
|
71 |
+
switch ($post->post_type) {
|
72 |
+
case 'forum':
|
73 |
+
$this->EventForumByCode($post, 8006);
|
74 |
+
break;
|
75 |
+
case 'topic':
|
76 |
+
$this->EventTopicByCode($post, 8020);
|
77 |
+
break;
|
78 |
+
}
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Moved to Trash
|
84 |
+
*/
|
85 |
+
public function EventForumTrashed($post_id)
|
86 |
+
{
|
87 |
+
$post = get_post($post_id);
|
88 |
+
if ($this->CheckBBPress($post)) {
|
89 |
+
switch ($post->post_type) {
|
90 |
+
case 'forum':
|
91 |
+
$this->EventForumByCode($post, 8005);
|
92 |
+
break;
|
93 |
+
case 'topic':
|
94 |
+
$this->EventTopicByCode($post, 8019);
|
95 |
+
break;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Restored from Trash
|
102 |
+
*/
|
103 |
+
public function EventForumUntrashed($post_id)
|
104 |
+
{
|
105 |
+
$post = get_post($post_id);
|
106 |
+
if ($this->CheckBBPress($post)) {
|
107 |
+
switch ($post->post_type) {
|
108 |
+
case 'forum':
|
109 |
+
$this->EventForumByCode($post, 8007);
|
110 |
+
break;
|
111 |
+
case 'topic':
|
112 |
+
$this->EventTopicByCode($post, 8021);
|
113 |
+
break;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
private function CheckBBPress($post)
|
119 |
+
{
|
120 |
+
switch ($post->post_type) {
|
121 |
+
case 'forum':
|
122 |
+
case 'topic':
|
123 |
+
case 'reply':
|
124 |
+
return true;
|
125 |
+
default:
|
126 |
+
return false;
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
private function EventForumCreation($old_post, $new_post)
|
131 |
+
{
|
132 |
+
$original = isset($_POST['original_post_status']) ? $_POST['original_post_status'] : '';
|
133 |
+
if ($old_post->post_status == 'draft' || $original == 'auto-draft') {
|
134 |
+
if ($new_post->post_status == 'publish') {
|
135 |
+
switch ($old_post->post_type) {
|
136 |
+
case 'forum':
|
137 |
+
$this->plugin->alerts->Trigger(8000, array(
|
138 |
+
'ForumName' => $new_post->post_title,
|
139 |
+
'ForumURL' => get_permalink($new_post->ID)
|
140 |
+
));
|
141 |
+
break;
|
142 |
+
case 'topic':
|
143 |
+
$this->plugin->alerts->Trigger(8014, array(
|
144 |
+
'TopicName' => $new_post->post_title,
|
145 |
+
'TopicURL' => get_permalink($new_post->ID)
|
146 |
+
));
|
147 |
+
break;
|
148 |
+
}
|
149 |
+
return 1;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
return 0;
|
153 |
+
}
|
154 |
+
|
155 |
+
private function EventForumChangedVisibility($post)
|
156 |
+
{
|
157 |
+
$result = 0;
|
158 |
+
switch ($post->post_type) {
|
159 |
+
case 'forum':
|
160 |
+
$oldVisibility = !empty($_REQUEST['visibility']) ? $_REQUEST['visibility'] : '';
|
161 |
+
$newVisibility = !empty($_REQUEST['bbp_forum_visibility']) ? $_REQUEST['bbp_forum_visibility'] : '';
|
162 |
+
$newVisibility = ($newVisibility == 'publish') ? 'public' : $newVisibility;
|
163 |
+
|
164 |
+
if (!empty($newVisibility) && $oldVisibility != 'auto-draft' && $oldVisibility != $newVisibility) {
|
165 |
+
$this->plugin->alerts->Trigger(8002, array(
|
166 |
+
'ForumName' => $post->post_title,
|
167 |
+
'OldVisibility' => $oldVisibility,
|
168 |
+
'NewVisibility' => $newVisibility
|
169 |
+
));
|
170 |
+
$result = 1;
|
171 |
+
}
|
172 |
+
break;
|
173 |
+
case 'topic':
|
174 |
+
$oldVisibility = !empty($_REQUEST['hidden_post_visibility']) ? $_REQUEST['hidden_post_visibility'] : '';
|
175 |
+
$newVisibility = !empty($_REQUEST['visibility']) ? $_REQUEST['visibility'] : '';
|
176 |
+
$newVisibility = ($newVisibility == 'password') ? 'password protected' : $newVisibility;
|
177 |
+
|
178 |
+
if (!empty($newVisibility) && $oldVisibility != 'auto-draft' && $oldVisibility != $newVisibility) {
|
179 |
+
$this->plugin->alerts->Trigger(8022, array(
|
180 |
+
'TopicName' => $post->post_title,
|
181 |
+
'OldVisibility' => $oldVisibility,
|
182 |
+
'NewVisibility' => $newVisibility
|
183 |
+
));
|
184 |
+
$result = 1;
|
185 |
+
}
|
186 |
+
break;
|
187 |
+
}
|
188 |
+
return $result;
|
189 |
+
}
|
190 |
+
|
191 |
+
private function EventForumChangedType($post)
|
192 |
+
{
|
193 |
+
$result = 0;
|
194 |
+
switch ($post->post_type) {
|
195 |
+
case 'forum':
|
196 |
+
$bbp_forum_type = get_post_meta($post->ID, '_bbp_forum_type', true);
|
197 |
+
$oldType = !empty($bbp_forum_type) ? $bbp_forum_type : 'forum';
|
198 |
+
$newType = !empty($_POST['bbp_forum_type']) ? $_POST['bbp_forum_type'] : '';
|
199 |
+
if (!empty($newType) && $oldType != $newType) {
|
200 |
+
$this->plugin->alerts->Trigger(8011, array(
|
201 |
+
'ForumName' => $post->post_title,
|
202 |
+
'OldType' => $oldType,
|
203 |
+
'NewType' => $newType
|
204 |
+
));
|
205 |
+
$result = 1;
|
206 |
+
}
|
207 |
+
break;
|
208 |
+
case 'topic':
|
209 |
+
if (!empty($_POST['parent_id'])) {
|
210 |
+
$post_id = $_POST['parent_id'];
|
211 |
+
} else {
|
212 |
+
$post_id = $post->ID;
|
213 |
+
}
|
214 |
+
$bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
|
215 |
+
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
216 |
+
$bbp_super_sticky_topics = maybe_unserialize($fn('_bbp_super_sticky_topics'));
|
217 |
+
if (!empty($bbp_sticky_topics) && in_array($post->ID, $bbp_sticky_topics)) {
|
218 |
+
$oldType = 'sticky';
|
219 |
+
} elseif (!empty($bbp_super_sticky_topics) && in_array($post->ID, $bbp_super_sticky_topics)) {
|
220 |
+
$oldType = 'super';
|
221 |
+
} else {
|
222 |
+
$oldType = 'unstick';
|
223 |
+
}
|
224 |
+
$newType = !empty($_POST['bbp_stick_topic']) ? $_POST['bbp_stick_topic'] : '';
|
225 |
+
if (!empty($newType) && $oldType != $newType) {
|
226 |
+
$this->plugin->alerts->Trigger(8016, array(
|
227 |
+
'TopicName' => $post->post_title,
|
228 |
+
'OldType' => ($oldType == 'unstick') ? 'normal' : (($oldType == 'super') ? 'super sticky' : $oldType),
|
229 |
+
'NewType' => ($newType == 'unstick') ? 'normal' : (($newType == 'super') ? 'super sticky' : $newType)
|
230 |
+
));
|
231 |
+
$result = 1;
|
232 |
+
}
|
233 |
+
break;
|
234 |
+
}
|
235 |
+
return $result;
|
236 |
+
}
|
237 |
+
|
238 |
+
private function EventForumChangedStatus($post)
|
239 |
+
{
|
240 |
+
$result = 0;
|
241 |
+
switch ($post->post_type) {
|
242 |
+
case 'forum':
|
243 |
+
$bbp_status = get_post_meta($post->ID, '_bbp_status', true);
|
244 |
+
$oldStatus = !empty($bbp_status) ? $bbp_status : 'open';
|
245 |
+
$newStatus = !empty($_REQUEST['bbp_forum_status']) ? $_REQUEST['bbp_forum_status'] : '';
|
246 |
+
if (!empty($newStatus) && $oldStatus != $newStatus) {
|
247 |
+
$this->plugin->alerts->Trigger(8001, array(
|
248 |
+
'ForumName' => $post->post_title,
|
249 |
+
'OldStatus' => $oldStatus,
|
250 |
+
'NewStatus' => $newStatus
|
251 |
+
));
|
252 |
+
$result = 1;
|
253 |
+
}
|
254 |
+
break;
|
255 |
+
case 'topic':
|
256 |
+
$oldStatus = !empty($_REQUEST['original_post_status']) ? $_REQUEST['original_post_status'] : '';
|
257 |
+
$newStatus = !empty($_REQUEST['post_status']) ? $_REQUEST['post_status'] : '';
|
258 |
+
// In case of Ajax request Spam/Not spam
|
259 |
+
if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_spam') {
|
260 |
+
$oldStatus = $post->post_status;
|
261 |
+
$newStatus = 'spam';
|
262 |
+
if (isset($_GET['post_status']) && $_GET['post_status'] == 'spam') {
|
263 |
+
$newStatus = 'publish';
|
264 |
+
}
|
265 |
+
}
|
266 |
+
// In case of Ajax request Close/Open
|
267 |
+
if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_close') {
|
268 |
+
$oldStatus = $post->post_status;
|
269 |
+
$newStatus = 'closed';
|
270 |
+
if (isset($_GET['post_status']) && $_GET['post_status'] == 'closed') {
|
271 |
+
$newStatus = 'publish';
|
272 |
+
}
|
273 |
+
}
|
274 |
+
if (!empty($newStatus) && $oldStatus != $newStatus) {
|
275 |
+
$this->plugin->alerts->Trigger(8015, array(
|
276 |
+
'TopicName' => $post->post_title,
|
277 |
+
'OldStatus' => ($oldStatus == 'publish') ? 'open' : $oldStatus,
|
278 |
+
'NewStatus' => ($newStatus == 'publish') ? 'open' : $newStatus
|
279 |
+
));
|
280 |
+
$result = 1;
|
281 |
+
}
|
282 |
+
break;
|
283 |
+
}
|
284 |
+
return $result;
|
285 |
+
}
|
286 |
+
|
287 |
+
private function EventForumChanged($old_post, $new_post)
|
288 |
+
{
|
289 |
+
// Changed Order
|
290 |
+
if ($old_post->menu_order != $new_post->menu_order) {
|
291 |
+
$this->plugin->alerts->Trigger(8004, array(
|
292 |
+
'ForumName' => $new_post->post_title,
|
293 |
+
'OldOrder' => $old_post->menu_order,
|
294 |
+
'NewOrder' => $new_post->menu_order
|
295 |
+
));
|
296 |
+
return 1;
|
297 |
+
}
|
298 |
+
// Changed Parent
|
299 |
+
if ($old_post->post_parent != $new_post->post_parent) {
|
300 |
+
switch ($old_post->post_type) {
|
301 |
+
case 'forum':
|
302 |
+
$this->plugin->alerts->Trigger(8008, array(
|
303 |
+
'ForumName' => $new_post->post_title,
|
304 |
+
'OldParent' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
|
305 |
+
'NewParent' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent'
|
306 |
+
));
|
307 |
+
break;
|
308 |
+
case 'topic':
|
309 |
+
$this->plugin->alerts->Trigger(8018, array(
|
310 |
+
'TopicName' => $new_post->post_title,
|
311 |
+
'OldForum' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
|
312 |
+
'NewForum' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent'
|
313 |
+
));
|
314 |
+
break;
|
315 |
+
}
|
316 |
+
return 1;
|
317 |
+
}
|
318 |
+
// Changed URL
|
319 |
+
$oldLink = $this->_OldLink;
|
320 |
+
$newLink = get_permalink($new_post->ID);
|
321 |
+
if (!empty($oldLink) && $oldLink != $newLink) {
|
322 |
+
switch ($old_post->post_type) {
|
323 |
+
case 'forum':
|
324 |
+
$this->plugin->alerts->Trigger(8003, array(
|
325 |
+
'ForumName' => $new_post->post_title,
|
326 |
+
'OldUrl' => $oldLink,
|
327 |
+
'NewUrl' => $newLink
|
328 |
+
));
|
329 |
+
break;
|
330 |
+
case 'topic':
|
331 |
+
$this->plugin->alerts->Trigger(8017, array(
|
332 |
+
'TopicName' => $new_post->post_title,
|
333 |
+
'OldUrl' => $oldLink,
|
334 |
+
'NewUrl' => $newLink
|
335 |
+
));
|
336 |
+
break;
|
337 |
+
}
|
338 |
+
return 1;
|
339 |
+
}
|
340 |
+
return 0;
|
341 |
+
}
|
342 |
+
|
343 |
+
private function EventForumByCode($post, $event)
|
344 |
+
{
|
345 |
+
$this->plugin->alerts->Trigger($event, array(
|
346 |
+
'ForumID' => $post->ID,
|
347 |
+
'ForumName' => $post->post_title
|
348 |
+
));
|
349 |
+
}
|
350 |
+
|
351 |
+
private function EventTopicByCode($post, $event)
|
352 |
+
{
|
353 |
+
$this->plugin->alerts->Trigger($event, array(
|
354 |
+
'TopicID' => $post->ID,
|
355 |
+
'TopicName' => $post->post_title
|
356 |
+
));
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Trigger of ajax events generated in the Topic Grid
|
361 |
+
*/
|
362 |
+
public function TriggerAjaxChange()
|
363 |
+
{
|
364 |
+
if (!empty($_GET['post_type']) && !empty($_GET['topic_id'])) {
|
365 |
+
if ($_GET['post_type'] == 'topic') {
|
366 |
+
$post = get_post($_GET['topic_id']);
|
367 |
+
|
368 |
+
// Topic type
|
369 |
+
if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_stick') {
|
370 |
+
if (!empty($post->post_parent)) {
|
371 |
+
$post_id = $post->post_parent;
|
372 |
+
} else {
|
373 |
+
$post_id = $_GET['topic_id'];
|
374 |
+
}
|
375 |
+
|
376 |
+
$bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
|
377 |
+
$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
|
378 |
+
$bbp_super_sticky_topics = maybe_unserialize($fn('_bbp_super_sticky_topics'));
|
379 |
+
if (!empty($bbp_sticky_topics) && in_array($_GET['topic_id'], $bbp_sticky_topics)) {
|
380 |
+
$oldType = 'sticky';
|
381 |
+
} elseif (!empty($bbp_super_sticky_topics) && in_array($_GET['topic_id'], $bbp_super_sticky_topics)) {
|
382 |
+
$oldType = 'super sticky';
|
383 |
+
} else {
|
384 |
+
$oldType = 'normal';
|
385 |
+
}
|
386 |
+
|
387 |
+
switch ($oldType) {
|
388 |
+
case 'sticky':
|
389 |
+
case 'super sticky':
|
390 |
+
$newType = 'normal';
|
391 |
+
break;
|
392 |
+
case 'normal':
|
393 |
+
if (isset($_GET['super']) && $_GET['super'] == 1) {
|
394 |
+
$newType = 'super sticky';
|
395 |
+
} else {
|
396 |
+
$newType = 'sticky';
|
397 |
+
}
|
398 |
+
break;
|
399 |
+
}
|
400 |
+
|
401 |
+
if (!empty($newType) && $oldType != $newType) {
|
402 |
+
$this->plugin->alerts->Trigger(8016, array(
|
403 |
+
'TopicName' => $post->post_title,
|
404 |
+
'OldType' => $oldType,
|
405 |
+
'NewType' => $newType
|
406 |
+
));
|
407 |
+
}
|
408 |
+
}
|
409 |
+
}
|
410 |
+
}
|
411 |
+
}
|
412 |
+
}
|
classes/Sensors/Content.php
CHANGED
@@ -1,635 +1,635 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Content extends WSAL_AbstractSensor
|
4 |
-
{
|
5 |
-
|
6 |
-
public function HookEvents()
|
7 |
-
{
|
8 |
-
if (current_user_can("edit_posts")) {
|
9 |
-
add_action('admin_init', array($this, 'EventWordpressInit'));
|
10 |
-
}
|
11 |
-
add_action('transition_post_status', array($this, 'EventPostChanged'), 10, 3);
|
12 |
-
add_action('delete_post', array($this, 'EventPostDeleted'), 10, 1);
|
13 |
-
add_action('wp_trash_post', array($this, 'EventPostTrashed'), 10, 1);
|
14 |
-
add_action('untrash_post', array($this, 'EventPostUntrashed'));
|
15 |
-
add_action('edit_category', array($this, 'EventChangedCategoryParent'));
|
16 |
-
add_action('save_post', array($this, 'SetRevisionLink'), 10, 3);
|
17 |
-
add_action('publish_future_post', array($this, 'EventPublishFuture'), 10, 1);
|
18 |
-
}
|
19 |
-
|
20 |
-
protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
|
21 |
-
{
|
22 |
-
switch ($post->post_type) {
|
23 |
-
case 'page':
|
24 |
-
return $typePage;
|
25 |
-
case 'post':
|
26 |
-
return $typePost;
|
27 |
-
default:
|
28 |
-
return $typeCustom;
|
29 |
-
}
|
30 |
-
}
|
31 |
-
|
32 |
-
protected $_OldPost = null;
|
33 |
-
protected $_OldLink = null;
|
34 |
-
protected $_OldCats = null;
|
35 |
-
protected $_OldTmpl = null;
|
36 |
-
protected $_OldStky = null;
|
37 |
-
|
38 |
-
public function EventWordpressInit()
|
39 |
-
{
|
40 |
-
// load old data, if applicable
|
41 |
-
$this->RetrieveOldData();
|
42 |
-
// check for category changes
|
43 |
-
$this->CheckCategoryCreation();
|
44 |
-
$this->CheckCategoryDeletion();
|
45 |
-
}
|
46 |
-
|
47 |
-
protected function RetrieveOldData()
|
48 |
-
{
|
49 |
-
if (isset($_POST) && isset($_POST['post_ID'])
|
50 |
-
&& !(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
|
51 |
-
&& !(isset($_POST['action']) && $_POST['action'] == 'autosave')
|
52 |
-
) {
|
53 |
-
$postID = intval($_POST['post_ID']);
|
54 |
-
$this->_OldPost = get_post($postID);
|
55 |
-
$this->_OldLink = get_permalink($postID);
|
56 |
-
$this->_OldTmpl = $this->GetPostTemplate($this->_OldPost);
|
57 |
-
$this->_OldCats = $this->GetPostCategories($this->_OldPost);
|
58 |
-
$this->_OldStky = in_array($postID, get_option('sticky_posts'));
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
-
protected function GetPostTemplate($post)
|
63 |
-
{
|
64 |
-
$id = $post->ID;
|
65 |
-
$template = get_page_template_slug($id);
|
66 |
-
$pagename = $post->post_name;
|
67 |
-
|
68 |
-
$templates = array();
|
69 |
-
if ($template && 0 === validate_file($template)) {
|
70 |
-
$templates[] = $template;
|
71 |
-
}
|
72 |
-
if ($pagename) {
|
73 |
-
$templates[] = "page-$pagename.php";
|
74 |
-
}
|
75 |
-
if ($id) {
|
76 |
-
$templates[] = "page-$id.php";
|
77 |
-
}
|
78 |
-
$templates[] = 'page.php';
|
79 |
-
|
80 |
-
return get_query_template('page', $templates);
|
81 |
-
}
|
82 |
-
|
83 |
-
protected function GetPostCategories($post)
|
84 |
-
{
|
85 |
-
return wp_get_post_categories($post->ID, array('fields' => 'names'));
|
86 |
-
}
|
87 |
-
|
88 |
-
public function EventPostChanged($newStatus, $oldStatus, $post)
|
89 |
-
{
|
90 |
-
// ignorable states
|
91 |
-
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
92 |
-
return;
|
93 |
-
}
|
94 |
-
if (empty($post->post_type)) {
|
95 |
-
return;
|
96 |
-
}
|
97 |
-
if ($post->post_type == 'revision') {
|
98 |
-
return;
|
99 |
-
}
|
100 |
-
|
101 |
-
$original = isset($_POST['original_post_status']) ? $_POST['original_post_status'] : '';
|
102 |
-
|
103 |
-
WSAL_Sensors_Request::SetVars(array(
|
104 |
-
'$newStatus' => $newStatus,
|
105 |
-
'$oldStatus' => $oldStatus,
|
106 |
-
'$original' => $original,
|
107 |
-
));
|
108 |
-
// run checks
|
109 |
-
if ($this->_OldPost) {
|
110 |
-
if ($this->CheckBBPress($this->_OldPost)) {
|
111 |
-
return;
|
112 |
-
}
|
113 |
-
if ($oldStatus == 'auto-draft' || $original == 'auto-draft') {
|
114 |
-
// Handle create post events
|
115 |
-
$this->CheckPostCreation($this->_OldPost, $post);
|
116 |
-
} else {
|
117 |
-
// Handle update post events
|
118 |
-
$changes = 0
|
119 |
-
+ $this->CheckAuthorChange($this->_OldPost, $post)
|
120 |
-
+ $this->CheckStatusChange($this->_OldPost, $post)
|
121 |
-
+ $this->CheckParentChange($this->_OldPost, $post)
|
122 |
-
+ $this->CheckStickyChange($this->_OldStky, isset($_REQUEST['sticky']), $post)
|
123 |
-
+ $this->CheckVisibilityChange($this->_OldPost, $post, $oldStatus, $newStatus)
|
124 |
-
+ $this->CheckTemplateChange($this->_OldTmpl, $this->GetPostTemplate($post), $post)
|
125 |
-
+ $this->CheckCategoriesChange($this->_OldCats, $this->GetPostCategories($post), $post)
|
126 |
-
;
|
127 |
-
if (!$changes) {
|
128 |
-
$changes = $this->CheckPermalinkChange($this->_OldLink, get_permalink($post->ID), $post);
|
129 |
-
}
|
130 |
-
if (!$changes) {
|
131 |
-
$changes = $this->CheckModificationChange($post->ID, $this->_OldPost, $post);
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
-
}
|
136 |
-
|
137 |
-
protected function CheckPostCreation($oldPost, $newPost)
|
138 |
-
{
|
139 |
-
$event = 0;
|
140 |
-
$is_scheduled = false;
|
141 |
-
switch ($newPost->post_status) {
|
142 |
-
case 'publish':
|
143 |
-
$event = $this->GetEventTypeForPostType($oldPost, 2001, 2005, 2030);
|
144 |
-
break;
|
145 |
-
case 'draft':
|
146 |
-
$event = $this->GetEventTypeForPostType($oldPost, 2000, 2004, 2029);
|
147 |
-
break;
|
148 |
-
case 'future':
|
149 |
-
$event = $this->GetEventTypeForPostType($oldPost, 2074, 2075, 2076);
|
150 |
-
$is_scheduled = true;
|
151 |
-
break;
|
152 |
-
case 'pending':
|
153 |
-
$event = 2073;
|
154 |
-
break;
|
155 |
-
}
|
156 |
-
if ($event) {
|
157 |
-
if ($is_scheduled) {
|
158 |
-
$this->plugin->alerts->Trigger($event, array(
|
159 |
-
'PostType' => $newPost->post_type,
|
160 |
-
'PostTitle' => $newPost->post_title,
|
161 |
-
'PublishingDate' => $newPost->post_date
|
162 |
-
));
|
163 |
-
} else {
|
164 |
-
$this->plugin->alerts->Trigger($event, array(
|
165 |
-
'PostID' => $newPost->ID,
|
166 |
-
'PostType' => $newPost->post_type,
|
167 |
-
'PostTitle' => $newPost->post_title,
|
168 |
-
'PostUrl' => get_permalink($newPost->ID)
|
169 |
-
));
|
170 |
-
}
|
171 |
-
}
|
172 |
-
}
|
173 |
-
|
174 |
-
public function EventPublishFuture($post_id)
|
175 |
-
{
|
176 |
-
$post = get_post($post_id);
|
177 |
-
$event = $this->GetEventTypeForPostType($post, 2001, 2005, 2030);
|
178 |
-
|
179 |
-
if ($event) {
|
180 |
-
$this->plugin->alerts->Trigger($event, array(
|
181 |
-
'PostID' => $post->ID,
|
182 |
-
'PostType' => $post->post_type,
|
183 |
-
'PostTitle' => $post->post_title,
|
184 |
-
'PostUrl' => get_permalink($post->ID)
|
185 |
-
));
|
186 |
-
}
|
187 |
-
}
|
188 |
-
|
189 |
-
protected function CheckCategoryCreation()
|
190 |
-
{
|
191 |
-
if (empty($_POST)) {
|
192 |
-
return;
|
193 |
-
}
|
194 |
-
$categoryName = '';
|
195 |
-
if (!empty($_POST['screen']) && !empty($_POST['tag-name']) &&
|
196 |
-
$_POST['screen'] == 'edit-category' &&
|
197 |
-
$_POST['taxonomy'] == 'category' &&
|
198 |
-
$_POST['action'] == 'add-tag') {
|
199 |
-
$categoryName = $_POST['tag-name'];
|
200 |
-
} elseif (!empty($_POST['newcategory']) && $_POST['action'] == 'add-category') {
|
201 |
-
$categoryName = $_POST['newcategory'];
|
202 |
-
}
|
203 |
-
|
204 |
-
if ($categoryName) {
|
205 |
-
$this->plugin->alerts->Trigger(2023, array(
|
206 |
-
'CategoryName' => $categoryName,
|
207 |
-
));
|
208 |
-
}
|
209 |
-
}
|
210 |
-
|
211 |
-
protected function CheckCategoryDeletion()
|
212 |
-
{
|
213 |
-
if (empty($_POST)) {
|
214 |
-
return;
|
215 |
-
}
|
216 |
-
$action = !empty($_POST['action']) ? $_POST['action']
|
217 |
-
: (!empty($_POST['action2']) ? $_POST['action2'] : '');
|
218 |
-
if (!$action) {
|
219 |
-
return;
|
220 |
-
}
|
221 |
-
|
222 |
-
$categoryIds = array();
|
223 |
-
|
224 |
-
if (isset($_POST['taxonomy'])) {
|
225 |
-
if ($action == 'delete' && $_POST['taxonomy'] == 'category' && !empty($_POST['delete_tags'])) {
|
226 |
-
// bulk delete
|
227 |
-
$categoryIds[] = $_POST['delete_tags'];
|
228 |
-
} elseif ($action == 'delete-tag' && $_POST['taxonomy'] == 'category' && !empty($_POST['tag_ID'])) {
|
229 |
-
// single delete
|
230 |
-
$categoryIds[] = $_POST['tag_ID'];
|
231 |
-
}
|
232 |
-
}
|
233 |
-
|
234 |
-
foreach ($categoryIds as $categoryID) {
|
235 |
-
$category = get_category($categoryID);
|
236 |
-
$this->plugin->alerts->Trigger(2024, array(
|
237 |
-
'CategoryID' => $categoryID,
|
238 |
-
'CategoryName' => $category->cat_name,
|
239 |
-
));
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
public function EventPostDeleted($post_id)
|
244 |
-
{
|
245 |
-
$post = get_post($post_id);
|
246 |
-
if ($this->CheckBBPress($post)) {
|
247 |
-
return;
|
248 |
-
}
|
249 |
-
if (!in_array($post->post_type, array('attachment', 'revision', 'nav_menu_item'))) { // ignore attachments, revisions and menu items
|
250 |
-
$event = $this->GetEventTypeForPostType($post, 2008, 2009, 2033);
|
251 |
-
// check WordPress backend operations
|
252 |
-
if ($this->CheckAutoDraft($event, $post->post_title)) {
|
253 |
-
return;
|
254 |
-
}
|
255 |
-
$this->plugin->alerts->Trigger($event, array(
|
256 |
-
'PostID' => $post->ID,
|
257 |
-
'PostType' => $post->post_type,
|
258 |
-
'PostTitle' => $post->post_title,
|
259 |
-
));
|
260 |
-
}
|
261 |
-
}
|
262 |
-
|
263 |
-
public function EventPostTrashed($post_id)
|
264 |
-
{
|
265 |
-
$post = get_post($post_id);
|
266 |
-
if ($this->CheckBBPress($post)) {
|
267 |
-
return;
|
268 |
-
}
|
269 |
-
$event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
|
270 |
-
$this->plugin->alerts->Trigger($event, array(
|
271 |
-
'PostID' => $post->ID,
|
272 |
-
'PostType' => $post->post_type,
|
273 |
-
'PostTitle' => $post->post_title,
|
274 |
-
));
|
275 |
-
}
|
276 |
-
|
277 |
-
public function EventPostUntrashed($post_id)
|
278 |
-
{
|
279 |
-
$post = get_post($post_id);
|
280 |
-
if ($this->CheckBBPress($post)) {
|
281 |
-
return;
|
282 |
-
}
|
283 |
-
$event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
|
284 |
-
$this->plugin->alerts->Trigger($event, array(
|
285 |
-
'PostID' => $post->ID,
|
286 |
-
'PostType' => $post->post_type,
|
287 |
-
'PostTitle' => $post->post_title,
|
288 |
-
));
|
289 |
-
}
|
290 |
-
|
291 |
-
protected function CheckDateChange($oldpost, $newpost)
|
292 |
-
{
|
293 |
-
$from = strtotime($oldpost->post_date);
|
294 |
-
$to = strtotime($newpost->post_date);
|
295 |
-
if ($oldpost->post_status == 'draft') {
|
296 |
-
return 0;
|
297 |
-
}
|
298 |
-
$pending = $this->CheckReviewPendingChange($oldpost, $newpost);
|
299 |
-
if ($pending) {
|
300 |
-
return 0;
|
301 |
-
}
|
302 |
-
if ($from != $to) {
|
303 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
|
304 |
-
$this->plugin->alerts->Trigger($event, array(
|
305 |
-
'PostID' => $oldpost->ID,
|
306 |
-
'PostType' => $oldpost->post_type,
|
307 |
-
'PostTitle' => $oldpost->post_title,
|
308 |
-
'OldDate' => $oldpost->post_date,
|
309 |
-
'NewDate' => $newpost->post_date,
|
310 |
-
));
|
311 |
-
return 1;
|
312 |
-
}
|
313 |
-
}
|
314 |
-
|
315 |
-
// Revision used
|
316 |
-
protected function CheckReviewPendingChange($oldpost, $newpost)
|
317 |
-
{
|
318 |
-
if ($oldpost->post_status == 'pending') {
|
319 |
-
$this->plugin->alerts->Trigger(2072, array(
|
320 |
-
'PostID' => $oldpost->ID,
|
321 |
-
'PostType' => $oldpost->post_type,
|
322 |
-
'PostTitle' => $oldpost->post_title
|
323 |
-
));
|
324 |
-
return 1;
|
325 |
-
}
|
326 |
-
return 0;
|
327 |
-
}
|
328 |
-
|
329 |
-
protected function CheckCategoriesChange($oldCats, $newCats, $post)
|
330 |
-
{
|
331 |
-
$oldCats = implode(', ', $oldCats);
|
332 |
-
$newCats = implode(', ', $newCats);
|
333 |
-
if ($oldCats != $newCats) {
|
334 |
-
$event = $this->GetEventTypeForPostType($post, 2016, 0, 2036);
|
335 |
-
if ($event) {
|
336 |
-
$this->plugin->alerts->Trigger($event, array(
|
337 |
-
'PostID' => $post->ID,
|
338 |
-
'PostType' => $post->post_type,
|
339 |
-
'PostTitle' => $post->post_title,
|
340 |
-
'OldCategories' => $oldCats ? $oldCats : 'no categories',
|
341 |
-
'NewCategories' => $newCats ? $newCats : 'no categories',
|
342 |
-
));
|
343 |
-
return 1;
|
344 |
-
}
|
345 |
-
}
|
346 |
-
}
|
347 |
-
|
348 |
-
protected function CheckAuthorChange($oldpost, $newpost)
|
349 |
-
{
|
350 |
-
if ($oldpost->post_author != $newpost->post_author) {
|
351 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2019, 2020, 2038);
|
352 |
-
$this->plugin->alerts->Trigger($event, array(
|
353 |
-
'PostID' => $oldpost->ID,
|
354 |
-
'PostType' => $oldpost->post_type,
|
355 |
-
'PostTitle' => $oldpost->post_title,
|
356 |
-
'OldAuthor' => get_userdata($oldpost->post_author)->user_login,
|
357 |
-
'NewAuthor' => get_userdata($newpost->post_author)->user_login,
|
358 |
-
));
|
359 |
-
return 1;
|
360 |
-
}
|
361 |
-
}
|
362 |
-
|
363 |
-
protected function CheckStatusChange($oldpost, $newpost)
|
364 |
-
{
|
365 |
-
if ($oldpost->post_status != $newpost->post_status) {
|
366 |
-
if (isset($_REQUEST['publish'])) {
|
367 |
-
// special case (publishing a post)
|
368 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2001, 2005, 2030);
|
369 |
-
$this->plugin->alerts->Trigger($event, array(
|
370 |
-
'PostID' => $newpost->ID,
|
371 |
-
'PostType' => $newpost->post_type,
|
372 |
-
'PostTitle' => $newpost->post_title,
|
373 |
-
'PostUrl' => get_permalink($newpost->ID),
|
374 |
-
));
|
375 |
-
} else {
|
376 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2021, 2022, 2039);
|
377 |
-
$this->plugin->alerts->Trigger($event, array(
|
378 |
-
'PostID' => $oldpost->ID,
|
379 |
-
'PostType' => $oldpost->post_type,
|
380 |
-
'PostTitle' => $oldpost->post_title,
|
381 |
-
'OldStatus' => $oldpost->post_status,
|
382 |
-
'NewStatus' => $newpost->post_status,
|
383 |
-
));
|
384 |
-
}
|
385 |
-
return 1;
|
386 |
-
}
|
387 |
-
}
|
388 |
-
|
389 |
-
protected function CheckParentChange($oldpost, $newpost)
|
390 |
-
{
|
391 |
-
if ($oldpost->post_parent != $newpost->post_parent) {
|
392 |
-
$event = $this->GetEventTypeForPostType($oldpost, 0, 2047, 0);
|
393 |
-
if ($event) {
|
394 |
-
$this->plugin->alerts->Trigger($event, array(
|
395 |
-
'PostID' => $oldpost->ID,
|
396 |
-
'PostType' => $oldpost->post_type,
|
397 |
-
'PostTitle' => $oldpost->post_title,
|
398 |
-
'OldParent' => $oldpost->post_parent,
|
399 |
-
'NewParent' => $newpost->post_parent,
|
400 |
-
'OldParentName' => $oldpost->post_parent ? get_the_title($oldpost->post_parent) : 'no parent',
|
401 |
-
'NewParentName' => $newpost->post_parent ? get_the_title($newpost->post_parent) : 'no parent',
|
402 |
-
));
|
403 |
-
return 1;
|
404 |
-
}
|
405 |
-
}
|
406 |
-
}
|
407 |
-
|
408 |
-
protected function CheckPermalinkChange($oldLink, $newLink, $post)
|
409 |
-
{
|
410 |
-
if ($oldLink != $newLink) {
|
411 |
-
$event = $this->GetEventTypeForPostType($post, 2017, 2018, 2037);
|
412 |
-
$this->plugin->alerts->Trigger($event, array(
|
413 |
-
'PostID' => $post->ID,
|
414 |
-
'PostType' => $post->post_type,
|
415 |
-
'PostTitle' => $post->post_title,
|
416 |
-
'OldUrl' => $oldLink,
|
417 |
-
'NewUrl' => $newLink,
|
418 |
-
));
|
419 |
-
return 1;
|
420 |
-
}
|
421 |
-
}
|
422 |
-
|
423 |
-
protected function CheckVisibilityChange($oldpost, $newpost, $oldStatus, $newStatus)
|
424 |
-
{
|
425 |
-
if ($oldStatus == 'draft' || $newStatus == 'draft') {
|
426 |
-
return;
|
427 |
-
}
|
428 |
-
|
429 |
-
$oldVisibility = '';
|
430 |
-
$newVisibility = '';
|
431 |
-
|
432 |
-
if ($oldpost->post_password) {
|
433 |
-
$oldVisibility = __('Password Protected', 'wp-security-audit-log');
|
434 |
-
} elseif ($oldStatus == 'publish') {
|
435 |
-
$oldVisibility = __('Public', 'wp-security-audit-log');
|
436 |
-
} elseif ($oldStatus == 'private') {
|
437 |
-
$oldVisibility = __('Private', 'wp-security-audit-log');
|
438 |
-
}
|
439 |
-
|
440 |
-
if ($newpost->post_password) {
|
441 |
-
$newVisibility = __('Password Protected', 'wp-security-audit-log');
|
442 |
-
} elseif ($newStatus == 'publish') {
|
443 |
-
$newVisibility = __('Public', 'wp-security-audit-log');
|
444 |
-
} elseif ($newStatus == 'private') {
|
445 |
-
$newVisibility = __('Private', 'wp-security-audit-log');
|
446 |
-
}
|
447 |
-
|
448 |
-
if ($oldVisibility && $newVisibility && ($oldVisibility != $newVisibility)) {
|
449 |
-
$event = $this->GetEventTypeForPostType($oldpost, 2025, 2026, 2040);
|
450 |
-
$this->plugin->alerts->Trigger($event, array(
|
451 |
-
'PostID' => $oldpost->ID,
|
452 |
-
'PostType' => $oldpost->post_type,
|
453 |
-
'PostTitle' => $oldpost->post_title,
|
454 |
-
'OldVisibility' => $oldVisibility,
|
455 |
-
'NewVisibility' => $newVisibility,
|
456 |
-
));
|
457 |
-
return 1;
|
458 |
-
}
|
459 |
-
}
|
460 |
-
|
461 |
-
protected function CheckTemplateChange($oldTmpl, $newTmpl, $post)
|
462 |
-
{
|
463 |
-
if ($oldTmpl != $newTmpl) {
|
464 |
-
$event = $this->GetEventTypeForPostType($post, 0, 2048, 0);
|
465 |
-
if ($event) {
|
466 |
-
$this->plugin->alerts->Trigger($event, array(
|
467 |
-
'PostID' => $post->ID,
|
468 |
-
'PostType' => $post->post_type,
|
469 |
-
'PostTitle' => $post->post_title,
|
470 |
-
'OldTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($oldTmpl, '.php'))),
|
471 |
-
'NewTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($newTmpl, '.php'))),
|
472 |
-
'OldTemplatePath' => $oldTmpl,
|
473 |
-
'NewTemplatePath' => $newTmpl,
|
474 |
-
));
|
475 |
-
return 1;
|
476 |
-
}
|
477 |
-
}
|
478 |
-
}
|
479 |
-
|
480 |
-
protected function CheckStickyChange($oldStky, $newStky, $post)
|
481 |
-
{
|
482 |
-
if ($oldStky != $newStky) {
|
483 |
-
$event = $newStky ? 2049 : 2050;
|
484 |
-
$this->plugin->alerts->Trigger($event, array(
|
485 |
-
'PostID' => $post->ID,
|
486 |
-
'PostType' => $post->post_type,
|
487 |
-
'PostTitle' => $post->post_title,
|
488 |
-
));
|
489 |
-
return 1;
|
490 |
-
}
|
491 |
-
}
|
492 |
-
|
493 |
-
public function CheckModificationChange($post_ID, $oldpost, $newpost)
|
494 |
-
{
|
495 |
-
if ($this->CheckBBPress($oldpost)) {
|
496 |
-
return;
|
497 |
-
}
|
498 |
-
$changes = 0 + $this->CheckDateChange($oldpost, $newpost)
|
499 |
-
+ $this->CheckTitleChange($oldpost, $newpost);
|
500 |
-
if (!$changes) {
|
501 |
-
$contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
|
502 |
-
|
503 |
-
if ($oldpost->post_modified != $newpost->post_modified) {
|
504 |
-
$event = 0;
|
505 |
-
// @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
|
506 |
-
switch ($oldpost->post_status) { // TODO or should this be $newpost?
|
507 |
-
case 'draft':
|
508 |
-
if ($contentChanged) {
|
509 |
-
$event = $this->GetEventTypeForPostType($newpost, 2068, 2069, 2070);
|
510 |
-
} else {
|
511 |
-
$event = $this->GetEventTypeForPostType($newpost, 2003, 2007, 2032);
|
512 |
-
}
|
513 |
-
break;
|
514 |
-
case 'publish':
|
515 |
-
if ($contentChanged) {
|
516 |
-
$event = $this->GetEventTypeForPostType($newpost, 2065, 2066, 2067);
|
517 |
-
} else {
|
518 |
-
$event = $this->GetEventTypeForPostType($newpost, 2002, 2006, 2031);
|
519 |
-
}
|
520 |
-
break;
|
521 |
-
}
|
522 |
-
if ($event) {
|
523 |
-
$this->plugin->alerts->Trigger($event, array(
|
524 |
-
'PostID' => $post_ID,
|
525 |
-
'PostType' => $oldpost->post_type,
|
526 |
-
'PostTitle' => $oldpost->post_title,
|
527 |
-
'PostUrl' => get_permalink($post_ID) // TODO or should this be $newpost?
|
528 |
-
));
|
529 |
-
return 1;
|
530 |
-
}
|
531 |
-
}
|
532 |
-
}
|
533 |
-
}
|
534 |
-
|
535 |
-
public function EventChangedCategoryParent()
|
536 |
-
{
|
537 |
-
if (empty($_POST)) {
|
538 |
-
return;
|
539 |
-
}
|
540 |
-
if (!current_user_can("manage_categories")) {
|
541 |
-
return;
|
542 |
-
}
|
543 |
-
if (isset($_POST['name'])) {
|
544 |
-
$category = get_category($_POST['tag_ID']);
|
545 |
-
if ($category->parent != 0) {
|
546 |
-
$oldParent = get_category($category->parent);
|
547 |
-
$oldParentName = (empty($oldParent))? 'no parent' : $oldParent->name;
|
548 |
-
} else {
|
549 |
-
$oldParentName = 'no parent';
|
550 |
-
}
|
551 |
-
if (isset($_POST['parent'])) {
|
552 |
-
$newParent = get_category($_POST['parent']);
|
553 |
-
$newParentName = (empty($newParent))? 'no parent' : $newParent->name;
|
554 |
-
}
|
555 |
-
$this->plugin->alerts->Trigger(2052, array(
|
556 |
-
'CategoryName' => $category->name,
|
557 |
-
'OldParent' => $oldParentName,
|
558 |
-
'NewParent' => $newParentName,
|
559 |
-
));
|
560 |
-
}
|
561 |
-
}
|
562 |
-
|
563 |
-
private function CheckAutoDraft($code, $title)
|
564 |
-
{
|
565 |
-
if ($code == 2008 && $title == "auto-draft") {
|
566 |
-
// to do check setting else return false
|
567 |
-
if ($this->plugin->settings->IsWPBackend() == 1) {
|
568 |
-
return true;
|
569 |
-
} else {
|
570 |
-
return false;
|
571 |
-
}
|
572 |
-
} else {
|
573 |
-
return false;
|
574 |
-
}
|
575 |
-
}
|
576 |
-
|
577 |
-
private function getRevisionLink($revision_id)
|
578 |
-
{
|
579 |
-
if (!empty($revision_id)) {
|
580 |
-
return admin_url('revision.php?revision='.$revision_id);
|
581 |
-
} else {
|
582 |
-
return null;
|
583 |
-
}
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
* Ignore post from BBPress Plugin,
|
588 |
-
* Triggered on the BBPress Sensor
|
589 |
-
*/
|
590 |
-
private function CheckBBPress($post)
|
591 |
-
{
|
592 |
-
switch ($post->post_type) {
|
593 |
-
case 'forum':
|
594 |
-
case 'topic':
|
595 |
-
case 'reply':
|
596 |
-
return true;
|
597 |
-
default:
|
598 |
-
return false;
|
599 |
-
}
|
600 |
-
}
|
601 |
-
|
602 |
-
/**
|
603 |
-
* Triggered after save post for add revision link
|
604 |
-
*/
|
605 |
-
public function SetRevisionLink($post_id, $post, $update)
|
606 |
-
{
|
607 |
-
$revisions = wp_get_post_revisions($post_id);
|
608 |
-
if (!empty($revisions)) {
|
609 |
-
$revision = array_shift($revisions);
|
610 |
-
|
611 |
-
$objOcc = new WSAL_Models_Occurrence();
|
612 |
-
$occ = $objOcc->GetByPostID($post_id);
|
613 |
-
$occ = count($occ) ? $occ[0] : null;
|
614 |
-
if (!empty($occ)) {
|
615 |
-
$revisionLink = $this->getRevisionLink($revision->ID);
|
616 |
-
if (!empty($revisionLink)) {
|
617 |
-
$occ->SetMetaValue('RevisionLink', $revisionLink);
|
618 |
-
}
|
619 |
-
}
|
620 |
-
}
|
621 |
-
}
|
622 |
-
|
623 |
-
private function CheckTitleChange($oldpost, $newpost)
|
624 |
-
{
|
625 |
-
if ($oldpost->post_title != $newpost->post_title) {
|
626 |
-
$event = $this->GetEventTypeForPostType($newpost, 2086, 2087, 2088);
|
627 |
-
$this->plugin->alerts->Trigger($event, array(
|
628 |
-
'OldTitle' => $oldpost->post_title,
|
629 |
-
'NewTitle' => $newpost->post_title,
|
630 |
-
));
|
631 |
-
return 1;
|
632 |
-
}
|
633 |
-
return 0;
|
634 |
-
}
|
635 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Content extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
|
6 |
+
public function HookEvents()
|
7 |
+
{
|
8 |
+
if (current_user_can("edit_posts")) {
|
9 |
+
add_action('admin_init', array($this, 'EventWordpressInit'));
|
10 |
+
}
|
11 |
+
add_action('transition_post_status', array($this, 'EventPostChanged'), 10, 3);
|
12 |
+
add_action('delete_post', array($this, 'EventPostDeleted'), 10, 1);
|
13 |
+
add_action('wp_trash_post', array($this, 'EventPostTrashed'), 10, 1);
|
14 |
+
add_action('untrash_post', array($this, 'EventPostUntrashed'));
|
15 |
+
add_action('edit_category', array($this, 'EventChangedCategoryParent'));
|
16 |
+
add_action('save_post', array($this, 'SetRevisionLink'), 10, 3);
|
17 |
+
add_action('publish_future_post', array($this, 'EventPublishFuture'), 10, 1);
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
|
21 |
+
{
|
22 |
+
switch ($post->post_type) {
|
23 |
+
case 'page':
|
24 |
+
return $typePage;
|
25 |
+
case 'post':
|
26 |
+
return $typePost;
|
27 |
+
default:
|
28 |
+
return $typeCustom;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
protected $_OldPost = null;
|
33 |
+
protected $_OldLink = null;
|
34 |
+
protected $_OldCats = null;
|
35 |
+
protected $_OldTmpl = null;
|
36 |
+
protected $_OldStky = null;
|
37 |
+
|
38 |
+
public function EventWordpressInit()
|
39 |
+
{
|
40 |
+
// load old data, if applicable
|
41 |
+
$this->RetrieveOldData();
|
42 |
+
// check for category changes
|
43 |
+
$this->CheckCategoryCreation();
|
44 |
+
$this->CheckCategoryDeletion();
|
45 |
+
}
|
46 |
+
|
47 |
+
protected function RetrieveOldData()
|
48 |
+
{
|
49 |
+
if (isset($_POST) && isset($_POST['post_ID'])
|
50 |
+
&& !(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
|
51 |
+
&& !(isset($_POST['action']) && $_POST['action'] == 'autosave')
|
52 |
+
) {
|
53 |
+
$postID = intval($_POST['post_ID']);
|
54 |
+
$this->_OldPost = get_post($postID);
|
55 |
+
$this->_OldLink = get_permalink($postID);
|
56 |
+
$this->_OldTmpl = $this->GetPostTemplate($this->_OldPost);
|
57 |
+
$this->_OldCats = $this->GetPostCategories($this->_OldPost);
|
58 |
+
$this->_OldStky = in_array($postID, get_option('sticky_posts'));
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
protected function GetPostTemplate($post)
|
63 |
+
{
|
64 |
+
$id = $post->ID;
|
65 |
+
$template = get_page_template_slug($id);
|
66 |
+
$pagename = $post->post_name;
|
67 |
+
|
68 |
+
$templates = array();
|
69 |
+
if ($template && 0 === validate_file($template)) {
|
70 |
+
$templates[] = $template;
|
71 |
+
}
|
72 |
+
if ($pagename) {
|
73 |
+
$templates[] = "page-$pagename.php";
|
74 |
+
}
|
75 |
+
if ($id) {
|
76 |
+
$templates[] = "page-$id.php";
|
77 |
+
}
|
78 |
+
$templates[] = 'page.php';
|
79 |
+
|
80 |
+
return get_query_template('page', $templates);
|
81 |
+
}
|
82 |
+
|
83 |
+
protected function GetPostCategories($post)
|
84 |
+
{
|
85 |
+
return wp_get_post_categories($post->ID, array('fields' => 'names'));
|
86 |
+
}
|
87 |
+
|
88 |
+
public function EventPostChanged($newStatus, $oldStatus, $post)
|
89 |
+
{
|
90 |
+
// ignorable states
|
91 |
+
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
92 |
+
return;
|
93 |
+
}
|
94 |
+
if (empty($post->post_type)) {
|
95 |
+
return;
|
96 |
+
}
|
97 |
+
if ($post->post_type == 'revision') {
|
98 |
+
return;
|
99 |
+
}
|
100 |
+
|
101 |
+
$original = isset($_POST['original_post_status']) ? $_POST['original_post_status'] : '';
|
102 |
+
|
103 |
+
WSAL_Sensors_Request::SetVars(array(
|
104 |
+
'$newStatus' => $newStatus,
|
105 |
+
'$oldStatus' => $oldStatus,
|
106 |
+
'$original' => $original,
|
107 |
+
));
|
108 |
+
// run checks
|
109 |
+
if ($this->_OldPost) {
|
110 |
+
if ($this->CheckBBPress($this->_OldPost)) {
|
111 |
+
return;
|
112 |
+
}
|
113 |
+
if ($oldStatus == 'auto-draft' || $original == 'auto-draft') {
|
114 |
+
// Handle create post events
|
115 |
+
$this->CheckPostCreation($this->_OldPost, $post);
|
116 |
+
} else {
|
117 |
+
// Handle update post events
|
118 |
+
$changes = 0
|
119 |
+
+ $this->CheckAuthorChange($this->_OldPost, $post)
|
120 |
+
+ $this->CheckStatusChange($this->_OldPost, $post)
|
121 |
+
+ $this->CheckParentChange($this->_OldPost, $post)
|
122 |
+
+ $this->CheckStickyChange($this->_OldStky, isset($_REQUEST['sticky']), $post)
|
123 |
+
+ $this->CheckVisibilityChange($this->_OldPost, $post, $oldStatus, $newStatus)
|
124 |
+
+ $this->CheckTemplateChange($this->_OldTmpl, $this->GetPostTemplate($post), $post)
|
125 |
+
+ $this->CheckCategoriesChange($this->_OldCats, $this->GetPostCategories($post), $post)
|
126 |
+
;
|
127 |
+
if (!$changes) {
|
128 |
+
$changes = $this->CheckPermalinkChange($this->_OldLink, get_permalink($post->ID), $post);
|
129 |
+
}
|
130 |
+
if (!$changes) {
|
131 |
+
$changes = $this->CheckModificationChange($post->ID, $this->_OldPost, $post);
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
protected function CheckPostCreation($oldPost, $newPost)
|
138 |
+
{
|
139 |
+
$event = 0;
|
140 |
+
$is_scheduled = false;
|
141 |
+
switch ($newPost->post_status) {
|
142 |
+
case 'publish':
|
143 |
+
$event = $this->GetEventTypeForPostType($oldPost, 2001, 2005, 2030);
|
144 |
+
break;
|
145 |
+
case 'draft':
|
146 |
+
$event = $this->GetEventTypeForPostType($oldPost, 2000, 2004, 2029);
|
147 |
+
break;
|
148 |
+
case 'future':
|
149 |
+
$event = $this->GetEventTypeForPostType($oldPost, 2074, 2075, 2076);
|
150 |
+
$is_scheduled = true;
|
151 |
+
break;
|
152 |
+
case 'pending':
|
153 |
+
$event = 2073;
|
154 |
+
break;
|
155 |
+
}
|
156 |
+
if ($event) {
|
157 |
+
if ($is_scheduled) {
|
158 |
+
$this->plugin->alerts->Trigger($event, array(
|
159 |
+
'PostType' => $newPost->post_type,
|
160 |
+
'PostTitle' => $newPost->post_title,
|
161 |
+
'PublishingDate' => $newPost->post_date
|
162 |
+
));
|
163 |
+
} else {
|
164 |
+
$this->plugin->alerts->Trigger($event, array(
|
165 |
+
'PostID' => $newPost->ID,
|
166 |
+
'PostType' => $newPost->post_type,
|
167 |
+
'PostTitle' => $newPost->post_title,
|
168 |
+
'PostUrl' => get_permalink($newPost->ID)
|
169 |
+
));
|
170 |
+
}
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
+
public function EventPublishFuture($post_id)
|
175 |
+
{
|
176 |
+
$post = get_post($post_id);
|
177 |
+
$event = $this->GetEventTypeForPostType($post, 2001, 2005, 2030);
|
178 |
+
|
179 |
+
if ($event) {
|
180 |
+
$this->plugin->alerts->Trigger($event, array(
|
181 |
+
'PostID' => $post->ID,
|
182 |
+
'PostType' => $post->post_type,
|
183 |
+
'PostTitle' => $post->post_title,
|
184 |
+
'PostUrl' => get_permalink($post->ID)
|
185 |
+
));
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
protected function CheckCategoryCreation()
|
190 |
+
{
|
191 |
+
if (empty($_POST)) {
|
192 |
+
return;
|
193 |
+
}
|
194 |
+
$categoryName = '';
|
195 |
+
if (!empty($_POST['screen']) && !empty($_POST['tag-name']) &&
|
196 |
+
$_POST['screen'] == 'edit-category' &&
|
197 |
+
$_POST['taxonomy'] == 'category' &&
|
198 |
+
$_POST['action'] == 'add-tag') {
|
199 |
+
$categoryName = $_POST['tag-name'];
|
200 |
+
} elseif (!empty($_POST['newcategory']) && $_POST['action'] == 'add-category') {
|
201 |
+
$categoryName = $_POST['newcategory'];
|
202 |
+
}
|
203 |
+
|
204 |
+
if ($categoryName) {
|
205 |
+
$this->plugin->alerts->Trigger(2023, array(
|
206 |
+
'CategoryName' => $categoryName,
|
207 |
+
));
|
208 |
+
}
|
209 |
+
}
|
210 |
+
|
211 |
+
protected function CheckCategoryDeletion()
|
212 |
+
{
|
213 |
+
if (empty($_POST)) {
|
214 |
+
return;
|
215 |
+
}
|
216 |
+
$action = !empty($_POST['action']) ? $_POST['action']
|
217 |
+
: (!empty($_POST['action2']) ? $_POST['action2'] : '');
|
218 |
+
if (!$action) {
|
219 |
+
return;
|
220 |
+
}
|
221 |
+
|
222 |
+
$categoryIds = array();
|
223 |
+
|
224 |
+
if (isset($_POST['taxonomy'])) {
|
225 |
+
if ($action == 'delete' && $_POST['taxonomy'] == 'category' && !empty($_POST['delete_tags'])) {
|
226 |
+
// bulk delete
|
227 |
+
$categoryIds[] = $_POST['delete_tags'];
|
228 |
+
} elseif ($action == 'delete-tag' && $_POST['taxonomy'] == 'category' && !empty($_POST['tag_ID'])) {
|
229 |
+
// single delete
|
230 |
+
$categoryIds[] = $_POST['tag_ID'];
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
foreach ($categoryIds as $categoryID) {
|
235 |
+
$category = get_category($categoryID);
|
236 |
+
$this->plugin->alerts->Trigger(2024, array(
|
237 |
+
'CategoryID' => $categoryID,
|
238 |
+
'CategoryName' => $category->cat_name,
|
239 |
+
));
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
public function EventPostDeleted($post_id)
|
244 |
+
{
|
245 |
+
$post = get_post($post_id);
|
246 |
+
if ($this->CheckBBPress($post)) {
|
247 |
+
return;
|
248 |
+
}
|
249 |
+
if (!in_array($post->post_type, array('attachment', 'revision', 'nav_menu_item'))) { // ignore attachments, revisions and menu items
|
250 |
+
$event = $this->GetEventTypeForPostType($post, 2008, 2009, 2033);
|
251 |
+
// check WordPress backend operations
|
252 |
+
if ($this->CheckAutoDraft($event, $post->post_title)) {
|
253 |
+
return;
|
254 |
+
}
|
255 |
+
$this->plugin->alerts->Trigger($event, array(
|
256 |
+
'PostID' => $post->ID,
|
257 |
+
'PostType' => $post->post_type,
|
258 |
+
'PostTitle' => $post->post_title,
|
259 |
+
));
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
public function EventPostTrashed($post_id)
|
264 |
+
{
|
265 |
+
$post = get_post($post_id);
|
266 |
+
if ($this->CheckBBPress($post)) {
|
267 |
+
return;
|
268 |
+
}
|
269 |
+
$event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
|
270 |
+
$this->plugin->alerts->Trigger($event, array(
|
271 |
+
'PostID' => $post->ID,
|
272 |
+
'PostType' => $post->post_type,
|
273 |
+
'PostTitle' => $post->post_title,
|
274 |
+
));
|
275 |
+
}
|
276 |
+
|
277 |
+
public function EventPostUntrashed($post_id)
|
278 |
+
{
|
279 |
+
$post = get_post($post_id);
|
280 |
+
if ($this->CheckBBPress($post)) {
|
281 |
+
return;
|
282 |
+
}
|
283 |
+
$event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
|
284 |
+
$this->plugin->alerts->Trigger($event, array(
|
285 |
+
'PostID' => $post->ID,
|
286 |
+
'PostType' => $post->post_type,
|
287 |
+
'PostTitle' => $post->post_title,
|
288 |
+
));
|
289 |
+
}
|
290 |
+
|
291 |
+
protected function CheckDateChange($oldpost, $newpost)
|
292 |
+
{
|
293 |
+
$from = strtotime($oldpost->post_date);
|
294 |
+
$to = strtotime($newpost->post_date);
|
295 |
+
if ($oldpost->post_status == 'draft') {
|
296 |
+
return 0;
|
297 |
+
}
|
298 |
+
$pending = $this->CheckReviewPendingChange($oldpost, $newpost);
|
299 |
+
if ($pending) {
|
300 |
+
return 0;
|
301 |
+
}
|
302 |
+
if ($from != $to) {
|
303 |
+
$event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
|
304 |
+
$this->plugin->alerts->Trigger($event, array(
|
305 |
+
'PostID' => $oldpost->ID,
|
306 |
+
'PostType' => $oldpost->post_type,
|
307 |
+
'PostTitle' => $oldpost->post_title,
|
308 |
+
'OldDate' => $oldpost->post_date,
|
309 |
+
'NewDate' => $newpost->post_date,
|
310 |
+
));
|
311 |
+
return 1;
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
// Revision used
|
316 |
+
protected function CheckReviewPendingChange($oldpost, $newpost)
|
317 |
+
{
|
318 |
+
if ($oldpost->post_status == 'pending') {
|
319 |
+
$this->plugin->alerts->Trigger(2072, array(
|
320 |
+
'PostID' => $oldpost->ID,
|
321 |
+
'PostType' => $oldpost->post_type,
|
322 |
+
'PostTitle' => $oldpost->post_title
|
323 |
+
));
|
324 |
+
return 1;
|
325 |
+
}
|
326 |
+
return 0;
|
327 |
+
}
|
328 |
+
|
329 |
+
protected function CheckCategoriesChange($oldCats, $newCats, $post)
|
330 |
+
{
|
331 |
+
$oldCats = implode(', ', $oldCats);
|
332 |
+
$newCats = implode(', ', $newCats);
|
333 |
+
if ($oldCats != $newCats) {
|
334 |
+
$event = $this->GetEventTypeForPostType($post, 2016, 0, 2036);
|
335 |
+
if ($event) {
|
336 |
+
$this->plugin->alerts->Trigger($event, array(
|
337 |
+
'PostID' => $post->ID,
|
338 |
+
'PostType' => $post->post_type,
|
339 |
+
'PostTitle' => $post->post_title,
|
340 |
+
'OldCategories' => $oldCats ? $oldCats : 'no categories',
|
341 |
+
'NewCategories' => $newCats ? $newCats : 'no categories',
|
342 |
+
));
|
343 |
+
return 1;
|
344 |
+
}
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
protected function CheckAuthorChange($oldpost, $newpost)
|
349 |
+
{
|
350 |
+
if ($oldpost->post_author != $newpost->post_author) {
|
351 |
+
$event = $this->GetEventTypeForPostType($oldpost, 2019, 2020, 2038);
|
352 |
+
$this->plugin->alerts->Trigger($event, array(
|
353 |
+
'PostID' => $oldpost->ID,
|
354 |
+
'PostType' => $oldpost->post_type,
|
355 |
+
'PostTitle' => $oldpost->post_title,
|
356 |
+
'OldAuthor' => get_userdata($oldpost->post_author)->user_login,
|
357 |
+
'NewAuthor' => get_userdata($newpost->post_author)->user_login,
|
358 |
+
));
|
359 |
+
return 1;
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
protected function CheckStatusChange($oldpost, $newpost)
|
364 |
+
{
|
365 |
+
if ($oldpost->post_status != $newpost->post_status) {
|
366 |
+
if (isset($_REQUEST['publish'])) {
|
367 |
+
// special case (publishing a post)
|
368 |
+
$event = $this->GetEventTypeForPostType($oldpost, 2001, 2005, 2030);
|
369 |
+
$this->plugin->alerts->Trigger($event, array(
|
370 |
+
'PostID' => $newpost->ID,
|
371 |
+
'PostType' => $newpost->post_type,
|
372 |
+
'PostTitle' => $newpost->post_title,
|
373 |
+
'PostUrl' => get_permalink($newpost->ID),
|
374 |
+
));
|
375 |
+
} else {
|
376 |
+
$event = $this->GetEventTypeForPostType($oldpost, 2021, 2022, 2039);
|
377 |
+
$this->plugin->alerts->Trigger($event, array(
|
378 |
+
'PostID' => $oldpost->ID,
|
379 |
+
'PostType' => $oldpost->post_type,
|
380 |
+
'PostTitle' => $oldpost->post_title,
|
381 |
+
'OldStatus' => $oldpost->post_status,
|
382 |
+
'NewStatus' => $newpost->post_status,
|
383 |
+
));
|
384 |
+
}
|
385 |
+
return 1;
|
386 |
+
}
|
387 |
+
}
|
388 |
+
|
389 |
+
protected function CheckParentChange($oldpost, $newpost)
|
390 |
+
{
|
391 |
+
if ($oldpost->post_parent != $newpost->post_parent) {
|
392 |
+
$event = $this->GetEventTypeForPostType($oldpost, 0, 2047, 0);
|
393 |
+
if ($event) {
|
394 |
+
$this->plugin->alerts->Trigger($event, array(
|
395 |
+
'PostID' => $oldpost->ID,
|
396 |
+
'PostType' => $oldpost->post_type,
|
397 |
+
'PostTitle' => $oldpost->post_title,
|
398 |
+
'OldParent' => $oldpost->post_parent,
|
399 |
+
'NewParent' => $newpost->post_parent,
|
400 |
+
'OldParentName' => $oldpost->post_parent ? get_the_title($oldpost->post_parent) : 'no parent',
|
401 |
+
'NewParentName' => $newpost->post_parent ? get_the_title($newpost->post_parent) : 'no parent',
|
402 |
+
));
|
403 |
+
return 1;
|
404 |
+
}
|
405 |
+
}
|
406 |
+
}
|
407 |
+
|
408 |
+
protected function CheckPermalinkChange($oldLink, $newLink, $post)
|
409 |
+
{
|
410 |
+
if ($oldLink != $newLink) {
|
411 |
+
$event = $this->GetEventTypeForPostType($post, 2017, 2018, 2037);
|
412 |
+
$this->plugin->alerts->Trigger($event, array(
|
413 |
+
'PostID' => $post->ID,
|
414 |
+
'PostType' => $post->post_type,
|
415 |
+
'PostTitle' => $post->post_title,
|
416 |
+
'OldUrl' => $oldLink,
|
417 |
+
'NewUrl' => $newLink,
|
418 |
+
));
|
419 |
+
return 1;
|
420 |
+
}
|
421 |
+
}
|
422 |
+
|
423 |
+
protected function CheckVisibilityChange($oldpost, $newpost, $oldStatus, $newStatus)
|
424 |
+
{
|
425 |
+
if ($oldStatus == 'draft' || $newStatus == 'draft') {
|
426 |
+
return;
|
427 |
+
}
|
428 |
+
|
429 |
+
$oldVisibility = '';
|
430 |
+
$newVisibility = '';
|
431 |
+
|
432 |
+
if ($oldpost->post_password) {
|
433 |
+
$oldVisibility = __('Password Protected', 'wp-security-audit-log');
|
434 |
+
} elseif ($oldStatus == 'publish') {
|
435 |
+
$oldVisibility = __('Public', 'wp-security-audit-log');
|
436 |
+
} elseif ($oldStatus == 'private') {
|
437 |
+
$oldVisibility = __('Private', 'wp-security-audit-log');
|
438 |
+
}
|
439 |
+
|
440 |
+
if ($newpost->post_password) {
|
441 |
+
$newVisibility = __('Password Protected', 'wp-security-audit-log');
|
442 |
+
} elseif ($newStatus == 'publish') {
|
443 |
+
$newVisibility = __('Public', 'wp-security-audit-log');
|
444 |
+
} elseif ($newStatus == 'private') {
|
445 |
+
$newVisibility = __('Private', 'wp-security-audit-log');
|
446 |
+
}
|
447 |
+
|
448 |
+
if ($oldVisibility && $newVisibility && ($oldVisibility != $newVisibility)) {
|
449 |
+
$event = $this->GetEventTypeForPostType($oldpost, 2025, 2026, 2040);
|
450 |
+
$this->plugin->alerts->Trigger($event, array(
|
451 |
+
'PostID' => $oldpost->ID,
|
452 |
+
'PostType' => $oldpost->post_type,
|
453 |
+
'PostTitle' => $oldpost->post_title,
|
454 |
+
'OldVisibility' => $oldVisibility,
|
455 |
+
'NewVisibility' => $newVisibility,
|
456 |
+
));
|
457 |
+
return 1;
|
458 |
+
}
|
459 |
+
}
|
460 |
+
|
461 |
+
protected function CheckTemplateChange($oldTmpl, $newTmpl, $post)
|
462 |
+
{
|
463 |
+
if ($oldTmpl != $newTmpl) {
|
464 |
+
$event = $this->GetEventTypeForPostType($post, 0, 2048, 0);
|
465 |
+
if ($event) {
|
466 |
+
$this->plugin->alerts->Trigger($event, array(
|
467 |
+
'PostID' => $post->ID,
|
468 |
+
'PostType' => $post->post_type,
|
469 |
+
'PostTitle' => $post->post_title,
|
470 |
+
'OldTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($oldTmpl, '.php'))),
|
471 |
+
'NewTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($newTmpl, '.php'))),
|
472 |
+
'OldTemplatePath' => $oldTmpl,
|
473 |
+
'NewTemplatePath' => $newTmpl,
|
474 |
+
));
|
475 |
+
return 1;
|
476 |
+
}
|
477 |
+
}
|
478 |
+
}
|
479 |
+
|
480 |
+
protected function CheckStickyChange($oldStky, $newStky, $post)
|
481 |
+
{
|
482 |
+
if ($oldStky != $newStky) {
|
483 |
+
$event = $newStky ? 2049 : 2050;
|
484 |
+
$this->plugin->alerts->Trigger($event, array(
|
485 |
+
'PostID' => $post->ID,
|
486 |
+
'PostType' => $post->post_type,
|
487 |
+
'PostTitle' => $post->post_title,
|
488 |
+
));
|
489 |
+
return 1;
|
490 |
+
}
|
491 |
+
}
|
492 |
+
|
493 |
+
public function CheckModificationChange($post_ID, $oldpost, $newpost)
|
494 |
+
{
|
495 |
+
if ($this->CheckBBPress($oldpost)) {
|
496 |
+
return;
|
497 |
+
}
|
498 |
+
$changes = 0 + $this->CheckDateChange($oldpost, $newpost)
|
499 |
+
+ $this->CheckTitleChange($oldpost, $newpost);
|
500 |
+
if (!$changes) {
|
501 |
+
$contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
|
502 |
+
|
503 |
+
if ($oldpost->post_modified != $newpost->post_modified) {
|
504 |
+
$event = 0;
|
505 |
+
// @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
|
506 |
+
switch ($oldpost->post_status) { // TODO or should this be $newpost?
|
507 |
+
case 'draft':
|
508 |
+
if ($contentChanged) {
|
509 |
+
$event = $this->GetEventTypeForPostType($newpost, 2068, 2069, 2070);
|
510 |
+
} else {
|
511 |
+
$event = $this->GetEventTypeForPostType($newpost, 2003, 2007, 2032);
|
512 |
+
}
|
513 |
+
break;
|
514 |
+
case 'publish':
|
515 |
+
if ($contentChanged) {
|
516 |
+
$event = $this->GetEventTypeForPostType($newpost, 2065, 2066, 2067);
|
517 |
+
} else {
|
518 |
+
$event = $this->GetEventTypeForPostType($newpost, 2002, 2006, 2031);
|
519 |
+
}
|
520 |
+
break;
|
521 |
+
}
|
522 |
+
if ($event) {
|
523 |
+
$this->plugin->alerts->Trigger($event, array(
|
524 |
+
'PostID' => $post_ID,
|
525 |
+
'PostType' => $oldpost->post_type,
|
526 |
+
'PostTitle' => $oldpost->post_title,
|
527 |
+
'PostUrl' => get_permalink($post_ID) // TODO or should this be $newpost?
|
528 |
+
));
|
529 |
+
return 1;
|
530 |
+
}
|
531 |
+
}
|
532 |
+
}
|
533 |
+
}
|
534 |
+
|
535 |
+
public function EventChangedCategoryParent()
|
536 |
+
{
|
537 |
+
if (empty($_POST)) {
|
538 |
+
return;
|
539 |
+
}
|
540 |
+
if (!current_user_can("manage_categories")) {
|
541 |
+
return;
|
542 |
+
}
|
543 |
+
if (isset($_POST['name'])) {
|
544 |
+
$category = get_category($_POST['tag_ID']);
|
545 |
+
if ($category->parent != 0) {
|
546 |
+
$oldParent = get_category($category->parent);
|
547 |
+
$oldParentName = (empty($oldParent))? 'no parent' : $oldParent->name;
|
548 |
+
} else {
|
549 |
+
$oldParentName = 'no parent';
|
550 |
+
}
|
551 |
+
if (isset($_POST['parent'])) {
|
552 |
+
$newParent = get_category($_POST['parent']);
|
553 |
+
$newParentName = (empty($newParent))? 'no parent' : $newParent->name;
|
554 |
+
}
|
555 |
+
$this->plugin->alerts->Trigger(2052, array(
|
556 |
+
'CategoryName' => $category->name,
|
557 |
+
'OldParent' => $oldParentName,
|
558 |
+
'NewParent' => $newParentName,
|
559 |
+
));
|
560 |
+
}
|
561 |
+
}
|
562 |
+
|
563 |
+
private function CheckAutoDraft($code, $title)
|
564 |
+
{
|
565 |
+
if ($code == 2008 && $title == "auto-draft") {
|
566 |
+
// to do check setting else return false
|
567 |
+
if ($this->plugin->settings->IsWPBackend() == 1) {
|
568 |
+
return true;
|
569 |
+
} else {
|
570 |
+
return false;
|
571 |
+
}
|
572 |
+
} else {
|
573 |
+
return false;
|
574 |
+
}
|
575 |
+
}
|
576 |
+
|
577 |
+
private function getRevisionLink($revision_id)
|
578 |
+
{
|
579 |
+
if (!empty($revision_id)) {
|
580 |
+
return admin_url('revision.php?revision='.$revision_id);
|
581 |
+
} else {
|
582 |
+
return null;
|
583 |
+
}
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Ignore post from BBPress Plugin,
|
588 |
+
* Triggered on the BBPress Sensor
|
589 |
+
*/
|
590 |
+
private function CheckBBPress($post)
|
591 |
+
{
|
592 |
+
switch ($post->post_type) {
|
593 |
+
case 'forum':
|
594 |
+
case 'topic':
|
595 |
+
case 'reply':
|
596 |
+
return true;
|
597 |
+
default:
|
598 |
+
return false;
|
599 |
+
}
|
600 |
+
}
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Triggered after save post for add revision link
|
604 |
+
*/
|
605 |
+
public function SetRevisionLink($post_id, $post, $update)
|
606 |
+
{
|
607 |
+
$revisions = wp_get_post_revisions($post_id);
|
608 |
+
if (!empty($revisions)) {
|
609 |
+
$revision = array_shift($revisions);
|
610 |
+
|
611 |
+
$objOcc = new WSAL_Models_Occurrence();
|
612 |
+
$occ = $objOcc->GetByPostID($post_id);
|
613 |
+
$occ = count($occ) ? $occ[0] : null;
|
614 |
+
if (!empty($occ)) {
|
615 |
+
$revisionLink = $this->getRevisionLink($revision->ID);
|
616 |
+
if (!empty($revisionLink)) {
|
617 |
+
$occ->SetMetaValue('RevisionLink', $revisionLink);
|
618 |
+
}
|
619 |
+
}
|
620 |
+
}
|
621 |
+
}
|
622 |
+
|
623 |
+
private function CheckTitleChange($oldpost, $newpost)
|
624 |
+
{
|
625 |
+
if ($oldpost->post_title != $newpost->post_title) {
|
626 |
+
$event = $this->GetEventTypeForPostType($newpost, 2086, 2087, 2088);
|
627 |
+
$this->plugin->alerts->Trigger($event, array(
|
628 |
+
'OldTitle' => $oldpost->post_title,
|
629 |
+
'NewTitle' => $newpost->post_title,
|
630 |
+
));
|
631 |
+
return 1;
|
632 |
+
}
|
633 |
+
return 0;
|
634 |
+
}
|
635 |
+
}
|
classes/Sensors/CustomHooks.php
CHANGED
@@ -1,49 +1,49 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* The Class is used to allow developers to create
|
4 |
-
* custom alerts
|
5 |
-
*/
|
6 |
-
class WSAL_Sensors_CustomHooks extends WSAL_AbstractSensor
|
7 |
-
{
|
8 |
-
public function HookEvents()
|
9 |
-
{
|
10 |
-
/**
|
11 |
-
* Use add_action() for every hook and pass the following:
|
12 |
-
* @param string sample_hook_name
|
13 |
-
* @param string SampleFunction - the name of the function above
|
14 |
-
* @param int 10 - priority (Optional)
|
15 |
-
* @param int 2 - number of parameters passed to the function (Optional)(Check the hook documentation)
|
16 |
-
* @see http://adambrown.info/p/wp_hooks for more information on WordPress hooks
|
17 |
-
*/
|
18 |
-
add_action('sample_hook_name', array($this, 'SampleFunction'), 10, 2);
|
19 |
-
}
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Sample function with 0 or more parameters.
|
23 |
-
* Create one function for each hook:
|
24 |
-
* @param anyType $paramname (Optional)
|
25 |
-
*/
|
26 |
-
public function SampleFunction($value_1 = null, $value_2 = null)
|
27 |
-
{
|
28 |
-
/**
|
29 |
-
* @var int (4 digit) $alertCode Alert code (3 types of criticality level)
|
30 |
-
* @example Critical 2222, Warning 3333, Notice 4444
|
31 |
-
*/
|
32 |
-
$alertCode = 2222;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @var string: the alert text
|
36 |
-
*/
|
37 |
-
$alertText = 'Sample alert text';
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @var array $variables used in the alert (With 1 or more elements)
|
41 |
-
* { @var string $alertText }
|
42 |
-
*/
|
43 |
-
$variables = array(
|
44 |
-
'CustomAlertText' => $alertText
|
45 |
-
);
|
46 |
-
|
47 |
-
$this->plugin->alerts->Trigger($alertCode, $variables);
|
48 |
-
}
|
49 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* The Class is used to allow developers to create
|
4 |
+
* custom alerts
|
5 |
+
*/
|
6 |
+
class WSAL_Sensors_CustomHooks extends WSAL_AbstractSensor
|
7 |
+
{
|
8 |
+
public function HookEvents()
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Use add_action() for every hook and pass the following:
|
12 |
+
* @param string sample_hook_name
|
13 |
+
* @param string SampleFunction - the name of the function above
|
14 |
+
* @param int 10 - priority (Optional)
|
15 |
+
* @param int 2 - number of parameters passed to the function (Optional)(Check the hook documentation)
|
16 |
+
* @see http://adambrown.info/p/wp_hooks for more information on WordPress hooks
|
17 |
+
*/
|
18 |
+
add_action('sample_hook_name', array($this, 'SampleFunction'), 10, 2);
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Sample function with 0 or more parameters.
|
23 |
+
* Create one function for each hook:
|
24 |
+
* @param anyType $paramname (Optional)
|
25 |
+
*/
|
26 |
+
public function SampleFunction($value_1 = null, $value_2 = null)
|
27 |
+
{
|
28 |
+
/**
|
29 |
+
* @var int (4 digit) $alertCode Alert code (3 types of criticality level)
|
30 |
+
* @example Critical 2222, Warning 3333, Notice 4444
|
31 |
+
*/
|
32 |
+
$alertCode = 2222;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var string: the alert text
|
36 |
+
*/
|
37 |
+
$alertText = 'Sample alert text';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @var array $variables used in the alert (With 1 or more elements)
|
41 |
+
* { @var string $alertText }
|
42 |
+
*/
|
43 |
+
$variables = array(
|
44 |
+
'CustomAlertText' => $alertText
|
45 |
+
);
|
46 |
+
|
47 |
+
$this->plugin->alerts->Trigger($alertCode, $variables);
|
48 |
+
}
|
49 |
+
}
|
classes/Sensors/Database.php
CHANGED
@@ -1,132 +1,132 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Database extends WSAL_AbstractSensor
|
4 |
-
{
|
5 |
-
public function HookEvents()
|
6 |
-
{
|
7 |
-
add_action('dbdelta_queries', array($this, 'EventDBDeltaQuery'));
|
8 |
-
add_action('query', array($this, 'EventDropQuery'));
|
9 |
-
}
|
10 |
-
|
11 |
-
public function EventDropQuery($query)
|
12 |
-
{
|
13 |
-
$table_names = array();
|
14 |
-
$str = explode(" ", $query);
|
15 |
-
|
16 |
-
if (preg_match("|DROP TABLE ([^ ]*)|", $query)) {
|
17 |
-
if (!empty($str[4])) {
|
18 |
-
array_push($table_names, $str[4]);
|
19 |
-
} else {
|
20 |
-
array_push($table_names, $str[2]);
|
21 |
-
}
|
22 |
-
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
23 |
-
$alertOptions = $this->GetActionType($actype);
|
24 |
-
}
|
25 |
-
|
26 |
-
if (!empty($table_names)) {
|
27 |
-
$event_code = $this->GetEventQueryType($actype, "delete");
|
28 |
-
$alertOptions["TableNames"] = implode(",", $table_names);
|
29 |
-
$this->plugin->alerts->Trigger($event_code, $alertOptions);
|
30 |
-
}
|
31 |
-
return $query;
|
32 |
-
}
|
33 |
-
|
34 |
-
public function EventDBDeltaQuery($queries)
|
35 |
-
{
|
36 |
-
$typeQueries = array(
|
37 |
-
"create" => array(),
|
38 |
-
"update" => array(),
|
39 |
-
"delete" => array()
|
40 |
-
);
|
41 |
-
global $wpdb;
|
42 |
-
|
43 |
-
foreach ($queries as $qry) {
|
44 |
-
$str = explode(" ", $qry);
|
45 |
-
if (preg_match("|CREATE TABLE ([^ ]*)|", $qry)) {
|
46 |
-
if ($wpdb->get_var("SHOW TABLES LIKE '" . $str[2] . "'") != $str[2]) {
|
47 |
-
//some plugins keep trying to create tables even when they already exist- would result in too many alerts
|
48 |
-
array_push($typeQueries['create'], $str[2]);
|
49 |
-
}
|
50 |
-
} else if (preg_match("|ALTER TABLE ([^ ]*)|", $qry)) {
|
51 |
-
array_push($typeQueries['update'], $str[2]);
|
52 |
-
} else if (preg_match("|DROP TABLE ([^ ]*)|", $qry)) {
|
53 |
-
if (!empty($str[4])) {
|
54 |
-
array_push($typeQueries['delete'], $str[4]);
|
55 |
-
} else {
|
56 |
-
array_push($typeQueries['delete'], $str[2]);
|
57 |
-
}
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
if (!empty($typeQueries["create"]) || !empty($typeQueries["update"]) || !empty($typeQueries["delete"])) {
|
62 |
-
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
63 |
-
$alertOptions = $this->GetActionType($actype);
|
64 |
-
|
65 |
-
foreach ($typeQueries as $queryType => $tableNames) {
|
66 |
-
if (!empty($tableNames)) {
|
67 |
-
$event_code = $this->GetEventQueryType($actype, $queryType);
|
68 |
-
$alertOptions["TableNames"] = implode(",", $tableNames);
|
69 |
-
$this->plugin->alerts->Trigger($event_code, $alertOptions);
|
70 |
-
}
|
71 |
-
}
|
72 |
-
}
|
73 |
-
|
74 |
-
return $queries;
|
75 |
-
}
|
76 |
-
|
77 |
-
protected function GetEventQueryType($type_action, $type_query)
|
78 |
-
{
|
79 |
-
switch ($type_action) {
|
80 |
-
case 'plugins':
|
81 |
-
if ($type_query == 'create') return 5010;
|
82 |
-
else if ($type_query == 'update') return 5011;
|
83 |
-
else if ($type_query == 'delete') return 5012;
|
84 |
-
case 'themes':
|
85 |
-
if ($type_query == 'create') return 5013;
|
86 |
-
else if ($type_query == 'update') return 5014;
|
87 |
-
else if ($type_query == 'delete') return 5015;
|
88 |
-
default:
|
89 |
-
if ($type_query == 'create') return 5016;
|
90 |
-
else if ($type_query == 'update') return 5017;
|
91 |
-
else if ($type_query == 'delete') return 5018;
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
protected function GetActionType($actype)
|
96 |
-
{
|
97 |
-
$is_themes = $actype == 'themes';
|
98 |
-
$is_plugins = $actype == 'plugins';
|
99 |
-
//Action Plugin Component
|
100 |
-
$alertOptions = array();
|
101 |
-
if ($is_plugins) {
|
102 |
-
if (isset($_REQUEST['plugin'])) {
|
103 |
-
$pluginFile = $_REQUEST['plugin'];
|
104 |
-
} else {
|
105 |
-
$pluginFile = $_REQUEST['checked'][0];
|
106 |
-
}
|
107 |
-
$pluginName = basename($pluginFile, '.php');
|
108 |
-
$pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
|
109 |
-
$pluginName = ucwords($pluginName);
|
110 |
-
$alertOptions["Plugin"] = (object)array(
|
111 |
-
'Name' => $pluginName,
|
112 |
-
);
|
113 |
-
//Action Theme Component
|
114 |
-
} else if ($is_themes) {
|
115 |
-
if (isset($_REQUEST['theme'])) {
|
116 |
-
$themeName = $_REQUEST['theme'];
|
117 |
-
} else {
|
118 |
-
$themeName = $_REQUEST['checked'][0];
|
119 |
-
}
|
120 |
-
$themeName = str_replace(array('_', '-', ' '), ' ', $themeName);
|
121 |
-
$themeName = ucwords($themeName);
|
122 |
-
$alertOptions["Theme"] = (object)array(
|
123 |
-
'Name' => $themeName,
|
124 |
-
);
|
125 |
-
//Action Unknown Component
|
126 |
-
} else {
|
127 |
-
$alertOptions["Component"] = "Unknown";
|
128 |
-
}
|
129 |
-
|
130 |
-
return $alertOptions;
|
131 |
-
}
|
132 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Database extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
public function HookEvents()
|
6 |
+
{
|
7 |
+
add_action('dbdelta_queries', array($this, 'EventDBDeltaQuery'));
|
8 |
+
add_action('query', array($this, 'EventDropQuery'));
|
9 |
+
}
|
10 |
+
|
11 |
+
public function EventDropQuery($query)
|
12 |
+
{
|
13 |
+
$table_names = array();
|
14 |
+
$str = explode(" ", $query);
|
15 |
+
|
16 |
+
if (preg_match("|DROP TABLE ([^ ]*)|", $query)) {
|
17 |
+
if (!empty($str[4])) {
|
18 |
+
array_push($table_names, $str[4]);
|
19 |
+
} else {
|
20 |
+
array_push($table_names, $str[2]);
|
21 |
+
}
|
22 |
+
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
23 |
+
$alertOptions = $this->GetActionType($actype);
|
24 |
+
}
|
25 |
+
|
26 |
+
if (!empty($table_names)) {
|
27 |
+
$event_code = $this->GetEventQueryType($actype, "delete");
|
28 |
+
$alertOptions["TableNames"] = implode(",", $table_names);
|
29 |
+
$this->plugin->alerts->Trigger($event_code, $alertOptions);
|
30 |
+
}
|
31 |
+
return $query;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function EventDBDeltaQuery($queries)
|
35 |
+
{
|
36 |
+
$typeQueries = array(
|
37 |
+
"create" => array(),
|
38 |
+
"update" => array(),
|
39 |
+
"delete" => array()
|
40 |
+
);
|
41 |
+
global $wpdb;
|
42 |
+
|
43 |
+
foreach ($queries as $qry) {
|
44 |
+
$str = explode(" ", $qry);
|
45 |
+
if (preg_match("|CREATE TABLE ([^ ]*)|", $qry)) {
|
46 |
+
if ($wpdb->get_var("SHOW TABLES LIKE '" . $str[2] . "'") != $str[2]) {
|
47 |
+
//some plugins keep trying to create tables even when they already exist- would result in too many alerts
|
48 |
+
array_push($typeQueries['create'], $str[2]);
|
49 |
+
}
|
50 |
+
} else if (preg_match("|ALTER TABLE ([^ ]*)|", $qry)) {
|
51 |
+
array_push($typeQueries['update'], $str[2]);
|
52 |
+
} else if (preg_match("|DROP TABLE ([^ ]*)|", $qry)) {
|
53 |
+
if (!empty($str[4])) {
|
54 |
+
array_push($typeQueries['delete'], $str[4]);
|
55 |
+
} else {
|
56 |
+
array_push($typeQueries['delete'], $str[2]);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
if (!empty($typeQueries["create"]) || !empty($typeQueries["update"]) || !empty($typeQueries["delete"])) {
|
62 |
+
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
63 |
+
$alertOptions = $this->GetActionType($actype);
|
64 |
+
|
65 |
+
foreach ($typeQueries as $queryType => $tableNames) {
|
66 |
+
if (!empty($tableNames)) {
|
67 |
+
$event_code = $this->GetEventQueryType($actype, $queryType);
|
68 |
+
$alertOptions["TableNames"] = implode(",", $tableNames);
|
69 |
+
$this->plugin->alerts->Trigger($event_code, $alertOptions);
|
70 |
+
}
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
return $queries;
|
75 |
+
}
|
76 |
+
|
77 |
+
protected function GetEventQueryType($type_action, $type_query)
|
78 |
+
{
|
79 |
+
switch ($type_action) {
|
80 |
+
case 'plugins':
|
81 |
+
if ($type_query == 'create') return 5010;
|
82 |
+
else if ($type_query == 'update') return 5011;
|
83 |
+
else if ($type_query == 'delete') return 5012;
|
84 |
+
case 'themes':
|
85 |
+
if ($type_query == 'create') return 5013;
|
86 |
+
else if ($type_query == 'update') return 5014;
|
87 |
+
else if ($type_query == 'delete') return 5015;
|
88 |
+
default:
|
89 |
+
if ($type_query == 'create') return 5016;
|
90 |
+
else if ($type_query == 'update') return 5017;
|
91 |
+
else if ($type_query == 'delete') return 5018;
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
protected function GetActionType($actype)
|
96 |
+
{
|
97 |
+
$is_themes = $actype == 'themes';
|
98 |
+
$is_plugins = $actype == 'plugins';
|
99 |
+
//Action Plugin Component
|
100 |
+
$alertOptions = array();
|
101 |
+
if ($is_plugins) {
|
102 |
+
if (isset($_REQUEST['plugin'])) {
|
103 |
+
$pluginFile = $_REQUEST['plugin'];
|
104 |
+
} else {
|
105 |
+
$pluginFile = $_REQUEST['checked'][0];
|
106 |
+
}
|
107 |
+
$pluginName = basename($pluginFile, '.php');
|
108 |
+
$pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
|
109 |
+
$pluginName = ucwords($pluginName);
|
110 |
+
$alertOptions["Plugin"] = (object)array(
|
111 |
+
'Name' => $pluginName,
|
112 |
+
);
|
113 |
+
//Action Theme Component
|
114 |
+
} else if ($is_themes) {
|
115 |
+
if (isset($_REQUEST['theme'])) {
|
116 |
+
$themeName = $_REQUEST['theme'];
|
117 |
+
} else {
|
118 |
+
$themeName = $_REQUEST['checked'][0];
|
119 |
+
}
|
120 |
+
$themeName = str_replace(array('_', '-', ' '), ' ', $themeName);
|
121 |
+
$themeName = ucwords($themeName);
|
122 |
+
$alertOptions["Theme"] = (object)array(
|
123 |
+
'Name' => $themeName,
|
124 |
+
);
|
125 |
+
//Action Unknown Component
|
126 |
+
} else {
|
127 |
+
$alertOptions["Component"] = "Unknown";
|
128 |
+
}
|
129 |
+
|
130 |
+
return $alertOptions;
|
131 |
+
}
|
132 |
+
}
|
classes/Sensors/Files.php
CHANGED
@@ -1,55 +1,55 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
4 |
-
|
5 |
-
public function HookEvents() {
|
6 |
-
add_action('add_attachment', array($this, 'EventFileUploaded'));
|
7 |
-
add_action('delete_attachment', array($this, 'EventFileUploadedDeleted'));
|
8 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
9 |
-
}
|
10 |
-
|
11 |
-
protected $IsFileUploaded = false;
|
12 |
-
|
13 |
-
public function EventFileUploaded($attachmentID){
|
14 |
-
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
15 |
-
if($action != 'upload-theme' && $action != 'upload-plugin'){
|
16 |
-
$file = get_attached_file($attachmentID);
|
17 |
-
$this->plugin->alerts->Trigger(2010, array(
|
18 |
-
'AttachmentID' => $attachmentID,
|
19 |
-
'FileName' => basename($file),
|
20 |
-
'FilePath' => dirname($file),
|
21 |
-
));
|
22 |
-
}
|
23 |
-
$this->IsFileUploaded = true;
|
24 |
-
}
|
25 |
-
|
26 |
-
public function EventFileUploadedDeleted($attachmentID){
|
27 |
-
if($this->IsFileUploaded)return;
|
28 |
-
$file = get_attached_file($attachmentID);
|
29 |
-
$this->plugin->alerts->Trigger(2011, array(
|
30 |
-
'AttachmentID' => $attachmentID,
|
31 |
-
'FileName' => basename($file),
|
32 |
-
'FilePath' => dirname($file),
|
33 |
-
));
|
34 |
-
}
|
35 |
-
|
36 |
-
public function EventAdminInit(){
|
37 |
-
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
38 |
-
$is_theme_editor = basename($_SERVER['SCRIPT_NAME']) == 'theme-editor.php';
|
39 |
-
$is_plugin_editor = basename($_SERVER['SCRIPT_NAME']) == 'plugin-editor.php';
|
40 |
-
|
41 |
-
if($is_theme_editor && $action == 'update'){
|
42 |
-
$this->plugin->alerts->Trigger(2046, array(
|
43 |
-
'File' => $_REQUEST['file'],
|
44 |
-
'Theme' => $_REQUEST['theme'],
|
45 |
-
));
|
46 |
-
}
|
47 |
-
|
48 |
-
if($is_plugin_editor && $action == 'update'){
|
49 |
-
$this->plugin->alerts->Trigger(2051, array(
|
50 |
-
'File' => $_REQUEST['file'],
|
51 |
-
'Plugin' => $_REQUEST['plugin'],
|
52 |
-
));
|
53 |
-
}
|
54 |
-
}
|
55 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Files extends WSAL_AbstractSensor {
|
4 |
+
|
5 |
+
public function HookEvents() {
|
6 |
+
add_action('add_attachment', array($this, 'EventFileUploaded'));
|
7 |
+
add_action('delete_attachment', array($this, 'EventFileUploadedDeleted'));
|
8 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
9 |
+
}
|
10 |
+
|
11 |
+
protected $IsFileUploaded = false;
|
12 |
+
|
13 |
+
public function EventFileUploaded($attachmentID){
|
14 |
+
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
15 |
+
if($action != 'upload-theme' && $action != 'upload-plugin'){
|
16 |
+
$file = get_attached_file($attachmentID);
|
17 |
+
$this->plugin->alerts->Trigger(2010, array(
|
18 |
+
'AttachmentID' => $attachmentID,
|
19 |
+
'FileName' => basename($file),
|
20 |
+
'FilePath' => dirname($file),
|
21 |
+
));
|
22 |
+
}
|
23 |
+
$this->IsFileUploaded = true;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function EventFileUploadedDeleted($attachmentID){
|
27 |
+
if($this->IsFileUploaded)return;
|
28 |
+
$file = get_attached_file($attachmentID);
|
29 |
+
$this->plugin->alerts->Trigger(2011, array(
|
30 |
+
'AttachmentID' => $attachmentID,
|
31 |
+
'FileName' => basename($file),
|
32 |
+
'FilePath' => dirname($file),
|
33 |
+
));
|
34 |
+
}
|
35 |
+
|
36 |
+
public function EventAdminInit(){
|
37 |
+
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
38 |
+
$is_theme_editor = basename($_SERVER['SCRIPT_NAME']) == 'theme-editor.php';
|
39 |
+
$is_plugin_editor = basename($_SERVER['SCRIPT_NAME']) == 'plugin-editor.php';
|
40 |
+
|
41 |
+
if($is_theme_editor && $action == 'update'){
|
42 |
+
$this->plugin->alerts->Trigger(2046, array(
|
43 |
+
'File' => $_REQUEST['file'],
|
44 |
+
'Theme' => $_REQUEST['theme'],
|
45 |
+
));
|
46 |
+
}
|
47 |
+
|
48 |
+
if($is_plugin_editor && $action == 'update'){
|
49 |
+
$this->plugin->alerts->Trigger(2051, array(
|
50 |
+
'File' => $_REQUEST['file'],
|
51 |
+
'Plugin' => $_REQUEST['plugin'],
|
52 |
+
));
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
classes/Sensors/LogInOut.php
CHANGED
@@ -1,182 +1,215 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
add_action('
|
9 |
-
add_action('
|
10 |
-
add_action('
|
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 |
-
protected function
|
52 |
-
{
|
53 |
-
return
|
54 |
-
}
|
55 |
-
|
56 |
-
protected function
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
|
6 |
+
public function HookEvents()
|
7 |
+
{
|
8 |
+
add_action('wp_login', array($this, 'EventLogin'), 10, 2);
|
9 |
+
add_action('wp_logout', array($this, 'EventLogout'));
|
10 |
+
add_action('password_reset', array($this, 'EventPasswordReset'), 10, 2);
|
11 |
+
add_action('wp_login_failed', array($this, 'EventLoginFailure'));
|
12 |
+
add_action('clear_auth_cookie', array($this, 'GetCurrentUser'), 10);
|
13 |
+
add_filter('wp_login_blocked', array($this, 'EventLoginBlocked'), 10, 1);
|
14 |
+
}
|
15 |
+
|
16 |
+
protected $_current_user = null;
|
17 |
+
|
18 |
+
public function GetCurrentUser()
|
19 |
+
{
|
20 |
+
$this->_current_user = wp_get_current_user();
|
21 |
+
}
|
22 |
+
|
23 |
+
public function EventLogin($user_login, $user = null)
|
24 |
+
{
|
25 |
+
if (empty($user)) {
|
26 |
+
$user = get_user_by('login', $user_login);
|
27 |
+
}
|
28 |
+
$userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
|
29 |
+
if ($this->plugin->settings->IsLoginSuperAdmin($user_login)) {
|
30 |
+
$userRoles[] = 'superadmin';
|
31 |
+
}
|
32 |
+
$this->plugin->alerts->Trigger(1000, array(
|
33 |
+
'Username' => $user_login,
|
34 |
+
'CurrentUserRoles' => $userRoles,
|
35 |
+
), true);
|
36 |
+
}
|
37 |
+
|
38 |
+
public function EventLogout()
|
39 |
+
{
|
40 |
+
if ($this->_current_user->ID != 0) {
|
41 |
+
$this->plugin->alerts->Trigger(1001, array(
|
42 |
+
'CurrentUserID' => $this->_current_user->ID,
|
43 |
+
'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($this->_current_user->roles),
|
44 |
+
), true);
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
const TRANSIENT_FAILEDLOGINS = 'wsal-failedlogins-known';
|
49 |
+
const TRANSIENT_FAILEDLOGINS_UNKNOWN = 'wsal-failedlogins-unknown';
|
50 |
+
|
51 |
+
protected function GetLoginFailureLogLimit()
|
52 |
+
{
|
53 |
+
return 10;
|
54 |
+
}
|
55 |
+
|
56 |
+
protected function GetLoginFailureExpiration()
|
57 |
+
{
|
58 |
+
return 12 * 60 * 60;
|
59 |
+
}
|
60 |
+
|
61 |
+
protected function IsPastLoginFailureLimit($ip, $site_id, $user)
|
62 |
+
{
|
63 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
64 |
+
if ($user) {
|
65 |
+
$dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
|
66 |
+
return ($dataKnown !== false) && isset($dataKnown[$site_id.":".$user->ID.":".$ip]) && ($dataKnown[$site_id.":".$user->ID.":".$ip] > $this->GetLoginFailureLogLimit());
|
67 |
+
} else {
|
68 |
+
$dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
|
69 |
+
return ($dataUnknown !== false) && isset($dataUnknown[$site_id.":".$ip]) && ($dataUnknown[$site_id.":".$ip] > $this->GetLoginFailureLogLimit());
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
protected function IncrementLoginFailure($ip, $site_id, $user)
|
74 |
+
{
|
75 |
+
$get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
|
76 |
+
$set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
|
77 |
+
if ($user) {
|
78 |
+
$dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
|
79 |
+
if (!$dataKnown) {
|
80 |
+
$dataKnown = array();
|
81 |
+
}
|
82 |
+
if (!isset($dataKnown[$site_id.":".$user->ID.":".$ip])) {
|
83 |
+
$dataKnown[$site_id.":".$user->ID.":".$ip] = 1;
|
84 |
+
}
|
85 |
+
$dataKnown[$site_id.":".$user->ID.":".$ip]++;
|
86 |
+
$set_fn(self::TRANSIENT_FAILEDLOGINS, $dataKnown, $this->GetLoginFailureExpiration());
|
87 |
+
} else {
|
88 |
+
$dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
|
89 |
+
if (!$dataUnknown) {
|
90 |
+
$dataUnknown = array();
|
91 |
+
}
|
92 |
+
if (!isset($dataUnknown[$site_id.":".$ip])) {
|
93 |
+
$dataUnknown[$site_id.":".$ip] = 1;
|
94 |
+
}
|
95 |
+
$dataUnknown[$site_id.":".$ip]++;
|
96 |
+
$set_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $dataUnknown, $this->GetLoginFailureExpiration());
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
public function EventLoginFailure($username)
|
101 |
+
{
|
102 |
+
list($y, $m, $d) = explode('-', date('Y-m-d'));
|
103 |
+
|
104 |
+
$ip = $this->plugin->settings->GetMainClientIP();
|
105 |
+
|
106 |
+
$username = array_key_exists('log', $_POST) ? $_POST["log"] : $username;
|
107 |
+
$newAlertCode = 1003;
|
108 |
+
$user = get_user_by('login', $username);
|
109 |
+
$site_id = (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
|
110 |
+
if ($user) {
|
111 |
+
$newAlertCode = 1002;
|
112 |
+
$userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
|
113 |
+
if ($this->plugin->settings->IsLoginSuperAdmin($username)) {
|
114 |
+
$userRoles[] = 'superadmin';
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
if ($this->IsPastLoginFailureLimit($ip, $site_id, $user)) {
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
|
122 |
+
$objOcc = new WSAL_Models_Occurrence();
|
123 |
+
|
124 |
+
if ($newAlertCode == 1002) {
|
125 |
+
if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles)) {
|
126 |
+
return;
|
127 |
+
}
|
128 |
+
$occ = $objOcc->CheckKnownUsers(
|
129 |
+
array(
|
130 |
+
$ip,
|
131 |
+
$username,
|
132 |
+
1002,
|
133 |
+
$site_id,
|
134 |
+
mktime(0, 0, 0, $m, $d, $y),
|
135 |
+
mktime(0, 0, 0, $m, $d + 1, $y) - 1
|
136 |
+
)
|
137 |
+
);
|
138 |
+
$occ = count($occ) ? $occ[0] : null;
|
139 |
+
|
140 |
+
if (!empty($occ)) {
|
141 |
+
// update existing record exists user
|
142 |
+
$this->IncrementLoginFailure($ip, $site_id, $user);
|
143 |
+
$new = $occ->GetMetaValue('Attempts', 0) + 1;
|
144 |
+
|
145 |
+
if ($new > $this->GetLoginFailureLogLimit()) {
|
146 |
+
$new = $this->GetLoginFailureLogLimit() . '+';
|
147 |
+
}
|
148 |
+
$occ->UpdateMetaValue('Attempts', $new);
|
149 |
+
$occ->UpdateMetaValue('Username', $username);
|
150 |
+
//$occ->SetMetaValue('CurrentUserRoles', $userRoles);
|
151 |
+
$occ->created_on = null;
|
152 |
+
$occ->Save();
|
153 |
+
} else {
|
154 |
+
// create a new record exists user
|
155 |
+
$this->plugin->alerts->Trigger($newAlertCode, array(
|
156 |
+
'Attempts' => 1,
|
157 |
+
'Username' => $username,
|
158 |
+
'CurrentUserRoles' => $userRoles
|
159 |
+
));
|
160 |
+
}
|
161 |
+
} else {
|
162 |
+
$occUnknown = $objOcc->CheckUnKnownUsers(
|
163 |
+
array(
|
164 |
+
$ip,
|
165 |
+
1003,
|
166 |
+
$site_id,
|
167 |
+
mktime(0, 0, 0, $m, $d, $y),
|
168 |
+
mktime(0, 0, 0, $m, $d + 1, $y) - 1
|
169 |
+
)
|
170 |
+
);
|
171 |
+
|
172 |
+
$occUnknown = count($occUnknown) ? $occUnknown[0] : null;
|
173 |
+
if (!empty($occUnknown)) {
|
174 |
+
// update existing record not exists user
|
175 |
+
$this->IncrementLoginFailure($ip, $site_id, false);
|
176 |
+
$new = $occUnknown->GetMetaValue('Attempts', 0) + 1;
|
177 |
+
|
178 |
+
if ($new > $this->GetLoginFailureLogLimit()) {
|
179 |
+
$new = $this->GetLoginFailureLogLimit() . '+';
|
180 |
+
}
|
181 |
+
$occUnknown->UpdateMetaValue('Attempts', $new);
|
182 |
+
$occUnknown->created_on = null;
|
183 |
+
$occUnknown->Save();
|
184 |
+
} else {
|
185 |
+
// create a new record not exists user
|
186 |
+
$this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1));
|
187 |
+
}
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
public function EventPasswordReset($user, $new_pass)
|
192 |
+
{
|
193 |
+
if (!empty($user)) {
|
194 |
+
$userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
|
195 |
+
$this->plugin->alerts->Trigger(4003, array(
|
196 |
+
'Username' => $user->user_login,
|
197 |
+
'CurrentUserRoles' => $userRoles
|
198 |
+
), true);
|
199 |
+
}
|
200 |
+
}
|
201 |
+
|
202 |
+
public function EventLoginBlocked($username)
|
203 |
+
{
|
204 |
+
$user = get_user_by('login', $username);
|
205 |
+
$userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
|
206 |
+
|
207 |
+
if ($this->plugin->settings->IsLoginSuperAdmin($username)) {
|
208 |
+
$userRoles[] = 'superadmin';
|
209 |
+
}
|
210 |
+
$this->plugin->alerts->Trigger(1004, array(
|
211 |
+
'Username' => $username,
|
212 |
+
'CurrentUserRoles' => $userRoles
|
213 |
+
), true);
|
214 |
+
}
|
215 |
+
}
|
classes/Sensors/Menus.php
CHANGED
@@ -1,416 +1,416 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Menus extends WSAL_AbstractSensor
|
4 |
-
{
|
5 |
-
protected $_OldMenu = null;
|
6 |
-
protected $_OldMenuTerms = array();
|
7 |
-
protected $_OldMenuItems = array();
|
8 |
-
protected $_OldMenuLocations = null;
|
9 |
-
|
10 |
-
public function HookEvents()
|
11 |
-
{
|
12 |
-
add_action('wp_create_nav_menu', array($this, 'CreateMenu'), 10, 2);
|
13 |
-
add_action('wp_delete_nav_menu', array($this, 'DeleteMenu'), 10, 1);
|
14 |
-
add_action('wp_update_nav_menu', array($this, 'UpdateMenu'), 10, 2);
|
15 |
-
add_action('admin_menu', array($this, 'ManageMenuLocations'));
|
16 |
-
|
17 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
18 |
-
// Customizer trigger
|
19 |
-
add_action('customize_register', array($this, 'CustomizeInit'));
|
20 |
-
add_action('customize_save_after', array($this, 'CustomizeSave'));
|
21 |
-
}
|
22 |
-
|
23 |
-
public function CreateMenu($term_id, $menu_data)
|
24 |
-
{
|
25 |
-
$this->plugin->alerts->Trigger(2078, array(
|
26 |
-
'MenuName' => $menu_data['menu-name']
|
27 |
-
));
|
28 |
-
}
|
29 |
-
|
30 |
-
public function ManageMenuLocations()
|
31 |
-
{
|
32 |
-
// Manage Location tab
|
33 |
-
if (isset($_POST['menu-locations'])) {
|
34 |
-
$new_locations = $_POST['menu-locations'];
|
35 |
-
if (isset($new_locations['primary'])) {
|
36 |
-
$this->LocationSetting($new_locations['primary'], 'primary');
|
37 |
-
}
|
38 |
-
if (isset($new_locations['social'])) {
|
39 |
-
$this->LocationSetting($new_locations['social'], 'social');
|
40 |
-
}
|
41 |
-
}
|
42 |
-
}
|
43 |
-
|
44 |
-
private function LocationSetting($new_location, $type)
|
45 |
-
{
|
46 |
-
$old_locations = get_nav_menu_locations();
|
47 |
-
if ($new_location != 0) {
|
48 |
-
$menu = wp_get_nav_menu_object($new_location);
|
49 |
-
if (!empty($old_locations[$type]) && $old_locations[$type] != $new_location) {
|
50 |
-
$this->EventMenuSetting($menu->name, "Enabled", "Location: ".$type." menu");
|
51 |
-
}
|
52 |
-
} else {
|
53 |
-
if (!empty($old_locations[$type])) {
|
54 |
-
$menu = wp_get_nav_menu_object($old_locations[$type]);
|
55 |
-
$this->EventMenuSetting($menu->name, "Disabled", "Location: ".$type." menu");
|
56 |
-
}
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
public function DeleteMenu($term_id)
|
61 |
-
{
|
62 |
-
if ($this->_OldMenu) {
|
63 |
-
$this->plugin->alerts->Trigger(2081, array(
|
64 |
-
'MenuName' => $this->_OldMenu->name
|
65 |
-
));
|
66 |
-
}
|
67 |
-
}
|
68 |
-
|
69 |
-
public function UpdateMenu($menu_id, $menu_data = null)
|
70 |
-
{
|
71 |
-
if (!empty($menu_data)) {
|
72 |
-
$contentNamesOld = array();
|
73 |
-
$contentTypesOld = array();
|
74 |
-
$contentOrderOld = array();
|
75 |
-
|
76 |
-
$items = wp_get_nav_menu_items($menu_id);
|
77 |
-
if (!empty($items)) {
|
78 |
-
foreach ($items as $item) {
|
79 |
-
array_push($contentNamesOld, $item->title);
|
80 |
-
array_push($contentTypesOld, $item->object);
|
81 |
-
$contentOrderOld[$item->ID] = $item->menu_order;
|
82 |
-
}
|
83 |
-
}
|
84 |
-
// Menu changed name
|
85 |
-
if (!empty($this->_OldMenuTerms) && isset($_POST['menu']) && isset($_POST['menu-name'])) {
|
86 |
-
foreach ($this->_OldMenuTerms as $oldMenuTerm) {
|
87 |
-
if ($oldMenuTerm['term_id'] == $_POST['menu']) {
|
88 |
-
if ($oldMenuTerm['name'] != $_POST['menu-name']) {
|
89 |
-
$this->EventChangeName($oldMenuTerm['name'], $_POST['menu-name']);
|
90 |
-
} else {
|
91 |
-
// Remove the last menu item
|
92 |
-
if (count($contentNamesOld) == 1 && count($contentTypesOld) == 1) {
|
93 |
-
$this->EventRemoveItems($contentTypesOld[0], $contentNamesOld[0], $_POST['menu-name']);
|
94 |
-
}
|
95 |
-
}
|
96 |
-
}
|
97 |
-
}
|
98 |
-
}
|
99 |
-
|
100 |
-
$is_occurred_event = false;
|
101 |
-
if (isset($_POST['menu-item-title']) && isset($_POST['menu-item-object'])) {
|
102 |
-
$contentNamesNew = array_values($_POST['menu-item-title']);
|
103 |
-
$contentTypesNew = array_values($_POST['menu-item-object']);
|
104 |
-
$contentOrderNew = $_POST['menu-item-position'];
|
105 |
-
|
106 |
-
$order = array_diff_assoc($contentOrderNew, $contentOrderOld);
|
107 |
-
// Changed order of the objects in a menu
|
108 |
-
if ((count($contentOrderOld) == count($contentOrderNew)) && count($order) > 0) {
|
109 |
-
$is_occurred_event = true;
|
110 |
-
$this->EventChangeOrder($menu_data['menu-name']);
|
111 |
-
}
|
112 |
-
$addedNames = array_diff_assoc($contentNamesNew, $contentNamesOld);
|
113 |
-
$addedTypes = array_diff_assoc($contentTypesNew, $contentTypesOld);
|
114 |
-
|
115 |
-
if (!$is_occurred_event) {
|
116 |
-
// Add Items to the menu
|
117 |
-
if (count($addedNames) > 0 && count($addedTypes) > 0) {
|
118 |
-
$is_occurred_event = true;
|
119 |
-
foreach ($addedNames as $key => $contentName) {
|
120 |
-
$contentType = str_replace("custom", "custom link", $contentTypesNew[$key]);
|
121 |
-
if (!empty($contentType)) {
|
122 |
-
$this->EventAddItems($contentType, $contentName, $menu_data['menu-name']);
|
123 |
-
}
|
124 |
-
}
|
125 |
-
}
|
126 |
-
|
127 |
-
$removedNames = array_diff_assoc($contentNamesOld, $contentNamesNew);
|
128 |
-
$removedTypes = array_diff_assoc($contentTypesOld, $contentTypesNew);
|
129 |
-
// Remove items from the menu
|
130 |
-
if (count($removedNames) > 0 && count($removedTypes) > 0) {
|
131 |
-
$is_occurred_event = true;
|
132 |
-
foreach ($removedNames as $key => $contentName) {
|
133 |
-
$contentType = str_replace("custom", "custom link", $contentTypesOld[$key]);
|
134 |
-
if (!empty($contentType)) {
|
135 |
-
$this->EventRemoveItems($contentType, $contentName, $menu_data['menu-name']);
|
136 |
-
}
|
137 |
-
}
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
// Modified Items in the menu
|
142 |
-
if (!$is_occurred_event && count($addedNames) > 0) {
|
143 |
-
foreach ($addedNames as $key => $contentName) {
|
144 |
-
$contentType = str_replace("custom", "custom link", $contentTypesOld[$key]);
|
145 |
-
if (!empty($contentType)) {
|
146 |
-
$this->EventModifiedItems($contentType, $contentName, $menu_data['menu-name']);
|
147 |
-
}
|
148 |
-
}
|
149 |
-
}
|
150 |
-
}
|
151 |
-
// Enable/Disable menu setting
|
152 |
-
$nav_menu_options = maybe_unserialize(get_option('nav_menu_options'));
|
153 |
-
$auto_add = null;
|
154 |
-
if (isset($nav_menu_options['auto_add'])) {
|
155 |
-
if (in_array($menu_id, $nav_menu_options['auto_add'])) {
|
156 |
-
if (empty($_POST['auto-add-pages'])) {
|
157 |
-
$auto_add = "Disabled";
|
158 |
-
}
|
159 |
-
} else {
|
160 |
-
if (isset($_POST['auto-add-pages'])) {
|
161 |
-
$auto_add = "Enabled";
|
162 |
-
}
|
163 |
-
}
|
164 |
-
} else {
|
165 |
-
if (isset($_POST['auto-add-pages'])) {
|
166 |
-
$auto_add = "Enabled";
|
167 |
-
}
|
168 |
-
}
|
169 |
-
// Alert 2082 Auto add pages
|
170 |
-
if (!empty($auto_add)) {
|
171 |
-
$this->EventMenuSetting($menu_data['menu-name'], $auto_add, "Auto add pages");
|
172 |
-
}
|
173 |
-
|
174 |
-
$nav_menu_locations = get_nav_menu_locations();
|
175 |
-
|
176 |
-
$locationPrimary = null;
|
177 |
-
if (isset($this->_OldMenuLocations['primary']) && isset($nav_menu_locations['primary'])) {
|
178 |
-
if ($nav_menu_locations['primary'] == $menu_id && $this->_OldMenuLocations['primary'] != $nav_menu_locations['primary']) {
|
179 |
-
$locationPrimary = "Enabled";
|
180 |
-
}
|
181 |
-
} elseif (empty($this->_OldMenuLocations['primary']) && isset($nav_menu_locations['primary'])) {
|
182 |
-
if ($nav_menu_locations['primary'] == $menu_id) {
|
183 |
-
$locationPrimary = "Enabled";
|
184 |
-
}
|
185 |
-
} elseif (isset($this->_OldMenuLocations['primary']) && empty($nav_menu_locations['primary'])) {
|
186 |
-
if ($this->_OldMenuLocations['primary'] == $menu_id) {
|
187 |
-
$locationPrimary = "Disabled";
|
188 |
-
}
|
189 |
-
}
|
190 |
-
// Alert 2082 Primary menu
|
191 |
-
if (!empty($locationPrimary)) {
|
192 |
-
$this->EventMenuSetting($menu_data['menu-name'], $locationPrimary, "Location: primary menu");
|
193 |
-
}
|
194 |
-
|
195 |
-
$locationSocial = null;
|
196 |
-
if (isset($this->_OldMenuLocations['social']) && isset($nav_menu_locations['social'])) {
|
197 |
-
if ($nav_menu_locations['social'] == $menu_id && $this->_OldMenuLocations['social'] != $nav_menu_locations['social']) {
|
198 |
-
$locationSocial = "Enabled";
|
199 |
-
}
|
200 |
-
} elseif (empty($this->_OldMenuLocations['social']) && isset($nav_menu_locations['social'])) {
|
201 |
-
if ($nav_menu_locations['social'] == $menu_id) {
|
202 |
-
$locationSocial = "Enabled";
|
203 |
-
}
|
204 |
-
} elseif (isset($this->_OldMenuLocations['social']) && empty($nav_menu_locations['social'])) {
|
205 |
-
if ($this->_OldMenuLocations['social'] == $menu_id) {
|
206 |
-
$locationSocial = "Disabled";
|
207 |
-
}
|
208 |
-
}
|
209 |
-
// Alert 2082 Social links menu
|
210 |
-
if (!empty($locationSocial)) {
|
211 |
-
$this->EventMenuSetting($menu_data['menu-name'], $locationSocial, "Location: social menu");
|
212 |
-
}
|
213 |
-
}
|
214 |
-
}
|
215 |
-
|
216 |
-
private function BuildOldMenuTermsAndItems()
|
217 |
-
{
|
218 |
-
$menus = wp_get_nav_menus();
|
219 |
-
if (!empty($menus)) {
|
220 |
-
foreach ($menus as $menu) {
|
221 |
-
array_push($this->_OldMenuTerms, array("term_id" => $menu->term_id, "name" => $menu->name));
|
222 |
-
$items = wp_get_nav_menu_items($menu->term_id);
|
223 |
-
if (!empty($items)) {
|
224 |
-
foreach ($items as $item) {
|
225 |
-
array_push($this->_OldMenuItems, array(
|
226 |
-
'item_id' => $item->ID,
|
227 |
-
'title' => $item->title,
|
228 |
-
'object' => $item->object,
|
229 |
-
'menu_name' => $menu->name,
|
230 |
-
'menu_order' => $item->menu_order
|
231 |
-
));
|
232 |
-
}
|
233 |
-
}
|
234 |
-
}
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
public function EventAdminInit()
|
239 |
-
{
|
240 |
-
$is_nav_menu = basename($_SERVER['SCRIPT_NAME']) == 'nav-menus.php';
|
241 |
-
if ($is_nav_menu) {
|
242 |
-
if (isset($_GET['action']) && $_GET['action'] == 'delete') {
|
243 |
-
if (isset($_GET['menu'])) {
|
244 |
-
$this->_OldMenu = wp_get_nav_menu_object($_GET['menu']);
|
245 |
-
}
|
246 |
-
} else {
|
247 |
-
$this->BuildOldMenuTermsAndItems();
|
248 |
-
}
|
249 |
-
$this->_OldMenuLocations = get_nav_menu_locations();
|
250 |
-
}
|
251 |
-
}
|
252 |
-
|
253 |
-
public function CustomizeInit()
|
254 |
-
{
|
255 |
-
$this->BuildOldMenuTermsAndItems();
|
256 |
-
$this->_OldMenuLocations = get_nav_menu_locations();
|
257 |
-
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Customize Events Function
|
261 |
-
*/
|
262 |
-
public function CustomizeSave()
|
263 |
-
{
|
264 |
-
$updateMenus = array();
|
265 |
-
$menus = wp_get_nav_menus();
|
266 |
-
if (!empty($menus)) {
|
267 |
-
foreach ($menus as $menu) {
|
268 |
-
array_push($updateMenus, array("term_id" => $menu->term_id, "name" => $menu->name));
|
269 |
-
}
|
270 |
-
}
|
271 |
-
// Deleted Menu
|
272 |
-
if (isset($updateMenus) && isset($this->_OldMenuTerms)) {
|
273 |
-
$terms = array_diff(array_map('serialize', $this->_OldMenuTerms), array_map('serialize', $updateMenus));
|
274 |
-
$terms = array_map('unserialize', $terms);
|
275 |
-
|
276 |
-
if (isset($terms) && count($terms) > 0) {
|
277 |
-
foreach ($terms as $term) {
|
278 |
-
$this->plugin->alerts->Trigger(2081, array(
|
279 |
-
'MenuName' => $term['name']
|
280 |
-
));
|
281 |
-
}
|
282 |
-
}
|
283 |
-
}
|
284 |
-
if (isset($_POST['action']) && $_POST['action'] == 'customize_save') {
|
285 |
-
if (isset($_POST['wp_customize'], $_POST['customized'])) {
|
286 |
-
$customized = json_decode(wp_unslash($_POST['customized']), true);
|
287 |
-
if (is_array($customized)) {
|
288 |
-
foreach ($customized as $key => $value) {
|
289 |
-
if (!empty($value['nav_menu_term_id'])) {
|
290 |
-
$is_occurred_event = false;
|
291 |
-
$menu = wp_get_nav_menu_object($value['nav_menu_term_id']);
|
292 |
-
$content_name = !empty($value['title']) ? $value['title'] : "no title";
|
293 |
-
if (!empty($this->_OldMenuItems)) {
|
294 |
-
foreach ($this->_OldMenuItems as $old_item) {
|
295 |
-
$item_id = substr(trim($key, ']'), 14);
|
296 |
-
// Modified Items in the menu
|
297 |
-
if ($old_item['item_id'] == $item_id && $old_item['title'] != $content_name) {
|
298 |
-
$is_occurred_event = true;
|
299 |
-
$this->EventModifiedItems($value['type_label'], $content_name, $menu->name);
|
300 |
-
}
|
301 |
-
// Changed order of the objects in a menu
|
302 |
-
if ($old_item['item_id'] == $item_id && $old_item['menu_order'] != $value['position']) {
|
303 |
-
$is_occurred_event = true;
|
304 |
-
$this->EventChangeOrder($menu->name);
|
305 |
-
return;
|
306 |
-
}
|
307 |
-
}
|
308 |
-
}
|
309 |
-
// Add Items to the menu
|
310 |
-
if (!$is_occurred_event) {
|
311 |
-
$menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : $menu->name;
|
312 |
-
$this->EventAddItems($value['type_label'], $content_name, $menu_name);
|
313 |
-
}
|
314 |
-
} else {
|
315 |
-
// Menu changed name
|
316 |
-
if (isset($updateMenus) && isset($this->_OldMenuTerms)) {
|
317 |
-
foreach ($this->_OldMenuTerms as $old_menu) {
|
318 |
-
foreach ($updateMenus as $update_menu) {
|
319 |
-
if ($old_menu['term_id'] == $update_menu['term_id'] && $old_menu['name'] != $update_menu['name']) {
|
320 |
-
$this->EventChangeName($old_menu['name'], $update_menu['name']);
|
321 |
-
}
|
322 |
-
}
|
323 |
-
}
|
324 |
-
}
|
325 |
-
// Setting Auto add pages
|
326 |
-
if (!empty($value) && isset($value['auto_add'])) {
|
327 |
-
if ($value['auto_add']) {
|
328 |
-
$this->EventMenuSetting($value['name'], 'Enabled', "Auto add pages");
|
329 |
-
} else {
|
330 |
-
$this->EventMenuSetting($value['name'], 'Disabled', "Auto add pages");
|
331 |
-
}
|
332 |
-
}
|
333 |
-
// Setting Location
|
334 |
-
if (false !== strpos($key, 'nav_menu_locations[')) {
|
335 |
-
$loc = substr(trim($key, ']'), 19);
|
336 |
-
if (!empty($value)) {
|
337 |
-
$menu = wp_get_nav_menu_object($value);
|
338 |
-
$menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : (!empty($menu) ? $menu->name : '');
|
339 |
-
$this->EventMenuSetting($menu_name, "Enabled", "Location: ".$loc." menu");
|
340 |
-
} else {
|
341 |
-
if (!empty($this->_OldMenuLocations[$loc])) {
|
342 |
-
$menu = wp_get_nav_menu_object($this->_OldMenuLocations[$loc]);
|
343 |
-
$menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : (!empty($menu) ? $menu->name : '');
|
344 |
-
$this->EventMenuSetting($menu_name, "Disabled", "Location: ".$loc." menu");
|
345 |
-
}
|
346 |
-
}
|
347 |
-
}
|
348 |
-
// Remove items from the menu
|
349 |
-
if (false !== strpos($key, 'nav_menu_item[')) {
|
350 |
-
$item_id = substr(trim($key, ']'), 14);
|
351 |
-
if (!empty($this->_OldMenuItems)) {
|
352 |
-
foreach ($this->_OldMenuItems as $old_item) {
|
353 |
-
if ($old_item['item_id'] == $item_id) {
|
354 |
-
$this->EventRemoveItems($old_item['object'], $old_item['title'], $old_item['menu_name']);
|
355 |
-
}
|
356 |
-
}
|
357 |
-
}
|
358 |
-
}
|
359 |
-
}
|
360 |
-
}
|
361 |
-
}
|
362 |
-
}
|
363 |
-
}
|
364 |
-
}
|
365 |
-
|
366 |
-
private function EventAddItems($content_type, $content_name, $menu_name)
|
367 |
-
{
|
368 |
-
$this->plugin->alerts->Trigger(2079, array(
|
369 |
-
'ContentType' => $content_type,
|
370 |
-
'ContentName' => $content_name,
|
371 |
-
'MenuName' => $menu_name
|
372 |
-
));
|
373 |
-
}
|
374 |
-
|
375 |
-
private function EventRemoveItems($content_type, $content_name, $menu_name)
|
376 |
-
{
|
377 |
-
$this->plugin->alerts->Trigger(2080, array(
|
378 |
-
'ContentType' => $content_type,
|
379 |
-
'ContentName' => $content_name,
|
380 |
-
'MenuName' => $menu_name
|
381 |
-
));
|
382 |
-
}
|
383 |
-
|
384 |
-
private function EventMenuSetting($menu_name, $status, $menu_setting)
|
385 |
-
{
|
386 |
-
$this->plugin->alerts->Trigger(2082, array(
|
387 |
-
'Status' => $status,
|
388 |
-
'MenuSetting' => $menu_setting,
|
389 |
-
'MenuName' => $menu_name
|
390 |
-
));
|
391 |
-
}
|
392 |
-
|
393 |
-
private function EventModifiedItems($content_type, $content_name, $menu_name)
|
394 |
-
{
|
395 |
-
$this->plugin->alerts->Trigger(2083, array(
|
396 |
-
'ContentType' => $content_type,
|
397 |
-
'ContentName' => $content_name,
|
398 |
-
'MenuName' => $menu_name
|
399 |
-
));
|
400 |
-
}
|
401 |
-
|
402 |
-
private function EventChangeName($old_menu_name, $new_menu_name)
|
403 |
-
{
|
404 |
-
$this->plugin->alerts->Trigger(2084, array(
|
405 |
-
'OldMenuName' => $old_menu_name,
|
406 |
-
'NewMenuName' => $new_menu_name
|
407 |
-
));
|
408 |
-
}
|
409 |
-
|
410 |
-
private function EventChangeOrder($menu_name)
|
411 |
-
{
|
412 |
-
$this->plugin->alerts->Trigger(2085, array(
|
413 |
-
'MenuName' => $menu_name
|
414 |
-
));
|
415 |
-
}
|
416 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Menus extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
protected $_OldMenu = null;
|
6 |
+
protected $_OldMenuTerms = array();
|
7 |
+
protected $_OldMenuItems = array();
|
8 |
+
protected $_OldMenuLocations = null;
|
9 |
+
|
10 |
+
public function HookEvents()
|
11 |
+
{
|
12 |
+
add_action('wp_create_nav_menu', array($this, 'CreateMenu'), 10, 2);
|
13 |
+
add_action('wp_delete_nav_menu', array($this, 'DeleteMenu'), 10, 1);
|
14 |
+
add_action('wp_update_nav_menu', array($this, 'UpdateMenu'), 10, 2);
|
15 |
+
add_action('admin_menu', array($this, 'ManageMenuLocations'));
|
16 |
+
|
17 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
18 |
+
// Customizer trigger
|
19 |
+
add_action('customize_register', array($this, 'CustomizeInit'));
|
20 |
+
add_action('customize_save_after', array($this, 'CustomizeSave'));
|
21 |
+
}
|
22 |
+
|
23 |
+
public function CreateMenu($term_id, $menu_data)
|
24 |
+
{
|
25 |
+
$this->plugin->alerts->Trigger(2078, array(
|
26 |
+
'MenuName' => $menu_data['menu-name']
|
27 |
+
));
|
28 |
+
}
|
29 |
+
|
30 |
+
public function ManageMenuLocations()
|
31 |
+
{
|
32 |
+
// Manage Location tab
|
33 |
+
if (isset($_POST['menu-locations'])) {
|
34 |
+
$new_locations = $_POST['menu-locations'];
|
35 |
+
if (isset($new_locations['primary'])) {
|
36 |
+
$this->LocationSetting($new_locations['primary'], 'primary');
|
37 |
+
}
|
38 |
+
if (isset($new_locations['social'])) {
|
39 |
+
$this->LocationSetting($new_locations['social'], 'social');
|
40 |
+
}
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
private function LocationSetting($new_location, $type)
|
45 |
+
{
|
46 |
+
$old_locations = get_nav_menu_locations();
|
47 |
+
if ($new_location != 0) {
|
48 |
+
$menu = wp_get_nav_menu_object($new_location);
|
49 |
+
if (!empty($old_locations[$type]) && $old_locations[$type] != $new_location) {
|
50 |
+
$this->EventMenuSetting($menu->name, "Enabled", "Location: ".$type." menu");
|
51 |
+
}
|
52 |
+
} else {
|
53 |
+
if (!empty($old_locations[$type])) {
|
54 |
+
$menu = wp_get_nav_menu_object($old_locations[$type]);
|
55 |
+
$this->EventMenuSetting($menu->name, "Disabled", "Location: ".$type." menu");
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
public function DeleteMenu($term_id)
|
61 |
+
{
|
62 |
+
if ($this->_OldMenu) {
|
63 |
+
$this->plugin->alerts->Trigger(2081, array(
|
64 |
+
'MenuName' => $this->_OldMenu->name
|
65 |
+
));
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
public function UpdateMenu($menu_id, $menu_data = null)
|
70 |
+
{
|
71 |
+
if (!empty($menu_data)) {
|
72 |
+
$contentNamesOld = array();
|
73 |
+
$contentTypesOld = array();
|
74 |
+
$contentOrderOld = array();
|
75 |
+
|
76 |
+
$items = wp_get_nav_menu_items($menu_id);
|
77 |
+
if (!empty($items)) {
|
78 |
+
foreach ($items as $item) {
|
79 |
+
array_push($contentNamesOld, $item->title);
|
80 |
+
array_push($contentTypesOld, $item->object);
|
81 |
+
$contentOrderOld[$item->ID] = $item->menu_order;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
// Menu changed name
|
85 |
+
if (!empty($this->_OldMenuTerms) && isset($_POST['menu']) && isset($_POST['menu-name'])) {
|
86 |
+
foreach ($this->_OldMenuTerms as $oldMenuTerm) {
|
87 |
+
if ($oldMenuTerm['term_id'] == $_POST['menu']) {
|
88 |
+
if ($oldMenuTerm['name'] != $_POST['menu-name']) {
|
89 |
+
$this->EventChangeName($oldMenuTerm['name'], $_POST['menu-name']);
|
90 |
+
} else {
|
91 |
+
// Remove the last menu item
|
92 |
+
if (count($contentNamesOld) == 1 && count($contentTypesOld) == 1) {
|
93 |
+
$this->EventRemoveItems($contentTypesOld[0], $contentNamesOld[0], $_POST['menu-name']);
|
94 |
+
}
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
$is_occurred_event = false;
|
101 |
+
if (isset($_POST['menu-item-title']) && isset($_POST['menu-item-object'])) {
|
102 |
+
$contentNamesNew = array_values($_POST['menu-item-title']);
|
103 |
+
$contentTypesNew = array_values($_POST['menu-item-object']);
|
104 |
+
$contentOrderNew = $_POST['menu-item-position'];
|
105 |
+
|
106 |
+
$order = array_diff_assoc($contentOrderNew, $contentOrderOld);
|
107 |
+
// Changed order of the objects in a menu
|
108 |
+
if ((count($contentOrderOld) == count($contentOrderNew)) && count($order) > 0) {
|
109 |
+
$is_occurred_event = true;
|
110 |
+
$this->EventChangeOrder($menu_data['menu-name']);
|
111 |
+
}
|
112 |
+
$addedNames = array_diff_assoc($contentNamesNew, $contentNamesOld);
|
113 |
+
$addedTypes = array_diff_assoc($contentTypesNew, $contentTypesOld);
|
114 |
+
|
115 |
+
if (!$is_occurred_event) {
|
116 |
+
// Add Items to the menu
|
117 |
+
if (count($addedNames) > 0 && count($addedTypes) > 0) {
|
118 |
+
$is_occurred_event = true;
|
119 |
+
foreach ($addedNames as $key => $contentName) {
|
120 |
+
$contentType = str_replace("custom", "custom link", $contentTypesNew[$key]);
|
121 |
+
if (!empty($contentType)) {
|
122 |
+
$this->EventAddItems($contentType, $contentName, $menu_data['menu-name']);
|
123 |
+
}
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
$removedNames = array_diff_assoc($contentNamesOld, $contentNamesNew);
|
128 |
+
$removedTypes = array_diff_assoc($contentTypesOld, $contentTypesNew);
|
129 |
+
// Remove items from the menu
|
130 |
+
if (count($removedNames) > 0 && count($removedTypes) > 0) {
|
131 |
+
$is_occurred_event = true;
|
132 |
+
foreach ($removedNames as $key => $contentName) {
|
133 |
+
$contentType = str_replace("custom", "custom link", $contentTypesOld[$key]);
|
134 |
+
if (!empty($contentType)) {
|
135 |
+
$this->EventRemoveItems($contentType, $contentName, $menu_data['menu-name']);
|
136 |
+
}
|
137 |
+
}
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
// Modified Items in the menu
|
142 |
+
if (!$is_occurred_event && count($addedNames) > 0) {
|
143 |
+
foreach ($addedNames as $key => $contentName) {
|
144 |
+
$contentType = str_replace("custom", "custom link", $contentTypesOld[$key]);
|
145 |
+
if (!empty($contentType)) {
|
146 |
+
$this->EventModifiedItems($contentType, $contentName, $menu_data['menu-name']);
|
147 |
+
}
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
// Enable/Disable menu setting
|
152 |
+
$nav_menu_options = maybe_unserialize(get_option('nav_menu_options'));
|
153 |
+
$auto_add = null;
|
154 |
+
if (isset($nav_menu_options['auto_add'])) {
|
155 |
+
if (in_array($menu_id, $nav_menu_options['auto_add'])) {
|
156 |
+
if (empty($_POST['auto-add-pages'])) {
|
157 |
+
$auto_add = "Disabled";
|
158 |
+
}
|
159 |
+
} else {
|
160 |
+
if (isset($_POST['auto-add-pages'])) {
|
161 |
+
$auto_add = "Enabled";
|
162 |
+
}
|
163 |
+
}
|
164 |
+
} else {
|
165 |
+
if (isset($_POST['auto-add-pages'])) {
|
166 |
+
$auto_add = "Enabled";
|
167 |
+
}
|
168 |
+
}
|
169 |
+
// Alert 2082 Auto add pages
|
170 |
+
if (!empty($auto_add)) {
|
171 |
+
$this->EventMenuSetting($menu_data['menu-name'], $auto_add, "Auto add pages");
|
172 |
+
}
|
173 |
+
|
174 |
+
$nav_menu_locations = get_nav_menu_locations();
|
175 |
+
|
176 |
+
$locationPrimary = null;
|
177 |
+
if (isset($this->_OldMenuLocations['primary']) && isset($nav_menu_locations['primary'])) {
|
178 |
+
if ($nav_menu_locations['primary'] == $menu_id && $this->_OldMenuLocations['primary'] != $nav_menu_locations['primary']) {
|
179 |
+
$locationPrimary = "Enabled";
|
180 |
+
}
|
181 |
+
} elseif (empty($this->_OldMenuLocations['primary']) && isset($nav_menu_locations['primary'])) {
|
182 |
+
if ($nav_menu_locations['primary'] == $menu_id) {
|
183 |
+
$locationPrimary = "Enabled";
|
184 |
+
}
|
185 |
+
} elseif (isset($this->_OldMenuLocations['primary']) && empty($nav_menu_locations['primary'])) {
|
186 |
+
if ($this->_OldMenuLocations['primary'] == $menu_id) {
|
187 |
+
$locationPrimary = "Disabled";
|
188 |
+
}
|
189 |
+
}
|
190 |
+
// Alert 2082 Primary menu
|
191 |
+
if (!empty($locationPrimary)) {
|
192 |
+
$this->EventMenuSetting($menu_data['menu-name'], $locationPrimary, "Location: primary menu");
|
193 |
+
}
|
194 |
+
|
195 |
+
$locationSocial = null;
|
196 |
+
if (isset($this->_OldMenuLocations['social']) && isset($nav_menu_locations['social'])) {
|
197 |
+
if ($nav_menu_locations['social'] == $menu_id && $this->_OldMenuLocations['social'] != $nav_menu_locations['social']) {
|
198 |
+
$locationSocial = "Enabled";
|
199 |
+
}
|
200 |
+
} elseif (empty($this->_OldMenuLocations['social']) && isset($nav_menu_locations['social'])) {
|
201 |
+
if ($nav_menu_locations['social'] == $menu_id) {
|
202 |
+
$locationSocial = "Enabled";
|
203 |
+
}
|
204 |
+
} elseif (isset($this->_OldMenuLocations['social']) && empty($nav_menu_locations['social'])) {
|
205 |
+
if ($this->_OldMenuLocations['social'] == $menu_id) {
|
206 |
+
$locationSocial = "Disabled";
|
207 |
+
}
|
208 |
+
}
|
209 |
+
// Alert 2082 Social links menu
|
210 |
+
if (!empty($locationSocial)) {
|
211 |
+
$this->EventMenuSetting($menu_data['menu-name'], $locationSocial, "Location: social menu");
|
212 |
+
}
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
private function BuildOldMenuTermsAndItems()
|
217 |
+
{
|
218 |
+
$menus = wp_get_nav_menus();
|
219 |
+
if (!empty($menus)) {
|
220 |
+
foreach ($menus as $menu) {
|
221 |
+
array_push($this->_OldMenuTerms, array("term_id" => $menu->term_id, "name" => $menu->name));
|
222 |
+
$items = wp_get_nav_menu_items($menu->term_id);
|
223 |
+
if (!empty($items)) {
|
224 |
+
foreach ($items as $item) {
|
225 |
+
array_push($this->_OldMenuItems, array(
|
226 |
+
'item_id' => $item->ID,
|
227 |
+
'title' => $item->title,
|
228 |
+
'object' => $item->object,
|
229 |
+
'menu_name' => $menu->name,
|
230 |
+
'menu_order' => $item->menu_order
|
231 |
+
));
|
232 |
+
}
|
233 |
+
}
|
234 |
+
}
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
public function EventAdminInit()
|
239 |
+
{
|
240 |
+
$is_nav_menu = basename($_SERVER['SCRIPT_NAME']) == 'nav-menus.php';
|
241 |
+
if ($is_nav_menu) {
|
242 |
+
if (isset($_GET['action']) && $_GET['action'] == 'delete') {
|
243 |
+
if (isset($_GET['menu'])) {
|
244 |
+
$this->_OldMenu = wp_get_nav_menu_object($_GET['menu']);
|
245 |
+
}
|
246 |
+
} else {
|
247 |
+
$this->BuildOldMenuTermsAndItems();
|
248 |
+
}
|
249 |
+
$this->_OldMenuLocations = get_nav_menu_locations();
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
public function CustomizeInit()
|
254 |
+
{
|
255 |
+
$this->BuildOldMenuTermsAndItems();
|
256 |
+
$this->_OldMenuLocations = get_nav_menu_locations();
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Customize Events Function
|
261 |
+
*/
|
262 |
+
public function CustomizeSave()
|
263 |
+
{
|
264 |
+
$updateMenus = array();
|
265 |
+
$menus = wp_get_nav_menus();
|
266 |
+
if (!empty($menus)) {
|
267 |
+
foreach ($menus as $menu) {
|
268 |
+
array_push($updateMenus, array("term_id" => $menu->term_id, "name" => $menu->name));
|
269 |
+
}
|
270 |
+
}
|
271 |
+
// Deleted Menu
|
272 |
+
if (isset($updateMenus) && isset($this->_OldMenuTerms)) {
|
273 |
+
$terms = array_diff(array_map('serialize', $this->_OldMenuTerms), array_map('serialize', $updateMenus));
|
274 |
+
$terms = array_map('unserialize', $terms);
|
275 |
+
|
276 |
+
if (isset($terms) && count($terms) > 0) {
|
277 |
+
foreach ($terms as $term) {
|
278 |
+
$this->plugin->alerts->Trigger(2081, array(
|
279 |
+
'MenuName' => $term['name']
|
280 |
+
));
|
281 |
+
}
|
282 |
+
}
|
283 |
+
}
|
284 |
+
if (isset($_POST['action']) && $_POST['action'] == 'customize_save') {
|
285 |
+
if (isset($_POST['wp_customize'], $_POST['customized'])) {
|
286 |
+
$customized = json_decode(wp_unslash($_POST['customized']), true);
|
287 |
+
if (is_array($customized)) {
|
288 |
+
foreach ($customized as $key => $value) {
|
289 |
+
if (!empty($value['nav_menu_term_id'])) {
|
290 |
+
$is_occurred_event = false;
|
291 |
+
$menu = wp_get_nav_menu_object($value['nav_menu_term_id']);
|
292 |
+
$content_name = !empty($value['title']) ? $value['title'] : "no title";
|
293 |
+
if (!empty($this->_OldMenuItems)) {
|
294 |
+
foreach ($this->_OldMenuItems as $old_item) {
|
295 |
+
$item_id = substr(trim($key, ']'), 14);
|
296 |
+
// Modified Items in the menu
|
297 |
+
if ($old_item['item_id'] == $item_id && $old_item['title'] != $content_name) {
|
298 |
+
$is_occurred_event = true;
|
299 |
+
$this->EventModifiedItems($value['type_label'], $content_name, $menu->name);
|
300 |
+
}
|
301 |
+
// Changed order of the objects in a menu
|
302 |
+
if ($old_item['item_id'] == $item_id && $old_item['menu_order'] != $value['position']) {
|
303 |
+
$is_occurred_event = true;
|
304 |
+
$this->EventChangeOrder($menu->name);
|
305 |
+
return;
|
306 |
+
}
|
307 |
+
}
|
308 |
+
}
|
309 |
+
// Add Items to the menu
|
310 |
+
if (!$is_occurred_event) {
|
311 |
+
$menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : $menu->name;
|
312 |
+
$this->EventAddItems($value['type_label'], $content_name, $menu_name);
|
313 |
+
}
|
314 |
+
} else {
|
315 |
+
// Menu changed name
|
316 |
+
if (isset($updateMenus) && isset($this->_OldMenuTerms)) {
|
317 |
+
foreach ($this->_OldMenuTerms as $old_menu) {
|
318 |
+
foreach ($updateMenus as $update_menu) {
|
319 |
+
if ($old_menu['term_id'] == $update_menu['term_id'] && $old_menu['name'] != $update_menu['name']) {
|
320 |
+
$this->EventChangeName($old_menu['name'], $update_menu['name']);
|
321 |
+
}
|
322 |
+
}
|
323 |
+
}
|
324 |
+
}
|
325 |
+
// Setting Auto add pages
|
326 |
+
if (!empty($value) && isset($value['auto_add'])) {
|
327 |
+
if ($value['auto_add']) {
|
328 |
+
$this->EventMenuSetting($value['name'], 'Enabled', "Auto add pages");
|
329 |
+
} else {
|
330 |
+
$this->EventMenuSetting($value['name'], 'Disabled', "Auto add pages");
|
331 |
+
}
|
332 |
+
}
|
333 |
+
// Setting Location
|
334 |
+
if (false !== strpos($key, 'nav_menu_locations[')) {
|
335 |
+
$loc = substr(trim($key, ']'), 19);
|
336 |
+
if (!empty($value)) {
|
337 |
+
$menu = wp_get_nav_menu_object($value);
|
338 |
+
$menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : (!empty($menu) ? $menu->name : '');
|
339 |
+
$this->EventMenuSetting($menu_name, "Enabled", "Location: ".$loc." menu");
|
340 |
+
} else {
|
341 |
+
if (!empty($this->_OldMenuLocations[$loc])) {
|
342 |
+
$menu = wp_get_nav_menu_object($this->_OldMenuLocations[$loc]);
|
343 |
+
$menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : (!empty($menu) ? $menu->name : '');
|
344 |
+
$this->EventMenuSetting($menu_name, "Disabled", "Location: ".$loc." menu");
|
345 |
+
}
|
346 |
+
}
|
347 |
+
}
|
348 |
+
// Remove items from the menu
|
349 |
+
if (false !== strpos($key, 'nav_menu_item[')) {
|
350 |
+
$item_id = substr(trim($key, ']'), 14);
|
351 |
+
if (!empty($this->_OldMenuItems)) {
|
352 |
+
foreach ($this->_OldMenuItems as $old_item) {
|
353 |
+
if ($old_item['item_id'] == $item_id) {
|
354 |
+
$this->EventRemoveItems($old_item['object'], $old_item['title'], $old_item['menu_name']);
|
355 |
+
}
|
356 |
+
}
|
357 |
+
}
|
358 |
+
}
|
359 |
+
}
|
360 |
+
}
|
361 |
+
}
|
362 |
+
}
|
363 |
+
}
|
364 |
+
}
|
365 |
+
|
366 |
+
private function EventAddItems($content_type, $content_name, $menu_name)
|
367 |
+
{
|
368 |
+
$this->plugin->alerts->Trigger(2079, array(
|
369 |
+
'ContentType' => $content_type,
|
370 |
+
'ContentName' => $content_name,
|
371 |
+
'MenuName' => $menu_name
|
372 |
+
));
|
373 |
+
}
|
374 |
+
|
375 |
+
private function EventRemoveItems($content_type, $content_name, $menu_name)
|
376 |
+
{
|
377 |
+
$this->plugin->alerts->Trigger(2080, array(
|
378 |
+
'ContentType' => $content_type,
|
379 |
+
'ContentName' => $content_name,
|
380 |
+
'MenuName' => $menu_name
|
381 |
+
));
|
382 |
+
}
|
383 |
+
|
384 |
+
private function EventMenuSetting($menu_name, $status, $menu_setting)
|
385 |
+
{
|
386 |
+
$this->plugin->alerts->Trigger(2082, array(
|
387 |
+
'Status' => $status,
|
388 |
+
'MenuSetting' => $menu_setting,
|
389 |
+
'MenuName' => $menu_name
|
390 |
+
));
|
391 |
+
}
|
392 |
+
|
393 |
+
private function EventModifiedItems($content_type, $content_name, $menu_name)
|
394 |
+
{
|
395 |
+
$this->plugin->alerts->Trigger(2083, array(
|
396 |
+
'ContentType' => $content_type,
|
397 |
+
'ContentName' => $content_name,
|
398 |
+
'MenuName' => $menu_name
|
399 |
+
));
|
400 |
+
}
|
401 |
+
|
402 |
+
private function EventChangeName($old_menu_name, $new_menu_name)
|
403 |
+
{
|
404 |
+
$this->plugin->alerts->Trigger(2084, array(
|
405 |
+
'OldMenuName' => $old_menu_name,
|
406 |
+
'NewMenuName' => $new_menu_name
|
407 |
+
));
|
408 |
+
}
|
409 |
+
|
410 |
+
private function EventChangeOrder($menu_name)
|
411 |
+
{
|
412 |
+
$this->plugin->alerts->Trigger(2085, array(
|
413 |
+
'MenuName' => $menu_name
|
414 |
+
));
|
415 |
+
}
|
416 |
+
}
|
classes/Sensors/MetaData.php
CHANGED
@@ -1,208 +1,208 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_MetaData extends WSAL_AbstractSensor
|
4 |
-
{
|
5 |
-
|
6 |
-
public function HookEvents()
|
7 |
-
{
|
8 |
-
add_action('add_post_meta', array($this, 'EventPostMetaCreated'), 10, 3);
|
9 |
-
add_action('update_post_meta', array($this, 'EventPostMetaUpdating'), 10, 3);
|
10 |
-
add_action('updated_post_meta', array($this, 'EventPostMetaUpdated'), 10, 4);
|
11 |
-
add_action('deleted_post_meta', array($this, 'EventPostMetaDeleted'), 10, 4);
|
12 |
-
}
|
13 |
-
|
14 |
-
protected $old_meta = array();
|
15 |
-
|
16 |
-
protected function CanLogPostMeta($object_id, $meta_key)
|
17 |
-
{
|
18 |
-
//check if excluded meta key or starts with _
|
19 |
-
if (substr($meta_key, 0, 1) == '_') {
|
20 |
-
return false;
|
21 |
-
} else if ($this->IsExcludedCustomFields($meta_key)) {
|
22 |
-
return false;
|
23 |
-
} else {
|
24 |
-
return true;
|
25 |
-
}
|
26 |
-
}
|
27 |
-
|
28 |
-
public function IsExcludedCustomFields($custom)
|
29 |
-
{
|
30 |
-
$customFields = $this->plugin->settings->GetExcludedMonitoringCustom();
|
31 |
-
return (in_array($custom, $customFields)) ? true : false;
|
32 |
-
}
|
33 |
-
|
34 |
-
public function EventPostMetaCreated($object_id, $meta_key, $meta_value)
|
35 |
-
{
|
36 |
-
$post = get_post($object_id);
|
37 |
-
|
38 |
-
if (!$this->CanLogPostMeta($object_id, $meta_key)) return;
|
39 |
-
|
40 |
-
switch ($post->post_type) {
|
41 |
-
case 'page':
|
42 |
-
$this->plugin->alerts->Trigger(2059, array(
|
43 |
-
'PostID' => $object_id,
|
44 |
-
'PostTitle' => $post->post_title,
|
45 |
-
'MetaKey' => $meta_key,
|
46 |
-
'MetaValue' => $meta_value,
|
47 |
-
'MetaLink' => $meta_key,
|
48 |
-
));
|
49 |
-
break;
|
50 |
-
case 'post':
|
51 |
-
$this->plugin->alerts->Trigger(2053, array(
|
52 |
-
'PostID' => $object_id,
|
53 |
-
'PostTitle' => $post->post_title,
|
54 |
-
'MetaKey' => $meta_key,
|
55 |
-
'MetaValue' => $meta_value,
|
56 |
-
'MetaLink' => $meta_key,
|
57 |
-
));
|
58 |
-
break;
|
59 |
-
default:
|
60 |
-
$this->plugin->alerts->Trigger(2056, array(
|
61 |
-
'PostID' => $object_id,
|
62 |
-
'PostTitle' => $post->post_title,
|
63 |
-
'PostType' => $post->post_type,
|
64 |
-
'MetaKey' => $meta_key,
|
65 |
-
'MetaValue' => $meta_value,
|
66 |
-
'MetaLink' => $meta_key,
|
67 |
-
));
|
68 |
-
break;
|
69 |
-
}
|
70 |
-
}
|
71 |
-
|
72 |
-
public function EventPostMetaUpdating($meta_id, $object_id, $meta_key)
|
73 |
-
{
|
74 |
-
static $meta_type = 'post';
|
75 |
-
$this->old_meta[$meta_id] = (object)array(
|
76 |
-
'key' => ($meta = get_metadata_by_mid($meta_type, $meta_id)) ? $meta->meta_key : $meta_key,
|
77 |
-
'val' => get_metadata($meta_type, $object_id, $meta_key, true),
|
78 |
-
);
|
79 |
-
}
|
80 |
-
|
81 |
-
public function EventPostMetaUpdated($meta_id, $object_id, $meta_key, $meta_value)
|
82 |
-
{
|
83 |
-
$post = get_post($object_id);
|
84 |
-
|
85 |
-
if (!$this->CanLogPostMeta($object_id, $meta_key)) return;
|
86 |
-
|
87 |
-
if (isset($this->old_meta[$meta_id])) {
|
88 |
-
// check change in meta key
|
89 |
-
if ($this->old_meta[$meta_id]->key != $meta_key) {
|
90 |
-
switch ($post->post_type) {
|
91 |
-
case 'page':
|
92 |
-
$this->plugin->alerts->Trigger(2064, array(
|
93 |
-
'PostID' => $object_id,
|
94 |
-
'PostTitle' => $post->post_title,
|
95 |
-
'MetaID' => $meta_id,
|
96 |
-
'MetaKeyNew' => $meta_key,
|
97 |
-
'MetaKeyOld' => $this->old_meta[$meta_id]->key,
|
98 |
-
'MetaValue' => $meta_value,
|
99 |
-
'MetaLink' => $meta_key,
|
100 |
-
));
|
101 |
-
break;
|
102 |
-
case 'post':
|
103 |
-
$this->plugin->alerts->Trigger(2062, array(
|
104 |
-
'PostID' => $object_id,
|
105 |
-
'PostTitle' => $post->post_title,
|
106 |
-
'MetaID' => $meta_id,
|
107 |
-
'MetaKeyNew' => $meta_key,
|
108 |
-
'MetaKeyOld' => $this->old_meta[$meta_id]->key,
|
109 |
-
'MetaValue' => $meta_value,
|
110 |
-
'MetaLink' => $meta_key,
|
111 |
-
));
|
112 |
-
break;
|
113 |
-
default:
|
114 |
-
$this->plugin->alerts->Trigger(2063, array(
|
115 |
-
'PostID' => $object_id,
|
116 |
-
'PostTitle' => $post->post_title,
|
117 |
-
'PostType' => $post->post_type,
|
118 |
-
'MetaID' => $meta_id,
|
119 |
-
'MetaKeyNew' => $meta_key,
|
120 |
-
'MetaKeyOld' => $this->old_meta[$meta_id]->key,
|
121 |
-
'MetaValue' => $meta_value,
|
122 |
-
'MetaLink' => $smeta_key,
|
123 |
-
));
|
124 |
-
break;
|
125 |
-
}
|
126 |
-
} else if ($this->old_meta[$meta_id]->val != $meta_value) { // check change in meta value
|
127 |
-
switch ($post->post_type) {
|
128 |
-
case 'page':
|
129 |
-
$this->plugin->alerts->Trigger(2060, array(
|
130 |
-
'PostID' => $object_id,
|
131 |
-
'PostTitle' => $post->post_title,
|
132 |
-
'MetaID' => $meta_id,
|
133 |
-
'MetaKey' => $meta_key,
|
134 |
-
'MetaValueNew' => $meta_value,
|
135 |
-
'MetaValueOld' => $this->old_meta[$meta_id]->val,
|
136 |
-
'MetaLink' => $meta_key,
|
137 |
-
));
|
138 |
-
break;
|
139 |
-
case 'post':
|
140 |
-
$this->plugin->alerts->Trigger(2054, array(
|
141 |
-
'PostID' => $object_id,
|
142 |
-
'PostTitle' => $post->post_title,
|
143 |
-
'MetaID' => $meta_id,
|
144 |
-
'MetaKey' => $meta_key,
|
145 |
-
'MetaValueNew' => $meta_value,
|
146 |
-
'MetaValueOld' => $this->old_meta[$meta_id]->val,
|
147 |
-
'MetaLink' => $meta_key,
|
148 |
-
));
|
149 |
-
break;
|
150 |
-
default:
|
151 |
-
$this->plugin->alerts->Trigger(2057, array(
|
152 |
-
'PostID' => $object_id,
|
153 |
-
'PostTitle' => $post->post_title,
|
154 |
-
'PostType' => $post->post_type,
|
155 |
-
'MetaID' => $meta_id,
|
156 |
-
'MetaKey' => $meta_key,
|
157 |
-
'MetaValueNew' => $meta_value,
|
158 |
-
'MetaValueOld' => $this->old_meta[$meta_id]->val,
|
159 |
-
'MetaLink' => $meta_key,
|
160 |
-
));
|
161 |
-
break;
|
162 |
-
}
|
163 |
-
}
|
164 |
-
// remove old meta update data
|
165 |
-
unset($this->old_meta[$meta_id]);
|
166 |
-
}
|
167 |
-
}
|
168 |
-
|
169 |
-
public function EventPostMetaDeleted($meta_ids, $object_id, $meta_key, $meta_value)
|
170 |
-
{
|
171 |
-
$post = get_post($object_id);
|
172 |
-
|
173 |
-
foreach ($meta_ids as $meta_id) {
|
174 |
-
if (!$this->CanLogPostMeta($object_id, $meta_key)) continue;
|
175 |
-
|
176 |
-
switch ($post->post_type) {
|
177 |
-
case 'page':
|
178 |
-
$this->plugin->alerts->Trigger(2061, array(
|
179 |
-
'PostID' => $object_id,
|
180 |
-
'PostTitle' => $post->post_title,
|
181 |
-
'MetaID' => $meta_id,
|
182 |
-
'MetaKey' => $meta_key,
|
183 |
-
'MetaValue' => $meta_value,
|
184 |
-
));
|
185 |
-
break;
|
186 |
-
case 'post':
|
187 |
-
$this->plugin->alerts->Trigger(2055, array(
|
188 |
-
'PostID' => $object_id,
|
189 |
-
'PostTitle' => $post->post_title,
|
190 |
-
'MetaID' => $meta_id,
|
191 |
-
'MetaKey' => $meta_key,
|
192 |
-
'MetaValue' => $meta_value,
|
193 |
-
));
|
194 |
-
break;
|
195 |
-
default:
|
196 |
-
$this->plugin->alerts->Trigger(2058, array(
|
197 |
-
'PostID' => $object_id,
|
198 |
-
'PostTitle' => $post->post_title,
|
199 |
-
'PostType' => $post->post_type,
|
200 |
-
'MetaID' => $meta_id,
|
201 |
-
'MetaKey' => $meta_key,
|
202 |
-
'MetaValue' => $meta_value,
|
203 |
-
));
|
204 |
-
break;
|
205 |
-
}
|
206 |
-
}
|
207 |
-
}
|
208 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_MetaData extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
|
6 |
+
public function HookEvents()
|
7 |
+
{
|
8 |
+
add_action('add_post_meta', array($this, 'EventPostMetaCreated'), 10, 3);
|
9 |
+
add_action('update_post_meta', array($this, 'EventPostMetaUpdating'), 10, 3);
|
10 |
+
add_action('updated_post_meta', array($this, 'EventPostMetaUpdated'), 10, 4);
|
11 |
+
add_action('deleted_post_meta', array($this, 'EventPostMetaDeleted'), 10, 4);
|
12 |
+
}
|
13 |
+
|
14 |
+
protected $old_meta = array();
|
15 |
+
|
16 |
+
protected function CanLogPostMeta($object_id, $meta_key)
|
17 |
+
{
|
18 |
+
//check if excluded meta key or starts with _
|
19 |
+
if (substr($meta_key, 0, 1) == '_') {
|
20 |
+
return false;
|
21 |
+
} else if ($this->IsExcludedCustomFields($meta_key)) {
|
22 |
+
return false;
|
23 |
+
} else {
|
24 |
+
return true;
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
public function IsExcludedCustomFields($custom)
|
29 |
+
{
|
30 |
+
$customFields = $this->plugin->settings->GetExcludedMonitoringCustom();
|
31 |
+
return (in_array($custom, $customFields)) ? true : false;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function EventPostMetaCreated($object_id, $meta_key, $meta_value)
|
35 |
+
{
|
36 |
+
$post = get_post($object_id);
|
37 |
+
|
38 |
+
if (!$this->CanLogPostMeta($object_id, $meta_key)) return;
|
39 |
+
|
40 |
+
switch ($post->post_type) {
|
41 |
+
case 'page':
|
42 |
+
$this->plugin->alerts->Trigger(2059, array(
|
43 |
+
'PostID' => $object_id,
|
44 |
+
'PostTitle' => $post->post_title,
|
45 |
+
'MetaKey' => $meta_key,
|
46 |
+
'MetaValue' => $meta_value,
|
47 |
+
'MetaLink' => $meta_key,
|
48 |
+
));
|
49 |
+
break;
|
50 |
+
case 'post':
|
51 |
+
$this->plugin->alerts->Trigger(2053, array(
|
52 |
+
'PostID' => $object_id,
|
53 |
+
'PostTitle' => $post->post_title,
|
54 |
+
'MetaKey' => $meta_key,
|
55 |
+
'MetaValue' => $meta_value,
|
56 |
+
'MetaLink' => $meta_key,
|
57 |
+
));
|
58 |
+
break;
|
59 |
+
default:
|
60 |
+
$this->plugin->alerts->Trigger(2056, array(
|
61 |
+
'PostID' => $object_id,
|
62 |
+
'PostTitle' => $post->post_title,
|
63 |
+
'PostType' => $post->post_type,
|
64 |
+
'MetaKey' => $meta_key,
|
65 |
+
'MetaValue' => $meta_value,
|
66 |
+
'MetaLink' => $meta_key,
|
67 |
+
));
|
68 |
+
break;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
public function EventPostMetaUpdating($meta_id, $object_id, $meta_key)
|
73 |
+
{
|
74 |
+
static $meta_type = 'post';
|
75 |
+
$this->old_meta[$meta_id] = (object)array(
|
76 |
+
'key' => ($meta = get_metadata_by_mid($meta_type, $meta_id)) ? $meta->meta_key : $meta_key,
|
77 |
+
'val' => get_metadata($meta_type, $object_id, $meta_key, true),
|
78 |
+
);
|
79 |
+
}
|
80 |
+
|
81 |
+
public function EventPostMetaUpdated($meta_id, $object_id, $meta_key, $meta_value)
|
82 |
+
{
|
83 |
+
$post = get_post($object_id);
|
84 |
+
|
85 |
+
if (!$this->CanLogPostMeta($object_id, $meta_key)) return;
|
86 |
+
|
87 |
+
if (isset($this->old_meta[$meta_id])) {
|
88 |
+
// check change in meta key
|
89 |
+
if ($this->old_meta[$meta_id]->key != $meta_key) {
|
90 |
+
switch ($post->post_type) {
|
91 |
+
case 'page':
|
92 |
+
$this->plugin->alerts->Trigger(2064, array(
|
93 |
+
'PostID' => $object_id,
|
94 |
+
'PostTitle' => $post->post_title,
|
95 |
+
'MetaID' => $meta_id,
|
96 |
+
'MetaKeyNew' => $meta_key,
|
97 |
+
'MetaKeyOld' => $this->old_meta[$meta_id]->key,
|
98 |
+
'MetaValue' => $meta_value,
|
99 |
+
'MetaLink' => $meta_key,
|
100 |
+
));
|
101 |
+
break;
|
102 |
+
case 'post':
|
103 |
+
$this->plugin->alerts->Trigger(2062, array(
|
104 |
+
'PostID' => $object_id,
|
105 |
+
'PostTitle' => $post->post_title,
|
106 |
+
'MetaID' => $meta_id,
|
107 |
+
'MetaKeyNew' => $meta_key,
|
108 |
+
'MetaKeyOld' => $this->old_meta[$meta_id]->key,
|
109 |
+
'MetaValue' => $meta_value,
|
110 |
+
'MetaLink' => $meta_key,
|
111 |
+
));
|
112 |
+
break;
|
113 |
+
default:
|
114 |
+
$this->plugin->alerts->Trigger(2063, array(
|
115 |
+
'PostID' => $object_id,
|
116 |
+
'PostTitle' => $post->post_title,
|
117 |
+
'PostType' => $post->post_type,
|
118 |
+
'MetaID' => $meta_id,
|
119 |
+
'MetaKeyNew' => $meta_key,
|
120 |
+
'MetaKeyOld' => $this->old_meta[$meta_id]->key,
|
121 |
+
'MetaValue' => $meta_value,
|
122 |
+
'MetaLink' => $smeta_key,
|
123 |
+
));
|
124 |
+
break;
|
125 |
+
}
|
126 |
+
} else if ($this->old_meta[$meta_id]->val != $meta_value) { // check change in meta value
|
127 |
+
switch ($post->post_type) {
|
128 |
+
case 'page':
|
129 |
+
$this->plugin->alerts->Trigger(2060, array(
|
130 |
+
'PostID' => $object_id,
|
131 |
+
'PostTitle' => $post->post_title,
|
132 |
+
'MetaID' => $meta_id,
|
133 |
+
'MetaKey' => $meta_key,
|
134 |
+
'MetaValueNew' => $meta_value,
|
135 |
+
'MetaValueOld' => $this->old_meta[$meta_id]->val,
|
136 |
+
'MetaLink' => $meta_key,
|
137 |
+
));
|
138 |
+
break;
|
139 |
+
case 'post':
|
140 |
+
$this->plugin->alerts->Trigger(2054, array(
|
141 |
+
'PostID' => $object_id,
|
142 |
+
'PostTitle' => $post->post_title,
|
143 |
+
'MetaID' => $meta_id,
|
144 |
+
'MetaKey' => $meta_key,
|
145 |
+
'MetaValueNew' => $meta_value,
|
146 |
+
'MetaValueOld' => $this->old_meta[$meta_id]->val,
|
147 |
+
'MetaLink' => $meta_key,
|
148 |
+
));
|
149 |
+
break;
|
150 |
+
default:
|
151 |
+
$this->plugin->alerts->Trigger(2057, array(
|
152 |
+
'PostID' => $object_id,
|
153 |
+
'PostTitle' => $post->post_title,
|
154 |
+
'PostType' => $post->post_type,
|
155 |
+
'MetaID' => $meta_id,
|
156 |
+
'MetaKey' => $meta_key,
|
157 |
+
'MetaValueNew' => $meta_value,
|
158 |
+
'MetaValueOld' => $this->old_meta[$meta_id]->val,
|
159 |
+
'MetaLink' => $meta_key,
|
160 |
+
));
|
161 |
+
break;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
// remove old meta update data
|
165 |
+
unset($this->old_meta[$meta_id]);
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
public function EventPostMetaDeleted($meta_ids, $object_id, $meta_key, $meta_value)
|
170 |
+
{
|
171 |
+
$post = get_post($object_id);
|
172 |
+
|
173 |
+
foreach ($meta_ids as $meta_id) {
|
174 |
+
if (!$this->CanLogPostMeta($object_id, $meta_key)) continue;
|
175 |
+
|
176 |
+
switch ($post->post_type) {
|
177 |
+
case 'page':
|
178 |
+
$this->plugin->alerts->Trigger(2061, array(
|
179 |
+
'PostID' => $object_id,
|
180 |
+
'PostTitle' => $post->post_title,
|
181 |
+
'MetaID' => $meta_id,
|
182 |
+
'MetaKey' => $meta_key,
|
183 |
+
'MetaValue' => $meta_value,
|
184 |
+
));
|
185 |
+
break;
|
186 |
+
case 'post':
|
187 |
+
$this->plugin->alerts->Trigger(2055, array(
|
188 |
+
'PostID' => $object_id,
|
189 |
+
'PostTitle' => $post->post_title,
|
190 |
+
'MetaID' => $meta_id,
|
191 |
+
'MetaKey' => $meta_key,
|
192 |
+
'MetaValue' => $meta_value,
|
193 |
+
));
|
194 |
+
break;
|
195 |
+
default:
|
196 |
+
$this->plugin->alerts->Trigger(2058, array(
|
197 |
+
'PostID' => $object_id,
|
198 |
+
'PostTitle' => $post->post_title,
|
199 |
+
'PostType' => $post->post_type,
|
200 |
+
'MetaID' => $meta_id,
|
201 |
+
'MetaKey' => $meta_key,
|
202 |
+
'MetaValue' => $meta_value,
|
203 |
+
));
|
204 |
+
break;
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
classes/Sensors/Multisite.php
CHANGED
@@ -1,130 +1,130 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
4 |
-
|
5 |
-
public function HookEvents() {
|
6 |
-
if($this->plugin->IsMultisite()){
|
7 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
8 |
-
if(current_user_can('switch_themes'))add_action('shutdown', array($this, 'EventAdminShutdown'));
|
9 |
-
add_action('wpmu_new_blog', array($this, 'EventNewBlog'), 10, 1);
|
10 |
-
add_action('archive_blog', array($this, 'EventArchiveBlog'));
|
11 |
-
add_action('unarchive_blog', array($this, 'EventUnarchiveBlog'));
|
12 |
-
add_action('activate_blog', array($this, 'EventActivateBlog'));
|
13 |
-
add_action('deactivate_blog', array($this, 'EventDeactivateBlog'));
|
14 |
-
add_action('delete_blog', array($this, 'EventDeleteBlog'));
|
15 |
-
add_action('add_user_to_blog', array($this, 'EventUserAddedToBlog'), 10, 3);
|
16 |
-
add_action('remove_user_from_blog', array($this, 'EventUserRemovedFromBlog'));
|
17 |
-
}
|
18 |
-
}
|
19 |
-
|
20 |
-
protected $old_allowedthemes = null;
|
21 |
-
|
22 |
-
public function EventAdminInit(){
|
23 |
-
$this->old_allowedthemes = array_keys((array)get_site_option('allowedthemes'));
|
24 |
-
}
|
25 |
-
|
26 |
-
public function EventAdminShutdown(){
|
27 |
-
if(is_null($this->old_allowedthemes))return;
|
28 |
-
$new_allowedthemes = array_keys((array)get_site_option('allowedthemes'));
|
29 |
-
|
30 |
-
// check for enabled themes
|
31 |
-
foreach($new_allowedthemes as $theme)
|
32 |
-
if(!in_array($theme, (array)$this->old_allowedthemes)){
|
33 |
-
$theme = wp_get_theme($theme);
|
34 |
-
$this->plugin->alerts->Trigger(5008, array(
|
35 |
-
'Theme' => (object)array(
|
36 |
-
'Name' => $theme->Name,
|
37 |
-
'ThemeURI' => $theme->ThemeURI,
|
38 |
-
'Description' => $theme->Description,
|
39 |
-
'Author' => $theme->Author,
|
40 |
-
'Version' => $theme->Version,
|
41 |
-
'get_template_directory' => $theme->get_template_directory(),
|
42 |
-
),
|
43 |
-
));
|
44 |
-
}
|
45 |
-
|
46 |
-
// check for disabled themes
|
47 |
-
foreach((array)$this->old_allowedthemes as $theme)
|
48 |
-
if(!in_array($theme, $new_allowedthemes)){
|
49 |
-
$theme = wp_get_theme($theme);
|
50 |
-
$this->plugin->alerts->Trigger(5009, array(
|
51 |
-
'Theme' => (object)array(
|
52 |
-
'Name' => $theme->Name,
|
53 |
-
'ThemeURI' => $theme->ThemeURI,
|
54 |
-
'Description' => $theme->Description,
|
55 |
-
'Author' => $theme->Author,
|
56 |
-
'Version' => $theme->Version,
|
57 |
-
'get_template_directory' => $theme->get_template_directory(),
|
58 |
-
),
|
59 |
-
));
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
public function EventNewBlog($blog_id){
|
64 |
-
$this->plugin->alerts->Trigger(7000, array(
|
65 |
-
'BlogID' => $blog_id,
|
66 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
67 |
-
));
|
68 |
-
}
|
69 |
-
|
70 |
-
public function EventArchiveBlog($blog_id){
|
71 |
-
$this->plugin->alerts->Trigger(7001, array(
|
72 |
-
'BlogID' => $blog_id,
|
73 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
74 |
-
));
|
75 |
-
}
|
76 |
-
|
77 |
-
public function EventUnarchiveBlog($blog_id){
|
78 |
-
$this->plugin->alerts->Trigger(7002, array(
|
79 |
-
'BlogID' => $blog_id,
|
80 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
81 |
-
));
|
82 |
-
}
|
83 |
-
|
84 |
-
public function EventActivateBlog($blog_id){
|
85 |
-
$this->plugin->alerts->Trigger(7003, array(
|
86 |
-
'BlogID' => $blog_id,
|
87 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
88 |
-
));
|
89 |
-
}
|
90 |
-
|
91 |
-
public function EventDeactivateBlog($blog_id){
|
92 |
-
$this->plugin->alerts->Trigger(7004, array(
|
93 |
-
'BlogID' => $blog_id,
|
94 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
95 |
-
));
|
96 |
-
}
|
97 |
-
|
98 |
-
public function EventDeleteBlog($blog_id){
|
99 |
-
$this->plugin->alerts->Trigger(7005, array(
|
100 |
-
'BlogID' => $blog_id,
|
101 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
102 |
-
));
|
103 |
-
}
|
104 |
-
|
105 |
-
public function EventUserAddedToBlog($user_id, $role, $blog_id){
|
106 |
-
$this->plugin->alerts->TriggerIf(4010, array(
|
107 |
-
'TargetUserID' => $user_id,
|
108 |
-
'TargetUsername' => get_userdata($user_id)->user_login,
|
109 |
-
'TargetUserRole' => $role,
|
110 |
-
'BlogID' => $blog_id,
|
111 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
112 |
-
), array($this, 'MustNotContainCreateUser'));
|
113 |
-
}
|
114 |
-
|
115 |
-
public function EventUserRemovedFromBlog($user_id){
|
116 |
-
$user = get_userdata($user_id);
|
117 |
-
$blog_id = (isset($_REQUEST['id']) ? $_REQUEST['id'] : 0);
|
118 |
-
$this->plugin->alerts->TriggerIf(4011, array(
|
119 |
-
'TargetUserID' => $user_id,
|
120 |
-
'TargetUsername' => $user->user_login,
|
121 |
-
'TargetUserRole' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
|
122 |
-
'BlogID' => $blog_id,
|
123 |
-
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
124 |
-
), array($this, 'MustNotContainCreateUser'));
|
125 |
-
}
|
126 |
-
|
127 |
-
public function MustNotContainCreateUser(WSAL_AlertManager $mgr){
|
128 |
-
return !$mgr->WillTrigger(4012);
|
129 |
-
}
|
130 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Multisite extends WSAL_AbstractSensor {
|
4 |
+
|
5 |
+
public function HookEvents() {
|
6 |
+
if($this->plugin->IsMultisite()){
|
7 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
8 |
+
if(current_user_can('switch_themes'))add_action('shutdown', array($this, 'EventAdminShutdown'));
|
9 |
+
add_action('wpmu_new_blog', array($this, 'EventNewBlog'), 10, 1);
|
10 |
+
add_action('archive_blog', array($this, 'EventArchiveBlog'));
|
11 |
+
add_action('unarchive_blog', array($this, 'EventUnarchiveBlog'));
|
12 |
+
add_action('activate_blog', array($this, 'EventActivateBlog'));
|
13 |
+
add_action('deactivate_blog', array($this, 'EventDeactivateBlog'));
|
14 |
+
add_action('delete_blog', array($this, 'EventDeleteBlog'));
|
15 |
+
add_action('add_user_to_blog', array($this, 'EventUserAddedToBlog'), 10, 3);
|
16 |
+
add_action('remove_user_from_blog', array($this, 'EventUserRemovedFromBlog'));
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
protected $old_allowedthemes = null;
|
21 |
+
|
22 |
+
public function EventAdminInit(){
|
23 |
+
$this->old_allowedthemes = array_keys((array)get_site_option('allowedthemes'));
|
24 |
+
}
|
25 |
+
|
26 |
+
public function EventAdminShutdown(){
|
27 |
+
if(is_null($this->old_allowedthemes))return;
|
28 |
+
$new_allowedthemes = array_keys((array)get_site_option('allowedthemes'));
|
29 |
+
|
30 |
+
// check for enabled themes
|
31 |
+
foreach($new_allowedthemes as $theme)
|
32 |
+
if(!in_array($theme, (array)$this->old_allowedthemes)){
|
33 |
+
$theme = wp_get_theme($theme);
|
34 |
+
$this->plugin->alerts->Trigger(5008, array(
|
35 |
+
'Theme' => (object)array(
|
36 |
+
'Name' => $theme->Name,
|
37 |
+
'ThemeURI' => $theme->ThemeURI,
|
38 |
+
'Description' => $theme->Description,
|
39 |
+
'Author' => $theme->Author,
|
40 |
+
'Version' => $theme->Version,
|
41 |
+
'get_template_directory' => $theme->get_template_directory(),
|
42 |
+
),
|
43 |
+
));
|
44 |
+
}
|
45 |
+
|
46 |
+
// check for disabled themes
|
47 |
+
foreach((array)$this->old_allowedthemes as $theme)
|
48 |
+
if(!in_array($theme, $new_allowedthemes)){
|
49 |
+
$theme = wp_get_theme($theme);
|
50 |
+
$this->plugin->alerts->Trigger(5009, array(
|
51 |
+
'Theme' => (object)array(
|
52 |
+
'Name' => $theme->Name,
|
53 |
+
'ThemeURI' => $theme->ThemeURI,
|
54 |
+
'Description' => $theme->Description,
|
55 |
+
'Author' => $theme->Author,
|
56 |
+
'Version' => $theme->Version,
|
57 |
+
'get_template_directory' => $theme->get_template_directory(),
|
58 |
+
),
|
59 |
+
));
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
public function EventNewBlog($blog_id){
|
64 |
+
$this->plugin->alerts->Trigger(7000, array(
|
65 |
+
'BlogID' => $blog_id,
|
66 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
67 |
+
));
|
68 |
+
}
|
69 |
+
|
70 |
+
public function EventArchiveBlog($blog_id){
|
71 |
+
$this->plugin->alerts->Trigger(7001, array(
|
72 |
+
'BlogID' => $blog_id,
|
73 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
74 |
+
));
|
75 |
+
}
|
76 |
+
|
77 |
+
public function EventUnarchiveBlog($blog_id){
|
78 |
+
$this->plugin->alerts->Trigger(7002, array(
|
79 |
+
'BlogID' => $blog_id,
|
80 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
81 |
+
));
|
82 |
+
}
|
83 |
+
|
84 |
+
public function EventActivateBlog($blog_id){
|
85 |
+
$this->plugin->alerts->Trigger(7003, array(
|
86 |
+
'BlogID' => $blog_id,
|
87 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
88 |
+
));
|
89 |
+
}
|
90 |
+
|
91 |
+
public function EventDeactivateBlog($blog_id){
|
92 |
+
$this->plugin->alerts->Trigger(7004, array(
|
93 |
+
'BlogID' => $blog_id,
|
94 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
95 |
+
));
|
96 |
+
}
|
97 |
+
|
98 |
+
public function EventDeleteBlog($blog_id){
|
99 |
+
$this->plugin->alerts->Trigger(7005, array(
|
100 |
+
'BlogID' => $blog_id,
|
101 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
102 |
+
));
|
103 |
+
}
|
104 |
+
|
105 |
+
public function EventUserAddedToBlog($user_id, $role, $blog_id){
|
106 |
+
$this->plugin->alerts->TriggerIf(4010, array(
|
107 |
+
'TargetUserID' => $user_id,
|
108 |
+
'TargetUsername' => get_userdata($user_id)->user_login,
|
109 |
+
'TargetUserRole' => $role,
|
110 |
+
'BlogID' => $blog_id,
|
111 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
112 |
+
), array($this, 'MustNotContainCreateUser'));
|
113 |
+
}
|
114 |
+
|
115 |
+
public function EventUserRemovedFromBlog($user_id){
|
116 |
+
$user = get_userdata($user_id);
|
117 |
+
$blog_id = (isset($_REQUEST['id']) ? $_REQUEST['id'] : 0);
|
118 |
+
$this->plugin->alerts->TriggerIf(4011, array(
|
119 |
+
'TargetUserID' => $user_id,
|
120 |
+
'TargetUsername' => $user->user_login,
|
121 |
+
'TargetUserRole' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
|
122 |
+
'BlogID' => $blog_id,
|
123 |
+
'SiteName' => get_blog_option($blog_id, 'blogname'),
|
124 |
+
), array($this, 'MustNotContainCreateUser'));
|
125 |
+
}
|
126 |
+
|
127 |
+
public function MustNotContainCreateUser(WSAL_AlertManager $mgr){
|
128 |
+
return !$mgr->WillTrigger(4012);
|
129 |
+
}
|
130 |
}
|
classes/Sensors/PhpErrors.php
CHANGED
@@ -1,104 +1,104 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_PhpErrors extends WSAL_AbstractSensor {
|
4 |
-
|
5 |
-
protected $_avoid_error_recursion = false;
|
6 |
-
|
7 |
-
protected $_error_types = array(
|
8 |
-
0001 => array(1,4,16,64,256,4096), // errors
|
9 |
-
0002 => array(2,32,128,512), // warnings
|
10 |
-
0003 => array(8,1024,2048,8192,16384), // notices
|
11 |
-
0004 => array(), // exceptions
|
12 |
-
0005 => array(), // shutdown
|
13 |
-
);
|
14 |
-
|
15 |
-
protected $_maybe_last_error = null;
|
16 |
-
|
17 |
-
public function HookEvents() {
|
18 |
-
if($this->plugin->settings->IsPhpErrorLoggingEnabled()){
|
19 |
-
set_error_handler(array($this, 'EventError'), E_ALL);
|
20 |
-
set_exception_handler(array($this, 'EventException'));
|
21 |
-
register_shutdown_function(array($this, 'EventShutdown'));
|
22 |
-
}
|
23 |
-
}
|
24 |
-
|
25 |
-
protected function GetErrorHash($code, $mesg, $file, $line){
|
26 |
-
return md5(implode(':', func_get_args()));
|
27 |
-
}
|
28 |
-
|
29 |
-
public function EventError($errno, $errstr, $errfile = 'unknown', $errline = 0, $errcontext = array()){
|
30 |
-
if($this->_avoid_error_recursion)return;
|
31 |
-
|
32 |
-
$errbacktrace = 'No Backtrace';
|
33 |
-
if($this->plugin->settings->IsBacktraceLoggingEnabled()){
|
34 |
-
ob_start();
|
35 |
-
debug_print_backtrace();
|
36 |
-
$errbacktrace = ob_get_clean();
|
37 |
-
}
|
38 |
-
|
39 |
-
$data = array(
|
40 |
-
'Code' => $errno,
|
41 |
-
'Message' => $errstr,
|
42 |
-
'File' => $errfile,
|
43 |
-
'Line' => $errline,
|
44 |
-
'Context' => $errcontext,
|
45 |
-
'Trace' => $errbacktrace,
|
46 |
-
);
|
47 |
-
|
48 |
-
$type = 0002; // default (middle ground)
|
49 |
-
foreach($this->_error_types as $temp => $codes){
|
50 |
-
if(in_array($errno, $codes)){
|
51 |
-
$type = $temp;
|
52 |
-
}
|
53 |
-
}
|
54 |
-
|
55 |
-
$this->_maybe_last_error = $this->GetErrorHash($errno, $errstr, $errfile, $errline);
|
56 |
-
|
57 |
-
$this->_avoid_error_recursion = true;
|
58 |
-
$this->plugin->alerts->Trigger($type, $data);
|
59 |
-
$this->_avoid_error_recursion = false;
|
60 |
-
}
|
61 |
-
|
62 |
-
public function EventException(Exception $ex){
|
63 |
-
if($this->_avoid_error_recursion)return;
|
64 |
-
|
65 |
-
$errbacktrace = 'No Backtrace';
|
66 |
-
if($this->plugin->settings->IsBacktraceLoggingEnabled()){
|
67 |
-
$errbacktrace = $ex->getTraceAsString();
|
68 |
-
}
|
69 |
-
|
70 |
-
$data = array(
|
71 |
-
'Class' => get_class($ex),
|
72 |
-
'Code' => $ex->getCode(),
|
73 |
-
'Message' => $ex->getMessage(),
|
74 |
-
'File' => $ex->getFile(),
|
75 |
-
'Line' => $ex->getLine(),
|
76 |
-
'Trace' => $errbacktrace,
|
77 |
-
);
|
78 |
-
|
79 |
-
if(method_exists($ex, 'getContext'))
|
80 |
-
$data['Context'] = $ex->getContext();
|
81 |
-
|
82 |
-
$this->_avoid_error_recursion = true;
|
83 |
-
$this->plugin->alerts->Trigger(0004, $data);
|
84 |
-
$this->_avoid_error_recursion = false;
|
85 |
-
}
|
86 |
-
|
87 |
-
public function EventShutdown(){
|
88 |
-
if($this->_avoid_error_recursion)return;
|
89 |
-
|
90 |
-
if(!!($e = error_get_last()) && ($this->_maybe_last_error != $this->GetErrorHash($e['type'], $e['message'], $e['file'], $e['line']))){
|
91 |
-
$data = array(
|
92 |
-
'Code' => $e['type'],
|
93 |
-
'Message' => $e['message'],
|
94 |
-
'File' => $e['file'],
|
95 |
-
'Line' => $e['line'],
|
96 |
-
);
|
97 |
-
|
98 |
-
$this->_avoid_error_recursion = true;
|
99 |
-
$this->plugin->alerts->Trigger(0005, $data);
|
100 |
-
$this->_avoid_error_recursion = false;
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_PhpErrors extends WSAL_AbstractSensor {
|
4 |
+
|
5 |
+
protected $_avoid_error_recursion = false;
|
6 |
+
|
7 |
+
protected $_error_types = array(
|
8 |
+
0001 => array(1,4,16,64,256,4096), // errors
|
9 |
+
0002 => array(2,32,128,512), // warnings
|
10 |
+
0003 => array(8,1024,2048,8192,16384), // notices
|
11 |
+
0004 => array(), // exceptions
|
12 |
+
0005 => array(), // shutdown
|
13 |
+
);
|
14 |
+
|
15 |
+
protected $_maybe_last_error = null;
|
16 |
+
|
17 |
+
public function HookEvents() {
|
18 |
+
if($this->plugin->settings->IsPhpErrorLoggingEnabled()){
|
19 |
+
set_error_handler(array($this, 'EventError'), E_ALL);
|
20 |
+
set_exception_handler(array($this, 'EventException'));
|
21 |
+
register_shutdown_function(array($this, 'EventShutdown'));
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function GetErrorHash($code, $mesg, $file, $line){
|
26 |
+
return md5(implode(':', func_get_args()));
|
27 |
+
}
|
28 |
+
|
29 |
+
public function EventError($errno, $errstr, $errfile = 'unknown', $errline = 0, $errcontext = array()){
|
30 |
+
if($this->_avoid_error_recursion)return;
|
31 |
+
|
32 |
+
$errbacktrace = 'No Backtrace';
|
33 |
+
if($this->plugin->settings->IsBacktraceLoggingEnabled()){
|
34 |
+
ob_start();
|
35 |
+
debug_print_backtrace();
|
36 |
+
$errbacktrace = ob_get_clean();
|
37 |
+
}
|
38 |
+
|
39 |
+
$data = array(
|
40 |
+
'Code' => $errno,
|
41 |
+
'Message' => $errstr,
|
42 |
+
'File' => $errfile,
|
43 |
+
'Line' => $errline,
|
44 |
+
'Context' => $errcontext,
|
45 |
+
'Trace' => $errbacktrace,
|
46 |
+
);
|
47 |
+
|
48 |
+
$type = 0002; // default (middle ground)
|
49 |
+
foreach($this->_error_types as $temp => $codes){
|
50 |
+
if(in_array($errno, $codes)){
|
51 |
+
$type = $temp;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
$this->_maybe_last_error = $this->GetErrorHash($errno, $errstr, $errfile, $errline);
|
56 |
+
|
57 |
+
$this->_avoid_error_recursion = true;
|
58 |
+
$this->plugin->alerts->Trigger($type, $data);
|
59 |
+
$this->_avoid_error_recursion = false;
|
60 |
+
}
|
61 |
+
|
62 |
+
public function EventException(Exception $ex){
|
63 |
+
if($this->_avoid_error_recursion)return;
|
64 |
+
|
65 |
+
$errbacktrace = 'No Backtrace';
|
66 |
+
if($this->plugin->settings->IsBacktraceLoggingEnabled()){
|
67 |
+
$errbacktrace = $ex->getTraceAsString();
|
68 |
+
}
|
69 |
+
|
70 |
+
$data = array(
|
71 |
+
'Class' => get_class($ex),
|
72 |
+
'Code' => $ex->getCode(),
|
73 |
+
'Message' => $ex->getMessage(),
|
74 |
+
'File' => $ex->getFile(),
|
75 |
+
'Line' => $ex->getLine(),
|
76 |
+
'Trace' => $errbacktrace,
|
77 |
+
);
|
78 |
+
|
79 |
+
if(method_exists($ex, 'getContext'))
|
80 |
+
$data['Context'] = $ex->getContext();
|
81 |
+
|
82 |
+
$this->_avoid_error_recursion = true;
|
83 |
+
$this->plugin->alerts->Trigger(0004, $data);
|
84 |
+
$this->_avoid_error_recursion = false;
|
85 |
+
}
|
86 |
+
|
87 |
+
public function EventShutdown(){
|
88 |
+
if($this->_avoid_error_recursion)return;
|
89 |
+
|
90 |
+
if(!!($e = error_get_last()) && ($this->_maybe_last_error != $this->GetErrorHash($e['type'], $e['message'], $e['file'], $e['line']))){
|
91 |
+
$data = array(
|
92 |
+
'Code' => $e['type'],
|
93 |
+
'Message' => $e['message'],
|
94 |
+
'File' => $e['file'],
|
95 |
+
'Line' => $e['line'],
|
96 |
+
);
|
97 |
+
|
98 |
+
$this->_avoid_error_recursion = true;
|
99 |
+
$this->plugin->alerts->Trigger(0005, $data);
|
100 |
+
$this->_avoid_error_recursion = false;
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
}
|
classes/Sensors/PluginsThemes.php
CHANGED
@@ -1,215 +1,215 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
4 |
-
|
5 |
-
public function HookEvents() {
|
6 |
-
$hasPermission = (current_user_can("install_plugins") || current_user_can("activate_plugins") ||
|
7 |
-
current_user_can("delete_plugins") || current_user_can("update_plugins") || current_user_can("install_themes"));
|
8 |
-
|
9 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
10 |
-
if($hasPermission)add_action('shutdown', array($this, 'EventAdminShutdown'));
|
11 |
-
add_action('switch_theme', array($this, 'EventThemeActivated'));
|
12 |
-
}
|
13 |
-
|
14 |
-
protected $old_themes = array();
|
15 |
-
protected $old_plugins = array();
|
16 |
-
|
17 |
-
public function EventAdminInit(){
|
18 |
-
$this->old_themes = wp_get_themes();
|
19 |
-
$this->old_plugins = get_plugins();
|
20 |
-
}
|
21 |
-
|
22 |
-
public function EventAdminShutdown(){
|
23 |
-
$action = (isset($_REQUEST['action']) && $_REQUEST['action'] != "-1") ? $_REQUEST['action'] : '';
|
24 |
-
$action = (isset($_REQUEST['action2']) && $_REQUEST['action2'] != "-1") ? $_REQUEST['action2'] : $action;
|
25 |
-
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
26 |
-
$is_themes = $actype == 'themes';
|
27 |
-
$is_plugins = $actype == 'plugins';
|
28 |
-
|
29 |
-
// install plugin
|
30 |
-
if(in_array($action, array('install-plugin', 'upload-plugin')) && current_user_can("install_plugins")){
|
31 |
-
$plugin = array_values(array_diff(array_keys(get_plugins()), array_keys($this->old_plugins)));
|
32 |
-
if(count($plugin) != 1)
|
33 |
-
return $this->LogError(
|
34 |
-
'Expected exactly one new plugin but found ' . count($plugin),
|
35 |
-
array('NewPlugin' => $plugin, 'OldPlugins' => $this->old_plugins, 'NewPlugins' => get_plugins())
|
36 |
-
);
|
37 |
-
$pluginPath = $plugin[0];
|
38 |
-
$plugin = get_plugins();
|
39 |
-
$plugin = $plugin[$pluginPath];
|
40 |
-
$pluginPath = plugin_dir_path(WP_PLUGIN_DIR . '/' . $pluginPath[0]);
|
41 |
-
$this->plugin->alerts->Trigger(5000, array(
|
42 |
-
'Plugin' => (object)array(
|
43 |
-
'Name' => $plugin['Name'],
|
44 |
-
'PluginURI' => $plugin['PluginURI'],
|
45 |
-
'Version' => $plugin['Version'],
|
46 |
-
'Author' => $plugin['Author'],
|
47 |
-
'Network' => $plugin['Network'] ? 'True' : 'False',
|
48 |
-
'plugin_dir_path' => $pluginPath,
|
49 |
-
),
|
50 |
-
));
|
51 |
-
}
|
52 |
-
|
53 |
-
// activate plugin
|
54 |
-
if($is_plugins && in_array($action, array('activate', 'activate-selected')) && current_user_can("activate_plugins")){
|
55 |
-
if(isset($_REQUEST['plugin'])){
|
56 |
-
if(!isset($_REQUEST['checked']))
|
57 |
-
$_REQUEST['checked'] = array();
|
58 |
-
$_REQUEST['checked'][] = $_REQUEST['plugin'];
|
59 |
-
}
|
60 |
-
foreach($_REQUEST['checked'] as $pluginFile){
|
61 |
-
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
62 |
-
$pluginData = get_plugin_data($pluginFile, false, true);
|
63 |
-
$this->plugin->alerts->Trigger(5001, array(
|
64 |
-
'PluginFile' => $pluginFile,
|
65 |
-
'PluginData' => (object)array(
|
66 |
-
'Name' => $pluginData['Name'],
|
67 |
-
'PluginURI' => $pluginData['PluginURI'],
|
68 |
-
'Version' => $pluginData['Version'],
|
69 |
-
'Author' => $pluginData['Author'],
|
70 |
-
'Network' => $pluginData['Network'] ? 'True' : 'False',
|
71 |
-
),
|
72 |
-
));
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
// deactivate plugin
|
77 |
-
if($is_plugins && in_array($action, array('deactivate', 'deactivate-selected')) && current_user_can("activate_plugins")){
|
78 |
-
if(isset($_REQUEST['plugin'])){
|
79 |
-
if(!isset($_REQUEST['checked']))
|
80 |
-
$_REQUEST['checked'] = array();
|
81 |
-
$_REQUEST['checked'][] = $_REQUEST['plugin'];
|
82 |
-
}
|
83 |
-
foreach($_REQUEST['checked'] as $pluginFile){
|
84 |
-
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
85 |
-
$pluginData = get_plugin_data($pluginFile, false, true);
|
86 |
-
$this->plugin->alerts->Trigger(5002, array(
|
87 |
-
'PluginFile' => $pluginFile,
|
88 |
-
'PluginData' => (object)array(
|
89 |
-
'Name' => $pluginData['Name'],
|
90 |
-
'PluginURI' => $pluginData['PluginURI'],
|
91 |
-
'Version' => $pluginData['Version'],
|
92 |
-
'Author' => $pluginData['Author'],
|
93 |
-
'Network' => $pluginData['Network'] ? 'True' : 'False',
|
94 |
-
),
|
95 |
-
));
|
96 |
-
}
|
97 |
-
}
|
98 |
-
|
99 |
-
// uninstall plugin
|
100 |
-
if($is_plugins && in_array($action, array('delete-selected')) && current_user_can("delete_plugins")){
|
101 |
-
if(!isset($_REQUEST['verify-delete'])){
|
102 |
-
// first step, before user approves deletion
|
103 |
-
// TODO store plugin data in session here
|
104 |
-
}else{
|
105 |
-
// second step, after deletion approval
|
106 |
-
// TODO use plugin data from session
|
107 |
-
foreach($_REQUEST['checked'] as $pluginFile){
|
108 |
-
$pluginName = basename($pluginFile, '.php');
|
109 |
-
$pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
|
110 |
-
$pluginName = ucwords($pluginName);
|
111 |
-
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
112 |
-
$this->plugin->alerts->Trigger(5003, array(
|
113 |
-
'PluginFile' => $pluginFile,
|
114 |
-
'PluginData' => (object)array(
|
115 |
-
'Name' => $pluginName,
|
116 |
-
),
|
117 |
-
));
|
118 |
-
}
|
119 |
-
}
|
120 |
-
}
|
121 |
-
|
122 |
-
// upgrade plugin
|
123 |
-
if(in_array($action, array('upgrade-plugin', 'update-plugin', 'update-selected')) && current_user_can("update_plugins")){
|
124 |
-
$plugins = array();
|
125 |
-
if(isset($_REQUEST['plugins'])){
|
126 |
-
$plugins = explode(",", $_REQUEST['plugins']);
|
127 |
-
} else if(isset($_REQUEST['plugin'])){
|
128 |
-
$plugins[] = $_REQUEST['plugin'];
|
129 |
-
}
|
130 |
-
if(isset($plugins)){
|
131 |
-
foreach($plugins as $pluginFile){
|
132 |
-
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
133 |
-
$pluginData = get_plugin_data($pluginFile, false, true);
|
134 |
-
$this->plugin->alerts->Trigger(5004, array(
|
135 |
-
'PluginFile' => $pluginFile,
|
136 |
-
'PluginData' => (object)array(
|
137 |
-
'Name' => $pluginData['Name'],
|
138 |
-
'PluginURI' => $pluginData['PluginURI'],
|
139 |
-
'Version' => $pluginData['Version'],
|
140 |
-
'Author' => $pluginData['Author'],
|
141 |
-
'Network' => $pluginData['Network'] ? 'True' : 'False',
|
142 |
-
),
|
143 |
-
));
|
144 |
-
}
|
145 |
-
}
|
146 |
-
}
|
147 |
-
|
148 |
-
// install theme
|
149 |
-
if(in_array($action, array('install-theme', 'upload-theme')) && current_user_can("install_themes")){
|
150 |
-
$themes = array_diff(wp_get_themes(), $this->old_themes);
|
151 |
-
foreach($themes as $theme){
|
152 |
-
$this->plugin->alerts->Trigger(5005, array(
|
153 |
-
'Theme' => (object)array(
|
154 |
-
'Name' => $theme->Name,
|
155 |
-
'ThemeURI' => $theme->ThemeURI,
|
156 |
-
'Description' => $theme->Description,
|
157 |
-
'Author' => $theme->Author,
|
158 |
-
'Version' => $theme->Version,
|
159 |
-
'get_template_directory' => $theme->get_template_directory(),
|
160 |
-
),
|
161 |
-
));
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
// uninstall theme
|
166 |
-
if($is_themes && in_array($action, array('delete-selected', 'delete')) && current_user_can("install_themes")){
|
167 |
-
foreach($this->GetRemovedThemes() as $theme){
|
168 |
-
$this->plugin->alerts->Trigger(5007, array(
|
169 |
-
'Theme' => (object)array(
|
170 |
-
'Name' => $theme->Name,
|
171 |
-
'ThemeURI' => $theme->ThemeURI,
|
172 |
-
'Description' => $theme->Description,
|
173 |
-
'Author' => $theme->Author,
|
174 |
-
'Version' => $theme->Version,
|
175 |
-
'get_template_directory' => $theme->get_template_directory(),
|
176 |
-
),
|
177 |
-
));
|
178 |
-
}
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
-
public function EventThemeActivated($themeName){
|
183 |
-
$theme = null;
|
184 |
-
foreach(wp_get_themes() as $item){
|
185 |
-
if($item->Name == $themeName){
|
186 |
-
$theme = $item;
|
187 |
-
break;
|
188 |
-
}
|
189 |
-
}
|
190 |
-
if($theme == null)
|
191 |
-
return $this->LogError(
|
192 |
-
'Could not locate theme named "' . $theme . '".',
|
193 |
-
array('ThemeName' => $themeName, 'Themes' => wp_get_themes())
|
194 |
-
);
|
195 |
-
$this->plugin->alerts->Trigger(5006, array(
|
196 |
-
'Theme' => (object)array(
|
197 |
-
'Name' => $theme->Name,
|
198 |
-
'ThemeURI' => $theme->ThemeURI,
|
199 |
-
'Description' => $theme->Description,
|
200 |
-
'Author' => $theme->Author,
|
201 |
-
'Version' => $theme->Version,
|
202 |
-
'get_template_directory' => $theme->get_template_directory(),
|
203 |
-
),
|
204 |
-
));
|
205 |
-
}
|
206 |
-
|
207 |
-
protected function GetRemovedThemes(){
|
208 |
-
$result = $this->old_themes;
|
209 |
-
foreach($result as $i => $theme)
|
210 |
-
if(file_exists($theme->get_template_directory()))
|
211 |
-
unset($result[$i]);
|
212 |
-
return array_values($result);
|
213 |
-
}
|
214 |
-
|
215 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_PluginsThemes extends WSAL_AbstractSensor {
|
4 |
+
|
5 |
+
public function HookEvents() {
|
6 |
+
$hasPermission = (current_user_can("install_plugins") || current_user_can("activate_plugins") ||
|
7 |
+
current_user_can("delete_plugins") || current_user_can("update_plugins") || current_user_can("install_themes"));
|
8 |
+
|
9 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
10 |
+
if($hasPermission)add_action('shutdown', array($this, 'EventAdminShutdown'));
|
11 |
+
add_action('switch_theme', array($this, 'EventThemeActivated'));
|
12 |
+
}
|
13 |
+
|
14 |
+
protected $old_themes = array();
|
15 |
+
protected $old_plugins = array();
|
16 |
+
|
17 |
+
public function EventAdminInit(){
|
18 |
+
$this->old_themes = wp_get_themes();
|
19 |
+
$this->old_plugins = get_plugins();
|
20 |
+
}
|
21 |
+
|
22 |
+
public function EventAdminShutdown(){
|
23 |
+
$action = (isset($_REQUEST['action']) && $_REQUEST['action'] != "-1") ? $_REQUEST['action'] : '';
|
24 |
+
$action = (isset($_REQUEST['action2']) && $_REQUEST['action2'] != "-1") ? $_REQUEST['action2'] : $action;
|
25 |
+
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
26 |
+
$is_themes = $actype == 'themes';
|
27 |
+
$is_plugins = $actype == 'plugins';
|
28 |
+
|
29 |
+
// install plugin
|
30 |
+
if(in_array($action, array('install-plugin', 'upload-plugin')) && current_user_can("install_plugins")){
|
31 |
+
$plugin = array_values(array_diff(array_keys(get_plugins()), array_keys($this->old_plugins)));
|
32 |
+
if(count($plugin) != 1)
|
33 |
+
return $this->LogError(
|
34 |
+
'Expected exactly one new plugin but found ' . count($plugin),
|
35 |
+
array('NewPlugin' => $plugin, 'OldPlugins' => $this->old_plugins, 'NewPlugins' => get_plugins())
|
36 |
+
);
|
37 |
+
$pluginPath = $plugin[0];
|
38 |
+
$plugin = get_plugins();
|
39 |
+
$plugin = $plugin[$pluginPath];
|
40 |
+
$pluginPath = plugin_dir_path(WP_PLUGIN_DIR . '/' . $pluginPath[0]);
|
41 |
+
$this->plugin->alerts->Trigger(5000, array(
|
42 |
+
'Plugin' => (object)array(
|
43 |
+
'Name' => $plugin['Name'],
|
44 |
+
'PluginURI' => $plugin['PluginURI'],
|
45 |
+
'Version' => $plugin['Version'],
|
46 |
+
'Author' => $plugin['Author'],
|
47 |
+
'Network' => $plugin['Network'] ? 'True' : 'False',
|
48 |
+
'plugin_dir_path' => $pluginPath,
|
49 |
+
),
|
50 |
+
));
|
51 |
+
}
|
52 |
+
|
53 |
+
// activate plugin
|
54 |
+
if($is_plugins && in_array($action, array('activate', 'activate-selected')) && current_user_can("activate_plugins")){
|
55 |
+
if(isset($_REQUEST['plugin'])){
|
56 |
+
if(!isset($_REQUEST['checked']))
|
57 |
+
$_REQUEST['checked'] = array();
|
58 |
+
$_REQUEST['checked'][] = $_REQUEST['plugin'];
|
59 |
+
}
|
60 |
+
foreach($_REQUEST['checked'] as $pluginFile){
|
61 |
+
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
62 |
+
$pluginData = get_plugin_data($pluginFile, false, true);
|
63 |
+
$this->plugin->alerts->Trigger(5001, array(
|
64 |
+
'PluginFile' => $pluginFile,
|
65 |
+
'PluginData' => (object)array(
|
66 |
+
'Name' => $pluginData['Name'],
|
67 |
+
'PluginURI' => $pluginData['PluginURI'],
|
68 |
+
'Version' => $pluginData['Version'],
|
69 |
+
'Author' => $pluginData['Author'],
|
70 |
+
'Network' => $pluginData['Network'] ? 'True' : 'False',
|
71 |
+
),
|
72 |
+
));
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
// deactivate plugin
|
77 |
+
if($is_plugins && in_array($action, array('deactivate', 'deactivate-selected')) && current_user_can("activate_plugins")){
|
78 |
+
if(isset($_REQUEST['plugin'])){
|
79 |
+
if(!isset($_REQUEST['checked']))
|
80 |
+
$_REQUEST['checked'] = array();
|
81 |
+
$_REQUEST['checked'][] = $_REQUEST['plugin'];
|
82 |
+
}
|
83 |
+
foreach($_REQUEST['checked'] as $pluginFile){
|
84 |
+
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
85 |
+
$pluginData = get_plugin_data($pluginFile, false, true);
|
86 |
+
$this->plugin->alerts->Trigger(5002, array(
|
87 |
+
'PluginFile' => $pluginFile,
|
88 |
+
'PluginData' => (object)array(
|
89 |
+
'Name' => $pluginData['Name'],
|
90 |
+
'PluginURI' => $pluginData['PluginURI'],
|
91 |
+
'Version' => $pluginData['Version'],
|
92 |
+
'Author' => $pluginData['Author'],
|
93 |
+
'Network' => $pluginData['Network'] ? 'True' : 'False',
|
94 |
+
),
|
95 |
+
));
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
// uninstall plugin
|
100 |
+
if($is_plugins && in_array($action, array('delete-selected')) && current_user_can("delete_plugins")){
|
101 |
+
if(!isset($_REQUEST['verify-delete'])){
|
102 |
+
// first step, before user approves deletion
|
103 |
+
// TODO store plugin data in session here
|
104 |
+
}else{
|
105 |
+
// second step, after deletion approval
|
106 |
+
// TODO use plugin data from session
|
107 |
+
foreach($_REQUEST['checked'] as $pluginFile){
|
108 |
+
$pluginName = basename($pluginFile, '.php');
|
109 |
+
$pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
|
110 |
+
$pluginName = ucwords($pluginName);
|
111 |
+
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
112 |
+
$this->plugin->alerts->Trigger(5003, array(
|
113 |
+
'PluginFile' => $pluginFile,
|
114 |
+
'PluginData' => (object)array(
|
115 |
+
'Name' => $pluginName,
|
116 |
+
),
|
117 |
+
));
|
118 |
+
}
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
// upgrade plugin
|
123 |
+
if(in_array($action, array('upgrade-plugin', 'update-plugin', 'update-selected')) && current_user_can("update_plugins")){
|
124 |
+
$plugins = array();
|
125 |
+
if(isset($_REQUEST['plugins'])){
|
126 |
+
$plugins = explode(",", $_REQUEST['plugins']);
|
127 |
+
} else if(isset($_REQUEST['plugin'])){
|
128 |
+
$plugins[] = $_REQUEST['plugin'];
|
129 |
+
}
|
130 |
+
if(isset($plugins)){
|
131 |
+
foreach($plugins as $pluginFile){
|
132 |
+
$pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
|
133 |
+
$pluginData = get_plugin_data($pluginFile, false, true);
|
134 |
+
$this->plugin->alerts->Trigger(5004, array(
|
135 |
+
'PluginFile' => $pluginFile,
|
136 |
+
'PluginData' => (object)array(
|
137 |
+
'Name' => $pluginData['Name'],
|
138 |
+
'PluginURI' => $pluginData['PluginURI'],
|
139 |
+
'Version' => $pluginData['Version'],
|
140 |
+
'Author' => $pluginData['Author'],
|
141 |
+
'Network' => $pluginData['Network'] ? 'True' : 'False',
|
142 |
+
),
|
143 |
+
));
|
144 |
+
}
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
// install theme
|
149 |
+
if(in_array($action, array('install-theme', 'upload-theme')) && current_user_can("install_themes")){
|
150 |
+
$themes = array_diff(wp_get_themes(), $this->old_themes);
|
151 |
+
foreach($themes as $theme){
|
152 |
+
$this->plugin->alerts->Trigger(5005, array(
|
153 |
+
'Theme' => (object)array(
|
154 |
+
'Name' => $theme->Name,
|
155 |
+
'ThemeURI' => $theme->ThemeURI,
|
156 |
+
'Description' => $theme->Description,
|
157 |
+
'Author' => $theme->Author,
|
158 |
+
'Version' => $theme->Version,
|
159 |
+
'get_template_directory' => $theme->get_template_directory(),
|
160 |
+
),
|
161 |
+
));
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
// uninstall theme
|
166 |
+
if($is_themes && in_array($action, array('delete-selected', 'delete')) && current_user_can("install_themes")){
|
167 |
+
foreach($this->GetRemovedThemes() as $theme){
|
168 |
+
$this->plugin->alerts->Trigger(5007, array(
|
169 |
+
'Theme' => (object)array(
|
170 |
+
'Name' => $theme->Name,
|
171 |
+
'ThemeURI' => $theme->ThemeURI,
|
172 |
+
'Description' => $theme->Description,
|
173 |
+
'Author' => $theme->Author,
|
174 |
+
'Version' => $theme->Version,
|
175 |
+
'get_template_directory' => $theme->get_template_directory(),
|
176 |
+
),
|
177 |
+
));
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
public function EventThemeActivated($themeName){
|
183 |
+
$theme = null;
|
184 |
+
foreach(wp_get_themes() as $item){
|
185 |
+
if($item->Name == $themeName){
|
186 |
+
$theme = $item;
|
187 |
+
break;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
if($theme == null)
|
191 |
+
return $this->LogError(
|
192 |
+
'Could not locate theme named "' . $theme . '".',
|
193 |
+
array('ThemeName' => $themeName, 'Themes' => wp_get_themes())
|
194 |
+
);
|
195 |
+
$this->plugin->alerts->Trigger(5006, array(
|
196 |
+
'Theme' => (object)array(
|
197 |
+
'Name' => $theme->Name,
|
198 |
+
'ThemeURI' => $theme->ThemeURI,
|
199 |
+
'Description' => $theme->Description,
|
200 |
+
'Author' => $theme->Author,
|
201 |
+
'Version' => $theme->Version,
|
202 |
+
'get_template_directory' => $theme->get_template_directory(),
|
203 |
+
),
|
204 |
+
));
|
205 |
+
}
|
206 |
+
|
207 |
+
protected function GetRemovedThemes(){
|
208 |
+
$result = $this->old_themes;
|
209 |
+
foreach($result as $i => $theme)
|
210 |
+
if(file_exists($theme->get_template_directory()))
|
211 |
+
unset($result[$i]);
|
212 |
+
return array_values($result);
|
213 |
+
}
|
214 |
+
|
215 |
+
}
|
classes/Sensors/Request.php
CHANGED
@@ -1,41 +1,41 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Request extends WSAL_AbstractSensor {
|
4 |
-
public function HookEvents() {
|
5 |
-
if($this->plugin->settings->IsRequestLoggingEnabled()){
|
6 |
-
add_action('shutdown', array($this, 'EventShutdown'));
|
7 |
-
}
|
8 |
-
}
|
9 |
-
|
10 |
-
public function EventShutdown(){
|
11 |
-
$file = $this->plugin->GetBaseDir() . 'Request.log.php';
|
12 |
-
|
13 |
-
$line = '['.date('Y-m-d H:i:s').'] '
|
14 |
-
. $_SERVER['REQUEST_METHOD'] . ' '
|
15 |
-
. $_SERVER['REQUEST_URI'] . ' '
|
16 |
-
. (!empty($_POST) ? str_pad(PHP_EOL, 24) . json_encode($_POST) : '')
|
17 |
-
. (!empty(self::$envvars) ? str_pad(PHP_EOL, 24) . json_encode(self::$envvars) : '')
|
18 |
-
. PHP_EOL;
|
19 |
-
|
20 |
-
if(!file_exists($file) && !file_put_contents($file, '<'.'?php die(\'Access Denied\'); ?>' . PHP_EOL))
|
21 |
-
return $this->LogError('Could not initialize request log file', array('file' => $file));
|
22 |
-
|
23 |
-
$f = fopen($file, 'a');
|
24 |
-
if($f){
|
25 |
-
if(!fwrite($f, $line))
|
26 |
-
$this->LogWarn('Could not write to log file', array('file' => $file));
|
27 |
-
if(!fclose($f))
|
28 |
-
$this->LogWarn('Could not close log file', array('file' => $file));
|
29 |
-
}else $this->LogWarn('Could not open log file', array('file' => $file));
|
30 |
-
}
|
31 |
-
|
32 |
-
protected static $envvars = array();
|
33 |
-
|
34 |
-
public static function SetVar($name, $value){
|
35 |
-
self::$envvars[$name] = $value;
|
36 |
-
}
|
37 |
-
|
38 |
-
public static function SetVars($data){
|
39 |
-
foreach($data as $name => $value)self::SetVar($name, $value);
|
40 |
-
}
|
41 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Request extends WSAL_AbstractSensor {
|
4 |
+
public function HookEvents() {
|
5 |
+
if($this->plugin->settings->IsRequestLoggingEnabled()){
|
6 |
+
add_action('shutdown', array($this, 'EventShutdown'));
|
7 |
+
}
|
8 |
+
}
|
9 |
+
|
10 |
+
public function EventShutdown(){
|
11 |
+
$file = $this->plugin->GetBaseDir() . 'Request.log.php';
|
12 |
+
|
13 |
+
$line = '['.date('Y-m-d H:i:s').'] '
|
14 |
+
. $_SERVER['REQUEST_METHOD'] . ' '
|
15 |
+
. $_SERVER['REQUEST_URI'] . ' '
|
16 |
+
. (!empty($_POST) ? str_pad(PHP_EOL, 24) . json_encode($_POST) : '')
|
17 |
+
. (!empty(self::$envvars) ? str_pad(PHP_EOL, 24) . json_encode(self::$envvars) : '')
|
18 |
+
. PHP_EOL;
|
19 |
+
|
20 |
+
if(!file_exists($file) && !file_put_contents($file, '<'.'?php die(\'Access Denied\'); ?>' . PHP_EOL))
|
21 |
+
return $this->LogError('Could not initialize request log file', array('file' => $file));
|
22 |
+
|
23 |
+
$f = fopen($file, 'a');
|
24 |
+
if($f){
|
25 |
+
if(!fwrite($f, $line))
|
26 |
+
$this->LogWarn('Could not write to log file', array('file' => $file));
|
27 |
+
if(!fclose($f))
|
28 |
+
$this->LogWarn('Could not close log file', array('file' => $file));
|
29 |
+
}else $this->LogWarn('Could not open log file', array('file' => $file));
|
30 |
+
}
|
31 |
+
|
32 |
+
protected static $envvars = array();
|
33 |
+
|
34 |
+
public static function SetVar($name, $value){
|
35 |
+
self::$envvars[$name] = $value;
|
36 |
+
}
|
37 |
+
|
38 |
+
public static function SetVars($data){
|
39 |
+
foreach($data as $name => $value)self::SetVar($name, $value);
|
40 |
+
}
|
41 |
}
|
classes/Sensors/System.php
CHANGED
@@ -1,168 +1,168 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_System extends WSAL_AbstractSensor
|
4 |
-
{
|
5 |
-
|
6 |
-
public function HookEvents()
|
7 |
-
{
|
8 |
-
add_action('wsal_prune', array($this, 'EventPruneEvents'), 10, 2);
|
9 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
10 |
-
|
11 |
-
add_action('automatic_updates_complete', array($this, 'WPUpdate'), 10,
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @param int $count The number of deleted events.
|
16 |
-
* @param string $query Query that selected events for deletion.
|
17 |
-
*/
|
18 |
-
public function EventPruneEvents($count, $query)
|
19 |
-
{
|
20 |
-
$this->plugin->alerts->Trigger(6000, array(
|
21 |
-
'EventCount' => $count,
|
22 |
-
'PruneQuery' => $query,
|
23 |
-
));
|
24 |
-
}
|
25 |
-
|
26 |
-
public function EventAdminInit()
|
27 |
-
{
|
28 |
-
// make sure user can actually modify target options
|
29 |
-
if (!current_user_can('manage_options')) return;
|
30 |
-
|
31 |
-
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
32 |
-
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
33 |
-
$is_option_page = $actype == 'options';
|
34 |
-
$is_network_settings = $actype == 'settings';
|
35 |
-
$is_permalink_page = $actype == 'options-permalink';
|
36 |
-
|
37 |
-
if ($is_option_page && (get_option('users_can_register') xor isset($_POST['users_can_register']))) {
|
38 |
-
$old = get_option('users_can_register') ? 'Enabled' : 'Disabled';
|
39 |
-
$new = isset($_POST['users_can_register']) ? 'Enabled' : 'Disabled';
|
40 |
-
if ($old !== $new) {
|
41 |
-
$this->plugin->alerts->Trigger(6001, array(
|
42 |
-
'OldValue' => $old,
|
43 |
-
'NewValue' => $new,
|
44 |
-
'CurrentUserID' => wp_get_current_user()->ID,
|
45 |
-
));
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
if ($is_option_page && !empty($_POST['default_role'])) {
|
50 |
-
$old = get_option('default_role');
|
51 |
-
$new = trim($_POST['default_role']);
|
52 |
-
if ($old !== $new) {
|
53 |
-
$this->plugin->alerts->Trigger(6002, array(
|
54 |
-
'OldRole' => $old,
|
55 |
-
'NewRole' => $new,
|
56 |
-
'CurrentUserID' => wp_get_current_user()->ID,
|
57 |
-
));
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
if ($is_option_page && !empty($_POST['admin_email'])) {
|
62 |
-
$old = get_option('admin_email');
|
63 |
-
$new = trim($_POST['admin_email']);
|
64 |
-
if ($old !== $new) {
|
65 |
-
$this->plugin->alerts->Trigger(6003, array(
|
66 |
-
'OldEmail' => $old,
|
67 |
-
'NewEmail' => $new,
|
68 |
-
'CurrentUserID' => wp_get_current_user()->ID,
|
69 |
-
));
|
70 |
-
}
|
71 |
-
}
|
72 |
-
|
73 |
-
if ($is_network_settings && !empty($_POST['admin_email'])) {
|
74 |
-
$old = get_site_option('admin_email');
|
75 |
-
$new = trim($_POST['admin_email']);
|
76 |
-
if ($old !== $new) {
|
77 |
-
$this->plugin->alerts->Trigger(6003, array(
|
78 |
-
'OldEmail' => $old,
|
79 |
-
'NewEmail' => $new,
|
80 |
-
'CurrentUserID' => wp_get_current_user()->ID,
|
81 |
-
));
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
if ($is_permalink_page && !empty($_POST['permalink_structure'])) {
|
86 |
-
$old = get_option('permalink_structure');
|
87 |
-
$new = trim($_POST['permalink_structure']);
|
88 |
-
if ($old !== $new) {
|
89 |
-
$this->plugin->alerts->Trigger(6005, array(
|
90 |
-
'OldPattern' => $old,
|
91 |
-
'NewPattern' => $new,
|
92 |
-
'CurrentUserID' => wp_get_current_user()->ID,
|
93 |
-
));
|
94 |
-
}
|
95 |
-
}
|
96 |
-
|
97 |
-
if ($action == 'do-core-upgrade' && isset($_REQUEST['version'])) {
|
98 |
-
$oldVersion = get_bloginfo('version');
|
99 |
-
$newVersion = $_REQUEST['version'];
|
100 |
-
if ($oldVersion !== $newVersion) {
|
101 |
-
$this->plugin->alerts->Trigger(6004, array(
|
102 |
-
'OldVersion' => $oldVersion,
|
103 |
-
'NewVersion' => $newVersion,
|
104 |
-
));
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
/* BBPress Forum support Setting */
|
109 |
-
if ($action == 'update' && isset($_REQUEST['_bbp_default_role'])) {
|
110 |
-
$oldRole = get_option('_bbp_default_role');
|
111 |
-
$newRole = $_REQUEST['_bbp_default_role'];
|
112 |
-
if ($oldRole !== $newRole) {
|
113 |
-
$this->plugin->alerts->Trigger(8009, array(
|
114 |
-
'OldRole' => $oldRole,
|
115 |
-
'NewRole' => $newRole
|
116 |
-
));
|
117 |
-
}
|
118 |
-
}
|
119 |
-
|
120 |
-
if ($action == 'update' && isset($_REQUEST['option_page']) && ($_REQUEST['option_page'] == 'bbpress')) {
|
121 |
-
// Anonymous posting
|
122 |
-
$allow_anonymous = get_option('_bbp_allow_anonymous');
|
123 |
-
$oldStatus = !empty($allow_anonymous) ? 1 : 0;
|
124 |
-
$newStatus = !empty($_REQUEST['_bbp_allow_anonymous']) ? 1 : 0;
|
125 |
-
if ($oldStatus != $newStatus) {
|
126 |
-
$status = ($newStatus == 1) ? 'Enabled' : 'Disabled';
|
127 |
-
$this->plugin->alerts->Trigger(8010, array(
|
128 |
-
'Status' => $status
|
129 |
-
));
|
130 |
-
}
|
131 |
-
// Disallow editing after
|
132 |
-
$bbp_edit_lock = get_option('_bbp_edit_lock');
|
133 |
-
$oldTime = !empty($bbp_edit_lock) ? $bbp_edit_lock : '';
|
134 |
-
$newTime = !empty($_REQUEST['_bbp_edit_lock']) ? $_REQUEST['_bbp_edit_lock'] : '';
|
135 |
-
if ($oldTime != $newTime) {
|
136 |
-
$this->plugin->alerts->Trigger(8012, array(
|
137 |
-
'OldTime' => $oldTime,
|
138 |
-
'NewTime' => $newTime
|
139 |
-
));
|
140 |
-
}
|
141 |
-
// Throttle posting every
|
142 |
-
$bbp_throttle_time = get_option('_bbp_throttle_time');
|
143 |
-
$oldTime2 = !empty($bbp_throttle_time) ? $bbp_throttle_time : '';
|
144 |
-
$newTime2 = !empty($_REQUEST['_bbp_throttle_time']) ? $_REQUEST['_bbp_throttle_time'] : '';
|
145 |
-
if ($oldTime2 != $newTime2) {
|
146 |
-
$this->plugin->alerts->Trigger(8013, array(
|
147 |
-
'OldTime' => $oldTime2,
|
148 |
-
'NewTime' => $newTime2
|
149 |
-
));
|
150 |
-
}
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* WordPress auto core update
|
156 |
-
*/
|
157 |
-
public function WPUpdate($automatic
|
158 |
-
{
|
159 |
-
if (isset($automatic['core'][0])) {
|
160 |
-
$obj = $automatic['core'][0];
|
161 |
-
$oldVersion = get_bloginfo('version');
|
162 |
-
$this->plugin->alerts->Trigger(6004, array(
|
163 |
-
'OldVersion' => $oldVersion,
|
164 |
-
'NewVersion' => $obj->item->version.' (auto update)'
|
165 |
-
));
|
166 |
-
}
|
167 |
-
}
|
168 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_System extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
|
6 |
+
public function HookEvents()
|
7 |
+
{
|
8 |
+
add_action('wsal_prune', array($this, 'EventPruneEvents'), 10, 2);
|
9 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
10 |
+
|
11 |
+
add_action('automatic_updates_complete', array($this, 'WPUpdate'), 10, 1);
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param int $count The number of deleted events.
|
16 |
+
* @param string $query Query that selected events for deletion.
|
17 |
+
*/
|
18 |
+
public function EventPruneEvents($count, $query)
|
19 |
+
{
|
20 |
+
$this->plugin->alerts->Trigger(6000, array(
|
21 |
+
'EventCount' => $count,
|
22 |
+
'PruneQuery' => $query,
|
23 |
+
));
|
24 |
+
}
|
25 |
+
|
26 |
+
public function EventAdminInit()
|
27 |
+
{
|
28 |
+
// make sure user can actually modify target options
|
29 |
+
if (!current_user_can('manage_options')) return;
|
30 |
+
|
31 |
+
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
|
32 |
+
$actype = basename($_SERVER['SCRIPT_NAME'], '.php');
|
33 |
+
$is_option_page = $actype == 'options';
|
34 |
+
$is_network_settings = $actype == 'settings';
|
35 |
+
$is_permalink_page = $actype == 'options-permalink';
|
36 |
+
|
37 |
+
if ($is_option_page && (get_option('users_can_register') xor isset($_POST['users_can_register']))) {
|
38 |
+
$old = get_option('users_can_register') ? 'Enabled' : 'Disabled';
|
39 |
+
$new = isset($_POST['users_can_register']) ? 'Enabled' : 'Disabled';
|
40 |
+
if ($old !== $new) {
|
41 |
+
$this->plugin->alerts->Trigger(6001, array(
|
42 |
+
'OldValue' => $old,
|
43 |
+
'NewValue' => $new,
|
44 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
45 |
+
));
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
if ($is_option_page && !empty($_POST['default_role'])) {
|
50 |
+
$old = get_option('default_role');
|
51 |
+
$new = trim($_POST['default_role']);
|
52 |
+
if ($old !== $new) {
|
53 |
+
$this->plugin->alerts->Trigger(6002, array(
|
54 |
+
'OldRole' => $old,
|
55 |
+
'NewRole' => $new,
|
56 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
57 |
+
));
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
if ($is_option_page && !empty($_POST['admin_email'])) {
|
62 |
+
$old = get_option('admin_email');
|
63 |
+
$new = trim($_POST['admin_email']);
|
64 |
+
if ($old !== $new) {
|
65 |
+
$this->plugin->alerts->Trigger(6003, array(
|
66 |
+
'OldEmail' => $old,
|
67 |
+
'NewEmail' => $new,
|
68 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
69 |
+
));
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
if ($is_network_settings && !empty($_POST['admin_email'])) {
|
74 |
+
$old = get_site_option('admin_email');
|
75 |
+
$new = trim($_POST['admin_email']);
|
76 |
+
if ($old !== $new) {
|
77 |
+
$this->plugin->alerts->Trigger(6003, array(
|
78 |
+
'OldEmail' => $old,
|
79 |
+
'NewEmail' => $new,
|
80 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
81 |
+
));
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
if ($is_permalink_page && !empty($_POST['permalink_structure'])) {
|
86 |
+
$old = get_option('permalink_structure');
|
87 |
+
$new = trim($_POST['permalink_structure']);
|
88 |
+
if ($old !== $new) {
|
89 |
+
$this->plugin->alerts->Trigger(6005, array(
|
90 |
+
'OldPattern' => $old,
|
91 |
+
'NewPattern' => $new,
|
92 |
+
'CurrentUserID' => wp_get_current_user()->ID,
|
93 |
+
));
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
if ($action == 'do-core-upgrade' && isset($_REQUEST['version'])) {
|
98 |
+
$oldVersion = get_bloginfo('version');
|
99 |
+
$newVersion = $_REQUEST['version'];
|
100 |
+
if ($oldVersion !== $newVersion) {
|
101 |
+
$this->plugin->alerts->Trigger(6004, array(
|
102 |
+
'OldVersion' => $oldVersion,
|
103 |
+
'NewVersion' => $newVersion,
|
104 |
+
));
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/* BBPress Forum support Setting */
|
109 |
+
if ($action == 'update' && isset($_REQUEST['_bbp_default_role'])) {
|
110 |
+
$oldRole = get_option('_bbp_default_role');
|
111 |
+
$newRole = $_REQUEST['_bbp_default_role'];
|
112 |
+
if ($oldRole !== $newRole) {
|
113 |
+
$this->plugin->alerts->Trigger(8009, array(
|
114 |
+
'OldRole' => $oldRole,
|
115 |
+
'NewRole' => $newRole
|
116 |
+
));
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
if ($action == 'update' && isset($_REQUEST['option_page']) && ($_REQUEST['option_page'] == 'bbpress')) {
|
121 |
+
// Anonymous posting
|
122 |
+
$allow_anonymous = get_option('_bbp_allow_anonymous');
|
123 |
+
$oldStatus = !empty($allow_anonymous) ? 1 : 0;
|
124 |
+
$newStatus = !empty($_REQUEST['_bbp_allow_anonymous']) ? 1 : 0;
|
125 |
+
if ($oldStatus != $newStatus) {
|
126 |
+
$status = ($newStatus == 1) ? 'Enabled' : 'Disabled';
|
127 |
+
$this->plugin->alerts->Trigger(8010, array(
|
128 |
+
'Status' => $status
|
129 |
+
));
|
130 |
+
}
|
131 |
+
// Disallow editing after
|
132 |
+
$bbp_edit_lock = get_option('_bbp_edit_lock');
|
133 |
+
$oldTime = !empty($bbp_edit_lock) ? $bbp_edit_lock : '';
|
134 |
+
$newTime = !empty($_REQUEST['_bbp_edit_lock']) ? $_REQUEST['_bbp_edit_lock'] : '';
|
135 |
+
if ($oldTime != $newTime) {
|
136 |
+
$this->plugin->alerts->Trigger(8012, array(
|
137 |
+
'OldTime' => $oldTime,
|
138 |
+
'NewTime' => $newTime
|
139 |
+
));
|
140 |
+
}
|
141 |
+
// Throttle posting every
|
142 |
+
$bbp_throttle_time = get_option('_bbp_throttle_time');
|
143 |
+
$oldTime2 = !empty($bbp_throttle_time) ? $bbp_throttle_time : '';
|
144 |
+
$newTime2 = !empty($_REQUEST['_bbp_throttle_time']) ? $_REQUEST['_bbp_throttle_time'] : '';
|
145 |
+
if ($oldTime2 != $newTime2) {
|
146 |
+
$this->plugin->alerts->Trigger(8013, array(
|
147 |
+
'OldTime' => $oldTime2,
|
148 |
+
'NewTime' => $newTime2
|
149 |
+
));
|
150 |
+
}
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* WordPress auto core update
|
156 |
+
*/
|
157 |
+
public function WPUpdate($automatic)
|
158 |
+
{
|
159 |
+
if (isset($automatic['core'][0])) {
|
160 |
+
$obj = $automatic['core'][0];
|
161 |
+
$oldVersion = get_bloginfo('version');
|
162 |
+
$this->plugin->alerts->Trigger(6004, array(
|
163 |
+
'OldVersion' => $oldVersion,
|
164 |
+
'NewVersion' => $obj->item->version.' (auto update)'
|
165 |
+
));
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
classes/Sensors/UserProfile.php
CHANGED
@@ -1,164 +1,164 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor
|
4 |
-
{
|
5 |
-
|
6 |
-
public function HookEvents()
|
7 |
-
{
|
8 |
-
add_action('admin_init', array($this, 'EventAdminInit'));
|
9 |
-
add_action('user_register', array($this, 'EventUserRegister'));
|
10 |
-
add_action('edit_user_profile_update', array($this, 'EventUserChanged'));
|
11 |
-
add_action('personal_options_update', array($this, 'EventUserChanged'));
|
12 |
-
add_action('delete_user', array($this, 'EventUserDeleted'));
|
13 |
-
add_action('wpmu_delete_user', array($this, 'EventUserDeleted'));
|
14 |
-
add_action('set_user_role', array($this, 'EventUserRoleChanged'), 10, 3);
|
15 |
-
}
|
16 |
-
|
17 |
-
protected $old_superadmins;
|
18 |
-
|
19 |
-
public function EventAdminInit()
|
20 |
-
{
|
21 |
-
if ($this->IsMultisite()) {
|
22 |
-
$this->old_superadmins = get_super_admins();
|
23 |
-
}
|
24 |
-
}
|
25 |
-
|
26 |
-
public function EventUserRegister($user_id)
|
27 |
-
{
|
28 |
-
$user = get_userdata($user_id);
|
29 |
-
$ismu = function_exists('is_multisite') && is_multisite();
|
30 |
-
$event = $ismu ? 4012 : (is_user_logged_in() ? 4001 : 4000);
|
31 |
-
$this->plugin->alerts->Trigger($event, array(
|
32 |
-
'NewUserID' => $user_id,
|
33 |
-
'NewUserData' => (object)array(
|
34 |
-
'Username' => $user->user_login,
|
35 |
-
'FirstName' => $user->user_firstname,
|
36 |
-
'LastName' => $user->user_lastname,
|
37 |
-
'Email' => $user->user_email,
|
38 |
-
'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
|
39 |
-
),
|
40 |
-
), true);
|
41 |
-
}
|
42 |
-
|
43 |
-
public function EventUserRoleChanged($user_id, $role, $oldRoles)
|
44 |
-
{
|
45 |
-
$user = get_userdata($user_id);
|
46 |
-
$aBbpRoles = array('bbp_spectator', 'bbp_moderator', 'bbp_participant', 'bbp_keymaster', 'bbp_blocked');
|
47 |
-
// remove any BBPress roles
|
48 |
-
if (is_array($oldRoles)) {
|
49 |
-
foreach ($oldRoles as $value) {
|
50 |
-
if (in_array($value, $aBbpRoles)) {
|
51 |
-
if ($_POST['bbp-forums-role'] != $value) {
|
52 |
-
$current_user = wp_get_current_user();
|
53 |
-
$this->plugin->alerts->TriggerIf(4013, array(
|
54 |
-
'TargetUsername' => $user->user_login,
|
55 |
-
'OldRole' => ucfirst(substr($value, 4)),
|
56 |
-
'NewRole' => ucfirst(substr($_POST['bbp-forums-role'], 4)),
|
57 |
-
'UserChanger' => $current_user->user_login
|
58 |
-
));
|
59 |
-
}
|
60 |
-
}
|
61 |
-
}
|
62 |
-
$oldRoles = array_diff($oldRoles, $aBbpRoles);
|
63 |
-
}
|
64 |
-
$oldRole = count($oldRoles) ? implode(', ', $oldRoles) : '';
|
65 |
-
$newRole = $role;
|
66 |
-
if ($oldRole != $newRole) {
|
67 |
-
$this->plugin->alerts->TriggerIf(4002, array(
|
68 |
-
'TargetUserID' => $user_id,
|
69 |
-
'TargetUsername' => $user->user_login,
|
70 |
-
'OldRole' => $oldRole,
|
71 |
-
'NewRole' => $newRole,
|
72 |
-
), array($this, 'MustNotContainUserChanges'));
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
public function EventUserChanged($user_id)
|
77 |
-
{
|
78 |
-
$user = get_userdata($user_id);
|
79 |
-
|
80 |
-
// password changed
|
81 |
-
if (!empty($_REQUEST['pass1']) && !empty($_REQUEST['pass2'])) {
|
82 |
-
if (trim($_REQUEST['pass1']) == trim($_REQUEST['pass2'])) {
|
83 |
-
$event = $user_id == get_current_user_id() ? 4003 : 4004;
|
84 |
-
$this->plugin->alerts->Trigger($event, array(
|
85 |
-
'TargetUserID' => $user_id,
|
86 |
-
'TargetUserData' => (object)array(
|
87 |
-
'Username' => $user->user_login,
|
88 |
-
'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
|
89 |
-
),
|
90 |
-
));
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
// email changed
|
95 |
-
if (!empty($_REQUEST['email'])) {
|
96 |
-
$oldEmail = $user->user_email;
|
97 |
-
$newEmail = trim($_REQUEST['email']);
|
98 |
-
if ($oldEmail != $newEmail) {
|
99 |
-
$event = $user_id == get_current_user_id() ? 4005 : 4006;
|
100 |
-
$this->plugin->alerts->Trigger($event, array(
|
101 |
-
'TargetUserID' => $user_id,
|
102 |
-
'TargetUsername' => $user->user_login,
|
103 |
-
'OldEmail' => $oldEmail,
|
104 |
-
'NewEmail' => $newEmail,
|
105 |
-
));
|
106 |
-
}
|
107 |
-
}
|
108 |
-
|
109 |
-
if ($this->IsMultisite()) {
|
110 |
-
$username = $user->user_login;
|
111 |
-
$enabled = isset($_REQUEST['super_admin']);
|
112 |
-
|
113 |
-
if ($user_id != get_current_user_id()) {
|
114 |
-
// super admin enabled
|
115 |
-
if ($enabled && !in_array($username, $this->old_superadmins)) {
|
116 |
-
$this->plugin->alerts->Trigger(4008, array(
|
117 |
-
'TargetUserID' => $user_id,
|
118 |
-
'TargetUsername' => $user->user_login,
|
119 |
-
));
|
120 |
-
}
|
121 |
-
|
122 |
-
// super admin disabled
|
123 |
-
if (!$enabled && in_array($username, $this->old_superadmins)) {
|
124 |
-
$this->plugin->alerts->Trigger(4009, array(
|
125 |
-
'TargetUserID' => $user_id,
|
126 |
-
'TargetUsername' => $user->user_login,
|
127 |
-
));
|
128 |
-
}
|
129 |
-
|
130 |
-
}
|
131 |
-
}
|
132 |
-
}
|
133 |
-
|
134 |
-
public function EventUserDeleted($user_id)
|
135 |
-
{
|
136 |
-
$user = get_userdata($user_id);
|
137 |
-
$role = is_array($user->roles) ? implode(', ', $user->roles) : $user->roles;
|
138 |
-
$this->plugin->alerts->TriggerIf(4007, array(
|
139 |
-
'TargetUserID' => $user_id,
|
140 |
-
'TargetUserData' => (object)array(
|
141 |
-
'Username' => $user->user_login,
|
142 |
-
'FirstName' => $user->user_firstname,
|
143 |
-
'LastName' => $user->user_lastname,
|
144 |
-
'Email' => $user->user_email,
|
145 |
-
'Roles' => $role ? $role : 'none',
|
146 |
-
),
|
147 |
-
), array($this, 'MustNotContainCreateUser'));
|
148 |
-
}
|
149 |
-
|
150 |
-
public function MustNotContainCreateUser(WSAL_AlertManager $mgr)
|
151 |
-
{
|
152 |
-
return !$mgr->WillTrigger(4012);
|
153 |
-
}
|
154 |
-
|
155 |
-
public function MustNotContainUserChanges(WSAL_AlertManager $mgr)
|
156 |
-
{
|
157 |
-
return !( $mgr->WillOrHasTriggered(4010)
|
158 |
-
|| $mgr->WillOrHasTriggered(4011)
|
159 |
-
|| $mgr->WillOrHasTriggered(4012)
|
160 |
-
|| $mgr->WillOrHasTriggered(4000)
|
161 |
-
|| $mgr->WillOrHasTriggered(4001)
|
162 |
-
);
|
163 |
-
}
|
164 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor
|
4 |
+
{
|
5 |
+
|
6 |
+
public function HookEvents()
|
7 |
+
{
|
8 |
+
add_action('admin_init', array($this, 'EventAdminInit'));
|
9 |
+
add_action('user_register', array($this, 'EventUserRegister'));
|
10 |
+
add_action('edit_user_profile_update', array($this, 'EventUserChanged'));
|
11 |
+
add_action('personal_options_update', array($this, 'EventUserChanged'));
|
12 |
+
add_action('delete_user', array($this, 'EventUserDeleted'));
|
13 |
+
add_action('wpmu_delete_user', array($this, 'EventUserDeleted'));
|
14 |
+
add_action('set_user_role', array($this, 'EventUserRoleChanged'), 10, 3);
|
15 |
+
}
|
16 |
+
|
17 |
+
protected $old_superadmins;
|
18 |
+
|
19 |
+
public function EventAdminInit()
|
20 |
+
{
|
21 |
+
if ($this->IsMultisite()) {
|
22 |
+
$this->old_superadmins = get_super_admins();
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
public function EventUserRegister($user_id)
|
27 |
+
{
|
28 |
+
$user = get_userdata($user_id);
|
29 |
+
$ismu = function_exists('is_multisite') && is_multisite();
|
30 |
+
$event = $ismu ? 4012 : (is_user_logged_in() ? 4001 : 4000);
|
31 |
+
$this->plugin->alerts->Trigger($event, array(
|
32 |
+
'NewUserID' => $user_id,
|
33 |
+
'NewUserData' => (object)array(
|
34 |
+
'Username' => $user->user_login,
|
35 |
+
'FirstName' => $user->user_firstname,
|
36 |
+
'LastName' => $user->user_lastname,
|
37 |
+
'Email' => $user->user_email,
|
38 |
+
'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
|
39 |
+
),
|
40 |
+
), true);
|
41 |
+
}
|
42 |
+
|
43 |
+
public function EventUserRoleChanged($user_id, $role, $oldRoles)
|
44 |
+
{
|
45 |
+
$user = get_userdata($user_id);
|
46 |
+
$aBbpRoles = array('bbp_spectator', 'bbp_moderator', 'bbp_participant', 'bbp_keymaster', 'bbp_blocked');
|
47 |
+
// remove any BBPress roles
|
48 |
+
if (is_array($oldRoles)) {
|
49 |
+
foreach ($oldRoles as $value) {
|
50 |
+
if (in_array($value, $aBbpRoles)) {
|
51 |
+
if ($_POST['bbp-forums-role'] != $value) {
|
52 |
+
$current_user = wp_get_current_user();
|
53 |
+
$this->plugin->alerts->TriggerIf(4013, array(
|
54 |
+
'TargetUsername' => $user->user_login,
|
55 |
+
'OldRole' => ucfirst(substr($value, 4)),
|
56 |
+
'NewRole' => ucfirst(substr($_POST['bbp-forums-role'], 4)),
|
57 |
+
'UserChanger' => $current_user->user_login
|
58 |
+
));
|
59 |
+
}
|
60 |
+
}
|
61 |
+
}
|
62 |
+
$oldRoles = array_diff($oldRoles, $aBbpRoles);
|
63 |
+
}
|
64 |
+
$oldRole = count($oldRoles) ? implode(', ', $oldRoles) : '';
|
65 |
+
$newRole = $role;
|
66 |
+
if ($oldRole != $newRole) {
|
67 |
+
$this->plugin->alerts->TriggerIf(4002, array(
|
68 |
+
'TargetUserID' => $user_id,
|
69 |
+
'TargetUsername' => $user->user_login,
|
70 |
+
'OldRole' => $oldRole,
|
71 |
+
'NewRole' => $newRole,
|
72 |
+
), array($this, 'MustNotContainUserChanges'));
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
public function EventUserChanged($user_id)
|
77 |
+
{
|
78 |
+
$user = get_userdata($user_id);
|
79 |
+
|
80 |
+
// password changed
|
81 |
+
if (!empty($_REQUEST['pass1']) && !empty($_REQUEST['pass2'])) {
|
82 |
+
if (trim($_REQUEST['pass1']) == trim($_REQUEST['pass2'])) {
|
83 |
+
$event = $user_id == get_current_user_id() ? 4003 : 4004;
|
84 |
+
$this->plugin->alerts->Trigger($event, array(
|
85 |
+
'TargetUserID' => $user_id,
|
86 |
+
'TargetUserData' => (object)array(
|
87 |
+
'Username' => $user->user_login,
|
88 |
+
'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
|
89 |
+
),
|
90 |
+
));
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
// email changed
|
95 |
+
if (!empty($_REQUEST['email'])) {
|
96 |
+
$oldEmail = $user->user_email;
|
97 |
+
$newEmail = trim($_REQUEST['email']);
|
98 |
+
if ($oldEmail != $newEmail) {
|
99 |
+
$event = $user_id == get_current_user_id() ? 4005 : 4006;
|
100 |
+
$this->plugin->alerts->Trigger($event, array(
|
101 |
+
'TargetUserID' => $user_id,
|
102 |
+
'TargetUsername' => $user->user_login,
|
103 |
+
'OldEmail' => $oldEmail,
|
104 |
+
'NewEmail' => $newEmail,
|
105 |
+
));
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
if ($this->IsMultisite()) {
|
110 |
+
$username = $user->user_login;
|
111 |
+
$enabled = isset($_REQUEST['super_admin']);
|
112 |
+
|
113 |
+
if ($user_id != get_current_user_id()) {
|
114 |
+
// super admin enabled
|
115 |
+
if ($enabled && !in_array($username, $this->old_superadmins)) {
|
116 |
+
$this->plugin->alerts->Trigger(4008, array(
|
117 |
+
'TargetUserID' => $user_id,
|
118 |
+
'TargetUsername' => $user->user_login,
|
119 |
+
));
|
120 |
+
}
|
121 |
+
|
122 |
+
// super admin disabled
|
123 |
+
if (!$enabled && in_array($username, $this->old_superadmins)) {
|
124 |
+
$this->plugin->alerts->Trigger(4009, array(
|
125 |
+
'TargetUserID' => $user_id,
|
126 |
+
'TargetUsername' => $user->user_login,
|
127 |
+
));
|
128 |
+
}
|
129 |
+
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
public function EventUserDeleted($user_id)
|
135 |
+
{
|
136 |
+
$user = get_userdata($user_id);
|
137 |
+
$role = is_array($user->roles) ? implode(', ', $user->roles) : $user->roles;
|
138 |
+
$this->plugin->alerts->TriggerIf(4007, array(
|
139 |
+
'TargetUserID' => $user_id,
|
140 |
+
'TargetUserData' => (object)array(
|
141 |
+
'Username' => $user->user_login,
|
142 |
+
'FirstName' => $user->user_firstname,
|
143 |
+
'LastName' => $user->user_lastname,
|
144 |
+
'Email' => $user->user_email,
|
145 |
+
'Roles' => $role ? $role : 'none',
|
146 |
+
),
|
147 |
+
), array($this, 'MustNotContainCreateUser'));
|
148 |
+
}
|
149 |
+
|
150 |
+
public function MustNotContainCreateUser(WSAL_AlertManager $mgr)
|
151 |
+
{
|
152 |
+
return !$mgr->WillTrigger(4012);
|
153 |
+
}
|
154 |
+
|
155 |
+
public function MustNotContainUserChanges(WSAL_AlertManager $mgr)
|
156 |
+
{
|
157 |
+
return !( $mgr->WillOrHasTriggered(4010)
|
158 |
+
|| $mgr->WillOrHasTriggered(4011)
|
159 |
+
|| $mgr->WillOrHasTriggered(4012)
|
160 |
+
|| $mgr->WillOrHasTriggered(4000)
|
161 |
+
|| $mgr->WillOrHasTriggered(4001)
|
162 |
+
);
|
163 |
+
}
|
164 |
+
}
|
classes/Sensors/Widgets.php
CHANGED
@@ -1,235 +1,235 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
4 |
-
|
5 |
-
public function HookEvents() {
|
6 |
-
if(current_user_can("edit_theme_options")) {
|
7 |
-
add_action('admin_init', array($this, 'EventWidgetMove'));
|
8 |
-
add_action('admin_init', array($this, 'EventWidgetPostMove'));
|
9 |
-
}
|
10 |
-
add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
|
11 |
-
}
|
12 |
-
|
13 |
-
protected $_WidgetMoveData = null;
|
14 |
-
|
15 |
-
public function EventWidgetMove(){
|
16 |
-
if(isset($_POST) && !empty($_POST['sidebars']))
|
17 |
-
{
|
18 |
-
$crtSidebars = $_POST['sidebars'];
|
19 |
-
$sidebars = array();
|
20 |
-
foreach ( $crtSidebars as $key => $val )
|
21 |
-
{
|
22 |
-
$sb = array();
|
23 |
-
if ( !empty($val) )
|
24 |
-
{
|
25 |
-
$val = explode(',', $val);
|
26 |
-
foreach ( $val as $k => $v )
|
27 |
-
{
|
28 |
-
if ( strpos($v, 'widget-') === false ) continue;
|
29 |
-
$sb[$k] = substr($v, strpos($v, '_') + 1);
|
30 |
-
}
|
31 |
-
}
|
32 |
-
$sidebars[$key] = $sb;
|
33 |
-
}
|
34 |
-
$crtSidebars = $sidebars;
|
35 |
-
$dbSidebars = get_option('sidebars_widgets');
|
36 |
-
$wName = $fromSidebar = $toSidebar = '';
|
37 |
-
foreach($crtSidebars as $sidebarName => $values)
|
38 |
-
{
|
39 |
-
if(is_array($values) && ! empty($values) && isset($dbSidebars[$sidebarName]))
|
40 |
-
{
|
41 |
-
foreach($values as $widgetName)
|
42 |
-
{
|
43 |
-
if(! in_array($widgetName, $dbSidebars[$sidebarName]))
|
44 |
-
{
|
45 |
-
$toSidebar = $sidebarName;
|
46 |
-
$wName = $widgetName;
|
47 |
-
foreach($dbSidebars as $name => $v)
|
48 |
-
{
|
49 |
-
if(is_array($v) && !empty($v) && in_array($widgetName, $v))
|
50 |
-
{
|
51 |
-
$fromSidebar = $name;
|
52 |
-
continue;
|
53 |
-
}
|
54 |
-
}
|
55 |
-
}
|
56 |
-
}
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
if (empty($wName) || empty($fromSidebar) || empty($toSidebar)) return;
|
61 |
-
|
62 |
-
if(preg_match('/^sidebar-/', $fromSidebar) || preg_match('/^sidebar-/', $toSidebar)){
|
63 |
-
// This option will hold the data needed to trigger the event 2045
|
64 |
-
// as at this moment the $wp_registered_sidebars variable is not yet populated
|
65 |
-
// so we cannot retrieve the name for sidebar-1 || sidebar-2
|
66 |
-
// we will then check for this variable in the EventWidgetPostMove() event
|
67 |
-
$this->_WidgetMoveData = array('widget' => $wName, 'from' => $fromSidebar, 'to' => $toSidebar);
|
68 |
-
return;
|
69 |
-
}
|
70 |
-
|
71 |
-
$this->plugin->alerts->Trigger(2045, array(
|
72 |
-
'WidgetName' => $wName,
|
73 |
-
'OldSidebar' => $fromSidebar,
|
74 |
-
'NewSidebar' => $toSidebar,
|
75 |
-
));
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
public function EventWidgetPostMove() {
|
80 |
-
//#!-- generates the event 2071
|
81 |
-
if (isset($_REQUEST['action'])&&($_REQUEST['action']=='widgets-order'))
|
82 |
-
{
|
83 |
-
if (isset($_REQUEST['sidebars'])) {
|
84 |
-
// Get the sidebars from $_REQUEST
|
85 |
-
$requestSidebars = array();
|
86 |
-
if ($_REQUEST['sidebars']) {
|
87 |
-
foreach($_REQUEST['sidebars'] as $key => &$value){
|
88 |
-
if(!empty($value)){
|
89 |
-
// build the sidebars array
|
90 |
-
$value = explode(',', $value);
|
91 |
-
// Cleanup widgets' name
|
92 |
-
foreach($value as $k => &$widgetName){
|
93 |
-
$widgetName = preg_replace("/^([a-z]+-[0-9]+)+?_/i",'', $widgetName);
|
94 |
-
}
|
95 |
-
$requestSidebars[$key] = $value;
|
96 |
-
}
|
97 |
-
}
|
98 |
-
}
|
99 |
-
|
100 |
-
if ($requestSidebars) {
|
101 |
-
// Get the sidebars from DATABASE
|
102 |
-
$sidebar_widgets = wp_get_sidebars_widgets();
|
103 |
-
// Get global sidebars so we can retrieve the real name of the sidebar
|
104 |
-
global $wp_registered_sidebars;
|
105 |
-
|
106 |
-
// Check in each array if there's any change
|
107 |
-
foreach ($requestSidebars as $sidebarName => $widgets) {
|
108 |
-
if (isset($sidebar_widgets[$sidebarName])) {
|
109 |
-
foreach ($sidebar_widgets[$sidebarName] as $i => $widgetName) {
|
110 |
-
$index = array_search($widgetName, $widgets);
|
111 |
-
// check to see whether or not the widget has been moved
|
112 |
-
if ($i != $index) {
|
113 |
-
$sn = $sidebarName;
|
114 |
-
// Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebarName
|
115 |
-
if ($wp_registered_sidebars && isset($wp_registered_sidebars[$sidebarName])) {
|
116 |
-
$sn = $wp_registered_sidebars[$sidebarName]['name'];
|
117 |
-
}
|
118 |
-
$this->plugin->alerts->Trigger(2071, array(
|
119 |
-
'WidgetName' => $widgetName,
|
120 |
-
'OldPosition' => $i+1,
|
121 |
-
'NewPosition' => $index+1,
|
122 |
-
'Sidebar' => $sn,
|
123 |
-
));
|
124 |
-
}
|
125 |
-
}
|
126 |
-
}
|
127 |
-
}
|
128 |
-
}
|
129 |
-
}
|
130 |
-
}
|
131 |
-
//#!--
|
132 |
-
|
133 |
-
if($this->_WidgetMoveData){
|
134 |
-
$wName = $this->_WidgetMoveData['widget'];
|
135 |
-
$fromSidebar = $this->_WidgetMoveData['from'];
|
136 |
-
$toSidebar = $this->_WidgetMoveData['to'];
|
137 |
-
|
138 |
-
global $wp_registered_sidebars;
|
139 |
-
|
140 |
-
if(preg_match('/^sidebar-/', $fromSidebar))
|
141 |
-
$fromSidebar = isset($wp_registered_sidebars[$fromSidebar])
|
142 |
-
? $wp_registered_sidebars[$fromSidebar]['name']
|
143 |
-
: $fromSidebar
|
144 |
-
;
|
145 |
-
if(preg_match('/^sidebar-/', $toSidebar))
|
146 |
-
$toSidebar = isset($wp_registered_sidebars[$toSidebar])
|
147 |
-
? $wp_registered_sidebars[$toSidebar]['name']
|
148 |
-
: $toSidebar
|
149 |
-
;
|
150 |
-
|
151 |
-
$this->plugin->alerts->Trigger(2045, array(
|
152 |
-
'WidgetName' => $wName,
|
153 |
-
'OldSidebar' => $fromSidebar,
|
154 |
-
'NewSidebar' => $toSidebar,
|
155 |
-
));
|
156 |
-
}
|
157 |
-
}
|
158 |
-
|
159 |
-
public function EventWidgetActivity(){
|
160 |
-
if(!isset($_POST) || !isset($_POST['widget-id']) || empty($_POST['widget-id'])){
|
161 |
-
return;
|
162 |
-
}
|
163 |
-
|
164 |
-
$postData = $_POST;
|
165 |
-
global $wp_registered_sidebars;
|
166 |
-
$canCheckSidebar = (empty($wp_registered_sidebars) ? false : true);
|
167 |
-
|
168 |
-
switch(true){
|
169 |
-
|
170 |
-
// added widget
|
171 |
-
case isset($postData['add_new']) && $postData['add_new'] == 'multi':
|
172 |
-
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
173 |
-
if($canCheckSidebar && preg_match('/^sidebar-/', $sidebar)){
|
174 |
-
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
175 |
-
}
|
176 |
-
$this->plugin->alerts->Trigger(2042, array(
|
177 |
-
'WidgetName' => $postData['id_base'],
|
178 |
-
'Sidebar' => $sidebar,
|
179 |
-
));
|
180 |
-
break;
|
181 |
-
|
182 |
-
// deleted widget
|
183 |
-
case isset($postData['delete_widget']) && intval($postData['delete_widget']) == 1:
|
184 |
-
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
185 |
-
if($canCheckSidebar && preg_match('/^sidebar-/',$sidebar)){
|
186 |
-
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
187 |
-
}
|
188 |
-
$this->plugin->alerts->Trigger(2044, array(
|
189 |
-
'WidgetName' => $postData['id_base'],
|
190 |
-
'Sidebar' => $sidebar,
|
191 |
-
));
|
192 |
-
break;
|
193 |
-
|
194 |
-
// modified widget
|
195 |
-
case isset($postData['id_base']) && !empty($postData['id_base']):
|
196 |
-
$wId = 0;
|
197 |
-
if(!empty($postData['multi_number'])){
|
198 |
-
$wId = intval($postData['multi_number']);
|
199 |
-
}elseif(!empty($postData['widget_number'])){
|
200 |
-
$wId = intval($postData['widget_number']);
|
201 |
-
}
|
202 |
-
if(empty($wId))return;
|
203 |
-
|
204 |
-
$wName = $postData['id_base'];
|
205 |
-
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
206 |
-
$wData = isset($postData["widget-$wName"][$wId])
|
207 |
-
? $postData["widget-$wName"][$wId]
|
208 |
-
: null;
|
209 |
-
|
210 |
-
if(empty($wData))return;
|
211 |
-
|
212 |
-
// get info from db
|
213 |
-
$wdbData = get_option("widget_".$wName);
|
214 |
-
if(empty($wdbData[$wId]))return;
|
215 |
-
|
216 |
-
// transform 'on' -> 1
|
217 |
-
foreach($wData as $k => $v)if($v == 'on')$wData[$k] = 1;
|
218 |
-
|
219 |
-
// compare - checks for any changes inside widgets
|
220 |
-
$diff = array_diff_assoc($wData, $wdbData[$wId]);
|
221 |
-
$count = count($diff);
|
222 |
-
if($count > 0){
|
223 |
-
if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
|
224 |
-
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
225 |
-
}
|
226 |
-
$this->plugin->alerts->Trigger(2043, array(
|
227 |
-
'WidgetName' => $wName,
|
228 |
-
'Sidebar' => $sidebar,
|
229 |
-
));
|
230 |
-
}
|
231 |
-
break;
|
232 |
-
|
233 |
-
}
|
234 |
-
}
|
235 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
|
4 |
+
|
5 |
+
public function HookEvents() {
|
6 |
+
if(current_user_can("edit_theme_options")) {
|
7 |
+
add_action('admin_init', array($this, 'EventWidgetMove'));
|
8 |
+
add_action('admin_init', array($this, 'EventWidgetPostMove'));
|
9 |
+
}
|
10 |
+
add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
|
11 |
+
}
|
12 |
+
|
13 |
+
protected $_WidgetMoveData = null;
|
14 |
+
|
15 |
+
public function EventWidgetMove(){
|
16 |
+
if(isset($_POST) && !empty($_POST['sidebars']))
|
17 |
+
{
|
18 |
+
$crtSidebars = $_POST['sidebars'];
|
19 |
+
$sidebars = array();
|
20 |
+
foreach ( $crtSidebars as $key => $val )
|
21 |
+
{
|
22 |
+
$sb = array();
|
23 |
+
if ( !empty($val) )
|
24 |
+
{
|
25 |
+
$val = explode(',', $val);
|
26 |
+
foreach ( $val as $k => $v )
|
27 |
+
{
|
28 |
+
if ( strpos($v, 'widget-') === false ) continue;
|
29 |
+
$sb[$k] = substr($v, strpos($v, '_') + 1);
|
30 |
+
}
|
31 |
+
}
|
32 |
+
$sidebars[$key] = $sb;
|
33 |
+
}
|
34 |
+
$crtSidebars = $sidebars;
|
35 |
+
$dbSidebars = get_option('sidebars_widgets');
|
36 |
+
$wName = $fromSidebar = $toSidebar = '';
|
37 |
+
foreach($crtSidebars as $sidebarName => $values)
|
38 |
+
{
|
39 |
+
if(is_array($values) && ! empty($values) && isset($dbSidebars[$sidebarName]))
|
40 |
+
{
|
41 |
+
foreach($values as $widgetName)
|
42 |
+
{
|
43 |
+
if(! in_array($widgetName, $dbSidebars[$sidebarName]))
|
44 |
+
{
|
45 |
+
$toSidebar = $sidebarName;
|
46 |
+
$wName = $widgetName;
|
47 |
+
foreach($dbSidebars as $name => $v)
|
48 |
+
{
|
49 |
+
if(is_array($v) && !empty($v) && in_array($widgetName, $v))
|
50 |
+
{
|
51 |
+
$fromSidebar = $name;
|
52 |
+
continue;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
if (empty($wName) || empty($fromSidebar) || empty($toSidebar)) return;
|
61 |
+
|
62 |
+
if(preg_match('/^sidebar-/', $fromSidebar) || preg_match('/^sidebar-/', $toSidebar)){
|
63 |
+
// This option will hold the data needed to trigger the event 2045
|
64 |
+
// as at this moment the $wp_registered_sidebars variable is not yet populated
|
65 |
+
// so we cannot retrieve the name for sidebar-1 || sidebar-2
|
66 |
+
// we will then check for this variable in the EventWidgetPostMove() event
|
67 |
+
$this->_WidgetMoveData = array('widget' => $wName, 'from' => $fromSidebar, 'to' => $toSidebar);
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
|
71 |
+
$this->plugin->alerts->Trigger(2045, array(
|
72 |
+
'WidgetName' => $wName,
|
73 |
+
'OldSidebar' => $fromSidebar,
|
74 |
+
'NewSidebar' => $toSidebar,
|
75 |
+
));
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
public function EventWidgetPostMove() {
|
80 |
+
//#!-- generates the event 2071
|
81 |
+
if (isset($_REQUEST['action'])&&($_REQUEST['action']=='widgets-order'))
|
82 |
+
{
|
83 |
+
if (isset($_REQUEST['sidebars'])) {
|
84 |
+
// Get the sidebars from $_REQUEST
|
85 |
+
$requestSidebars = array();
|
86 |
+
if ($_REQUEST['sidebars']) {
|
87 |
+
foreach($_REQUEST['sidebars'] as $key => &$value){
|
88 |
+
if(!empty($value)){
|
89 |
+
// build the sidebars array
|
90 |
+
$value = explode(',', $value);
|
91 |
+
// Cleanup widgets' name
|
92 |
+
foreach($value as $k => &$widgetName){
|
93 |
+
$widgetName = preg_replace("/^([a-z]+-[0-9]+)+?_/i",'', $widgetName);
|
94 |
+
}
|
95 |
+
$requestSidebars[$key] = $value;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
if ($requestSidebars) {
|
101 |
+
// Get the sidebars from DATABASE
|
102 |
+
$sidebar_widgets = wp_get_sidebars_widgets();
|
103 |
+
// Get global sidebars so we can retrieve the real name of the sidebar
|
104 |
+
global $wp_registered_sidebars;
|
105 |
+
|
106 |
+
// Check in each array if there's any change
|
107 |
+
foreach ($requestSidebars as $sidebarName => $widgets) {
|
108 |
+
if (isset($sidebar_widgets[$sidebarName])) {
|
109 |
+
foreach ($sidebar_widgets[$sidebarName] as $i => $widgetName) {
|
110 |
+
$index = array_search($widgetName, $widgets);
|
111 |
+
// check to see whether or not the widget has been moved
|
112 |
+
if ($i != $index) {
|
113 |
+
$sn = $sidebarName;
|
114 |
+
// Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebarName
|
115 |
+
if ($wp_registered_sidebars && isset($wp_registered_sidebars[$sidebarName])) {
|
116 |
+
$sn = $wp_registered_sidebars[$sidebarName]['name'];
|
117 |
+
}
|
118 |
+
$this->plugin->alerts->Trigger(2071, array(
|
119 |
+
'WidgetName' => $widgetName,
|
120 |
+
'OldPosition' => $i+1,
|
121 |
+
'NewPosition' => $index+1,
|
122 |
+
'Sidebar' => $sn,
|
123 |
+
));
|
124 |
+
}
|
125 |
+
}
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
}
|
130 |
+
}
|
131 |
+
//#!--
|
132 |
+
|
133 |
+
if($this->_WidgetMoveData){
|
134 |
+
$wName = $this->_WidgetMoveData['widget'];
|
135 |
+
$fromSidebar = $this->_WidgetMoveData['from'];
|
136 |
+
$toSidebar = $this->_WidgetMoveData['to'];
|
137 |
+
|
138 |
+
global $wp_registered_sidebars;
|
139 |
+
|
140 |
+
if(preg_match('/^sidebar-/', $fromSidebar))
|
141 |
+
$fromSidebar = isset($wp_registered_sidebars[$fromSidebar])
|
142 |
+
? $wp_registered_sidebars[$fromSidebar]['name']
|
143 |
+
: $fromSidebar
|
144 |
+
;
|
145 |
+
if(preg_match('/^sidebar-/', $toSidebar))
|
146 |
+
$toSidebar = isset($wp_registered_sidebars[$toSidebar])
|
147 |
+
? $wp_registered_sidebars[$toSidebar]['name']
|
148 |
+
: $toSidebar
|
149 |
+
;
|
150 |
+
|
151 |
+
$this->plugin->alerts->Trigger(2045, array(
|
152 |
+
'WidgetName' => $wName,
|
153 |
+
'OldSidebar' => $fromSidebar,
|
154 |
+
'NewSidebar' => $toSidebar,
|
155 |
+
));
|
156 |
+
}
|
157 |
+
}
|
158 |
+
|
159 |
+
public function EventWidgetActivity(){
|
160 |
+
if(!isset($_POST) || !isset($_POST['widget-id']) || empty($_POST['widget-id'])){
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
|
164 |
+
$postData = $_POST;
|
165 |
+
global $wp_registered_sidebars;
|
166 |
+
$canCheckSidebar = (empty($wp_registered_sidebars) ? false : true);
|
167 |
+
|
168 |
+
switch(true){
|
169 |
+
|
170 |
+
// added widget
|
171 |
+
case isset($postData['add_new']) && $postData['add_new'] == 'multi':
|
172 |
+
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
173 |
+
if($canCheckSidebar && preg_match('/^sidebar-/', $sidebar)){
|
174 |
+
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
175 |
+
}
|
176 |
+
$this->plugin->alerts->Trigger(2042, array(
|
177 |
+
'WidgetName' => $postData['id_base'],
|
178 |
+
'Sidebar' => $sidebar,
|
179 |
+
));
|
180 |
+
break;
|
181 |
+
|
182 |
+
// deleted widget
|
183 |
+
case isset($postData['delete_widget']) && intval($postData['delete_widget']) == 1:
|
184 |
+
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
185 |
+
if($canCheckSidebar && preg_match('/^sidebar-/',$sidebar)){
|
186 |
+
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
187 |
+
}
|
188 |
+
$this->plugin->alerts->Trigger(2044, array(
|
189 |
+
'WidgetName' => $postData['id_base'],
|
190 |
+
'Sidebar' => $sidebar,
|
191 |
+
));
|
192 |
+
break;
|
193 |
+
|
194 |
+
// modified widget
|
195 |
+
case isset($postData['id_base']) && !empty($postData['id_base']):
|
196 |
+
$wId = 0;
|
197 |
+
if(!empty($postData['multi_number'])){
|
198 |
+
$wId = intval($postData['multi_number']);
|
199 |
+
}elseif(!empty($postData['widget_number'])){
|
200 |
+
$wId = intval($postData['widget_number']);
|
201 |
+
}
|
202 |
+
if(empty($wId))return;
|
203 |
+
|
204 |
+
$wName = $postData['id_base'];
|
205 |
+
$sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
|
206 |
+
$wData = isset($postData["widget-$wName"][$wId])
|
207 |
+
? $postData["widget-$wName"][$wId]
|
208 |
+
: null;
|
209 |
+
|
210 |
+
if(empty($wData))return;
|
211 |
+
|
212 |
+
// get info from db
|
213 |
+
$wdbData = get_option("widget_".$wName);
|
214 |
+
if(empty($wdbData[$wId]))return;
|
215 |
+
|
216 |
+
// transform 'on' -> 1
|
217 |
+
foreach($wData as $k => $v)if($v == 'on')$wData[$k] = 1;
|
218 |
+
|
219 |
+
// compare - checks for any changes inside widgets
|
220 |
+
$diff = array_diff_assoc($wData, $wdbData[$wId]);
|
221 |
+
$count = count($diff);
|
222 |
+
if($count > 0){
|
223 |
+
if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
|
224 |
+
$sidebar = $wp_registered_sidebars[$sidebar]['name'];
|
225 |
+
}
|
226 |
+
$this->plugin->alerts->Trigger(2043, array(
|
227 |
+
'WidgetName' => $wName,
|
228 |
+
'Sidebar' => $sidebar,
|
229 |
+
));
|
230 |
+
}
|
231 |
+
break;
|
232 |
+
|
233 |
+
}
|
234 |
+
}
|
235 |
}
|
classes/Settings.php
CHANGED
@@ -1,639 +1,639 @@
|
|
1 |
-
<?php
|
2 |
-
class WSAL_Settings {
|
3 |
-
/**
|
4 |
-
* @var WpSecurityAuditLog
|
5 |
-
*/
|
6 |
-
protected $_plugin;
|
7 |
-
public function __construct(WpSecurityAuditLog $plugin) {
|
8 |
-
$this->_plugin = $plugin;
|
9 |
-
}
|
10 |
-
|
11 |
-
// <editor-fold desc="Developer Options">
|
12 |
-
const OPT_DEV_DATA_INSPECTOR = 'd';
|
13 |
-
const OPT_DEV_PHP_ERRORS = 'p';
|
14 |
-
const OPT_DEV_REQUEST_LOG = 'r';
|
15 |
-
const OPT_DEV_BACKTRACE_LOG = 'b';
|
16 |
-
|
17 |
-
const ERROR_CODE_INVALID_IP = 901;
|
18 |
-
|
19 |
-
protected $_devoption = null;
|
20 |
-
/**
|
21 |
-
* @return array Array of developer options to be enabled by default.
|
22 |
-
*/
|
23 |
-
public function GetDefaultDevOptions(){
|
24 |
-
return array();
|
25 |
-
}
|
26 |
-
/**
|
27 |
-
* Returns whether a developer option is enabled or not.
|
28 |
-
* @param string $option See self::OPT_DEV_* constants.
|
29 |
-
* @return boolean If option is enabled or not.
|
30 |
-
*/
|
31 |
-
public function IsDevOptionEnabled($option){
|
32 |
-
if(is_null($this->_devoption)){
|
33 |
-
$this->_devoption = $this->_plugin->GetGlobalOption(
|
34 |
-
'dev-options',
|
35 |
-
implode(',', $this->GetDefaultDevOptions())
|
36 |
-
);
|
37 |
-
$this->_devoption = explode(',', $this->_devoption);
|
38 |
-
}
|
39 |
-
return in_array($option, $this->_devoption);
|
40 |
-
}
|
41 |
-
/**
|
42 |
-
* @return boolean Whether any developer option has been enabled or not.
|
43 |
-
*/
|
44 |
-
public function IsAnyDevOptionEnabled(){
|
45 |
-
return !!$this->_plugin->GetGlobalOption('dev-options', null);
|
46 |
-
}
|
47 |
-
/**
|
48 |
-
* Sets whether a developer option is enabled or not.
|
49 |
-
* @param string $option See self::OPT_DEV_* constants.
|
50 |
-
* @param boolean $enabled If option should be enabled or not.
|
51 |
-
*/
|
52 |
-
public function SetDevOptionEnabled($option, $enabled){
|
53 |
-
// make sure options have been loaded
|
54 |
-
$this->IsDevOptionEnabled('');
|
55 |
-
// remove option if it exists
|
56 |
-
while(($p = array_search($option, $this->_devoption)) !== false)
|
57 |
-
unset($this->_devoption[$p]);
|
58 |
-
// add option if callee wants it enabled
|
59 |
-
if($enabled)
|
60 |
-
$this->_devoption[] = $option;
|
61 |
-
// commit option
|
62 |
-
$this->_plugin->SetGlobalOption(
|
63 |
-
'dev-options',
|
64 |
-
implode(',', $this->_devoption)
|
65 |
-
);
|
66 |
-
}
|
67 |
-
/**
|
68 |
-
* Remove all enabled developer options.
|
69 |
-
*/
|
70 |
-
public function ClearDevOptions(){
|
71 |
-
$this->_devoption = array();
|
72 |
-
$this->_plugin->SetGlobalOption('dev-options', '');
|
73 |
-
}
|
74 |
-
/**
|
75 |
-
* @return boolean Whether to enable data inspector or not.
|
76 |
-
*/
|
77 |
-
public function IsDataInspectorEnabled(){
|
78 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_DATA_INSPECTOR);
|
79 |
-
}
|
80 |
-
/**
|
81 |
-
* @return boolean Whether to PHP error logging or not.
|
82 |
-
*/
|
83 |
-
public function IsPhpErrorLoggingEnabled(){
|
84 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_PHP_ERRORS);
|
85 |
-
}
|
86 |
-
/**
|
87 |
-
* @return boolean Whether to log requests to file or not.
|
88 |
-
*/
|
89 |
-
public function IsRequestLoggingEnabled(){
|
90 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_REQUEST_LOG);
|
91 |
-
}
|
92 |
-
/**
|
93 |
-
* @return boolean Whether to store debug backtrace for PHP alerts or not.
|
94 |
-
*/
|
95 |
-
public function IsBacktraceLoggingEnabled(){
|
96 |
-
return $this->IsDevOptionEnabled(self::OPT_DEV_BACKTRACE_LOG);
|
97 |
-
}
|
98 |
-
|
99 |
-
// </editor-fold>
|
100 |
-
/**
|
101 |
-
* @return boolean Whether dashboard widgets are enabled or not.
|
102 |
-
*/
|
103 |
-
public function IsWidgetsEnabled(){
|
104 |
-
return !$this->_plugin->GetGlobalOption('disable-widgets');
|
105 |
-
}
|
106 |
-
/**
|
107 |
-
* @param boolean $newvalue Whether dashboard widgets are enabled or not.
|
108 |
-
*/
|
109 |
-
public function SetWidgetsEnabled($newvalue){
|
110 |
-
$this->_plugin->SetGlobalOption('disable-widgets', !$newvalue);
|
111 |
-
}
|
112 |
-
/**
|
113 |
-
* @return boolean Whether alerts in audit log view refresh automatically or not.
|
114 |
-
*/
|
115 |
-
public function IsRefreshAlertsEnabled(){
|
116 |
-
return !$this->_plugin->GetGlobalOption('disable-refresh');
|
117 |
-
}
|
118 |
-
/**
|
119 |
-
* @param boolean $newvalue Whether alerts in audit log view refresh automatically or not.
|
120 |
-
*/
|
121 |
-
public function SetRefreshAlertsEnabled($newvalue){
|
122 |
-
$this->_plugin->SetGlobalOption('disable-refresh', !$newvalue);
|
123 |
-
}
|
124 |
-
/**
|
125 |
-
* @return int Maximum number of alerts to show in dashboard widget.
|
126 |
-
*/
|
127 |
-
public function GetDashboardWidgetMaxAlerts(){
|
128 |
-
return 5;
|
129 |
-
}
|
130 |
-
|
131 |
-
// <editor-fold desc="Pruning Settings">
|
132 |
-
/**
|
133 |
-
* @return int The maximum number of alerts allowable.
|
134 |
-
*/
|
135 |
-
public function GetMaxAllowedAlerts(){
|
136 |
-
return 5000;
|
137 |
-
}
|
138 |
-
/**
|
139 |
-
* @return string The default pruning date.
|
140 |
-
*/
|
141 |
-
public function GetDefaultPruningDate(){
|
142 |
-
return '1 month';
|
143 |
-
}
|
144 |
-
protected $_pruning = 0;
|
145 |
-
/**
|
146 |
-
* @return string The current pruning date.
|
147 |
-
*/
|
148 |
-
public function GetPruningDate(){
|
149 |
-
if(!$this->_pruning){
|
150 |
-
$this->_pruning = $this->_plugin->GetGlobalOption('pruning-date');
|
151 |
-
if(!strtotime($this->_pruning))
|
152 |
-
$this->_pruning = $this->GetDefaultPruningDate();
|
153 |
-
}
|
154 |
-
return $this->_pruning;
|
155 |
-
}
|
156 |
-
/**
|
157 |
-
* @param string $newvalue The new pruning date.
|
158 |
-
*/
|
159 |
-
public function SetPruningDate($newvalue){
|
160 |
-
if(strtotime($newvalue)){
|
161 |
-
$this->_plugin->SetGlobalOption('pruning-date', $newvalue);
|
162 |
-
$this->_pruning = $newvalue;
|
163 |
-
}
|
164 |
-
}
|
165 |
-
/**
|
166 |
-
* @return integer Maximum number of alerts to keep.
|
167 |
-
*/
|
168 |
-
public function GetPruningLimit(){
|
169 |
-
$val = (int)$this->_plugin->GetGlobalOption('pruning-limit');
|
170 |
-
return $val ? $val : $this->GetMaxAllowedAlerts();
|
171 |
-
}
|
172 |
-
/**
|
173 |
-
* @param integer $newvalue The new maximum number of alerts.
|
174 |
-
*/
|
175 |
-
public function SetPruningLimit($newvalue){
|
176 |
-
$newvalue = max(/*min(*/(int)$newvalue/*, $this->GetMaxAllowedAlerts())*/, 1);
|
177 |
-
$this->_plugin->SetGlobalOption('pruning-limit', $newvalue);
|
178 |
-
}
|
179 |
-
public function SetPruningDateEnabled($enabled){
|
180 |
-
$this->_plugin->SetGlobalOption('pruning-date-e', $enabled);
|
181 |
-
}
|
182 |
-
public function SetPruningLimitEnabled($enabled){
|
183 |
-
$this->_plugin->SetGlobalOption('pruning-limit-e', $enabled);
|
184 |
-
}
|
185 |
-
public function IsPruningDateEnabled(){
|
186 |
-
return $this->_plugin->GetGlobalOption('pruning-date-e');
|
187 |
-
}
|
188 |
-
public function IsPruningLimitEnabled(){
|
189 |
-
return $this->_plugin->GetGlobalOption('pruning-limit-e');
|
190 |
-
}
|
191 |
-
public function IsRestrictAdmins(){
|
192 |
-
return $this->_plugin->GetGlobalOption('restrict-admins', false);
|
193 |
-
}
|
194 |
-
/**
|
195 |
-
* @deprecated Sandbox functionality is now in an external plugin.
|
196 |
-
*/
|
197 |
-
public function IsSandboxPageEnabled(){
|
198 |
-
$plugins = $this->_plugin->licensing->plugins();
|
199 |
-
return isset($plugins['wsal-sandbox-extensionphp']);
|
200 |
-
}
|
201 |
-
public function SetRestrictAdmins($enable){
|
202 |
-
$this->_plugin->SetGlobalOption('restrict-admins', (bool)$enable);
|
203 |
-
}
|
204 |
-
|
205 |
-
// </editor-fold>
|
206 |
-
protected $_disabled = null;
|
207 |
-
public function GetDefaultDisabledAlerts(){
|
208 |
-
return array(0000, 0001, 0002, 0003, 0004, 0005);
|
209 |
-
}
|
210 |
-
/**
|
211 |
-
* @return array IDs of disabled alerts.
|
212 |
-
*/
|
213 |
-
public function GetDisabledAlerts(){
|
214 |
-
if(!$this->_disabled){
|
215 |
-
$this->_disabled = implode(',', $this->GetDefaultDisabledAlerts());
|
216 |
-
$this->_disabled = $this->_plugin->GetGlobalOption('disabled-alerts', $this->_disabled);
|
217 |
-
$this->_disabled = ($this->_disabled == '') ? array() : explode(',', $this->_disabled);
|
218 |
-
$this->_disabled = array_map('intval', $this->_disabled);
|
219 |
-
}
|
220 |
-
return $this->_disabled;
|
221 |
-
}
|
222 |
-
/**
|
223 |
-
* @param array $types IDs alerts to disable.
|
224 |
-
*/
|
225 |
-
public function SetDisabledAlerts($types){
|
226 |
-
$this->_disabled = array_unique(array_map('intval', $types));
|
227 |
-
$this->_plugin->SetGlobalOption('disabled-alerts', implode(',', $this->_disabled));
|
228 |
-
}
|
229 |
-
public function IsIncognito(){
|
230 |
-
return $this->_plugin->GetGlobalOption('hide-plugin');
|
231 |
-
}
|
232 |
-
public function SetIncognito($enabled){
|
233 |
-
return $this->_plugin->SetGlobalOption('hide-plugin', $enabled);
|
234 |
-
}
|
235 |
-
|
236 |
-
/**
|
237 |
-
* Checking if the data will be removed.
|
238 |
-
*/
|
239 |
-
public function IsDeleteData(){
|
240 |
-
return $this->_plugin->GetGlobalOption('delete-data');
|
241 |
-
}
|
242 |
-
|
243 |
-
public function SetDeleteData($enabled){
|
244 |
-
return $this->_plugin->SetGlobalOption('delete-data', $enabled);
|
245 |
-
}
|
246 |
-
|
247 |
-
// <editor-fold desc="Access Control">
|
248 |
-
|
249 |
-
protected $_viewers = null;
|
250 |
-
public function SetAllowedPluginViewers($usersOrRoles){
|
251 |
-
$this->_viewers = $usersOrRoles;
|
252 |
-
$this->_plugin->SetGlobalOption('plugin-viewers', implode(',', $this->_viewers));
|
253 |
-
}
|
254 |
-
public function GetAllowedPluginViewers(){
|
255 |
-
if(is_null($this->_viewers)){
|
256 |
-
$this->_viewers = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-viewers'))));
|
257 |
-
}
|
258 |
-
return $this->_viewers;
|
259 |
-
}
|
260 |
-
protected $_editors = null;
|
261 |
-
public function SetAllowedPluginEditors($usersOrRoles){
|
262 |
-
$this->_editors = $usersOrRoles;
|
263 |
-
$this->_plugin->SetGlobalOption('plugin-editors', implode(',', $this->_editors));
|
264 |
-
}
|
265 |
-
public function GetAllowedPluginEditors(){
|
266 |
-
if(is_null($this->_editors)){
|
267 |
-
$this->_editors = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-editors'))));
|
268 |
-
}
|
269 |
-
return $this->_editors;
|
270 |
-
}
|
271 |
-
protected $_perpage = null;
|
272 |
-
public function SetViewPerPage($newvalue){
|
273 |
-
$this->_perpage = max($newvalue, 1);
|
274 |
-
$this->_plugin->SetGlobalOption('items-per-page', $this->_perpage);
|
275 |
-
}
|
276 |
-
public function GetViewPerPage(){
|
277 |
-
if(is_null($this->_perpage)){
|
278 |
-
$this->_perpage = (int)$this->_plugin->GetGlobalOption('items-per-page', 10);
|
279 |
-
}
|
280 |
-
return $this->_perpage;
|
281 |
-
}
|
282 |
-
/**
|
283 |
-
* @param string $action Type of action, either 'view' or 'edit'.
|
284 |
-
* @return boolean If user has access or not.
|
285 |
-
*/
|
286 |
-
public function CurrentUserCan($action){
|
287 |
-
return $this->UserCan(wp_get_current_user(), $action);
|
288 |
-
}
|
289 |
-
/**
|
290 |
-
* @return string[] List of superadmin usernames.
|
291 |
-
*/
|
292 |
-
protected function GetSuperAdmins(){
|
293 |
-
return $this->_plugin->IsMultisite() ? get_super_admins() : array();
|
294 |
-
}
|
295 |
-
/**
|
296 |
-
* @return string[] List of admin usernames.
|
297 |
-
*/
|
298 |
-
protected function GetAdmins(){
|
299 |
-
if($this->_plugin->IsMultisite()){
|
300 |
-
// see: https://gist.github.com/1508426/65785a15b8638d43a9905effb59e4d97319ef8f8
|
301 |
-
global $wpdb;
|
302 |
-
$cap = $wpdb->prefix."capabilities";
|
303 |
-
$sql = "SELECT DISTINCT $wpdb->users.user_login"
|
304 |
-
. " FROM $wpdb->users"
|
305 |
-
. " INNER JOIN $wpdb->usermeta ON ($wpdb->users.ID = $wpdb->usermeta.user_id )"
|
306 |
-
. " WHERE $wpdb->usermeta.meta_key = '$cap'"
|
307 |
-
. " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
|
308 |
-
return $wpdb->get_col($sql);
|
309 |
-
}else{
|
310 |
-
$result = array();
|
311 |
-
$query = 'role=administrator&fields[]=user_login';
|
312 |
-
foreach (get_users($query) as $user) $result[] = $user->user_login;
|
313 |
-
return $result;
|
314 |
-
}
|
315 |
-
}
|
316 |
-
/**
|
317 |
-
* Returns access tokens for a particular action.
|
318 |
-
* @param string $action Type of action.
|
319 |
-
* @return string[] List of tokens (usernames, roles etc).
|
320 |
-
*/
|
321 |
-
public function GetAccessTokens($action){
|
322 |
-
$allowed = array();
|
323 |
-
switch($action){
|
324 |
-
case 'view':
|
325 |
-
$allowed = $this->GetAllowedPluginViewers();
|
326 |
-
$allowed = array_merge($allowed, $this->GetAllowedPluginEditors());
|
327 |
-
if (!$this->IsRestrictAdmins()) {
|
328 |
-
$allowed = array_merge($allowed, $this->GetSuperAdmins());
|
329 |
-
$allowed = array_merge($allowed, $this->GetAdmins());
|
330 |
-
}
|
331 |
-
break;
|
332 |
-
case 'edit':
|
333 |
-
$allowed = $this->GetAllowedPluginEditors();
|
334 |
-
if (!$this->IsRestrictAdmins()) {
|
335 |
-
$allowed = array_merge($allowed, $this->_plugin->IsMultisite() ?
|
336 |
-
$this->GetSuperAdmins() : $this->GetAdmins()
|
337 |
-
);
|
338 |
-
}
|
339 |
-
break;
|
340 |
-
default:
|
341 |
-
throw new Exception('Unknown action "'.$action.'".');
|
342 |
-
}
|
343 |
-
if (!$this->IsRestrictAdmins()) {
|
344 |
-
if(is_multisite()){
|
345 |
-
$allowed = array_merge($allowed, get_super_admins());
|
346 |
-
}else{
|
347 |
-
$allowed[] = 'administrator';
|
348 |
-
}
|
349 |
-
}
|
350 |
-
return array_unique($allowed);
|
351 |
-
}
|
352 |
-
/**
|
353 |
-
* @param integer|WP_user $user User object to check.
|
354 |
-
* @param string $action Type of action, either 'view' or 'edit'.
|
355 |
-
* @return boolean If user has access or not.
|
356 |
-
*/
|
357 |
-
public function UserCan($user, $action){
|
358 |
-
if(is_int($user))$user = get_userdata($user);
|
359 |
-
$allowed = $this->GetAccessTokens($action);
|
360 |
-
$check = array_merge(
|
361 |
-
$user->roles,
|
362 |
-
array($user->user_login)
|
363 |
-
);
|
364 |
-
foreach($check as $item){
|
365 |
-
if(in_array($item, $allowed)){
|
366 |
-
return true;
|
367 |
-
}
|
368 |
-
}
|
369 |
-
return false;
|
370 |
-
}
|
371 |
-
public function GetCurrentUserRoles($baseRoles = null){
|
372 |
-
if ($baseRoles == null) $baseRoles = wp_get_current_user()->roles;
|
373 |
-
if (function_exists('is_super_admin') && is_super_admin()) $baseRoles[] = 'superadmin';
|
374 |
-
return $baseRoles;
|
375 |
-
}
|
376 |
-
|
377 |
-
public function IsLoginSuperAdmin($username){
|
378 |
-
$userId = username_exists($username);
|
379 |
-
if ( function_exists('is_super_admin') && is_super_admin($userId) ) return true;
|
380 |
-
else return false;
|
381 |
-
}
|
382 |
-
|
383 |
-
// </editor-fold>
|
384 |
-
|
385 |
-
// <editor-fold desc="Licensing">
|
386 |
-
public function GetLicenses(){
|
387 |
-
return $this->_plugin->GetGlobalOption('licenses');
|
388 |
-
}
|
389 |
-
public function GetLicense($name){
|
390 |
-
$data = $this->GetLicenses();
|
391 |
-
$name = sanitize_key(basename($name));
|
392 |
-
return isset($data[$name]) ? $data[$name] : array();
|
393 |
-
}
|
394 |
-
public function SetLicenses($data){
|
395 |
-
$this->_plugin->SetGlobalOption('licenses', $data);
|
396 |
-
}
|
397 |
-
public function GetLicenseKey($name){
|
398 |
-
$data = $this->GetLicense($name);
|
399 |
-
return isset($data['key']) ? $data['key'] : '';
|
400 |
-
}
|
401 |
-
public function GetLicenseStatus($name){
|
402 |
-
$data = $this->GetLicense($name);
|
403 |
-
return isset($data['sts']) ? $data['sts'] : '';
|
404 |
-
}
|
405 |
-
public function GetLicenseErrors($name){
|
406 |
-
$data = $this->GetLicense($name);
|
407 |
-
return isset($data['err']) ? $data['err'] : '';
|
408 |
-
}
|
409 |
-
public function SetLicenseKey($name, $key){
|
410 |
-
$data = $this->GetLicenses();
|
411 |
-
if (!isset($data[$name])) $data[$name] = array();
|
412 |
-
$data[$name]['key'] = $key;
|
413 |
-
$this->SetLicenses($data);
|
414 |
-
}
|
415 |
-
public function SetLicenseStatus($name, $status){
|
416 |
-
$data = $this->GetLicenses();
|
417 |
-
if (!isset($data[$name])) $data[$name] = array();
|
418 |
-
$data[$name]['sts'] = $status;
|
419 |
-
$this->SetLicenses($data);
|
420 |
-
}
|
421 |
-
public function SetLicenseErrors($name, $errors){
|
422 |
-
$data = $this->GetLicenses();
|
423 |
-
if (!isset($data[$name])) $data[$name] = array();
|
424 |
-
$data[$name]['err'] = $errors;
|
425 |
-
$this->SetLicenses($data);
|
426 |
-
}
|
427 |
-
public function ClearLicenses(){
|
428 |
-
$this->SetLicenses(array());
|
429 |
-
}
|
430 |
-
|
431 |
-
// </editor-fold>
|
432 |
-
|
433 |
-
// <editor-fold desc="Client IP Retrieval">
|
434 |
-
|
435 |
-
public function IsMainIPFromProxy(){
|
436 |
-
return $this->_plugin->GetGlobalOption('use-proxy-ip');
|
437 |
-
}
|
438 |
-
public function SetMainIPFromProxy($enabled){
|
439 |
-
return $this->_plugin->SetGlobalOption('use-proxy-ip', $enabled);
|
440 |
-
}
|
441 |
-
|
442 |
-
public function IsInternalIPsFiltered(){
|
443 |
-
return $this->_plugin->GetGlobalOption('filter-internal-ip');
|
444 |
-
}
|
445 |
-
public function SetInternalIPsFiltering($enabled){
|
446 |
-
return $this->_plugin->SetGlobalOption('filter-internal-ip', $enabled);
|
447 |
-
}
|
448 |
-
|
449 |
-
public function GetMainClientIP(){
|
450 |
-
$result = null;
|
451 |
-
if ($this->IsMainIPFromProxy()) {
|
452 |
-
// TODO the algorithm below just gets the first IP in the list...we might want to make this more intelligent somehow
|
453 |
-
$result = $this->GetClientIPs();
|
454 |
-
$result = reset($result);
|
455 |
-
$result = isset($result[0]) ? $result[0] : null;
|
456 |
-
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
457 |
-
$result = $this->NormalizeIP($_SERVER['REMOTE_ADDR']);
|
458 |
-
if (!$this->ValidateIP($result)) {
|
459 |
-
$result = "Error " . self::ERROR_CODE_INVALID_IP . ": Invalid IP Address";
|
460 |
-
}
|
461 |
-
}
|
462 |
-
return $result;
|
463 |
-
}
|
464 |
-
|
465 |
-
public function GetClientIPs(){
|
466 |
-
$ips = array();
|
467 |
-
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) {
|
468 |
-
if (isset($_SERVER[$key])) {
|
469 |
-
$ips[$key] = array();
|
470 |
-
foreach (explode(',', $_SERVER[$key]) as $ip)
|
471 |
-
if ($this->ValidateIP($ip = $this->NormalizeIP($ip)))
|
472 |
-
$ips[$key][] = $ip;
|
473 |
-
}
|
474 |
-
}
|
475 |
-
return $ips;
|
476 |
-
}
|
477 |
-
|
478 |
-
protected function NormalizeIP($ip){
|
479 |
-
$ip = trim($ip);
|
480 |
-
if(strpos($ip, ':') !== false && substr_count($ip, '.') == 3 && strpos($ip, '[') === false){
|
481 |
-
// IPv4 with a port (eg: 11.22.33.44:80)
|
482 |
-
$ip = explode(':', $ip);
|
483 |
-
$ip = $ip[0];
|
484 |
-
}else{
|
485 |
-
// IPv6 with a port (eg: [::1]:80)
|
486 |
-
$ip = explode(']', $ip);
|
487 |
-
$ip = ltrim($ip[0], '[');
|
488 |
-
}
|
489 |
-
return $ip;
|
490 |
-
}
|
491 |
-
|
492 |
-
protected function ValidateIP($ip){
|
493 |
-
$opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
|
494 |
-
if ($this->IsInternalIPsFiltered()) $opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
495 |
-
$filteredIP = filter_var($ip, FILTER_VALIDATE_IP, $opts);
|
496 |
-
if (!$filteredIP || empty($filteredIP)) {
|
497 |
-
//Regex IPV4
|
498 |
-
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)) return $ip;
|
499 |
-
//Regex IPV6
|
500 |
-
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)) return $ip;
|
501 |
-
|
502 |
-
error_log("Invalid IP in ValidateIP function: ".$ip);
|
503 |
-
return false;
|
504 |
-
} else {
|
505 |
-
return $filteredIP;
|
506 |
-
}
|
507 |
-
}
|
508 |
-
|
509 |
-
/**
|
510 |
-
* Users excluded from monitoring
|
511 |
-
*/
|
512 |
-
protected $_excluded_users = array();
|
513 |
-
public function SetExcludedMonitoringUsers($users)
|
514 |
-
{
|
515 |
-
$this->_excluded_users = $users;
|
516 |
-
$this->_plugin->SetGlobalOption('excluded-users', implode(',', $this->_excluded_users));
|
517 |
-
}
|
518 |
-
public function GetExcludedMonitoringUsers()
|
519 |
-
{
|
520 |
-
if(empty($this->_excluded_users)){
|
521 |
-
$this->_excluded_users = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-users'))));
|
522 |
-
}
|
523 |
-
return $this->_excluded_users;
|
524 |
-
}
|
525 |
-
|
526 |
-
/**
|
527 |
-
* Roles excluded from monitoring
|
528 |
-
*/
|
529 |
-
protected $_excluded_roles = array();
|
530 |
-
public function SetExcludedMonitoringRoles($roles){
|
531 |
-
$this->_excluded_roles = $roles;
|
532 |
-
$this->_plugin->SetGlobalOption('excluded-roles', implode(',', $this->_excluded_roles));
|
533 |
-
}
|
534 |
-
public function GetExcludedMonitoringRoles(){
|
535 |
-
if(empty($this->_excluded_roles)){
|
536 |
-
$this->_excluded_roles = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-roles'))));
|
537 |
-
}
|
538 |
-
return $this->_excluded_roles;
|
539 |
-
}
|
540 |
-
|
541 |
-
/**
|
542 |
-
* Custom fields excluded from monitoring
|
543 |
-
*/
|
544 |
-
protected $_excluded_custom = array();
|
545 |
-
public function SetExcludedMonitoringCustom($custom){
|
546 |
-
$this->_excluded_custom = $custom;
|
547 |
-
$this->_plugin->SetGlobalOption('excluded-custom', implode(',', $this->_excluded_custom));
|
548 |
-
}
|
549 |
-
public function GetExcludedMonitoringCustom(){
|
550 |
-
if(empty($this->_excluded_custom)){
|
551 |
-
$this->_excluded_custom = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-custom'))));
|
552 |
-
asort($this->_excluded_custom);
|
553 |
-
}
|
554 |
-
return $this->_excluded_custom;
|
555 |
-
}
|
556 |
-
|
557 |
-
/**
|
558 |
-
* IP excluded from monitoring
|
559 |
-
*/
|
560 |
-
protected $_excluded_ip = array();
|
561 |
-
public function SetExcludedMonitoringIP($ip){
|
562 |
-
$this->_excluded_ip = $ip;
|
563 |
-
$this->_plugin->SetGlobalOption('excluded-ip', implode(',', $this->_excluded_ip));
|
564 |
-
}
|
565 |
-
public function GetExcludedMonitoringIP(){
|
566 |
-
if(empty($this->_excluded_ip)){
|
567 |
-
$this->_excluded_ip = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-ip'))));
|
568 |
-
}
|
569 |
-
return $this->_excluded_ip;
|
570 |
-
}
|
571 |
-
|
572 |
-
/**
|
573 |
-
* Datetime format.
|
574 |
-
* 24 hours or AM/PM
|
575 |
-
*/
|
576 |
-
public function GetDatetimeFormat(){
|
577 |
-
return $this->_plugin->GetGlobalOption('datetime-format', 0);
|
578 |
-
}
|
579 |
-
|
580 |
-
public function SetDatetimeFormat($newvalue){
|
581 |
-
return $this->_plugin->SetGlobalOption('datetime-format', $newvalue);
|
582 |
-
}
|
583 |
-
|
584 |
-
/**
|
585 |
-
* Alerts Timestamp
|
586 |
-
* Server's timezone or WordPress' timezone
|
587 |
-
*/
|
588 |
-
public function GetTimezone(){
|
589 |
-
return $this->_plugin->GetGlobalOption('timezone', 0);
|
590 |
-
}
|
591 |
-
|
592 |
-
public function SetTimezone($newvalue){
|
593 |
-
return $this->_plugin->SetGlobalOption('timezone', $newvalue);
|
594 |
-
}
|
595 |
-
|
596 |
-
public function GetAdapterConfig($name_field){
|
597 |
-
return $this->_plugin->GetGlobalOption($name_field);
|
598 |
-
}
|
599 |
-
|
600 |
-
public function SetAdapterConfig($name_field, $newvalue){
|
601 |
-
return $this->_plugin->SetGlobalOption($name_field, trim($newvalue));
|
602 |
-
}
|
603 |
-
|
604 |
-
public function GetColumns(){
|
605 |
-
$columns = array('alert_code' => '1', 'type' => '1', 'date' => '1', 'username' => '1', 'source_ip' => '1', 'message' => '1');
|
606 |
-
if ($this->_plugin->IsMultisite()) {
|
607 |
-
$columns = array_slice($columns, 0, 5, true) + array('site' => '1') + array_slice($columns, 5, null, true);
|
608 |
-
}
|
609 |
-
$selected = $this->GetColumnsSelected();
|
610 |
-
if (!empty($selected)) {
|
611 |
-
$columns = array('alert_code' => '0', 'type' => '0', 'date' => '0', 'username' => '0', 'source_ip' => '0', 'message' => '0');
|
612 |
-
if ($this->_plugin->IsMultisite()) {
|
613 |
-
$columns = array_slice($columns, 0, 5, true) + array('site' => '0') + array_slice($columns, 5, null, true);
|
614 |
-
}
|
615 |
-
$selected = (array)json_decode($selected);
|
616 |
-
$columns = array_merge($columns, $selected);
|
617 |
-
return $columns;
|
618 |
-
} else {
|
619 |
-
return $columns;
|
620 |
-
}
|
621 |
-
}
|
622 |
-
|
623 |
-
public function GetColumnsSelected(){
|
624 |
-
return $this->_plugin->GetGlobalOption('columns');
|
625 |
-
}
|
626 |
-
|
627 |
-
public function SetColumns($columns){
|
628 |
-
return $this->_plugin->SetGlobalOption('columns', json_encode($columns));
|
629 |
-
}
|
630 |
-
|
631 |
-
public function IsWPBackend(){
|
632 |
-
return $this->_plugin->GetGlobalOption('wp-backend');
|
633 |
-
}
|
634 |
-
|
635 |
-
public function SetWPBackend($enabled){
|
636 |
-
return $this->_plugin->SetGlobalOption('wp-backend', $enabled);
|
637 |
-
}
|
638 |
-
// </editor-fold>
|
639 |
-
}
|
1 |
+
<?php
|
2 |
+
class WSAL_Settings {
|
3 |
+
/**
|
4 |
+
* @var WpSecurityAuditLog
|
5 |
+
*/
|
6 |
+
protected $_plugin;
|
7 |
+
public function __construct(WpSecurityAuditLog $plugin) {
|
8 |
+
$this->_plugin = $plugin;
|
9 |
+
}
|
10 |
+
|
11 |
+
// <editor-fold desc="Developer Options">
|
12 |
+
const OPT_DEV_DATA_INSPECTOR = 'd';
|
13 |
+
const OPT_DEV_PHP_ERRORS = 'p';
|
14 |
+
const OPT_DEV_REQUEST_LOG = 'r';
|
15 |
+
const OPT_DEV_BACKTRACE_LOG = 'b';
|
16 |
+
|
17 |
+
const ERROR_CODE_INVALID_IP = 901;
|
18 |
+
|
19 |
+
protected $_devoption = null;
|
20 |
+
/**
|
21 |
+
* @return array Array of developer options to be enabled by default.
|
22 |
+
*/
|
23 |
+
public function GetDefaultDevOptions(){
|
24 |
+
return array();
|
25 |
+
}
|
26 |
+
/**
|
27 |
+
* Returns whether a developer option is enabled or not.
|
28 |
+
* @param string $option See self::OPT_DEV_* constants.
|
29 |
+
* @return boolean If option is enabled or not.
|
30 |
+
*/
|
31 |
+
public function IsDevOptionEnabled($option){
|
32 |
+
if(is_null($this->_devoption)){
|
33 |
+
$this->_devoption = $this->_plugin->GetGlobalOption(
|
34 |
+
'dev-options',
|
35 |
+
implode(',', $this->GetDefaultDevOptions())
|
36 |
+
);
|
37 |
+
$this->_devoption = explode(',', $this->_devoption);
|
38 |
+
}
|
39 |
+
return in_array($option, $this->_devoption);
|
40 |
+
}
|
41 |
+
/**
|
42 |
+
* @return boolean Whether any developer option has been enabled or not.
|
43 |
+
*/
|
44 |
+
public function IsAnyDevOptionEnabled(){
|
45 |
+
return !!$this->_plugin->GetGlobalOption('dev-options', null);
|
46 |
+
}
|
47 |
+
/**
|
48 |
+
* Sets whether a developer option is enabled or not.
|
49 |
+
* @param string $option See self::OPT_DEV_* constants.
|
50 |
+
* @param boolean $enabled If option should be enabled or not.
|
51 |
+
*/
|
52 |
+
public function SetDevOptionEnabled($option, $enabled){
|
53 |
+
// make sure options have been loaded
|
54 |
+
$this->IsDevOptionEnabled('');
|
55 |
+
// remove option if it exists
|
56 |
+
while(($p = array_search($option, $this->_devoption)) !== false)
|
57 |
+
unset($this->_devoption[$p]);
|
58 |
+
// add option if callee wants it enabled
|
59 |
+
if($enabled)
|
60 |
+
$this->_devoption[] = $option;
|
61 |
+
// commit option
|
62 |
+
$this->_plugin->SetGlobalOption(
|
63 |
+
'dev-options',
|
64 |
+
implode(',', $this->_devoption)
|
65 |
+
);
|
66 |
+
}
|
67 |
+
/**
|
68 |
+
* Remove all enabled developer options.
|
69 |
+
*/
|
70 |
+
public function ClearDevOptions(){
|
71 |
+
$this->_devoption = array();
|
72 |
+
$this->_plugin->SetGlobalOption('dev-options', '');
|
73 |
+
}
|
74 |
+
/**
|
75 |
+
* @return boolean Whether to enable data inspector or not.
|
76 |
+
*/
|
77 |
+
public function IsDataInspectorEnabled(){
|
78 |
+
return $this->IsDevOptionEnabled(self::OPT_DEV_DATA_INSPECTOR);
|
79 |
+
}
|
80 |
+
/**
|
81 |
+
* @return boolean Whether to PHP error logging or not.
|
82 |
+
*/
|
83 |
+
public function IsPhpErrorLoggingEnabled(){
|
84 |
+
return $this->IsDevOptionEnabled(self::OPT_DEV_PHP_ERRORS);
|
85 |
+
}
|
86 |
+
/**
|
87 |
+
* @return boolean Whether to log requests to file or not.
|
88 |
+
*/
|
89 |
+
public function IsRequestLoggingEnabled(){
|
90 |
+
return $this->IsDevOptionEnabled(self::OPT_DEV_REQUEST_LOG);
|
91 |
+
}
|
92 |
+
/**
|
93 |
+
* @return boolean Whether to store debug backtrace for PHP alerts or not.
|
94 |
+
*/
|
95 |
+
public function IsBacktraceLoggingEnabled(){
|
96 |
+
return $this->IsDevOptionEnabled(self::OPT_DEV_BACKTRACE_LOG);
|
97 |
+
}
|
98 |
+
|
99 |
+
// </editor-fold>
|
100 |
+
/**
|
101 |
+
* @return boolean Whether dashboard widgets are enabled or not.
|
102 |
+
*/
|
103 |
+
public function IsWidgetsEnabled(){
|
104 |
+
return !$this->_plugin->GetGlobalOption('disable-widgets');
|
105 |
+
}
|
106 |
+
/**
|
107 |
+
* @param boolean $newvalue Whether dashboard widgets are enabled or not.
|
108 |
+
*/
|
109 |
+
public function SetWidgetsEnabled($newvalue){
|
110 |
+
$this->_plugin->SetGlobalOption('disable-widgets', !$newvalue);
|
111 |
+
}
|
112 |
+
/**
|
113 |
+
* @return boolean Whether alerts in audit log view refresh automatically or not.
|
114 |
+
*/
|
115 |
+
public function IsRefreshAlertsEnabled(){
|
116 |
+
return !$this->_plugin->GetGlobalOption('disable-refresh');
|
117 |
+
}
|
118 |
+
/**
|
119 |
+
* @param boolean $newvalue Whether alerts in audit log view refresh automatically or not.
|
120 |
+
*/
|
121 |
+
public function SetRefreshAlertsEnabled($newvalue){
|
122 |
+
$this->_plugin->SetGlobalOption('disable-refresh', !$newvalue);
|
123 |
+
}
|
124 |
+
/**
|
125 |
+
* @return int Maximum number of alerts to show in dashboard widget.
|
126 |
+
*/
|
127 |
+
public function GetDashboardWidgetMaxAlerts(){
|
128 |
+
return 5;
|
129 |
+
}
|
130 |
+
|
131 |
+
// <editor-fold desc="Pruning Settings">
|
132 |
+
/**
|
133 |
+
* @return int The maximum number of alerts allowable.
|
134 |
+
*/
|
135 |
+
public function GetMaxAllowedAlerts(){
|
136 |
+
return 5000;
|
137 |
+
}
|
138 |
+
/**
|
139 |
+
* @return string The default pruning date.
|
140 |
+
*/
|
141 |
+
public function GetDefaultPruningDate(){
|
142 |
+
return '1 month';
|
143 |
+
}
|
144 |
+
protected $_pruning = 0;
|
145 |
+
/**
|
146 |
+
* @return string The current pruning date.
|
147 |
+
*/
|
148 |
+
public function GetPruningDate(){
|
149 |
+
if(!$this->_pruning){
|
150 |
+
$this->_pruning = $this->_plugin->GetGlobalOption('pruning-date');
|
151 |
+
if(!strtotime($this->_pruning))
|
152 |
+
$this->_pruning = $this->GetDefaultPruningDate();
|
153 |
+
}
|
154 |
+
return $this->_pruning;
|
155 |
+
}
|
156 |
+
/**
|
157 |
+
* @param string $newvalue The new pruning date.
|
158 |
+
*/
|
159 |
+
public function SetPruningDate($newvalue){
|
160 |
+
if(strtotime($newvalue)){
|
161 |
+
$this->_plugin->SetGlobalOption('pruning-date', $newvalue);
|
162 |
+
$this->_pruning = $newvalue;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
/**
|
166 |
+
* @return integer Maximum number of alerts to keep.
|
167 |
+
*/
|
168 |
+
public function GetPruningLimit(){
|
169 |
+
$val = (int)$this->_plugin->GetGlobalOption('pruning-limit');
|
170 |
+
return $val ? $val : $this->GetMaxAllowedAlerts();
|
171 |
+
}
|
172 |
+
/**
|
173 |
+
* @param integer $newvalue The new maximum number of alerts.
|
174 |
+
*/
|
175 |
+
public function SetPruningLimit($newvalue){
|
176 |
+
$newvalue = max(/*min(*/(int)$newvalue/*, $this->GetMaxAllowedAlerts())*/, 1);
|
177 |
+
$this->_plugin->SetGlobalOption('pruning-limit', $newvalue);
|
178 |
+
}
|
179 |
+
public function SetPruningDateEnabled($enabled){
|
180 |
+
$this->_plugin->SetGlobalOption('pruning-date-e', $enabled);
|
181 |
+
}
|
182 |
+
public function SetPruningLimitEnabled($enabled){
|
183 |
+
$this->_plugin->SetGlobalOption('pruning-limit-e', $enabled);
|
184 |
+
}
|
185 |
+
public function IsPruningDateEnabled(){
|
186 |
+
return $this->_plugin->GetGlobalOption('pruning-date-e');
|
187 |
+
}
|
188 |
+
public function IsPruningLimitEnabled(){
|
189 |
+
return $this->_plugin->GetGlobalOption('pruning-limit-e');
|
190 |
+
}
|
191 |
+
public function IsRestrictAdmins(){
|
192 |
+
return $this->_plugin->GetGlobalOption('restrict-admins', false);
|
193 |
+
}
|
194 |
+
/**
|
195 |
+
* @deprecated Sandbox functionality is now in an external plugin.
|
196 |
+
*/
|
197 |
+
public function IsSandboxPageEnabled(){
|
198 |
+
$plugins = $this->_plugin->licensing->plugins();
|
199 |
+
return isset($plugins['wsal-sandbox-extensionphp']);
|
200 |
+
}
|
201 |
+
public function SetRestrictAdmins($enable){
|
202 |
+
$this->_plugin->SetGlobalOption('restrict-admins', (bool)$enable);
|
203 |
+
}
|
204 |
+
|
205 |
+
// </editor-fold>
|
206 |
+
protected $_disabled = null;
|
207 |
+
public function GetDefaultDisabledAlerts(){
|
208 |
+
return array(0000, 0001, 0002, 0003, 0004, 0005);
|
209 |
+
}
|
210 |
+
/**
|
211 |
+
* @return array IDs of disabled alerts.
|
212 |
+
*/
|
213 |
+
public function GetDisabledAlerts(){
|
214 |
+
if(!$this->_disabled){
|
215 |
+
$this->_disabled = implode(',', $this->GetDefaultDisabledAlerts());
|
216 |
+
$this->_disabled = $this->_plugin->GetGlobalOption('disabled-alerts', $this->_disabled);
|
217 |
+
$this->_disabled = ($this->_disabled == '') ? array() : explode(',', $this->_disabled);
|
218 |
+
$this->_disabled = array_map('intval', $this->_disabled);
|
219 |
+
}
|
220 |
+
return $this->_disabled;
|
221 |
+
}
|
222 |
+
/**
|
223 |
+
* @param array $types IDs alerts to disable.
|
224 |
+
*/
|
225 |
+
public function SetDisabledAlerts($types){
|
226 |
+
$this->_disabled = array_unique(array_map('intval', $types));
|
227 |
+
$this->_plugin->SetGlobalOption('disabled-alerts', implode(',', $this->_disabled));
|
228 |
+
}
|
229 |
+
public function IsIncognito(){
|
230 |
+
return $this->_plugin->GetGlobalOption('hide-plugin');
|
231 |
+
}
|
232 |
+
public function SetIncognito($enabled){
|
233 |
+
return $this->_plugin->SetGlobalOption('hide-plugin', $enabled);
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Checking if the data will be removed.
|
238 |
+
*/
|
239 |
+
public function IsDeleteData(){
|
240 |
+
return $this->_plugin->GetGlobalOption('delete-data');
|
241 |
+
}
|
242 |
+
|
243 |
+
public function SetDeleteData($enabled){
|
244 |
+
return $this->_plugin->SetGlobalOption('delete-data', $enabled);
|
245 |
+
}
|
246 |
+
|
247 |
+
// <editor-fold desc="Access Control">
|
248 |
+
|
249 |
+
protected $_viewers = null;
|
250 |
+
public function SetAllowedPluginViewers($usersOrRoles){
|
251 |
+
$this->_viewers = $usersOrRoles;
|
252 |
+
$this->_plugin->SetGlobalOption('plugin-viewers', implode(',', $this->_viewers));
|
253 |
+
}
|
254 |
+
public function GetAllowedPluginViewers(){
|
255 |
+
if(is_null($this->_viewers)){
|
256 |
+
$this->_viewers = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-viewers'))));
|
257 |
+
}
|
258 |
+
return $this->_viewers;
|
259 |
+
}
|
260 |
+
protected $_editors = null;
|
261 |
+
public function SetAllowedPluginEditors($usersOrRoles){
|
262 |
+
$this->_editors = $usersOrRoles;
|
263 |
+
$this->_plugin->SetGlobalOption('plugin-editors', implode(',', $this->_editors));
|
264 |
+
}
|
265 |
+
public function GetAllowedPluginEditors(){
|
266 |
+
if(is_null($this->_editors)){
|
267 |
+
$this->_editors = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-editors'))));
|
268 |
+
}
|
269 |
+
return $this->_editors;
|
270 |
+
}
|
271 |
+
protected $_perpage = null;
|
272 |
+
public function SetViewPerPage($newvalue){
|
273 |
+
$this->_perpage = max($newvalue, 1);
|
274 |
+
$this->_plugin->SetGlobalOption('items-per-page', $this->_perpage);
|
275 |
+
}
|
276 |
+
public function GetViewPerPage(){
|
277 |
+
if(is_null($this->_perpage)){
|
278 |
+
$this->_perpage = (int)$this->_plugin->GetGlobalOption('items-per-page', 10);
|
279 |
+
}
|
280 |
+
return $this->_perpage;
|
281 |
+
}
|
282 |
+
/**
|
283 |
+
* @param string $action Type of action, either 'view' or 'edit'.
|
284 |
+
* @return boolean If user has access or not.
|
285 |
+
*/
|
286 |
+
public function CurrentUserCan($action){
|
287 |
+
return $this->UserCan(wp_get_current_user(), $action);
|
288 |
+
}
|
289 |
+
/**
|
290 |
+
* @return string[] List of superadmin usernames.
|
291 |
+
*/
|
292 |
+
protected function GetSuperAdmins(){
|
293 |
+
return $this->_plugin->IsMultisite() ? get_super_admins() : array();
|
294 |
+
}
|
295 |
+
/**
|
296 |
+
* @return string[] List of admin usernames.
|
297 |
+
*/
|
298 |
+
protected function GetAdmins(){
|
299 |
+
if($this->_plugin->IsMultisite()){
|
300 |
+
// see: https://gist.github.com/1508426/65785a15b8638d43a9905effb59e4d97319ef8f8
|
301 |
+
global $wpdb;
|
302 |
+
$cap = $wpdb->prefix."capabilities";
|
303 |
+
$sql = "SELECT DISTINCT $wpdb->users.user_login"
|
304 |
+
. " FROM $wpdb->users"
|
305 |
+
. " INNER JOIN $wpdb->usermeta ON ($wpdb->users.ID = $wpdb->usermeta.user_id )"
|
306 |
+
. " WHERE $wpdb->usermeta.meta_key = '$cap'"
|
307 |
+
. " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
|
308 |
+
return $wpdb->get_col($sql);
|
309 |
+
}else{
|
310 |
+
$result = array();
|
311 |
+
$query = 'role=administrator&fields[]=user_login';
|
312 |
+
foreach (get_users($query) as $user) $result[] = $user->user_login;
|
313 |
+
return $result;
|
314 |
+
}
|
315 |
+
}
|
316 |
+
/**
|
317 |
+
* Returns access tokens for a particular action.
|
318 |
+
* @param string $action Type of action.
|
319 |
+
* @return string[] List of tokens (usernames, roles etc).
|
320 |
+
*/
|
321 |
+
public function GetAccessTokens($action){
|
322 |
+
$allowed = array();
|
323 |
+
switch($action){
|
324 |
+
case 'view':
|
325 |
+
$allowed = $this->GetAllowedPluginViewers();
|
326 |
+
$allowed = array_merge($allowed, $this->GetAllowedPluginEditors());
|
327 |
+
if (!$this->IsRestrictAdmins()) {
|
328 |
+
$allowed = array_merge($allowed, $this->GetSuperAdmins());
|
329 |
+
$allowed = array_merge($allowed, $this->GetAdmins());
|
330 |
+
}
|
331 |
+
break;
|
332 |
+
case 'edit':
|
333 |
+
$allowed = $this->GetAllowedPluginEditors();
|
334 |
+
if (!$this->IsRestrictAdmins()) {
|
335 |
+
$allowed = array_merge($allowed, $this->_plugin->IsMultisite() ?
|
336 |
+
$this->GetSuperAdmins() : $this->GetAdmins()
|
337 |
+
);
|
338 |
+
}
|
339 |
+
break;
|
340 |
+
default:
|
341 |
+
throw new Exception('Unknown action "'.$action.'".');
|
342 |
+
}
|
343 |
+
if (!$this->IsRestrictAdmins()) {
|
344 |
+
if(is_multisite()){
|
345 |
+
$allowed = array_merge($allowed, get_super_admins());
|
346 |
+
}else{
|
347 |
+
$allowed[] = 'administrator';
|
348 |
+
}
|
349 |
+
}
|
350 |
+
return array_unique($allowed);
|
351 |
+
}
|
352 |
+
/**
|
353 |
+
* @param integer|WP_user $user User object to check.
|
354 |
+
* @param string $action Type of action, either 'view' or 'edit'.
|
355 |
+
* @return boolean If user has access or not.
|
356 |
+
*/
|
357 |
+
public function UserCan($user, $action){
|
358 |
+
if(is_int($user))$user = get_userdata($user);
|
359 |
+
$allowed = $this->GetAccessTokens($action);
|
360 |
+
$check = array_merge(
|
361 |
+
$user->roles,
|
362 |
+
array($user->user_login)
|
363 |
+
);
|
364 |
+
foreach($check as $item){
|
365 |
+
if(in_array($item, $allowed)){
|
366 |
+
return true;
|
367 |
+
}
|
368 |
+
}
|
369 |
+
return false;
|
370 |
+
}
|
371 |
+
public function GetCurrentUserRoles($baseRoles = null){
|
372 |
+
if ($baseRoles == null) $baseRoles = wp_get_current_user()->roles;
|
373 |
+
if (function_exists('is_super_admin') && is_super_admin()) $baseRoles[] = 'superadmin';
|
374 |
+
return $baseRoles;
|
375 |
+
}
|
376 |
+
|
377 |
+
public function IsLoginSuperAdmin($username){
|
378 |
+
$userId = username_exists($username);
|
379 |
+
if ( function_exists('is_super_admin') && is_super_admin($userId) ) return true;
|
380 |
+
else return false;
|
381 |
+
}
|
382 |
+
|
383 |
+
// </editor-fold>
|
384 |
+
|
385 |
+
// <editor-fold desc="Licensing">
|
386 |
+
public function GetLicenses(){
|
387 |
+
return $this->_plugin->GetGlobalOption('licenses');
|
388 |
+
}
|
389 |
+
public function GetLicense($name){
|
390 |
+
$data = $this->GetLicenses();
|
391 |
+
$name = sanitize_key(basename($name));
|
392 |
+
return isset($data[$name]) ? $data[$name] : array();
|
393 |
+
}
|
394 |
+
public function SetLicenses($data){
|
395 |
+
$this->_plugin->SetGlobalOption('licenses', $data);
|
396 |
+
}
|
397 |
+
public function GetLicenseKey($name){
|
398 |
+
$data = $this->GetLicense($name);
|
399 |
+
return isset($data['key']) ? $data['key'] : '';
|
400 |
+
}
|
401 |
+
public function GetLicenseStatus($name){
|
402 |
+
$data = $this->GetLicense($name);
|
403 |
+
return isset($data['sts']) ? $data['sts'] : '';
|
404 |
+
}
|
405 |
+
public function GetLicenseErrors($name){
|
406 |
+
$data = $this->GetLicense($name);
|
407 |
+
return isset($data['err']) ? $data['err'] : '';
|
408 |
+
}
|
409 |
+
public function SetLicenseKey($name, $key){
|
410 |
+
$data = $this->GetLicenses();
|
411 |
+
if (!isset($data[$name])) $data[$name] = array();
|
412 |
+
$data[$name]['key'] = $key;
|
413 |
+
$this->SetLicenses($data);
|
414 |
+
}
|
415 |
+
public function SetLicenseStatus($name, $status){
|
416 |
+
$data = $this->GetLicenses();
|
417 |
+
if (!isset($data[$name])) $data[$name] = array();
|
418 |
+
$data[$name]['sts'] = $status;
|
419 |
+
$this->SetLicenses($data);
|
420 |
+
}
|
421 |
+
public function SetLicenseErrors($name, $errors){
|
422 |
+
$data = $this->GetLicenses();
|
423 |
+
if (!isset($data[$name])) $data[$name] = array();
|
424 |
+
$data[$name]['err'] = $errors;
|
425 |
+
$this->SetLicenses($data);
|
426 |
+
}
|
427 |
+
public function ClearLicenses(){
|
428 |
+
$this->SetLicenses(array());
|
429 |
+
}
|
430 |
+
|
431 |
+
// </editor-fold>
|
432 |
+
|
433 |
+
// <editor-fold desc="Client IP Retrieval">
|
434 |
+
|
435 |
+
public function IsMainIPFromProxy(){
|
436 |
+
return $this->_plugin->GetGlobalOption('use-proxy-ip');
|
437 |
+
}
|
438 |
+
public function SetMainIPFromProxy($enabled){
|
439 |
+
return $this->_plugin->SetGlobalOption('use-proxy-ip', $enabled);
|
440 |
+
}
|
441 |
+
|
442 |
+
public function IsInternalIPsFiltered(){
|
443 |
+
return $this->_plugin->GetGlobalOption('filter-internal-ip');
|
444 |
+
}
|
445 |
+
public function SetInternalIPsFiltering($enabled){
|
446 |
+
return $this->_plugin->SetGlobalOption('filter-internal-ip', $enabled);
|
447 |
+
}
|
448 |
+
|
449 |
+
public function GetMainClientIP(){
|
450 |
+
$result = null;
|
451 |
+
if ($this->IsMainIPFromProxy()) {
|
452 |
+
// TODO the algorithm below just gets the first IP in the list...we might want to make this more intelligent somehow
|
453 |
+
$result = $this->GetClientIPs();
|
454 |
+
$result = reset($result);
|
455 |
+
$result = isset($result[0]) ? $result[0] : null;
|
456 |
+
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
457 |
+
$result = $this->NormalizeIP($_SERVER['REMOTE_ADDR']);
|
458 |
+
if (!$this->ValidateIP($result)) {
|
459 |
+
$result = "Error " . self::ERROR_CODE_INVALID_IP . ": Invalid IP Address";
|
460 |
+
}
|
461 |
+
}
|
462 |
+
return $result;
|
463 |
+
}
|
464 |
+
|
465 |
+
public function GetClientIPs(){
|
466 |
+
$ips = array();
|
467 |
+
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) {
|
468 |
+
if (isset($_SERVER[$key])) {
|
469 |
+
$ips[$key] = array();
|
470 |
+
foreach (explode(',', $_SERVER[$key]) as $ip)
|
471 |
+
if ($this->ValidateIP($ip = $this->NormalizeIP($ip)))
|
472 |
+
$ips[$key][] = $ip;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
return $ips;
|
476 |
+
}
|
477 |
+
|
478 |
+
protected function NormalizeIP($ip){
|
479 |
+
$ip = trim($ip);
|
480 |
+
if(strpos($ip, ':') !== false && substr_count($ip, '.') == 3 && strpos($ip, '[') === false){
|
481 |
+
// IPv4 with a port (eg: 11.22.33.44:80)
|
482 |
+
$ip = explode(':', $ip);
|
483 |
+
$ip = $ip[0];
|
484 |
+
}else{
|
485 |
+
// IPv6 with a port (eg: [::1]:80)
|
486 |
+
$ip = explode(']', $ip);
|
487 |
+
$ip = ltrim($ip[0], '[');
|
488 |
+
}
|
489 |
+
return $ip;
|
490 |
+
}
|
491 |
+
|
492 |
+
protected function ValidateIP($ip){
|
493 |
+
$opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
|
494 |
+
if ($this->IsInternalIPsFiltered()) $opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
|
495 |
+
$filteredIP = filter_var($ip, FILTER_VALIDATE_IP, $opts);
|
496 |
+
if (!$filteredIP || empty($filteredIP)) {
|
497 |
+
//Regex IPV4
|
498 |
+
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)) return $ip;
|
499 |
+
//Regex IPV6
|
500 |
+
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)) return $ip;
|
501 |
+
|
502 |
+
error_log("Invalid IP in ValidateIP function: ".$ip);
|
503 |
+
return false;
|
504 |
+
} else {
|
505 |
+
return $filteredIP;
|
506 |
+
}
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Users excluded from monitoring
|
511 |
+
*/
|
512 |
+
protected $_excluded_users = array();
|
513 |
+
public function SetExcludedMonitoringUsers($users)
|
514 |
+
{
|
515 |
+
$this->_excluded_users = $users;
|
516 |
+
$this->_plugin->SetGlobalOption('excluded-users', implode(',', $this->_excluded_users));
|
517 |
+
}
|
518 |
+
public function GetExcludedMonitoringUsers()
|
519 |
+
{
|
520 |
+
if(empty($this->_excluded_users)){
|
521 |
+
$this->_excluded_users = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-users'))));
|
522 |
+
}
|
523 |
+
return $this->_excluded_users;
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Roles excluded from monitoring
|
528 |
+
*/
|
529 |
+
protected $_excluded_roles = array();
|
530 |
+
public function SetExcludedMonitoringRoles($roles){
|
531 |
+
$this->_excluded_roles = $roles;
|
532 |
+
$this->_plugin->SetGlobalOption('excluded-roles', implode(',', $this->_excluded_roles));
|
533 |
+
}
|
534 |
+
public function GetExcludedMonitoringRoles(){
|
535 |
+
if(empty($this->_excluded_roles)){
|
536 |
+
$this->_excluded_roles = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-roles'))));
|
537 |
+
}
|
538 |
+
return $this->_excluded_roles;
|
539 |
+
}
|
540 |
+
|
541 |
+
/**
|
542 |
+
* Custom fields excluded from monitoring
|
543 |
+
*/
|
544 |
+
protected $_excluded_custom = array();
|
545 |
+
public function SetExcludedMonitoringCustom($custom){
|
546 |
+
$this->_excluded_custom = $custom;
|
547 |
+
$this->_plugin->SetGlobalOption('excluded-custom', implode(',', $this->_excluded_custom));
|
548 |
+
}
|
549 |
+
public function GetExcludedMonitoringCustom(){
|
550 |
+
if(empty($this->_excluded_custom)){
|
551 |
+
$this->_excluded_custom = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-custom'))));
|
552 |
+
asort($this->_excluded_custom);
|
553 |
+
}
|
554 |
+
return $this->_excluded_custom;
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* IP excluded from monitoring
|
559 |
+
*/
|
560 |
+
protected $_excluded_ip = array();
|
561 |
+
public function SetExcludedMonitoringIP($ip){
|
562 |
+
$this->_excluded_ip = $ip;
|
563 |
+
$this->_plugin->SetGlobalOption('excluded-ip', implode(',', $this->_excluded_ip));
|
564 |
+
}
|
565 |
+
public function GetExcludedMonitoringIP(){
|
566 |
+
if(empty($this->_excluded_ip)){
|
567 |
+
$this->_excluded_ip = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-ip'))));
|
568 |
+
}
|
569 |
+
return $this->_excluded_ip;
|
570 |
+
}
|
571 |
+
|
572 |
+
/**
|
573 |
+
* Datetime format.
|
574 |
+
* 24 hours or AM/PM
|
575 |
+
*/
|
576 |
+
public function GetDatetimeFormat(){
|
577 |
+
return $this->_plugin->GetGlobalOption('datetime-format', 0);
|
578 |
+
}
|
579 |
+
|
580 |
+
public function SetDatetimeFormat($newvalue){
|
581 |
+
return $this->_plugin->SetGlobalOption('datetime-format', $newvalue);
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Alerts Timestamp
|
586 |
+
* Server's timezone or WordPress' timezone
|
587 |
+
*/
|
588 |
+
public function GetTimezone(){
|
589 |
+
return $this->_plugin->GetGlobalOption('timezone', 0);
|
590 |
+
}
|
591 |
+
|
592 |
+
public function SetTimezone($newvalue){
|
593 |
+
return $this->_plugin->SetGlobalOption('timezone', $newvalue);
|
594 |
+
}
|
595 |
+
|
596 |
+
public function GetAdapterConfig($name_field){
|
597 |
+
return $this->_plugin->GetGlobalOption($name_field);
|
598 |
+
}
|
599 |
+
|
600 |
+
public function SetAdapterConfig($name_field, $newvalue){
|
601 |
+
return $this->_plugin->SetGlobalOption($name_field, trim($newvalue));
|
602 |
+
}
|
603 |
+
|
604 |
+
public function GetColumns(){
|
605 |
+
$columns = array('alert_code' => '1', 'type' => '1', 'date' => '1', 'username' => '1', 'source_ip' => '1', 'message' => '1');
|
606 |
+
if ($this->_plugin->IsMultisite()) {
|
607 |
+
$columns = array_slice($columns, 0, 5, true) + array('site' => '1') + array_slice($columns, 5, null, true);
|
608 |
+
}
|
609 |
+
$selected = $this->GetColumnsSelected();
|
610 |
+
if (!empty($selected)) {
|
611 |
+
$columns = array('alert_code' => '0', 'type' => '0', 'date' => '0', 'username' => '0', 'source_ip' => '0', 'message' => '0');
|
612 |
+
if ($this->_plugin->IsMultisite()) {
|
613 |
+
$columns = array_slice($columns, 0, 5, true) + array('site' => '0') + array_slice($columns, 5, null, true);
|
614 |
+
}
|
615 |
+
$selected = (array)json_decode($selected);
|
616 |
+
$columns = array_merge($columns, $selected);
|
617 |
+
return $columns;
|
618 |
+
} else {
|
619 |
+
return $columns;
|
620 |
+
}
|
621 |
+
}
|
622 |
+
|
623 |
+
public function GetColumnsSelected(){
|
624 |
+
return $this->_plugin->GetGlobalOption('columns');
|
625 |
+
}
|
626 |
+
|
627 |
+
public function SetColumns($columns){
|
628 |
+
return $this->_plugin->SetGlobalOption('columns', json_encode($columns));
|
629 |
+
}
|
630 |
+
|
631 |
+
public function IsWPBackend(){
|
632 |
+
return $this->_plugin->GetGlobalOption('wp-backend');
|
633 |
+
}
|
634 |
+
|
635 |
+
public function SetWPBackend($enabled){
|
636 |
+
return $this->_plugin->SetGlobalOption('wp-backend', $enabled);
|
637 |
+
}
|
638 |
+
// </editor-fold>
|
639 |
+
}
|
classes/SimpleProfiler.php
CHANGED
@@ -1,44 +1,44 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_SimpleProfiler {
|
4 |
-
protected $_items = array();
|
5 |
-
|
6 |
-
public function Start($name) {
|
7 |
-
$item = new WSAL_SimpleProfiler_Item($name);
|
8 |
-
$this->_items[] = $item;
|
9 |
-
return $item;
|
10 |
-
}
|
11 |
-
|
12 |
-
public function AsComment(){
|
13 |
-
echo '<!-- ' . PHP_EOL;
|
14 |
-
foreach($this->_items as $item){
|
15 |
-
echo ' ' . $item . PHP_EOL;
|
16 |
-
}
|
17 |
-
echo '-->' . PHP_EOL;
|
18 |
-
}
|
19 |
-
|
20 |
-
public function GetItems(){
|
21 |
-
return $this->_items;
|
22 |
-
}
|
23 |
-
}
|
24 |
-
|
25 |
-
class WSAL_SimpleProfiler_Item{
|
26 |
-
public function __construct($name){
|
27 |
-
$this->name = $name;
|
28 |
-
$this->t_bgn = microtime(true);
|
29 |
-
$this->m_bgn = memory_get_usage();
|
30 |
-
}
|
31 |
-
|
32 |
-
public function Stop(){
|
33 |
-
$this->t_end = microtime(true);
|
34 |
-
$this->m_end = memory_get_usage();
|
35 |
-
}
|
36 |
-
|
37 |
-
public function __toString(){
|
38 |
-
$t_diff = $this->t_end - $this->t_bgn;
|
39 |
-
$m_diff = $this->m_end - $this->m_bgn;
|
40 |
-
return number_format($t_diff, 6) . 's '
|
41 |
-
. str_pad(number_format($m_diff, 0), 12, ' ', STR_PAD_LEFT) . 'b '
|
42 |
-
. $this->name;
|
43 |
-
}
|
44 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_SimpleProfiler {
|
4 |
+
protected $_items = array();
|
5 |
+
|
6 |
+
public function Start($name) {
|
7 |
+
$item = new WSAL_SimpleProfiler_Item($name);
|
8 |
+
$this->_items[] = $item;
|
9 |
+
return $item;
|
10 |
+
}
|
11 |
+
|
12 |
+
public function AsComment(){
|
13 |
+
echo '<!-- ' . PHP_EOL;
|
14 |
+
foreach($this->_items as $item){
|
15 |
+
echo ' ' . $item . PHP_EOL;
|
16 |
+
}
|
17 |
+
echo '-->' . PHP_EOL;
|
18 |
+
}
|
19 |
+
|
20 |
+
public function GetItems(){
|
21 |
+
return $this->_items;
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
class WSAL_SimpleProfiler_Item{
|
26 |
+
public function __construct($name){
|
27 |
+
$this->name = $name;
|
28 |
+
$this->t_bgn = microtime(true);
|
29 |
+
$this->m_bgn = memory_get_usage();
|
30 |
+
}
|
31 |
+
|
32 |
+
public function Stop(){
|
33 |
+
$this->t_end = microtime(true);
|
34 |
+
$this->m_end = memory_get_usage();
|
35 |
+
}
|
36 |
+
|
37 |
+
public function __toString(){
|
38 |
+
$t_diff = $this->t_end - $this->t_bgn;
|
39 |
+
$m_diff = $this->m_end - $this->m_bgn;
|
40 |
+
return number_format($t_diff, 6) . 's '
|
41 |
+
. str_pad(number_format($m_diff, 0), 12, ' ', STR_PAD_LEFT) . 'b '
|
42 |
+
. $this->name;
|
43 |
+
}
|
44 |
}
|
classes/ViewManager.php
CHANGED
@@ -1,215 +1,215 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_ViewManager {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var WSAL_AbstractView[]
|
7 |
-
*/
|
8 |
-
public $views = array();
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var WpSecurityAuditLog
|
12 |
-
*/
|
13 |
-
protected $_plugin;
|
14 |
-
|
15 |
-
public function __construct(WpSecurityAuditLog $plugin){
|
16 |
-
$this->_plugin = $plugin;
|
17 |
-
|
18 |
-
// load views
|
19 |
-
foreach(glob(dirname(__FILE__) . '/Views/*.php') as $file)
|
20 |
-
$this->AddFromFile($file);
|
21 |
-
|
22 |
-
// add menus
|
23 |
-
add_action('admin_menu', array($this, 'AddAdminMenus'));
|
24 |
-
add_action('network_admin_menu', array($this, 'AddAdminMenus'));
|
25 |
-
|
26 |
-
// add plugin shortcut links
|
27 |
-
add_filter('plugin_action_links_' . $plugin->GetBaseName(), array($this, 'AddPluginShortcuts'));
|
28 |
-
|
29 |
-
// render header
|
30 |
-
add_action('admin_enqueue_scripts', array($this, 'RenderViewHeader'));
|
31 |
-
|
32 |
-
// render footer
|
33 |
-
add_action('admin_footer', array($this, 'RenderViewFooter'));
|
34 |
-
}
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Add new view from file inside autoloader path.
|
38 |
-
* @param string $file Path to file.
|
39 |
-
*/
|
40 |
-
public function AddFromFile($file){
|
41 |
-
$this->AddFromClass($this->_plugin->GetClassFileClassName($file));
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Add new view given class name.
|
46 |
-
* @param string $class Class name.
|
47 |
-
*/
|
48 |
-
public function AddFromClass($class){
|
49 |
-
$this->AddInstance(new $class($this->_plugin));
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Add newly created view to list.
|
54 |
-
* @param WSAL_AbstractView $view The new view.
|
55 |
-
*/
|
56 |
-
public function AddInstance(WSAL_AbstractView $view){
|
57 |
-
$this->views[] = $view;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Order views by their declared weight.
|
62 |
-
*/
|
63 |
-
public function ReorderViews(){
|
64 |
-
usort($this->views, array($this, 'OrderByWeight'));
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* @internal This has to be public for PHP to call it.
|
69 |
-
* @param WSAL_AbstractView $a
|
70 |
-
* @param WSAL_AbstractView $b
|
71 |
-
* @return int
|
72 |
-
*/
|
73 |
-
public function OrderByWeight(WSAL_AbstractView $a, WSAL_AbstractView $b){
|
74 |
-
$wa = $a->GetWeight();
|
75 |
-
$wb = $b->GetWeight();
|
76 |
-
switch(true){
|
77 |
-
case $wa < $wb:
|
78 |
-
return -1;
|
79 |
-
case $wa > $wb:
|
80 |
-
return 1;
|
81 |
-
default:
|
82 |
-
return 0;
|
83 |
-
}
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Wordpress Action
|
88 |
-
*/
|
89 |
-
public function AddAdminMenus(){
|
90 |
-
$this->ReorderViews();
|
91 |
-
|
92 |
-
if($this->_plugin->settings->CurrentUserCan('view') && count($this->views)){
|
93 |
-
// add main menu
|
94 |
-
$this->views[0]->hook_suffix = add_menu_page(
|
95 |
-
'WP Security Audit Log',
|
96 |
-
'Audit Log',
|
97 |
-
'read', // no capability requirement
|
98 |
-
$this->views[0]->GetSafeViewName(),
|
99 |
-
array($this, 'RenderViewBody'),
|
100 |
-
$this->views[0]->GetIcon(),
|
101 |
-
'2.5' // right after dashboard
|
102 |
-
);
|
103 |
-
|
104 |
-
// add menu items
|
105 |
-
foreach($this->views as $view){
|
106 |
-
if($view->IsAccessible()){
|
107 |
-
$view->hook_suffix = add_submenu_page(
|
108 |
-
$view->IsVisible() ? $this->views[0]->GetSafeViewName() : null,
|
109 |
-
$view->GetTitle(),
|
110 |
-
$view->GetName(),
|
111 |
-
'read', // no capability requirement
|
112 |
-
$view->GetSafeViewName(),
|
113 |
-
array($this, 'RenderViewBody'),
|
114 |
-
$view->GetIcon()
|
115 |
-
);
|
116 |
-
}
|
117 |
-
}
|
118 |
-
}
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Wordpress Filter
|
123 |
-
*/
|
124 |
-
public function AddPluginShortcuts($old_links){
|
125 |
-
$this->ReorderViews();
|
126 |
-
|
127 |
-
$new_links = array();
|
128 |
-
foreach($this->views as $view){
|
129 |
-
if($view->HasPluginShortcutLink()){
|
130 |
-
$new_links[] =
|
131 |
-
'<a href="'
|
132 |
-
. admin_url('admin.php?page='
|
133 |
-
. $view->GetSafeViewName()
|
134 |
-
) . '">'
|
135 |
-
. $view->GetName()
|
136 |
-
. '</a>';
|
137 |
-
}
|
138 |
-
}
|
139 |
-
return array_merge($new_links, $old_links);
|
140 |
-
}
|
141 |
-
|
142 |
-
/**
|
143 |
-
* @return int Returns page id of current page (or false on error).
|
144 |
-
*/
|
145 |
-
protected function GetBackendPageIndex(){
|
146 |
-
if(isset($_REQUEST['page']))
|
147 |
-
foreach($this->views as $i => $view)
|
148 |
-
if($_REQUEST['page'] == $view->GetSafeViewName())
|
149 |
-
return $i;
|
150 |
-
return false;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
*
|
155 |
-
* @var WSAL_AbstractView|null
|
156 |
-
*/
|
157 |
-
protected $_active_view = false;
|
158 |
-
|
159 |
-
/**
|
160 |
-
* @return WSAL_AbstractView|null Returns the current active view or null if none.
|
161 |
-
*/
|
162 |
-
public function GetActiveView(){
|
163 |
-
if($this->_active_view === false){
|
164 |
-
$this->_active_view = null;
|
165 |
-
|
166 |
-
if(isset($_REQUEST['page']))
|
167 |
-
foreach($this->views as $view)
|
168 |
-
if($_REQUEST['page'] == $view->GetSafeViewName())
|
169 |
-
$this->_active_view = $view;
|
170 |
-
|
171 |
-
if($this->_active_view)
|
172 |
-
$this->_active_view->is_active = true;
|
173 |
-
}
|
174 |
-
return $this->_active_view;
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Render header of the current view.
|
179 |
-
*/
|
180 |
-
public function RenderViewHeader(){
|
181 |
-
if (!!($view = $this->GetActiveView())) $view->Header();
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Render footer of the current view.
|
186 |
-
*/
|
187 |
-
public function RenderViewFooter(){
|
188 |
-
if (!!($view = $this->GetActiveView())) $view->Footer();
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* Render content of the current view.
|
193 |
-
*/
|
194 |
-
public function RenderViewBody(){
|
195 |
-
$view = $this->GetActiveView();
|
196 |
-
?><div class="wrap"><?php
|
197 |
-
$view->RenderIcon();
|
198 |
-
$view->RenderTitle();
|
199 |
-
$view->RenderContent();
|
200 |
-
?></div><?php
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* Returns view instance corresponding to its class name.
|
205 |
-
* @param string $className View class name.
|
206 |
-
* @return WSAL_AbstractView The view or false on failure.
|
207 |
-
*/
|
208 |
-
public function FindByClassName($className){
|
209 |
-
foreach($this->views as $view)
|
210 |
-
if($view instanceof $className)
|
211 |
-
return $view;
|
212 |
-
return false;
|
213 |
-
}
|
214 |
-
|
215 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_ViewManager {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var WSAL_AbstractView[]
|
7 |
+
*/
|
8 |
+
public $views = array();
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var WpSecurityAuditLog
|
12 |
+
*/
|
13 |
+
protected $_plugin;
|
14 |
+
|
15 |
+
public function __construct(WpSecurityAuditLog $plugin){
|
16 |
+
$this->_plugin = $plugin;
|
17 |
+
|
18 |
+
// load views
|
19 |
+
foreach(glob(dirname(__FILE__) . '/Views/*.php') as $file)
|
20 |
+
$this->AddFromFile($file);
|
21 |
+
|
22 |
+
// add menus
|
23 |
+
add_action('admin_menu', array($this, 'AddAdminMenus'));
|
24 |
+
add_action('network_admin_menu', array($this, 'AddAdminMenus'));
|
25 |
+
|
26 |
+
// add plugin shortcut links
|
27 |
+
add_filter('plugin_action_links_' . $plugin->GetBaseName(), array($this, 'AddPluginShortcuts'));
|
28 |
+
|
29 |
+
// render header
|
30 |
+
add_action('admin_enqueue_scripts', array($this, 'RenderViewHeader'));
|
31 |
+
|
32 |
+
// render footer
|
33 |
+
add_action('admin_footer', array($this, 'RenderViewFooter'));
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Add new view from file inside autoloader path.
|
38 |
+
* @param string $file Path to file.
|
39 |
+
*/
|
40 |
+
public function AddFromFile($file){
|
41 |
+
$this->AddFromClass($this->_plugin->GetClassFileClassName($file));
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Add new view given class name.
|
46 |
+
* @param string $class Class name.
|
47 |
+
*/
|
48 |
+
public function AddFromClass($class){
|
49 |
+
$this->AddInstance(new $class($this->_plugin));
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Add newly created view to list.
|
54 |
+
* @param WSAL_AbstractView $view The new view.
|
55 |
+
*/
|
56 |
+
public function AddInstance(WSAL_AbstractView $view){
|
57 |
+
$this->views[] = $view;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Order views by their declared weight.
|
62 |
+
*/
|
63 |
+
public function ReorderViews(){
|
64 |
+
usort($this->views, array($this, 'OrderByWeight'));
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @internal This has to be public for PHP to call it.
|
69 |
+
* @param WSAL_AbstractView $a
|
70 |
+
* @param WSAL_AbstractView $b
|
71 |
+
* @return int
|
72 |
+
*/
|
73 |
+
public function OrderByWeight(WSAL_AbstractView $a, WSAL_AbstractView $b){
|
74 |
+
$wa = $a->GetWeight();
|
75 |
+
$wb = $b->GetWeight();
|
76 |
+
switch(true){
|
77 |
+
case $wa < $wb:
|
78 |
+
return -1;
|
79 |
+
case $wa > $wb:
|
80 |
+
return 1;
|
81 |
+
default:
|
82 |
+
return 0;
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Wordpress Action
|
88 |
+
*/
|
89 |
+
public function AddAdminMenus(){
|
90 |
+
$this->ReorderViews();
|
91 |
+
|
92 |
+
if($this->_plugin->settings->CurrentUserCan('view') && count($this->views)){
|
93 |
+
// add main menu
|
94 |
+
$this->views[0]->hook_suffix = add_menu_page(
|
95 |
+
'WP Security Audit Log',
|
96 |
+
'Audit Log',
|
97 |
+
'read', // no capability requirement
|
98 |
+
$this->views[0]->GetSafeViewName(),
|
99 |
+
array($this, 'RenderViewBody'),
|
100 |
+
$this->views[0]->GetIcon(),
|
101 |
+
'2.5' // right after dashboard
|
102 |
+
);
|
103 |
+
|
104 |
+
// add menu items
|
105 |
+
foreach($this->views as $view){
|
106 |
+
if($view->IsAccessible()){
|
107 |
+
$view->hook_suffix = add_submenu_page(
|
108 |
+
$view->IsVisible() ? $this->views[0]->GetSafeViewName() : null,
|
109 |
+
$view->GetTitle(),
|
110 |
+
$view->GetName(),
|
111 |
+
'read', // no capability requirement
|
112 |
+
$view->GetSafeViewName(),
|
113 |
+
array($this, 'RenderViewBody'),
|
114 |
+
$view->GetIcon()
|
115 |
+
);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Wordpress Filter
|
123 |
+
*/
|
124 |
+
public function AddPluginShortcuts($old_links){
|
125 |
+
$this->ReorderViews();
|
126 |
+
|
127 |
+
$new_links = array();
|
128 |
+
foreach($this->views as $view){
|
129 |
+
if($view->HasPluginShortcutLink()){
|
130 |
+
$new_links[] =
|
131 |
+
'<a href="'
|
132 |
+
. admin_url('admin.php?page='
|
133 |
+
. $view->GetSafeViewName()
|
134 |
+
) . '">'
|
135 |
+
. $view->GetName()
|
136 |
+
. '</a>';
|
137 |
+
}
|
138 |
+
}
|
139 |
+
return array_merge($new_links, $old_links);
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @return int Returns page id of current page (or false on error).
|
144 |
+
*/
|
145 |
+
protected function GetBackendPageIndex(){
|
146 |
+
if(isset($_REQUEST['page']))
|
147 |
+
foreach($this->views as $i => $view)
|
148 |
+
if($_REQUEST['page'] == $view->GetSafeViewName())
|
149 |
+
return $i;
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
*
|
155 |
+
* @var WSAL_AbstractView|null
|
156 |
+
*/
|
157 |
+
protected $_active_view = false;
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @return WSAL_AbstractView|null Returns the current active view or null if none.
|
161 |
+
*/
|
162 |
+
public function GetActiveView(){
|
163 |
+
if($this->_active_view === false){
|
164 |
+
$this->_active_view = null;
|
165 |
+
|
166 |
+
if(isset($_REQUEST['page']))
|
167 |
+
foreach($this->views as $view)
|
168 |
+
if($_REQUEST['page'] == $view->GetSafeViewName())
|
169 |
+
$this->_active_view = $view;
|
170 |
+
|
171 |
+
if($this->_active_view)
|
172 |
+
$this->_active_view->is_active = true;
|
173 |
+
}
|
174 |
+
return $this->_active_view;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Render header of the current view.
|
179 |
+
*/
|
180 |
+
public function RenderViewHeader(){
|
181 |
+
if (!!($view = $this->GetActiveView())) $view->Header();
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Render footer of the current view.
|
186 |
+
*/
|
187 |
+
public function RenderViewFooter(){
|
188 |
+
if (!!($view = $this->GetActiveView())) $view->Footer();
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Render content of the current view.
|
193 |
+
*/
|
194 |
+
public function RenderViewBody(){
|
195 |
+
$view = $this->GetActiveView();
|
196 |
+
?><div class="wrap"><?php
|
197 |
+
$view->RenderIcon();
|
198 |
+
$view->RenderTitle();
|
199 |
+
$view->RenderContent();
|
200 |
+
?></div><?php
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Returns view instance corresponding to its class name.
|
205 |
+
* @param string $className View class name.
|
206 |
+
* @return WSAL_AbstractView The view or false on failure.
|
207 |
+
*/
|
208 |
+
public function FindByClassName($className){
|
209 |
+
foreach($this->views as $view)
|
210 |
+
if($view instanceof $className)
|
211 |
+
return $view;
|
212 |
+
return false;
|
213 |
+
}
|
214 |
+
|
215 |
}
|
classes/Views/About.php
CHANGED
@@ -1,86 +1,86 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Views_About extends WSAL_AbstractView {
|
4 |
-
|
5 |
-
public function GetTitle() {
|
6 |
-
return __('About WP Security Audit Log', 'wp-security-audit-log');
|
7 |
-
}
|
8 |
-
|
9 |
-
public function GetIcon() {
|
10 |
-
return 'dashicons-editor-help';
|
11 |
-
}
|
12 |
-
|
13 |
-
public function GetName() {
|
14 |
-
return __('About', 'wp-security-audit-log');
|
15 |
-
}
|
16 |
-
|
17 |
-
public function GetWeight(){
|
18 |
-
return 6;
|
19 |
-
}
|
20 |
-
|
21 |
-
public function Render(){
|
22 |
-
?><div class="metabox-holder" style="position: relative;">
|
23 |
-
|
24 |
-
<div class="postbox" style="margin-right: 270px;">
|
25 |
-
<!--h3 class="hndl"><span>About WP Security Audit Log</span></h3-->
|
26 |
-
<div class="inside">
|
27 |
-
<div class="activity-block">
|
28 |
-
<?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'); ?>
|
29 |
-
|
30 |
-
<h2><?php _e('Keep A WordPress Security Audit Log & Identify WordPress Security Issues', 'wp-security-audit-log'); ?></h2>
|
31 |
-
<p>
|
32 |
-
<?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'); ?>
|
33 |
-
</p>
|
34 |
-
<ul style="list-style-type: disc; margin-left: 2.5em; list-style-position: outside;">
|
35 |
-
<li><?php _e('User creates a new user or a new user is registered', 'wp-security-audit-log'); ?></li>
|
36 |
-
<li><?php _e('Existing user changes the role, password or other properties of another user', 'wp-security-audit-log'); ?></li>
|
37 |
-
<li><?php _e('Existing user on a WordPress multisite network is added to a site', 'wp-security-audit-log'); ?></li>
|
38 |
-
<li><?php _e('User uploads or deletes a file, changes a password or email address', 'wp-security-audit-log'); ?></li>
|
39 |
-
<li><?php _e('User installs, activates, deactivates, upgrades or uninstalls a plugin', 'wp-security-audit-log'); ?></li>
|
40 |
-
<li><?php _e('User creates, modifies or deletes a new post, page, category or a custom post type', 'wp-security-audit-log'); ?></li>
|
41 |
-
<li><?php _e('User installs or activates a WordPress theme', 'wp-security-audit-log'); ?></li>
|
42 |
-
<li><?php _e('User adds, modifies or deletes a widget', 'wp-security-audit-log'); ?></li>
|
43 |
-
<li><?php _e('User uses the dashboard file editor', 'wp-security-audit-log'); ?></li>
|
44 |
-
<li><?php _e('WordPress settings are changed', 'wp-security-audit-log'); ?></li>
|
45 |
-
<li><?php _e('Failed login attempts', 'wp-security-audit-log'); ?></li>
|
46 |
-
<li><?php _e('and much more…', 'wp-security-audit-log'); ?></li>
|
47 |
-
</ul>
|
48 |
-
<br/>
|
49 |
-
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.
|
50 |
-
</div>
|
51 |
-
</div>
|
52 |
-
</div>
|
53 |
-
|
54 |
-
<div style="position: absolute; right: 70px; width: 180px; top: 10px;">
|
55 |
-
<div class="postbox">
|
56 |
-
<h3 class="hndl"><span><?php _e('Extend the Functionality & Get More Value from WP Security Audit Log', 'wp-security-audit-log'); ?></span></h3>
|
57 |
-
<div class="inside">
|
58 |
-
<p>
|
59 |
-
<?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.'); ?>
|
60 |
-
</p>
|
61 |
-
<a class="button button-primary" href="http://www.wpsecurityauditlog.com/plugin-extensions/" target="_blank"><?php _e('See Add-Ons', 'wp-security-audit-log'); ?></a>
|
62 |
-
</div>
|
63 |
-
</div>
|
64 |
-
<div class="postbox">
|
65 |
-
<h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
|
66 |
-
<div class="inside">
|
67 |
-
<?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
|
68 |
-
<a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
|
69 |
-
</div>
|
70 |
-
</div>
|
71 |
-
<div class="postbox">
|
72 |
-
<h3 class="hndl"><span><?php _e('WordPress Security Services', 'wp-security-audit-log'); ?></span></h3>
|
73 |
-
<div class="inside">
|
74 |
-
<?php _e('Professional WordPress security services provided by WP White Security', 'wp-security-audit-log'); ?>
|
75 |
-
<ul>
|
76 |
-
<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>
|
77 |
-
<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>
|
78 |
-
<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>
|
79 |
-
</ul>
|
80 |
-
</div>
|
81 |
-
</div>
|
82 |
-
</div>
|
83 |
-
</div><?php
|
84 |
-
}
|
85 |
-
|
86 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Views_About extends WSAL_AbstractView {
|
4 |
+
|
5 |
+
public function GetTitle() {
|
6 |
+
return __('About WP Security Audit Log', 'wp-security-audit-log');
|
7 |
+
}
|
8 |
+
|
9 |
+
public function GetIcon() {
|
10 |
+
return 'dashicons-editor-help';
|
11 |
+
}
|
12 |
+
|
13 |
+
public function GetName() {
|
14 |
+
return __('About', 'wp-security-audit-log');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function GetWeight(){
|
18 |
+
return 6;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function Render(){
|
22 |
+
?><div class="metabox-holder" style="position: relative;">
|
23 |
+
|
24 |
+
<div class="postbox" style="margin-right: 270px;">
|
25 |
+
<!--h3 class="hndl"><span>About WP Security Audit Log</span></h3-->
|
26 |
+
<div class="inside">
|
27 |
+
<div class="activity-block">
|
28 |
+
<?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'); ?>
|
29 |
+
|
30 |
+
<h2><?php _e('Keep A WordPress Security Audit Log & Identify WordPress Security Issues', 'wp-security-audit-log'); ?></h2>
|
31 |
+
<p>
|
32 |
+
<?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'); ?>
|
33 |
+
</p>
|
34 |
+
<ul style="list-style-type: disc; margin-left: 2.5em; list-style-position: outside;">
|
35 |
+
<li><?php _e('User creates a new user or a new user is registered', 'wp-security-audit-log'); ?></li>
|
36 |
+
<li><?php _e('Existing user changes the role, password or other properties of another user', 'wp-security-audit-log'); ?></li>
|
37 |
+
<li><?php _e('Existing user on a WordPress multisite network is added to a site', 'wp-security-audit-log'); ?></li>
|
38 |
+
<li><?php _e('User uploads or deletes a file, changes a password or email address', 'wp-security-audit-log'); ?></li>
|
39 |
+
<li><?php _e('User installs, activates, deactivates, upgrades or uninstalls a plugin', 'wp-security-audit-log'); ?></li>
|
40 |
+
<li><?php _e('User creates, modifies or deletes a new post, page, category or a custom post type', 'wp-security-audit-log'); ?></li>
|
41 |
+
<li><?php _e('User installs or activates a WordPress theme', 'wp-security-audit-log'); ?></li>
|
42 |
+
<li><?php _e('User adds, modifies or deletes a widget', 'wp-security-audit-log'); ?></li>
|
43 |
+
<li><?php _e('User uses the dashboard file editor', 'wp-security-audit-log'); ?></li>
|
44 |
+
<li><?php _e('WordPress settings are changed', 'wp-security-audit-log'); ?></li>
|
45 |
+
<li><?php _e('Failed login attempts', 'wp-security-audit-log'); ?></li>
|
46 |
+
<li><?php _e('and much more…', 'wp-security-audit-log'); ?></li>
|
47 |
+
</ul>
|
48 |
+
<br/>
|
49 |
+
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.
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
</div>
|
53 |
+
|
54 |
+
<div style="position: absolute; right: 70px; width: 180px; top: 10px;">
|
55 |
+
<div class="postbox">
|
56 |
+
<h3 class="hndl"><span><?php _e('Extend the Functionality & Get More Value from WP Security Audit Log', 'wp-security-audit-log'); ?></span></h3>
|
57 |
+
<div class="inside">
|
58 |
+
<p>
|
59 |
+
<?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.'); ?>
|
60 |
+
</p>
|
61 |
+
<a class="button button-primary" href="http://www.wpsecurityauditlog.com/plugin-extensions/" target="_blank"><?php _e('See Add-Ons', 'wp-security-audit-log'); ?></a>
|
62 |
+
</div>
|
63 |
+
</div>
|
64 |
+
<div class="postbox">
|
65 |
+
<h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
|
66 |
+
<div class="inside">
|
67 |
+
<?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
|
68 |
+
<a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
|
69 |
+
</div>
|
70 |
+
</div>
|
71 |
+
<div class="postbox">
|
72 |
+
<h3 class="hndl"><span><?php _e('WordPress Security Services', 'wp-security-audit-log'); ?></span></h3>
|
73 |
+
<div class="inside">
|
74 |
+
<?php _e('Professional WordPress security services provided by WP White Security', 'wp-security-audit-log'); ?>
|
75 |
+
<ul>
|
76 |
+
<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>
|
77 |
+
<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>
|
78 |
+
<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>
|
79 |
+
</ul>
|
80 |
+
</div>
|
81 |
+
</div>
|
82 |
+
</div>
|
83 |
+
</div><?php
|
84 |
+
}
|
85 |
+
|
86 |
}
|
classes/Views/AuditLog.php
CHANGED
@@ -1,177 +1,177 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
4 |
-
/**
|
5 |
-
* @var WSAL_AuditLogListView
|
6 |
-
*/
|
7 |
-
protected $_listview;
|
8 |
-
|
9 |
-
public function __construct(WpSecurityAuditLog $plugin) {
|
10 |
-
parent::__construct($plugin);
|
11 |
-
add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
|
12 |
-
add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
|
13 |
-
add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
|
14 |
-
add_action('wp_ajax_AjaxSearchSite', array($this, 'AjaxSearchSite'));
|
15 |
-
|
16 |
-
$this->RegisterNotice('notifications-extension');
|
17 |
-
}
|
18 |
-
|
19 |
-
public function HasPluginShortcutLink(){
|
20 |
-
return true;
|
21 |
-
}
|
22 |
-
|
23 |
-
public function GetTitle() {
|
24 |
-
return __('Audit Log Viewer', 'wp-security-audit-log');
|
25 |
-
}
|
26 |
-
|
27 |
-
public function GetIcon() {
|
28 |
-
return $this->_wpversion < 3.8
|
29 |
-
? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
|
30 |
-
: 'dashicons-welcome-view-site';
|
31 |
-
}
|
32 |
-
|
33 |
-
public function GetName() {
|
34 |
-
return __('Audit Log Viewer', 'wp-security-audit-log');
|
35 |
-
}
|
36 |
-
|
37 |
-
public function GetWeight(){
|
38 |
-
return 1;
|
39 |
-
}
|
40 |
-
|
41 |
-
protected function GetListView(){
|
42 |
-
if (is_null($this->_listview)) $this->_listview = new WSAL_AuditLogListView($this->_plugin);
|
43 |
-
return $this->_listview;
|
44 |
-
}
|
45 |
-
|
46 |
-
public function Render(){
|
47 |
-
if(!$this->_plugin->settings->CurrentUserCan('view')){
|
48 |
-
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
49 |
-
}
|
50 |
-
|
51 |
-
$this->GetListView()->prepare_items();
|
52 |
-
$occ = new WSAL_Models_Occurrence();
|
53 |
-
|
54 |
-
?><form id="audit-log-viewer" method="post">
|
55 |
-
<div id="audit-log-viewer-content">
|
56 |
-
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
57 |
-
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr(isset($_REQUEST['wsal-cbid']) ? $_REQUEST['wsal-cbid'] : '0'); ?>" />
|
58 |
-
<?php do_action('wsal_auditlog_before_view', $this->GetListView()); ?>
|
59 |
-
<?php $this->GetListView()->display(); ?>
|
60 |
-
<?php do_action('wsal_auditlog_after_view', $this->GetListView()); ?>
|
61 |
-
</div>
|
62 |
-
</form><?php
|
63 |
-
|
64 |
-
?><script type="text/javascript">
|
65 |
-
jQuery(document).ready(function(){
|
66 |
-
WsalAuditLogInit(<?php echo json_encode(array(
|
67 |
-
'ajaxurl' => admin_url('admin-ajax.php'),
|
68 |
-
'tr8n' => array(
|
69 |
-
'numofitems' => __('Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log'),
|
70 |
-
'searchback' => __('All Sites', 'wp-security-audit-log'),
|
71 |
-
'searchnone' => __('No Results', 'wp-security-audit-log'),
|
72 |
-
),
|
73 |
-
'autorefresh' => array(
|
74 |
-
'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
|
75 |
-
'token' => (int)$occ->Count(),
|
76 |
-
),
|
77 |
-
)); ?>);
|
78 |
-
});
|
79 |
-
</script><?php
|
80 |
-
}
|
81 |
-
|
82 |
-
public function AjaxInspector(){
|
83 |
-
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
84 |
-
die('Access Denied.');
|
85 |
-
if(!isset($_REQUEST['occurrence']))
|
86 |
-
die('Occurrence parameter expected.');
|
87 |
-
$occ = new WSAL_Models_Occurrence();
|
88 |
-
$occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
|
89 |
-
|
90 |
-
echo '<!DOCTYPE html><html><head>';
|
91 |
-
echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
|
92 |
-
echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
|
93 |
-
echo '<style type="text/css">';
|
94 |
-
echo 'html, body { margin: 0; padding: 0; }';
|
95 |
-
echo '.nice_r { position: absolute; padding: 8px; }';
|
96 |
-
echo '.nice_r a { overflow: visible; }';
|
97 |
-
echo '</style>';
|
98 |
-
echo '</head><body>';
|
99 |
-
$nicer = new WSAL_Nicer($occ->GetMetaArray());
|
100 |
-
$nicer->render();
|
101 |
-
echo '</body></html>';
|
102 |
-
die;
|
103 |
-
}
|
104 |
-
|
105 |
-
public function AjaxRefresh(){
|
106 |
-
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
107 |
-
die('Access Denied.');
|
108 |
-
if(!isset($_REQUEST['logcount']))
|
109 |
-
die('Log count parameter expected.');
|
110 |
-
|
111 |
-
$old = (int)$_REQUEST['logcount'];
|
112 |
-
$max = 40; // 40*500msec = 20sec
|
113 |
-
|
114 |
-
session_write_close(); // fixes session lock issue
|
115 |
-
|
116 |
-
do{
|
117 |
-
$occ = new WSAL_Models_Occurrence();
|
118 |
-
$new = $occ->Count();
|
119 |
-
usleep(500000); // 500msec
|
120 |
-
}while(($old == $new) && (--$max > 0));
|
121 |
-
|
122 |
-
echo $old == $new ? 'false' : $new;
|
123 |
-
die;
|
124 |
-
}
|
125 |
-
|
126 |
-
public function AjaxSetIpp(){
|
127 |
-
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
128 |
-
die('Access Denied.');
|
129 |
-
if(!isset($_REQUEST['count']))
|
130 |
-
die('Count parameter expected.');
|
131 |
-
$this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
|
132 |
-
die;
|
133 |
-
}
|
134 |
-
|
135 |
-
public function AjaxSearchSite(){
|
136 |
-
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
137 |
-
die('Access Denied.');
|
138 |
-
if(!isset($_REQUEST['search']))
|
139 |
-
die('Search parameter expected.');
|
140 |
-
|
141 |
-
$grp1 = array();
|
142 |
-
$grp2 = array();
|
143 |
-
|
144 |
-
$search = $_REQUEST['search'];
|
145 |
-
|
146 |
-
foreach($this->GetListView()->get_sites() as $site){
|
147 |
-
if(stripos($site->blogname, $search) !== false)
|
148 |
-
$grp1[] = $site;
|
149 |
-
else
|
150 |
-
if(stripos($site->domain, $search) !== false)
|
151 |
-
$grp2[] = $site;
|
152 |
-
}
|
153 |
-
|
154 |
-
die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
|
155 |
-
}
|
156 |
-
|
157 |
-
public function Header(){
|
158 |
-
add_thickbox();
|
159 |
-
wp_enqueue_style(
|
160 |
-
'auditlog',
|
161 |
-
$this->_plugin->GetBaseUrl() . '/css/auditlog.css',
|
162 |
-
array(),
|
163 |
-
filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
|
164 |
-
);
|
165 |
-
}
|
166 |
-
|
167 |
-
public function Footer() {
|
168 |
-
wp_enqueue_script('jquery');
|
169 |
-
wp_enqueue_script('suggest');
|
170 |
-
wp_enqueue_script(
|
171 |
-
'auditlog',
|
172 |
-
$this->_plugin->GetBaseUrl() . '/js/auditlog.js',
|
173 |
-
array(),
|
174 |
-
filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
|
175 |
-
);
|
176 |
-
}
|
177 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Views_AuditLog extends WSAL_AbstractView {
|
4 |
+
/**
|
5 |
+
* @var WSAL_AuditLogListView
|
6 |
+
*/
|
7 |
+
protected $_listview;
|
8 |
+
|
9 |
+
public function __construct(WpSecurityAuditLog $plugin) {
|
10 |
+
parent::__construct($plugin);
|
11 |
+
add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
|
12 |
+
add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
|
13 |
+
add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
|
14 |
+
add_action('wp_ajax_AjaxSearchSite', array($this, 'AjaxSearchSite'));
|
15 |
+
|
16 |
+
$this->RegisterNotice('notifications-extension');
|
17 |
+
}
|
18 |
+
|
19 |
+
public function HasPluginShortcutLink(){
|
20 |
+
return true;
|
21 |
+
}
|
22 |
+
|
23 |
+
public function GetTitle() {
|
24 |
+
return __('Audit Log Viewer', 'wp-security-audit-log');
|
25 |
+
}
|
26 |
+
|
27 |
+
public function GetIcon() {
|
28 |
+
return $this->_wpversion < 3.8
|
29 |
+
? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
|
30 |
+
: 'dashicons-welcome-view-site';
|
31 |
+
}
|
32 |
+
|
33 |
+
public function GetName() {
|
34 |
+
return __('Audit Log Viewer', 'wp-security-audit-log');
|
35 |
+
}
|
36 |
+
|
37 |
+
public function GetWeight(){
|
38 |
+
return 1;
|
39 |
+
}
|
40 |
+
|
41 |
+
protected function GetListView(){
|
42 |
+
if (is_null($this->_listview)) $this->_listview = new WSAL_AuditLogListView($this->_plugin);
|
43 |
+
return $this->_listview;
|
44 |
+
}
|
45 |
+
|
46 |
+
public function Render(){
|
47 |
+
if(!$this->_plugin->settings->CurrentUserCan('view')){
|
48 |
+
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
49 |
+
}
|
50 |
+
|
51 |
+
$this->GetListView()->prepare_items();
|
52 |
+
$occ = new WSAL_Models_Occurrence();
|
53 |
+
|
54 |
+
?><form id="audit-log-viewer" method="post">
|
55 |
+
<div id="audit-log-viewer-content">
|
56 |
+
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
57 |
+
<input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr(isset($_REQUEST['wsal-cbid']) ? $_REQUEST['wsal-cbid'] : '0'); ?>" />
|
58 |
+
<?php do_action('wsal_auditlog_before_view', $this->GetListView()); ?>
|
59 |
+
<?php $this->GetListView()->display(); ?>
|
60 |
+
<?php do_action('wsal_auditlog_after_view', $this->GetListView()); ?>
|
61 |
+
</div>
|
62 |
+
</form><?php
|
63 |
+
|
64 |
+
?><script type="text/javascript">
|
65 |
+
jQuery(document).ready(function(){
|
66 |
+
WsalAuditLogInit(<?php echo json_encode(array(
|
67 |
+
'ajaxurl' => admin_url('admin-ajax.php'),
|
68 |
+
'tr8n' => array(
|
69 |
+
'numofitems' => __('Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log'),
|
70 |
+
'searchback' => __('All Sites', 'wp-security-audit-log'),
|
71 |
+
'searchnone' => __('No Results', 'wp-security-audit-log'),
|
72 |
+
),
|
73 |
+
'autorefresh' => array(
|
74 |
+
'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
|
75 |
+
'token' => (int)$occ->Count(),
|
76 |
+
),
|
77 |
+
)); ?>);
|
78 |
+
});
|
79 |
+
</script><?php
|
80 |
+
}
|
81 |
+
|
82 |
+
public function AjaxInspector(){
|
83 |
+
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
84 |
+
die('Access Denied.');
|
85 |
+
if(!isset($_REQUEST['occurrence']))
|
86 |
+
die('Occurrence parameter expected.');
|
87 |
+
$occ = new WSAL_Models_Occurrence();
|
88 |
+
$occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
|
89 |
+
|
90 |
+
echo '<!DOCTYPE html><html><head>';
|
91 |
+
echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
|
92 |
+
echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
|
93 |
+
echo '<style type="text/css">';
|
94 |
+
echo 'html, body { margin: 0; padding: 0; }';
|
95 |
+
echo '.nice_r { position: absolute; padding: 8px; }';
|
96 |
+
echo '.nice_r a { overflow: visible; }';
|
97 |
+
echo '</style>';
|
98 |
+
echo '</head><body>';
|
99 |
+
$nicer = new WSAL_Nicer($occ->GetMetaArray());
|
100 |
+
$nicer->render();
|
101 |
+
echo '</body></html>';
|
102 |
+
die;
|
103 |
+
}
|
104 |
+
|
105 |
+
public function AjaxRefresh(){
|
106 |
+
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
107 |
+
die('Access Denied.');
|
108 |
+
if(!isset($_REQUEST['logcount']))
|
109 |
+
die('Log count parameter expected.');
|
110 |
+
|
111 |
+
$old = (int)$_REQUEST['logcount'];
|
112 |
+
$max = 40; // 40*500msec = 20sec
|
113 |
+
|
114 |
+
session_write_close(); // fixes session lock issue
|
115 |
+
|
116 |
+
do{
|
117 |
+
$occ = new WSAL_Models_Occurrence();
|
118 |
+
$new = $occ->Count();
|
119 |
+
usleep(500000); // 500msec
|
120 |
+
}while(($old == $new) && (--$max > 0));
|
121 |
+
|
122 |
+
echo $old == $new ? 'false' : $new;
|
123 |
+
die;
|
124 |
+
}
|
125 |
+
|
126 |
+
public function AjaxSetIpp(){
|
127 |
+
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
128 |
+
die('Access Denied.');
|
129 |
+
if(!isset($_REQUEST['count']))
|
130 |
+
die('Count parameter expected.');
|
131 |
+
$this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
|
132 |
+
die;
|
133 |
+
}
|
134 |
+
|
135 |
+
public function AjaxSearchSite(){
|
136 |
+
if(!$this->_plugin->settings->CurrentUserCan('view'))
|
137 |
+
die('Access Denied.');
|
138 |
+
if(!isset($_REQUEST['search']))
|
139 |
+
die('Search parameter expected.');
|
140 |
+
|
141 |
+
$grp1 = array();
|
142 |
+
$grp2 = array();
|
143 |
+
|
144 |
+
$search = $_REQUEST['search'];
|
145 |
+
|
146 |
+
foreach($this->GetListView()->get_sites() as $site){
|
147 |
+
if(stripos($site->blogname, $search) !== false)
|
148 |
+
$grp1[] = $site;
|
149 |
+
else
|
150 |
+
if(stripos($site->domain, $search) !== false)
|
151 |
+
$grp2[] = $site;
|
152 |
+
}
|
153 |
+
|
154 |
+
die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
|
155 |
+
}
|
156 |
+
|
157 |
+
public function Header(){
|
158 |
+
add_thickbox();
|
159 |
+
wp_enqueue_style(
|
160 |
+
'auditlog',
|
161 |
+
$this->_plugin->GetBaseUrl() . '/css/auditlog.css',
|
162 |
+
array(),
|
163 |
+
filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
|
164 |
+
);
|
165 |
+
}
|
166 |
+
|
167 |
+
public function Footer() {
|
168 |
+
wp_enqueue_script('jquery');
|
169 |
+
wp_enqueue_script('suggest');
|
170 |
+
wp_enqueue_script(
|
171 |
+
'auditlog',
|
172 |
+
$this->_plugin->GetBaseUrl() . '/js/auditlog.js',
|
173 |
+
array(),
|
174 |
+
filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
|
175 |
+
);
|
176 |
+
}
|
177 |
+
}
|
classes/Views/Help.php
CHANGED
@@ -1,77 +1,79 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Views_Help extends WSAL_AbstractView {
|
4 |
-
|
5 |
-
public function GetTitle() {
|
6 |
-
return __('Help', 'wp-security-audit-log');
|
7 |
-
}
|
8 |
-
|
9 |
-
public function GetIcon() {
|
10 |
-
return 'dashicons-sos';
|
11 |
-
}
|
12 |
-
|
13 |
-
public function GetName() {
|
14 |
-
return __('Help', 'wp-security-audit-log');
|
15 |
-
}
|
16 |
-
|
17 |
-
public function GetWeight() {
|
18 |
-
return 5;
|
19 |
-
}
|
20 |
-
|
21 |
-
public function Render(){
|
22 |
-
?><div class="metabox-holder" style="position: relative;">
|
23 |
-
|
24 |
-
<div class="postbox" style="margin-right: 270px;">
|
25 |
-
<div class="inside">
|
26 |
-
<div class="activity-block">
|
27 |
-
<h2><?php _e('Plugin Support', 'wp-security-audit-log'); ?></h2>
|
28 |
-
<p>
|
29 |
-
<?php _e('Have you encountered or noticed any issues while using WP Security Audit Log plugin?', 'wp-security-audit-log'); ?>
|
30 |
-
<?php _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'); ?>
|
31 |
-
</p><p>
|
32 |
-
<a class="button" href="https://wordpress.org/support/plugin/wp-security-audit-log" target="_blank"><?php _e('Free Support Forum', 'wp-security-audit-log'); ?></a>
|
33 |
-
|
34 |
-
<a class="button" href="http://www.wpsecurityauditlog.com/contact/" target="_blank"><?php _e('Free Support Email', 'wp-security-audit-log'); ?></a>
|
35 |
-
</p>
|
36 |
-
</div>
|
37 |
-
|
38 |
-
<div class="activity-block">
|
39 |
-
<h2><?php _e('Plugin Documentation', 'wp-security-audit-log'); ?></h2>
|
40 |
-
<p>
|
41 |
-
<?php _e('For more detailed information about WP Security Audit Log you can visit the plugin website.', 'wp-security-audit-log'); ?>
|
42 |
-
<?php _e('You can also visit the official list of WordPress Security Alerts for more information about all of the WordPress activity and changes you can monitor with WP Security Audit Log.', 'wp-security-audit-log'); ?>
|
43 |
-
</p><p>
|
44 |
-
<a class="button" href="http://www.wpsecurityauditlog.com/?utm_source=
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
<a class="button" href="http://www.wpwhitesecurity.com/
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
|
|
|
|
77 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Views_Help extends WSAL_AbstractView {
|
4 |
+
|
5 |
+
public function GetTitle() {
|
6 |
+
return __('Help', 'wp-security-audit-log');
|
7 |
+
}
|
8 |
+
|
9 |
+
public function GetIcon() {
|
10 |
+
return 'dashicons-sos';
|
11 |
+
}
|
12 |
+
|
13 |
+
public function GetName() {
|
14 |
+
return __('Help', 'wp-security-audit-log');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function GetWeight() {
|
18 |
+
return 5;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function Render(){
|
22 |
+
?><div class="metabox-holder" style="position: relative;">
|
23 |
+
|
24 |
+
<div class="postbox" style="margin-right: 270px;">
|
25 |
+
<div class="inside">
|
26 |
+
<div class="activity-block">
|
27 |
+
<h2><?php _e('Plugin Support', 'wp-security-audit-log'); ?></h2>
|
28 |
+
<p>
|
29 |
+
<?php _e('Have you encountered or noticed any issues while using WP Security Audit Log plugin?', 'wp-security-audit-log'); ?>
|
30 |
+
<?php _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'); ?>
|
31 |
+
</p><p>
|
32 |
+
<a class="button" href="https://wordpress.org/support/plugin/wp-security-audit-log" target="_blank"><?php _e('Free Support Forum', 'wp-security-audit-log'); ?></a>
|
33 |
+
|
34 |
+
<a class="button" href="http://www.wpsecurityauditlog.com/contact/" target="_blank"><?php _e('Free Support Email', 'wp-security-audit-log'); ?></a>
|
35 |
+
</p>
|
36 |
+
</div>
|
37 |
+
|
38 |
+
<div class="activity-block">
|
39 |
+
<h2><?php _e('Plugin Documentation', 'wp-security-audit-log'); ?></h2>
|
40 |
+
<p>
|
41 |
+
<?php _e('For more detailed information about WP Security Audit Log you can visit the plugin website.', 'wp-security-audit-log'); ?>
|
42 |
+
<?php _e('You can also visit the official list of WordPress Security Alerts for more information about all of the WordPress activity and changes you can monitor with WP Security Audit Log.', 'wp-security-audit-log'); ?>
|
43 |
+
</p><p>
|
44 |
+
<a class="button" href="http://www.wpsecurityauditlog.com/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
|
45 |
+
|
46 |
+
<a class="button" href="https://www.wpsecurityauditlog.com/documentation/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('Plugin Documenation', 'wp-security-audit-log'); ?></a>
|
47 |
+
|
48 |
+
<a class="button" href="https://www.wpsecurityauditlog.com/documentation/frequently-asked-questions-faqs/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('FAQs', 'wp-security-audit-log'); ?></a>
|
49 |
+
|
50 |
+
<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 _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
|
51 |
+
</p>
|
52 |
+
</div>
|
53 |
+
|
54 |
+
<div class="">
|
55 |
+
<h2><?php _e('Keep Yourself Up-to-Date with WordPress Security', 'wp-security-audit-log'); ?></h2>
|
56 |
+
<p>
|
57 |
+
<?php _e('Keep yourself informed with what is happening in the WordPress security ecosystem, which are the new vulnerabilities, which plugins you need to update and what are the latest WordPress security hacks so you can stay one step ahead of the hackers.', 'wp-security-audit-log'); ?>
|
58 |
+
</p>
|
59 |
+
<a class="button" href="http://www.wpwhitesecurity.com/blog/" target="_blank"><?php _e('Read the WP White Security Blog', 'wp-security-audit-log'); ?></a>
|
60 |
+
|
61 |
+
<a class="button" href="http://www.wpsecuritybloggers.com" target="_blank"><?php _e('Subscribe to WP Security Bloggers (An Aggregate of WordPress Security Blogs)', 'wp-security-audit-log'); ?></a>
|
62 |
+
</div>
|
63 |
+
</div>
|
64 |
+
</div>
|
65 |
+
|
66 |
+
<div style="position: absolute; right: 70px; width: 180px; top: 10px;">
|
67 |
+
<div class="postbox">
|
68 |
+
<h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
|
69 |
+
<div class="inside">
|
70 |
+
<?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
|
71 |
+
<a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
|
72 |
+
</div>
|
73 |
+
</div>
|
74 |
+
</div>
|
75 |
+
|
76 |
+
</div><?php
|
77 |
+
}
|
78 |
+
|
79 |
}
|
classes/Views/Licensing.php
CHANGED
@@ -1,88 +1,88 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_Views_Licensing extends WSAL_AbstractView {
|
4 |
-
|
5 |
-
public function GetTitle() {
|
6 |
-
return __('Licensing', 'wp-security-audit-log');
|
7 |
-
}
|
8 |
-
|
9 |
-
public function GetIcon() {
|
10 |
-
return 'dashicons-cart';
|
11 |
-
}
|
12 |
-
|
13 |
-
public function GetName() {
|
14 |
-
return __('Licensing', 'wp-security-audit-log');
|
15 |
-
}
|
16 |
-
|
17 |
-
public function GetWeight() {
|
18 |
-
return 4;
|
19 |
-
}
|
20 |
-
|
21 |
-
public function IsAccessible(){
|
22 |
-
return !!$this->_plugin->licensing->CountPlugins();
|
23 |
-
}
|
24 |
-
|
25 |
-
protected function Save(){
|
26 |
-
$this->_plugin->settings->ClearLicenses();
|
27 |
-
if (isset($_REQUEST['license']))
|
28 |
-
foreach ($_REQUEST['license'] as $name => $key)
|
29 |
-
$this->_plugin->licensing->ActivateLicense($name, $key);
|
30 |
-
}
|
31 |
-
|
32 |
-
public function Render(){
|
33 |
-
if(!$this->_plugin->settings->CurrentUserCan('edit')){
|
34 |
-
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
35 |
-
}
|
36 |
-
if(isset($_POST['submit'])){
|
37 |
-
try {
|
38 |
-
$this->Save();
|
39 |
-
?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
|
40 |
-
}catch(Exception $ex){
|
41 |
-
?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
|
42 |
-
}
|
43 |
-
}
|
44 |
-
?><form id="audit-log-licensing" method="post">
|
45 |
-
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
46 |
-
|
47 |
-
<table class="wp-list-table widefat fixed">
|
48 |
-
<thead>
|
49 |
-
<tr><th>Plugin</th><th>License</th><th></th></tr>
|
50 |
-
</thead><tbody>
|
51 |
-
<?php $counter = 0; ?>
|
52 |
-
<?php foreach($this->_plugin->licensing->Plugins() as $name => $plugin){ ?>
|
53 |
-
<?php $licenseKey = trim($this->_plugin->settings->GetLicenseKey($name)); ?>
|
54 |
-
<?php $licenseStatus = trim($this->_plugin->settings->GetLicenseStatus($name)); ?>
|
55 |
-
<?php $licenseErrors = trim($this->_plugin->settings->GetLicenseErrors($name)); ?>
|
56 |
-
<tr class="<?php echo ($counter++ % 2 === 0) ? 'alternate' : ''; ?>">
|
57 |
-
<td>
|
58 |
-
<a href="<?php echo esc_attr($plugin['PluginData']['PluginURI']); ?>" target="_blank">
|
59 |
-
<?php echo esc_html($plugin['PluginData']['Name']); ?>
|
60 |
-
</a><br/><small><b>
|
61 |
-
<?php _e('Version', 'wp-security-audit-log'); ?>
|
62 |
-
<?php echo esc_html($plugin['PluginData']['Version']); ?>
|
63 |
-
</b></small>
|
64 |
-
</td><td>
|
65 |
-
<input type="text" style="width: 360px; margin: 6px 0;"
|
66 |
-
name="license[<?php echo esc_attr($name); ?>]"
|
67 |
-
value="<?php echo esc_attr($licenseKey); ?>"/>
|
68 |
-
</td><td style="vertical-align: middle;">
|
69 |
-
<?php if($licenseKey){ ?>
|
70 |
-
<?php if($licenseStatus === 'valid'){ ?>
|
71 |
-
<?php _e('Active', 'wp-security-audit-log'); ?>
|
72 |
-
<?php }else{ ?>
|
73 |
-
<?php _e('Inactive', 'wp-security-audit-log'); ?><br/>
|
74 |
-
<small><?php echo esc_html($licenseErrors); ?></small>
|
75 |
-
<?php } ?>
|
76 |
-
<?php } ?>
|
77 |
-
</td>
|
78 |
-
</tr>
|
79 |
-
<?php } ?>
|
80 |
-
</tbody><tfoot>
|
81 |
-
<tr><th>Plugin</th><th>License</th><th></th></tr>
|
82 |
-
</tfoot>
|
83 |
-
</table>
|
84 |
-
<?php submit_button(); ?>
|
85 |
-
</form><?php
|
86 |
-
}
|
87 |
-
|
88 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_Views_Licensing extends WSAL_AbstractView {
|
4 |
+
|
5 |
+
public function GetTitle() {
|
6 |
+
return __('Licensing', 'wp-security-audit-log');
|
7 |
+
}
|
8 |
+
|
9 |
+
public function GetIcon() {
|
10 |
+
return 'dashicons-cart';
|
11 |
+
}
|
12 |
+
|
13 |
+
public function GetName() {
|
14 |
+
return __('Licensing', 'wp-security-audit-log');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function GetWeight() {
|
18 |
+
return 4;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function IsAccessible(){
|
22 |
+
return !!$this->_plugin->licensing->CountPlugins();
|
23 |
+
}
|
24 |
+
|
25 |
+
protected function Save(){
|
26 |
+
$this->_plugin->settings->ClearLicenses();
|
27 |
+
if (isset($_REQUEST['license']))
|
28 |
+
foreach ($_REQUEST['license'] as $name => $key)
|
29 |
+
$this->_plugin->licensing->ActivateLicense($name, $key);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function Render(){
|
33 |
+
if(!$this->_plugin->settings->CurrentUserCan('edit')){
|
34 |
+
wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
|
35 |
+
}
|
36 |
+
if(isset($_POST['submit'])){
|
37 |
+
try {
|
38 |
+
$this->Save();
|
39 |
+
?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
|
40 |
+
}catch(Exception $ex){
|
41 |
+
?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
|
42 |
+
}
|
43 |
+
}
|
44 |
+
?><form id="audit-log-licensing" method="post">
|
45 |
+
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
46 |
+
|
47 |
+
<table class="wp-list-table widefat fixed">
|
48 |
+
<thead>
|
49 |
+
<tr><th>Plugin</th><th>License</th><th></th></tr>
|
50 |
+
</thead><tbody>
|
51 |
+
<?php $counter = 0; ?>
|
52 |
+
<?php foreach($this->_plugin->licensing->Plugins() as $name => $plugin){ ?>
|
53 |
+
<?php $licenseKey = trim($this->_plugin->settings->GetLicenseKey($name)); ?>
|
54 |
+
<?php $licenseStatus = trim($this->_plugin->settings->GetLicenseStatus($name)); ?>
|
55 |
+
<?php $licenseErrors = trim($this->_plugin->settings->GetLicenseErrors($name)); ?>
|
56 |
+
<tr class="<?php echo ($counter++ % 2 === 0) ? 'alternate' : ''; ?>">
|
57 |
+
<td>
|
58 |
+
<a href="<?php echo esc_attr($plugin['PluginData']['PluginURI']); ?>" target="_blank">
|
59 |
+
<?php echo esc_html($plugin['PluginData']['Name']); ?>
|
60 |
+
</a><br/><small><b>
|
61 |
+
<?php _e('Version', 'wp-security-audit-log'); ?>
|
62 |
+
<?php echo esc_html($plugin['PluginData']['Version']); ?>
|
63 |
+
</b></small>
|
64 |
+
</td><td>
|
65 |
+
<input type="text" style="width: 360px; margin: 6px 0;"
|
66 |
+
name="license[<?php echo esc_attr($name); ?>]"
|
67 |
+
value="<?php echo esc_attr($licenseKey); ?>"/>
|
68 |
+
</td><td style="vertical-align: middle;">
|
69 |
+
<?php if($licenseKey){ ?>
|
70 |
+
<?php if($licenseStatus === 'valid'){ ?>
|
71 |
+
<?php _e('Active', 'wp-security-audit-log'); ?>
|
72 |
+
<?php }else{ ?>
|
73 |
+
<?php _e('Inactive', 'wp-security-audit-log'); ?><br/>
|
74 |
+
<small><?php echo esc_html($licenseErrors); ?></small>
|
75 |
+
<?php } ?>
|
76 |
+
<?php } ?>
|
77 |
+
</td>
|
78 |
+
</tr>
|
79 |
+
<?php } ?>
|
80 |
+
</tbody><tfoot>
|
81 |
+
<tr><th>Plugin</th><th>License</th><th></th></tr>
|
82 |
+
</tfoot>
|
83 |
+
</table>
|
84 |
+
<?php submit_button(); ?>
|
85 |
+
</form><?php
|
86 |
+
}
|
87 |
+
|
88 |
}
|
classes/Views/Settings.php
CHANGED
@@ -1,682 +1,682 @@
|
|
1 |
-
<?php
|
2 |
-
class WSAL_Views_Settings extends WSAL_AbstractView
|
3 |
-
{
|
4 |
-
|
5 |
-
public $adapterMsg = '';
|
6 |
-
|
7 |
-
public function __construct(WpSecurityAuditLog $plugin)
|
8 |
-
{
|
9 |
-
parent::__construct($plugin);
|
10 |
-
|
11 |
-
add_action('wp_ajax_AjaxCheckSecurityToken', array($this, 'AjaxCheckSecurityToken'));
|
12 |
-
add_action('wp_ajax_AjaxRunCleanup', array($this, 'AjaxRunCleanup'));
|
13 |
-
add_action('wp_ajax_AjaxGetAllUsers', array($this, 'AjaxGetAllUsers'));
|
14 |
-
add_action('wp_ajax_AjaxGetAllRoles', array($this, 'AjaxGetAllRoles'));
|
15 |
-
}
|
16 |
-
|
17 |
-
public function HasPluginShortcutLink(){
|
18 |
-
return true;
|
19 |
-
}
|
20 |
-
|
21 |
-
public function GetTitle() {
|
22 |
-
return __('Settings', 'wp-security-audit-log');
|
23 |
-
}
|
24 |
-
|
25 |
-
public function GetIcon() {
|
26 |
-
return 'dashicons-admin-generic';
|
27 |
-
}
|
28 |
-
|
29 |
-
public function GetName() {
|
30 |
-
return __('Settings', 'wp-security-audit-log');
|
31 |
-
}
|
32 |
-
|
33 |
-
public function GetWeight() {
|
34 |
-
return 3;
|
35 |
-
}
|
36 |
-
|
37 |
-
protected function GetTokenType($token){
|
38 |
-
$users = array();
|
39 |
-
foreach (get_users('blog_id=0&fields[]=user_login') as $obj)
|
40 |
-
$users[] = $obj->user_login;
|
41 |
-
$roles = array_keys(get_editable_roles());
|
42 |
-
|
43 |
-
if(in_array($token, $users))return 'user';
|
44 |
-
if(in_array($token, $roles))return 'role';
|
45 |
-
return 'other';
|
46 |
-
}
|
47 |
-
|
48 |
-
protected function Save()
|
49 |
-
{
|
50 |
-
check_admin_referer('wsal-settings');
|
51 |
-
$this->_plugin->settings->SetPruningDateEnabled($_REQUEST['PruneBy'] == 'date');
|
52 |
-
$this->_plugin->settings->SetPruningDate($_REQUEST['PruningDate']);
|
53 |
-
$this->_plugin->settings->SetPruningLimitEnabled($_REQUEST['PruneBy'] == 'limit');
|
54 |
-
$this->_plugin->settings->SetPruningLimit($_REQUEST['PruningLimit']);
|
55 |
-
$this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
|
56 |
-
$this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
|
57 |
-
$this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
|
58 |
-
|
59 |
-
$this->_plugin->settings->SetExcludedMonitoringUsers(isset($_REQUEST['ExUsers']) ? $_REQUEST['ExUsers'] : array());
|
60 |
-
$this->_plugin->settings->SetExcludedMonitoringRoles(isset($_REQUEST['ExRoles']) ? $_REQUEST['ExRoles'] : array());
|
61 |
-
$this->_plugin->settings->SetExcludedMonitoringCustom(isset($_REQUEST['Customs']) ? $_REQUEST['Customs'] : array());
|
62 |
-
$this->_plugin->settings->SetExcludedMonitoringIP(isset($_REQUEST['IpAddrs']) ? $_REQUEST['IpAddrs'] : array());
|
63 |
-
|
64 |
-
$this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
|
65 |
-
$this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
|
66 |
-
$this->_plugin->settings->SetMainIPFromProxy(isset($_REQUEST['EnableProxyIpCapture']));
|
67 |
-
$this->_plugin->settings->SetInternalIPsFiltering(isset($_REQUEST['EnableIpFiltering']));
|
68 |
-
$this->_plugin->settings->SetIncognito(isset($_REQUEST['Incognito']));
|
69 |
-
$this->_plugin->settings->SetDeleteData(isset($_REQUEST['DeleteData']));
|
70 |
-
$this->_plugin->settings->SetDatetimeFormat($_REQUEST['DatetimeFormat']);
|
71 |
-
$this->_plugin->settings->SetTimezone($_REQUEST['Timezone']);
|
72 |
-
$this->_plugin->settings->SetWPBackend(isset($_REQUEST['WPBackend']));
|
73 |
-
if (!empty($_REQUEST['Columns'])) {
|
74 |
-
$this->_plugin->settings->SetColumns($_REQUEST['Columns']);
|
75 |
-
}
|
76 |
-
$this->_plugin->settings->ClearDevOptions();
|
77 |
-
|
78 |
-
if (isset($_REQUEST['DevOptions'])) {
|
79 |
-
foreach ($_REQUEST['DevOptions'] as $opt) {
|
80 |
-
$this->_plugin->settings->SetDevOptionEnabled($opt, true);
|
81 |
-
}
|
82 |
-
}
|
83 |
-
|
84 |
-
// Database Adapter Settings
|
85 |
-
// Temporarily not used
|
86 |
-
/* Check Adapter config */
|
87 |
-
if (!empty($_REQUEST["AdapterUser"]) && ($_REQUEST['AdapterUser'] != '') && ($_REQUEST['AdapterName'] != '') && ($_REQUEST['AdapterHostname'] != '')) {
|
88 |
-
WSAL_Connector_ConnectorFactory::CheckConfig(
|
89 |
-
trim($_REQUEST['AdapterType']),
|
90 |
-
trim($_REQUEST['AdapterUser']),
|
91 |
-
trim($_REQUEST['AdapterPassword']),
|
92 |
-
trim($_REQUEST['AdapterName']),
|
93 |
-
trim($_REQUEST['AdapterHostname']),
|
94 |
-
trim($_REQUEST['AdapterBasePrefix'])
|
95 |
-
);
|
96 |
-
|
97 |
-
/* Setting Adapter config */
|
98 |
-
$this->_plugin->settings->SetAdapterConfig('adapter-type', $_REQUEST['AdapterType']);
|
99 |
-
$this->_plugin->settings->SetAdapterConfig('adapter-user', $_REQUEST['AdapterUser']);
|
100 |
-
$this->_plugin->settings->SetAdapterConfig('adapter-password', $_REQUEST['AdapterPassword']);
|
101 |
-
$this->_plugin->settings->SetAdapterConfig('adapter-name', $_REQUEST['AdapterName']);
|
102 |
-
$this->_plugin->settings->SetAdapterConfig('adapter-hostname', $_REQUEST['AdapterHostname']);
|
103 |
-
$this->_plugin->settings->SetAdapterConfig('adapter-base-prefix', $_REQUEST['AdapterBasePrefix']);
|
104 |
-
}
|
105 |
-
}
|
106 |
-
|
107 |
-
public function AjaxCheckSecurityToken()
|
108 |
-
{
|
109 |
-
if (!$this->_plugin->settings->CurrentUserCan('view'))
|
110 |
-
die('Access Denied.');
|
111 |
-
if (!isset($_REQUEST['token']))
|
112 |
-
die('Token parameter expected.');
|
113 |
-
die($this->GetTokenType($_REQUEST['token']));
|
114 |
-
}
|
115 |
-
|
116 |
-
public function AjaxRunCleanup()
|
117 |
-
{
|
118 |
-
if (!$this->_plugin->settings->CurrentUserCan('view'))
|
119 |
-
die('Access Denied.');
|
120 |
-
$this->_plugin->CleanUp();
|
121 |
-
wp_redirect($this->GetUrl());
|
122 |
-
exit;
|
123 |
-
}
|
124 |
-
|
125 |
-
public function Render()
|
126 |
-
{
|
127 |
-
if (!$this->_plugin->settings->CurrentUserCan('edit')) {
|
128 |
-
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-security-audit-log'));
|
129 |
-
}
|
130 |
-
if (isset($_POST['submit'])) {
|
131 |
-
try {
|
132 |
-
$this->Save();
|
133 |
-
?><div class="updated">
|
134 |
-
<p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p>
|
135 |
-
</div><?php
|
136 |
-
} catch (Exception $ex) {
|
137 |
-
?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
|
138 |
-
}
|
139 |
-
}
|
140 |
-
?>
|
141 |
-
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
142 |
-
<a href="#tab-general" class="nav-tab">General</a>
|
143 |
-
<a href="#tab-exclude" class="nav-tab">Exclude Objects</a>
|
144 |
-
<!--<a href="#adapter" class="nav-tab">Data Storage Adapter</a>-->
|
145 |
-
</h2>
|
146 |
-
<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"/></script>
|
147 |
-
<form id="audit-log-settings" method="post">
|
148 |
-
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
149 |
-
<input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
|
150 |
-
<?php wp_nonce_field('wsal-settings'); ?>
|
151 |
-
|
152 |
-
<div id="audit-log-adverts">
|
153 |
-
<a href="http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=settingspage&utm_campaign=notifications">
|
154 |
-
<img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/notifications_250x150.gif" width="250" height="150" alt=""/>
|
155 |
-
</a>
|
156 |
-
<a href="http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=settingspage&utm_campaign=search">
|
157 |
-
<img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/search_250x150.gif" width="250" height="150" alt=""/>
|
158 |
-
</a>
|
159 |
-
<a href="http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=settingspage&utm_campaign=reports">
|
160 |
-
<img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/reporting_250x150.gif" width="250" height="150" alt=""/>
|
161 |
-
</a>
|
162 |
-
</div>
|
163 |
-
<div class="nav-tabs">
|
164 |
-
<table class="form-table wsal-tab widefat" id="tab-general">
|
165 |
-
<tbody>
|
166 |
-
<tr>
|
167 |
-
<th><label for="delete1"><?php _e('Security Alerts Pruning', 'wp-security-audit-log'); ?></label></th>
|
168 |
-
<td>
|
169 |
-
<fieldset>
|
170 |
-
<?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
|
171 |
-
<?php $nbld = !($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
|
172 |
-
<label for="delete0">
|
173 |
-
<input type="radio" id="delete0" name="PruneBy" value="" <?php if($nbld)echo 'checked="checked"'; ?>/>
|
174 |
-
<?php echo __('None', 'wp-security-audit-log'); ?>
|
175 |
-
</label>
|
176 |
-
</fieldset>
|
177 |
-
<fieldset>
|
178 |
-
<?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
|
179 |
-
<?php $nbld = $this->_plugin->settings->IsPruningDateEnabled(); ?>
|
180 |
-
<label for="delete1">
|
181 |
-
<input type="radio" id="delete1" name="PruneBy" value="date" <?php if($nbld)echo 'checked="checked"'; ?>/>
|
182 |
-
<?php echo __('Delete alerts older than', 'wp-security-audit-log'); ?>
|
183 |
-
</label>
|
184 |
-
<input type="text" id="PruningDate" name="PruningDate" placeholder="<?php echo $text; ?>"
|
185 |
-
value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"
|
186 |
-
onfocus="jQuery('#delete1').attr('checked', true);"/>
|
187 |
-
<span> <?php echo $text; ?></span>
|
188 |
-
</fieldset>
|
189 |
-
<fieldset>
|
190 |
-
<?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
|
191 |
-
<?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
|
192 |
-
<label for="delete2">
|
193 |
-
<input type="radio" id="delete2" name="PruneBy" value="limit" <?php if($nbld)echo 'checked="checked"'; ?>/>
|
194 |
-
<?php echo __('Keep up to', 'wp-security-audit-log'); ?>
|
195 |
-
</label>
|
196 |
-
<input type="text" id="PruningLimit" name="PruningLimit" placeholder="<?php echo $text;?>"
|
197 |
-
value="<?php echo esc_attr($this->_plugin->settings->GetPruningLimit()); ?>"
|
198 |
-
onfocus="jQuery('#delete2').attr('checked', true);"/>
|
199 |
-
<?php echo __('alerts', 'wp-security-audit-log'); ?>
|
200 |
-
<span><?php echo $text; ?></span>
|
201 |
-
</fieldset>
|
202 |
-
<p class="description"><?php
|
203 |
-
echo __('Next Scheduled Cleanup is in ', 'wp-security-audit-log');
|
204 |
-
echo human_time_diff(current_time('timestamp'), $next = wp_next_scheduled('wsal_cleanup'));
|
205 |
-
echo '<!-- ' . date('dMy H:i:s', $next) . ' --> ';
|
206 |
-
echo sprintf(
|
207 |
-
__('(or %s)', 'wp-security-audit-log'),
|
208 |
-
'<a href="' . admin_url('admin-ajax.php?action=AjaxRunCleanup') . '">' . __('Run Manually', 'wp-security-audit-log') . '</a>'
|
209 |
-
);
|
210 |
-
?></p>
|
211 |
-
</td>
|
212 |
-
</tr>
|
213 |
-
<tr>
|
214 |
-
<th><label for="dwoption_on"><?php _e('Alerts Dashboard Widget', 'wp-security-audit-log'); ?></label></th>
|
215 |
-
<td>
|
216 |
-
<fieldset>
|
217 |
-
<?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
|
218 |
-
<label for="dwoption_on">
|
219 |
-
<input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php if($dwe)echo 'checked="checked"'; ?> value="1">
|
220 |
-
<span><?php _e('On', 'wp-security-audit-log'); ?></span>
|
221 |
-
</label>
|
222 |
-
<br/>
|
223 |
-
<label for="dwoption_off">
|
224 |
-
<input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php if(!$dwe)echo 'checked="checked"'; ?> value="0">
|
225 |
-
<span><?php _e('Off', 'wp-security-audit-log'); ?></span>
|
226 |
-
</label>
|
227 |
-
<br/>
|
228 |
-
<p class="description"><?php
|
229 |
-
echo sprintf(
|
230 |
-
__('Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log'),
|
231 |
-
$this->_plugin->settings->GetDashboardWidgetMaxAlerts()
|
232 |
-
);
|
233 |
-
?></p>
|
234 |
-
</fieldset>
|
235 |
-
</td>
|
236 |
-
</tr>
|
237 |
-
<tr>
|
238 |
-
<th><label for="pioption_on"><?php _e('Reverse Proxy / Firewall Options', 'wp-security-audit-log'); ?></label></th>
|
239 |
-
<td>
|
240 |
-
<fieldset>
|
241 |
-
<label for="EnableProxyIpCapture">
|
242 |
-
<input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
|
243 |
-
if($this->_plugin->settings->IsMainIPFromProxy())echo ' checked="checked"';
|
244 |
-
?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?><br/>
|
245 |
-
<span class="description"><?php _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>
|
246 |
-
</label>
|
247 |
-
<br/>
|
248 |
-
<label for="EnableIpFiltering">
|
249 |
-
<input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
|
250 |
-
if($this->_plugin->settings->IsInternalIPsFiltered())echo ' checked="checked"';
|
251 |
-
?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?><br/>
|
252 |
-
<span class="description"><?php _e('Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log'); ?></span>
|
253 |
-
</label>
|
254 |
-
</fieldset>
|
255 |
-
</td>
|
256 |
-
</tr>
|
257 |
-
<tr>
|
258 |
-
<th><label for="ViewerQueryBox"><?php _e('Can View Alerts', 'wp-security-audit-log'); ?></label></th>
|
259 |
-
<td>
|
260 |
-
<fieldset>
|
261 |
-
<input type="text" id="ViewerQueryBox" style="float: left; display: block; width: 250px;">
|
262 |
-
<input type="button" id="ViewerQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
263 |
-
<br style="clear: both;"/>
|
264 |
-
<p class="description"><?php
|
265 |
-
_e('Users and Roles in this list can view the security alerts', 'wp-security-audit-log');
|
266 |
-
?></p>
|
267 |
-
<div id="ViewerList"><?php
|
268 |
-
foreach($this->_plugin->settings->GetAllowedPluginViewers() as $item){
|
269 |
-
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
270 |
-
<input type="hidden" name="Viewers[]" value="<?php echo esc_attr($item); ?>"/>
|
271 |
-
<?php echo esc_html($item); ?>
|
272 |
-
<a href="javascript:;" title="Remove">×</a>
|
273 |
-
</span><?php
|
274 |
-
}
|
275 |
-
?></div>
|
276 |
-
</fieldset>
|
277 |
-
</td>
|
278 |
-
</tr>
|
279 |
-
<tr>
|
280 |
-
<th><label for="EditorQueryBox"><?php _e('Can Manage Plugin', 'wp-security-audit-log'); ?></label></th>
|
281 |
-
<td>
|
282 |
-
<fieldset>
|
283 |
-
<input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
|
284 |
-
<input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
285 |
-
<br style="clear: both;"/>
|
286 |
-
<p class="description"><?php
|
287 |
-
_e('Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log');
|
288 |
-
?></p>
|
289 |
-
<div id="EditorList"><?php
|
290 |
-
foreach($this->_plugin->settings->GetAllowedPluginEditors() as $item){
|
291 |
-
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
292 |
-
<input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
|
293 |
-
<?php echo esc_html($item); ?>
|
294 |
-
<a href="javascript:;" title="Remove">×</a>
|
295 |
-
</span><?php
|
296 |
-
}
|
297 |
-
?></div>
|
298 |
-
</fieldset>
|
299 |
-
</td>
|
300 |
-
</tr>
|
301 |
-
<tr>
|
302 |
-
<th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
|
303 |
-
<td>
|
304 |
-
<fieldset>
|
305 |
-
<input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
|
306 |
-
<label for="RestrictAdmins">
|
307 |
-
<?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
|
308 |
-
<input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
|
309 |
-
<span class="description">
|
310 |
-
<?php _e('By default all the administrators on this WordPress have access to manage this plugin.<br/>By enabling this option only the users specified in the two options above and your username will have access to view alerts and manage this plugin.', 'wp-security-audit-log'); ?>
|
311 |
-
</span>
|
312 |
-
</label>
|
313 |
-
</fieldset>
|
314 |
-
</td>
|
315 |
-
</tr>
|
316 |
-
<tr>
|
317 |
-
<th><label for="aroption_on"><?php _e('Refresh Audit Log Viewer', 'wp-security-audit-log'); ?></label></th>
|
318 |
-
<td>
|
319 |
-
<fieldset>
|
320 |
-
<?php $are = $this->_plugin->settings->IsRefreshAlertsEnabled(); ?>
|
321 |
-
<label for="aroption_on">
|
322 |
-
<input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: 2px;" <?php if($are)echo 'checked="checked"'; ?> value="1">
|
323 |
-
<span><?php _e('Automatic', 'wp-security-audit-log'); ?></span>
|
324 |
-
</label>
|
325 |
-
<span class="description"> — <?php _e('Refresh Audit Log Viewer as soon as there are new alerts.', 'wp-security-audit-log'); ?></span>
|
326 |
-
<br/>
|
327 |
-
<label for="aroption_off">
|
328 |
-
<input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: 2px;" <?php if(!$are)echo 'checked="checked"'; ?> value="0">
|
329 |
-
<span><?php _e('Manual', 'wp-security-audit-log'); ?></span>
|
330 |
-
</label>
|
331 |
-
<span class="description"> — <?php _e('Refresh Audit Log Viewer only when the page is reloaded.', 'wp-security-audit-log'); ?></span>
|
332 |
-
<br/>
|
333 |
-
</fieldset>
|
334 |
-
</td>
|
335 |
-
</tr>
|
336 |
-
<tr>
|
337 |
-
<th><label for="datetime_format_24"><?php _e('Alerts Time Format', 'wp-security-audit-log'); ?></label></th>
|
338 |
-
<td>
|
339 |
-
<fieldset>
|
340 |
-
<?php $datetime = $this->_plugin->settings->GetDatetimeFormat(); ?>
|
341 |
-
<label for="datetime_format_24">
|
342 |
-
<input type="radio" name="DatetimeFormat" id="datetime_format_24" style="margin-top: 2px;" <?php if($datetime)echo 'checked="checked"'; ?> value="1">
|
343 |
-
<span><?php _e('24 hours', 'wp-security-audit-log'); ?></span>
|
344 |
-
</label>
|
345 |
-
<br/>
|
346 |
-
<label for="datetime_format_default">
|
347 |
-
<input type="radio" name="DatetimeFormat" id="datetime_format_default" style="margin-top: 2px;" <?php if(!$datetime)echo 'checked="checked"'; ?> value="0">
|
348 |
-
<span><?php _e('AM/PM', 'wp-security-audit-log'); ?></span>
|
349 |
-
</label>
|
350 |
-
<br/>
|
351 |
-
</fieldset>
|
352 |
-
</td>
|
353 |
-
</tr>
|
354 |
-
<tr>
|
355 |
-
<th><label for="timezone-default"><?php _e('Alerts Timestamp', 'wp-security-audit-log'); ?></label></th>
|
356 |
-
<td>
|
357 |
-
<fieldset>
|
358 |
-
<?php $timezone = $this->_plugin->settings->GetTimezone(); ?>
|
359 |
-
<label for="timezone-default">
|
360 |
-
<input type="radio" name="Timezone" id="timezone-default" style="margin-top: 2px;" <?php if(!$timezone)echo 'checked="checked"'; ?> value="0">
|
361 |
-
<span><?php _e('UTC', 'wp-security-audit-log'); ?></span>
|
362 |
-
</label>
|
363 |
-
<br/>
|
364 |
-
<label for="timezone">
|
365 |
-
<input type="radio" name="Timezone" id="timezone" style="margin-top: 2px;" <?php if($timezone)echo 'checked="checked"'; ?> value="1">
|
366 |
-
<span><?php _e('WordPress\' timezone', 'wp-security-audit-log'); ?></span>
|
367 |
-
</label>
|
368 |
-
<br/>
|
369 |
-
<span class="description"><?php _e('Select which timestamp should the alerts have in the Audit Log viewer. Note that the WordPress\' timezone might be different from that of the server.', 'wp-security-audit-log'); ?></span>
|
370 |
-
</fieldset>
|
371 |
-
</td>
|
372 |
-
</tr>
|
373 |
-
<tr>
|
374 |
-
<th><label for="columns"><?php _e('Audit Log Columns Selection', 'wp-security-audit-log'); ?></label></th>
|
375 |
-
<td>
|
376 |
-
<fieldset>
|
377 |
-
<?php $columns = $this->_plugin->settings->GetColumns(); ?>
|
378 |
-
<?php foreach ($columns as $key => $value) { ?>
|
379 |
-
<label for="columns">
|
380 |
-
<input type="checkbox" name="Columns[<?php echo $key; ?>]" id="<?php echo $key; ?>" class="sel-columns" style="margin-top: 2px;" <?php if ($value == '1') echo 'checked="checked"'; ?> value="1">
|
381 |
-
<span><?php echo ucwords(str_replace("_", " ", $key)); ?></span>
|
382 |
-
</label>
|
383 |
-
<br/>
|
384 |
-
<?php } ?>
|
385 |
-
<span class="description"><?php _e('When you disable any of the above such details won’t be shown in the Audit Log
|
386 |
-
viewer though the plugin will still record such information in the database.', 'wp-security-audit-log'); ?></span>
|
387 |
-
</fieldset>
|
388 |
-
</td>
|
389 |
-
</tr>
|
390 |
-
<tr>
|
391 |
-
<th><label><?php _e('Developer Options', 'wp-security-audit-log'); ?></label></th>
|
392 |
-
<td>
|
393 |
-
<fieldset>
|
394 |
-
<?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
|
395 |
-
<a href="javascript:;" style="<?php if($any)echo 'display: none;'; ?>"
|
396 |
-
onclick="jQuery(this).hide().next().show();">Show Developer Options</a>
|
397 |
-
<div style="<?php if(!$any)echo 'display: none;'; ?>">
|
398 |
-
<p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;"><?php
|
399 |
-
_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');
|
400 |
-
?></p><?php
|
401 |
-
foreach (array(
|
402 |
-
WSAL_Settings::OPT_DEV_DATA_INSPECTOR => array(
|
403 |
-
__('Data Inspector', 'wp-security-audit-log'),
|
404 |
-
__('View data logged for each triggered alert.', 'wp-security-audit-log')
|
405 |
-
),
|
406 |
-
WSAL_Settings::OPT_DEV_PHP_ERRORS => array(
|
407 |
-
__('PHP Errors', 'wp-security-audit-log'),
|
408 |
-
__('Enables sensor for alerts generated from PHP.', 'wp-security-audit-log')
|
409 |
-
),
|
410 |
-
WSAL_Settings::OPT_DEV_REQUEST_LOG => array(
|
411 |
-
__('Request Log', 'wp-security-audit-log'),
|
412 |
-
__('Enables logging request to file.', 'wp-security-audit-log')
|
413 |
-
),
|
414 |
-
WSAL_Settings::OPT_DEV_BACKTRACE_LOG => array(
|
415 |
-
__('Backtrace', 'wp-security-audit-log'),
|
416 |
-
__('Log full backtrace for PHP-generated alerts.', 'wp-security-audit-log')
|
417 |
-
),
|
418 |
-
) as $opt => $info) {
|
419 |
-
?><label for="devoption_<?php echo $opt; ?>">
|
420 |
-
<input type="checkbox" name="DevOptions[]" id="devoption_<?php echo $opt; ?>" <?php
|
421 |
-
if($this->_plugin->settings->IsDevOptionEnabled($opt))echo 'checked="checked"'; ?> value="<?php echo $opt; ?>">
|
422 |
-
<span><?php echo $info[0]; ?></span>
|
423 |
-
<?php if (isset($info[1]) && $info[1]) { ?>
|
424 |
-
<span class="description"> — <?php echo $info[1]; ?></span>
|
425 |
-
<?php }
|
426 |
-
?></label><br/><?php
|
427 |
-
}
|
428 |
-
?></div>
|
429 |
-
</fieldset>
|
430 |
-
</td>
|
431 |
-
</tr>
|
432 |
-
|
433 |
-
<tr>
|
434 |
-
<th><label for="Incognito"><?php _e('Hide Plugin in Plugins Page', 'wp-security-audit-log'); ?></label></th>
|
435 |
-
<td>
|
436 |
-
<fieldset>
|
437 |
-
<label for="Incognito">
|
438 |
-
<input type="checkbox" name="Incognito" value="1" id="Incognito"<?php
|
439 |
-
if ($this->_plugin->settings->IsIncognito()) echo ' checked="checked"';
|
440 |
-
?>/> <?php _e('Hide', 'wp-security-audit-log'); ?>
|
441 |
-
</label>
|
442 |
-
<br/>
|
443 |
-
<span class="description">
|
444 |
-
<?php _e('To manually revert this setting set the value of option wsal-hide-plugin to 0 in the wp_options table.', 'wp-security-audit-log'); ?>
|
445 |
-
</span>
|
446 |
-
</fieldset>
|
447 |
-
</td>
|
448 |
-
</tr>
|
449 |
-
<tr>
|
450 |
-
<th><label for="DeleteData"><?php _e('Disable Alerts for WordPress Background Activity', 'wp-security-audit-log'); ?></label></th>
|
451 |
-
<td>
|
452 |
-
<fieldset>
|
453 |
-
<label for="WPBackend">
|
454 |
-
<input type="checkbox" name="WPBackend" value="1" id="WPBackend" <?php
|
455 |
-
if ($this->_plugin->settings->IsWPBackend()) echo ' checked="checked"';
|
456 |
-
?>/> <?php _e('Hide activity', 'wp-security-audit-log'); ?>
|
457 |
-
</label>
|
458 |
-
<br/>
|
459 |
-
<span class="description">
|
460 |
-
<?php _e('For example do not raise an alert when WordPress deletes the auto drafts.', 'wp-security-audit-log'); ?>
|
461 |
-
</span>
|
462 |
-
</fieldset>
|
463 |
-
</td>
|
464 |
-
</tr>
|
465 |
-
<tr>
|
466 |
-
<th><label for="DeleteData"><?php _e('Remove Data on Uninstall', 'wp-security-audit-log'); ?></label></th>
|
467 |
-
<td>
|
468 |
-
<fieldset>
|
469 |
-
<label for="DeleteData">
|
470 |
-
<input type="checkbox" name="DeleteData" value="1" id="DeleteData" onclick="return delete_confirm(this);"<?php
|
471 |
-
if ($this->_plugin->settings->IsDeleteData()) echo ' checked="checked"';
|
472 |
-
?>/> <span class="description">Check this box if you would like remove all data when the plugin is deleted.</span>
|
473 |
-
</label>
|
474 |
-
</fieldset>
|
475 |
-
</td>
|
476 |
-
</tr>
|
477 |
-
</tbody>
|
478 |
-
</table>
|
479 |
-
<!-- End general Tab-->
|
480 |
-
<table class="form-table wsal-tab widefat" id="tab-exclude">
|
481 |
-
<tbody>
|
482 |
-
<tr>
|
483 |
-
<th><h2>Users & Roles</h2></th>
|
484 |
-
</tr>
|
485 |
-
<tr>
|
486 |
-
<td colspan="2">Any of the users and roles listed in the below options will be excluded from monitoring. This means that any change they do will not be logged.</td>
|
487 |
-
</tr>
|
488 |
-
<tr>
|
489 |
-
<th><label for="ExUserQueryBox"><?php _e('Excluded Users', 'wp-security-audit-log'); ?></label></th>
|
490 |
-
<td>
|
491 |
-
<fieldset>
|
492 |
-
<input type="text" id="ExUserQueryBox" style="float: left; display: block; width: 250px;">
|
493 |
-
<input type="button" id="ExUserQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
494 |
-
<br style="clear: both;"/>
|
495 |
-
<div id="ExUserList"><?php
|
496 |
-
foreach($this->_plugin->settings->GetExcludedMonitoringUsers() as $item){
|
497 |
-
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
498 |
-
<input type="hidden" name="ExUsers[]" value="<?php echo esc_attr($item); ?>"/>
|
499 |
-
<?php echo esc_html($item); ?>
|
500 |
-
<a href="javascript:;" title="Remove">×</a>
|
501 |
-
</span><?php
|
502 |
-
}
|
503 |
-
?></div>
|
504 |
-
</fieldset>
|
505 |
-
</td>
|
506 |
-
</tr>
|
507 |
-
<tr>
|
508 |
-
<th><label for="ExRoleQueryBox"><?php _e('Excluded Roles', 'wp-security-audit-log'); ?></label></th>
|
509 |
-
<td>
|
510 |
-
<fieldset>
|
511 |
-
<input type="text" id="ExRoleQueryBox" style="float: left; display: block; width: 250px;">
|
512 |
-
<input type="button" id="ExRoleQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
513 |
-
<br style="clear: both;"/>
|
514 |
-
<div id="ExRoleList"><?php
|
515 |
-
foreach($this->_plugin->settings->GetExcludedMonitoringRoles() as $item){
|
516 |
-
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
517 |
-
<input type="hidden" name="ExRoles[]" value="<?php echo esc_attr($item); ?>"/>
|
518 |
-
<?php echo esc_html($item); ?>
|
519 |
-
<a href="javascript:;" title="Remove">×</a>
|
520 |
-
</span><?php
|
521 |
-
}
|
522 |
-
?></div>
|
523 |
-
</fieldset>
|
524 |
-
</td>
|
525 |
-
</tr>
|
526 |
-
<tr>
|
527 |
-
<th><h2>Custom Fields</h2></th>
|
528 |
-
</tr>
|
529 |
-
<tr>
|
530 |
-
<td colspan="2">Any of the custom fields listed below will be excluded from monitoring. This means that if they are changed or updated the plugin will not log such activity.</td>
|
531 |
-
</tr>
|
532 |
-
<tr>
|
533 |
-
<th><label for="CustomQueryBox"><?php _e('Excluded Custom Fields', 'wp-security-audit-log'); ?></label></th>
|
534 |
-
<td>
|
535 |
-
<fieldset>
|
536 |
-
<input type="text" id="CustomQueryBox" style="float: left; display: block; width: 250px;">
|
537 |
-
<input type="button" id="CustomQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
538 |
-
<br style="clear: both;"/>
|
539 |
-
<div id="CustomList">
|
540 |
-
<?php foreach ($this->_plugin->settings->GetExcludedMonitoringCustom() as $item) { ?>
|
541 |
-
<span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
542 |
-
<input type="hidden" name="Customs[]" value="<?php echo esc_attr($item); ?>"/>
|
543 |
-
<?php echo esc_html($item); ?>
|
544 |
-
<a href="javascript:;" title="Remove">×</a>
|
545 |
-
</span>
|
546 |
-
<?php } ?>
|
547 |
-
</div>
|
548 |
-
</fieldset>
|
549 |
-
</td>
|
550 |
-
</tr>
|
551 |
-
<tr>
|
552 |
-
<th><h2>IP Addresses</h2></th>
|
553 |
-
</tr>
|
554 |
-
<tr>
|
555 |
-
<td colspan="2">Any of the IP addresses listed below will be excluded from monitoring. This means that all activity from such IP address will not be recorded.</td>
|
556 |
-
</tr>
|
557 |
-
<tr>
|
558 |
-
<th><label for="IpAddrQueryBox"><?php _e('Excluded IP Addresses', 'wp-security-audit-log'); ?></label></th>
|
559 |
-
<td>
|
560 |
-
<fieldset>
|
561 |
-
<input type="text" id="IpAddrQueryBox" style="float: left; display: block; width: 250px;">
|
562 |
-
<input type="button" id="IpAddrQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
563 |
-
<br style="clear: both;"/>
|
564 |
-
<div id="IpAddrList">
|
565 |
-
<?php foreach ($this->_plugin->settings->GetExcludedMonitoringIP() as $item) { ?>
|
566 |
-
<span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
567 |
-
<input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr($item); ?>"/>
|
568 |
-
<?php echo esc_html($item); ?>
|
569 |
-
<a href="javascript:;" title="Remove">×</a>
|
570 |
-
</span>
|
571 |
-
<?php } ?>
|
572 |
-
</div>
|
573 |
-
</fieldset>
|
574 |
-
</td>
|
575 |
-
</tr>
|
576 |
-
</tbody>
|
577 |
-
</table>
|
578 |
-
</div>
|
579 |
-
<p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes"></p>
|
580 |
-
</form>
|
581 |
-
<script type="text/javascript">
|
582 |
-
<!--
|
583 |
-
function delete_confirm(elementRef)
|
584 |
-
{
|
585 |
-
if ( elementRef.checked )
|
586 |
-
{
|
587 |
-
if ( window.confirm('Do you want remove all data when the plugin is deleted?') == false )
|
588 |
-
elementRef.checked = false;
|
589 |
-
}
|
590 |
-
}
|
591 |
-
// -->
|
592 |
-
</script><?php
|
593 |
-
}
|
594 |
-
|
595 |
-
public function Header()
|
596 |
-
{
|
597 |
-
wp_enqueue_style(
|
598 |
-
'settings',
|
599 |
-
$this->_plugin->GetBaseUrl() . '/css/settings.css',
|
600 |
-
array(),
|
601 |
-
filemtime($this->_plugin->GetBaseDir() . '/css/settings.css')
|
602 |
-
);
|
603 |
-
?><style type="text/css">
|
604 |
-
.wsal-tab {
|
605 |
-
display: none;
|
606 |
-
}
|
607 |
-
.wsal-tab tr.alert-incomplete td {
|
608 |
-
color: #9BE;
|
609 |
-
}
|
610 |
-
.wsal-tab tr.alert-unavailable td {
|
611 |
-
color: #CCC;
|
612 |
-
}
|
613 |
-
</style><?php
|
614 |
-
}
|
615 |
-
|
616 |
-
public function Footer()
|
617 |
-
{
|
618 |
-
wp_enqueue_script(
|
619 |
-
'settings',
|
620 |
-
$this->_plugin->GetBaseUrl() . '/js/settings.js',
|
621 |
-
array(),
|
622 |
-
filemtime($this->_plugin->GetBaseDir() . '/js/settings.js')
|
623 |
-
);
|
624 |
-
?><script type="text/javascript">
|
625 |
-
jQuery(document).ready(function(){
|
626 |
-
// tab handling code
|
627 |
-
jQuery('#wsal-tabs>a').click(function(){
|
628 |
-
jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
|
629 |
-
jQuery('table.wsal-tab').hide();
|
630 |
-
jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
|
631 |
-
});
|
632 |
-
// show relevant tab
|
633 |
-
var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
|
634 |
-
if (hashlink.length) {
|
635 |
-
hashlink.click();
|
636 |
-
} else {
|
637 |
-
jQuery('#wsal-tabs>a:first').click();
|
638 |
-
}
|
639 |
-
|
640 |
-
jQuery(".sel-columns").change(function(){
|
641 |
-
var notChecked = 1;
|
642 |
-
jQuery(".sel-columns").each(function(){
|
643 |
-
if(this.checked) notChecked = 0;
|
644 |
-
})
|
645 |
-
if(notChecked == 1){
|
646 |
-
alert("You have to select at least one column!");
|
647 |
-
}
|
648 |
-
});
|
649 |
-
});
|
650 |
-
</script><?php
|
651 |
-
}
|
652 |
-
|
653 |
-
public function AjaxGetAllUsers()
|
654 |
-
{
|
655 |
-
if (!$this->_plugin->settings->CurrentUserCan('view')) {
|
656 |
-
die('Access Denied.');
|
657 |
-
}
|
658 |
-
$users = array();
|
659 |
-
foreach (get_users() as $user) {
|
660 |
-
if (strpos($user->user_login, $_GET['term']) !== false) {
|
661 |
-
array_push($users, $user->user_login);
|
662 |
-
}
|
663 |
-
}
|
664 |
-
echo json_encode($users);
|
665 |
-
exit;
|
666 |
-
}
|
667 |
-
|
668 |
-
public function AjaxGetAllRoles()
|
669 |
-
{
|
670 |
-
if (!$this->_plugin->settings->CurrentUserCan('view')) {
|
671 |
-
die('Access Denied.');
|
672 |
-
}
|
673 |
-
$roles = array();
|
674 |
-
foreach (get_editable_roles() as $role_name => $role_info) {
|
675 |
-
if (strpos($role_name, $_GET['term']) !== false) {
|
676 |
-
array_push($roles, $role_name);
|
677 |
-
}
|
678 |
-
}
|
679 |
-
echo json_encode($roles);
|
680 |
-
exit;
|
681 |
-
}
|
682 |
-
}
|
1 |
+
<?php
|
2 |
+
class WSAL_Views_Settings extends WSAL_AbstractView
|
3 |
+
{
|
4 |
+
|
5 |
+
public $adapterMsg = '';
|
6 |
+
|
7 |
+
public function __construct(WpSecurityAuditLog $plugin)
|
8 |
+
{
|
9 |
+
parent::__construct($plugin);
|
10 |
+
|
11 |
+
add_action('wp_ajax_AjaxCheckSecurityToken', array($this, 'AjaxCheckSecurityToken'));
|
12 |
+
add_action('wp_ajax_AjaxRunCleanup', array($this, 'AjaxRunCleanup'));
|
13 |
+
add_action('wp_ajax_AjaxGetAllUsers', array($this, 'AjaxGetAllUsers'));
|
14 |
+
add_action('wp_ajax_AjaxGetAllRoles', array($this, 'AjaxGetAllRoles'));
|
15 |
+
}
|
16 |
+
|
17 |
+
public function HasPluginShortcutLink(){
|
18 |
+
return true;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function GetTitle() {
|
22 |
+
return __('Settings', 'wp-security-audit-log');
|
23 |
+
}
|
24 |
+
|
25 |
+
public function GetIcon() {
|
26 |
+
return 'dashicons-admin-generic';
|
27 |
+
}
|
28 |
+
|
29 |
+
public function GetName() {
|
30 |
+
return __('Settings', 'wp-security-audit-log');
|
31 |
+
}
|
32 |
+
|
33 |
+
public function GetWeight() {
|
34 |
+
return 3;
|
35 |
+
}
|
36 |
+
|
37 |
+
protected function GetTokenType($token){
|
38 |
+
$users = array();
|
39 |
+
foreach (get_users('blog_id=0&fields[]=user_login') as $obj)
|
40 |
+
$users[] = $obj->user_login;
|
41 |
+
$roles = array_keys(get_editable_roles());
|
42 |
+
|
43 |
+
if(in_array($token, $users))return 'user';
|
44 |
+
if(in_array($token, $roles))return 'role';
|
45 |
+
return 'other';
|
46 |
+
}
|
47 |
+
|
48 |
+
protected function Save()
|
49 |
+
{
|
50 |
+
check_admin_referer('wsal-settings');
|
51 |
+
$this->_plugin->settings->SetPruningDateEnabled($_REQUEST['PruneBy'] == 'date');
|
52 |
+
$this->_plugin->settings->SetPruningDate($_REQUEST['PruningDate']);
|
53 |
+
$this->_plugin->settings->SetPruningLimitEnabled($_REQUEST['PruneBy'] == 'limit');
|
54 |
+
$this->_plugin->settings->SetPruningLimit($_REQUEST['PruningLimit']);
|
55 |
+
$this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
|
56 |
+
$this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
|
57 |
+
$this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
|
58 |
+
|
59 |
+
$this->_plugin->settings->SetExcludedMonitoringUsers(isset($_REQUEST['ExUsers']) ? $_REQUEST['ExUsers'] : array());
|
60 |
+
$this->_plugin->settings->SetExcludedMonitoringRoles(isset($_REQUEST['ExRoles']) ? $_REQUEST['ExRoles'] : array());
|
61 |
+
$this->_plugin->settings->SetExcludedMonitoringCustom(isset($_REQUEST['Customs']) ? $_REQUEST['Customs'] : array());
|
62 |
+
$this->_plugin->settings->SetExcludedMonitoringIP(isset($_REQUEST['IpAddrs']) ? $_REQUEST['IpAddrs'] : array());
|
63 |
+
|
64 |
+
$this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
|
65 |
+
$this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
|
66 |
+
$this->_plugin->settings->SetMainIPFromProxy(isset($_REQUEST['EnableProxyIpCapture']));
|
67 |
+
$this->_plugin->settings->SetInternalIPsFiltering(isset($_REQUEST['EnableIpFiltering']));
|
68 |
+
$this->_plugin->settings->SetIncognito(isset($_REQUEST['Incognito']));
|
69 |
+
$this->_plugin->settings->SetDeleteData(isset($_REQUEST['DeleteData']));
|
70 |
+
$this->_plugin->settings->SetDatetimeFormat($_REQUEST['DatetimeFormat']);
|
71 |
+
$this->_plugin->settings->SetTimezone($_REQUEST['Timezone']);
|
72 |
+
$this->_plugin->settings->SetWPBackend(isset($_REQUEST['WPBackend']));
|
73 |
+
if (!empty($_REQUEST['Columns'])) {
|
74 |
+
$this->_plugin->settings->SetColumns($_REQUEST['Columns']);
|
75 |
+
}
|
76 |
+
$this->_plugin->settings->ClearDevOptions();
|
77 |
+
|
78 |
+
if (isset($_REQUEST['DevOptions'])) {
|
79 |
+
foreach ($_REQUEST['DevOptions'] as $opt) {
|
80 |
+
$this->_plugin->settings->SetDevOptionEnabled($opt, true);
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
// Database Adapter Settings
|
85 |
+
// Temporarily not used
|
86 |
+
/* Check Adapter config */
|
87 |
+
if (!empty($_REQUEST["AdapterUser"]) && ($_REQUEST['AdapterUser'] != '') && ($_REQUEST['AdapterName'] != '') && ($_REQUEST['AdapterHostname'] != '')) {
|
88 |
+
WSAL_Connector_ConnectorFactory::CheckConfig(
|
89 |
+
trim($_REQUEST['AdapterType']),
|
90 |
+
trim($_REQUEST['AdapterUser']),
|
91 |
+
trim($_REQUEST['AdapterPassword']),
|
92 |
+
trim($_REQUEST['AdapterName']),
|
93 |
+
trim($_REQUEST['AdapterHostname']),
|
94 |
+
trim($_REQUEST['AdapterBasePrefix'])
|
95 |
+
);
|
96 |
+
|
97 |
+
/* Setting Adapter config */
|
98 |
+
$this->_plugin->settings->SetAdapterConfig('adapter-type', $_REQUEST['AdapterType']);
|
99 |
+
$this->_plugin->settings->SetAdapterConfig('adapter-user', $_REQUEST['AdapterUser']);
|
100 |
+
$this->_plugin->settings->SetAdapterConfig('adapter-password', $_REQUEST['AdapterPassword']);
|
101 |
+
$this->_plugin->settings->SetAdapterConfig('adapter-name', $_REQUEST['AdapterName']);
|
102 |
+
$this->_plugin->settings->SetAdapterConfig('adapter-hostname', $_REQUEST['AdapterHostname']);
|
103 |
+
$this->_plugin->settings->SetAdapterConfig('adapter-base-prefix', $_REQUEST['AdapterBasePrefix']);
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
public function AjaxCheckSecurityToken()
|
108 |
+
{
|
109 |
+
if (!$this->_plugin->settings->CurrentUserCan('view'))
|
110 |
+
die('Access Denied.');
|
111 |
+
if (!isset($_REQUEST['token']))
|
112 |
+
die('Token parameter expected.');
|
113 |
+
die($this->GetTokenType($_REQUEST['token']));
|
114 |
+
}
|
115 |
+
|
116 |
+
public function AjaxRunCleanup()
|
117 |
+
{
|
118 |
+
if (!$this->_plugin->settings->CurrentUserCan('view'))
|
119 |
+
die('Access Denied.');
|
120 |
+
$this->_plugin->CleanUp();
|
121 |
+
wp_redirect($this->GetUrl());
|
122 |
+
exit;
|
123 |
+
}
|
124 |
+
|
125 |
+
public function Render()
|
126 |
+
{
|
127 |
+
if (!$this->_plugin->settings->CurrentUserCan('edit')) {
|
128 |
+
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-security-audit-log'));
|
129 |
+
}
|
130 |
+
if (isset($_POST['submit'])) {
|
131 |
+
try {
|
132 |
+
$this->Save();
|
133 |
+
?><div class="updated">
|
134 |
+
<p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p>
|
135 |
+
</div><?php
|
136 |
+
} catch (Exception $ex) {
|
137 |
+
?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
|
138 |
+
}
|
139 |
+
}
|
140 |
+
?>
|
141 |
+
<h2 id="wsal-tabs" class="nav-tab-wrapper">
|
142 |
+
<a href="#tab-general" class="nav-tab">General</a>
|
143 |
+
<a href="#tab-exclude" class="nav-tab">Exclude Objects</a>
|
144 |
+
<!--<a href="#adapter" class="nav-tab">Data Storage Adapter</a>-->
|
145 |
+
</h2>
|
146 |
+
<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"/></script>
|
147 |
+
<form id="audit-log-settings" method="post">
|
148 |
+
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
149 |
+
<input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
|
150 |
+
<?php wp_nonce_field('wsal-settings'); ?>
|
151 |
+
|
152 |
+
<div id="audit-log-adverts">
|
153 |
+
<a href="http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=settingspage&utm_campaign=notifications">
|
154 |
+
<img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/notifications_250x150.gif" width="250" height="150" alt=""/>
|
155 |
+
</a>
|
156 |
+
<a href="http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=settingspage&utm_campaign=search">
|
157 |
+
<img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/search_250x150.gif" width="250" height="150" alt=""/>
|
158 |
+
</a>
|
159 |
+
<a href="http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=settingspage&utm_campaign=reports">
|
160 |
+
<img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/reporting_250x150.gif" width="250" height="150" alt=""/>
|
161 |
+
</a>
|
162 |
+
</div>
|
163 |
+
<div class="nav-tabs">
|
164 |
+
<table class="form-table wsal-tab widefat" id="tab-general">
|
165 |
+
<tbody>
|
166 |
+
<tr>
|
167 |
+
<th><label for="delete1"><?php _e('Security Alerts Pruning', 'wp-security-audit-log'); ?></label></th>
|
168 |
+
<td>
|
169 |
+
<fieldset>
|
170 |
+
<?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
|
171 |
+
<?php $nbld = !($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
|
172 |
+
<label for="delete0">
|
173 |
+
<input type="radio" id="delete0" name="PruneBy" value="" <?php if($nbld)echo 'checked="checked"'; ?>/>
|
174 |
+
<?php echo __('None', 'wp-security-audit-log'); ?>
|
175 |
+
</label>
|
176 |
+
</fieldset>
|
177 |
+
<fieldset>
|
178 |
+
<?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
|
179 |
+
<?php $nbld = $this->_plugin->settings->IsPruningDateEnabled(); ?>
|
180 |
+
<label for="delete1">
|
181 |
+
<input type="radio" id="delete1" name="PruneBy" value="date" <?php if($nbld)echo 'checked="checked"'; ?>/>
|
182 |
+
<?php echo __('Delete alerts older than', 'wp-security-audit-log'); ?>
|
183 |
+
</label>
|
184 |
+
<input type="text" id="PruningDate" name="PruningDate" placeholder="<?php echo $text; ?>"
|
185 |
+
value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"
|
186 |
+
onfocus="jQuery('#delete1').attr('checked', true);"/>
|
187 |
+
<span> <?php echo $text; ?></span>
|
188 |
+
</fieldset>
|
189 |
+
<fieldset>
|
190 |
+
<?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
|
191 |
+
<?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
|
192 |
+
<label for="delete2">
|
193 |
+
<input type="radio" id="delete2" name="PruneBy" value="limit" <?php if($nbld)echo 'checked="checked"'; ?>/>
|
194 |
+
<?php echo __('Keep up to', 'wp-security-audit-log'); ?>
|
195 |
+
</label>
|
196 |
+
<input type="text" id="PruningLimit" name="PruningLimit" placeholder="<?php echo $text;?>"
|
197 |
+
value="<?php echo esc_attr($this->_plugin->settings->GetPruningLimit()); ?>"
|
198 |
+
onfocus="jQuery('#delete2').attr('checked', true);"/>
|
199 |
+
<?php echo __('alerts', 'wp-security-audit-log'); ?>
|
200 |
+
<span><?php echo $text; ?></span>
|
201 |
+
</fieldset>
|
202 |
+
<p class="description"><?php
|
203 |
+
echo __('Next Scheduled Cleanup is in ', 'wp-security-audit-log');
|
204 |
+
echo human_time_diff(current_time('timestamp'), $next = wp_next_scheduled('wsal_cleanup'));
|
205 |
+
echo '<!-- ' . date('dMy H:i:s', $next) . ' --> ';
|
206 |
+
echo sprintf(
|
207 |
+
__('(or %s)', 'wp-security-audit-log'),
|
208 |
+
'<a href="' . admin_url('admin-ajax.php?action=AjaxRunCleanup') . '">' . __('Run Manually', 'wp-security-audit-log') . '</a>'
|
209 |
+
);
|
210 |
+
?></p>
|
211 |
+
</td>
|
212 |
+
</tr>
|
213 |
+
<tr>
|
214 |
+
<th><label for="dwoption_on"><?php _e('Alerts Dashboard Widget', 'wp-security-audit-log'); ?></label></th>
|
215 |
+
<td>
|
216 |
+
<fieldset>
|
217 |
+
<?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
|
218 |
+
<label for="dwoption_on">
|
219 |
+
<input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php if($dwe)echo 'checked="checked"'; ?> value="1">
|
220 |
+
<span><?php _e('On', 'wp-security-audit-log'); ?></span>
|
221 |
+
</label>
|
222 |
+
<br/>
|
223 |
+
<label for="dwoption_off">
|
224 |
+
<input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php if(!$dwe)echo 'checked="checked"'; ?> value="0">
|
225 |
+
<span><?php _e('Off', 'wp-security-audit-log'); ?></span>
|
226 |
+
</label>
|
227 |
+
<br/>
|
228 |
+
<p class="description"><?php
|
229 |
+
echo sprintf(
|
230 |
+
__('Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log'),
|
231 |
+
$this->_plugin->settings->GetDashboardWidgetMaxAlerts()
|
232 |
+
);
|
233 |
+
?></p>
|
234 |
+
</fieldset>
|
235 |
+
</td>
|
236 |
+
</tr>
|
237 |
+
<tr>
|
238 |
+
<th><label for="pioption_on"><?php _e('Reverse Proxy / Firewall Options', 'wp-security-audit-log'); ?></label></th>
|
239 |
+
<td>
|
240 |
+
<fieldset>
|
241 |
+
<label for="EnableProxyIpCapture">
|
242 |
+
<input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
|
243 |
+
if($this->_plugin->settings->IsMainIPFromProxy())echo ' checked="checked"';
|
244 |
+
?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?><br/>
|
245 |
+
<span class="description"><?php _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>
|
246 |
+
</label>
|
247 |
+
<br/>
|
248 |
+
<label for="EnableIpFiltering">
|
249 |
+
<input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
|
250 |
+
if($this->_plugin->settings->IsInternalIPsFiltered())echo ' checked="checked"';
|
251 |
+
?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?><br/>
|
252 |
+
<span class="description"><?php _e('Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log'); ?></span>
|
253 |
+
</label>
|
254 |
+
</fieldset>
|
255 |
+
</td>
|
256 |
+
</tr>
|
257 |
+
<tr>
|
258 |
+
<th><label for="ViewerQueryBox"><?php _e('Can View Alerts', 'wp-security-audit-log'); ?></label></th>
|
259 |
+
<td>
|
260 |
+
<fieldset>
|
261 |
+
<input type="text" id="ViewerQueryBox" style="float: left; display: block; width: 250px;">
|
262 |
+
<input type="button" id="ViewerQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
263 |
+
<br style="clear: both;"/>
|
264 |
+
<p class="description"><?php
|
265 |
+
_e('Users and Roles in this list can view the security alerts', 'wp-security-audit-log');
|
266 |
+
?></p>
|
267 |
+
<div id="ViewerList"><?php
|
268 |
+
foreach($this->_plugin->settings->GetAllowedPluginViewers() as $item){
|
269 |
+
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
270 |
+
<input type="hidden" name="Viewers[]" value="<?php echo esc_attr($item); ?>"/>
|
271 |
+
<?php echo esc_html($item); ?>
|
272 |
+
<a href="javascript:;" title="Remove">×</a>
|
273 |
+
</span><?php
|
274 |
+
}
|
275 |
+
?></div>
|
276 |
+
</fieldset>
|
277 |
+
</td>
|
278 |
+
</tr>
|
279 |
+
<tr>
|
280 |
+
<th><label for="EditorQueryBox"><?php _e('Can Manage Plugin', 'wp-security-audit-log'); ?></label></th>
|
281 |
+
<td>
|
282 |
+
<fieldset>
|
283 |
+
<input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
|
284 |
+
<input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
285 |
+
<br style="clear: both;"/>
|
286 |
+
<p class="description"><?php
|
287 |
+
_e('Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log');
|
288 |
+
?></p>
|
289 |
+
<div id="EditorList"><?php
|
290 |
+
foreach($this->_plugin->settings->GetAllowedPluginEditors() as $item){
|
291 |
+
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
292 |
+
<input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
|
293 |
+
<?php echo esc_html($item); ?>
|
294 |
+
<a href="javascript:;" title="Remove">×</a>
|
295 |
+
</span><?php
|
296 |
+
}
|
297 |
+
?></div>
|
298 |
+
</fieldset>
|
299 |
+
</td>
|
300 |
+
</tr>
|
301 |
+
<tr>
|
302 |
+
<th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
|
303 |
+
<td>
|
304 |
+
<fieldset>
|
305 |
+
<input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
|
306 |
+
<label for="RestrictAdmins">
|
307 |
+
<?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
|
308 |
+
<input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
|
309 |
+
<span class="description">
|
310 |
+
<?php _e('By default all the administrators on this WordPress have access to manage this plugin.<br/>By enabling this option only the users specified in the two options above and your username will have access to view alerts and manage this plugin.', 'wp-security-audit-log'); ?>
|
311 |
+
</span>
|
312 |
+
</label>
|
313 |
+
</fieldset>
|
314 |
+
</td>
|
315 |
+
</tr>
|
316 |
+
<tr>
|
317 |
+
<th><label for="aroption_on"><?php _e('Refresh Audit Log Viewer', 'wp-security-audit-log'); ?></label></th>
|
318 |
+
<td>
|
319 |
+
<fieldset>
|
320 |
+
<?php $are = $this->_plugin->settings->IsRefreshAlertsEnabled(); ?>
|
321 |
+
<label for="aroption_on">
|
322 |
+
<input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: 2px;" <?php if($are)echo 'checked="checked"'; ?> value="1">
|
323 |
+
<span><?php _e('Automatic', 'wp-security-audit-log'); ?></span>
|
324 |
+
</label>
|
325 |
+
<span class="description"> — <?php _e('Refresh Audit Log Viewer as soon as there are new alerts.', 'wp-security-audit-log'); ?></span>
|
326 |
+
<br/>
|
327 |
+
<label for="aroption_off">
|
328 |
+
<input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: 2px;" <?php if(!$are)echo 'checked="checked"'; ?> value="0">
|
329 |
+
<span><?php _e('Manual', 'wp-security-audit-log'); ?></span>
|
330 |
+
</label>
|
331 |
+
<span class="description"> — <?php _e('Refresh Audit Log Viewer only when the page is reloaded.', 'wp-security-audit-log'); ?></span>
|
332 |
+
<br/>
|
333 |
+
</fieldset>
|
334 |
+
</td>
|
335 |
+
</tr>
|
336 |
+
<tr>
|
337 |
+
<th><label for="datetime_format_24"><?php _e('Alerts Time Format', 'wp-security-audit-log'); ?></label></th>
|
338 |
+
<td>
|
339 |
+
<fieldset>
|
340 |
+
<?php $datetime = $this->_plugin->settings->GetDatetimeFormat(); ?>
|
341 |
+
<label for="datetime_format_24">
|
342 |
+
<input type="radio" name="DatetimeFormat" id="datetime_format_24" style="margin-top: 2px;" <?php if($datetime)echo 'checked="checked"'; ?> value="1">
|
343 |
+
<span><?php _e('24 hours', 'wp-security-audit-log'); ?></span>
|
344 |
+
</label>
|
345 |
+
<br/>
|
346 |
+
<label for="datetime_format_default">
|
347 |
+
<input type="radio" name="DatetimeFormat" id="datetime_format_default" style="margin-top: 2px;" <?php if(!$datetime)echo 'checked="checked"'; ?> value="0">
|
348 |
+
<span><?php _e('AM/PM', 'wp-security-audit-log'); ?></span>
|
349 |
+
</label>
|
350 |
+
<br/>
|
351 |
+
</fieldset>
|
352 |
+
</td>
|
353 |
+
</tr>
|
354 |
+
<tr>
|
355 |
+
<th><label for="timezone-default"><?php _e('Alerts Timestamp', 'wp-security-audit-log'); ?></label></th>
|
356 |
+
<td>
|
357 |
+
<fieldset>
|
358 |
+
<?php $timezone = $this->_plugin->settings->GetTimezone(); ?>
|
359 |
+
<label for="timezone-default">
|
360 |
+
<input type="radio" name="Timezone" id="timezone-default" style="margin-top: 2px;" <?php if(!$timezone)echo 'checked="checked"'; ?> value="0">
|
361 |
+
<span><?php _e('UTC', 'wp-security-audit-log'); ?></span>
|
362 |
+
</label>
|
363 |
+
<br/>
|
364 |
+
<label for="timezone">
|
365 |
+
<input type="radio" name="Timezone" id="timezone" style="margin-top: 2px;" <?php if($timezone)echo 'checked="checked"'; ?> value="1">
|
366 |
+
<span><?php _e('WordPress\' timezone', 'wp-security-audit-log'); ?></span>
|
367 |
+
</label>
|
368 |
+
<br/>
|
369 |
+
<span class="description"><?php _e('Select which timestamp should the alerts have in the Audit Log viewer. Note that the WordPress\' timezone might be different from that of the server.', 'wp-security-audit-log'); ?></span>
|
370 |
+
</fieldset>
|
371 |
+
</td>
|
372 |
+
</tr>
|
373 |
+
<tr>
|
374 |
+
<th><label for="columns"><?php _e('Audit Log Columns Selection', 'wp-security-audit-log'); ?></label></th>
|
375 |
+
<td>
|
376 |
+
<fieldset>
|
377 |
+
<?php $columns = $this->_plugin->settings->GetColumns(); ?>
|
378 |
+
<?php foreach ($columns as $key => $value) { ?>
|
379 |
+
<label for="columns">
|
380 |
+
<input type="checkbox" name="Columns[<?php echo $key; ?>]" id="<?php echo $key; ?>" class="sel-columns" style="margin-top: 2px;" <?php if ($value == '1') echo 'checked="checked"'; ?> value="1">
|
381 |
+
<span><?php echo ucwords(str_replace("_", " ", $key)); ?></span>
|
382 |
+
</label>
|
383 |
+
<br/>
|
384 |
+
<?php } ?>
|
385 |
+
<span class="description"><?php _e('When you disable any of the above such details won’t be shown in the Audit Log
|
386 |
+
viewer though the plugin will still record such information in the database.', 'wp-security-audit-log'); ?></span>
|
387 |
+
</fieldset>
|
388 |
+
</td>
|
389 |
+
</tr>
|
390 |
+
<tr>
|
391 |
+
<th><label><?php _e('Developer Options', 'wp-security-audit-log'); ?></label></th>
|
392 |
+
<td>
|
393 |
+
<fieldset>
|
394 |
+
<?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
|
395 |
+
<a href="javascript:;" style="<?php if($any)echo 'display: none;'; ?>"
|
396 |
+
onclick="jQuery(this).hide().next().show();">Show Developer Options</a>
|
397 |
+
<div style="<?php if(!$any)echo 'display: none;'; ?>">
|
398 |
+
<p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;"><?php
|
399 |
+
_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');
|
400 |
+
?></p><?php
|
401 |
+
foreach (array(
|
402 |
+
WSAL_Settings::OPT_DEV_DATA_INSPECTOR => array(
|
403 |
+
__('Data Inspector', 'wp-security-audit-log'),
|
404 |
+
__('View data logged for each triggered alert.', 'wp-security-audit-log')
|
405 |
+
),
|
406 |
+
WSAL_Settings::OPT_DEV_PHP_ERRORS => array(
|
407 |
+
__('PHP Errors', 'wp-security-audit-log'),
|
408 |
+
__('Enables sensor for alerts generated from PHP.', 'wp-security-audit-log')
|
409 |
+
),
|
410 |
+
WSAL_Settings::OPT_DEV_REQUEST_LOG => array(
|
411 |
+
__('Request Log', 'wp-security-audit-log'),
|
412 |
+
__('Enables logging request to file.', 'wp-security-audit-log')
|
413 |
+
),
|
414 |
+
WSAL_Settings::OPT_DEV_BACKTRACE_LOG => array(
|
415 |
+
__('Backtrace', 'wp-security-audit-log'),
|
416 |
+
__('Log full backtrace for PHP-generated alerts.', 'wp-security-audit-log')
|
417 |
+
),
|
418 |
+
) as $opt => $info) {
|
419 |
+
?><label for="devoption_<?php echo $opt; ?>">
|
420 |
+
<input type="checkbox" name="DevOptions[]" id="devoption_<?php echo $opt; ?>" <?php
|
421 |
+
if($this->_plugin->settings->IsDevOptionEnabled($opt))echo 'checked="checked"'; ?> value="<?php echo $opt; ?>">
|
422 |
+
<span><?php echo $info[0]; ?></span>
|
423 |
+
<?php if (isset($info[1]) && $info[1]) { ?>
|
424 |
+
<span class="description"> — <?php echo $info[1]; ?></span>
|
425 |
+
<?php }
|
426 |
+
?></label><br/><?php
|
427 |
+
}
|
428 |
+
?></div>
|
429 |
+
</fieldset>
|
430 |
+
</td>
|
431 |
+
</tr>
|
432 |
+
|
433 |
+
<tr>
|
434 |
+
<th><label for="Incognito"><?php _e('Hide Plugin in Plugins Page', 'wp-security-audit-log'); ?></label></th>
|
435 |
+
<td>
|
436 |
+
<fieldset>
|
437 |
+
<label for="Incognito">
|
438 |
+
<input type="checkbox" name="Incognito" value="1" id="Incognito"<?php
|
439 |
+
if ($this->_plugin->settings->IsIncognito()) echo ' checked="checked"';
|
440 |
+
?>/> <?php _e('Hide', 'wp-security-audit-log'); ?>
|
441 |
+
</label>
|
442 |
+
<br/>
|
443 |
+
<span class="description">
|
444 |
+
<?php _e('To manually revert this setting set the value of option wsal-hide-plugin to 0 in the wp_options table.', 'wp-security-audit-log'); ?>
|
445 |
+
</span>
|
446 |
+
</fieldset>
|
447 |
+
</td>
|
448 |
+
</tr>
|
449 |
+
<tr>
|
450 |
+
<th><label for="DeleteData"><?php _e('Disable Alerts for WordPress Background Activity', 'wp-security-audit-log'); ?></label></th>
|
451 |
+
<td>
|
452 |
+
<fieldset>
|
453 |
+
<label for="WPBackend">
|
454 |
+
<input type="checkbox" name="WPBackend" value="1" id="WPBackend" <?php
|
455 |
+
if ($this->_plugin->settings->IsWPBackend()) echo ' checked="checked"';
|
456 |
+
?>/> <?php _e('Hide activity', 'wp-security-audit-log'); ?>
|
457 |
+
</label>
|
458 |
+
<br/>
|
459 |
+
<span class="description">
|
460 |
+
<?php _e('For example do not raise an alert when WordPress deletes the auto drafts.', 'wp-security-audit-log'); ?>
|
461 |
+
</span>
|
462 |
+
</fieldset>
|
463 |
+
</td>
|
464 |
+
</tr>
|
465 |
+
<tr>
|
466 |
+
<th><label for="DeleteData"><?php _e('Remove Data on Uninstall', 'wp-security-audit-log'); ?></label></th>
|
467 |
+
<td>
|
468 |
+
<fieldset>
|
469 |
+
<label for="DeleteData">
|
470 |
+
<input type="checkbox" name="DeleteData" value="1" id="DeleteData" onclick="return delete_confirm(this);"<?php
|
471 |
+
if ($this->_plugin->settings->IsDeleteData()) echo ' checked="checked"';
|
472 |
+
?>/> <span class="description">Check this box if you would like remove all data when the plugin is deleted.</span>
|
473 |
+
</label>
|
474 |
+
</fieldset>
|
475 |
+
</td>
|
476 |
+
</tr>
|
477 |
+
</tbody>
|
478 |
+
</table>
|
479 |
+
<!-- End general Tab-->
|
480 |
+
<table class="form-table wsal-tab widefat" id="tab-exclude">
|
481 |
+
<tbody>
|
482 |
+
<tr>
|
483 |
+
<th><h2>Users & Roles</h2></th>
|
484 |
+
</tr>
|
485 |
+
<tr>
|
486 |
+
<td colspan="2">Any of the users and roles listed in the below options will be excluded from monitoring. This means that any change they do will not be logged.</td>
|
487 |
+
</tr>
|
488 |
+
<tr>
|
489 |
+
<th><label for="ExUserQueryBox"><?php _e('Excluded Users', 'wp-security-audit-log'); ?></label></th>
|
490 |
+
<td>
|
491 |
+
<fieldset>
|
492 |
+
<input type="text" id="ExUserQueryBox" style="float: left; display: block; width: 250px;">
|
493 |
+
<input type="button" id="ExUserQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
494 |
+
<br style="clear: both;"/>
|
495 |
+
<div id="ExUserList"><?php
|
496 |
+
foreach($this->_plugin->settings->GetExcludedMonitoringUsers() as $item){
|
497 |
+
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
498 |
+
<input type="hidden" name="ExUsers[]" value="<?php echo esc_attr($item); ?>"/>
|
499 |
+
<?php echo esc_html($item); ?>
|
500 |
+
<a href="javascript:;" title="Remove">×</a>
|
501 |
+
</span><?php
|
502 |
+
}
|
503 |
+
?></div>
|
504 |
+
</fieldset>
|
505 |
+
</td>
|
506 |
+
</tr>
|
507 |
+
<tr>
|
508 |
+
<th><label for="ExRoleQueryBox"><?php _e('Excluded Roles', 'wp-security-audit-log'); ?></label></th>
|
509 |
+
<td>
|
510 |
+
<fieldset>
|
511 |
+
<input type="text" id="ExRoleQueryBox" style="float: left; display: block; width: 250px;">
|
512 |
+
<input type="button" id="ExRoleQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
513 |
+
<br style="clear: both;"/>
|
514 |
+
<div id="ExRoleList"><?php
|
515 |
+
foreach($this->_plugin->settings->GetExcludedMonitoringRoles() as $item){
|
516 |
+
?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
517 |
+
<input type="hidden" name="ExRoles[]" value="<?php echo esc_attr($item); ?>"/>
|
518 |
+
<?php echo esc_html($item); ?>
|
519 |
+
<a href="javascript:;" title="Remove">×</a>
|
520 |
+
</span><?php
|
521 |
+
}
|
522 |
+
?></div>
|
523 |
+
</fieldset>
|
524 |
+
</td>
|
525 |
+
</tr>
|
526 |
+
<tr>
|
527 |
+
<th><h2>Custom Fields</h2></th>
|
528 |
+
</tr>
|
529 |
+
<tr>
|
530 |
+
<td colspan="2">Any of the custom fields listed below will be excluded from monitoring. This means that if they are changed or updated the plugin will not log such activity.</td>
|
531 |
+
</tr>
|
532 |
+
<tr>
|
533 |
+
<th><label for="CustomQueryBox"><?php _e('Excluded Custom Fields', 'wp-security-audit-log'); ?></label></th>
|
534 |
+
<td>
|
535 |
+
<fieldset>
|
536 |
+
<input type="text" id="CustomQueryBox" style="float: left; display: block; width: 250px;">
|
537 |
+
<input type="button" id="CustomQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
538 |
+
<br style="clear: both;"/>
|
539 |
+
<div id="CustomList">
|
540 |
+
<?php foreach ($this->_plugin->settings->GetExcludedMonitoringCustom() as $item) { ?>
|
541 |
+
<span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
542 |
+
<input type="hidden" name="Customs[]" value="<?php echo esc_attr($item); ?>"/>
|
543 |
+
<?php echo esc_html($item); ?>
|
544 |
+
<a href="javascript:;" title="Remove">×</a>
|
545 |
+
</span>
|
546 |
+
<?php } ?>
|
547 |
+
</div>
|
548 |
+
</fieldset>
|
549 |
+
</td>
|
550 |
+
</tr>
|
551 |
+
<tr>
|
552 |
+
<th><h2>IP Addresses</h2></th>
|
553 |
+
</tr>
|
554 |
+
<tr>
|
555 |
+
<td colspan="2">Any of the IP addresses listed below will be excluded from monitoring. This means that all activity from such IP address will not be recorded.</td>
|
556 |
+
</tr>
|
557 |
+
<tr>
|
558 |
+
<th><label for="IpAddrQueryBox"><?php _e('Excluded IP Addresses', 'wp-security-audit-log'); ?></label></th>
|
559 |
+
<td>
|
560 |
+
<fieldset>
|
561 |
+
<input type="text" id="IpAddrQueryBox" style="float: left; display: block; width: 250px;">
|
562 |
+
<input type="button" id="IpAddrQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
|
563 |
+
<br style="clear: both;"/>
|
564 |
+
<div id="IpAddrList">
|
565 |
+
<?php foreach ($this->_plugin->settings->GetExcludedMonitoringIP() as $item) { ?>
|
566 |
+
<span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
|
567 |
+
<input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr($item); ?>"/>
|
568 |
+
<?php echo esc_html($item); ?>
|
569 |
+
<a href="javascript:;" title="Remove">×</a>
|
570 |
+
</span>
|
571 |
+
<?php } ?>
|
572 |
+
</div>
|
573 |
+
</fieldset>
|
574 |
+
</td>
|
575 |
+
</tr>
|
576 |
+
</tbody>
|
577 |
+
</table>
|
578 |
+
</div>
|
579 |
+
<p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes"></p>
|
580 |
+
</form>
|
581 |
+
<script type="text/javascript">
|
582 |
+
<!--
|
583 |
+
function delete_confirm(elementRef)
|
584 |
+
{
|
585 |
+
if ( elementRef.checked )
|
586 |
+
{
|
587 |
+
if ( window.confirm('Do you want remove all data when the plugin is deleted?') == false )
|
588 |
+
elementRef.checked = false;
|
589 |
+
}
|
590 |
+
}
|
591 |
+
// -->
|
592 |
+
</script><?php
|
593 |
+
}
|
594 |
+
|
595 |
+
public function Header()
|
596 |
+
{
|
597 |
+
wp_enqueue_style(
|
598 |
+
'settings',
|
599 |
+
$this->_plugin->GetBaseUrl() . '/css/settings.css',
|
600 |
+
array(),
|
601 |
+
filemtime($this->_plugin->GetBaseDir() . '/css/settings.css')
|
602 |
+
);
|
603 |
+
?><style type="text/css">
|
604 |
+
.wsal-tab {
|
605 |
+
display: none;
|
606 |
+
}
|
607 |
+
.wsal-tab tr.alert-incomplete td {
|
608 |
+
color: #9BE;
|
609 |
+
}
|
610 |
+
.wsal-tab tr.alert-unavailable td {
|
611 |
+
color: #CCC;
|
612 |
+
}
|
613 |
+
</style><?php
|
614 |
+
}
|
615 |
+
|
616 |
+
public function Footer()
|
617 |
+
{
|
618 |
+
wp_enqueue_script(
|
619 |
+
'settings',
|
620 |
+
$this->_plugin->GetBaseUrl() . '/js/settings.js',
|
621 |
+
array(),
|
622 |
+
filemtime($this->_plugin->GetBaseDir() . '/js/settings.js')
|
623 |
+
);
|
624 |
+
?><script type="text/javascript">
|
625 |
+
jQuery(document).ready(function(){
|
626 |
+
// tab handling code
|
627 |
+
jQuery('#wsal-tabs>a').click(function(){
|
628 |
+
jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
|
629 |
+
jQuery('table.wsal-tab').hide();
|
630 |
+
jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
|
631 |
+
});
|
632 |
+
// show relevant tab
|
633 |
+
var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
|
634 |
+
if (hashlink.length) {
|
635 |
+
hashlink.click();
|
636 |
+
} else {
|
637 |
+
jQuery('#wsal-tabs>a:first').click();
|
638 |
+
}
|
639 |
+
|
640 |
+
jQuery(".sel-columns").change(function(){
|
641 |
+
var notChecked = 1;
|
642 |
+
jQuery(".sel-columns").each(function(){
|
643 |
+
if(this.checked) notChecked = 0;
|
644 |
+
})
|
645 |
+
if(notChecked == 1){
|
646 |
+
alert("You have to select at least one column!");
|
647 |
+
}
|
648 |
+
});
|
649 |
+
});
|
650 |
+
</script><?php
|
651 |
+
}
|
652 |
+
|
653 |
+
public function AjaxGetAllUsers()
|
654 |
+
{
|
655 |
+
if (!$this->_plugin->settings->CurrentUserCan('view')) {
|
656 |
+
die('Access Denied.');
|
657 |
+
}
|
658 |
+
$users = array();
|
659 |
+
foreach (get_users() as $user) {
|
660 |
+
if (strpos($user->user_login, $_GET['term']) !== false) {
|
661 |
+
array_push($users, $user->user_login);
|
662 |
+
}
|
663 |
+
}
|
664 |
+
echo json_encode($users);
|
665 |
+
exit;
|
666 |
+
}
|
667 |
+
|
668 |
+
public function AjaxGetAllRoles()
|
669 |
+
{
|
670 |
+
if (!$this->_plugin->settings->CurrentUserCan('view')) {
|
671 |
+
die('Access Denied.');
|
672 |
+
}
|
673 |
+
$roles = array();
|
674 |
+
foreach (get_editable_roles() as $role_name => $role_info) {
|
675 |
+
if (strpos($role_name, $_GET['term']) !== false) {
|
676 |
+
array_push($roles, $role_name);
|
677 |
+
}
|
678 |
+
}
|
679 |
+
echo json_encode($roles);
|
680 |
+
exit;
|
681 |
+
}
|
682 |
+
}
|
classes/Views/ToggleAlerts.php
CHANGED
@@ -1,150 +1,150 @@
|
|
1 |
-
<?php
|
2 |
-
class WSAL_Views_ToggleAlerts extends WSAL_AbstractView
|
3 |
-
{
|
4 |
-
|
5 |
-
public function GetTitle() {
|
6 |
-
return __('Enable/Disable Alerts', 'wp-security-audit-log');
|
7 |
-
}
|
8 |
-
|
9 |
-
public function GetIcon() {
|
10 |
-
return 'dashicons-forms';
|
11 |
-
}
|
12 |
-
|
13 |
-
public function GetName() {
|
14 |
-
return __('Enable/Disable Alerts', 'wp-security-audit-log');
|
15 |
-
}
|
16 |
-
|
17 |
-
public function GetWeight() {
|
18 |
-
return 2;
|
19 |
-
}
|
20 |
-
|
21 |
-
protected function GetSafeCatgName($name) {
|
22 |
-
return strtolower(
|
23 |
-
preg_replace('/[^A-Za-z0-9\-]/', '-', $name)
|
24 |
-
);
|
25 |
-
}
|
26 |
-
|
27 |
-
public function Render()
|
28 |
-
{
|
29 |
-
if (!$this->_plugin->settings->CurrentUserCan('edit')) {
|
30 |
-
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-security-audit-log'));
|
31 |
-
}
|
32 |
-
$alert = new WSAL_Alert(); // IDE type hinting
|
33 |
-
$groupedAlerts = $this->_plugin->alerts->GetCategorizedAlerts();
|
34 |
-
$safeNames = array_map(array($this, 'GetSafeCatgName'), array_keys($groupedAlerts));
|
35 |
-
$safeNames = array_combine(array_keys($groupedAlerts), $safeNames);
|
36 |
-
if (isset($_POST['submit']) && isset($_POST['alert'])) {
|
37 |
-
check_admin_referer('wsal-togglealerts');
|
38 |
-
try {
|
39 |
-
$enabled = array_map('intval', $_POST['alert']);
|
40 |
-
$disabled = array();
|
41 |
-
foreach ($this->_plugin->alerts->GetAlerts() as $alert)
|
42 |
-
if (!in_array($alert->type, $enabled))
|
43 |
-
$disabled[] = $alert->type;
|
44 |
-
$this->_plugin->alerts->SetDisabledAlerts($disabled);
|
45 |
-
?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
|
46 |
-
} catch (Exception $ex) {
|
47 |
-
?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
|
48 |
-
}
|
49 |
-
}
|
50 |
-
?><h2 id="wsal-tabs" class="nav-tab-wrapper"><?php
|
51 |
-
foreach ($safeNames as $name => $safe) {
|
52 |
-
?><a href="#tab-<?php echo $safe; ?>" class="nav-tab"><?php echo $name; ?></a><?php
|
53 |
-
}
|
54 |
-
?></h2>
|
55 |
-
<form id="audit-log-viewer" method="post">
|
56 |
-
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
57 |
-
<?php wp_nonce_field('wsal-togglealerts'); ?>
|
58 |
-
|
59 |
-
<div class="nav-tabs"><?php
|
60 |
-
foreach ($groupedAlerts as $name => $alerts) {
|
61 |
-
$active = array();
|
62 |
-
$allactive = true;
|
63 |
-
foreach ($alerts as $alert) {
|
64 |
-
if ($alert->type <= 0006) continue; // <- ignore php alerts
|
65 |
-
if ($alert->type == 9999) continue; // <- ignore promo alerts
|
66 |
-
$active[$alert->type] = $this->_plugin->alerts->IsEnabled($alert->type);
|
67 |
-
if (!$active[$alert->type]) $allactive = false;
|
68 |
-
}
|
69 |
-
?><table class="wp-list-table wsal-tab widefat fixed" cellspacing="0" id="tab-<?php echo $safeNames[$name]; ?>">
|
70 |
-
<thead>
|
71 |
-
<tr>
|
72 |
-
<th width="48"><input type="checkbox"<?php if ($allactive) echo 'checked="checked"'; ?>/></th>
|
73 |
-
<th width="80"><?php _e('Code', 'wp-security-audit-log'); ?></th>
|
74 |
-
<th width="100"><?php _e('Type', 'wp-security-audit-log'); ?></th>
|
75 |
-
<th><?php _e('Description', 'wp-security-audit-log'); ?></th>
|
76 |
-
</tr>
|
77 |
-
</thead>
|
78 |
-
<tbody><?php
|
79 |
-
foreach ($alerts as $alert) {
|
80 |
-
if ($alert->type <= 0006) continue; // <- ignore php alerts
|
81 |
-
if ($alert->type == 9999) continue; // <- ignore promo alerts
|
82 |
-
$attrs = '';
|
83 |
-
switch (true) {
|
84 |
-
case !$alert->mesg:
|
85 |
-
$attrs = ' title="'. __('Not Implemented', 'wp-security-audit-log') . '" class="alert-incomplete"';
|
86 |
-
break;
|
87 |
-
case false:
|
88 |
-
$attrs = ' title="'. __('Not Available', 'wp-security-audit-log') . '" class="alert-unavailable"';
|
89 |
-
break;
|
90 |
-
}
|
91 |
-
?><tr<?php echo $attrs; ?>>
|
92 |
-
<th><input name="alert[]" type="checkbox" <?php if ($active[$alert->type]) echo 'checked="checked"'; ?> value="<?php echo (int)$alert->type; ?>"></th>
|
93 |
-
<td><?php echo str_pad($alert->type, 4, '0', STR_PAD_LEFT); ?></td>
|
94 |
-
<td><?php echo $this->_plugin->constants->GetConstantBy('value', $alert->code)->name; ?></td>
|
95 |
-
<td><?php echo esc_html($alert->desc); ?></td>
|
96 |
-
</tr><?php
|
97 |
-
}
|
98 |
-
?></tbody>
|
99 |
-
</table><?php
|
100 |
-
}
|
101 |
-
?></div>
|
102 |
-
<p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php echo esc_attr(__('Save Changes', 'wp-security-audit-log')); ?>"></p>
|
103 |
-
</form><?php
|
104 |
-
}
|
105 |
-
|
106 |
-
public function Header()
|
107 |
-
{
|
108 |
-
?><style type="text/css">
|
109 |
-
.wsal-tab {
|
110 |
-
display: none;
|
111 |
-
}
|
112 |
-
.wsal-tab tr.alert-incomplete td {
|
113 |
-
color: #9BE;
|
114 |
-
}
|
115 |
-
.wsal-tab tr.alert-unavailable td {
|
116 |
-
color: #CCC;
|
117 |
-
}
|
118 |
-
</style><?php
|
119 |
-
}
|
120 |
-
|
121 |
-
public function Footer()
|
122 |
-
{
|
123 |
-
?><script type="text/javascript">
|
124 |
-
jQuery(document).ready(function(){
|
125 |
-
// tab handling code
|
126 |
-
jQuery('#wsal-tabs>a').click(function(){
|
127 |
-
jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
|
128 |
-
jQuery('table.wsal-tab').hide();
|
129 |
-
jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
|
130 |
-
});
|
131 |
-
// checkbox handling code
|
132 |
-
jQuery('table.wsal-tab>thead>tr>th>:checkbox').change(function(){
|
133 |
-
jQuery(this).parents('table:first').find('tbody>tr>th>:checkbox').attr('checked', this.checked);
|
134 |
-
});
|
135 |
-
jQuery('table.wsal-tab>tbody>tr>th>:checkbox').change(function(){
|
136 |
-
var allchecked = jQuery(this).parents('tbody:first').find('th>:checkbox:not(:checked)').length === 0;
|
137 |
-
jQuery(this).parents('table:first').find('thead>tr>th:first>:checkbox:first').attr('checked', allchecked);
|
138 |
-
});
|
139 |
-
// show relevant tab
|
140 |
-
var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
|
141 |
-
if(hashlink.length){
|
142 |
-
hashlink.click();
|
143 |
-
}else{
|
144 |
-
jQuery('#wsal-tabs>a:first').click();
|
145 |
-
}
|
146 |
-
});
|
147 |
-
</script><?php
|
148 |
-
}
|
149 |
-
|
150 |
-
}
|
1 |
+
<?php
|
2 |
+
class WSAL_Views_ToggleAlerts extends WSAL_AbstractView
|
3 |
+
{
|
4 |
+
|
5 |
+
public function GetTitle() {
|
6 |
+
return __('Enable/Disable Alerts', 'wp-security-audit-log');
|
7 |
+
}
|
8 |
+
|
9 |
+
public function GetIcon() {
|
10 |
+
return 'dashicons-forms';
|
11 |
+
}
|
12 |
+
|
13 |
+
public function GetName() {
|
14 |
+
return __('Enable/Disable Alerts', 'wp-security-audit-log');
|
15 |
+
}
|
16 |
+
|
17 |
+
public function GetWeight() {
|
18 |
+
return 2;
|
19 |
+
}
|
20 |
+
|
21 |
+
protected function GetSafeCatgName($name) {
|
22 |
+
return strtolower(
|
23 |
+
preg_replace('/[^A-Za-z0-9\-]/', '-', $name)
|
24 |
+
);
|
25 |
+
}
|
26 |
+
|
27 |
+
public function Render()
|
28 |
+
{
|
29 |
+
if (!$this->_plugin->settings->CurrentUserCan('edit')) {
|
30 |
+
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-security-audit-log'));
|
31 |
+
}
|
32 |
+
$alert = new WSAL_Alert(); // IDE type hinting
|
33 |
+
$groupedAlerts = $this->_plugin->alerts->GetCategorizedAlerts();
|
34 |
+
$safeNames = array_map(array($this, 'GetSafeCatgName'), array_keys($groupedAlerts));
|
35 |
+
$safeNames = array_combine(array_keys($groupedAlerts), $safeNames);
|
36 |
+
if (isset($_POST['submit']) && isset($_POST['alert'])) {
|
37 |
+
check_admin_referer('wsal-togglealerts');
|
38 |
+
try {
|
39 |
+
$enabled = array_map('intval', $_POST['alert']);
|
40 |
+
$disabled = array();
|
41 |
+
foreach ($this->_plugin->alerts->GetAlerts() as $alert)
|
42 |
+
if (!in_array($alert->type, $enabled))
|
43 |
+
$disabled[] = $alert->type;
|
44 |
+
$this->_plugin->alerts->SetDisabledAlerts($disabled);
|
45 |
+
?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
|
46 |
+
} catch (Exception $ex) {
|
47 |
+
?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
|
48 |
+
}
|
49 |
+
}
|
50 |
+
?><h2 id="wsal-tabs" class="nav-tab-wrapper"><?php
|
51 |
+
foreach ($safeNames as $name => $safe) {
|
52 |
+
?><a href="#tab-<?php echo $safe; ?>" class="nav-tab"><?php echo $name; ?></a><?php
|
53 |
+
}
|
54 |
+
?></h2>
|
55 |
+
<form id="audit-log-viewer" method="post">
|
56 |
+
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
|
57 |
+
<?php wp_nonce_field('wsal-togglealerts'); ?>
|
58 |
+
|
59 |
+
<div class="nav-tabs"><?php
|
60 |
+
foreach ($groupedAlerts as $name => $alerts) {
|
61 |
+
$active = array();
|
62 |
+
$allactive = true;
|
63 |
+
foreach ($alerts as $alert) {
|
64 |
+
if ($alert->type <= 0006) continue; // <- ignore php alerts
|
65 |
+
if ($alert->type == 9999) continue; // <- ignore promo alerts
|
66 |
+
$active[$alert->type] = $this->_plugin->alerts->IsEnabled($alert->type);
|
67 |
+
if (!$active[$alert->type]) $allactive = false;
|
68 |
+
}
|
69 |
+
?><table class="wp-list-table wsal-tab widefat fixed" cellspacing="0" id="tab-<?php echo $safeNames[$name]; ?>">
|
70 |
+
<thead>
|
71 |
+
<tr>
|
72 |
+
<th width="48"><input type="checkbox"<?php if ($allactive) echo 'checked="checked"'; ?>/></th>
|
73 |
+
<th width="80"><?php _e('Code', 'wp-security-audit-log'); ?></th>
|
74 |
+
<th width="100"><?php _e('Type', 'wp-security-audit-log'); ?></th>
|
75 |
+
<th><?php _e('Description', 'wp-security-audit-log'); ?></th>
|
76 |
+
</tr>
|
77 |
+
</thead>
|
78 |
+
<tbody><?php
|
79 |
+
foreach ($alerts as $alert) {
|
80 |
+
if ($alert->type <= 0006) continue; // <- ignore php alerts
|
81 |
+
if ($alert->type == 9999) continue; // <- ignore promo alerts
|
82 |
+
$attrs = '';
|
83 |
+
switch (true) {
|
84 |
+
case !$alert->mesg:
|
85 |
+
$attrs = ' title="'. __('Not Implemented', 'wp-security-audit-log') . '" class="alert-incomplete"';
|
86 |
+
break;
|
87 |
+
case false:
|
88 |
+
$attrs = ' title="'. __('Not Available', 'wp-security-audit-log') . '" class="alert-unavailable"';
|
89 |
+
break;
|
90 |
+
}
|
91 |
+
?><tr<?php echo $attrs; ?>>
|
92 |
+
<th><input name="alert[]" type="checkbox" <?php if ($active[$alert->type]) echo 'checked="checked"'; ?> value="<?php echo (int)$alert->type; ?>"></th>
|
93 |
+
<td><?php echo str_pad($alert->type, 4, '0', STR_PAD_LEFT); ?></td>
|
94 |
+
<td><?php echo $this->_plugin->constants->GetConstantBy('value', $alert->code)->name; ?></td>
|
95 |
+
<td><?php echo esc_html($alert->desc); ?></td>
|
96 |
+
</tr><?php
|
97 |
+
}
|
98 |
+
?></tbody>
|
99 |
+
</table><?php
|
100 |
+
}
|
101 |
+
?></div>
|
102 |
+
<p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php echo esc_attr(__('Save Changes', 'wp-security-audit-log')); ?>"></p>
|
103 |
+
</form><?php
|
104 |
+
}
|
105 |
+
|
106 |
+
public function Header()
|
107 |
+
{
|
108 |
+
?><style type="text/css">
|
109 |
+
.wsal-tab {
|
110 |
+
display: none;
|
111 |
+
}
|
112 |
+
.wsal-tab tr.alert-incomplete td {
|
113 |
+
color: #9BE;
|
114 |
+
}
|
115 |
+
.wsal-tab tr.alert-unavailable td {
|
116 |
+
color: #CCC;
|
117 |
+
}
|
118 |
+
</style><?php
|
119 |
+
}
|
120 |
+
|
121 |
+
public function Footer()
|
122 |
+
{
|
123 |
+
?><script type="text/javascript">
|
124 |
+
jQuery(document).ready(function(){
|
125 |
+
// tab handling code
|
126 |
+
jQuery('#wsal-tabs>a').click(function(){
|
127 |
+
jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
|
128 |
+
jQuery('table.wsal-tab').hide();
|
129 |
+
jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
|
130 |
+
});
|
131 |
+
// checkbox handling code
|
132 |
+
jQuery('table.wsal-tab>thead>tr>th>:checkbox').change(function(){
|
133 |
+
jQuery(this).parents('table:first').find('tbody>tr>th>:checkbox').attr('checked', this.checked);
|
134 |
+
});
|
135 |
+
jQuery('table.wsal-tab>tbody>tr>th>:checkbox').change(function(){
|
136 |
+
var allchecked = jQuery(this).parents('tbody:first').find('th>:checkbox:not(:checked)').length === 0;
|
137 |
+
jQuery(this).parents('table:first').find('thead>tr>th:first>:checkbox:first').attr('checked', allchecked);
|
138 |
+
});
|
139 |
+
// show relevant tab
|
140 |
+
var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
|
141 |
+
if(hashlink.length){
|
142 |
+
hashlink.click();
|
143 |
+
}else{
|
144 |
+
jQuery('#wsal-tabs>a:first').click();
|
145 |
+
}
|
146 |
+
});
|
147 |
+
</script><?php
|
148 |
+
}
|
149 |
+
|
150 |
+
}
|
classes/WidgetManager.php
CHANGED
@@ -1,79 +1,79 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WSAL_WidgetManager
|
4 |
-
{
|
5 |
-
/**
|
6 |
-
* @var WpSecurityAuditLog
|
7 |
-
*/
|
8 |
-
protected $_plugin;
|
9 |
-
|
10 |
-
public function __construct(WpSecurityAuditLog $plugin)
|
11 |
-
{
|
12 |
-
$this->_plugin = $plugin;
|
13 |
-
add_action('wp_dashboard_setup', array($this, 'AddWidgets'));
|
14 |
-
}
|
15 |
-
|
16 |
-
public function AddWidgets()
|
17 |
-
{
|
18 |
-
if ($this->_plugin->settings->IsWidgetsEnabled()
|
19 |
-
&& $this->_plugin->settings->CurrentUserCan('view')) {
|
20 |
-
wp_add_dashboard_widget(
|
21 |
-
'wsal',
|
22 |
-
__('Latest Alerts', 'wp-security-audit-log') . ' | WP Security Audit Log',
|
23 |
-
array($this, 'RenderWidget')
|
24 |
-
);
|
25 |
-
}
|
26 |
-
}
|
27 |
-
|
28 |
-
public function RenderWidget()
|
29 |
-
{
|
30 |
-
$query = new WSAL_Models_OccurrenceQuery();
|
31 |
-
|
32 |
-
$bid = (int)$this->get_view_site_id();
|
33 |
-
if ($bid) {
|
34 |
-
$query->addCondition("site_id = %s ", $bid);
|
35 |
-
}
|
36 |
-
$query->addOrderBy("created_on", true);
|
37 |
-
$query->setLimit($this->_plugin->settings->GetDashboardWidgetMaxAlerts());
|
38 |
-
$results = $query->getAdapter()->Execute($query);
|
39 |
-
|
40 |
-
?><div><?php
|
41 |
-
if (!count($results)) {
|
42 |
-
?><p><?php _e('No alerts found.', 'wp-security-audit-log'); ?></p><?php
|
43 |
-
} else {
|
44 |
-
?><table class="wp-list-table widefat" cellspacing="0" cellpadding="0"
|
45 |
-
style="display: block; overflow-x: auto;">
|
46 |
-
<thead>
|
47 |
-
<th class="manage-column" style="width: 15%;" scope="col"><?php _e('User', 'wp-security-audit-log'); ?></th>
|
48 |
-
<th class="manage-column" style="width: 85%;" scope="col"><?php _e('Description', 'wp-security-audit-log'); ?></th>
|
49 |
-
</thead>
|
50 |
-
<tbody><?php
|
51 |
-
$url = 'admin.php?page=' . $this->_plugin->views->views[0]->GetSafeViewName();
|
52 |
-
$fmt = array(new WSAL_AuditLogListView($this->_plugin), 'meta_formatter');
|
53 |
-
foreach ($results as $entry) {
|
54 |
-
?><tr>
|
55 |
-
<td><?php
|
56 |
-
echo ($un = $entry->GetUsername()) ? esc_html($un) : '<i>unknown</i>';
|
57 |
-
?></td>
|
58 |
-
<td>
|
59 |
-
<a href="<?php echo $url . '#Event' . $entry->id; ?>"><?php
|
60 |
-
echo $entry->GetMessage($fmt);
|
61 |
-
?></a>
|
62 |
-
</td>
|
63 |
-
</tr><?php
|
64 |
-
}
|
65 |
-
?></tbody>
|
66 |
-
</table><?php
|
67 |
-
}
|
68 |
-
?></div><?php
|
69 |
-
}
|
70 |
-
|
71 |
-
protected function get_view_site_id()
|
72 |
-
{
|
73 |
-
if (is_super_admin()) {
|
74 |
-
return 0;
|
75 |
-
} else {
|
76 |
-
return get_current_blog_id();
|
77 |
-
}
|
78 |
-
}
|
79 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WSAL_WidgetManager
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* @var WpSecurityAuditLog
|
7 |
+
*/
|
8 |
+
protected $_plugin;
|
9 |
+
|
10 |
+
public function __construct(WpSecurityAuditLog $plugin)
|
11 |
+
{
|
12 |
+
$this->_plugin = $plugin;
|
13 |
+
add_action('wp_dashboard_setup', array($this, 'AddWidgets'));
|
14 |
+
}
|
15 |
+
|
16 |
+
public function AddWidgets()
|
17 |
+
{
|
18 |
+
if ($this->_plugin->settings->IsWidgetsEnabled()
|
19 |
+
&& $this->_plugin->settings->CurrentUserCan('view')) {
|
20 |
+
wp_add_dashboard_widget(
|
21 |
+
'wsal',
|
22 |
+
__('Latest Alerts', 'wp-security-audit-log') . ' | WP Security Audit Log',
|
23 |
+
array($this, 'RenderWidget')
|
24 |
+
);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
public function RenderWidget()
|
29 |
+
{
|
30 |
+
$query = new WSAL_Models_OccurrenceQuery();
|
31 |
+
|
32 |
+
$bid = (int)$this->get_view_site_id();
|
33 |
+
if ($bid) {
|
34 |
+
$query->addCondition("site_id = %s ", $bid);
|
35 |
+
}
|
36 |
+
$query->addOrderBy("created_on", true);
|
37 |
+
$query->setLimit($this->_plugin->settings->GetDashboardWidgetMaxAlerts());
|
38 |
+
$results = $query->getAdapter()->Execute($query);
|
39 |
+
|
40 |
+
?><div><?php
|
41 |
+
if (!count($results)) {
|
42 |
+
?><p><?php _e('No alerts found.', 'wp-security-audit-log'); ?></p><?php
|
43 |
+
} else {
|
44 |
+
?><table class="wp-list-table widefat" cellspacing="0" cellpadding="0"
|
45 |
+
style="display: block; overflow-x: auto;">
|
46 |
+
<thead>
|
47 |
+
<th class="manage-column" style="width: 15%;" scope="col"><?php _e('User', 'wp-security-audit-log'); ?></th>
|
48 |
+
<th class="manage-column" style="width: 85%;" scope="col"><?php _e('Description', 'wp-security-audit-log'); ?></th>
|
49 |
+
</thead>
|
50 |
+
<tbody><?php
|
51 |
+
$url = 'admin.php?page=' . $this->_plugin->views->views[0]->GetSafeViewName();
|
52 |
+
$fmt = array(new WSAL_AuditLogListView($this->_plugin), 'meta_formatter');
|
53 |
+
foreach ($results as $entry) {
|
54 |
+
?><tr>
|
55 |
+
<td><?php
|
56 |
+
echo ($un = $entry->GetUsername()) ? esc_html($un) : '<i>unknown</i>';
|
57 |
+
?></td>
|
58 |
+
<td>
|
59 |
+
<a href="<?php echo $url . '#Event' . $entry->id; ?>"><?php
|
60 |
+
echo $entry->GetMessage($fmt);
|
61 |
+
?></a>
|
62 |
+
</td>
|
63 |
+
</tr><?php
|
64 |
+
}
|
65 |
+
?></tbody>
|
66 |
+
</table><?php
|
67 |
+
}
|
68 |
+
?></div><?php
|
69 |
+
}
|
70 |
+
|
71 |
+
protected function get_view_site_id()
|
72 |
+
{
|
73 |
+
if (is_super_admin()) {
|
74 |
+
return 0;
|
75 |
+
} else {
|
76 |
+
return get_current_blog_id();
|
77 |
+
}
|
78 |
+
}
|
79 |
+
}
|
css/auditlog.css
CHANGED
@@ -1,180 +1,180 @@
|
|
1 |
-
.wsal-ipp,
|
2 |
-
.wsal-ssa {
|
3 |
-
display: inline-block;
|
4 |
-
color: #555;
|
5 |
-
line-height: 30px;
|
6 |
-
font-size: 12px;
|
7 |
-
}
|
8 |
-
|
9 |
-
.wsal-ipp select {
|
10 |
-
margin-bottom: 6px;
|
11 |
-
width: 56px;
|
12 |
-
}
|
13 |
-
|
14 |
-
.wsal-ssa input,
|
15 |
-
.wsal-ssa select {
|
16 |
-
margin-bottom: 6px;
|
17 |
-
width: 120px;
|
18 |
-
margin-left: 16px;
|
19 |
-
}
|
20 |
-
|
21 |
-
.column-read,
|
22 |
-
.column-type,
|
23 |
-
.column-code,
|
24 |
-
.column-more,
|
25 |
-
.column-data {
|
26 |
-
width: 70px;
|
27 |
-
}
|
28 |
-
|
29 |
-
.column-crtd {
|
30 |
-
width: 125px;
|
31 |
-
}
|
32 |
-
|
33 |
-
.column-user {
|
34 |
-
width: 160px;
|
35 |
-
}
|
36 |
-
|
37 |
-
.column-site {
|
38 |
-
width: 160px;
|
39 |
-
}
|
40 |
-
|
41 |
-
td.column-user {
|
42 |
-
font-size: 75% !important;
|
43 |
-
}
|
44 |
-
|
45 |
-
.column-user img {
|
46 |
-
float: left;
|
47 |
-
margin-right: 4px;
|
48 |
-
-webkit-border-radius: 50px;
|
49 |
-
-moz-border-radius: 50px;
|
50 |
-
-ms-border-radius: 50px;
|
51 |
-
border-radius: 50px;
|
52 |
-
}
|
53 |
-
|
54 |
-
.column-scip {
|
55 |
-
width: 120px;
|
56 |
-
}
|
57 |
-
|
58 |
-
.more-info {
|
59 |
-
float: right;
|
60 |
-
display: block;
|
61 |
-
width: 16px;
|
62 |
-
height: 16px;
|
63 |
-
color: #FFF;
|
64 |
-
font-weight: bold;
|
65 |
-
font-size: 13px;
|
66 |
-
line-height: 10px;
|
67 |
-
text-align: center;
|
68 |
-
border-radius: 32px;
|
69 |
-
margin-left: 8px;
|
70 |
-
background: #AAA;
|
71 |
-
}
|
72 |
-
|
73 |
-
.more-info:hover {
|
74 |
-
color: #FFF;
|
75 |
-
background: #333;
|
76 |
-
}
|
77 |
-
|
78 |
-
.log-read:after {
|
79 |
-
display: block;
|
80 |
-
width: 16px;
|
81 |
-
height: 16px;
|
82 |
-
color: #FFF;
|
83 |
-
font-weight: bold;
|
84 |
-
font-size: 13px;
|
85 |
-
line-height: 16px;
|
86 |
-
text-align: center;
|
87 |
-
border-radius: 32px;
|
88 |
-
margin-left: 8px;
|
89 |
-
content: "\2713";
|
90 |
-
background: #CCC;
|
91 |
-
}
|
92 |
-
|
93 |
-
.log-read-new:after {
|
94 |
-
background: #290;
|
95 |
-
}
|
96 |
-
|
97 |
-
.log-type {
|
98 |
-
cursor: help;
|
99 |
-
}
|
100 |
-
|
101 |
-
.log-type:after {
|
102 |
-
display: block;
|
103 |
-
width: 16px;
|
104 |
-
height: 16px;
|
105 |
-
color: #FFF;
|
106 |
-
font-weight: bold;
|
107 |
-
font-size: 11px;
|
108 |
-
line-height: 17px;
|
109 |
-
background: #CCC;
|
110 |
-
text-align: center;
|
111 |
-
border-radius: 32px;
|
112 |
-
margin-left: 8px;
|
113 |
-
}
|
114 |
-
|
115 |
-
/* errors */
|
116 |
-
.log-type-0:after,
|
117 |
-
.log-type-1:after,
|
118 |
-
.log-type-4:after,
|
119 |
-
.log-type-16:after,
|
120 |
-
.log-type-64:after,
|
121 |
-
.log-type-256:after,
|
122 |
-
.log-type-4096:after,
|
123 |
-
.log-type-E_CRITICAL:after
|
124 |
-
{ background: #E00; content: "!"; }
|
125 |
-
|
126 |
-
/* warnings */
|
127 |
-
.log-type-2:after,
|
128 |
-
.log-type-32:after,
|
129 |
-
.log-type-128:after,
|
130 |
-
.log-type-512:after
|
131 |
-
{ background: #EB0; content: "!"; }
|
132 |
-
|
133 |
-
/* notices/strict/deprecation */
|
134 |
-
.log-type-8:after,
|
135 |
-
.log-type-1024:after,
|
136 |
-
.log-type-2048:after,
|
137 |
-
.log-type-8192:after,
|
138 |
-
.log-type-16384:after,
|
139 |
-
.log-type-E_DEBUG:after
|
140 |
-
{ background: #09E; content: "i"; }
|
141 |
-
|
142 |
-
/* search box */
|
143 |
-
.wsal-ssas-dd {
|
144 |
-
position: absolute;
|
145 |
-
border: 1px solid windowframe;
|
146 |
-
background: #FFF;
|
147 |
-
padding: 0;
|
148 |
-
margin: -8px 16px;
|
149 |
-
background: window;
|
150 |
-
color: windowtext;
|
151 |
-
min-width: 140px;
|
152 |
-
}
|
153 |
-
.wsal-ssas-dd * {
|
154 |
-
cursor: default;
|
155 |
-
}
|
156 |
-
.wsal-ssas-dd a {
|
157 |
-
padding: 2px 8px;
|
158 |
-
display: block;
|
159 |
-
line-height: normal;
|
160 |
-
text-decoration: none;
|
161 |
-
color: windowtext;
|
162 |
-
}
|
163 |
-
.wsal-ssas-dd a:hover,
|
164 |
-
.wsal-ssas-dd .active {
|
165 |
-
background: highlight;
|
166 |
-
color: highlighttext;
|
167 |
-
}
|
168 |
-
.wsal-ssas-dd a u {
|
169 |
-
text-decoration: underline;
|
170 |
-
}
|
171 |
-
.wsal-ssas-dd span {
|
172 |
-
color: #555;
|
173 |
-
font-style: italic;
|
174 |
-
padding: 2px 8px;
|
175 |
-
display: block;
|
176 |
-
line-height: normal;
|
177 |
-
}
|
178 |
-
.wsal-ssas-dd .allsites {
|
179 |
-
border-bottom: 1px solid windowframe;
|
180 |
-
}
|
1 |
+
.wsal-ipp,
|
2 |
+
.wsal-ssa {
|
3 |
+
display: inline-block;
|
4 |
+
color: #555;
|
5 |
+
line-height: 30px;
|
6 |
+
font-size: 12px;
|
7 |
+
}
|
8 |
+
|
9 |
+
.wsal-ipp select {
|
10 |
+
margin-bottom: 6px;
|
11 |
+
width: 56px;
|
12 |
+
}
|
13 |
+
|
14 |
+
.wsal-ssa input,
|
15 |
+
.wsal-ssa select {
|
16 |
+
margin-bottom: 6px;
|
17 |
+
width: 120px;
|
18 |
+
margin-left: 16px;
|
19 |
+
}
|
20 |
+
|
21 |
+
.column-read,
|
22 |
+
.column-type,
|
23 |
+
.column-code,
|
24 |
+
.column-more,
|
25 |
+
.column-data {
|
26 |
+
width: 70px;
|
27 |
+
}
|
28 |
+
|
29 |
+
.column-crtd {
|
30 |
+
width: 125px;
|
31 |
+
}
|
32 |
+
|
33 |
+
.column-user {
|
34 |
+
width: 160px;
|
35 |
+
}
|
36 |
+
|
37 |
+
.column-site {
|
38 |
+
width: 160px;
|
39 |
+
}
|
40 |
+
|
41 |
+
td.column-user {
|
42 |
+
font-size: 75% !important;
|
43 |
+
}
|
44 |
+
|
45 |
+
.column-user img {
|
46 |
+
float: left;
|
47 |
+
margin-right: 4px;
|
48 |
+
-webkit-border-radius: 50px;
|
49 |
+
-moz-border-radius: 50px;
|
50 |
+
-ms-border-radius: 50px;
|
51 |
+
border-radius: 50px;
|
52 |
+
}
|
53 |
+
|
54 |
+
.column-scip {
|
55 |
+
width: 120px;
|
56 |
+
}
|
57 |
+
|
58 |
+
.more-info {
|
59 |
+
float: right;
|
60 |
+
display: block;
|
61 |
+
width: 16px;
|
62 |
+
height: 16px;
|
63 |
+
color: #FFF;
|
64 |
+
font-weight: bold;
|
65 |
+
font-size: 13px;
|
66 |
+
line-height: 10px;
|
67 |
+
text-align: center;
|
68 |
+
border-radius: 32px;
|
69 |
+
margin-left: 8px;
|
70 |
+
background: #AAA;
|
71 |
+
}
|
72 |
+
|
73 |
+
.more-info:hover {
|
74 |
+
color: #FFF;
|
75 |
+
background: #333;
|
76 |
+
}
|
77 |
+
|
78 |
+
.log-read:after {
|
79 |
+
display: block;
|
80 |
+
width: 16px;
|
81 |
+
height: 16px;
|
82 |
+
color: #FFF;
|
83 |
+
font-weight: bold;
|
84 |
+
font-size: 13px;
|
85 |
+
line-height: 16px;
|
86 |
+
text-align: center;
|
87 |
+
border-radius: 32px;
|
88 |
+
margin-left: 8px;
|
89 |
+
content: "\2713";
|
90 |
+
background: #CCC;
|
91 |
+
}
|
92 |
+
|
93 |
+
.log-read-new:after {
|
94 |
+
background: #290;
|
95 |
+
}
|
96 |
+
|
97 |
+
.log-type {
|
98 |
+
cursor: help;
|
99 |
+
}
|
100 |
+
|
101 |
+
.log-type:after {
|
102 |
+
display: block;
|
103 |
+
width: 16px;
|
104 |
+
height: 16px;
|
105 |
+
color: #FFF;
|
106 |
+
font-weight: bold;
|
107 |
+
font-size: 11px;
|
108 |
+
line-height: 17px;
|
109 |
+
background: #CCC;
|
110 |
+
text-align: center;
|
111 |
+
border-radius: 32px;
|
112 |
+
margin-left: 8px;
|
113 |
+
}
|
114 |
+
|
115 |
+
/* errors */
|
116 |
+
.log-type-0:after,
|
117 |
+
.log-type-1:after,
|
118 |
+
.log-type-4:after,
|
119 |
+
.log-type-16:after,
|
120 |
+
.log-type-64:after,
|
121 |
+
.log-type-256:after,
|
122 |
+
.log-type-4096:after,
|
123 |
+
.log-type-E_CRITICAL:after
|
124 |
+
{ background: #E00; content: "!"; }
|
125 |
+
|
126 |
+
/* warnings */
|
127 |
+
.log-type-2:after,
|
128 |
+
.log-type-32:after,
|
129 |
+
.log-type-128:after,
|
130 |
+
.log-type-512:after
|
131 |
+
{ background: #EB0; content: "!"; }
|
132 |
+
|
133 |
+
/* notices/strict/deprecation */
|
134 |
+
.log-type-8:after,
|
135 |
+
.log-type-1024:after,
|
136 |
+
.log-type-2048:after,
|
137 |
+
.log-type-8192:after,
|
138 |
+
.log-type-16384:after,
|
139 |
+
.log-type-E_DEBUG:after
|
140 |
+
{ background: #09E; content: "i"; }
|
141 |
+
|
142 |
+
/* search box */
|
143 |
+
.wsal-ssas-dd {
|
144 |
+
position: absolute;
|
145 |
+
border: 1px solid windowframe;
|
146 |
+
background: #FFF;
|
147 |
+
padding: 0;
|
148 |
+
margin: -8px 16px;
|
149 |
+
background: window;
|
150 |
+
color: windowtext;
|
151 |
+
min-width: 140px;
|
152 |
+
}
|
153 |
+
.wsal-ssas-dd * {
|
154 |
+
cursor: default;
|
155 |
+
}
|
156 |
+
.wsal-ssas-dd a {
|
157 |
+
padding: 2px 8px;
|
158 |
+
display: block;
|
159 |
+
line-height: normal;
|
160 |
+
text-decoration: none;
|
161 |
+
color: windowtext;
|
162 |
+
}
|
163 |
+
.wsal-ssas-dd a:hover,
|
164 |
+
.wsal-ssas-dd .active {
|
165 |
+
background: highlight;
|
166 |
+
color: highlighttext;
|
167 |
+
}
|
168 |
+
.wsal-ssas-dd a u {
|
169 |
+
text-decoration: underline;
|
170 |
+
}
|
171 |
+
.wsal-ssas-dd span {
|
172 |
+
color: #555;
|
173 |
+
font-style: italic;
|
174 |
+
padding: 2px 8px;
|
175 |
+
display: block;
|
176 |
+
line-height: normal;
|
177 |
+
}
|
178 |
+
.wsal-ssas-dd .allsites {
|
179 |
+
border-bottom: 1px solid windowframe;
|
180 |
+
}
|
css/install-error.css
CHANGED
@@ -1,41 +1,41 @@
|
|
1 |
-
.warn-icon-tri {
|
2 |
-
top: 5px;
|
3 |
-
left: 5px;
|
4 |
-
position: absolute;
|
5 |
-
border-left: 16px solid #FFF;
|
6 |
-
border-right: 16px solid #FFF;
|
7 |
-
border-bottom: 28px solid #C33;
|
8 |
-
height: 3px;
|
9 |
-
width: 4px
|
10 |
-
}
|
11 |
-
|
12 |
-
.warn-icon-chr {
|
13 |
-
top: 8px;
|
14 |
-
left: 18px;
|
15 |
-
position: absolute;
|
16 |
-
color: #FFF;
|
17 |
-
font: 26px Georgia;
|
18 |
-
}
|
19 |
-
|
20 |
-
.warn-icon-cir {
|
21 |
-
top: 2px;
|
22 |
-
left: 0px;
|
23 |
-
position: absolute;
|
24 |
-
overflow: hidden;
|
25 |
-
border: 6px solid #FFF;
|
26 |
-
border-radius: 32px;
|
27 |
-
width: 34px;
|
28 |
-
height: 34px;
|
29 |
-
}
|
30 |
-
|
31 |
-
.warn-wrap {
|
32 |
-
position: relative;
|
33 |
-
color: #A00;
|
34 |
-
font: 14px Arial;
|
35 |
-
padding: 6px 48px;
|
36 |
-
}
|
37 |
-
|
38 |
-
.warn-wrap a,
|
39 |
-
.warn-wrap a:hover {
|
40 |
-
color: #F56;
|
41 |
-
}
|
1 |
+
.warn-icon-tri {
|
2 |
+
top: 5px;
|
3 |
+
left: 5px;
|
4 |
+
position: absolute;
|
5 |
+
border-left: 16px solid #FFF;
|
6 |
+
border-right: 16px solid #FFF;
|
7 |
+
border-bottom: 28px solid #C33;
|
8 |
+
height: 3px;
|
9 |
+
width: 4px
|
10 |
+
}
|
11 |
+
|
12 |
+
.warn-icon-chr {
|
13 |
+
top: 8px;
|
14 |
+
left: 18px;
|
15 |
+
position: absolute;
|
16 |
+
color: #FFF;
|
17 |
+
font: 26px Georgia;
|
18 |
+
}
|
19 |
+
|
20 |
+
.warn-icon-cir {
|
21 |
+
top: 2px;
|
22 |
+
left: 0px;
|
23 |
+
position: absolute;
|
24 |
+
overflow: hidden;
|
25 |
+
border: 6px solid #FFF;
|
26 |
+
border-radius: 32px;
|
27 |
+
width: 34px;
|
28 |
+
height: 34px;
|
29 |
+
}
|
30 |
+
|
31 |
+
.warn-wrap {
|
32 |
+
position: relative;
|
33 |
+
color: #A00;
|
34 |
+
font: 14px Arial;
|
35 |
+
padding: 6px 48px;
|
36 |
+
}
|
37 |
+
|
38 |
+
.warn-wrap a,
|
39 |
+
.warn-wrap a:hover {
|
40 |
+
color: #F56;
|
41 |
+
}
|
css/nice_r.css
CHANGED
@@ -1,92 +1,92 @@
|
|
1 |
-
.nice_r {
|
2 |
-
font: 12px Consolas, "Lucida Console", monospace;
|
3 |
-
cursor: default;
|
4 |
-
}
|
5 |
-
|
6 |
-
.nice_r a {
|
7 |
-
display: block;
|
8 |
-
text-decoration: none;
|
9 |
-
color: #222;
|
10 |
-
padding: 2px;
|
11 |
-
white-space: nowrap;
|
12 |
-
overflow: hidden;
|
13 |
-
text-overflow: ellipsis;
|
14 |
-
}
|
15 |
-
|
16 |
-
.nice_r a:hover .nice_r_k,
|
17 |
-
.nice_r a:hover .nice_r_d,
|
18 |
-
.nice_r a:hover .nice_r_d span,
|
19 |
-
.nice_r a:hover .nice_r_p,
|
20 |
-
.nice_r a:hover .nice_r_a,
|
21 |
-
.nice_r a:hover {
|
22 |
-
background-color: Highlight;
|
23 |
-
color: HighlightText;
|
24 |
-
}
|
25 |
-
|
26 |
-
.nice_r_a {
|
27 |
-
color: #000;
|
28 |
-
}
|
29 |
-
|
30 |
-
.nice_r_ad {
|
31 |
-
opacity: 0.5;
|
32 |
-
}
|
33 |
-
|
34 |
-
.nice_r_k {
|
35 |
-
color: #060;
|
36 |
-
font-weight: bold;
|
37 |
-
}
|
38 |
-
|
39 |
-
.nice_r_d {
|
40 |
-
font-size: 11px;
|
41 |
-
color: #777;
|
42 |
-
}
|
43 |
-
|
44 |
-
.nice_r_d span {
|
45 |
-
color: #333;
|
46 |
-
}
|
47 |
-
|
48 |
-
.nice_r_p {
|
49 |
-
color: #000;
|
50 |
-
font-weight: bold;
|
51 |
-
}
|
52 |
-
|
53 |
-
.nice_r_v {
|
54 |
-
margin-left: 6px;
|
55 |
-
padding-left: 6px;
|
56 |
-
border-left: 1px dotted #CCC;
|
57 |
-
display: none;
|
58 |
-
}
|
59 |
-
|
60 |
-
.nice_r_ir {
|
61 |
-
font-style: italic;
|
62 |
-
}
|
63 |
-
|
64 |
-
.nice_r_p.nice_r_t_integer,
|
65 |
-
.nice_r_p.nice_r_t_double {
|
66 |
-
color: #F0E;
|
67 |
-
}
|
68 |
-
|
69 |
-
.nice_r_p.nice_r_t_string {
|
70 |
-
color: #E00;
|
71 |
-
}
|
72 |
-
|
73 |
-
.nice_r_p.nice_r_t_boolean {
|
74 |
-
color: #00E;
|
75 |
-
}
|
76 |
-
|
77 |
-
.nice_r_t_comment {
|
78 |
-
color: #080;
|
79 |
-
}
|
80 |
-
|
81 |
-
.nice_r a.nice_r_c .nice_r_k {
|
82 |
-
color: #909;
|
83 |
-
}
|
84 |
-
|
85 |
-
.nice_r a.nice_r_c .nice_r_ma {
|
86 |
-
font-weight: normal;
|
87 |
-
color: #777;
|
88 |
-
}
|
89 |
-
|
90 |
-
.nice_r a.nice_r_c .nice_r_mv {
|
91 |
-
color: #00E;
|
92 |
-
}
|
1 |
+
.nice_r {
|
2 |
+
font: 12px Consolas, "Lucida Console", monospace;
|
3 |
+
cursor: default;
|
4 |
+
}
|
5 |
+
|
6 |
+
.nice_r a {
|
7 |
+
display: block;
|
8 |
+
text-decoration: none;
|
9 |
+
color: #222;
|
10 |
+
padding: 2px;
|
11 |
+
white-space: nowrap;
|
12 |
+
overflow: hidden;
|
13 |
+
text-overflow: ellipsis;
|
14 |
+
}
|
15 |
+
|
16 |
+
.nice_r a:hover .nice_r_k,
|
17 |
+
.nice_r a:hover .nice_r_d,
|
18 |
+
.nice_r a:hover .nice_r_d span,
|
19 |
+
.nice_r a:hover .nice_r_p,
|
20 |
+
.nice_r a:hover .nice_r_a,
|
21 |
+
.nice_r a:hover {
|
22 |
+
background-color: Highlight;
|
23 |
+
color: HighlightText;
|
24 |
+
}
|
25 |
+
|
26 |
+
.nice_r_a {
|
27 |
+
color: #000;
|
28 |
+
}
|
29 |
+
|
30 |
+
.nice_r_ad {
|
31 |
+
opacity: 0.5;
|
32 |
+
}
|
33 |
+
|
34 |
+
.nice_r_k {
|
35 |
+
color: #060;
|
36 |
+
font-weight: bold;
|
37 |
+
}
|
38 |
+
|
39 |
+
.nice_r_d {
|
40 |
+
font-size: 11px;
|
41 |
+
color: #777;
|
42 |
+
}
|
43 |
+
|
44 |
+
.nice_r_d span {
|
45 |
+
color: #333;
|
46 |
+
}
|
47 |
+
|
48 |
+
.nice_r_p {
|
49 |
+
color: #000;
|
50 |
+
font-weight: bold;
|
51 |
+
}
|
52 |
+
|
53 |
+
.nice_r_v {
|
54 |
+
margin-left: 6px;
|
55 |
+
padding-left: 6px;
|
56 |
+
border-left: 1px dotted #CCC;
|
57 |
+
display: none;
|
58 |
+
}
|
59 |
+
|
60 |
+
.nice_r_ir {
|
61 |
+
font-style: italic;
|
62 |
+
}
|
63 |
+
|
64 |
+
.nice_r_p.nice_r_t_integer,
|
65 |
+
.nice_r_p.nice_r_t_double {
|
66 |
+
color: #F0E;
|
67 |
+
}
|
68 |
+
|
69 |
+
.nice_r_p.nice_r_t_string {
|
70 |
+
color: #E00;
|
71 |
+
}
|
72 |
+
|
73 |
+
.nice_r_p.nice_r_t_boolean {
|
74 |
+
color: #00E;
|
75 |
+
}
|
76 |
+
|
77 |
+
.nice_r_t_comment {
|
78 |
+
color: #080;
|
79 |
+
}
|
80 |
+
|
81 |
+
.nice_r a.nice_r_c .nice_r_k {
|
82 |
+
color: #909;
|
83 |
+
}
|
84 |
+
|
85 |
+
.nice_r a.nice_r_c .nice_r_ma {
|
86 |
+
font-weight: normal;
|
87 |
+
color: #777;
|
88 |
+
}
|
89 |
+
|
90 |
+
.nice_r a.nice_r_c .nice_r_mv {
|
91 |
+
color: #00E;
|
92 |
+
}
|
css/settings.css
CHANGED
@@ -1,71 +1,71 @@
|
|
1 |
-
#audit-log-settings {
|
2 |
-
padding-right: 256px;
|
3 |
-
position: relative;
|
4 |
-
}
|
5 |
-
|
6 |
-
#audit-log-adverts {
|
7 |
-
position: absolute;
|
8 |
-
top: 3px;
|
9 |
-
right: 3px;
|
10 |
-
overflow: hidden;
|
11 |
-
}
|
12 |
-
|
13 |
-
#audit-log-adverts a {
|
14 |
-
display: block;
|
15 |
-
text-decoration: none;
|
16 |
-
margin: 4px 0;
|
17 |
-
}
|
18 |
-
|
19 |
-
.sectoken-user,
|
20 |
-
.sectoken-role,
|
21 |
-
.sectoken-other {
|
22 |
-
display: inline-block;
|
23 |
-
border-width: 1px;
|
24 |
-
border-style: solid;
|
25 |
-
padding: 2px 4px;
|
26 |
-
margin: 2px 0 0 2px;
|
27 |
-
border-radius: 3px;
|
28 |
-
cursor: default;
|
29 |
-
}
|
30 |
-
.sectoken-other {
|
31 |
-
display: table;
|
32 |
-
border-collapse: separate;
|
33 |
-
}
|
34 |
-
|
35 |
-
.sectoken-user a,
|
36 |
-
.sectoken-role a,
|
37 |
-
.sectoken-other a {
|
38 |
-
text-decoration: none;
|
39 |
-
font-size: 12px;
|
40 |
-
font-weight: bold;
|
41 |
-
color: #FFF;
|
42 |
-
margin-left: 2px;
|
43 |
-
background: #BBB;
|
44 |
-
border-radius: 25px;
|
45 |
-
height: 14px;
|
46 |
-
display: inline-block;
|
47 |
-
width: 14px;
|
48 |
-
text-align: center;
|
49 |
-
line-height: 16px;
|
50 |
-
}
|
51 |
-
|
52 |
-
.sectoken-user a:hover,
|
53 |
-
.sectoken-role a:hover,
|
54 |
-
.sectoken-other a:hover {
|
55 |
-
background: #FB9;
|
56 |
-
}
|
57 |
-
|
58 |
-
.sectoken-user { background: #EFF; border-color: #5BE; }
|
59 |
-
.sectoken-role { background: #EFE; border-color: #5B5; }
|
60 |
-
.sectoken-other { background: #FFE; border-color: #ED5; }
|
61 |
-
.sectoken-del { background: #FEE; border-color: #EBB; }
|
62 |
-
|
63 |
-
.wsal-tab {
|
64 |
-
margin-top: 0px;
|
65 |
-
}
|
66 |
-
.wsal-tab th {
|
67 |
-
padding-left: 20px;
|
68 |
-
}
|
69 |
-
.wsal-tab td {
|
70 |
-
padding-left: 20px;
|
71 |
}
|
1 |
+
#audit-log-settings {
|
2 |
+
padding-right: 256px;
|
3 |
+
position: relative;
|
4 |
+
}
|
5 |
+
|
6 |
+
#audit-log-adverts {
|
7 |
+
position: absolute;
|
8 |
+
top: 3px;
|
9 |
+
right: 3px;
|
10 |
+
overflow: hidden;
|
11 |
+
}
|
12 |
+
|
13 |
+
#audit-log-adverts a {
|
14 |
+
display: block;
|
15 |
+
text-decoration: none;
|
16 |
+
margin: 4px 0;
|
17 |
+
}
|
18 |
+
|
19 |
+
.sectoken-user,
|
20 |
+
.sectoken-role,
|
21 |
+
.sectoken-other {
|
22 |
+
display: inline-block;
|
23 |
+
border-width: 1px;
|
24 |
+
border-style: solid;
|
25 |
+
padding: 2px 4px;
|
26 |
+
margin: 2px 0 0 2px;
|
27 |
+
border-radius: 3px;
|
28 |
+
cursor: default;
|
29 |
+
}
|
30 |
+
.sectoken-other {
|
31 |
+
display: table;
|
32 |
+
border-collapse: separate;
|
33 |
+
}
|
34 |
+
|
35 |
+
.sectoken-user a,
|
36 |
+
.sectoken-role a,
|
37 |
+
.sectoken-other a {
|
38 |
+
text-decoration: none;
|
39 |
+
font-size: 12px;
|
40 |
+
font-weight: bold;
|
41 |
+
color: #FFF;
|
42 |
+
margin-left: 2px;
|
43 |
+
background: #BBB;
|
44 |
+
border-radius: 25px;
|
45 |
+
height: 14px;
|
46 |
+
display: inline-block;
|
47 |
+
width: 14px;
|
48 |
+
text-align: center;
|
49 |
+
line-height: 16px;
|
50 |
+
}
|
51 |
+
|
52 |
+
.sectoken-user a:hover,
|
53 |
+
.sectoken-role a:hover,
|
54 |
+
.sectoken-other a:hover {
|
55 |
+
background: #FB9;
|
56 |
+
}
|
57 |
+
|
58 |
+
.sectoken-user { background: #EFF; border-color: #5BE; }
|
59 |
+
.sectoken-role { background: #EFE; border-color: #5B5; }
|
60 |
+
.sectoken-other { background: #FFE; border-color: #ED5; }
|
61 |
+
.sectoken-del { background: #FEE; border-color: #EBB; }
|
62 |
+
|
63 |
+
.wsal-tab {
|
64 |
+
margin-top: 0px;
|
65 |
+
}
|
66 |
+
.wsal-tab th {
|
67 |
+
padding-left: 20px;
|
68 |
+
}
|
69 |
+
.wsal-tab td {
|
70 |
+
padding-left: 20px;
|
71 |
}
|
defaults.php
CHANGED
@@ -40,6 +40,8 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal)
|
|
40 |
array(1001, E_NOTICE, __('User logs out', 'wp-security-audit-log'), __('Successfully logged out', 'wp-security-audit-log')),
|
41 |
array(1002, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected', 'wp-security-audit-log')),
|
42 |
array(1003, E_WARNING, __('Login failed / non existing user', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected using non existing user.', 'wp-security-audit-log')),
|
|
|
|
|
43 |
array(2010, E_NOTICE, __('User uploaded file from Uploads directory', 'wp-security-audit-log'), __('Uploaded the file %FileName% in %FilePath%', 'wp-security-audit-log')),
|
44 |
array(2011, E_WARNING, __('User deleted file from Uploads directory', 'wp-security-audit-log'), __('Deleted the file %FileName% from %FilePath%', 'wp-security-audit-log')),
|
45 |
array(2046, E_CRITICAL, __('User changed a file using the theme editor', 'wp-security-audit-log'), __('Modified %File% with the Theme Editor', 'wp-security-audit-log')),
|
@@ -163,6 +165,7 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal)
|
|
163 |
array(6003, E_CRITICAL, __('WordPress Administrator Notification email changed', 'wp-security-audit-log'), __('Changed the WordPress administrator notifications email address from %OldEmail% to %NewEmail%', 'wp-security-audit-log')),
|
164 |
array(6004, E_CRITICAL, __('WordPress was updated', 'wp-security-audit-log'), __('Updated WordPress from version %OldVersion% to %NewVersion%', 'wp-security-audit-log')),
|
165 |
array(6005, E_CRITICAL, __('User changes the WordPress Permalinks', 'wp-security-audit-log'), __('Changed the WordPress permalinks from %OldPattern% to %NewPattern%', 'wp-security-audit-log')),
|
|
|
166 |
array(9999, E_CRITICAL, __('Advertising Add-ons.', 'wp-security-audit-log'), __('%PromoMessage%', 'wp-security-audit-log')),
|
167 |
),
|
168 |
__('MultiSite', 'wp-security-audit-log') => array(
|
40 |
array(1001, E_NOTICE, __('User logs out', 'wp-security-audit-log'), __('Successfully logged out', 'wp-security-audit-log')),
|
41 |
array(1002, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected', 'wp-security-audit-log')),
|
42 |
array(1003, E_WARNING, __('Login failed / non existing user', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected using non existing user.', 'wp-security-audit-log')),
|
43 |
+
array(1004, E_WARNING, __('Login blocked', 'wp-security-audit-log'), __('Blocked from logging in because another user is logged in from %ClientIP%', 'wp-security-audit-log')),
|
44 |
+
array(1005, E_WARNING, __('User logs in with existing session(s)', 'wp-security-audit-log'), __('Successfully logged in. Other session(s) from %IPAddress% for this username already exists', 'wp-security-audit-log')),
|
45 |
array(2010, E_NOTICE, __('User uploaded file from Uploads directory', 'wp-security-audit-log'), __('Uploaded the file %FileName% in %FilePath%', 'wp-security-audit-log')),
|
46 |
array(2011, E_WARNING, __('User deleted file from Uploads directory', 'wp-security-audit-log'), __('Deleted the file %FileName% from %FilePath%', 'wp-security-audit-log')),
|
47 |
array(2046, E_CRITICAL, __('User changed a file using the theme editor', 'wp-security-audit-log'), __('Modified %File% with the Theme Editor', 'wp-security-audit-log')),
|
165 |
array(6003, E_CRITICAL, __('WordPress Administrator Notification email changed', 'wp-security-audit-log'), __('Changed the WordPress administrator notifications email address from %OldEmail% to %NewEmail%', 'wp-security-audit-log')),
|
166 |
array(6004, E_CRITICAL, __('WordPress was updated', 'wp-security-audit-log'), __('Updated WordPress from version %OldVersion% to %NewVersion%', 'wp-security-audit-log')),
|
167 |
array(6005, E_CRITICAL, __('User changes the WordPress Permalinks', 'wp-security-audit-log'), __('Changed the WordPress permalinks from %OldPattern% to %NewPattern%', 'wp-security-audit-log')),
|
168 |
+
array(6007, E_CRITICAL, __('User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log'), __(' Is requesting non-existing pages (404 Error Pages)', 'wp-security-audit-log')),
|
169 |
array(9999, E_CRITICAL, __('Advertising Add-ons.', 'wp-security-audit-log'), __('%PromoMessage%', 'wp-security-audit-log')),
|
170 |
),
|
171 |
__('MultiSite', 'wp-security-audit-log') => array(
|
js/auditlog.js
CHANGED
@@ -1,150 +1,150 @@
|
|
1 |
-
var WsalData;
|
2 |
-
|
3 |
-
window['WsalAuditLogRefreshed'] = function(){
|
4 |
-
// fix pagination links causing form params to get lost
|
5 |
-
jQuery('span.pagination-links a').click(function(ev){
|
6 |
-
ev.preventDefault();
|
7 |
-
var deparam = function(url){
|
8 |
-
var obj = {};
|
9 |
-
var pairs = url.split('&');
|
10 |
-
for(var i in pairs){
|
11 |
-
var split = pairs[i].split('=');
|
12 |
-
obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
|
13 |
-
}
|
14 |
-
return obj;
|
15 |
-
};
|
16 |
-
var paged = deparam(this.href).paged;
|
17 |
-
if (typeof paged === 'undefined') paged = 1;
|
18 |
-
jQuery('#audit-log-viewer').append(
|
19 |
-
jQuery('<input type="hidden" name="paged"/>').val(paged)
|
20 |
-
).submit();
|
21 |
-
});
|
22 |
-
};
|
23 |
-
|
24 |
-
function WsalAuditLogInit(_WsalData){
|
25 |
-
WsalData = _WsalData;
|
26 |
-
var WsalTkn = WsalData.autorefresh.token;
|
27 |
-
|
28 |
-
// list refresher
|
29 |
-
var WsalAjx = null;
|
30 |
-
var WsalChk = function(){
|
31 |
-
if(WsalAjx)WsalAjx.abort();
|
32 |
-
WsalAjx = jQuery.post(WsalData.ajaxurl, {
|
33 |
-
action: 'AjaxRefresh',
|
34 |
-
logcount: WsalTkn
|
35 |
-
}, function(data){
|
36 |
-
WsalAjx = null;
|
37 |
-
if(data && data !== 'false'){
|
38 |
-
WsalTkn = data;
|
39 |
-
jQuery('#audit-log-viewer').load(
|
40 |
-
location.href + ' #audit-log-viewer-content',
|
41 |
-
window['WsalAuditLogRefreshed']
|
42 |
-
);
|
43 |
-
}
|
44 |
-
WsalChk();
|
45 |
-
});
|
46 |
-
};
|
47 |
-
if(WsalData.autorefresh.enabled){
|
48 |
-
setInterval(WsalChk, 40000);
|
49 |
-
WsalChk();
|
50 |
-
}
|
51 |
-
|
52 |
-
WsalSsasInit();
|
53 |
-
}
|
54 |
-
|
55 |
-
var WsalIppsPrev;
|
56 |
-
|
57 |
-
function WsalIppsFocus(value){
|
58 |
-
WsalIppsPrev = value;
|
59 |
-
}
|
60 |
-
|
61 |
-
function WsalIppsChange(value){
|
62 |
-
if(value === ''){
|
63 |
-
value = window.prompt(WsalData.tr8n.numofitems, WsalIppsPrev);
|
64 |
-
if(value === null || value === WsalIppsPrev)return this.value = WsalIppsPrev; // operation canceled
|
65 |
-
}
|
66 |
-
jQuery('select.wsal-ipps').attr('disabled', true);
|
67 |
-
jQuery.post(WsalData.ajaxurl, {
|
68 |
-
action: 'AjaxSetIpp',
|
69 |
-
count: value
|
70 |
-
}, function(){
|
71 |
-
location.reload();
|
72 |
-
});
|
73 |
-
}
|
74 |
-
|
75 |
-
function WsalSsasInit(){
|
76 |
-
var SsasAjx = null;
|
77 |
-
var SsasInps = jQuery("input.wsal-ssas");
|
78 |
-
SsasInps.after('<div class="wsal-ssas-dd" style="display: none;"/>');
|
79 |
-
SsasInps.click(function(){
|
80 |
-
jQuery(this).select();
|
81 |
-
});
|
82 |
-
window['WsalAuditLogRefreshed']();
|
83 |
-
SsasInps.keyup(function(){
|
84 |
-
var SsasInp = jQuery(this);
|
85 |
-
var SsasDiv = SsasInp.next();
|
86 |
-
var SsasVal = SsasInp.val();
|
87 |
-
if(SsasAjx)SsasAjx.abort();
|
88 |
-
SsasInp.removeClass('loading');
|
89 |
-
|
90 |
-
// do a new search
|
91 |
-
if(SsasInp.attr('data-oldvalue') !== SsasVal && SsasVal.length > 2){
|
92 |
-
SsasInp.addClass('loading');
|
93 |
-
SsasAjx = jQuery.post(WsalData.ajaxurl, {
|
94 |
-
action: 'AjaxSearchSite',
|
95 |
-
search: SsasVal
|
96 |
-
}, function(data){
|
97 |
-
if(SsasAjx)SsasAjx = null;
|
98 |
-
SsasInp.removeClass('loading');
|
99 |
-
SsasDiv.hide();
|
100 |
-
SsasDiv.html('');
|
101 |
-
if(data && data.length){
|
102 |
-
var SsasReg = new RegExp(SsasVal.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'), 'gi');
|
103 |
-
for (var i = 0; i < data.length; i++){
|
104 |
-
var link = jQuery('<a href="javascript:;" onclick="WsalSsasChange(' + data[i].blog_id + ')"/>')
|
105 |
-
.text(data[i].blogname + ' (' + data[i].domain + ')');
|
106 |
-
link.html(link.text().replace(SsasReg, '<u>$&</u>'));
|
107 |
-
SsasDiv.append(link);
|
108 |
-
}
|
109 |
-
}else{
|
110 |
-
SsasDiv.append(jQuery('<span/>').text(WsalData.tr8n.searchnone));
|
111 |
-
}
|
112 |
-
SsasDiv.prepend(jQuery('<a href="javascript:;" onclick="WsalSsasChange(0)" class="allsites"/>').text(WsalData.tr8n.searchback));
|
113 |
-
SsasDiv.show();
|
114 |
-
}, 'json');
|
115 |
-
SsasInp.attr('data-oldvalue', SsasVal);
|
116 |
-
}
|
117 |
-
|
118 |
-
// handle keys
|
119 |
-
});
|
120 |
-
SsasInps.blur(function(){
|
121 |
-
setTimeout(function(){
|
122 |
-
var SsasInp = jQuery(this);
|
123 |
-
var SsasDiv = SsasInp.next();
|
124 |
-
SsasInp.attr('data-oldvalue', '');
|
125 |
-
SsasDiv.hide();
|
126 |
-
}, 200);
|
127 |
-
});
|
128 |
-
}
|
129 |
-
|
130 |
-
function WsalSsasChange(value){
|
131 |
-
jQuery('div.wsal-ssas-dd').hide();
|
132 |
-
jQuery('input.wsal-ssas').attr('disabled', true);
|
133 |
-
jQuery('#wsal-cbid').val(value);
|
134 |
-
jQuery('#audit-log-viewer').submit();
|
135 |
-
}
|
136 |
-
|
137 |
-
function WsalDisableCustom(link, meta_key){
|
138 |
-
var nfe = jQuery(this).parents('div:first');
|
139 |
-
jQuery(link).hide();
|
140 |
-
jQuery.ajax({
|
141 |
-
type: 'POST',
|
142 |
-
url: ajaxurl,
|
143 |
-
async: false,
|
144 |
-
data: { action: 'AjaxDisableCustomField', notice: meta_key },
|
145 |
-
success: function(data) {
|
146 |
-
var notice = jQuery('<div class="updated" data-notice-name="notifications-extension"></div>').html(data);
|
147 |
-
jQuery("h2:first").after(notice);
|
148 |
-
}
|
149 |
-
});
|
150 |
}
|
1 |
+
var WsalData;
|
2 |
+
|
3 |
+
window['WsalAuditLogRefreshed'] = function(){
|
4 |
+
// fix pagination links causing form params to get lost
|
5 |
+
jQuery('span.pagination-links a').click(function(ev){
|
6 |
+
ev.preventDefault();
|
7 |
+
var deparam = function(url){
|
8 |
+
var obj = {};
|
9 |
+
var pairs = url.split('&');
|
10 |
+
for(var i in pairs){
|
11 |
+
var split = pairs[i].split('=');
|
12 |
+
obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
|
13 |
+
}
|
14 |
+
return obj;
|
15 |
+
};
|
16 |
+
var paged = deparam(this.href).paged;
|
17 |
+
if (typeof paged === 'undefined') paged = 1;
|
18 |
+
jQuery('#audit-log-viewer').append(
|
19 |
+
jQuery('<input type="hidden" name="paged"/>').val(paged)
|
20 |
+
).submit();
|
21 |
+
});
|
22 |
+
};
|
23 |
+
|
24 |
+
function WsalAuditLogInit(_WsalData){
|
25 |
+
WsalData = _WsalData;
|
26 |
+
var WsalTkn = WsalData.autorefresh.token;
|
27 |
+
|
28 |
+
// list refresher
|
29 |
+
var WsalAjx = null;
|
30 |
+
var WsalChk = function(){
|
31 |
+
if(WsalAjx)WsalAjx.abort();
|
32 |
+
WsalAjx = jQuery.post(WsalData.ajaxurl, {
|
33 |
+
action: 'AjaxRefresh',
|
34 |
+
logcount: WsalTkn
|
35 |
+
}, function(data){
|
36 |
+
WsalAjx = null;
|
37 |
+
if(data && data !== 'false'){
|
38 |
+
WsalTkn = data;
|
39 |
+
jQuery('#audit-log-viewer').load(
|
40 |
+
location.href + ' #audit-log-viewer-content',
|
41 |
+
window['WsalAuditLogRefreshed']
|
42 |
+
);
|
43 |
+
}
|
44 |
+
WsalChk();
|
45 |
+
});
|
46 |
+
};
|
47 |
+
if(WsalData.autorefresh.enabled){
|
48 |
+
setInterval(WsalChk, 40000);
|
49 |
+
WsalChk();
|
50 |
+
}
|
51 |
+
|
52 |
+
WsalSsasInit();
|
53 |
+
}
|
54 |
+
|
55 |
+
var WsalIppsPrev;
|
56 |
+
|
57 |
+
function WsalIppsFocus(value){
|
58 |
+
WsalIppsPrev = value;
|
59 |
+
}
|
60 |
+
|
61 |
+
function WsalIppsChange(value){
|
62 |
+
if(value === ''){
|
63 |
+
value = window.prompt(WsalData.tr8n.numofitems, WsalIppsPrev);
|
64 |
+
if(value === null || value === WsalIppsPrev)return this.value = WsalIppsPrev; // operation canceled
|
65 |
+
}
|
66 |
+
jQuery('select.wsal-ipps').attr('disabled', true);
|
67 |
+
jQuery.post(WsalData.ajaxurl, {
|
68 |
+
action: 'AjaxSetIpp',
|
69 |
+
count: value
|
70 |
+
}, function(){
|
71 |
+
location.reload();
|
72 |
+
});
|
73 |
+
}
|
74 |
+
|
75 |
+
function WsalSsasInit(){
|
76 |
+
var SsasAjx = null;
|
77 |
+
var SsasInps = jQuery("input.wsal-ssas");
|
78 |
+
SsasInps.after('<div class="wsal-ssas-dd" style="display: none;"/>');
|
79 |
+
SsasInps.click(function(){
|
80 |
+
jQuery(this).select();
|
81 |
+
});
|
82 |
+
window['WsalAuditLogRefreshed']();
|
83 |
+
SsasInps.keyup(function(){
|
84 |
+
var SsasInp = jQuery(this);
|
85 |
+
var SsasDiv = SsasInp.next();
|
86 |
+
var SsasVal = SsasInp.val();
|
87 |
+
if(SsasAjx)SsasAjx.abort();
|
88 |
+
SsasInp.removeClass('loading');
|
89 |
+
|
90 |
+
// do a new search
|
91 |
+
if(SsasInp.attr('data-oldvalue') !== SsasVal && SsasVal.length > 2){
|
92 |
+
SsasInp.addClass('loading');
|
93 |
+
SsasAjx = jQuery.post(WsalData.ajaxurl, {
|
94 |
+
action: 'AjaxSearchSite',
|
95 |
+
search: SsasVal
|
96 |
+
}, function(data){
|
97 |
+
if(SsasAjx)SsasAjx = null;
|
98 |
+
SsasInp.removeClass('loading');
|
99 |
+
SsasDiv.hide();
|
100 |
+
SsasDiv.html('');
|
101 |
+
if(data && data.length){
|
102 |
+
var SsasReg = new RegExp(SsasVal.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'), 'gi');
|
103 |
+
for (var i = 0; i < data.length; i++){
|
104 |
+
var link = jQuery('<a href="javascript:;" onclick="WsalSsasChange(' + data[i].blog_id + ')"/>')
|
105 |
+
.text(data[i].blogname + ' (' + data[i].domain + ')');
|
106 |
+
link.html(link.text().replace(SsasReg, '<u>$&</u>'));
|
107 |
+
SsasDiv.append(link);
|
108 |
+
}
|
109 |
+
}else{
|
110 |
+
SsasDiv.append(jQuery('<span/>').text(WsalData.tr8n.searchnone));
|
111 |
+
}
|
112 |
+
SsasDiv.prepend(jQuery('<a href="javascript:;" onclick="WsalSsasChange(0)" class="allsites"/>').text(WsalData.tr8n.searchback));
|
113 |
+
SsasDiv.show();
|
114 |
+
}, 'json');
|
115 |
+
SsasInp.attr('data-oldvalue', SsasVal);
|
116 |
+
}
|
117 |
+
|
118 |
+
// handle keys
|
119 |
+
});
|
120 |
+
SsasInps.blur(function(){
|
121 |
+
setTimeout(function(){
|
122 |
+
var SsasInp = jQuery(this);
|
123 |
+
var SsasDiv = SsasInp.next();
|
124 |
+
SsasInp.attr('data-oldvalue', '');
|
125 |
+
SsasDiv.hide();
|
126 |
+
}, 200);
|
127 |
+
});
|
128 |
+
}
|
129 |
+
|
130 |
+
function WsalSsasChange(value){
|
131 |
+
jQuery('div.wsal-ssas-dd').hide();
|
132 |
+
jQuery('input.wsal-ssas').attr('disabled', true);
|
133 |
+
jQuery('#wsal-cbid').val(value);
|
134 |
+
jQuery('#audit-log-viewer').submit();
|
135 |
+
}
|
136 |
+
|
137 |
+
function WsalDisableCustom(link, meta_key){
|
138 |
+
var nfe = jQuery(this).parents('div:first');
|
139 |
+
jQuery(link).hide();
|
140 |
+
jQuery.ajax({
|
141 |
+
type: 'POST',
|
142 |
+
url: ajaxurl,
|
143 |
+
async: false,
|
144 |
+
data: { action: 'AjaxDisableCustomField', notice: meta_key },
|
145 |
+
success: function(data) {
|
146 |
+
var notice = jQuery('<div class="updated" data-notice-name="notifications-extension"></div>').html(data);
|
147 |
+
jQuery("h2:first").after(notice);
|
148 |
+
}
|
149 |
+
});
|
150 |
}
|
js/common.js
CHANGED
@@ -1,17 +1,17 @@
|
|
1 |
-
|
2 |
-
jQuery(document).ready(function(){
|
3 |
-
jQuery('a.wsal-dismiss-notification').click(function(){
|
4 |
-
var nfe = jQuery(this).parents('div:first');
|
5 |
-
var nfn = nfe.attr('data-notice-name');
|
6 |
-
jQuery.ajax({
|
7 |
-
type: 'POST',
|
8 |
-
url: ajaxurl,
|
9 |
-
async: false,
|
10 |
-
data: { action: 'AjaxDismissNotice', notice: nfn }
|
11 |
-
});
|
12 |
-
nfe.fadeOut();
|
13 |
-
});
|
14 |
-
|
15 |
-
jQuery('head').append('<style>.wp-submenu .dashicons-external:before{vertical-align: bottom;}</style>');
|
16 |
-
jQuery("a[href*='page=wsal-extensions']").addClass('dashicons-before dashicons-external').css('color', '#CC4444');
|
17 |
-
});
|
1 |
+
|
2 |
+
jQuery(document).ready(function(){
|
3 |
+
jQuery('a.wsal-dismiss-notification').click(function(){
|
4 |
+
var nfe = jQuery(this).parents('div:first');
|
5 |
+
var nfn = nfe.attr('data-notice-name');
|
6 |
+
jQuery.ajax({
|
7 |
+
type: 'POST',
|
8 |
+
url: ajaxurl,
|
9 |
+
async: false,
|
10 |
+
data: { action: 'AjaxDismissNotice', notice: nfn }
|
11 |
+
});
|
12 |
+
nfe.fadeOut();
|
13 |
+
});
|
14 |
+
|
15 |
+
jQuery('head').append('<style>.wp-submenu .dashicons-external:before{vertical-align: bottom;}</style>');
|
16 |
+
jQuery("a[href*='page=wsal-extensions']").addClass('dashicons-before dashicons-external').css('color', '#CC4444');
|
17 |
+
});
|
js/nice_r.js
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
-
function nice_r_toggle(pfx, id){
|
2 |
-
var el = document.getElementById(pfx+'_v'+id);
|
3 |
-
if(el){
|
4 |
-
if(el.style.display==='block'){
|
5 |
-
el.style.display = 'none';
|
6 |
-
document.getElementById(pfx+'_a'+id).innerHTML = '►';
|
7 |
-
}else{
|
8 |
-
el.style.display = 'block';
|
9 |
-
document.getElementById(pfx+'_a'+id).innerHTML = '▼';
|
10 |
-
}
|
11 |
-
}
|
12 |
}
|
1 |
+
function nice_r_toggle(pfx, id){
|
2 |
+
var el = document.getElementById(pfx+'_v'+id);
|
3 |
+
if(el){
|
4 |
+
if(el.style.display==='block'){
|
5 |
+
el.style.display = 'none';
|
6 |
+
document.getElementById(pfx+'_a'+id).innerHTML = '►';
|
7 |
+
}else{
|
8 |
+
el.style.display = 'block';
|
9 |
+
document.getElementById(pfx+'_a'+id).innerHTML = '▼';
|
10 |
+
}
|
11 |
+
}
|
12 |
}
|
js/settings.js
CHANGED
@@ -1,73 +1,73 @@
|
|
1 |
-
jQuery(document).ready(function(){
|
2 |
-
var RemoveSecToken = function(){
|
3 |
-
var $this = jQuery(this).parents('span:first');
|
4 |
-
$this.addClass('sectoken-del').fadeOut('fast', function(){
|
5 |
-
$this.remove();
|
6 |
-
});
|
7 |
-
};
|
8 |
-
|
9 |
-
jQuery('#ViewerQueryBox, #EditorQueryBox, #ExRoleQueryBox, #ExUserQueryBox, #CustomQueryBox, #IpAddrQueryBox').keydown(function(event){
|
10 |
-
if(event.keyCode === 13) {
|
11 |
-
var type = jQuery(this).attr('id').substr(0, 6);
|
12 |
-
jQuery('#'+type+'QueryAdd').click();
|
13 |
-
return false;
|
14 |
-
}
|
15 |
-
});
|
16 |
-
|
17 |
-
jQuery('#ViewerQueryAdd, #EditorQueryAdd, #ExRoleQueryAdd, #ExUserQueryAdd, #CustomQueryAdd, #IpAddrQueryAdd').click(function(){
|
18 |
-
var type = jQuery(this).attr('id').substr(0, 6);
|
19 |
-
var value = jQuery.trim(jQuery('#'+type+'QueryBox').val());
|
20 |
-
var existing = jQuery('#'+type+'List input').filter(function() { return this.value === value; });
|
21 |
-
|
22 |
-
if(!value || existing.length)return; // if value is empty or already used, stop here
|
23 |
-
|
24 |
-
jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', true);
|
25 |
-
jQuery.post(jQuery('#ajaxurl').val(), {action: 'AjaxCheckSecurityToken', token: value}, function(data){
|
26 |
-
jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', false);
|
27 |
-
if (type != 'Custom' && type != 'IpAddr') {
|
28 |
-
if(data === 'other') {
|
29 |
-
alert('The specified token is not a user nor a role!');
|
30 |
-
jQuery('#'+type+'QueryBox').val('');
|
31 |
-
return;
|
32 |
-
}
|
33 |
-
}
|
34 |
-
jQuery('#'+type+'QueryBox').val('');
|
35 |
-
jQuery('#'+type+'List').append(jQuery('<span class="sectoken-'+data+'"/>').text(value).append(
|
36 |
-
jQuery('<input type="hidden" name="'+type+'s[]"/>').val(value),
|
37 |
-
jQuery('<a href="javascript:;" title="Remove">×</a>').click(RemoveSecToken)
|
38 |
-
));
|
39 |
-
});
|
40 |
-
});
|
41 |
-
|
42 |
-
jQuery('#ViewerList>span>a, #EditorList>span>a, #ExRoleList>span>a, #ExUserList>span>a, #CustomList>span>a, #IpAddrList>span>a').click(RemoveSecToken);
|
43 |
-
|
44 |
-
jQuery('#RestrictAdmins').change(function(){
|
45 |
-
var user = jQuery('#RestrictAdminsDefaultUser').val();
|
46 |
-
var fltr = function() { return this.value === user; };
|
47 |
-
if (this.checked && jQuery('#EditorList input').filter(fltr).length === 0) {
|
48 |
-
jQuery('#EditorList').append(
|
49 |
-
jQuery('<span class="sectoken-user"/>').text(user)
|
50 |
-
.prepend(jQuery('<input type="hidden" name="Editors[]"/>').val(user))
|
51 |
-
.append(jQuery('<a href="javascript:;" title="Remove">×</a>').click(RemoveSecToken))
|
52 |
-
);
|
53 |
-
} else {
|
54 |
-
jQuery('#EditorList').children().remove();
|
55 |
-
}
|
56 |
-
});
|
57 |
-
|
58 |
-
|
59 |
-
var usersUrl = ajaxurl + "?action=AjaxGetAllUsers";
|
60 |
-
jQuery("#ExUserQueryBox").autocomplete({
|
61 |
-
source: usersUrl,
|
62 |
-
minLength:1
|
63 |
-
});
|
64 |
-
|
65 |
-
var rolesUrl = ajaxurl + "?action=AjaxGetAllRoles";
|
66 |
-
jQuery("#ExRoleQueryBox").autocomplete({
|
67 |
-
source: rolesUrl,
|
68 |
-
minLength:1
|
69 |
-
});
|
70 |
-
|
71 |
-
});
|
72 |
-
|
73 |
-
|
1 |
+
jQuery(document).ready(function(){
|
2 |
+
var RemoveSecToken = function(){
|
3 |
+
var $this = jQuery(this).parents('span:first');
|
4 |
+
$this.addClass('sectoken-del').fadeOut('fast', function(){
|
5 |
+
$this.remove();
|
6 |
+
});
|
7 |
+
};
|
8 |
+
|
9 |
+
jQuery('#ViewerQueryBox, #EditorQueryBox, #ExRoleQueryBox, #ExUserQueryBox, #CustomQueryBox, #IpAddrQueryBox').keydown(function(event){
|
10 |
+
if(event.keyCode === 13) {
|
11 |
+
var type = jQuery(this).attr('id').substr(0, 6);
|
12 |
+
jQuery('#'+type+'QueryAdd').click();
|
13 |
+
return false;
|
14 |
+
}
|
15 |
+
});
|
16 |
+
|
17 |
+
jQuery('#ViewerQueryAdd, #EditorQueryAdd, #ExRoleQueryAdd, #ExUserQueryAdd, #CustomQueryAdd, #IpAddrQueryAdd').click(function(){
|
18 |
+
var type = jQuery(this).attr('id').substr(0, 6);
|
19 |
+
var value = jQuery.trim(jQuery('#'+type+'QueryBox').val());
|
20 |
+
var existing = jQuery('#'+type+'List input').filter(function() { return this.value === value; });
|
21 |
+
|
22 |
+
if(!value || existing.length)return; // if value is empty or already used, stop here
|
23 |
+
|
24 |
+
jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', true);
|
25 |
+
jQuery.post(jQuery('#ajaxurl').val(), {action: 'AjaxCheckSecurityToken', token: value}, function(data){
|
26 |
+
jQuery('#'+type+'QueryBox, #'+type+'QueryAdd').attr('disabled', false);
|
27 |
+
if (type != 'Custom' && type != 'IpAddr') {
|
28 |
+
if(data === 'other') {
|
29 |
+
alert('The specified token is not a user nor a role!');
|
30 |
+
jQuery('#'+type+'QueryBox').val('');
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
}
|
34 |
+
jQuery('#'+type+'QueryBox').val('');
|
35 |
+
jQuery('#'+type+'List').append(jQuery('<span class="sectoken-'+data+'"/>').text(value).append(
|
36 |
+
jQuery('<input type="hidden" name="'+type+'s[]"/>').val(value),
|
37 |
+
jQuery('<a href="javascript:;" title="Remove">×</a>').click(RemoveSecToken)
|
38 |
+
));
|
39 |
+
});
|
40 |
+
});
|
41 |
+
|
42 |
+
jQuery('#ViewerList>span>a, #EditorList>span>a, #ExRoleList>span>a, #ExUserList>span>a, #CustomList>span>a, #IpAddrList>span>a').click(RemoveSecToken);
|
43 |
+
|
44 |
+
jQuery('#RestrictAdmins').change(function(){
|
45 |
+
var user = jQuery('#RestrictAdminsDefaultUser').val();
|
46 |
+
var fltr = function() { return this.value === user; };
|
47 |
+
if (this.checked && jQuery('#EditorList input').filter(fltr).length === 0) {
|
48 |
+
jQuery('#EditorList').append(
|
49 |
+
jQuery('<span class="sectoken-user"/>').text(user)
|
50 |
+
.prepend(jQuery('<input type="hidden" name="Editors[]"/>').val(user))
|
51 |
+
.append(jQuery('<a href="javascript:;" title="Remove">×</a>').click(RemoveSecToken))
|
52 |
+
);
|
53 |
+
} else {
|
54 |
+
jQuery('#EditorList').children().remove();
|
55 |
+
}
|
56 |
+
});
|
57 |
+
|
58 |
+
|
59 |
+
var usersUrl = ajaxurl + "?action=AjaxGetAllUsers";
|
60 |
+
jQuery("#ExUserQueryBox").autocomplete({
|
61 |
+
source: usersUrl,
|
62 |
+
minLength:1
|
63 |
+
});
|
64 |
+
|
65 |
+
var rolesUrl = ajaxurl + "?action=AjaxGetAllRoles";
|
66 |
+
jQuery("#ExRoleQueryBox").autocomplete({
|
67 |
+
source: rolesUrl,
|
68 |
+
minLength:1
|
69 |
+
});
|
70 |
+
|
71 |
+
});
|
72 |
+
|
73 |
+
|
readme.txt
CHANGED
@@ -7,7 +7,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
|
|
7 |
Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
|
8 |
Requires at least: 3.6
|
9 |
Tested up to: 4.5
|
10 |
-
Stable tag: 2.4.
|
11 |
|
12 |
Keep an audit trail of all changes and under the hood WordPress activity to ensure productivity and thwart possible WordPress hacker attacks.
|
13 |
|
@@ -18,8 +18,16 @@ Keep an audit log of everything that is happening on your WordPress and [WordPre
|
|
18 |
|
19 |
> <strong>Free and Premium Support</strong><br>
|
20 |
>
|
21 |
-
> WP White Security provides support for WP Security Audit Log plugin on the WordPress forums for free
|
22 |
-
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
= Keep A WordPress Security Audit Log & Identify WordPress Security Issues =
|
25 |
WP Security Audit Log keeps a log of 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 security alert is generated by the plugin when:
|
@@ -58,25 +66,18 @@ If you own a multi user WordPress blog or website, or a WordPress multisite netw
|
|
58 |
|
59 |
Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/) for more information on what other WordPress user activity can be monitored with the WP Security Audit Log WordPress plugin.
|
60 |
|
61 |
-
=
|
62 |
-
<strong>
|
63 |
|
64 |
-
|
65 |
|
66 |
-
|
67 |
-
<strong>The search functionality allows you to quickly find specific WordPress activity you are looking for.</strong>
|
68 |
|
69 |
-
|
70 |
|
71 |
-
|
72 |
-
<strong>Store the WordPress Audit Log in an external database to improve the security & Performance of your WordPress websites.</strong>
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
= Generate HTML and CSV WordPress Reports =
|
77 |
-
<strong>Generate WordPress activity reports to ensure users' productivity and meet any legal and regulatory compliance requirements your business needs to adhere to.</strong>
|
78 |
-
|
79 |
-
Use the premium [Reports Add-On](http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/) to generate any type of WordPress report. For example you can generate a WordPress user or group of users activity report, specific role activity report and also site activity report in case you are running WordPress multisite. Unlike other WordPress reports plugins, WSAL Reporting Extension does not have templates that restrict you to specific reports types, but it allows you to choose any data source for your reports.
|
80 |
|
81 |
= WP Security Audit Log for WordPress Multisite =
|
82 |
WP Security Audit Log is the first tracking and audit WordPress security monitoring plugin that supports WordPress multisite network installations and can monitor activity on such WordPress multisite network installations.
|
@@ -86,12 +87,6 @@ For more information about the features for WordPress Multisite network installa
|
|
86 |
= Easily Create Your Own Custom Alerts =
|
87 |
Is there something on your WordPress that the plugin does not monitor, but you would like to keep a record of it? Refer to the [Hooks for custom alerts documentation](https://www.wpsecurityauditlog.com/documentation/create-custom-alerts-wordpress-audit-trail/) to easily create your own custom alerts and keep record of any change on your WordPress, be it a change in a WordPress customization, a third party plugin and more.
|
88 |
|
89 |
-
= WordPress Security Audit Log in your Language! =
|
90 |
-
We need help translating the plugin and the WordPress Security Alerts. If you would like to translate this plugin visit the [WordPress translate Project](https://translate.wordpress.org/) for more information on how to translate the plugin. If you already know how translations work, [start translating WP Security Audit Log now](https://translate.wordpress.org/projects/wp-plugins/wp-security-audit-log) and contact us on plugins@wpwhitesecurity.com for a free license of all add-ons.
|
91 |
-
|
92 |
-
* Italian translation by [Leonardo Musumeci](http://leonardomusumeci.net/)
|
93 |
-
* German translation by [Mourad Louha](http://excel-translator.de)
|
94 |
-
|
95 |
= WordPress & PHP Errors Monitoring Tools =
|
96 |
Plugins and themes customizations are most probably the norm of the day on large WordPress websites, not to mention the installation of new plugins and components. With WP Security Audit Log now it is easier than ever before to monitor your plugins', theme's and other code behaviour, it will generate a alert when a PHP error, warning, exception or shutdown is detected. It is also possible to log all HTTP GET and POST requests that are reaching your WordPress installation to a log file with WP Security Audit Log. Simply enable the PHP Errors monitoring or logging from the plugins settings.
|
97 |
|
@@ -100,14 +95,14 @@ NOTE: Developer options should NEVER be enabled on Live websites. They should on
|
|
100 |
= Other Noteworthy Features =
|
101 |
WP Security Audit Log plugin also has a number of features that make WordPress and WordPress multisite monitoring and auditing easier, such as:
|
102 |
|
103 |
-
* Realtime Audit Log viewer to
|
104 |
* Built-in support for reverse proxies and web application firewalls [more information](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
|
105 |
-
*
|
106 |
-
*
|
107 |
-
* Limit who can view the
|
108 |
-
* Limit who can manage the plugin by users
|
109 |
* Configurable WordPress dashboard widget highlighting the most recent critical activity
|
110 |
-
* Configurable WordPress security
|
111 |
* User role is reported in alerts for a complete overview of what is happening
|
112 |
* User avatar is shown in the alerts for better recognizability
|
113 |
* Enable or disable any security alerts
|
@@ -141,20 +136,20 @@ We need help translating the plugin and the WordPress Security Alerts. Please vi
|
|
141 |
= Related Links and Documentation =
|
142 |
For more information and to get started with WordPress Security, check out the following:
|
143 |
|
144 |
-
* [What is a WordPress Audit Trail?](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-documentation/what-is-a-wordpress-audit-trail/
|
145 |
* [List of WordPress Security Alerts](http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/)
|
146 |
* [WordPress Multisite Features](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/)
|
147 |
* [WP Security Audit Log and Reverse Proxy and WAFs Support](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
|
148 |
* [WP Security Audit Log Database Documentation](http://www.wpsecurityauditlog.com/documentation/plugin-wordpress-database-documentation/)
|
149 |
* [Official WP Security Audit Log Plugin Website](http://www.wpsecurityauditlog.com/)
|
150 |
|
151 |
-
=
|
152 |
-
Even if WordPress security is not your cup of tea, the security of your WordPress is your responsibility. Keep yourself up to date with the latest WordPress Security Tips
|
153 |
|
154 |
-
= Plugin Newsletter =
|
155 |
-
To keep yourself updated with what is new and updated in
|
156 |
|
157 |
-
**Note: This plugin requires PHP 5.3 or higher
|
158 |
|
159 |
== Installation ==
|
160 |
|
@@ -170,16 +165,34 @@ Please refer to the [FAQs page](https://www.wpsecurityauditlog.com/documentation
|
|
170 |
== Screenshots ==
|
171 |
|
172 |
1. The Audit Log Viewer from where the WordPress administrator can see all the security events generated by WP Security Audit Log WordPress plugin.
|
173 |
-
2.
|
174 |
-
3.
|
175 |
-
4.
|
176 |
-
5.
|
177 |
-
6. The
|
178 |
-
7.
|
179 |
-
8.
|
|
|
180 |
|
181 |
== Changelog ==
|
182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
= 2.4.2 (2016-04-26) =
|
184 |
|
185 |
* **Improvement**
|
7 |
Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
|
8 |
Requires at least: 3.6
|
9 |
Tested up to: 4.5
|
10 |
+
Stable tag: 2.4.3
|
11 |
|
12 |
Keep an audit trail of all changes and under the hood WordPress activity to ensure productivity and thwart possible WordPress hacker attacks.
|
13 |
|
18 |
|
19 |
> <strong>Free and Premium Support</strong><br>
|
20 |
>
|
21 |
+
> WP White Security provides support for the WP Security Audit Log plugin on the WordPress forums for free. Since it is free support it is not always possible to answer all questions on a timely manner, although we do try our best.
|
22 |
+
>
|
23 |
+
> Premium world-class support is available via email to anyone who purchases any of the [Premium Add-Ons](http://www.wpsecurityauditlog.com/plugin-extensions/) listed below:
|
24 |
+
>
|
25 |
+
>* [All Add-Ons Package](https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/)
|
26 |
+
>* [Email Notifications](http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/)
|
27 |
+
>* [Users Sessions Management](http://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/)
|
28 |
+
>* [Search](http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/)
|
29 |
+
>* [External Database](http://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/)
|
30 |
+
>* [Reports](http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/)
|
31 |
|
32 |
= Keep A WordPress Security Audit Log & Identify WordPress Security Issues =
|
33 |
WP Security Audit Log keeps a log of 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 security alert is generated by the plugin when:
|
66 |
|
67 |
Refer to the complete list of [WordPress Security Audit Alerts](http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/) for more information on what other WordPress user activity can be monitored with the WP Security Audit Log WordPress plugin.
|
68 |
|
69 |
+
= Upgrade to Premium and Extend the Functionaly of the WP Security Audit Log Plugin =
|
70 |
+
<strong>[Upgrade to Premium](https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/)</strong> to add Email Alerts, Search, Reports and see who is logged in to your WordPress. Else you can buy any of the add-ons listed below separately:
|
71 |
|
72 |
+
* <strong>[Email Notifications Add-On](http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/)</strong>: get notified via email of important changes. You can setup your own triggers to for example be alerted via email should any WordPress user log in to your WordPress outside office hours.
|
73 |
|
74 |
+
* <strong>[Users Sessions Management Add-On](http://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/)</strong>: see who is logged in to your WordPress and WordPress multisite networks. This add-on also allows you to terminate users' sessions and either allow or deny multiple sessions for the same WordPress user.
|
|
|
75 |
|
76 |
+
* <strong>[Search Add-On](http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/)</strong>: do free-text based searches in the WordPress audit trail to easily pin-point a specific WordPress user change. The Search add-on also has built-in filters so you can fine tune your searches and find the WordPress change you are looking for easily and quickly.
|
77 |
|
78 |
+
* <strong>[Reports Add-On](http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/)</strong>: generate any type of HTML and CSV WordPress report. For example generate a WordPress user activity report, role activity report and also site activity report (for WordPress multisite). The Reports Add-On does not restrict you to specific reports types, it allows you to choose any data source for your reports. With this add-on you can also configure automated email summary reports.
|
|
|
79 |
|
80 |
+
* <strong>[External DB Add-on](http://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/)</strong>: store the WordPress Audit Trail in an external database to improve the security and perforamnce of your WordPress websites and blogs by ensuring such records are not tempered with even in case the website is hacked. By storing the audit trail in an external database you also ensure that your business WordPress website is compliant with today's strict regulatory compliance requirements.
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
= WP Security Audit Log for WordPress Multisite =
|
83 |
WP Security Audit Log is the first tracking and audit WordPress security monitoring plugin that supports WordPress multisite network installations and can monitor activity on such WordPress multisite network installations.
|
87 |
= Easily Create Your Own Custom Alerts =
|
88 |
Is there something on your WordPress that the plugin does not monitor, but you would like to keep a record of it? Refer to the [Hooks for custom alerts documentation](https://www.wpsecurityauditlog.com/documentation/create-custom-alerts-wordpress-audit-trail/) to easily create your own custom alerts and keep record of any change on your WordPress, be it a change in a WordPress customization, a third party plugin and more.
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
= WordPress & PHP Errors Monitoring Tools =
|
91 |
Plugins and themes customizations are most probably the norm of the day on large WordPress websites, not to mention the installation of new plugins and components. With WP Security Audit Log now it is easier than ever before to monitor your plugins', theme's and other code behaviour, it will generate a alert when a PHP error, warning, exception or shutdown is detected. It is also possible to log all HTTP GET and POST requests that are reaching your WordPress installation to a log file with WP Security Audit Log. Simply enable the PHP Errors monitoring or logging from the plugins settings.
|
92 |
|
95 |
= Other Noteworthy Features =
|
96 |
WP Security Audit Log plugin also has a number of features that make WordPress and WordPress multisite monitoring and auditing easier, such as:
|
97 |
|
98 |
+
* Realtime Audit Log viewer allowing you to see the changers as they happen without any delays
|
99 |
* Built-in support for reverse proxies and web application firewalls [more information](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
|
100 |
+
* Detailed WordPress audit trail allowing you to see what actually changed when the content of posts, pages and custom post types is changed
|
101 |
+
* WhatIsMyIpAddress.com integration so you can get all information about an IP address with just a mouse click
|
102 |
+
* Limit who can view the WordPress audit trail by either users or roles
|
103 |
+
* Limit who can manage the plugin by either users or roles
|
104 |
* Configurable WordPress dashboard widget highlighting the most recent critical activity
|
105 |
+
* Configurable WordPress security audit trail automatic pruning
|
106 |
* User role is reported in alerts for a complete overview of what is happening
|
107 |
* User avatar is shown in the alerts for better recognizability
|
108 |
* Enable or disable any security alerts
|
136 |
= Related Links and Documentation =
|
137 |
For more information and to get started with WordPress Security, check out the following:
|
138 |
|
139 |
+
* [What is a WordPress Audit Trail?](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-documentation/what-is-a-wordpress-audit-trail/)
|
140 |
* [List of WordPress Security Alerts](http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/)
|
141 |
* [WordPress Multisite Features](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/)
|
142 |
* [WP Security Audit Log and Reverse Proxy and WAFs Support](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
|
143 |
* [WP Security Audit Log Database Documentation](http://www.wpsecurityauditlog.com/documentation/plugin-wordpress-database-documentation/)
|
144 |
* [Official WP Security Audit Log Plugin Website](http://www.wpsecurityauditlog.com/)
|
145 |
|
146 |
+
= Stay a Step Ahead of the Bad Guys - Keep Yourself Informed =
|
147 |
+
Even if WordPress security is not your cup of tea, the security of your WordPress is your responsibility. Keep yourself up to date with the latest WordPress Security Tips, Tricks and news. <strong>[Subscribe to the WP Security Bloggers newsletter](http://www.wpsecuritybloggers.com/subscribe-wordpress-security-daily-weekly-roundup), for an aggregate of posts from the most popular WordPress security blogs.
|
148 |
|
149 |
+
= WP Security Audit Log Plugin Newsletter =
|
150 |
+
To keep yourself updated with what is new and updated in the WP Security Audit Log plugin please [subscribe to the newsletter](https://www.wpsecurityauditlog.com/subscribe-newsletter/).
|
151 |
|
152 |
+
**Note: This plugin requires PHP 5.3 or higher. Older versions of PHP are no longer maintained by PHP and are prone to security issues. For more information or if you need assistance with your version of PHP please get in touch with us by using our [contact form](http://www.wpsecurityauditlog.com/contact/).**
|
153 |
|
154 |
== Installation ==
|
155 |
|
165 |
== Screenshots ==
|
166 |
|
167 |
1. The Audit Log Viewer from where the WordPress administrator can see all the security events generated by WP Security Audit Log WordPress plugin.
|
168 |
+
2. See who is logged in to your WordPress and manage users sessions with the [Users Sessions Management Add-On](http://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/)
|
169 |
+
3. The WP Security Audit Log plugin options from where WordPress administrator can configure the auto pruning of security alerts and specific user access.
|
170 |
+
4. Configuring WordPress email alerts with the [Email Notifications Add-On](http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/)
|
171 |
+
5. Search and filters functionality to automatically search through the WordPress security audit log with the [Search Extension](http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/)
|
172 |
+
6. The Enable/Disable Alerts settings node from where Administrators can disable or enable WordPress security alerts.
|
173 |
+
7. The Audit Log Viewer of a Super Admin in a WordPress multisite network installation with the Site selection drop down menu.
|
174 |
+
8. If there are more than 15 sites in a multisite, an auto complete site search shows up instead of the drop down menu (see [screenshots](https://wordpress.org/plugins/wp-security-audit-log/screenshots/) for reference)
|
175 |
+
9. WP Security Audit Log is integrated with the built-in revision system of WordPress, thus allowing you to see what content changes users make on your WordPress posts, pages and custom post types. For more information read [Keep Record of All WordPress Content Changes with WP Security Audit Log Plugin](http://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/record-all-wordpress-content-changes-wp-security-audit-log-plugin/)
|
176 |
|
177 |
== Changelog ==
|
178 |
|
179 |
+
= 2.4.3 (2016-06-01) =
|
180 |
+
|
181 |
+
* **New Add-On Support**
|
182 |
+
* Included code to support the new [Users Sessions Management Add-On](http://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/), which allows you to see who is logged in to your WordPress and WordPress multisite networks.
|
183 |
+
|
184 |
+
* **New Alerts in the WordPress Audit Trail**
|
185 |
+
* 1004: A login attempt was blocked because a session with the same username already exists
|
186 |
+
* 1005: Multiple logged-in sessions for the same WordPress username has been detected
|
187 |
+
|
188 |
+
* **Improvement**
|
189 |
+
* Plugin reports changes when an object is moved as a sub object in a menu.
|
190 |
+
|
191 |
+
* **Bug fixes**
|
192 |
+
* Fixed a problem where wrong permissions were assigned to the reports directory in the uploads directory for the [Reports Add-On](https://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/).
|
193 |
+
* Fixed an issue where multiple incorrect changes were reported when changing the structure of a menu [Support ticket](https://wordpress.org/support/topic/multiple-entries-when-adding-menu-item).
|
194 |
+
* Fixed a bug in the settings sensor [support ticket](https://wordpress.org/support/topic/php-warning-missing-argument-2-for-wsal_sensors_systemwpupdate?replies=1).
|
195 |
+
|
196 |
= 2.4.2 (2016-04-26) =
|
197 |
|
198 |
* **Improvement**
|
uninstall.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// if uninstall not called from WordPress exit
|
4 |
-
if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) exit();
|
5 |
-
|
6 |
-
require('wp-security-audit-log.php');
|
7 |
WpSecurityAuditLog::GetInstance()->Uninstall();
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// if uninstall not called from WordPress exit
|
4 |
+
if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) exit();
|
5 |
+
|
6 |
+
require('wp-security-audit-log.php');
|
7 |
WpSecurityAuditLog::GetInstance()->Uninstall();
|
wp-security-audit-log.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: WP Security Audit Log
|
|
4 |
Plugin URI: http://www.wpsecurityauditlog.com/
|
5 |
Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
|
6 |
Author: WP White Security
|
7 |
-
Version: 2.4.
|
8 |
Text Domain: wp-security-audit-log
|
9 |
Author URI: http://www.wpsecurityauditlog.com/
|
10 |
License: GPL2
|
4 |
Plugin URI: http://www.wpsecurityauditlog.com/
|
5 |
Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
|
6 |
Author: WP White Security
|
7 |
+
Version: 2.4.3
|
8 |
Text Domain: wp-security-audit-log
|
9 |
Author URI: http://www.wpsecurityauditlog.com/
|
10 |
License: GPL2
|