WP Security Audit Log - Version 2.4.1

Version Description

(2016-04-20) =

Read the WP Security Audit Log 2.4 release notes for a detailed overview of what is new in this version.

  • New Features

    • New setting allowing the users to configure the timestamp of the alerts. Read the FAQ How to change the time zone in the WordPress Audit Trial for more information.
  • New WordPress Security Alerts for Content title changes

    • 2086: User changed the title of a post
    • 2087: User changed the title of a page
    • 2088: User changed the title of a custom post type
  • Improvements

    • Implemented AJAX calls for when migrating the WordPress Audit Trail between databases with the External DB add-on
Download this release

Release Info

Developer WPWhiteSecurity
Plugin Icon 128x128 WP Security Audit Log
Version 2.4.1
Comparing to
See all releases

Code changes from version 2.4 to 2.4.1

Files changed (71) hide show
  1. classes/AbstractLogger.php +13 -13
  2. classes/AbstractSandboxTask.php +68 -68
  3. classes/AbstractSensor.php +42 -42
  4. classes/AbstractView.php +180 -180
  5. classes/Alert.php +98 -98
  6. classes/AlertManager.php +382 -382
  7. classes/AuditLogListView.php +445 -430
  8. classes/Autoloader.php +69 -69
  9. classes/Connector/AbstractConnector.php +36 -36
  10. classes/Connector/ConnectorFactory.php +87 -87
  11. classes/Connector/ConnectorInterface.php +11 -11
  12. classes/Connector/MySQLDBConnector.php +351 -304
  13. classes/Connector/wp-db-custom.php +36 -36
  14. classes/ConstantManager.php +88 -88
  15. classes/EDD_SL_Plugin_Updater.php +170 -170
  16. classes/Helpers/DataHelper.php +22 -22
  17. classes/LicenseManager.php +171 -171
  18. classes/Models/ActiveRecord.php +267 -267
  19. classes/Models/Adapters/ActiveRecordInterface.php +15 -15
  20. classes/Models/Adapters/MetaInterface.php +13 -13
  21. classes/Models/Adapters/MySQL/ActiveRecordAdapter.php +448 -448
  22. classes/Models/Adapters/MySQL/MetaAdapter.php +53 -53
  23. classes/Models/Adapters/MySQL/OccurrenceAdapter.php +187 -187
  24. classes/Models/Adapters/MySQL/OptionAdapter.php +79 -79
  25. classes/Models/Adapters/MySQL/QueryAdapter.php +219 -219
  26. classes/Models/Adapters/OccurrenceInterface.php +11 -11
  27. classes/Models/Adapters/QueryInterface.php +8 -8
  28. classes/Models/Meta.php +34 -34
  29. classes/Models/Occurrence.php +199 -199
  30. classes/Models/OccurrenceQuery.php +29 -29
  31. classes/Models/Option.php +80 -80
  32. classes/Models/Query.php +187 -187
  33. classes/Nicer.php +289 -289
  34. classes/SensorManager.php +49 -49
  35. classes/Sensors/BBPress.php +412 -412
  36. classes/Sensors/Content.php +635 -621
  37. classes/Sensors/CustomHooks.php +49 -49
  38. classes/Sensors/Database.php +132 -132
  39. classes/Sensors/Files.php +55 -55
  40. classes/Sensors/LogInOut.php +182 -182
  41. classes/Sensors/Menus.php +416 -416
  42. classes/Sensors/MetaData.php +208 -208
  43. classes/Sensors/Multisite.php +129 -129
  44. classes/Sensors/PhpErrors.php +104 -104
  45. classes/Sensors/PluginsThemes.php +215 -215
  46. classes/Sensors/Request.php +40 -40
  47. classes/Sensors/System.php +168 -168
  48. classes/Sensors/UserProfile.php +164 -164
  49. classes/Sensors/Widgets.php +234 -234
  50. classes/Settings.php +639 -627
  51. classes/SimpleProfiler.php +43 -43
  52. classes/ViewManager.php +214 -214
  53. classes/Views/About.php +85 -85
  54. classes/Views/AuditLog.php +177 -177
  55. classes/Views/Help.php +76 -76
  56. classes/Views/Licensing.php +87 -87
  57. classes/Views/Settings.php +682 -655
  58. classes/Views/ToggleAlerts.php +150 -150
  59. classes/WidgetManager.php +79 -79
  60. css/auditlog.css +180 -180
  61. css/install-error.css +41 -41
  62. css/nice_r.css +92 -92
  63. css/settings.css +70 -70
  64. defaults.php +6 -3
  65. js/auditlog.js +149 -149
  66. js/common.js +17 -17
  67. js/nice_r.js +11 -11
  68. js/settings.js +73 -73
  69. readme.txt +20 -2
  70. uninstall.php +6 -6
  71. 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
- * 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
- }
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,430 +1,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
- * @var WpSecurityAuditLog
10
- */
11
- protected $_plugin;
12
-
13
- public function __construct($plugin){
14
- $this->_plugin = $plugin;
15
-
16
- $this->_gmt_offset_sec = get_option('gmt_offset') * HOUR_IN_SECONDS;
17
-
18
- parent::__construct(array(
19
- 'singular' => 'log',
20
- 'plural' => 'logs',
21
- 'ajax' => true,
22
- 'screen' => 'interval-list',
23
- ));
24
- }
25
-
26
- protected $_gmt_offset_sec = 0;
27
-
28
- public function no_items(){
29
- _e('No events so far.', 'wp-security-audit-log');
30
- }
31
-
32
- public function extra_tablenav($which){
33
- // items-per-page widget
34
- $o = __('Other', 'wp-security-audit-log');
35
- $p = $this->_plugin->settings->GetViewPerPage();
36
- $items = array($o, 5, 10, 15, 30, 50);
37
- if (!in_array($p, $items)) $items[] = $p;
38
- if ($p == $o || $p == 0) $p = $o[1]; // a sane default if things goes bust
39
-
40
- ?><div class="wsal-ipp wsal-ipp-<?php echo $which; ?>">
41
- <?php _e('Show ', 'wp-security-audit-log'); ?>
42
- <select class="wsal-ipps" onfocus="WsalIppsFocus(value);" onchange="WsalIppsChange(value);">
43
- <?php foreach($items as $item){ ?>
44
- <option
45
- value="<?php echo is_string($item) ? '' : $item; ?>"
46
- <?php if($item == $p)echo 'selected="selected"'; ?>><?php
47
- echo $item;
48
- ?></option>
49
- <?php } ?>
50
- </select>
51
- <?php _e(' Items', 'wp-security-audit-log'); ?>
52
- </div><?php
53
-
54
- // show site alerts widget
55
- if($this->is_multisite() && $this->is_main_blog()){
56
- $curr = $this->get_view_site_id();
57
- ?><div class="wsal-ssa wsal-ssa-<?php echo $which; ?>">
58
- <?php if($this->get_site_count() > 15){ ?>
59
- <?php $curr = $curr ? get_blog_details($curr) : null; ?>
60
- <?php $curr = $curr ? ($curr->blogname . ' (' . $curr->domain . ')') : 'All Sites'; ?>
61
- <input type="text" class="wsal-ssas" value="<?php echo esc_attr($curr); ?>"/>
62
- <?php }else{ ?>
63
- <select class="wsal-ssas" onchange="WsalSsasChange(value);">
64
- <option value="0"><?php _e('All Sites', 'wp-security-audit-log'); ?></option>
65
- <?php foreach($this->get_sites() as $info){ ?>
66
- <option value="<?php echo $info->blog_id; ?>"
67
- <?php if($info->blog_id == $curr)echo 'selected="selected"'; ?>><?php
68
- echo esc_html($info->blogname) . ' (' . esc_html($info->domain) . ')';
69
- ?></option>
70
- <?php } ?>
71
- </select>
72
- <?php } ?>
73
- </div><?php
74
- }
75
- }
76
-
77
- /**
78
- * @param int|null $limit Maximum number of sites to return (null = no limit).
79
- * @return object Object with keys: blog_id, blogname, domain
80
- */
81
- public function get_sites($limit = null){
82
- global $wpdb;
83
-
84
- // build query
85
- $sql = 'SELECT blog_id, domain FROM ' . $wpdb->blogs;
86
- if(!is_null($limit))$sql .= ' LIMIT ' . $limit;
87
-
88
- // execute query
89
- $res = $wpdb->get_results($sql);
90
-
91
- // modify result
92
- foreach($res as $row){
93
- $row->blogname = get_blog_option($row->blog_id, 'blogname');
94
- }
95
-
96
- // return result
97
- return $res;
98
- }
99
-
100
- /**
101
- * @return int The number of sites on the network.
102
- */
103
- public function get_site_count(){
104
- global $wpdb;
105
- $sql = 'SELECT COUNT(*) FROM ' . $wpdb->blogs;
106
- return (int)$wpdb->get_var($sql);
107
- }
108
-
109
- public function get_columns(){
110
- $cols = array(
111
- //'cb' => '<input type="checkbox" />',
112
- //'read' => __('Read', 'wp-security-audit-log'),
113
- 'type' => __('Code', 'wp-security-audit-log'),
114
- 'code' => __('Type', 'wp-security-audit-log'),
115
- 'crtd' => __('Date', 'wp-security-audit-log'),
116
- 'user' => __('Username', 'wp-security-audit-log'),
117
- 'scip' => __('Source IP', 'wp-security-audit-log'),
118
- );
119
- if($this->is_multisite() && $this->is_main_blog() && !$this->is_specific_view()){
120
- $cols['site'] = __('Site', 'wp-security-audit-log');
121
- }
122
- $cols['mesg'] = __('Message', 'wp-security-audit-log');
123
- if($this->_plugin->settings->IsDataInspectorEnabled()){
124
- $cols['data'] = '';
125
- }
126
- $sel_columns = $this->_plugin->settings->GetColumnsSelected();
127
- if (!empty($sel_columns)) {
128
- unset($cols);
129
- $sel_columns = (array)json_decode($sel_columns);
130
- foreach ($sel_columns as $key => $value) {
131
- switch ($key) {
132
- case 'alert_code':
133
- $cols['type'] = __('Code', 'wp-security-audit-log');
134
- break;
135
- case 'type':
136
- $cols['code'] = __('Type', 'wp-security-audit-log');
137
- break;
138
- case 'date':
139
- $cols['crtd'] = __('Date', 'wp-security-audit-log');
140
- break;
141
- case 'username':
142
- $cols['user'] = __('Username', 'wp-security-audit-log');
143
- break;
144
- case 'source_ip':
145
- $cols['scip'] = __('Source IP', 'wp-security-audit-log');
146
- break;
147
- case 'site':
148
- $cols['site'] = __('Site', 'wp-security-audit-log');
149
- break;
150
- case 'message':
151
- $cols['mesg'] = __('Message', 'wp-security-audit-log');
152
- break;
153
- }
154
- }
155
- }
156
- return $cols;
157
- }
158
-
159
- public function column_cb($item){
160
- return '<input type="checkbox" value="'.$item->id.'" '
161
- . 'name="'.esc_attr($this->_args['singular']).'[]"/>';
162
- }
163
-
164
- public function get_sortable_columns(){
165
- return array(
166
- 'read' => array('is_read', false),
167
- //'code' => array('code', false),
168
- 'type' => array('alert_id', false),
169
- 'crtd' => array('created_on', true),
170
- 'user' => array('user', true),
171
- 'scip' => array('scip', false)
172
- );
173
- }
174
-
175
- public function column_default($item, $column_name){
176
- //example: $item->getMetaValue('CurrentUserID')
177
-
178
- if (!$this->_plugin->settings->GetDatetimeFormat()) $datetimeFormat = 'h:i:s.$$$&\n\b\s\p;A';
179
- else $datetimeFormat = 'H:i:s.$$$';
180
- switch($column_name){
181
- case 'read':
182
- return '<span class="log-read log-read-'
183
- . ($item->is_read ? 'old' : 'new')
184
- . '" title="' . __('Click to toggle.', 'wp-security-audit-log') . '"></span>';
185
- case 'type':
186
- return str_pad($item->alert_id, 4, '0', STR_PAD_LEFT);
187
- case 'code':
188
- $code = $this->_plugin->alerts->GetAlert($item->alert_id);
189
- $code = $code ? $code->code : 0;
190
- $const = (object)array('name' => 'E_UNKNOWN', 'value' => 0, 'description' => __('Unknown error code.', 'wp-security-audit-log'));
191
- $const = $this->_plugin->constants->GetConstantBy('value', $code, $const);
192
- return '<span class="log-type log-type-' . $const->value
193
- . '" title="' . esc_html($const->name . ': ' . $const->description) . '"></span>';
194
- case 'crtd':
195
- return $item->created_on ? (
196
- str_replace(
197
- '$$$',
198
- substr(number_format(fmod($item->created_on + $this->_gmt_offset_sec, 1), 3), 2),
199
- date('Y-m-d<\b\r>'.$datetimeFormat, $item->created_on + $this->_gmt_offset_sec)
200
- )
201
- ) : '<i>unknown</i>';
202
- case 'user':
203
- $username = $item->GetUsername();
204
- if ($username && ($user = get_user_by('login', $username))) {
205
- $image = get_avatar($user->ID, 32);
206
- $uhtml = '<a href="' . admin_url('user-edit.php?user_id=' . $user->ID)
207
- . '" target="_blank">' . esc_html($user->display_name) . '</a>';
208
- $roles = $item->GetUserRoles();
209
- if (is_array($roles) && count($roles)) {
210
- $roles = __(esc_html(ucwords(implode(', ', $roles))));
211
- } else if (is_string($roles) && $roles != '') {
212
- $roles = __(esc_html(ucwords(str_replace(array("\"", "[", "]"), " ", $roles))));
213
- } else {
214
- $roles = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
215
- }
216
- } elseif ($username == 'Plugin') {
217
- $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/plugin-logo.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
218
- $uhtml = '<i>' . __('Plugin', 'wp-security-audit-log') . '</i>';
219
- $roles = '';
220
- } else {
221
- $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
222
- $uhtml = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
223
- $roles = '';
224
- }
225
- return $image . $uhtml . '<br/>' . $roles;
226
- case 'scip':
227
- $scip = $item->GetSourceIP();
228
- if (is_string($scip)) {
229
- $scip = str_replace(array("\"", "[", "]"), "", $scip);
230
- }
231
- $oips = array(); //$item->GetOtherIPs();
232
- // if there's no IP...
233
- if (is_null($scip) || $scip == '') return '<i>unknown</i>';
234
- // if there's only one IP...
235
- $link = "http://whatismyipaddress.com/ip/" . $scip ."?utm_source=plugin&utm_medium=referral&utm_campaign=WPSAL";
236
- if (count($oips) < 2) return "<a target='_blank' href='$link'>". esc_html($scip) .'</a>';
237
- // if there are many IPs...
238
- $html = "<a target='_blank' href='http://whatismyipaddress.com/ip/$scip'>". esc_html($scip) .'</a>'.' <a href="javascript:;" onclick="jQuery(this).hide().next().show();">(more&hellip;)</a><div style="display: none;">';
239
- foreach($oips as $ip)if($scip!=$ip)$html .= '<div>' . $ip . '</div>';
240
- $html .= '</div>';
241
- return $html;
242
- case 'site':
243
- $info = get_blog_details($item->site_id, true);
244
- return !$info ? ('Unknown Site '.$item->site_id)
245
- : ('<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>');
246
- case 'mesg':
247
- return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>';
248
- case 'data':
249
- $url = admin_url('admin-ajax.php') . '?action=AjaxInspector&amp;occurrence=' . $item->id;
250
- return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
251
- . ' href="' . $url . '&amp;TB_iframe=true&amp;width=600&amp;height=550">&hellip;</a>';
252
- default:
253
- return isset($item->$column_name)
254
- ? esc_html($item->$column_name)
255
- : 'Column "' . esc_html($column_name) . '" not found';
256
- }
257
- }
258
-
259
- public function reorder_items_str($a, $b){
260
- $result = strcmp($a->{$this->_orderby}, $b->{$this->_orderby});
261
- return ($this->_order === 'asc') ? $result : -$result;
262
- }
263
-
264
- public function reorder_items_int($a, $b){
265
- $result = $a->{$this->_orderby} - $b->{$this->_orderby};
266
- return ($this->_order === 'asc') ? $result : -$result;
267
- }
268
-
269
- public function meta_formatter($name, $value){
270
- switch(true){
271
-
272
- case $name == '%Message%':
273
- return esc_html($value);
274
-
275
- case $name == '%PromoMessage%':
276
- return '<p class="promo-alert">' . $value .'</p>';
277
-
278
- case $name == '%PromoLink%':
279
- return $value;
280
-
281
- case $name == '%MetaLink%':
282
- if (!empty($value)) {
283
- return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
284
- } else {
285
- return "";
286
- }
287
-
288
- case $name == '%RevisionLink%':
289
- if (!empty($value) && $value != 'NULL') {
290
- return ' Click <a target="_blank" href="'.$value.'">here</a> to see the content changes.';
291
- } else {
292
- return "";
293
- }
294
-
295
- case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
296
- return '<strong>' . (
297
- strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '&hellip;') : esc_html($value)
298
- ) . '</strong>';
299
-
300
- case strncmp($value, 'http://', 7) === 0:
301
- case strncmp($value, 'https://', 7) === 0:
302
- return '<a href="' . esc_html($value) . '"'
303
- . ' title="' . esc_html($value) . '"'
304
- . ' target="_blank">'
305
- . esc_html(parse_url($value, PHP_URL_HOST)) . '/&hellip;/'
306
- . esc_html(basename(parse_url($value, PHP_URL_PATH)))
307
- . '</a>';
308
-
309
- default:
310
- return '<strong>' . esc_html($value) . '</strong>';
311
- }
312
- }
313
-
314
- protected function is_multisite(){
315
- return $this->_plugin->IsMultisite();
316
- }
317
-
318
- protected function is_main_blog(){
319
- return get_current_blog_id() == 1;
320
- }
321
-
322
- protected function is_specific_view(){
323
- return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
324
- }
325
-
326
- protected function get_specific_view(){
327
- return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
328
- }
329
-
330
- protected function get_view_site_id(){
331
- switch(true){
332
-
333
- // non-multisite
334
- case !$this->is_multisite():
335
- return 0;
336
-
337
- // multisite + main site view
338
- case $this->is_main_blog() && !$this->is_specific_view():
339
- return 0;
340
-
341
- // multisite + switched site view
342
- case $this->is_main_blog() && $this->is_specific_view():
343
- return $this->get_specific_view();
344
-
345
- // multisite + local site view
346
- default:
347
- return get_current_blog_id();
348
-
349
- }
350
- }
351
-
352
- public function prepare_items() {
353
- $per_page = $this->_plugin->settings->GetViewPerPage();
354
-
355
- $columns = $this->get_columns();
356
- $hidden = array();
357
- $sortable = $this->get_sortable_columns();
358
-
359
- $this->_column_headers = array($columns, $hidden, $sortable);
360
-
361
- //$this->process_bulk_action();
362
-
363
- //TO DO: Get rid of OccurrenceQuery and use the Occurence Model
364
- $query = new WSAL_Models_OccurrenceQuery();
365
-
366
- $bid = (int)$this->get_view_site_id();
367
- if ($bid) {
368
- $query->addCondition("site_id = %s ", $bid);
369
- }
370
-
371
- $query = apply_filters('wsal_auditlog_query', $query);
372
-
373
- $total_items = $query->getAdapter()->Count($query);
374
-
375
- if (empty($_REQUEST["orderby"])) {
376
- $query->addOrderBy("created_on", true);
377
- } else {
378
- $orderByField = $_REQUEST["orderby"];
379
-
380
- $isDescending = true;
381
- if (!empty($_REQUEST['order']) && $_REQUEST["order"] == "asc") {
382
- $isDescending = false;
383
- }
384
-
385
- //TO DO: Allow order by meta values
386
- if ($orderByField == "scip") {
387
- $query->addMetaJoin();
388
- $query->addOrderBy('CASE WHEN meta.name = "ClientIP" THEN meta.value END', $isDescending);
389
- } else if ($orderByField == "user") {
390
- $query->addMetaJoin();
391
- $query->addOrderBy('CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $isDescending);
392
- } else {
393
- $tmp = new WSAL_Models_Occurrence();
394
- //Making sure the field exists to order by
395
- if (isset($tmp->{$orderByField})) {
396
- // TODO we used to use a custom comparator ... is it safe to let MySQL do the ordering now?
397
- $query->addOrderBy($_REQUEST["orderby"], $isDescending);
398
-
399
- } else {
400
- $query->addOrderBy("created_on", true);
401
- }
402
- }
403
- }
404
-
405
- /** @todo Modify $query instead */
406
- /** @deprecated */
407
- //$data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
408
- $query->setOffset(($this->get_pagenum() - 1) * $per_page);
409
- $query->setLimit($per_page);
410
-
411
- $this->items = $query->getAdapter()->Execute($query);
412
-
413
- $this->set_pagination_args(array(
414
- 'total_items' => $total_items,
415
- 'per_page' => $per_page,
416
- 'total_pages' => ceil($total_items / $per_page)
417
- ));
418
- }
419
-
420
- public function single_row($item)
421
- {
422
- if ($item->alert_id == 9999) {
423
- echo '<tr style="background-color: #D5E46E">';
424
- $this->single_row_columns($item);
425
- echo '</tr>';
426
- } else {
427
- parent::single_row($item);
428
- }
429
- }
430
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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&hellip;)</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&amp;occurrence=' . $item->id;
263
+ return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
264
+ . ' href="' . $url . '&amp;TB_iframe=true&amp;width=600&amp;height=550">&hellip;</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)) . '&hellip;') : esc_html($value)
313
+ ) . '</strong>';
314
+
315
+ case strncmp($value, 'http://', 7) === 0:
316
+ case strncmp($value, 'https://', 7) === 0:
317
+ return '<a href="' . esc_html($value) . '"'
318
+ . ' title="' . esc_html($value) . '"'
319
+ . ' target="_blank">'
320
+ . esc_html(parse_url($value, PHP_URL_HOST)) . '/&hellip;/'
321
+ . esc_html(basename(parse_url($value, PHP_URL_PATH)))
322
+ . '</a>';
323
+
324
+ default:
325
+ return '<strong>' . esc_html($value) . '</strong>';
326
+ }
327
+ }
328
+
329
+ protected function is_multisite()
330
+ {
331
+ return $this->_plugin->IsMultisite();
332
+ }
333
+
334
+ protected function is_main_blog()
335
+ {
336
+ return get_current_blog_id() == 1;
337
+ }
338
+
339
+ protected function is_specific_view()
340
+ {
341
+ return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
342
+ }
343
+
344
+ protected function get_specific_view()
345
+ {
346
+ return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
347
+ }
348
+
349
+ protected function get_view_site_id()
350
+ {
351
+ switch (true) {
352
+ // non-multisite
353
+ case !$this->is_multisite():
354
+ return 0;
355
+ // multisite + main site view
356
+ case $this->is_main_blog() && !$this->is_specific_view():
357
+ return 0;
358
+ // multisite + switched site view
359
+ case $this->is_main_blog() && $this->is_specific_view():
360
+ return $this->get_specific_view();
361
+ // multisite + local site view
362
+ default:
363
+ return get_current_blog_id();
364
+ }
365
+ }
366
+
367
+ public function prepare_items()
368
+ {
369
+ $per_page = $this->_plugin->settings->GetViewPerPage();
370
+
371
+ $columns = $this->get_columns();
372
+ $hidden = array();
373
+ $sortable = $this->get_sortable_columns();
374
+
375
+ $this->_column_headers = array($columns, $hidden, $sortable);
376
+
377
+ //$this->process_bulk_action();
378
+ //TO DO: Get rid of OccurrenceQuery and use the Occurence Model
379
+ $query = new WSAL_Models_OccurrenceQuery();
380
+
381
+ $bid = (int)$this->get_view_site_id();
382
+ if ($bid) {
383
+ $query->addCondition("site_id = %s ", $bid);
384
+ }
385
+
386
+ $query = apply_filters('wsal_auditlog_query', $query);
387
+
388
+ $total_items = $query->getAdapter()->Count($query);
389
+
390
+ if (empty($_REQUEST["orderby"])) {
391
+ $query->addOrderBy("created_on", true);
392
+ } else {
393
+ $orderByField = $_REQUEST["orderby"];
394
+
395
+ $isDescending = true;
396
+ if (!empty($_REQUEST['order']) && $_REQUEST["order"] == "asc") {
397
+ $isDescending = false;
398
+ }
399
+
400
+ //TO DO: Allow order by meta values
401
+ if ($orderByField == "scip") {
402
+ $query->addMetaJoin();
403
+ $query->addOrderBy('CASE WHEN meta.name = "ClientIP" THEN meta.value END', $isDescending);
404
+ } else if ($orderByField == "user") {
405
+ $query->addMetaJoin();
406
+ $query->addOrderBy('CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $isDescending);
407
+ } else {
408
+ $tmp = new WSAL_Models_Occurrence();
409
+ //Making sure the field exists to order by
410
+ if (isset($tmp->{$orderByField})) {
411
+ // TODO we used to use a custom comparator ... is it safe to let MySQL do the ordering now?
412
+ $query->addOrderBy($_REQUEST["orderby"], $isDescending);
413
+
414
+ } else {
415
+ $query->addOrderBy("created_on", true);
416
+ }
417
+ }
418
+ }
419
+
420
+ /** @todo Modify $query instead */
421
+ /** @deprecated */
422
+ //$data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
423
+ $query->setOffset(($this->get_pagenum() - 1) * $per_page);
424
+ $query->setLimit($per_page);
425
+
426
+ $this->items = $query->getAdapter()->Execute($query);
427
+
428
+ $this->set_pagination_args(array(
429
+ 'total_items' => $total_items,
430
+ 'per_page' => $per_page,
431
+ 'total_pages' => ceil($total_items / $per_page)
432
+ ));
433
+ }
434
+
435
+ public function single_row($item)
436
+ {
437
+ if ($item->alert_id == 9999) {
438
+ echo '<tr style="background-color: #D5E46E">';
439
+ $this->single_row_columns($item);
440
+ echo '</tr>';
441
+ } else {
442
+ parent::single_row($item);
443
+ }
444
+ }
445
+ }
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,304 +1,351 @@
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
- @ini_set('memory_limit', '256M');
13
-
14
- $this->connectionConfig = $connectionConfig;
15
- parent::__construct("MySQL");
16
- require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
17
- }
18
-
19
- public function TestConnection()
20
- {
21
- error_reporting(E_ALL ^ E_WARNING);
22
- $connectionConfig = $this->connectionConfig;
23
- $password = $this->decryptString($connectionConfig['password']);
24
- $newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
25
- if (!$newWpdb->has_connected) { // Database Error
26
- throw new Exception("Connection failed. Please check your connection details.");
27
- }
28
- }
29
-
30
- /**
31
- * Creates a connection and returns it
32
- * @return Instance of WPDB
33
- */
34
- private function createConnection()
35
- {
36
- if (!empty($this->connectionConfig)) {
37
- //TO DO: Use the provided connection config
38
- $connectionConfig = $this->connectionConfig;
39
- $password = $this->decryptString($connectionConfig['password']);
40
- $newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
41
- $newWpdb->set_prefix($connectionConfig['base_prefix']);
42
- return $newWpdb;
43
- } else {
44
- global $wpdb;
45
- return $wpdb;
46
- }
47
- }
48
-
49
- /**
50
- * Returns a wpdb instance
51
- */
52
- public function getConnection()
53
- {
54
- if (!empty($this->connection)) {
55
- return $this->connection;
56
- } else {
57
- $this->connection = $this->createConnection();
58
- return $this->connection;
59
- }
60
- }
61
-
62
- /**
63
- * Gets an adapter for the specified model
64
- */
65
- public function getAdapter($class_name)
66
- {
67
- $objName = $this->getAdapterClassName($class_name);
68
- return new $objName($this->getConnection());
69
- }
70
-
71
- protected function getAdapterClassName($class_name)
72
- {
73
- return 'WSAL_Adapters_MySQL_'.$class_name;
74
- }
75
-
76
- /**
77
- * Checks if the necessary tables are available
78
- */
79
- public function isInstalled()
80
- {
81
- global $wpdb;
82
- $table = $wpdb->base_prefix . 'wsal_occurrences';
83
- return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
84
- }
85
-
86
- /**
87
- * Checks if old version tables are available
88
- */
89
- public function canMigrate()
90
- {
91
- $wpdb = $this->getConnection();
92
- $table = $wpdb->base_prefix . 'wordpress_auditlog_events';
93
- return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
94
- }
95
-
96
- /**
97
- * Install all DB tables.
98
- */
99
- public function installAll($excludeOptions = false)
100
- {
101
- $plugin = WpSecurityAuditLog::GetInstance();
102
-
103
- foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
104
- $filePath = explode(DIRECTORY_SEPARATOR, $file);
105
- $fileName = $filePath[count($filePath) - 1];
106
- $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
107
-
108
- $class = new $className($this->getConnection());
109
- if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
110
- continue;
111
- }
112
-
113
- if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
114
- $class->Install();
115
- }
116
- }
117
- }
118
-
119
- /**
120
- * Uninstall all DB tables.
121
- */
122
- public function uninstallAll()
123
- {
124
- $plugin = WpSecurityAuditLog::GetInstance();
125
-
126
- foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
127
- $filePath = explode(DIRECTORY_SEPARATOR, $file);
128
- $fileName = $filePath[count($filePath) - 1];
129
- $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
130
-
131
- $class = new $className($this->getConnection());
132
- if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
133
- $class->Uninstall();
134
- }
135
- }
136
- }
137
-
138
- public function Migrate()
139
- {
140
- global $wpdb;
141
- $_wpdb = $this->getConnection();
142
-
143
- // Load data Occurrences from WP
144
- $occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
145
- if (!$occurrence->IsInstalled()) die("No alerts to import");
146
- $sql = 'SELECT * FROM ' . $occurrence->GetWPTable();
147
- $occurrences = $wpdb->get_results($sql, ARRAY_A);
148
-
149
- // Insert data to External DB
150
- if (!empty($occurrences)) {
151
- $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
152
- $increase_id = 0;
153
- $sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
154
- $increase_id = (int)$_wpdb->get_var($sql);
155
- // split data
156
- $occurrences_splited = $this->array_split($occurrences, 3);
157
- foreach ($occurrences_splited as $occurrences_partition) {
158
- if (!empty($occurrences_partition)) {
159
- $sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
160
- foreach ($occurrences_partition as $entry) {
161
- $sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
162
- }
163
- $sql = rtrim($sql, ", ");
164
- $_wpdb->query($sql);
165
- }
166
- }
167
- }
168
-
169
- // Load data Meta from WP
170
- $meta = new WSAL_Adapters_MySQL_Meta($wpdb);
171
- if (!$meta->IsInstalled()) die("No alerts to import");
172
- $sql = 'SELECT * FROM ' . $meta->GetWPTable();
173
- $metadata = $wpdb->get_results($sql, ARRAY_A);
174
-
175
- // Insert data to External DB
176
- if (!empty($metadata)) {
177
- $metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
178
- // split data
179
- $metadata_splited = $this->array_split($metadata, 3);
180
- foreach ($metadata_splited as $metadata_partition) {
181
- if (!empty($metadata_partition)) {
182
- $sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
183
- foreach ($metadata_partition as $entry) {
184
- $occurrence_id = $entry['occurrence_id'] + $increase_id;
185
- $sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.$entry['value'].'\'), ';
186
- }
187
- $sql = rtrim($sql, ", ");
188
- $_wpdb->query($sql);
189
- }
190
- }
191
- }
192
- $this->DeleteAfterMigrate($occurrence);
193
- $this->DeleteAfterMigrate($meta);
194
- }
195
-
196
- public function MigrateBack()
197
- {
198
- global $wpdb;
199
- $_wpdb = $this->getConnection();
200
-
201
- // Load data Occurrences from External DB
202
- $occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
203
- if (!$occurrence->IsInstalled()) die("No alerts to import");
204
- $sql = 'SELECT * FROM ' . $occurrence->GetTable();
205
- $occurrences = $_wpdb->get_results($sql, ARRAY_A);
206
-
207
- // Insert data to WP
208
- if (!empty($occurrences)) {
209
- $occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
210
- // split data
211
- $occurrences_splited = $this->array_split($occurrences, 3);
212
- foreach ($occurrences_splited as $occurrences_partition) {
213
- if (!empty($occurrences_partition)) {
214
- $sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
215
- foreach ($occurrences_partition as $entry) {
216
- $sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
217
- }
218
- $sql = rtrim($sql, ", ");
219
- $wpdb->query($sql);
220
- }
221
- }
222
- }
223
-
224
- // Load data Meta from External DB
225
- $meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
226
- if (!$meta->IsInstalled()) die("No alerts to import");
227
- $sql = 'SELECT * FROM ' . $meta->GetTable();
228
- $metadata = $_wpdb->get_results($sql, ARRAY_A);
229
-
230
- // Insert data to WP
231
- if (!empty($metadata)) {
232
- $metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
233
- // split data
234
- $metadata_splited = $this->array_split($metadata, 3);
235
- foreach ($metadata_splited as $metadata_partition) {
236
- if (!empty($metadata_partition)) {
237
- $sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
238
- foreach ($metadata_partition as $entry) {
239
- $sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.$entry['value'].'\'), ';
240
- }
241
- $sql = rtrim($sql, ", ");
242
- $wpdb->query($sql);
243
- }
244
- }
245
- }
246
- }
247
-
248
- private function DeleteAfterMigrate($record)
249
- {
250
- global $wpdb;
251
- $sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
252
- $wpdb->query($sql);
253
- }
254
-
255
- public function encryptString($plaintext)
256
- {
257
- $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
258
- $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
259
- $key = $this->truncateKey();
260
- $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
261
- $ciphertext = $iv . $ciphertext;
262
- $ciphertext_base64 = base64_encode($ciphertext);
263
-
264
- return $ciphertext_base64;
265
- }
266
-
267
- private function decryptString($ciphertext_base64)
268
- {
269
- $ciphertext_dec = base64_decode($ciphertext_base64);
270
- $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
271
-
272
- $iv_dec = substr($ciphertext_dec, 0, $iv_size);
273
- $ciphertext_dec = substr($ciphertext_dec, $iv_size);
274
- $key = $this->truncateKey();
275
- $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
276
-
277
- return rtrim($plaintext_dec, "\0");
278
- }
279
-
280
- private function truncateKey()
281
- {
282
- if (!defined('AUTH_KEY')) {
283
- return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
284
- }
285
- $key_size = strlen(AUTH_KEY);
286
- if ($key_size > 32) {
287
- return substr(AUTH_KEY, 0, 32);
288
- } else {
289
- return AUTH_KEY;
290
- }
291
- }
292
-
293
- // split the given array into n number of pieces
294
- private function array_split($array, $pieces = 2)
295
- {
296
- if ($pieces < 2) {
297
- return array($array);
298
- }
299
- $newCount = ceil(count($array)/$pieces);
300
- $a = array_slice($array, 0, $newCount);
301
- $b = $this->array_split(array_slice($array, $newCount), $pieces-1);
302
- return array_merge(array($a), $b);
303
- }
304
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ @ini_set('memory_limit', '256M');
13
+
14
+ $this->connectionConfig = $connectionConfig;
15
+ parent::__construct("MySQL");
16
+ require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
17
+ }
18
+
19
+ public function TestConnection()
20
+ {
21
+ error_reporting(E_ALL ^ E_WARNING);
22
+ $connectionConfig = $this->connectionConfig;
23
+ $password = $this->decryptString($connectionConfig['password']);
24
+ $newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
25
+ if (!$newWpdb->has_connected) { // Database Error
26
+ throw new Exception("Connection failed. Please check your connection details.");
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Creates a connection and returns it
32
+ * @return Instance of WPDB
33
+ */
34
+ private function createConnection()
35
+ {
36
+ if (!empty($this->connectionConfig)) {
37
+ //TO DO: Use the provided connection config
38
+ $connectionConfig = $this->connectionConfig;
39
+ $password = $this->decryptString($connectionConfig['password']);
40
+ $newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
41
+ $newWpdb->set_prefix($connectionConfig['base_prefix']);
42
+ return $newWpdb;
43
+ } else {
44
+ global $wpdb;
45
+ return $wpdb;
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Returns a wpdb instance
51
+ */
52
+ public function getConnection()
53
+ {
54
+ if (!empty($this->connection)) {
55
+ return $this->connection;
56
+ } else {
57
+ $this->connection = $this->createConnection();
58
+ return $this->connection;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Gets an adapter for the specified model
64
+ */
65
+ public function getAdapter($class_name)
66
+ {
67
+ $objName = $this->getAdapterClassName($class_name);
68
+ return new $objName($this->getConnection());
69
+ }
70
+
71
+ protected function getAdapterClassName($class_name)
72
+ {
73
+ return 'WSAL_Adapters_MySQL_'.$class_name;
74
+ }
75
+
76
+ /**
77
+ * Checks if the necessary tables are available
78
+ */
79
+ public function isInstalled()
80
+ {
81
+ global $wpdb;
82
+ $table = $wpdb->base_prefix . 'wsal_occurrences';
83
+ return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
84
+ }
85
+
86
+ /**
87
+ * Checks if old version tables are available
88
+ */
89
+ public function canMigrate()
90
+ {
91
+ $wpdb = $this->getConnection();
92
+ $table = $wpdb->base_prefix . 'wordpress_auditlog_events';
93
+ return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
94
+ }
95
+
96
+ /**
97
+ * Install all DB tables.
98
+ */
99
+ public function installAll($excludeOptions = false)
100
+ {
101
+ $plugin = WpSecurityAuditLog::GetInstance();
102
+
103
+ foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
104
+ $filePath = explode(DIRECTORY_SEPARATOR, $file);
105
+ $fileName = $filePath[count($filePath) - 1];
106
+ $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
107
+
108
+ $class = new $className($this->getConnection());
109
+ if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
110
+ continue;
111
+ }
112
+
113
+ if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
114
+ $class->Install();
115
+ }
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Uninstall all DB tables.
121
+ */
122
+ public function uninstallAll()
123
+ {
124
+ $plugin = WpSecurityAuditLog::GetInstance();
125
+
126
+ foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
127
+ $filePath = explode(DIRECTORY_SEPARATOR, $file);
128
+ $fileName = $filePath[count($filePath) - 1];
129
+ $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
130
+
131
+ $class = new $className($this->getConnection());
132
+ if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
133
+ $class->Uninstall();
134
+ }
135
+ }
136
+ }
137
+
138
+ private function GetIncreaseOccurrence()
139
+ {
140
+ $_wpdb = $this->getConnection();
141
+ $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
142
+ $sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
143
+ return (int)$_wpdb->get_var($sql);
144
+ }
145
+
146
+ public function MigrateMeta($index, $limit)
147
+ {
148
+ $result = null;
149
+ $offset = ($index * $limit);
150
+ global $wpdb;
151
+ $_wpdb = $this->getConnection();
152
+ // Add +1 because an alert is generated after delete the metadata table
153
+ $increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
154
+
155
+ // Load data Meta from WP
156
+ $meta = new WSAL_Adapters_MySQL_Meta($wpdb);
157
+ if (!$meta->IsInstalled()) {
158
+ $result['empty'] = true;
159
+ return $result;
160
+ }
161
+ $sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
162
+ $metadata = $wpdb->get_results($sql, ARRAY_A);
163
+
164
+ // Insert data to External DB
165
+ if (!empty($metadata)) {
166
+ $metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
167
+
168
+ $index++;
169
+ $sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
170
+ foreach ($metadata as $entry) {
171
+ $occurrence_id = intval($entry['occurrence_id']) + $increase_occurrence_id;
172
+ $sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
173
+ }
174
+ $sql = rtrim($sql, ", ");
175
+ $_wpdb->query($sql);
176
+
177
+ $result['complete'] = false;
178
+ } else {
179
+ $result['complete'] = true;
180
+ $this->DeleteAfterMigrate($meta);
181
+ }
182
+ $result['index'] = $index;
183
+ return $result;
184
+ }
185
+
186
+ public function MigrateOccurrence($index, $limit)
187
+ {
188
+ $result = null;
189
+ $offset = ($index * $limit);
190
+ global $wpdb;
191
+ $_wpdb = $this->getConnection();
192
+
193
+ // Load data Occurrences from WP
194
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
195
+ if (!$occurrence->IsInstalled()) {
196
+ $result['empty'] = true;
197
+ return $result;
198
+ }
199
+ $sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
200
+ $occurrences = $wpdb->get_results($sql, ARRAY_A);
201
+
202
+ // Insert data to External DB
203
+ if (!empty($occurrences)) {
204
+ $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
205
+
206
+ $index++;
207
+ $sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
208
+ foreach ($occurrences as $entry) {
209
+ $sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
210
+ }
211
+ $sql = rtrim($sql, ", ");
212
+ $_wpdb->query($sql);
213
+
214
+ $result['complete'] = false;
215
+ } else {
216
+ $result['complete'] = true;
217
+ $this->DeleteAfterMigrate($occurrence);
218
+ }
219
+ $result['index'] = $index;
220
+ return $result;
221
+ }
222
+
223
+ public function MigrateBackOccurrence($index, $limit)
224
+ {
225
+ $result = null;
226
+ $offset = ($index * $limit);
227
+ global $wpdb;
228
+ $_wpdb = $this->getConnection();
229
+
230
+ // Load data Occurrences from External DB
231
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
232
+ if (!$occurrence->IsInstalled()) {
233
+ $result['empty'] = true;
234
+ return $result;
235
+ }
236
+ $sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
237
+ $occurrences = $_wpdb->get_results($sql, ARRAY_A);
238
+
239
+ // Insert data to WP
240
+ if (!empty($occurrences)) {
241
+ $occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
242
+
243
+ $index++;
244
+ $sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
245
+ foreach ($occurrences as $entry) {
246
+ $sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
247
+ }
248
+ $sql = rtrim($sql, ", ");
249
+ $wpdb->query($sql);
250
+
251
+ $result['complete'] = false;
252
+ } else {
253
+ $result['complete'] = true;
254
+ }
255
+ $result['index'] = $index;
256
+ return $result;
257
+ }
258
+
259
+ public function MigrateBackMeta($index, $limit)
260
+ {
261
+ $result = null;
262
+ $offset = ($index * $limit);
263
+ global $wpdb;
264
+ $_wpdb = $this->getConnection();
265
+
266
+ // Load data Meta from External DB
267
+ $meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
268
+ if (!$meta->IsInstalled()) {
269
+ $result['empty'] = true;
270
+ return $result;
271
+ }
272
+ $sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
273
+ $metadata = $_wpdb->get_results($sql, ARRAY_A);
274
+
275
+ // Insert data to WP
276
+ if (!empty($metadata)) {
277
+ $metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
278
+
279
+ $index++;
280
+ $sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
281
+ foreach ($metadata as $entry) {
282
+ $sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
283
+ }
284
+ $sql = rtrim($sql, ", ");
285
+ $wpdb->query($sql);
286
+
287
+ $result['complete'] = false;
288
+ } else {
289
+ $result['complete'] = true;
290
+ }
291
+ $result['index'] = $index;
292
+ return $result;
293
+ }
294
+
295
+ private function DeleteAfterMigrate($record)
296
+ {
297
+ global $wpdb;
298
+ $sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
299
+ $wpdb->query($sql);
300
+ }
301
+
302
+ public function encryptString($plaintext)
303
+ {
304
+ $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
305
+ $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
306
+ $key = $this->truncateKey();
307
+ $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
308
+ $ciphertext = $iv . $ciphertext;
309
+ $ciphertext_base64 = base64_encode($ciphertext);
310
+
311
+ return $ciphertext_base64;
312
+ }
313
+
314
+ private function decryptString($ciphertext_base64)
315
+ {
316
+ $ciphertext_dec = base64_decode($ciphertext_base64);
317
+ $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
318
+
319
+ $iv_dec = substr($ciphertext_dec, 0, $iv_size);
320
+ $ciphertext_dec = substr($ciphertext_dec, $iv_size);
321
+ $key = $this->truncateKey();
322
+ $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
323
+
324
+ return rtrim($plaintext_dec, "\0");
325
+ }
326
+
327
+ private function truncateKey()
328
+ {
329
+ if (!defined('AUTH_KEY')) {
330
+ return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
331
+ }
332
+ $key_size = strlen(AUTH_KEY);
333
+ if ($key_size > 32) {
334
+ return substr(AUTH_KEY, 0, 32);
335
+ } else {
336
+ return AUTH_KEY;
337
+ }
338
+ }
339
+
340
+ // split the given array into n number of pieces
341
+ private function array_split($array, $pieces = 2)
342
+ {
343
+ if ($pieces < 2) {
344
+ return array($array);
345
+ }
346
+ $newCount = ceil(count($array)/$pieces);
347
+ $a = array_slice($array, 0, $newCount);
348
+ $b = $this->array_split(array_slice($array, $newCount), $pieces-1);
349
+ return array_merge(array($a), $b);
350
+ }
351
+ }
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,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 is_array($copy->$key):
106
- case is_object($copy->$key):
107
- $jsonDecodedVal = WSAL_Helpers_DataHelper::JsonDecode($val);
108
- $this->$key = ($jsonDecodedVal == null) ? $val : $jsonDecodedVal;
109
- break;
110
- case is_int($copy->$key):
111
- $this->$key = (int)$val;
112
- break;
113
- case is_float($copy->$key):
114
- $this->$key = (float)$val;
115
- break;
116
- case is_bool($copy->$key):
117
- $this->$key = (bool)$val;
118
- break;
119
- case is_string($copy->$key):
120
- $this->$key = (string)$val;
121
- break;
122
- default:
123
- throw new Exception('Unsupported type "'.gettype($copy->$key).'"');
124
- }
125
- }
126
- }
127
- return $this;
128
- }
129
-
130
- /**
131
- * Save this active record
132
- * @return integer|boolean Either the number of modified/inserted rows or false on failure.
133
- */
134
- public function Save()
135
- {
136
- $this->_state = self::STATE_UNKNOWN;
137
-
138
- // use today's date if not set up
139
- if (is_null($this->created_on)) {
140
- $this->created_on = $this->GetMicrotime();
141
- }
142
- $updateId = $this->getId();
143
- $result = $this->getAdapter()->Save($this);
144
-
145
- if ($result !== false) {
146
- $this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
147
- }
148
- return $result;
149
- }
150
-
151
- /**
152
- * Deletes this active record
153
- */
154
- public function Delete()
155
- {
156
- $this->_state = self::STATE_UNKNOWN;
157
- $result = $this->getAdapter()->Delete($this);
158
- if($result !== false)
159
- $this->_state = self::STATE_DELETED;
160
-
161
- return $result;
162
- }
163
-
164
- public function Count($cond = '%d', $args = array(1)) {
165
- $result = $this->getAdapter()->Count($cond, $args);
166
- return $result;
167
- }
168
-
169
- /**
170
- * @return boolean
171
- */
172
- public function IsLoaded(){
173
- return $this->_state == self::STATE_LOADED;
174
- }
175
-
176
- /**
177
- * @return boolean
178
- */
179
- public function IsSaved(){
180
- return $this->_state == self::STATE_CREATED
181
- || $this->_state == self::STATE_UPDATED;
182
- }
183
-
184
- /**
185
- * @return boolean
186
- */
187
- public function IsCreated(){
188
- return $this->_state == self::STATE_CREATED;
189
- }
190
-
191
- /**
192
- * @return boolean
193
- */
194
- public function IsUpdated()
195
- {
196
- return $this->_state == self::STATE_UPDATED;
197
- }
198
-
199
- /**
200
- * @return boolean
201
- */
202
- public function IsInstalled()
203
- {
204
- return $this->getAdapter()->IsInstalled();
205
- }
206
-
207
- public function Install()
208
- {
209
- return $this->getAdapter()->Install();
210
- }
211
-
212
- /**
213
- * @return boolean
214
- */
215
- public function IsDeleted()
216
- {
217
- return $this->_state == self::STATE_DELETED;
218
- }
219
-
220
- protected static $_cache = array();
221
-
222
- /**
223
- * Load ActiveRecord from DB or cache.
224
- * @param string $target ActiveRecord class name.
225
- * @param string $query Load condition.
226
- * @param array $args Arguments used in condition.
227
- * @return WSAL_Models_ActiveRecord
228
- */
229
- protected static function CacheLoad($target, $query, $args){
230
- $index = $target . '::' . vsprintf($query, $args);
231
- if(!isset(self::$_cache[$index])){
232
- self::$_cache[$index] = new $target();
233
- self::$_cache[$index]->Load($query, $args);
234
- }
235
- return self::$_cache[$index];
236
- }
237
-
238
- /**
239
- * Remove ActiveRecord cache.
240
- * @param string $target ActiveRecord class name.
241
- * @param string $query Load condition.
242
- * @param array $args Arguments used in condition.
243
- */
244
- protected static function CacheRemove($target, $query, $args){
245
- $index = $target . '::' . sprintf($query, $args);
246
- if(!isset(self::$_cache[$index])){
247
- unset(self::$_cache[$index]);
248
- }
249
- }
250
-
251
- /**
252
- * Clear the cache.
253
- */
254
- protected static function CacheClear()
255
- {
256
- self::$_cache = array();
257
- }
258
-
259
- /**
260
- * Function used in WSAL reporting extension
261
- */
262
- public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp)
263
- {
264
- return $this->getAdapter()->GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp);
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 is_array($copy->$key):
106
+ case is_object($copy->$key):
107
+ $jsonDecodedVal = WSAL_Helpers_DataHelper::JsonDecode($val);
108
+ $this->$key = ($jsonDecodedVal == null) ? $val : $jsonDecodedVal;
109
+ break;
110
+ case is_int($copy->$key):
111
+ $this->$key = (int)$val;
112
+ break;
113
+ case is_float($copy->$key):
114
+ $this->$key = (float)$val;
115
+ break;
116
+ case is_bool($copy->$key):
117
+ $this->$key = (bool)$val;
118
+ break;
119
+ case is_string($copy->$key):
120
+ $this->$key = (string)$val;
121
+ break;
122
+ default:
123
+ throw new Exception('Unsupported type "'.gettype($copy->$key).'"');
124
+ }
125
+ }
126
+ }
127
+ return $this;
128
+ }
129
+
130
+ /**
131
+ * Save this active record
132
+ * @return integer|boolean Either the number of modified/inserted rows or false on failure.
133
+ */
134
+ public function Save()
135
+ {
136
+ $this->_state = self::STATE_UNKNOWN;
137
+
138
+ // use today's date if not set up
139
+ if (is_null($this->created_on)) {
140
+ $this->created_on = $this->GetMicrotime();
141
+ }
142
+ $updateId = $this->getId();
143
+ $result = $this->getAdapter()->Save($this);
144
+
145
+ if ($result !== false) {
146
+ $this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
147
+ }
148
+ return $result;
149
+ }
150
+
151
+ /**
152
+ * Deletes this active record
153
+ */
154
+ public function Delete()
155
+ {
156
+ $this->_state = self::STATE_UNKNOWN;
157
+ $result = $this->getAdapter()->Delete($this);
158
+ if($result !== false)
159
+ $this->_state = self::STATE_DELETED;
160
+
161
+ return $result;
162
+ }
163
+
164
+ public function Count($cond = '%d', $args = array(1)) {
165
+ $result = $this->getAdapter()->Count($cond, $args);
166
+ return $result;
167
+ }
168
+
169
+ /**
170
+ * @return boolean
171
+ */
172
+ public function IsLoaded(){
173
+ return $this->_state == self::STATE_LOADED;
174
+ }
175
+
176
+ /**
177
+ * @return boolean
178
+ */
179
+ public function IsSaved(){
180
+ return $this->_state == self::STATE_CREATED
181
+ || $this->_state == self::STATE_UPDATED;
182
+ }
183
+
184
+ /**
185
+ * @return boolean
186
+ */
187
+ public function IsCreated(){
188
+ return $this->_state == self::STATE_CREATED;
189
+ }
190
+
191
+ /**
192
+ * @return boolean
193
+ */
194
+ public function IsUpdated()
195
+ {
196
+ return $this->_state == self::STATE_UPDATED;
197
+ }
198
+
199
+ /**
200
+ * @return boolean
201
+ */
202
+ public function IsInstalled()
203
+ {
204
+ return $this->getAdapter()->IsInstalled();
205
+ }
206
+
207
+ public function Install()
208
+ {
209
+ return $this->getAdapter()->Install();
210
+ }
211
+
212
+ /**
213
+ * @return boolean
214
+ */
215
+ public function IsDeleted()
216
+ {
217
+ return $this->_state == self::STATE_DELETED;
218
+ }
219
+
220
+ protected static $_cache = array();
221
+
222
+ /**
223
+ * Load ActiveRecord from DB or cache.
224
+ * @param string $target ActiveRecord class name.
225
+ * @param string $query Load condition.
226
+ * @param array $args Arguments used in condition.
227
+ * @return WSAL_Models_ActiveRecord
228
+ */
229
+ protected static function CacheLoad($target, $query, $args){
230
+ $index = $target . '::' . vsprintf($query, $args);
231
+ if(!isset(self::$_cache[$index])){
232
+ self::$_cache[$index] = new $target();
233
+ self::$_cache[$index]->Load($query, $args);
234
+ }
235
+ return self::$_cache[$index];
236
+ }
237
+
238
+ /**
239
+ * Remove ActiveRecord cache.
240
+ * @param string $target ActiveRecord class name.
241
+ * @param string $query Load condition.
242
+ * @param array $args Arguments used in condition.
243
+ */
244
+ protected static function CacheRemove($target, $query, $args){
245
+ $index = $target . '::' . sprintf($query, $args);
246
+ if(!isset(self::$_cache[$index])){
247
+ unset(self::$_cache[$index]);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Clear the cache.
253
+ */
254
+ protected static function CacheClear()
255
+ {
256
+ self::$_cache = array();
257
+ }
258
+
259
+ /**
260
+ * Function used in WSAL reporting extension
261
+ */
262
+ public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp)
263
+ {
264
+ return $this->getAdapter()->GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp);
265
+ }
266
+
267
+ }
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), '[', ''), ']', ''), '\\'', '') 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
+ }
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.'">&#9658;</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.'">&#9658;</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(' ', '&nbsp;', $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.'">&#9658;</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.'">&#9658;</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(' ', '&nbsp;', $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,621 +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
- if (!$changes) {
500
- $contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
501
-
502
- if ($oldpost->post_modified != $newpost->post_modified) {
503
- $event = 0;
504
- // @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
505
- switch ($oldpost->post_status) { // TODO or should this be $newpost?
506
- case 'draft':
507
- if ($contentChanged) {
508
- $event = $this->GetEventTypeForPostType($newpost, 2068, 2069, 2070);
509
- } else {
510
- $event = $this->GetEventTypeForPostType($newpost, 2003, 2007, 2032);
511
- }
512
- break;
513
- case 'publish':
514
- if ($contentChanged) {
515
- $event = $this->GetEventTypeForPostType($newpost, 2065, 2066, 2067);
516
- } else {
517
- $event = $this->GetEventTypeForPostType($newpost, 2002, 2006, 2031);
518
- }
519
- break;
520
- }
521
- if ($event) {
522
- $this->plugin->alerts->Trigger($event, array(
523
- 'PostID' => $post_ID,
524
- 'PostType' => $oldpost->post_type,
525
- 'PostTitle' => $oldpost->post_title,
526
- 'PostUrl' => get_permalink($post_ID) // TODO or should this be $newpost?
527
- ));
528
- return 1;
529
- }
530
- }
531
- }
532
- }
533
-
534
- public function EventChangedCategoryParent()
535
- {
536
- if (empty($_POST)) {
537
- return;
538
- }
539
- if (!current_user_can("manage_categories")) {
540
- return;
541
- }
542
- if (isset($_POST['name'])) {
543
- $category = get_category($_POST['tag_ID']);
544
- if ($category->parent != 0) {
545
- $oldParent = get_category($category->parent);
546
- $oldParentName = (empty($oldParent))? 'no parent' : $oldParent->name;
547
- } else {
548
- $oldParentName = 'no parent';
549
- }
550
- if (isset($_POST['parent'])) {
551
- $newParent = get_category($_POST['parent']);
552
- $newParentName = (empty($newParent))? 'no parent' : $newParent->name;
553
- }
554
- $this->plugin->alerts->Trigger(2052, array(
555
- 'CategoryName' => $category->name,
556
- 'OldParent' => $oldParentName,
557
- 'NewParent' => $newParentName,
558
- ));
559
- }
560
- }
561
-
562
- private function CheckAutoDraft($code, $title)
563
- {
564
- if ($code == 2008 && $title == "auto-draft") {
565
- // to do check setting else return false
566
- if ($this->plugin->settings->IsWPBackend() == 1) {
567
- return true;
568
- } else {
569
- return false;
570
- }
571
- } else {
572
- return false;
573
- }
574
- }
575
-
576
- private function getRevisionLink($revision_id)
577
- {
578
- if (!empty($revision_id)) {
579
- return admin_url('revision.php?revision='.$revision_id);
580
- } else {
581
- return null;
582
- }
583
- }
584
-
585
- /**
586
- * Ignore post from BBPress Plugin,
587
- * Triggered on the BBPress Sensor
588
- */
589
- private function CheckBBPress($post)
590
- {
591
- switch ($post->post_type) {
592
- case 'forum':
593
- case 'topic':
594
- case 'reply':
595
- return true;
596
- default:
597
- return false;
598
- }
599
- }
600
-
601
- /**
602
- * Triggered after save post for add revision link
603
- */
604
- public function SetRevisionLink($post_id, $post, $update)
605
- {
606
- $revisions = wp_get_post_revisions($post_id);
607
- if (!empty($revisions)) {
608
- $revision = array_shift($revisions);
609
-
610
- $objOcc = new WSAL_Models_Occurrence();
611
- $occ = $objOcc->GetByPostID($post_id);
612
- $occ = count($occ) ? $occ[0] : null;
613
- if (!empty($occ)) {
614
- $revisionLink = $this->getRevisionLink($revision->ID);
615
- if (!empty($revisionLink)) {
616
- $occ->SetMetaValue('RevisionLink', $revisionLink);
617
- }
618
- }
619
- }
620
- }
621
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- * Class used for to allow developers to create custom
4
- * alerts
5
- */
6
- class WSAL_Sensors_CustomHooks extends WSAL_AbstractSensor
7
- {
8
- public function HookEvents()
9
- {
10
- /**
11
- * For each hook use add_action() and pass:
12
- * @param string sample_hook_name
13
- * @param string SampleFunction is 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
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 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,182 @@
1
- <?php
2
-
3
- class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
4
-
5
- public function HookEvents() {
6
- add_action('wp_login', array($this, 'EventLogin'), 10, 2);
7
- add_action('wp_logout', array($this, 'EventLogout'));
8
- add_action('password_reset', array($this, 'EventPasswordReset'), 10, 2);
9
- add_action('wp_login_failed', array($this, 'EventLoginFailure'));
10
- add_action('clear_auth_cookie', array($this, 'GetCurrentUser'), 10);
11
- }
12
-
13
- protected $_current_user = null;
14
-
15
- public function GetCurrentUser()
16
- {
17
- $this->_current_user = wp_get_current_user();
18
- }
19
-
20
- public function EventLogin($user_login, $user = null)
21
- {
22
- if (empty($user)) {
23
- $user = get_user_by('login', $user_login);
24
- }
25
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
26
- if ( $this->plugin->settings->IsLoginSuperAdmin($user_login) ) $userRoles[] = 'superadmin';
27
- $this->plugin->alerts->Trigger(1000, array(
28
- 'Username' => $user_login,
29
- 'CurrentUserRoles' => $userRoles,
30
- ), true);
31
- }
32
-
33
- public function EventLogout()
34
- {
35
- if($this->_current_user->ID != 0){
36
- $this->plugin->alerts->Trigger(1001, array(
37
- 'CurrentUserID' => $this->_current_user->ID,
38
- 'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($this->_current_user->roles),
39
- ), true);
40
- }
41
- }
42
-
43
- const TRANSIENT_FAILEDLOGINS = 'wsal-failedlogins-known';
44
- const TRANSIENT_FAILEDLOGINS_UNKNOWN = 'wsal-failedlogins-unknown';
45
-
46
- protected function GetLoginFailureLogLimit()
47
- {
48
- return 10;
49
- }
50
-
51
- protected function GetLoginFailureExpiration()
52
- {
53
- return 12 * 60 * 60;
54
- }
55
-
56
- protected function IsPastLoginFailureLimit($ip, $site_id, $user)
57
- {
58
- $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
59
- if ($user) {
60
- $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
61
- return ($dataKnown !== false) && isset($dataKnown[$site_id.":".$user->ID.":".$ip]) && ($dataKnown[$site_id.":".$user->ID.":".$ip] > $this->GetLoginFailureLogLimit());
62
- } else {
63
- $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
64
- return ($dataUnknown !== false) && isset($dataUnknown[$site_id.":".$ip]) && ($dataUnknown[$site_id.":".$ip] > $this->GetLoginFailureLogLimit());
65
- }
66
- }
67
-
68
- protected function IncrementLoginFailure($ip, $site_id, $user)
69
- {
70
- $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
71
- $set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
72
- if ($user) {
73
- $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
74
- if(!$dataKnown)$dataKnown = array();
75
- if(!isset($dataKnown[$site_id.":".$user->ID.":".$ip]))$dataKnown[$site_id.":".$user->ID.":".$ip] = 1;
76
- $dataKnown[$site_id.":".$user->ID.":".$ip]++;
77
- $set_fn(self::TRANSIENT_FAILEDLOGINS, $dataKnown, $this->GetLoginFailureExpiration());
78
- } else {
79
- $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
80
- if(!$dataUnknown)$dataUnknown = array();
81
- if(!isset($dataUnknown[$site_id.":".$ip]))$dataUnknown[$site_id.":".$ip] = 1;
82
- $dataUnknown[$site_id.":".$ip]++;
83
- $set_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $dataUnknown, $this->GetLoginFailureExpiration());
84
- }
85
- }
86
-
87
- public function EventLoginFailure($username){
88
-
89
- list($y, $m, $d) = explode('-', date('Y-m-d'));
90
-
91
- $ip = $this->plugin->settings->GetMainClientIP();
92
-
93
- $username = array_key_exists('log', $_POST) ? $_POST["log"] : $username;
94
- $newAlertCode = 1003;
95
- $user = get_user_by('login', $username);
96
- $site_id = (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
97
- if ($user) {
98
- $newAlertCode = 1002;
99
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
100
- if ( $this->plugin->settings->IsLoginSuperAdmin($username) ) $userRoles[] = 'superadmin';
101
- }
102
-
103
- if($this->IsPastLoginFailureLimit($ip, $site_id, $user))return;
104
-
105
- $objOcc = new WSAL_Models_Occurrence();
106
-
107
- if ($newAlertCode == 1002) {
108
- if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles))return;
109
- $occ = $objOcc->CheckKnownUsers(
110
- array(
111
- $ip,
112
- $username,
113
- 1002,
114
- $site_id,
115
- mktime(0, 0, 0, $m, $d, $y),
116
- mktime(0, 0, 0, $m, $d + 1, $y) - 1
117
- )
118
- );
119
- $occ = count($occ) ? $occ[0] : null;
120
-
121
- if (!empty($occ)) {
122
- // update existing record exists user
123
- $this->IncrementLoginFailure($ip, $site_id, $user);
124
- $new = $occ->GetMetaValue('Attempts', 0) + 1;
125
-
126
- if ($new > $this->GetLoginFailureLogLimit())
127
- $new = $this->GetLoginFailureLogLimit() . '+';
128
-
129
- $occ->UpdateMetaValue('Attempts', $new);
130
- $occ->UpdateMetaValue('Username', $username);
131
- //$occ->SetMetaValue('CurrentUserRoles', $userRoles);
132
- $occ->created_on = null;
133
- $occ->Save();
134
- } else {
135
- // create a new record exists user
136
- $this->plugin->alerts->Trigger($newAlertCode, array(
137
- 'Attempts' => 1,
138
- 'Username' => $username,
139
- 'CurrentUserRoles' => $userRoles
140
- ));
141
- }
142
- } else {
143
- $occUnknown = $objOcc->CheckUnKnownUsers(
144
- array(
145
- $ip,
146
- 1003,
147
- $site_id,
148
- mktime(0, 0, 0, $m, $d, $y),
149
- mktime(0, 0, 0, $m, $d + 1, $y) - 1
150
- )
151
- );
152
-
153
- $occUnknown = count($occUnknown) ? $occUnknown[0] : null;
154
- if (!empty($occUnknown)) {
155
- // update existing record not exists user
156
- $this->IncrementLoginFailure($ip, $site_id, false);
157
- $new = $occUnknown->GetMetaValue('Attempts', 0) + 1;
158
-
159
- if ($new > $this->GetLoginFailureLogLimit())
160
- $new = $this->GetLoginFailureLogLimit() . '+';
161
-
162
- $occUnknown->UpdateMetaValue('Attempts', $new);
163
- $occUnknown->created_on = null;
164
- $occUnknown->Save();
165
- } else {
166
- // create a new record not exists user
167
- $this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1));
168
- }
169
- }
170
- }
171
-
172
- public function EventPasswordReset($user, $new_pass)
173
- {
174
- if (!empty($user)) {
175
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
176
- $this->plugin->alerts->Trigger(4003, array(
177
- 'Username' => $user->user_login,
178
- 'CurrentUserRoles' => $userRoles,
179
- ), true);
180
- }
181
- }
182
- }
1
+ <?php
2
+
3
+ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor {
4
+
5
+ public function HookEvents() {
6
+ add_action('wp_login', array($this, 'EventLogin'), 10, 2);
7
+ add_action('wp_logout', array($this, 'EventLogout'));
8
+ add_action('password_reset', array($this, 'EventPasswordReset'), 10, 2);
9
+ add_action('wp_login_failed', array($this, 'EventLoginFailure'));
10
+ add_action('clear_auth_cookie', array($this, 'GetCurrentUser'), 10);
11
+ }
12
+
13
+ protected $_current_user = null;
14
+
15
+ public function GetCurrentUser()
16
+ {
17
+ $this->_current_user = wp_get_current_user();
18
+ }
19
+
20
+ public function EventLogin($user_login, $user = null)
21
+ {
22
+ if (empty($user)) {
23
+ $user = get_user_by('login', $user_login);
24
+ }
25
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
26
+ if ( $this->plugin->settings->IsLoginSuperAdmin($user_login) ) $userRoles[] = 'superadmin';
27
+ $this->plugin->alerts->Trigger(1000, array(
28
+ 'Username' => $user_login,
29
+ 'CurrentUserRoles' => $userRoles,
30
+ ), true);
31
+ }
32
+
33
+ public function EventLogout()
34
+ {
35
+ if($this->_current_user->ID != 0){
36
+ $this->plugin->alerts->Trigger(1001, array(
37
+ 'CurrentUserID' => $this->_current_user->ID,
38
+ 'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($this->_current_user->roles),
39
+ ), true);
40
+ }
41
+ }
42
+
43
+ const TRANSIENT_FAILEDLOGINS = 'wsal-failedlogins-known';
44
+ const TRANSIENT_FAILEDLOGINS_UNKNOWN = 'wsal-failedlogins-unknown';
45
+
46
+ protected function GetLoginFailureLogLimit()
47
+ {
48
+ return 10;
49
+ }
50
+
51
+ protected function GetLoginFailureExpiration()
52
+ {
53
+ return 12 * 60 * 60;
54
+ }
55
+
56
+ protected function IsPastLoginFailureLimit($ip, $site_id, $user)
57
+ {
58
+ $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
59
+ if ($user) {
60
+ $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
61
+ return ($dataKnown !== false) && isset($dataKnown[$site_id.":".$user->ID.":".$ip]) && ($dataKnown[$site_id.":".$user->ID.":".$ip] > $this->GetLoginFailureLogLimit());
62
+ } else {
63
+ $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
64
+ return ($dataUnknown !== false) && isset($dataUnknown[$site_id.":".$ip]) && ($dataUnknown[$site_id.":".$ip] > $this->GetLoginFailureLogLimit());
65
+ }
66
+ }
67
+
68
+ protected function IncrementLoginFailure($ip, $site_id, $user)
69
+ {
70
+ $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
71
+ $set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
72
+ if ($user) {
73
+ $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
74
+ if(!$dataKnown)$dataKnown = array();
75
+ if(!isset($dataKnown[$site_id.":".$user->ID.":".$ip]))$dataKnown[$site_id.":".$user->ID.":".$ip] = 1;
76
+ $dataKnown[$site_id.":".$user->ID.":".$ip]++;
77
+ $set_fn(self::TRANSIENT_FAILEDLOGINS, $dataKnown, $this->GetLoginFailureExpiration());
78
+ } else {
79
+ $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
80
+ if(!$dataUnknown)$dataUnknown = array();
81
+ if(!isset($dataUnknown[$site_id.":".$ip]))$dataUnknown[$site_id.":".$ip] = 1;
82
+ $dataUnknown[$site_id.":".$ip]++;
83
+ $set_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $dataUnknown, $this->GetLoginFailureExpiration());
84
+ }
85
+ }
86
+
87
+ public function EventLoginFailure($username){
88
+
89
+ list($y, $m, $d) = explode('-', date('Y-m-d'));
90
+
91
+ $ip = $this->plugin->settings->GetMainClientIP();
92
+
93
+ $username = array_key_exists('log', $_POST) ? $_POST["log"] : $username;
94
+ $newAlertCode = 1003;
95
+ $user = get_user_by('login', $username);
96
+ $site_id = (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
97
+ if ($user) {
98
+ $newAlertCode = 1002;
99
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
100
+ if ( $this->plugin->settings->IsLoginSuperAdmin($username) ) $userRoles[] = 'superadmin';
101
+ }
102
+
103
+ if($this->IsPastLoginFailureLimit($ip, $site_id, $user))return;
104
+
105
+ $objOcc = new WSAL_Models_Occurrence();
106
+
107
+ if ($newAlertCode == 1002) {
108
+ if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles))return;
109
+ $occ = $objOcc->CheckKnownUsers(
110
+ array(
111
+ $ip,
112
+ $username,
113
+ 1002,
114
+ $site_id,
115
+ mktime(0, 0, 0, $m, $d, $y),
116
+ mktime(0, 0, 0, $m, $d + 1, $y) - 1
117
+ )
118
+ );
119
+ $occ = count($occ) ? $occ[0] : null;
120
+
121
+ if (!empty($occ)) {
122
+ // update existing record exists user
123
+ $this->IncrementLoginFailure($ip, $site_id, $user);
124
+ $new = $occ->GetMetaValue('Attempts', 0) + 1;
125
+
126
+ if ($new > $this->GetLoginFailureLogLimit())
127
+ $new = $this->GetLoginFailureLogLimit() . '+';
128
+
129
+ $occ->UpdateMetaValue('Attempts', $new);
130
+ $occ->UpdateMetaValue('Username', $username);
131
+ //$occ->SetMetaValue('CurrentUserRoles', $userRoles);
132
+ $occ->created_on = null;
133
+ $occ->Save();
134
+ } else {
135
+ // create a new record exists user
136
+ $this->plugin->alerts->Trigger($newAlertCode, array(
137
+ 'Attempts' => 1,
138
+ 'Username' => $username,
139
+ 'CurrentUserRoles' => $userRoles
140
+ ));
141
+ }
142
+ } else {
143
+ $occUnknown = $objOcc->CheckUnKnownUsers(
144
+ array(
145
+ $ip,
146
+ 1003,
147
+ $site_id,
148
+ mktime(0, 0, 0, $m, $d, $y),
149
+ mktime(0, 0, 0, $m, $d + 1, $y) - 1
150
+ )
151
+ );
152
+
153
+ $occUnknown = count($occUnknown) ? $occUnknown[0] : null;
154
+ if (!empty($occUnknown)) {
155
+ // update existing record not exists user
156
+ $this->IncrementLoginFailure($ip, $site_id, false);
157
+ $new = $occUnknown->GetMetaValue('Attempts', 0) + 1;
158
+
159
+ if ($new > $this->GetLoginFailureLogLimit())
160
+ $new = $this->GetLoginFailureLogLimit() . '+';
161
+
162
+ $occUnknown->UpdateMetaValue('Attempts', $new);
163
+ $occUnknown->created_on = null;
164
+ $occUnknown->Save();
165
+ } else {
166
+ // create a new record not exists user
167
+ $this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1));
168
+ }
169
+ }
170
+ }
171
+
172
+ public function EventPasswordReset($user, $new_pass)
173
+ {
174
+ if (!empty($user)) {
175
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
176
+ $this->plugin->alerts->Trigger(4003, array(
177
+ 'Username' => $user->user_login,
178
+ 'CurrentUserRoles' => $userRoles,
179
+ ), true);
180
+ }
181
+ }
182
+ }
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, 3);
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, $updates, $complete)
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, 3);
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, $updates, $complete)
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,627 +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
- public function GetAdapterConfig($name_field){
585
- return $this->_plugin->GetGlobalOption($name_field);
586
- }
587
-
588
- public function SetAdapterConfig($name_field, $newvalue){
589
- return $this->_plugin->SetGlobalOption($name_field, trim($newvalue));
590
- }
591
-
592
- public function GetColumns(){
593
- $columns = array('alert_code' => '1', 'type' => '1', 'date' => '1', 'username' => '1', 'source_ip' => '1', 'message' => '1');
594
- if ($this->_plugin->IsMultisite()) {
595
- $columns = array_slice($columns, 0, 5, true) + array('site' => '1') + array_slice($columns, 5, null, true);
596
- }
597
- $selected = $this->GetColumnsSelected();
598
- if (!empty($selected)) {
599
- $columns = array('alert_code' => '0', 'type' => '0', 'date' => '0', 'username' => '0', 'source_ip' => '0', 'message' => '0');
600
- if ($this->_plugin->IsMultisite()) {
601
- $columns = array_slice($columns, 0, 5, true) + array('site' => '0') + array_slice($columns, 5, null, true);
602
- }
603
- $selected = (array)json_decode($selected);
604
- $columns = array_merge($columns, $selected);
605
- return $columns;
606
- } else {
607
- return $columns;
608
- }
609
- }
610
-
611
- public function GetColumnsSelected(){
612
- return $this->_plugin->GetGlobalOption('columns');
613
- }
614
-
615
- public function SetColumns($columns){
616
- return $this->_plugin->SetGlobalOption('columns', json_encode($columns));
617
- }
618
-
619
- public function IsWPBackend(){
620
- return $this->_plugin->GetGlobalOption('wp-backend');
621
- }
622
-
623
- public function SetWPBackend($enabled){
624
- return $this->_plugin->SetGlobalOption('wp-backend', $enabled);
625
- }
626
- // </editor-fold>
627
- }
 
 
 
 
 
 
 
 
 
 
 
 
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&hellip;', '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&hellip;', '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,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
- &nbsp;&nbsp;&nbsp;&nbsp;
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=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
45
- &nbsp;&nbsp;&nbsp;&nbsp;
46
- <a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
47
- </p>
48
- </div>
49
-
50
- <div class="">
51
- <h2><?php _e('WordPress Security Blog', 'wp-security-audit-log'); ?></h2>
52
- <p>
53
- <?php _e('New to WordPress security?', 'wp-security-audit-log'); ?>
54
- <?php _e('Do not know from where to start or which is the best services for you?', 'wp-security-audit-log'); ?>
55
- <?php _e('Visit our WordPress security blog or the WordPress Security category directly for more information and a number of tips and tricks about WordPress security.', 'wp-security-audit-log'); ?>
56
- </p>
57
- <a class="button" href="http://www.wpwhitesecurity.com/blog/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WP White Security Blog', 'wp-security-audit-log'); ?></a>
58
- &nbsp;&nbsp;&nbsp;&nbsp;
59
- <a class="button" href="http://www.wpwhitesecurity.com/wordpress-security/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WordPress Security Category', 'wp-security-audit-log'); ?></a>
60
- </div>
61
- </div>
62
- </div>
63
-
64
- <div style="position: absolute; right: 70px; width: 180px; top: 10px;">
65
- <div class="postbox">
66
- <h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
67
- <div class="inside">
68
- <?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
69
- <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
70
- </div>
71
- </div>
72
- </div>
73
-
74
- </div><?php
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
+ &nbsp;&nbsp;&nbsp;&nbsp;
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=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
45
+ &nbsp;&nbsp;&nbsp;&nbsp;
46
+ <a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
47
+ </p>
48
+ </div>
49
+
50
+ <div class="">
51
+ <h2><?php _e('WordPress Security Blog', 'wp-security-audit-log'); ?></h2>
52
+ <p>
53
+ <?php _e('New to WordPress security?', 'wp-security-audit-log'); ?>
54
+ <?php _e('Do not know from where to start or which is the best services for you?', 'wp-security-audit-log'); ?>
55
+ <?php _e('Visit our WordPress security blog or the WordPress Security category directly for more information and a number of tips and tricks about WordPress security.', 'wp-security-audit-log'); ?>
56
+ </p>
57
+ <a class="button" href="http://www.wpwhitesecurity.com/blog/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WP White Security Blog', 'wp-security-audit-log'); ?></a>
58
+ &nbsp;&nbsp;&nbsp;&nbsp;
59
+ <a class="button" href="http://www.wpwhitesecurity.com/wordpress-security/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WordPress Security Category', 'wp-security-audit-log'); ?></a>
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+ <div style="position: absolute; right: 70px; width: 180px; top: 10px;">
65
+ <div class="postbox">
66
+ <h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
67
+ <div class="inside">
68
+ <?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
69
+ <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
70
+ </div>
71
+ </div>
72
+ </div>
73
+
74
+ </div><?php
75
+ }
76
+
77
  }
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,655 +1,682 @@
1
- <?php
2
- class WSAL_Views_Settings extends WSAL_AbstractView {
3
-
4
- public $adapterMsg = '';
5
-
6
- public function __construct(WpSecurityAuditLog $plugin) {
7
- parent::__construct($plugin);
8
-
9
- add_action('wp_ajax_AjaxCheckSecurityToken', array($this, 'AjaxCheckSecurityToken'));
10
- add_action('wp_ajax_AjaxRunCleanup', array($this, 'AjaxRunCleanup'));
11
- add_action('wp_ajax_AjaxGetAllUsers', array($this, 'AjaxGetAllUsers'));
12
- add_action('wp_ajax_AjaxGetAllRoles', array($this, 'AjaxGetAllRoles'));
13
- }
14
-
15
- public function HasPluginShortcutLink(){
16
- return true;
17
- }
18
-
19
- public function GetTitle() {
20
- return __('Settings', 'wp-security-audit-log');
21
- }
22
-
23
- public function GetIcon() {
24
- return 'dashicons-admin-generic';
25
- }
26
-
27
- public function GetName() {
28
- return __('Settings', 'wp-security-audit-log');
29
- }
30
-
31
- public function GetWeight() {
32
- return 3;
33
- }
34
-
35
- protected function GetTokenType($token){
36
- $users = array();
37
- foreach(get_users('blog_id=0&fields[]=user_login') as $obj)
38
- $users[] = $obj->user_login;
39
- $roles = array_keys(get_editable_roles());
40
-
41
- if(in_array($token, $users))return 'user';
42
- if(in_array($token, $roles))return 'role';
43
- return 'other';
44
- }
45
-
46
- protected function Save(){
47
- check_admin_referer('wsal-settings');
48
- $this->_plugin->settings->SetPruningDateEnabled($_REQUEST['PruneBy'] == 'date');
49
- $this->_plugin->settings->SetPruningDate($_REQUEST['PruningDate']);
50
- $this->_plugin->settings->SetPruningLimitEnabled($_REQUEST['PruneBy'] == 'limit');
51
- $this->_plugin->settings->SetPruningLimit($_REQUEST['PruningLimit']);
52
- $this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
53
- $this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
54
- $this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
55
-
56
- $this->_plugin->settings->SetExcludedMonitoringUsers(isset($_REQUEST['ExUsers']) ? $_REQUEST['ExUsers'] : array());
57
- $this->_plugin->settings->SetExcludedMonitoringRoles(isset($_REQUEST['ExRoles']) ? $_REQUEST['ExRoles'] : array());
58
- $this->_plugin->settings->SetExcludedMonitoringCustom(isset($_REQUEST['Customs']) ? $_REQUEST['Customs'] : array());
59
- $this->_plugin->settings->SetExcludedMonitoringIP(isset($_REQUEST['IpAddrs']) ? $_REQUEST['IpAddrs'] : array());
60
-
61
- $this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
62
- $this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
63
- $this->_plugin->settings->SetMainIPFromProxy(isset($_REQUEST['EnableProxyIpCapture']));
64
- $this->_plugin->settings->SetInternalIPsFiltering(isset($_REQUEST['EnableIpFiltering']));
65
- $this->_plugin->settings->SetIncognito(isset($_REQUEST['Incognito']));
66
- $this->_plugin->settings->SetDeleteData(isset($_REQUEST['DeleteData']));
67
- $this->_plugin->settings->SetDatetimeFormat($_REQUEST['DatetimeFormat']);
68
- $this->_plugin->settings->SetWPBackend(isset($_REQUEST['WPBackend']));
69
- if (!empty($_REQUEST['Columns'])) {
70
- $this->_plugin->settings->SetColumns($_REQUEST['Columns']);
71
- }
72
- $this->_plugin->settings->ClearDevOptions();
73
-
74
- if(isset($_REQUEST['DevOptions'])) {
75
- foreach($_REQUEST['DevOptions'] as $opt) {
76
- $this->_plugin->settings->SetDevOptionEnabled($opt, true);
77
- }
78
- }
79
-
80
- //
81
- // Database Adapter Settings
82
- // Temporarily not used
83
- //
84
- /* Check Adapter config */
85
- if (!empty($_REQUEST["AdapterUser"]) && ($_REQUEST['AdapterUser'] != '') && ($_REQUEST['AdapterName'] != '') && ($_REQUEST['AdapterHostname'] != '') ) {
86
- WSAL_Connector_ConnectorFactory::CheckConfig(
87
- trim($_REQUEST['AdapterType']),
88
- trim($_REQUEST['AdapterUser']),
89
- trim($_REQUEST['AdapterPassword']),
90
- trim($_REQUEST['AdapterName']),
91
- trim($_REQUEST['AdapterHostname']),
92
- trim($_REQUEST['AdapterBasePrefix'])
93
- );
94
-
95
- /* Setting Adapter config */
96
- $this->_plugin->settings->SetAdapterConfig('adapter-type', $_REQUEST['AdapterType']);
97
- $this->_plugin->settings->SetAdapterConfig('adapter-user', $_REQUEST['AdapterUser']);
98
- $this->_plugin->settings->SetAdapterConfig('adapter-password', $_REQUEST['AdapterPassword']);
99
- $this->_plugin->settings->SetAdapterConfig('adapter-name', $_REQUEST['AdapterName']);
100
- $this->_plugin->settings->SetAdapterConfig('adapter-hostname', $_REQUEST['AdapterHostname']);
101
- $this->_plugin->settings->SetAdapterConfig('adapter-base-prefix', $_REQUEST['AdapterBasePrefix']);
102
- }
103
- }
104
-
105
- public function AjaxCheckSecurityToken(){
106
- if(!$this->_plugin->settings->CurrentUserCan('view'))
107
- die('Access Denied.');
108
- if(!isset($_REQUEST['token']))
109
- die('Token parameter expected.');
110
- die($this->GetTokenType($_REQUEST['token']));
111
- }
112
-
113
- public function AjaxRunCleanup(){
114
- if(!$this->_plugin->settings->CurrentUserCan('view'))
115
- die('Access Denied.');
116
- $this->_plugin->CleanUp();
117
- wp_redirect($this->GetUrl());
118
- exit;
119
- }
120
-
121
- public function Render(){
122
- if(!$this->_plugin->settings->CurrentUserCan('edit')){
123
- wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
124
- }
125
- if(isset($_POST['submit'])){
126
- try {
127
- $this->Save();
128
- ?><div class="updated">
129
- <p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p>
130
- </div><?php
131
- }catch(Exception $ex){
132
- ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
133
- }
134
- }
135
- ?>
136
- <h2 id="wsal-tabs" class="nav-tab-wrapper">
137
- <a href="#tab-general" class="nav-tab">General</a>
138
- <a href="#tab-exclude" class="nav-tab">Exclude Objects</a>
139
- <!--<a href="#adapter" class="nav-tab">Data Storage Adapter</a>-->
140
- </h2>
141
- <script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"/></script>
142
- <form id="audit-log-settings" method="post">
143
- <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
144
- <input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
145
- <?php wp_nonce_field('wsal-settings'); ?>
146
-
147
- <div id="audit-log-adverts">
148
- <a href="http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=settingspage&utm_campaign=notifications">
149
- <img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/notifications_250x150.gif" width="250" height="150" alt=""/>
150
- </a>
151
- <a href="http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=settingspage&utm_campaign=search">
152
- <img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/search_250x150.gif" width="250" height="150" alt=""/>
153
- </a>
154
- <a href="http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=settingspage&utm_campaign=reports">
155
- <img src="<?php echo $this->_plugin->GetBaseUrl(); ?>/img/reporting_250x150.gif" width="250" height="150" alt=""/>
156
- </a>
157
- </div>
158
- <div class="nav-tabs">
159
- <table class="form-table wsal-tab widefat" id="tab-general">
160
- <tbody>
161
- <tr>
162
- <th><label for="delete1"><?php _e('Security Alerts Pruning', 'wp-security-audit-log'); ?></label></th>
163
- <td>
164
- <fieldset>
165
- <?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
166
- <?php $nbld = !($this->_plugin->settings->IsPruningDateEnabled() || $this->_plugin->settings->IsPruningLimitEnabled()); ?>
167
- <label for="delete0">
168
- <input type="radio" id="delete0" name="PruneBy" value="" <?php if($nbld)echo 'checked="checked"'; ?>/>
169
- <?php echo __('None', 'wp-security-audit-log'); ?>
170
- </label>
171
- </fieldset>
172
- <fieldset>
173
- <?php $text = __('(eg: 1 month)', 'wp-security-audit-log'); ?>
174
- <?php $nbld = $this->_plugin->settings->IsPruningDateEnabled(); ?>
175
- <label for="delete1">
176
- <input type="radio" id="delete1" name="PruneBy" value="date" <?php if($nbld)echo 'checked="checked"'; ?>/>
177
- <?php echo __('Delete alerts older than', 'wp-security-audit-log'); ?>
178
- </label>
179
- <input type="text" id="PruningDate" name="PruningDate" placeholder="<?php echo $text; ?>"
180
- value="<?php echo esc_attr($this->_plugin->settings->GetPruningDate()); ?>"
181
- onfocus="jQuery('#delete1').attr('checked', true);"/>
182
- <span> <?php echo $text; ?></span>
183
- </fieldset>
184
- <fieldset>
185
- <?php $text = __('(eg: 80)', 'wp-security-audit-log'); ?>
186
- <?php $nbld = $this->_plugin->settings->IsPruningLimitEnabled(); ?>
187
- <label for="delete2">
188
- <input type="radio" id="delete2" name="PruneBy" value="limit" <?php if($nbld)echo 'checked="checked"'; ?>/>
189
- <?php echo __('Keep up to', 'wp-security-audit-log'); ?>
190
- </label>
191
- <input type="text" id="PruningLimit" name="PruningLimit" placeholder="<?php echo $text;?>"
192
- value="<?php echo esc_attr($this->_plugin->settings->GetPruningLimit()); ?>"
193
- onfocus="jQuery('#delete2').attr('checked', true);"/>
194
- <?php echo __('alerts', 'wp-security-audit-log'); ?>
195
- <span><?php echo $text; ?></span>
196
- </fieldset>
197
- <p class="description"><?php
198
- echo __('Next Scheduled Cleanup is in ', 'wp-security-audit-log');
199
- echo human_time_diff(current_time('timestamp'), $next = wp_next_scheduled('wsal_cleanup'));
200
- echo '<!-- ' . date('dMy H:i:s', $next) . ' --> ';
201
- echo sprintf(
202
- __('(or %s)', 'wp-security-audit-log'),
203
- '<a href="' . admin_url('admin-ajax.php?action=AjaxRunCleanup') . '">' . __('Run Manually', 'wp-security-audit-log') . '</a>'
204
- );
205
- ?></p>
206
- </td>
207
- </tr>
208
- <tr>
209
- <th><label for="dwoption_on"><?php _e('Alerts Dashboard Widget', 'wp-security-audit-log'); ?></label></th>
210
- <td>
211
- <fieldset>
212
- <?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
213
- <label for="dwoption_on">
214
- <input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php if($dwe)echo 'checked="checked"'; ?> value="1">
215
- <span><?php _e('On', 'wp-security-audit-log'); ?></span>
216
- </label>
217
- <br/>
218
- <label for="dwoption_off">
219
- <input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php if(!$dwe)echo 'checked="checked"'; ?> value="0">
220
- <span><?php _e('Off', 'wp-security-audit-log'); ?></span>
221
- </label>
222
- <br/>
223
- <p class="description"><?php
224
- echo sprintf(
225
- __('Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log'),
226
- $this->_plugin->settings->GetDashboardWidgetMaxAlerts()
227
- );
228
- ?></p>
229
- </fieldset>
230
- </td>
231
- </tr>
232
- <tr>
233
- <th><label for="pioption_on"><?php _e('Reverse Proxy / Firewall Options', 'wp-security-audit-log'); ?></label></th>
234
- <td>
235
- <fieldset>
236
- <label for="EnableProxyIpCapture">
237
- <input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
238
- if($this->_plugin->settings->IsMainIPFromProxy())echo ' checked="checked"';
239
- ?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?><br/>
240
- <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>
241
- </label>
242
- <br/>
243
- <label for="EnableIpFiltering">
244
- <input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
245
- if($this->_plugin->settings->IsInternalIPsFiltered())echo ' checked="checked"';
246
- ?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?><br/>
247
- <span class="description"><?php _e('Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log'); ?></span>
248
- </label>
249
- </fieldset>
250
- </td>
251
- </tr>
252
- <tr>
253
- <th><label for="ViewerQueryBox"><?php _e('Can View Alerts', 'wp-security-audit-log'); ?></label></th>
254
- <td>
255
- <fieldset>
256
- <input type="text" id="ViewerQueryBox" style="float: left; display: block; width: 250px;">
257
- <input type="button" id="ViewerQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
258
- <br style="clear: both;"/>
259
- <p class="description"><?php
260
- _e('Users and Roles in this list can view the security alerts', 'wp-security-audit-log');
261
- ?></p>
262
- <div id="ViewerList"><?php
263
- foreach($this->_plugin->settings->GetAllowedPluginViewers() as $item){
264
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
265
- <input type="hidden" name="Viewers[]" value="<?php echo esc_attr($item); ?>"/>
266
- <?php echo esc_html($item); ?>
267
- <a href="javascript:;" title="Remove">&times;</a>
268
- </span><?php
269
- }
270
- ?></div>
271
- </fieldset>
272
- </td>
273
- </tr>
274
- <tr>
275
- <th><label for="EditorQueryBox"><?php _e('Can Manage Plugin', 'wp-security-audit-log'); ?></label></th>
276
- <td>
277
- <fieldset>
278
- <input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
279
- <input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
280
- <br style="clear: both;"/>
281
- <p class="description"><?php
282
- _e('Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log');
283
- ?></p>
284
- <div id="EditorList"><?php
285
- foreach($this->_plugin->settings->GetAllowedPluginEditors() as $item){
286
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
287
- <input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
288
- <?php echo esc_html($item); ?>
289
- <a href="javascript:;" title="Remove">&times;</a>
290
- </span><?php
291
- }
292
- ?></div>
293
- </fieldset>
294
- </td>
295
- </tr>
296
- <tr>
297
- <th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
298
- <td>
299
- <fieldset>
300
- <input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
301
- <label for="RestrictAdmins">
302
- <?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
303
- <input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
304
- <span class="description">
305
- <?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'); ?>
306
- </span>
307
- </label>
308
- </fieldset>
309
- </td>
310
- </tr>
311
- <tr>
312
- <th><label for="aroption_on"><?php _e('Refresh Audit Log Viewer', 'wp-security-audit-log'); ?></label></th>
313
- <td>
314
- <fieldset>
315
- <?php $are = $this->_plugin->settings->IsRefreshAlertsEnabled(); ?>
316
- <label for="aroption_on">
317
- <input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: 2px;" <?php if($are)echo 'checked="checked"'; ?> value="1">
318
- <span><?php _e('Automatic', 'wp-security-audit-log'); ?></span>
319
- </label>
320
- <span class="description"> &mdash; <?php _e('Refresh Audit Log Viewer as soon as there are new alerts.', 'wp-security-audit-log'); ?></span>
321
- <br/>
322
- <label for="aroption_off">
323
- <input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: 2px;" <?php if(!$are)echo 'checked="checked"'; ?> value="0">
324
- <span><?php _e('Manual', 'wp-security-audit-log'); ?></span>
325
- </label>
326
- <span class="description"> &mdash; <?php _e('Refresh Audit Log Viewer only when the page is reloaded.', 'wp-security-audit-log'); ?></span>
327
- <br/>
328
- </fieldset>
329
- </td>
330
- </tr>
331
- <tr>
332
- <th><label for="datetime_format_24"><?php _e('Alerts Time Format', 'wp-security-audit-log'); ?></label></th>
333
- <td>
334
- <fieldset>
335
- <?php $datetime = $this->_plugin->settings->GetDatetimeFormat(); ?>
336
- <label for="datetime_format_24">
337
- <input type="radio" name="DatetimeFormat" id="datetime_format_24" style="margin-top: 2px;" <?php if($datetime)echo 'checked="checked"'; ?> value="1">
338
- <span><?php _e('24 hours', 'wp-security-audit-log'); ?></span>
339
- </label>
340
- <br/>
341
- <label for="datetime_format_default">
342
- <input type="radio" name="DatetimeFormat" id="datetime_format_default" style="margin-top: 2px;" <?php if(!$datetime)echo 'checked="checked"'; ?> value="0">
343
- <span><?php _e('AM/PM', 'wp-security-audit-log'); ?></span>
344
- </label>
345
- <br/>
346
- </fieldset>
347
- </td>
348
- </tr>
349
- <tr>
350
- <th><label for="columns"><?php _e('Audit Log Columns Selection', 'wp-security-audit-log'); ?></label></th>
351
- <td>
352
- <fieldset>
353
- <?php $columns = $this->_plugin->settings->GetColumns(); ?>
354
- <?php foreach ($columns as $key => $value) { ?>
355
- <label for="columns">
356
- <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">
357
- <span><?php echo ucwords(str_replace("_", " ", $key)); ?></span>
358
- </label>
359
- <br/>
360
- <?php } ?>
361
- <span class="description"><?php _e('When you disable any of the above such details won’t be shown in the Audit Log
362
- viewer though the plugin will still record such information in the database.', 'wp-security-audit-log'); ?></span>
363
- </fieldset>
364
- </td>
365
- </tr>
366
- <tr>
367
- <th><label><?php _e('Developer Options', 'wp-security-audit-log'); ?></label></th>
368
- <td>
369
- <fieldset>
370
- <?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
371
- <a href="javascript:;" style="<?php if($any)echo 'display: none;'; ?>"
372
- onclick="jQuery(this).hide().next().show();">Show Developer Options</a>
373
- <div style="<?php if(!$any)echo 'display: none;'; ?>">
374
- <p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;"><?php
375
- _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');
376
- ?></p><?php
377
- foreach (array(
378
- WSAL_Settings::OPT_DEV_DATA_INSPECTOR => array(
379
- __('Data Inspector', 'wp-security-audit-log'),
380
- __('View data logged for each triggered alert.', 'wp-security-audit-log')
381
- ),
382
- WSAL_Settings::OPT_DEV_PHP_ERRORS => array(
383
- __('PHP Errors', 'wp-security-audit-log'),
384
- __('Enables sensor for alerts generated from PHP.', 'wp-security-audit-log')
385
- ),
386
- WSAL_Settings::OPT_DEV_REQUEST_LOG => array(
387
- __('Request Log', 'wp-security-audit-log'),
388
- __('Enables logging request to file.', 'wp-security-audit-log')
389
- ),
390
- WSAL_Settings::OPT_DEV_BACKTRACE_LOG => array(
391
- __('Backtrace', 'wp-security-audit-log'),
392
- __('Log full backtrace for PHP-generated alerts.', 'wp-security-audit-log')
393
- ),
394
- ) as $opt => $info) {
395
- ?><label for="devoption_<?php echo $opt; ?>">
396
- <input type="checkbox" name="DevOptions[]" id="devoption_<?php echo $opt; ?>" <?php
397
- if($this->_plugin->settings->IsDevOptionEnabled($opt))echo 'checked="checked"'; ?> value="<?php echo $opt; ?>">
398
- <span><?php echo $info[0]; ?></span>
399
- <?php if (isset($info[1]) && $info[1]) { ?>
400
- <span class="description"> &mdash; <?php echo $info[1]; ?></span>
401
- <?php }
402
- ?></label><br/><?php
403
- }
404
- ?></div>
405
- </fieldset>
406
- </td>
407
- </tr>
408
-
409
- <tr>
410
- <th><label for="Incognito"><?php _e('Hide Plugin in Plugins Page', 'wp-security-audit-log'); ?></label></th>
411
- <td>
412
- <fieldset>
413
- <label for="Incognito">
414
- <input type="checkbox" name="Incognito" value="1" id="Incognito"<?php
415
- if ($this->_plugin->settings->IsIncognito())echo ' checked="checked"';
416
- ?>/> <?php _e('Hide', 'wp-security-audit-log'); ?>
417
- </label>
418
- <br/>
419
- <span class="description">
420
- <?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'); ?>
421
- </span>
422
- </fieldset>
423
- </td>
424
- </tr>
425
- <tr>
426
- <th><label for="DeleteData"><?php _e('Disable Alerts for WordPress Background Activity', 'wp-security-audit-log'); ?></label></th>
427
- <td>
428
- <fieldset>
429
- <label for="WPBackend">
430
- <input type="checkbox" name="WPBackend" value="1" id="WPBackend" <?php
431
- if($this->_plugin->settings->IsWPBackend())echo ' checked="checked"';
432
- ?>/> <?php _e('Hide activity', 'wp-security-audit-log'); ?>
433
- </label>
434
- <br/>
435
- <span class="description">
436
- <?php _e('For example do not raise an alert when WordPress deletes the auto drafts.', 'wp-security-audit-log'); ?>
437
- </span>
438
- </fieldset>
439
- </td>
440
- </tr>
441
- <tr>
442
- <th><label for="DeleteData"><?php _e('Remove Data on Uninstall', 'wp-security-audit-log'); ?></label></th>
443
- <td>
444
- <fieldset>
445
- <label for="DeleteData">
446
- <input type="checkbox" name="DeleteData" value="1" id="DeleteData" onclick="return delete_confirm(this);"<?php
447
- if($this->_plugin->settings->IsDeleteData())echo ' checked="checked"';
448
- ?>/> <span class="description">Check this box if you would like remove all data when the plugin is deleted.</span>
449
- </label>
450
- </fieldset>
451
- </td>
452
- </tr>
453
- </tbody>
454
- </table>
455
- <!-- End general Tab-->
456
- <table class="form-table wsal-tab widefat" id="tab-exclude">
457
- <tbody>
458
- <tr>
459
- <th><h2>Users &amp; Roles</h2></th>
460
- </tr>
461
- <tr>
462
- <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>
463
- </tr>
464
- <tr>
465
- <th><label for="ExUserQueryBox"><?php _e('Excluded Users', 'wp-security-audit-log'); ?></label></th>
466
- <td>
467
- <fieldset>
468
- <input type="text" id="ExUserQueryBox" style="float: left; display: block; width: 250px;">
469
- <input type="button" id="ExUserQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
470
- <br style="clear: both;"/>
471
- <div id="ExUserList"><?php
472
- foreach($this->_plugin->settings->GetExcludedMonitoringUsers() as $item){
473
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
474
- <input type="hidden" name="ExUsers[]" value="<?php echo esc_attr($item); ?>"/>
475
- <?php echo esc_html($item); ?>
476
- <a href="javascript:;" title="Remove">&times;</a>
477
- </span><?php
478
- }
479
- ?></div>
480
- </fieldset>
481
- </td>
482
- </tr>
483
- <tr>
484
- <th><label for="ExRoleQueryBox"><?php _e('Excluded Roles', 'wp-security-audit-log'); ?></label></th>
485
- <td>
486
- <fieldset>
487
- <input type="text" id="ExRoleQueryBox" style="float: left; display: block; width: 250px;">
488
- <input type="button" id="ExRoleQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
489
- <br style="clear: both;"/>
490
- <div id="ExRoleList"><?php
491
- foreach($this->_plugin->settings->GetExcludedMonitoringRoles() as $item){
492
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
493
- <input type="hidden" name="ExRoles[]" value="<?php echo esc_attr($item); ?>"/>
494
- <?php echo esc_html($item); ?>
495
- <a href="javascript:;" title="Remove">&times;</a>
496
- </span><?php
497
- }
498
- ?></div>
499
- </fieldset>
500
- </td>
501
- </tr>
502
- <tr>
503
- <th><h2>Custom Fields</h2></th>
504
- </tr>
505
- <tr>
506
- <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>
507
- </tr>
508
- <tr>
509
- <th><label for="CustomQueryBox"><?php _e('Excluded Custom Fields', 'wp-security-audit-log'); ?></label></th>
510
- <td>
511
- <fieldset>
512
- <input type="text" id="CustomQueryBox" style="float: left; display: block; width: 250px;">
513
- <input type="button" id="CustomQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
514
- <br style="clear: both;"/>
515
- <div id="CustomList"><?php
516
- foreach($this->_plugin->settings->GetExcludedMonitoringCustom() as $item){
517
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
518
- <input type="hidden" name="Customs[]" value="<?php echo esc_attr($item); ?>"/>
519
- <?php echo esc_html($item); ?>
520
- <a href="javascript:;" title="Remove">&times;</a>
521
- </span><?php
522
- }
523
- ?></div>
524
- </fieldset>
525
- </td>
526
- </tr>
527
- <tr>
528
- <th><h2>IP Addresses</h2></th>
529
- </tr>
530
- <tr>
531
- <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>
532
- </tr>
533
- <tr>
534
- <th><label for="IpAddrQueryBox"><?php _e('Excluded IP Addresses', 'wp-security-audit-log'); ?></label></th>
535
- <td>
536
- <fieldset>
537
- <input type="text" id="IpAddrQueryBox" style="float: left; display: block; width: 250px;">
538
- <input type="button" id="IpAddrQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
539
- <br style="clear: both;"/>
540
- <div id="IpAddrList"><?php
541
- foreach($this->_plugin->settings->GetExcludedMonitoringIP() as $item){
542
- ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
543
- <input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr($item); ?>"/>
544
- <?php echo esc_html($item); ?>
545
- <a href="javascript:;" title="Remove">&times;</a>
546
- </span><?php
547
- }
548
- ?></div>
549
- </fieldset>
550
- </td>
551
- </tr>
552
- </tbody>
553
- </table>
554
- </div>
555
- <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes"></p>
556
- </form>
557
- <script type="text/javascript">
558
- <!--
559
- function delete_confirm(elementRef)
560
- {
561
- if ( elementRef.checked )
562
- {
563
- if ( window.confirm('Do you want remove all data when the plugin is deleted?') == false )
564
- elementRef.checked = false;
565
- }
566
- }
567
- // -->
568
- </script><?php
569
- }
570
-
571
- public function Header(){
572
- wp_enqueue_style(
573
- 'settings',
574
- $this->_plugin->GetBaseUrl() . '/css/settings.css',
575
- array(),
576
- filemtime($this->_plugin->GetBaseDir() . '/css/settings.css')
577
- );
578
- ?><style type="text/css">
579
- .wsal-tab {
580
- display: none;
581
- }
582
- .wsal-tab tr.alert-incomplete td {
583
- color: #9BE;
584
- }
585
- .wsal-tab tr.alert-unavailable td {
586
- color: #CCC;
587
- }
588
- </style><?php
589
- }
590
-
591
- public function Footer() {
592
- wp_enqueue_script(
593
- 'settings',
594
- $this->_plugin->GetBaseUrl() . '/js/settings.js',
595
- array(),
596
- filemtime($this->_plugin->GetBaseDir() . '/js/settings.js')
597
- );
598
- ?><script type="text/javascript">
599
- jQuery(document).ready(function(){
600
- // tab handling code
601
- jQuery('#wsal-tabs>a').click(function(){
602
- jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
603
- jQuery('table.wsal-tab').hide();
604
- jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
605
- });
606
- // show relevant tab
607
- var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
608
- if (hashlink.length) {
609
- hashlink.click();
610
- } else {
611
- jQuery('#wsal-tabs>a:first').click();
612
- }
613
-
614
- jQuery(".sel-columns").change(function(){
615
- var notChecked = 1;
616
- jQuery(".sel-columns").each(function(){
617
- if(this.checked) notChecked = 0;
618
- })
619
- if(notChecked == 1){
620
- alert("You have to select at least one column!");
621
- }
622
- });
623
- });
624
- </script><?php
625
- }
626
-
627
- public function AjaxGetAllUsers() {
628
- if(!$this->_plugin->settings->CurrentUserCan('view'))
629
- die('Access Denied.');
630
-
631
- $users = array();
632
- foreach ( get_users() as $user ) {
633
- if (strpos($user->user_login, $_GET['term']) !== false) {
634
- array_push($users, $user->user_login);
635
- }
636
- }
637
- echo json_encode($users);
638
- exit;
639
- }
640
-
641
- public function AjaxGetAllRoles() {
642
- if(!$this->_plugin->settings->CurrentUserCan('view'))
643
- die('Access Denied.');
644
-
645
- $roles = array();
646
- foreach ( get_editable_roles() as $role_name => $role_info ) {
647
- if (strpos($role_name, $_GET['term']) !== false) {
648
- array_push($roles, $role_name);
649
- }
650
- }
651
- echo json_encode($roles);
652
- exit;
653
- }
654
-
655
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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">&times;</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">&times;</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"> &mdash; <?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"> &mdash; <?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"> &mdash; <?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 &amp; 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">&times;</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">&times;</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">&times;</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">&times;</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
@@ -72,7 +72,8 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal)
72
  array(2068, E_NOTICE, __('User modifies content for a draft post', 'wp-security-audit-log'), __('Modified the content of draft post %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
73
  array(2072, E_NOTICE, __('User modifies content of a post', 'wp-security-audit-log'), __('Modified the content of post %PostTitle% which is submitted for review.'.'%RevisionLink%', 'wp-security-audit-log')),
74
  array(2073, E_NOTICE, __('User submitted a post for review', 'wp-security-audit-log'), __('Submitted blog post %PostTitle% for review. Blog post ID is %PostID%', 'wp-security-audit-log')),
75
- array(2074, E_NOTICE, __('User scheduled a post', 'wp-security-audit-log'), __('Scheduled the post %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log'))
 
76
  ),
77
  __('Pages', 'wp-security-audit-log') => array(
78
  array(2004, E_NOTICE, __('User created a new WordPress page and saved it as draft', 'wp-security-audit-log'), __('Created a new page called %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
@@ -95,7 +96,8 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal)
95
  array(2064, E_NOTICE, __('User updates a custom field name for a page', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
96
  array(2066, E_WARNING, __('User modifies content for a published page', 'wp-security-audit-log'), __('Modified the content of published page %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
97
  array(2069, E_NOTICE, __('User modifies content for a draft page', 'wp-security-audit-log'), __('Modified the content of draft page %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
98
- array(2075, E_NOTICE, __('User scheduled a page', 'wp-security-audit-log'), __('Scheduled the page %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log'))
 
99
  ),
100
  __('Custom Posts', 'wp-security-audit-log') => array(
101
  array(2029, E_NOTICE, __('User created a new post with custom post type and saved it as draft', 'wp-security-audit-log'), __('Created a new custom post called %PostTitle% of type %PostType%. Post ID is %PostID%', 'wp-security-audit-log')),
@@ -117,7 +119,8 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal)
117
  array(2063, E_NOTICE, __('User updates a custom field name for a custom post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
118
  array(2067, E_WARNING, __('User modifies content for a published custom post', 'wp-security-audit-log'), __('Modified the content of published custom post type %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
119
  array(2070, E_NOTICE, __('User modifies content for a draft custom post', 'wp-security-audit-log'), __('Modified the content of draft custom post type %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
120
- array(2076, E_NOTICE, __('User scheduled a custom post type', 'wp-security-audit-log'), __('Scheduled the custom post type %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log'))
 
121
  ),
122
  __('Widgets', 'wp-security-audit-log') => array(
123
  array(2042, E_CRITICAL, __('User added a new widget', 'wp-security-audit-log'), __('Added a new %WidgetName% widget in %Sidebar%', 'wp-security-audit-log')),
72
  array(2068, E_NOTICE, __('User modifies content for a draft post', 'wp-security-audit-log'), __('Modified the content of draft post %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
73
  array(2072, E_NOTICE, __('User modifies content of a post', 'wp-security-audit-log'), __('Modified the content of post %PostTitle% which is submitted for review.'.'%RevisionLink%', 'wp-security-audit-log')),
74
  array(2073, E_NOTICE, __('User submitted a post for review', 'wp-security-audit-log'), __('Submitted blog post %PostTitle% for review. Blog post ID is %PostID%', 'wp-security-audit-log')),
75
+ array(2074, E_NOTICE, __('User scheduled a post', 'wp-security-audit-log'), __('Scheduled the post %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log')),
76
+ array(2086, E_NOTICE, __('User changed title of a post', 'wp-security-audit-log'), __('Changed the title of post %OldTitle% to %NewTitle%', 'wp-security-audit-log'))
77
  ),
78
  __('Pages', 'wp-security-audit-log') => array(
79
  array(2004, E_NOTICE, __('User created a new WordPress page and saved it as draft', 'wp-security-audit-log'), __('Created a new page called %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
96
  array(2064, E_NOTICE, __('User updates a custom field name for a page', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
97
  array(2066, E_WARNING, __('User modifies content for a published page', 'wp-security-audit-log'), __('Modified the content of published page %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
98
  array(2069, E_NOTICE, __('User modifies content for a draft page', 'wp-security-audit-log'), __('Modified the content of draft page %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
99
+ array(2075, E_NOTICE, __('User scheduled a page', 'wp-security-audit-log'), __('Scheduled the page %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log')),
100
+ array(2087, E_NOTICE, __('User changed title of a page', 'wp-security-audit-log'), __('Changed the title of page %OldTitle% to %NewTitle%', 'wp-security-audit-log'))
101
  ),
102
  __('Custom Posts', 'wp-security-audit-log') => array(
103
  array(2029, E_NOTICE, __('User created a new post with custom post type and saved it as draft', 'wp-security-audit-log'), __('Created a new custom post called %PostTitle% of type %PostType%. Post ID is %PostID%', 'wp-security-audit-log')),
119
  array(2063, E_NOTICE, __('User updates a custom field name for a custom post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
120
  array(2067, E_WARNING, __('User modifies content for a published custom post', 'wp-security-audit-log'), __('Modified the content of published custom post type %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
121
  array(2070, E_NOTICE, __('User modifies content for a draft custom post', 'wp-security-audit-log'), __('Modified the content of draft custom post type %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
122
+ array(2076, E_NOTICE, __('User scheduled a custom post type', 'wp-security-audit-log'), __('Scheduled the custom post type %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log')),
123
+ array(2088, E_NOTICE, __('User changed title of a custom post', 'wp-security-audit-log'), __('Changed the title of custom post %OldTitle% to %NewTitle%', 'wp-security-audit-log'))
124
  ),
125
  __('Widgets', 'wp-security-audit-log') => array(
126
  array(2042, E_CRITICAL, __('User added a new widget', 'wp-security-audit-log'), __('Added a new %WidgetName% widget in %Sidebar%', 'wp-security-audit-log')),
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 = '&#9658;';
7
- }else{
8
- el.style.display = 'block';
9
- document.getElementById(pfx+'_a'+id).innerHTML = '&#9660;';
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 = '&#9658;';
7
+ }else{
8
+ el.style.display = 'block';
9
+ document.getElementById(pfx+'_a'+id).innerHTML = '&#9660;';
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">&times;</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">&times;</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">&times;</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">&times;</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
@@ -4,10 +4,10 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donat
4
  Plugin URI: http://www.wpsecurityauditlog.com
5
  License: GPLv3
6
  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
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
 
@@ -119,6 +119,7 @@ WP Security Audit Log plugin also has a number of features that make WordPress a
119
  * [ManageWP Plugins of the month](https://managewp.com/free-wordpress-plugins-june-2014)
120
  * [MyWPExpert](http://www.mywpexpert.com/wp-security-audit-log/)
121
  * [BlogVault](https://blogvault.net/wp-security-audit-log-plugin-review/)
 
122
  * [Pagely](https://pagely.com/blog/2015/01/log-wordpress-dashboard-activity-improved-security-auditing/)
123
  * [Design Wall](http://www.designwall.com/blog/10-wordpress-multisite-plugins-you-shouldnt-live-without/)
124
  * [WP Mayor](http://www.wpmayor.com/wp-security-audit-log-plugin-review-user-activity-logging-wordpress/)
@@ -126,6 +127,7 @@ WP Security Audit Log plugin also has a number of features that make WordPress a
126
  * [Tourqe News](http://torquemag.io/5-awesome-wordpress-plugins-you-may-not-have-heard-of/)
127
  * [Shout Me Loud](http://www.shoutmeloud.com/how-to-monitor-user-activities-wordpress-dashboard.html)
128
  * [Monster Post](http://blog.templatemonster.com/2015/12/15/wp-security-audit-log-plugin-review/)
 
129
  * [Make a Website Hub](http://makeawebsitehub.com/wordpress-security/)
130
  * [The Darknet](http://www.darknet.org.uk/2015/10/wp-security-audit-log-a-complete-audit-log-plugin-for-wordpress/)
131
 
@@ -138,6 +140,7 @@ We need help translating the plugin and the WordPress Security Alerts. Please vi
138
  = Related Links and Documentation =
139
  For more information and to get started with WordPress Security, check out the following:
140
 
 
141
  * [List of WordPress Security Alerts](http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/)
142
  * [WordPress Multisite Features](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/)
143
  * [WP Security Audit Log and Reverse Proxy and WAFs Support](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
@@ -208,6 +211,21 @@ Yes. To exclude an IP address you can specify it in the Excluded Objects section
208
 
209
  == Changelog ==
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  = 2.4 (2016-03-28) =
212
 
213
  Read the [WP Security Audit Log 2.4 release notes](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/integration-hooks-custom-alerts-monitoring-wordpress-menus-2-4) for a detailed overview of what is new.
4
  Plugin URI: http://www.wpsecurityauditlog.com
5
  License: GPLv3
6
  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.1
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
 
119
  * [ManageWP Plugins of the month](https://managewp.com/free-wordpress-plugins-june-2014)
120
  * [MyWPExpert](http://www.mywpexpert.com/wp-security-audit-log/)
121
  * [BlogVault](https://blogvault.net/wp-security-audit-log-plugin-review/)
122
+ * [Firewall.cx](http://www.firewall.cx/general-topics-reviews/security-articles/1146-wordpress-audit-monitor-log-site-security-alerts.html)
123
  * [Pagely](https://pagely.com/blog/2015/01/log-wordpress-dashboard-activity-improved-security-auditing/)
124
  * [Design Wall](http://www.designwall.com/blog/10-wordpress-multisite-plugins-you-shouldnt-live-without/)
125
  * [WP Mayor](http://www.wpmayor.com/wp-security-audit-log-plugin-review-user-activity-logging-wordpress/)
127
  * [Tourqe News](http://torquemag.io/5-awesome-wordpress-plugins-you-may-not-have-heard-of/)
128
  * [Shout Me Loud](http://www.shoutmeloud.com/how-to-monitor-user-activities-wordpress-dashboard.html)
129
  * [Monster Post](http://blog.templatemonster.com/2015/12/15/wp-security-audit-log-plugin-review/)
130
+ * [Templatic](https://templatic.com/tips-tricks/improve-wordpress-security-posture/)
131
  * [Make a Website Hub](http://makeawebsitehub.com/wordpress-security/)
132
  * [The Darknet](http://www.darknet.org.uk/2015/10/wp-security-audit-log-a-complete-audit-log-plugin-for-wordpress/)
133
 
140
  = Related Links and Documentation =
141
  For more information and to get started with WordPress Security, check out the following:
142
 
143
+ * [What is a WordPress Audit Trail?](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-documentation/what-is-a-wordpress-audit-trail/]
144
  * [List of WordPress Security Alerts](http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/)
145
  * [WordPress Multisite Features](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/)
146
  * [WP Security Audit Log and Reverse Proxy and WAFs Support](http://www.wpsecurityauditlog.com/documentation/automatically-retrieve-originating-wordpress-user-ip-address/)
211
 
212
  == Changelog ==
213
 
214
+ = 2.4.1 (2016-04-20) =
215
+
216
+ Read the [WP Security Audit Log 2.4 release notes](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/wp-security-audit-log-2-4-1-released/) for a detailed overview of what is new in this version.
217
+
218
+ * **New Features**
219
+ * New setting allowing the users to configure the timestamp of the alerts. Read the FAQ [How to change the time zone in the WordPress Audit Trial](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-documentation/faq-change-time-zone-wordpress-audit-trail/) for more information.
220
+
221
+ * **New WordPress Security Alerts for Content title changes**
222
+ * 2086: User changed the title of a post
223
+ * 2087: User changed the title of a page
224
+ * 2088: User changed the title of a custom post type
225
+
226
+ * **Improvements**
227
+ * Implemented AJAX calls for when migrating the WordPress Audit Trail between databases with the [External DB add-on](https://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/)
228
+
229
  = 2.4 (2016-03-28) =
230
 
231
  Read the [WP Security Audit Log 2.4 release notes](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/integration-hooks-custom-alerts-monitoring-wordpress-menus-2-4) for a detailed overview of what is new.
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.1
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2