WP Security Audit Log - Version 2.5.0

Version Description

(2016-07-12) =

Read the WP Security Audit Log 2.5.0 release notes for a detailed overview of what is new.

  • New Features

    • Plugin now keeps a record in the audit trail of changes in WordPress comments. Refer to the list of alerts for WordPress comments for the complete list.
    • Audit log alerts for 404 (page not found) requests.
    • Audit log alerts for pages / posts / custom post types automatically created by plugins.
    • Added wildcard (*) support for when excluding Custom Fields.
    • New setting to customize From email address and display name (The Reports, Email Alerts and Users Sessions Management add-ons have been updated to use the configured email address).
  • New WordPress Audit Trail Alert for Changes in Comments

    • 2090: User approved a comment
    • 2091: User unapproved a comment
    • 2092: User replied to a comment
    • 2093: User edited a comment
    • 2094: User marked a comment as Spam
    • 2095: User marked a comment as not Spam
    • 2096: User moved a comment to trash
    • 2097: User moved a comment out from the trash
    • 2098: User permanently deleted a comment
    • 2099: Website visitor / User posted a comment (disabled by default. Enable it from the Enable/Disable Alerts node in the plugin menu)
  • New WordPress Audit Trail Alerts for Plugins Activity

    • 5019: Plugin automatically created a post
    • 5020: Plugin automatically created a page
    • 5021: Plugin automatically created a custom post type
    • 5025: Plugin automatically deleted a post
    • 5026: Plugin automatically deleted a page
    • 5027: Plugin automatically deleted a custom post type
  • Other New WordPress Audit Trail Alerts

    • 5031: User updated a theme
    • 2089: User moved an object as a sub-object in a menu
    • 6007: User / website visitor requested a non-existing page (404 ERROR)
  • Improvements

    • Standardized all alerts messages / Improved the text of all of them. Each post / page / custom post type alert has a linkt to the Editor now
Download this release

Release Info

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

Code changes from version 2.4.4 to 2.5.0

Files changed (89) 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/{Models/Adapters → Adapters}/ActiveRecordInterface.php +15 -15
  6. classes/{Models/Adapters → Adapters}/MetaInterface.php +13 -13
  7. classes/{Models/Adapters → Adapters}/MySQL/ActiveRecordAdapter.php +448 -448
  8. classes/{Models/Adapters → Adapters}/MySQL/MetaAdapter.php +53 -53
  9. classes/{Models/Adapters → Adapters}/MySQL/OccurrenceAdapter.php +211 -187
  10. classes/{Models/Adapters → Adapters}/MySQL/OptionAdapter.php +79 -79
  11. classes/{Models/Adapters → Adapters}/MySQL/QueryAdapter.php +219 -219
  12. classes/{Models/Adapters → Adapters}/OccurrenceInterface.php +11 -11
  13. classes/{Models/Adapters → Adapters}/QueryInterface.php +8 -8
  14. classes/Alert.php +98 -98
  15. classes/AlertManager.php +391 -382
  16. classes/AuditLogListView.php +473 -452
  17. classes/Autoloader.php +69 -69
  18. classes/Connector/AbstractConnector.php +37 -36
  19. classes/Connector/ConnectorFactory.php +87 -87
  20. classes/Connector/ConnectorInterface.php +11 -11
  21. classes/Connector/MySQLDB.php +334 -0
  22. classes/Connector/MySQLDBConnector.php +337 -337
  23. classes/Connector/wp-db-custom.php +36 -36
  24. classes/ConstantManager.php +88 -88
  25. classes/EDD_SL_Plugin_Updater.php +170 -170
  26. classes/Helpers/DataHelper.php +22 -22
  27. classes/LicenseManager.php +176 -171
  28. classes/Loggers/Database.php +22 -75
  29. classes/Models/ActiveRecord.php +280 -280
  30. classes/Models/Meta.php +34 -34
  31. classes/Models/Occurrence.php +204 -199
  32. classes/Models/OccurrenceQuery.php +29 -29
  33. classes/Models/Option.php +80 -80
  34. classes/Models/Query.php +187 -187
  35. classes/Nicer.php +289 -289
  36. classes/SensorManager.php +49 -49
  37. classes/Sensors/BBPress.php +455 -412
  38. classes/Sensors/Comments.php +130 -0
  39. classes/Sensors/Content.php +697 -635
  40. classes/Sensors/CustomHooks.php +49 -49
  41. classes/Sensors/Database.php +132 -132
  42. classes/Sensors/Files.php +55 -55
  43. classes/Sensors/LogInOut.php +215 -215
  44. classes/Sensors/Menus.php +454 -416
  45. classes/Sensors/MetaData.php +265 -208
  46. classes/Sensors/Multisite.php +129 -129
  47. classes/Sensors/PhpErrors.php +104 -104
  48. classes/Sensors/PluginsThemes.php +286 -215
  49. classes/Sensors/Request.php +40 -40
  50. classes/Sensors/System.php +265 -168
  51. classes/Sensors/UserProfile.php +166 -164
  52. classes/Sensors/Widgets.php +234 -234
  53. classes/Settings.php +655 -639
  54. classes/SimpleProfiler.php +43 -43
  55. classes/ViewManager.php +245 -215
  56. classes/Views/About.php +85 -85
  57. classes/Views/AuditLog.php +203 -177
  58. classes/Views/EmailNotifications.php +58 -0
  59. classes/Views/Extensions.php +101 -54
  60. classes/Views/Help.php +78 -78
  61. classes/Views/Licensing.php +87 -87
  62. classes/Views/LogInUsers.php +58 -0
  63. classes/Views/Reports.php +58 -0
  64. classes/Views/Search.php +58 -0
  65. classes/Views/Settings.php +698 -682
  66. classes/Views/ToggleAlerts.php +150 -150
  67. classes/WidgetManager.php +79 -79
  68. css/auditlog.css +184 -180
  69. css/extensions.css +94 -0
  70. css/install-error.css +41 -41
  71. css/nice_r.css +92 -92
  72. css/settings.css +70 -70
  73. defaults.php +189 -169
  74. img/all.jpg +0 -0
  75. img/database.jpg +0 -0
  76. img/envelope.jpg +0 -0
  77. img/file.jpg +0 -0
  78. img/monitoring.jpg +0 -0
  79. img/notifications_250x150.gif +0 -0
  80. img/reporting_250x150.gif +0 -0
  81. img/search.jpg +0 -0
  82. img/search_250x150.gif +0 -0
  83. js/auditlog.js +149 -149
  84. js/common.js +21 -17
  85. js/nice_r.js +11 -11
  86. js/settings.js +73 -73
  87. readme.txt +40 -1
  88. uninstall.php +6 -6
  89. wp-security-audit-log.php +10 -9
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/{Models/Adapters → Adapters}/ActiveRecordInterface.php RENAMED
@@ -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 → Adapters}/MetaInterface.php RENAMED
@@ -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 → Adapters}/MySQL/ActiveRecordAdapter.php RENAMED
@@ -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 LIMIT 1), '[', ''), ']', ''), '\\'', '') AS roles,
398
- (SELECT replace(t2.value, '\"','') FROM $tableMeta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id LIMIT 1) AS ip,
399
- (SELECT replace(t3.value, '\"', '') FROM $tableMeta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id LIMIT 1) AS ua,
400
- COALESCE(
401
- (SELECT replace(t4.value, '\"', '') FROM $tableMeta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id LIMIT 1),
402
- (SELECT replace(t5.value, '\"', '') FROM $tableMeta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id LIMIT 1)
403
- ) as user_id
404
- FROM $tableOcc AS occ
405
- JOIN $tableMeta AS meta ON meta.occurrence_id = occ.id
406
- WHERE
407
- (@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
408
- AND (@userId is NULL OR (
409
- (meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
410
- OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
411
- ))
412
- AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
413
- AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
414
- ))
415
- AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
416
- AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
417
- AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
418
- {$conditionDate}
419
- ORDER BY
420
- created_on DESC
421
- ";
422
-
423
- $_wpdb->query("SET @siteId = $_siteId");
424
- $_wpdb->query("SET @userId = $_userId");
425
- $_wpdb->query("SET @roleName = $_roleName");
426
- $_wpdb->query("SET @alertCode = $_alertCode");
427
- $_wpdb->query("SET @startTimestamp = $_startTimestamp");
428
- $_wpdb->query("SET @endTimestamp = $_endTimestamp");
429
-
430
- if (!empty($_limit)) {
431
- $sql .= " LIMIT {$_limit}";
432
- }
433
- $results = $_wpdb->get_results($sql);
434
-
435
- foreach ($results as $row) {
436
- $sql = "SELECT t6.ID FROM $tableUsers AS t6 WHERE t6.user_login = \"$row->user_id\"";
437
- $userId = $wpdb->get_var($sql);
438
- if ($userId == null) {
439
- $sql = "SELECT t4.ID FROM $tableUsers AS t4 WHERE t4.ID = \"$row->user_id\"";
440
- $userId = $wpdb->get_var($sql);
441
- }
442
- $row->user_id = $userId;
443
- $results['lastDate'] = $row->created_on;
444
- }
445
-
446
- return $results;
447
- }
448
- }
1
+ <?php
2
+
3
+ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInterface
4
+ {
5
+ protected $connection;
6
+
7
+ /**
8
+ * Contains the table name
9
+ * @var string
10
+ */
11
+ protected $_table;
12
+
13
+ /**
14
+ * Contains primary key column name, override as required.
15
+ * @var string
16
+ */
17
+ protected $_idkey = '';
18
+
19
+ public function __construct($conn)
20
+ {
21
+ $this->connection = $conn;
22
+ }
23
+
24
+ public function GetModel()
25
+ {
26
+ return new WSAL_Models_ActiveRecord();
27
+ }
28
+
29
+ /**
30
+ * @return string Returns table name.
31
+ */
32
+ public function GetTable()
33
+ {
34
+ $_wpdb = $this->connection;
35
+ return $_wpdb->base_prefix . $this->_table;
36
+ }
37
+
38
+ /**
39
+ * Used for WordPress prefix
40
+ * @return string Returns table name of WordPress.
41
+ */
42
+ public function GetWPTable()
43
+ {
44
+ global $wpdb;
45
+ return $wpdb->base_prefix . $this->_table;
46
+ }
47
+
48
+ /**
49
+ * @return string SQL table options (constraints, foreign keys, indexes etc).
50
+ */
51
+ protected function GetTableOptions()
52
+ {
53
+ return ' PRIMARY KEY (' . $this->_idkey . ')';
54
+ }
55
+
56
+ /**
57
+ * @return array Returns this records' columns.
58
+ */
59
+ public function GetColumns()
60
+ {
61
+ $model = $this->GetModel();
62
+
63
+ if (!isset($this->_column_cache)) {
64
+ $this->_column_cache = array();
65
+ foreach (array_keys(get_object_vars($model)) as $col)
66
+ if (trim($col) && $col[0] != '_')
67
+ $this->_column_cache[] = $col;
68
+ }
69
+ return $this->_column_cache;
70
+ }
71
+
72
+ /**
73
+ * @deprecated
74
+ * @return boolean Returns whether table structure is installed or not.
75
+ */
76
+ public function IsInstalled(){
77
+ //global $wpdb;
78
+ $_wpdb = $this->connection;
79
+ $sql = 'SHOW TABLES LIKE "' . $this->GetTable() . '"';
80
+ return strtolower($_wpdb->get_var($sql)) == strtolower($this->GetTable());
81
+ }
82
+
83
+ /**
84
+ * Install this ActiveRecord structure into DB.
85
+ */
86
+ public function Install(){
87
+ $_wpdb = $this->connection;
88
+ $_wpdb->query($this->_GetInstallQuery());
89
+ }
90
+
91
+ /**
92
+ * Install this ActiveRecord structure into DB WordPress.
93
+ */
94
+ public function InstallOriginal(){
95
+ global $wpdb;
96
+ $wpdb->query($this->_GetInstallQuery(true));
97
+ }
98
+
99
+ /**
100
+ * Remove this ActiveRecord structure into DB.
101
+ */
102
+ public function Uninstall()
103
+ {
104
+ //global $wpdb;
105
+ $_wpdb = $this->connection;
106
+ $_wpdb->query($this->_GetUninstallQuery());
107
+ }
108
+
109
+ /**
110
+ * Save an active record to DB.
111
+ * @return integer|boolean Either the number of modified/inserted rows or false on failure.
112
+ */
113
+ public function Save($activeRecord)
114
+ {
115
+ //global $wpdb;
116
+ $_wpdb = $this->connection;
117
+ $copy = $activeRecord;
118
+ $data = array();
119
+ $format = array();
120
+
121
+ foreach ($this->GetColumns() as $index => $key) {
122
+ if ($key == $this->_idkey) {
123
+ $_idIndex = $index;
124
+ }
125
+
126
+ $val = $copy->$key;
127
+ $deffmt = '%s';
128
+ if (is_int($copy->$key)) {
129
+ $deffmt = '%d';
130
+ }
131
+ if (is_float($copy->$key)) {
132
+ $deffmt = '%f';
133
+ }
134
+ if (is_array($copy->$key) || is_object($copy->$key)) {
135
+ $data[$key] = WSAL_Helpers_DataHelper::JsonEncode($val);
136
+ } else {
137
+ $data[$key] = $val;
138
+ }
139
+ $format[] = $deffmt;
140
+ }
141
+
142
+ if (isset($data[$this->_idkey]) && empty($data[$this->_idkey])) {
143
+ unset($data[$this->_idkey]);
144
+ unset($format[$_idIndex]);
145
+ }
146
+
147
+ $result = $_wpdb->replace($this->GetTable(), $data, $format);
148
+
149
+ if ($result !== false) {
150
+ if ($_wpdb->insert_id) {
151
+ $copy->setId($_wpdb->insert_id);
152
+ }
153
+ }
154
+ return $result;
155
+ }
156
+
157
+ /**
158
+ * Load record from DB.
159
+ * @param string $cond (Optional) Load condition.
160
+ * @param array $args (Optional) Load condition arguments.
161
+ */
162
+ public function Load($cond = '%d', $args = array(1))
163
+ {
164
+ //global $wpdb;
165
+ $_wpdb = $this->connection;
166
+
167
+ $sql = $_wpdb->prepare('SELECT * FROM '.$this->GetTable().' WHERE '. $cond, $args);
168
+ $data = $_wpdb->get_row($sql, ARRAY_A);
169
+
170
+ return $data;
171
+ }
172
+
173
+ public function LoadArray($cond, $args = array())
174
+ {
175
+ //global $wpdb;
176
+ $_wpdb = $this->connection;
177
+ $result = array();
178
+ $sql = $_wpdb->prepare('SELECT * FROM '.$this->GetTable().' WHERE '. $cond, $args);
179
+ foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
180
+ $result[] = $this->getModel()->LoadData($data);
181
+ }
182
+ return $result;
183
+ }
184
+
185
+ /**
186
+ * Delete DB record.
187
+ * @return int|boolean Either the amount of deleted rows or False on error.
188
+ */
189
+ public function Delete($activeRecord)
190
+ {
191
+ //global $wpdb;
192
+ $_wpdb = $this->connection;
193
+ $result = $_wpdb->delete(
194
+ $this->GetTable(),
195
+ $activeRecord->getId()
196
+ );
197
+ return $result;
198
+ }
199
+
200
+ /**
201
+ * Delete records in DB matching a query.
202
+ * @param string $query Full SQL query.
203
+ * @param array $args (Optional) Query arguments.
204
+ */
205
+ public function DeleteQuery($query, $args = array())
206
+ {
207
+ $_wpdb = $this->connection;
208
+ $sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
209
+ $result = $_wpdb->query($sql);
210
+ return $result;
211
+ }
212
+
213
+ /**
214
+ * Load multiple records from DB.
215
+ * @param string $cond (Optional) Load condition (eg: 'some_id = %d' ).
216
+ * @param array $args (Optional) Load condition arguments (rg: array(45) ).
217
+ * @return self[] List of loaded records.
218
+ */
219
+ public function LoadMulti($cond, $args = array())
220
+ {
221
+ //global $wpdb;
222
+ $_wpdb = $this->connection;
223
+ $result = array();
224
+ $sql = (!is_array($args) || !count($args)) // do we really need to prepare() or not?
225
+ ? ($cond)
226
+ : $_wpdb->prepare($cond, $args)
227
+ ;
228
+ foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
229
+ $result[] = $this->getModel()->LoadData($data);
230
+ }
231
+ return $result;
232
+
233
+ }
234
+
235
+ /**
236
+ * Load multiple records from DB and call a callback for each record.
237
+ * This function is very memory-efficient, it doesn't load records in bulk.
238
+ * @param callable $callback The callback to invoke.
239
+ * @param string $cond (Optional) Load condition.
240
+ * @param array $args (Optional) Load condition arguments.
241
+ */
242
+ public function LoadAndCallForEach($callback, $cond = '%d', $args = array(1))
243
+ {
244
+ //global $wpdb;
245
+ $_wpdb = $this->connection;
246
+ $class = get_called_class();
247
+ $sql = $_wpdb->prepare('SELECT * FROM ' . $this->GetTable() . ' WHERE '.$cond, $args);
248
+ foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
249
+ call_user_func($callback, new $class($data));
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Count records in the DB matching a condition.
255
+ * If no parameters are given, this counts the number of records in the DB table.
256
+ * @param string $cond (Optional) Query condition.
257
+ * @param array $args (Optional) Condition arguments.
258
+ * @return int Number of matching records.
259
+ */
260
+ public function Count($cond = '%d', $args = array(1))
261
+ {
262
+ //global $wpdb;
263
+ $_wpdb = $this->connection;
264
+ $class = get_called_class();
265
+ $sql = $_wpdb->prepare('SELECT COUNT(*) FROM ' . $this->GetTable() . ' WHERE ' . $cond, $args);
266
+ return (int)$_wpdb->get_var($sql);
267
+ }
268
+
269
+ /**
270
+ * Count records in the DB matching a query.
271
+ * @param string $query Full SQL query.
272
+ * @param array $args (Optional) Query arguments.
273
+ * @return int Number of matching records.
274
+ */
275
+ public function CountQuery($query, $args = array())
276
+ {
277
+ //global $wpdb;
278
+ $_wpdb = $this->connection;
279
+ $sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
280
+ return (int)$_wpdb->get_var($sql);
281
+ }
282
+
283
+ /**
284
+ * Similar to LoadMulti but allows the use of a full SQL query.
285
+ * @param string $query Full SQL query.
286
+ * @param array $args (Optional) Query arguments.
287
+ * @return self[] List of loaded records.
288
+ */
289
+ public function LoadMultiQuery($query, $args = array())
290
+ {
291
+ //global $wpdb;
292
+ $_wpdb = $this->connection;
293
+ $class = get_called_class();
294
+ $result = array();
295
+ $sql = count($args) ? $_wpdb->prepare($query, $args) : $query;
296
+ foreach ($_wpdb->get_results($sql, ARRAY_A) as $data) {
297
+ $result[] = $this->getModel()->LoadData($data);
298
+ }
299
+ return $result;
300
+ }
301
+
302
+ /**
303
+ * @return string Must return SQL for creating table.
304
+ */
305
+ protected function _GetInstallQuery($prefix = false)
306
+ {
307
+ $_wpdb = $this->connection;
308
+
309
+ $class = get_class($this);
310
+ $copy = new $class($this->connection);
311
+ $table_name = ($prefix) ? $this->GetWPTable() : $this->GetTable();
312
+ $sql = 'CREATE TABLE IF NOT EXISTS ' . $table_name . ' (' . PHP_EOL;
313
+
314
+ foreach ($this->GetColumns() as $key) {
315
+ $sql .= ' ';
316
+ switch (true) {
317
+ case $key == $copy->_idkey:
318
+ $sql .= $key . ' BIGINT NOT NULL AUTO_INCREMENT,' . PHP_EOL;
319
+ break;
320
+ case is_integer($copy->$key):
321
+ $sql .= $key . ' BIGINT NOT NULL,' . PHP_EOL;
322
+ break;
323
+ case is_float($copy->$key):
324
+ $sql .= $key . ' DOUBLE NOT NULL,' . PHP_EOL;
325
+ break;
326
+ case is_string($copy->$key):
327
+ $maxlength = $key . '_maxlength';
328
+ if (property_exists($class, $maxlength)) {
329
+ $sql .= $key . ' VARCHAR(' . intval($class::$$maxlength) . ') NOT NULL,' . PHP_EOL;
330
+ } else {
331
+ $sql .= $key . ' TEXT NOT NULL,' . PHP_EOL;
332
+ }
333
+ break;
334
+ case is_bool($copy->$key):
335
+ $sql .= $key . ' BIT NOT NULL,' . PHP_EOL;
336
+ break;
337
+ case is_array($copy->$key):
338
+ case is_object($copy->$key):
339
+ $sql .= $key . ' LONGTEXT NOT NULL,' . PHP_EOL;
340
+ break;
341
+ }
342
+ }
343
+
344
+ $sql .= $this->GetTableOptions() . PHP_EOL;
345
+
346
+ $sql .= ')';
347
+
348
+ if (! empty($_wpdb->charset)) {
349
+ $sql .= ' DEFAULT CHARACTER SET ' . $_wpdb->charset;
350
+ }
351
+
352
+ return $sql;
353
+
354
+ }
355
+
356
+ /**
357
+ * @return string Must return SQL for removing table (at a minimum, it should be ` 'DROP TABLE ' . $this->_table `).
358
+ */
359
+ protected function _GetUninstallQuery()
360
+ {
361
+ return 'DROP TABLE ' . $this->GetTable();
362
+ }
363
+
364
+ /**
365
+ * Function used in WSAL reporting extension
366
+ */
367
+ public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp, $_nextDate = null, $_limit = 0)
368
+ {
369
+ global $wpdb;
370
+ $tableUsers = $wpdb->users;
371
+ $_wpdb = $this->connection;
372
+ // tables
373
+ $meta = new WSAL_Adapters_MySQL_Meta($this->connection);
374
+ $tableMeta = $meta->GetTable(); // metadata
375
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($this->connection);
376
+ $tableOcc = $occurrence->GetTable(); // occurrences
377
+
378
+ $user_names = '0';
379
+ if (!empty($_userId) && $_userId != "null") {
380
+ $sql = 'SELECT user_login FROM '.$tableUsers.' WHERE find_in_set(ID, @userId) > 0';
381
+ $wpdb->query("SET @userId = $_userId");
382
+ $result = $wpdb->get_results($sql, ARRAY_A);
383
+ $aUsers = array();
384
+ foreach ($result as $item) {
385
+ $aUsers[] = '"'.$item['user_login'].'"';
386
+ }
387
+ $user_names = implode(', ', $aUsers);
388
+ }
389
+ $conditionDate = !empty($_nextDate) ? ' AND occ.created_on < '.$_nextDate : '';
390
+
391
+ $sql = "SELECT DISTINCT
392
+ occ.id,
393
+ occ.alert_id,
394
+ occ.site_id,
395
+ occ.created_on,
396
+ replace(replace(replace((
397
+ SELECT t1.value FROM $tableMeta AS t1 WHERE t1.name = 'CurrentUserRoles' AND t1.occurrence_id = occ.id LIMIT 1), '[', ''), ']', ''), '\\'', '') AS roles,
398
+ (SELECT replace(t2.value, '\"','') FROM $tableMeta as t2 WHERE t2.name = 'ClientIP' AND t2.occurrence_id = occ.id LIMIT 1) AS ip,
399
+ (SELECT replace(t3.value, '\"', '') FROM $tableMeta as t3 WHERE t3.name = 'UserAgent' AND t3.occurrence_id = occ.id LIMIT 1) AS ua,
400
+ COALESCE(
401
+ (SELECT replace(t4.value, '\"', '') FROM $tableMeta as t4 WHERE t4.name = 'Username' AND t4.occurrence_id = occ.id LIMIT 1),
402
+ (SELECT replace(t5.value, '\"', '') FROM $tableMeta as t5 WHERE t5.name = 'CurrentUserID' AND t5.occurrence_id = occ.id LIMIT 1)
403
+ ) as user_id
404
+ FROM $tableOcc AS occ
405
+ JOIN $tableMeta AS meta ON meta.occurrence_id = occ.id
406
+ WHERE
407
+ (@siteId is NULL OR find_in_set(occ.site_id, @siteId) > 0)
408
+ AND (@userId is NULL OR (
409
+ (meta.name = 'CurrentUserID' AND find_in_set(meta.value, @userId) > 0)
410
+ OR (meta.name = 'Username' AND replace(meta.value, '\"', '') IN ($user_names))
411
+ ))
412
+ AND (@roleName is NULL OR (meta.name = 'CurrentUserRoles'
413
+ AND replace(replace(replace(meta.value, ']', ''), '[', ''), '\\'', '') REGEXP @roleName
414
+ ))
415
+ AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
416
+ AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
417
+ AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
418
+ {$conditionDate}
419
+ ORDER BY
420
+ created_on DESC
421
+ ";
422
+
423
+ $_wpdb->query("SET @siteId = $_siteId");
424
+ $_wpdb->query("SET @userId = $_userId");
425
+ $_wpdb->query("SET @roleName = $_roleName");
426
+ $_wpdb->query("SET @alertCode = $_alertCode");
427
+ $_wpdb->query("SET @startTimestamp = $_startTimestamp");
428
+ $_wpdb->query("SET @endTimestamp = $_endTimestamp");
429
+
430
+ if (!empty($_limit)) {
431
+ $sql .= " LIMIT {$_limit}";
432
+ }
433
+ $results = $_wpdb->get_results($sql);
434
+
435
+ foreach ($results as $row) {
436
+ $sql = "SELECT t6.ID FROM $tableUsers AS t6 WHERE t6.user_login = \"$row->user_id\"";
437
+ $userId = $wpdb->get_var($sql);
438
+ if ($userId == null) {
439
+ $sql = "SELECT t4.ID FROM $tableUsers AS t4 WHERE t4.ID = \"$row->user_id\"";
440
+ $userId = $wpdb->get_var($sql);
441
+ }
442
+ $row->user_id = $userId;
443
+ $results['lastDate'] = $row->created_on;
444
+ }
445
+
446
+ return $results;
447
+ }
448
+ }
classes/{Models/Adapters → Adapters}/MySQL/MetaAdapter.php RENAMED
@@ -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 → Adapters}/MySQL/OccurrenceAdapter.php RENAMED
@@ -1,187 +1,211 @@
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
+ /**
188
+ * Gets occurences of the same type by IP within specified time frame
189
+ * @param string $ipAddress
190
+ * @param string $username
191
+ * @param int $alertId Alert type we are lookign for
192
+ * @param int $siteId
193
+ * @param $startTime mktime
194
+ * @param $endTime mktime
195
+ */
196
+ public function CheckAlert404($args = array())
197
+ {
198
+ $tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
199
+ return self::LoadMultiQuery(
200
+ 'SELECT occurrence.* FROM `' . $this->GetTable() . '` occurrence
201
+ INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id
202
+ and ipMeta.name = "ClientIP" and ipMeta.value = %s
203
+ INNER JOIN `' . $tt2->GetTable() . '` usernameMeta on usernameMeta.occurrence_id = occurrence.id
204
+ and usernameMeta.name = "Username" and usernameMeta.value = %s
205
+ WHERE occurrence.alert_id = %d AND occurrence.site_id = %d
206
+ AND (created_on BETWEEN %d AND %d)
207
+ GROUP BY occurrence.id',
208
+ $args
209
+ );
210
+ }
211
+ }
classes/{Models/Adapters → Adapters}/MySQL/OptionAdapter.php RENAMED
@@ -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 → Adapters}/MySQL/QueryAdapter.php RENAMED
@@ -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 → Adapters}/OccurrenceInterface.php RENAMED
@@ -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 → Adapters}/QueryInterface.php RENAMED
@@ -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/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,391 @@
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
+ // Check if the user management plugin is loaded and adds the SessionID
287
+ if (class_exists('WSAL_User_Management_Plugin')) {
288
+ if (function_exists('get_current_user_id')) {
289
+ $session_tokens = get_user_meta(get_current_user_id(), 'session_tokens', true);
290
+ if (!empty($session_tokens)) {
291
+ end($session_tokens);
292
+ $data['SessionID'] = key($session_tokens);
293
+ }
294
+ }
295
+ }
296
+ //if(isset($_SERVER['REMOTE_HOST']) && $_SERVER['REMOTE_HOST'] != $data['ClientIP'])
297
+ // $data['ClientHost'] = $_SERVER['REMOTE_HOST'];
298
+ //$data['OtherIPs'] = $_SERVER['REMOTE_HOST'];
299
+
300
+ foreach ($this->_loggers as $logger) {
301
+ $logger->Log($type, $data);
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Return alert given alert type.
307
+ * @param integer $type Alert type.
308
+ * @param mixed $default Returned if alert is not found.
309
+ * @return WSAL_Alert
310
+ */
311
+ public function GetAlert($type, $default = null){
312
+ foreach($this->_alerts as $alert)
313
+ if($alert->type == $type)
314
+ return $alert;
315
+ return $default;
316
+ }
317
+
318
+ /**
319
+ * Returns all supported alerts.
320
+ * @return WSAL_Alert[]
321
+ */
322
+ public function GetAlerts(){
323
+ return $this->_alerts;
324
+ }
325
+
326
+ /**
327
+ * Returns all supported alerts.
328
+ * @return array
329
+ */
330
+ public function GetCategorizedAlerts(){
331
+ $result = array();
332
+ foreach($this->_alerts as $alert){
333
+ if(!isset($result[$alert->catg]))
334
+ $result[$alert->catg] = array();
335
+ $result[$alert->catg][] = $alert;
336
+ }
337
+ ksort($result);
338
+ return $result;
339
+ }
340
+
341
+ /**
342
+ * Returns whether user is enabled or not.
343
+ * @param string user.
344
+ * @return boolean True if disabled, false otherwise.
345
+ */
346
+ public function IsDisabledUser($user)
347
+ {
348
+ return (in_array($user, $this->GetDisabledUsers())) ? true : false;
349
+ }
350
+
351
+ /**
352
+ * @return Returns an array of disabled users.
353
+ */
354
+ public function GetDisabledUsers()
355
+ {
356
+ return $this->plugin->settings->GetExcludedMonitoringUsers();
357
+ }
358
+
359
+ /**
360
+ * Returns whether user is enabled or not.
361
+ * @param array roles.
362
+ * @return boolean True if disabled, false otherwise.
363
+ */
364
+ public function IsDisabledRole($roles)
365
+ {
366
+ $is_disabled = false;
367
+ foreach ($roles as $role) {
368
+ if(in_array($role, $this->GetDisabledRoles())) $is_disabled = true;
369
+ }
370
+ return $is_disabled;
371
+ }
372
+
373
+ /**
374
+ * @return Returns an array of disabled users.
375
+ */
376
+ public function GetDisabledRoles()
377
+ {
378
+ return $this->plugin->settings->GetExcludedMonitoringRoles();
379
+ }
380
+
381
+ private function IsDisabledIP()
382
+ {
383
+ $is_disabled = false;
384
+ $ip = $this->plugin->settings->GetMainClientIP();
385
+ $excluded_ips = $this->plugin->settings->GetExcludedMonitoringIP();
386
+ if (in_array($ip, $excluded_ips)) {
387
+ $is_disabled = true;
388
+ }
389
+ return $is_disabled;
390
+ }
391
+ }
classes/AuditLogListView.php CHANGED
@@ -1,452 +1,473 @@
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 $name == '%ClientIP%':
316
- if (is_string($value)) {
317
- return '<strong>' . str_replace(array("\"", "[", "]"), "", $value) . '</strong>';
318
- } else {
319
- return '<i>unknown</i>';
320
- }
321
-
322
- case strncmp($value, 'http://', 7) === 0:
323
- case strncmp($value, 'https://', 7) === 0:
324
- return '<a href="' . esc_html($value) . '"'
325
- . ' title="' . esc_html($value) . '"'
326
- . ' target="_blank">'
327
- . esc_html(parse_url($value, PHP_URL_HOST)) . '/&hellip;/'
328
- . esc_html(basename(parse_url($value, PHP_URL_PATH)))
329
- . '</a>';
330
-
331
- default:
332
- return '<strong>' . esc_html($value) . '</strong>';
333
- }
334
- }
335
-
336
- protected function is_multisite()
337
- {
338
- return $this->_plugin->IsMultisite();
339
- }
340
-
341
- protected function is_main_blog()
342
- {
343
- return get_current_blog_id() == 1;
344
- }
345
-
346
- protected function is_specific_view()
347
- {
348
- return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
349
- }
350
-
351
- protected function get_specific_view()
352
- {
353
- return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
354
- }
355
-
356
- protected function get_view_site_id()
357
- {
358
- switch (true) {
359
- // non-multisite
360
- case !$this->is_multisite():
361
- return 0;
362
- // multisite + main site view
363
- case $this->is_main_blog() && !$this->is_specific_view():
364
- return 0;
365
- // multisite + switched site view
366
- case $this->is_main_blog() && $this->is_specific_view():
367
- return $this->get_specific_view();
368
- // multisite + local site view
369
- default:
370
- return get_current_blog_id();
371
- }
372
- }
373
-
374
- public function prepare_items()
375
- {
376
- $per_page = $this->_plugin->settings->GetViewPerPage();
377
-
378
- $columns = $this->get_columns();
379
- $hidden = array();
380
- $sortable = $this->get_sortable_columns();
381
-
382
- $this->_column_headers = array($columns, $hidden, $sortable);
383
-
384
- //$this->process_bulk_action();
385
- //TO DO: Get rid of OccurrenceQuery and use the Occurence Model
386
- $query = new WSAL_Models_OccurrenceQuery();
387
-
388
- $bid = (int)$this->get_view_site_id();
389
- if ($bid) {
390
- $query->addCondition("site_id = %s ", $bid);
391
- }
392
-
393
- $query = apply_filters('wsal_auditlog_query', $query);
394
-
395
- $total_items = $query->getAdapter()->Count($query);
396
-
397
- if (empty($_REQUEST["orderby"])) {
398
- $query->addOrderBy("created_on", true);
399
- } else {
400
- $orderByField = $_REQUEST["orderby"];
401
-
402
- $isDescending = true;
403
- if (!empty($_REQUEST['order']) && $_REQUEST["order"] == "asc") {
404
- $isDescending = false;
405
- }
406
-
407
- //TO DO: Allow order by meta values
408
- if ($orderByField == "scip") {
409
- $query->addMetaJoin();
410
- $query->addOrderBy('CASE WHEN meta.name = "ClientIP" THEN meta.value END', $isDescending);
411
- } else if ($orderByField == "user") {
412
- $query->addMetaJoin();
413
- $query->addOrderBy('CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $isDescending);
414
- } else {
415
- $tmp = new WSAL_Models_Occurrence();
416
- //Making sure the field exists to order by
417
- if (isset($tmp->{$orderByField})) {
418
- // TODO we used to use a custom comparator ... is it safe to let MySQL do the ordering now?
419
- $query->addOrderBy($_REQUEST["orderby"], $isDescending);
420
-
421
- } else {
422
- $query->addOrderBy("created_on", true);
423
- }
424
- }
425
- }
426
-
427
- /** @todo Modify $query instead */
428
- /** @deprecated */
429
- //$data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
430
- $query->setOffset(($this->get_pagenum() - 1) * $per_page);
431
- $query->setLimit($per_page);
432
-
433
- $this->items = $query->getAdapter()->Execute($query);
434
-
435
- $this->set_pagination_args(array(
436
- 'total_items' => $total_items,
437
- 'per_page' => $per_page,
438
- 'total_pages' => ceil($total_items / $per_page)
439
- ));
440
- }
441
-
442
- public function single_row($item)
443
- {
444
- if ($item->alert_id == 9999) {
445
- echo '<tr style="background-color: #D5E46E">';
446
- $this->single_row_columns($item);
447
- echo '</tr>';
448
- } else {
449
- parent::single_row($item);
450
- }
451
- }
452
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ } elseif ($username == 'Plugins') {
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>' . __('Plugins', 'wp-security-audit-log') . '</i>';
236
+ $roles = '';
237
+ } elseif ($username == 'Website Visitor') {
238
+ $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
239
+ $uhtml = '<i>' . __('Website Visitor', 'wp-security-audit-log') . '</i>';
240
+ $roles = '';
241
+ } else {
242
+ $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
243
+ $uhtml = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
244
+ $roles = '';
245
+ }
246
+ return $image . $uhtml . '<br/>' . $roles;
247
+ case 'scip':
248
+ $scip = $item->GetSourceIP();
249
+ if (is_string($scip)) {
250
+ $scip = str_replace(array("\"", "[", "]"), "", $scip);
251
+ }
252
+ $oips = array(); //$item->GetOtherIPs();
253
+ // if there's no IP...
254
+ if (is_null($scip) || $scip == '') return '<i>unknown</i>';
255
+ // if there's only one IP...
256
+ $link = "http://whatismyipaddress.com/ip/" . $scip ."?utm_source=plugin&utm_medium=referral&utm_campaign=WPSAL";
257
+ if (count($oips) < 2) return "<a target='_blank' href='$link'>". esc_html($scip) .'</a>';
258
+ // if there are many IPs...
259
+ $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;">';
260
+ foreach ($oips as $ip) if($scip != $ip) $html .= '<div>' . $ip . '</div>';
261
+ $html .= '</div>';
262
+ return $html;
263
+ case 'site':
264
+ $info = get_blog_details($item->site_id, true);
265
+ return !$info ? ('Unknown Site '.$item->site_id)
266
+ : ('<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>');
267
+ case 'mesg':
268
+ return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>';
269
+ case 'data':
270
+ $url = admin_url('admin-ajax.php') . '?action=AjaxInspector&amp;occurrence=' . $item->id;
271
+ return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"'
272
+ . ' href="' . $url . '&amp;TB_iframe=true&amp;width=600&amp;height=550">&hellip;</a>';
273
+ default:
274
+ return isset($item->$column_name)
275
+ ? esc_html($item->$column_name)
276
+ : 'Column "' . esc_html($column_name) . '" not found';
277
+ }
278
+ }
279
+
280
+ public function reorder_items_str($a, $b)
281
+ {
282
+ $result = strcmp($a->{$this->_orderby}, $b->{$this->_orderby});
283
+ return ($this->_order === 'asc') ? $result : -$result;
284
+ }
285
+
286
+ public function reorder_items_int($a, $b)
287
+ {
288
+ $result = $a->{$this->_orderby} - $b->{$this->_orderby};
289
+ return ($this->_order === 'asc') ? $result : -$result;
290
+ }
291
+
292
+ public function meta_formatter($name, $value)
293
+ {
294
+ switch (true) {
295
+ case $name == '%Message%':
296
+ return esc_html($value);
297
+
298
+ case $name == '%PromoMessage%':
299
+ return '<p class="promo-alert">' . $value .'</p>';
300
+
301
+ case $name == '%PromoLink%':
302
+ case $name == '%CommentLink%':
303
+ case $name == '%CommentMsg%':
304
+ return $value;
305
+
306
+ case $name == '%MetaLink%':
307
+ if (!empty($value)) {
308
+ return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
309
+ } else {
310
+ return "";
311
+ }
312
+
313
+ case $name == '%RevisionLink%':
314
+ return ' Click <a target="_blank" href="'.esc_url($value).'">here</a> to see the content changes.';
315
+
316
+ case $name == '%EditorLinkPost%':
317
+ return ' <a target="_blank" href="'.esc_url($value).'">View the post</a>';
318
+
319
+ case $name == '%EditorLinkPage%':
320
+ return ' <a target="_blank" href="'.esc_url($value).'">View the page</a>';
321
+
322
+ case $name == '%CategoryLink%':
323
+ return ' <a target="_blank" href="'.esc_url($value).'">View the category</a>';
324
+
325
+ case $name == '%EditorLinkForum%':
326
+ return ' <a target="_blank" href="'.esc_url($value).'">View the forum</a>';
327
+
328
+ case $name == '%EditorLinkTopic%':
329
+ return ' <a target="_blank" href="'.esc_url($value).'">View the topic</a>';
330
+
331
+ case in_array($name, array('%MetaValue%', '%MetaValueOld%', '%MetaValueNew%')):
332
+ return '<strong>' . (
333
+ strlen($value) > 50 ? (esc_html(substr($value, 0, 50)) . '&hellip;') : esc_html($value)
334
+ ) . '</strong>';
335
+
336
+ case $name == '%ClientIP%':
337
+ if (is_string($value)) {
338
+ return '<strong>' . str_replace(array("\"", "[", "]"), "", $value) . '</strong>';
339
+ } else {
340
+ return '<i>unknown</i>';
341
+ }
342
+
343
+ case strncmp($value, 'http://', 7) === 0:
344
+ case strncmp($value, 'https://', 7) === 0:
345
+ return '<a href="' . esc_html($value) . '"'
346
+ . ' title="' . esc_html($value) . '"'
347
+ . ' target="_blank">'
348
+ . esc_html(parse_url($value, PHP_URL_HOST)) . '/&hellip;/'
349
+ . esc_html(basename(parse_url($value, PHP_URL_PATH)))
350
+ . '</a>';
351
+
352
+ default:
353
+ return '<strong>' . esc_html($value) . '</strong>';
354
+ }
355
+ }
356
+
357
+ protected function is_multisite()
358
+ {
359
+ return $this->_plugin->IsMultisite();
360
+ }
361
+
362
+ protected function is_main_blog()
363
+ {
364
+ return get_current_blog_id() == 1;
365
+ }
366
+
367
+ protected function is_specific_view()
368
+ {
369
+ return isset($_REQUEST['wsal-cbid']) && $_REQUEST['wsal-cbid'] != '0';
370
+ }
371
+
372
+ protected function get_specific_view()
373
+ {
374
+ return isset($_REQUEST['wsal-cbid']) ? (int)$_REQUEST['wsal-cbid'] : 0;
375
+ }
376
+
377
+ protected function get_view_site_id()
378
+ {
379
+ switch (true) {
380
+ // non-multisite
381
+ case !$this->is_multisite():
382
+ return 0;
383
+ // multisite + main site view
384
+ case $this->is_main_blog() && !$this->is_specific_view():
385
+ return 0;
386
+ // multisite + switched site view
387
+ case $this->is_main_blog() && $this->is_specific_view():
388
+ return $this->get_specific_view();
389
+ // multisite + local site view
390
+ default:
391
+ return get_current_blog_id();
392
+ }
393
+ }
394
+
395
+ public function prepare_items()
396
+ {
397
+ $per_page = $this->_plugin->settings->GetViewPerPage();
398
+
399
+ $columns = $this->get_columns();
400
+ $hidden = array();
401
+ $sortable = $this->get_sortable_columns();
402
+
403
+ $this->_column_headers = array($columns, $hidden, $sortable);
404
+
405
+ //$this->process_bulk_action();
406
+ //TO DO: Get rid of OccurrenceQuery and use the Occurence Model
407
+ $query = new WSAL_Models_OccurrenceQuery();
408
+
409
+ $bid = (int)$this->get_view_site_id();
410
+ if ($bid) {
411
+ $query->addCondition("site_id = %s ", $bid);
412
+ }
413
+
414
+ $query = apply_filters('wsal_auditlog_query', $query);
415
+
416
+ $total_items = $query->getAdapter()->Count($query);
417
+
418
+ if (empty($_REQUEST["orderby"])) {
419
+ $query->addOrderBy("created_on", true);
420
+ } else {
421
+ $orderByField = $_REQUEST["orderby"];
422
+
423
+ $isDescending = true;
424
+ if (!empty($_REQUEST['order']) && $_REQUEST["order"] == "asc") {
425
+ $isDescending = false;
426
+ }
427
+
428
+ //TO DO: Allow order by meta values
429
+ if ($orderByField == "scip") {
430
+ $query->addMetaJoin();
431
+ $query->addOrderBy('CASE WHEN meta.name = "ClientIP" THEN meta.value END', $isDescending);
432
+ } else if ($orderByField == "user") {
433
+ $query->addMetaJoin();
434
+ $query->addOrderBy('CASE WHEN meta.name = "CurrentUserID" THEN meta.value END', $isDescending);
435
+ } else {
436
+ $tmp = new WSAL_Models_Occurrence();
437
+ //Making sure the field exists to order by
438
+ if (isset($tmp->{$orderByField})) {
439
+ // TODO we used to use a custom comparator ... is it safe to let MySQL do the ordering now?
440
+ $query->addOrderBy($_REQUEST["orderby"], $isDescending);
441
+
442
+ } else {
443
+ $query->addOrderBy("created_on", true);
444
+ }
445
+ }
446
+ }
447
+
448
+ /** @todo Modify $query instead */
449
+ /** @deprecated */
450
+ //$data = array_slice($data, ($this->get_pagenum() - 1) * $per_page, $per_page);
451
+ $query->setOffset(($this->get_pagenum() - 1) * $per_page);
452
+ $query->setLimit($per_page);
453
+
454
+ $this->items = $query->getAdapter()->Execute($query);
455
+
456
+ $this->set_pagination_args(array(
457
+ 'total_items' => $total_items,
458
+ 'per_page' => $per_page,
459
+ 'total_pages' => ceil($total_items / $per_page)
460
+ ));
461
+ }
462
+
463
+ public function single_row($item)
464
+ {
465
+ if ($item->alert_id == 9999) {
466
+ echo '<tr style="background-color: #D5E46E">';
467
+ $this->single_row_columns($item);
468
+ echo '</tr>';
469
+ } else {
470
+ parent::single_row($item);
471
+ }
472
+ }
473
+ }
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,37 @@
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
+ require_once('wp-db-custom.php');
4
+
5
+ abstract class WSAL_Connector_AbstractConnector
6
+ {
7
+ protected $connection = null;
8
+ protected $adaptersBasePath = null;
9
+ protected $adaptersDirName = null;
10
+
11
+ public function __construct($adaptersDirName = null)
12
+ {
13
+ $this->adaptersBasePath = __DIR__ . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'Adapters'. DIRECTORY_SEPARATOR;
14
+
15
+ //require_once($this->adaptersBasePath . 'ActiveRecordInterface.php');
16
+ //require_once($this->adaptersBasePath . 'MetaInterface.php');
17
+ //require_once($this->adaptersBasePath . 'OccurrenceInterface.php');
18
+ //require_once($this->adaptersBasePath . 'QueryInterface.php');
19
+
20
+ if (!empty($adaptersDirName)) {
21
+ $this->adaptersDirName = $adaptersDirName;
22
+ require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'ActiveRecordAdapter.php');
23
+ require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'MetaAdapter.php');
24
+ require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'OccurrenceAdapter.php');
25
+ require_once($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . 'QueryAdapter.php');
26
+ }
27
+ }
28
+
29
+ public function getAdaptersDirectory()
30
+ {
31
+ if (!empty($this->adaptersBasePath) && !empty($this->adaptersDirName)) {
32
+ return $this->adaptersBasePath . $this->adaptersDirName;
33
+ } else {
34
+ return false;
35
+ }
36
+ }
37
+ }
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/MySQLDB.php ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface
4
+ {
5
+ protected $connectionConfig = null;
6
+
7
+ public function __construct($connectionConfig = null)
8
+ {
9
+ $this->connectionConfig = $connectionConfig;
10
+ parent::__construct("MySQL");
11
+ require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
12
+ }
13
+
14
+ public function TestConnection()
15
+ {
16
+ error_reporting(E_ALL ^ E_WARNING);
17
+ $connectionConfig = $this->connectionConfig;
18
+ $password = $this->decryptString($connectionConfig['password']);
19
+ $newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
20
+ if (!$newWpdb->has_connected) { // Database Error
21
+ throw new Exception("Connection failed. Please check your connection details.");
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Creates a connection and returns it
27
+ * @return Instance of WPDB
28
+ */
29
+ private function createConnection()
30
+ {
31
+ if (!empty($this->connectionConfig)) {
32
+ //TO DO: Use the provided connection config
33
+ $connectionConfig = $this->connectionConfig;
34
+ $password = $this->decryptString($connectionConfig['password']);
35
+ $newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
36
+ $newWpdb->set_prefix($connectionConfig['base_prefix']);
37
+ return $newWpdb;
38
+ } else {
39
+ global $wpdb;
40
+ return $wpdb;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Returns a wpdb instance
46
+ */
47
+ public function getConnection()
48
+ {
49
+ if (!empty($this->connection)) {
50
+ return $this->connection;
51
+ } else {
52
+ $this->connection = $this->createConnection();
53
+ return $this->connection;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Gets an adapter for the specified model
59
+ */
60
+ public function getAdapter($class_name)
61
+ {
62
+ $objName = $this->getAdapterClassName($class_name);
63
+ return new $objName($this->getConnection());
64
+ }
65
+
66
+ protected function getAdapterClassName($class_name)
67
+ {
68
+ return 'WSAL_Adapters_MySQL_'.$class_name;
69
+ }
70
+
71
+ /**
72
+ * Checks if the necessary tables are available
73
+ */
74
+ public function isInstalled()
75
+ {
76
+ global $wpdb;
77
+ $table = $wpdb->base_prefix . 'wsal_occurrences';
78
+ return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
79
+ }
80
+
81
+ /**
82
+ * Checks if old version tables are available
83
+ */
84
+ public function canMigrate()
85
+ {
86
+ $wpdb = $this->getConnection();
87
+ $table = $wpdb->base_prefix . 'wordpress_auditlog_events';
88
+ return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
89
+ }
90
+
91
+ /**
92
+ * Install all DB tables.
93
+ */
94
+ public function installAll($excludeOptions = false)
95
+ {
96
+ $plugin = WpSecurityAuditLog::GetInstance();
97
+
98
+ foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
99
+ $filePath = explode(DIRECTORY_SEPARATOR, $file);
100
+ $fileName = $filePath[count($filePath) - 1];
101
+ $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
102
+
103
+ $class = new $className($this->getConnection());
104
+ if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
105
+ continue;
106
+ }
107
+
108
+ if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
109
+ $class->Install();
110
+ }
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Uninstall all DB tables.
116
+ */
117
+ public function uninstallAll()
118
+ {
119
+ $plugin = WpSecurityAuditLog::GetInstance();
120
+
121
+ foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
122
+ $filePath = explode(DIRECTORY_SEPARATOR, $file);
123
+ $fileName = $filePath[count($filePath) - 1];
124
+ $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
125
+
126
+ $class = new $className($this->getConnection());
127
+ if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
128
+ $class->Uninstall();
129
+ }
130
+ }
131
+ }
132
+
133
+ private function GetIncreaseOccurrence()
134
+ {
135
+ $_wpdb = $this->getConnection();
136
+ $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
137
+ $sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
138
+ return (int)$_wpdb->get_var($sql);
139
+ }
140
+
141
+ public function MigrateMeta($index, $limit)
142
+ {
143
+ $result = null;
144
+ $offset = ($index * $limit);
145
+ global $wpdb;
146
+ $_wpdb = $this->getConnection();
147
+ // Add +1 because an alert is generated after delete the metadata table
148
+ $increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
149
+
150
+ // Load data Meta from WP
151
+ $meta = new WSAL_Adapters_MySQL_Meta($wpdb);
152
+ if (!$meta->IsInstalled()) {
153
+ $result['empty'] = true;
154
+ return $result;
155
+ }
156
+ $sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
157
+ $metadata = $wpdb->get_results($sql, ARRAY_A);
158
+
159
+ // Insert data to External DB
160
+ if (!empty($metadata)) {
161
+ $metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
162
+
163
+ $index++;
164
+ $sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
165
+ foreach ($metadata as $entry) {
166
+ $occurrence_id = intval($entry['occurrence_id']) + $increase_occurrence_id;
167
+ $sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
168
+ }
169
+ $sql = rtrim($sql, ", ");
170
+ $_wpdb->query($sql);
171
+
172
+ $result['complete'] = false;
173
+ } else {
174
+ $result['complete'] = true;
175
+ $this->DeleteAfterMigrate($meta);
176
+ }
177
+ $result['index'] = $index;
178
+ return $result;
179
+ }
180
+
181
+ public function MigrateOccurrence($index, $limit)
182
+ {
183
+ $result = null;
184
+ $offset = ($index * $limit);
185
+ global $wpdb;
186
+ $_wpdb = $this->getConnection();
187
+
188
+ // Load data Occurrences from WP
189
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
190
+ if (!$occurrence->IsInstalled()) {
191
+ $result['empty'] = true;
192
+ return $result;
193
+ }
194
+ $sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
195
+ $occurrences = $wpdb->get_results($sql, ARRAY_A);
196
+
197
+ // Insert data to External DB
198
+ if (!empty($occurrences)) {
199
+ $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
200
+
201
+ $index++;
202
+ $sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
203
+ foreach ($occurrences as $entry) {
204
+ $sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
205
+ }
206
+ $sql = rtrim($sql, ", ");
207
+ $_wpdb->query($sql);
208
+
209
+ $result['complete'] = false;
210
+ } else {
211
+ $result['complete'] = true;
212
+ $this->DeleteAfterMigrate($occurrence);
213
+ }
214
+ $result['index'] = $index;
215
+ return $result;
216
+ }
217
+
218
+ public function MigrateBackOccurrence($index, $limit)
219
+ {
220
+ $result = null;
221
+ $offset = ($index * $limit);
222
+ global $wpdb;
223
+ $_wpdb = $this->getConnection();
224
+
225
+ // Load data Occurrences from External DB
226
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
227
+ if (!$occurrence->IsInstalled()) {
228
+ $result['empty'] = true;
229
+ return $result;
230
+ }
231
+ $sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
232
+ $occurrences = $_wpdb->get_results($sql, ARRAY_A);
233
+
234
+ // Insert data to WP
235
+ if (!empty($occurrences)) {
236
+ $occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
237
+
238
+ $index++;
239
+ $sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
240
+ foreach ($occurrences as $entry) {
241
+ $sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
242
+ }
243
+ $sql = rtrim($sql, ", ");
244
+ $wpdb->query($sql);
245
+
246
+ $result['complete'] = false;
247
+ } else {
248
+ $result['complete'] = true;
249
+ }
250
+ $result['index'] = $index;
251
+ return $result;
252
+ }
253
+
254
+ public function MigrateBackMeta($index, $limit)
255
+ {
256
+ $result = null;
257
+ $offset = ($index * $limit);
258
+ global $wpdb;
259
+ $_wpdb = $this->getConnection();
260
+
261
+ // Load data Meta from External DB
262
+ $meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
263
+ if (!$meta->IsInstalled()) {
264
+ $result['empty'] = true;
265
+ return $result;
266
+ }
267
+ $sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
268
+ $metadata = $_wpdb->get_results($sql, ARRAY_A);
269
+
270
+ // Insert data to WP
271
+ if (!empty($metadata)) {
272
+ $metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
273
+
274
+ $index++;
275
+ $sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
276
+ foreach ($metadata as $entry) {
277
+ $sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
278
+ }
279
+ $sql = rtrim($sql, ", ");
280
+ $wpdb->query($sql);
281
+
282
+ $result['complete'] = false;
283
+ } else {
284
+ $result['complete'] = true;
285
+ }
286
+ $result['index'] = $index;
287
+ return $result;
288
+ }
289
+
290
+ private function DeleteAfterMigrate($record)
291
+ {
292
+ global $wpdb;
293
+ $sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
294
+ $wpdb->query($sql);
295
+ }
296
+
297
+ public function encryptString($plaintext)
298
+ {
299
+ $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
300
+ $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
301
+ $key = $this->truncateKey();
302
+ $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
303
+ $ciphertext = $iv . $ciphertext;
304
+ $ciphertext_base64 = base64_encode($ciphertext);
305
+
306
+ return $ciphertext_base64;
307
+ }
308
+
309
+ private function decryptString($ciphertext_base64)
310
+ {
311
+ $ciphertext_dec = base64_decode($ciphertext_base64);
312
+ $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
313
+
314
+ $iv_dec = substr($ciphertext_dec, 0, $iv_size);
315
+ $ciphertext_dec = substr($ciphertext_dec, $iv_size);
316
+ $key = $this->truncateKey();
317
+ $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
318
+
319
+ return rtrim($plaintext_dec, "\0");
320
+ }
321
+
322
+ private function truncateKey()
323
+ {
324
+ if (!defined('AUTH_KEY')) {
325
+ return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
326
+ }
327
+ $key_size = strlen(AUTH_KEY);
328
+ if ($key_size > 32) {
329
+ return substr(AUTH_KEY, 0, 32);
330
+ } else {
331
+ return AUTH_KEY;
332
+ }
333
+ }
334
+ }
classes/Connector/MySQLDBConnector.php CHANGED
@@ -1,337 +1,337 @@
1
- <?php
2
- require_once('ConnectorInterface.php');
3
- require_once('AbstractConnector.php');
4
- require_once('wp-db-custom.php');
5
-
6
- class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface
7
- {
8
- protected $connectionConfig = null;
9
-
10
- public function __construct($connectionConfig = null)
11
- {
12
- $this->connectionConfig = $connectionConfig;
13
- parent::__construct("MySQL");
14
- require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
15
- }
16
-
17
- public function TestConnection()
18
- {
19
- error_reporting(E_ALL ^ E_WARNING);
20
- $connectionConfig = $this->connectionConfig;
21
- $password = $this->decryptString($connectionConfig['password']);
22
- $newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
23
- if (!$newWpdb->has_connected) { // Database Error
24
- throw new Exception("Connection failed. Please check your connection details.");
25
- }
26
- }
27
-
28
- /**
29
- * Creates a connection and returns it
30
- * @return Instance of WPDB
31
- */
32
- private function createConnection()
33
- {
34
- if (!empty($this->connectionConfig)) {
35
- //TO DO: Use the provided connection config
36
- $connectionConfig = $this->connectionConfig;
37
- $password = $this->decryptString($connectionConfig['password']);
38
- $newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
39
- $newWpdb->set_prefix($connectionConfig['base_prefix']);
40
- return $newWpdb;
41
- } else {
42
- global $wpdb;
43
- return $wpdb;
44
- }
45
- }
46
-
47
- /**
48
- * Returns a wpdb instance
49
- */
50
- public function getConnection()
51
- {
52
- if (!empty($this->connection)) {
53
- return $this->connection;
54
- } else {
55
- $this->connection = $this->createConnection();
56
- return $this->connection;
57
- }
58
- }
59
-
60
- /**
61
- * Gets an adapter for the specified model
62
- */
63
- public function getAdapter($class_name)
64
- {
65
- $objName = $this->getAdapterClassName($class_name);
66
- return new $objName($this->getConnection());
67
- }
68
-
69
- protected function getAdapterClassName($class_name)
70
- {
71
- return 'WSAL_Adapters_MySQL_'.$class_name;
72
- }
73
-
74
- /**
75
- * Checks if the necessary tables are available
76
- */
77
- public function isInstalled()
78
- {
79
- global $wpdb;
80
- $table = $wpdb->base_prefix . 'wsal_occurrences';
81
- return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
82
- }
83
-
84
- /**
85
- * Checks if old version tables are available
86
- */
87
- public function canMigrate()
88
- {
89
- $wpdb = $this->getConnection();
90
- $table = $wpdb->base_prefix . 'wordpress_auditlog_events';
91
- return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
92
- }
93
-
94
- /**
95
- * Install all DB tables.
96
- */
97
- public function installAll($excludeOptions = false)
98
- {
99
- $plugin = WpSecurityAuditLog::GetInstance();
100
-
101
- foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
102
- $filePath = explode(DIRECTORY_SEPARATOR, $file);
103
- $fileName = $filePath[count($filePath) - 1];
104
- $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
105
-
106
- $class = new $className($this->getConnection());
107
- if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
108
- continue;
109
- }
110
-
111
- if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
112
- $class->Install();
113
- }
114
- }
115
- }
116
-
117
- /**
118
- * Uninstall all DB tables.
119
- */
120
- public function uninstallAll()
121
- {
122
- $plugin = WpSecurityAuditLog::GetInstance();
123
-
124
- foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
125
- $filePath = explode(DIRECTORY_SEPARATOR, $file);
126
- $fileName = $filePath[count($filePath) - 1];
127
- $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
128
-
129
- $class = new $className($this->getConnection());
130
- if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
131
- $class->Uninstall();
132
- }
133
- }
134
- }
135
-
136
- private function GetIncreaseOccurrence()
137
- {
138
- $_wpdb = $this->getConnection();
139
- $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
140
- $sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
141
- return (int)$_wpdb->get_var($sql);
142
- }
143
-
144
- public function MigrateMeta($index, $limit)
145
- {
146
- $result = null;
147
- $offset = ($index * $limit);
148
- global $wpdb;
149
- $_wpdb = $this->getConnection();
150
- // Add +1 because an alert is generated after delete the metadata table
151
- $increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
152
-
153
- // Load data Meta from WP
154
- $meta = new WSAL_Adapters_MySQL_Meta($wpdb);
155
- if (!$meta->IsInstalled()) {
156
- $result['empty'] = true;
157
- return $result;
158
- }
159
- $sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
160
- $metadata = $wpdb->get_results($sql, ARRAY_A);
161
-
162
- // Insert data to External DB
163
- if (!empty($metadata)) {
164
- $metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
165
-
166
- $index++;
167
- $sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
168
- foreach ($metadata as $entry) {
169
- $occurrence_id = intval($entry['occurrence_id']) + $increase_occurrence_id;
170
- $sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
171
- }
172
- $sql = rtrim($sql, ", ");
173
- $_wpdb->query($sql);
174
-
175
- $result['complete'] = false;
176
- } else {
177
- $result['complete'] = true;
178
- $this->DeleteAfterMigrate($meta);
179
- }
180
- $result['index'] = $index;
181
- return $result;
182
- }
183
-
184
- public function MigrateOccurrence($index, $limit)
185
- {
186
- $result = null;
187
- $offset = ($index * $limit);
188
- global $wpdb;
189
- $_wpdb = $this->getConnection();
190
-
191
- // Load data Occurrences from WP
192
- $occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
193
- if (!$occurrence->IsInstalled()) {
194
- $result['empty'] = true;
195
- return $result;
196
- }
197
- $sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
198
- $occurrences = $wpdb->get_results($sql, ARRAY_A);
199
-
200
- // Insert data to External DB
201
- if (!empty($occurrences)) {
202
- $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
203
-
204
- $index++;
205
- $sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
206
- foreach ($occurrences as $entry) {
207
- $sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
208
- }
209
- $sql = rtrim($sql, ", ");
210
- $_wpdb->query($sql);
211
-
212
- $result['complete'] = false;
213
- } else {
214
- $result['complete'] = true;
215
- $this->DeleteAfterMigrate($occurrence);
216
- }
217
- $result['index'] = $index;
218
- return $result;
219
- }
220
-
221
- public function MigrateBackOccurrence($index, $limit)
222
- {
223
- $result = null;
224
- $offset = ($index * $limit);
225
- global $wpdb;
226
- $_wpdb = $this->getConnection();
227
-
228
- // Load data Occurrences from External DB
229
- $occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
230
- if (!$occurrence->IsInstalled()) {
231
- $result['empty'] = true;
232
- return $result;
233
- }
234
- $sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
235
- $occurrences = $_wpdb->get_results($sql, ARRAY_A);
236
-
237
- // Insert data to WP
238
- if (!empty($occurrences)) {
239
- $occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
240
-
241
- $index++;
242
- $sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
243
- foreach ($occurrences as $entry) {
244
- $sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
245
- }
246
- $sql = rtrim($sql, ", ");
247
- $wpdb->query($sql);
248
-
249
- $result['complete'] = false;
250
- } else {
251
- $result['complete'] = true;
252
- }
253
- $result['index'] = $index;
254
- return $result;
255
- }
256
-
257
- public function MigrateBackMeta($index, $limit)
258
- {
259
- $result = null;
260
- $offset = ($index * $limit);
261
- global $wpdb;
262
- $_wpdb = $this->getConnection();
263
-
264
- // Load data Meta from External DB
265
- $meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
266
- if (!$meta->IsInstalled()) {
267
- $result['empty'] = true;
268
- return $result;
269
- }
270
- $sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
271
- $metadata = $_wpdb->get_results($sql, ARRAY_A);
272
-
273
- // Insert data to WP
274
- if (!empty($metadata)) {
275
- $metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
276
-
277
- $index++;
278
- $sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
279
- foreach ($metadata as $entry) {
280
- $sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
281
- }
282
- $sql = rtrim($sql, ", ");
283
- $wpdb->query($sql);
284
-
285
- $result['complete'] = false;
286
- } else {
287
- $result['complete'] = true;
288
- }
289
- $result['index'] = $index;
290
- return $result;
291
- }
292
-
293
- private function DeleteAfterMigrate($record)
294
- {
295
- global $wpdb;
296
- $sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
297
- $wpdb->query($sql);
298
- }
299
-
300
- public function encryptString($plaintext)
301
- {
302
- $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
303
- $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
304
- $key = $this->truncateKey();
305
- $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
306
- $ciphertext = $iv . $ciphertext;
307
- $ciphertext_base64 = base64_encode($ciphertext);
308
-
309
- return $ciphertext_base64;
310
- }
311
-
312
- private function decryptString($ciphertext_base64)
313
- {
314
- $ciphertext_dec = base64_decode($ciphertext_base64);
315
- $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
316
-
317
- $iv_dec = substr($ciphertext_dec, 0, $iv_size);
318
- $ciphertext_dec = substr($ciphertext_dec, $iv_size);
319
- $key = $this->truncateKey();
320
- $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
321
-
322
- return rtrim($plaintext_dec, "\0");
323
- }
324
-
325
- private function truncateKey()
326
- {
327
- if (!defined('AUTH_KEY')) {
328
- return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
329
- }
330
- $key_size = strlen(AUTH_KEY);
331
- if ($key_size > 32) {
332
- return substr(AUTH_KEY, 0, 32);
333
- } else {
334
- return AUTH_KEY;
335
- }
336
- }
337
- }
1
+ <?php
2
+ //require_once('ConnectorInterface.php');
3
+ //require_once('AbstractConnector.php');
4
+ //require_once('wp-db-custom.php');
5
+
6
+ class WSAL_Connector_MySQLDB extends WSAL_Connector_AbstractConnector implements WSAL_Connector_ConnectorInterface
7
+ {
8
+ protected $connectionConfig = null;
9
+
10
+ public function __construct($connectionConfig = null)
11
+ {
12
+ $this->connectionConfig = $connectionConfig;
13
+ parent::__construct("MySQL");
14
+ require_once($this->getAdaptersDirectory() . '/OptionAdapter.php');
15
+ }
16
+
17
+ public function TestConnection()
18
+ {
19
+ error_reporting(E_ALL ^ E_WARNING);
20
+ $connectionConfig = $this->connectionConfig;
21
+ $password = $this->decryptString($connectionConfig['password']);
22
+ $newWpdb = new wpdbCustom($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
23
+ if (!$newWpdb->has_connected) { // Database Error
24
+ throw new Exception("Connection failed. Please check your connection details.");
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Creates a connection and returns it
30
+ * @return Instance of WPDB
31
+ */
32
+ private function createConnection()
33
+ {
34
+ if (!empty($this->connectionConfig)) {
35
+ //TO DO: Use the provided connection config
36
+ $connectionConfig = $this->connectionConfig;
37
+ $password = $this->decryptString($connectionConfig['password']);
38
+ $newWpdb = new wpdb($connectionConfig['user'], $password, $connectionConfig['name'], $connectionConfig['hostname']);
39
+ $newWpdb->set_prefix($connectionConfig['base_prefix']);
40
+ return $newWpdb;
41
+ } else {
42
+ global $wpdb;
43
+ return $wpdb;
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Returns a wpdb instance
49
+ */
50
+ public function getConnection()
51
+ {
52
+ if (!empty($this->connection)) {
53
+ return $this->connection;
54
+ } else {
55
+ $this->connection = $this->createConnection();
56
+ return $this->connection;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Gets an adapter for the specified model
62
+ */
63
+ public function getAdapter($class_name)
64
+ {
65
+ $objName = $this->getAdapterClassName($class_name);
66
+ return new $objName($this->getConnection());
67
+ }
68
+
69
+ protected function getAdapterClassName($class_name)
70
+ {
71
+ return 'WSAL_Adapters_MySQL_'.$class_name;
72
+ }
73
+
74
+ /**
75
+ * Checks if the necessary tables are available
76
+ */
77
+ public function isInstalled()
78
+ {
79
+ global $wpdb;
80
+ $table = $wpdb->base_prefix . 'wsal_occurrences';
81
+ return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
82
+ }
83
+
84
+ /**
85
+ * Checks if old version tables are available
86
+ */
87
+ public function canMigrate()
88
+ {
89
+ $wpdb = $this->getConnection();
90
+ $table = $wpdb->base_prefix . 'wordpress_auditlog_events';
91
+ return ($wpdb->get_var('SHOW TABLES LIKE "'.$table.'"') == $table);
92
+ }
93
+
94
+ /**
95
+ * Install all DB tables.
96
+ */
97
+ public function installAll($excludeOptions = false)
98
+ {
99
+ $plugin = WpSecurityAuditLog::GetInstance();
100
+
101
+ foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
102
+ $filePath = explode(DIRECTORY_SEPARATOR, $file);
103
+ $fileName = $filePath[count($filePath) - 1];
104
+ $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
105
+
106
+ $class = new $className($this->getConnection());
107
+ if ($excludeOptions && $class instanceof WSAL_Adapters_MySQL_Option) {
108
+ continue;
109
+ }
110
+
111
+ if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
112
+ $class->Install();
113
+ }
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Uninstall all DB tables.
119
+ */
120
+ public function uninstallAll()
121
+ {
122
+ $plugin = WpSecurityAuditLog::GetInstance();
123
+
124
+ foreach (glob($this->getAdaptersDirectory() . DIRECTORY_SEPARATOR . '*.php') as $file) {
125
+ $filePath = explode(DIRECTORY_SEPARATOR, $file);
126
+ $fileName = $filePath[count($filePath) - 1];
127
+ $className = $this->getAdapterClassName(str_replace("Adapter.php", "", $fileName));
128
+
129
+ $class = new $className($this->getConnection());
130
+ if (is_subclass_of($class, "WSAL_Adapters_MySQL_ActiveRecord")) {
131
+ $class->Uninstall();
132
+ }
133
+ }
134
+ }
135
+
136
+ private function GetIncreaseOccurrence()
137
+ {
138
+ $_wpdb = $this->getConnection();
139
+ $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
140
+ $sql = 'SELECT MAX(id) FROM ' . $occurrenceNew->GetTable();
141
+ return (int)$_wpdb->get_var($sql);
142
+ }
143
+
144
+ public function MigrateMeta($index, $limit)
145
+ {
146
+ $result = null;
147
+ $offset = ($index * $limit);
148
+ global $wpdb;
149
+ $_wpdb = $this->getConnection();
150
+ // Add +1 because an alert is generated after delete the metadata table
151
+ $increase_occurrence_id = $this->GetIncreaseOccurrence() + 1;
152
+
153
+ // Load data Meta from WP
154
+ $meta = new WSAL_Adapters_MySQL_Meta($wpdb);
155
+ if (!$meta->IsInstalled()) {
156
+ $result['empty'] = true;
157
+ return $result;
158
+ }
159
+ $sql = 'SELECT * FROM ' . $meta->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
160
+ $metadata = $wpdb->get_results($sql, ARRAY_A);
161
+
162
+ // Insert data to External DB
163
+ if (!empty($metadata)) {
164
+ $metaNew = new WSAL_Adapters_MySQL_Meta($_wpdb);
165
+
166
+ $index++;
167
+ $sql = 'INSERT INTO ' . $metaNew->GetTable() . ' (occurrence_id, name, value) VALUES ' ;
168
+ foreach ($metadata as $entry) {
169
+ $occurrence_id = intval($entry['occurrence_id']) + $increase_occurrence_id;
170
+ $sql .= '('.$occurrence_id.', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
171
+ }
172
+ $sql = rtrim($sql, ", ");
173
+ $_wpdb->query($sql);
174
+
175
+ $result['complete'] = false;
176
+ } else {
177
+ $result['complete'] = true;
178
+ $this->DeleteAfterMigrate($meta);
179
+ }
180
+ $result['index'] = $index;
181
+ return $result;
182
+ }
183
+
184
+ public function MigrateOccurrence($index, $limit)
185
+ {
186
+ $result = null;
187
+ $offset = ($index * $limit);
188
+ global $wpdb;
189
+ $_wpdb = $this->getConnection();
190
+
191
+ // Load data Occurrences from WP
192
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($wpdb);
193
+ if (!$occurrence->IsInstalled()) {
194
+ $result['empty'] = true;
195
+ return $result;
196
+ }
197
+ $sql = 'SELECT * FROM ' . $occurrence->GetWPTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
198
+ $occurrences = $wpdb->get_results($sql, ARRAY_A);
199
+
200
+ // Insert data to External DB
201
+ if (!empty($occurrences)) {
202
+ $occurrenceNew = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
203
+
204
+ $index++;
205
+ $sql = 'INSERT INTO ' . $occurrenceNew->GetTable() . ' (site_id, alert_id, created_on, is_read) VALUES ' ;
206
+ foreach ($occurrences as $entry) {
207
+ $sql .= '('.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
208
+ }
209
+ $sql = rtrim($sql, ", ");
210
+ $_wpdb->query($sql);
211
+
212
+ $result['complete'] = false;
213
+ } else {
214
+ $result['complete'] = true;
215
+ $this->DeleteAfterMigrate($occurrence);
216
+ }
217
+ $result['index'] = $index;
218
+ return $result;
219
+ }
220
+
221
+ public function MigrateBackOccurrence($index, $limit)
222
+ {
223
+ $result = null;
224
+ $offset = ($index * $limit);
225
+ global $wpdb;
226
+ $_wpdb = $this->getConnection();
227
+
228
+ // Load data Occurrences from External DB
229
+ $occurrence = new WSAL_Adapters_MySQL_Occurrence($_wpdb);
230
+ if (!$occurrence->IsInstalled()) {
231
+ $result['empty'] = true;
232
+ return $result;
233
+ }
234
+ $sql = 'SELECT * FROM ' . $occurrence->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
235
+ $occurrences = $_wpdb->get_results($sql, ARRAY_A);
236
+
237
+ // Insert data to WP
238
+ if (!empty($occurrences)) {
239
+ $occurrenceWP = new WSAL_Adapters_MySQL_Occurrence($wpdb);
240
+
241
+ $index++;
242
+ $sql = 'INSERT INTO ' . $occurrenceWP->GetWPTable() . ' (id, site_id, alert_id, created_on, is_read) VALUES ' ;
243
+ foreach ($occurrences as $entry) {
244
+ $sql .= '('.$entry['id'].', '.$entry['site_id'].', '.$entry['alert_id'].', '.$entry['created_on'].', '.$entry['is_read'].'), ';
245
+ }
246
+ $sql = rtrim($sql, ", ");
247
+ $wpdb->query($sql);
248
+
249
+ $result['complete'] = false;
250
+ } else {
251
+ $result['complete'] = true;
252
+ }
253
+ $result['index'] = $index;
254
+ return $result;
255
+ }
256
+
257
+ public function MigrateBackMeta($index, $limit)
258
+ {
259
+ $result = null;
260
+ $offset = ($index * $limit);
261
+ global $wpdb;
262
+ $_wpdb = $this->getConnection();
263
+
264
+ // Load data Meta from External DB
265
+ $meta = new WSAL_Adapters_MySQL_Meta($_wpdb);
266
+ if (!$meta->IsInstalled()) {
267
+ $result['empty'] = true;
268
+ return $result;
269
+ }
270
+ $sql = 'SELECT * FROM ' . $meta->GetTable() . ' LIMIT ' . $limit . ' OFFSET '. $offset;
271
+ $metadata = $_wpdb->get_results($sql, ARRAY_A);
272
+
273
+ // Insert data to WP
274
+ if (!empty($metadata)) {
275
+ $metaWP = new WSAL_Adapters_MySQL_Meta($wpdb);
276
+
277
+ $index++;
278
+ $sql = 'INSERT INTO ' . $metaWP->GetWPTable() . ' (occurrence_id, name, value) VALUES ' ;
279
+ foreach ($metadata as $entry) {
280
+ $sql .= '('.$entry['occurrence_id'].', \''.$entry['name'].'\', \''.str_replace("'", "\'", $entry['value']).'\'), ';
281
+ }
282
+ $sql = rtrim($sql, ", ");
283
+ $wpdb->query($sql);
284
+
285
+ $result['complete'] = false;
286
+ } else {
287
+ $result['complete'] = true;
288
+ }
289
+ $result['index'] = $index;
290
+ return $result;
291
+ }
292
+
293
+ private function DeleteAfterMigrate($record)
294
+ {
295
+ global $wpdb;
296
+ $sql = 'DROP TABLE IF EXISTS ' . $record->GetTable();
297
+ $wpdb->query($sql);
298
+ }
299
+
300
+ public function encryptString($plaintext)
301
+ {
302
+ $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
303
+ $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
304
+ $key = $this->truncateKey();
305
+ $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
306
+ $ciphertext = $iv . $ciphertext;
307
+ $ciphertext_base64 = base64_encode($ciphertext);
308
+
309
+ return $ciphertext_base64;
310
+ }
311
+
312
+ private function decryptString($ciphertext_base64)
313
+ {
314
+ $ciphertext_dec = base64_decode($ciphertext_base64);
315
+ $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
316
+
317
+ $iv_dec = substr($ciphertext_dec, 0, $iv_size);
318
+ $ciphertext_dec = substr($ciphertext_dec, $iv_size);
319
+ $key = $this->truncateKey();
320
+ $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);
321
+
322
+ return rtrim($plaintext_dec, "\0");
323
+ }
324
+
325
+ private function truncateKey()
326
+ {
327
+ if (!defined('AUTH_KEY')) {
328
+ return 'x4>Tg@G-Kr6a]o-eJeP^?UO)KW;LbV)I';
329
+ }
330
+ $key_size = strlen(AUTH_KEY);
331
+ if ($key_size > 32) {
332
+ return substr(AUTH_KEY, 0, 32);
333
+ } else {
334
+ return AUTH_KEY;
335
+ }
336
+ }
337
+ }
classes/Connector/wp-db-custom.php CHANGED
@@ -1,36 +1,36 @@
1
- <?php
2
-
3
- class wpdbCustom extends wpdb
4
- {
5
- /*
6
- * overwrite wpdb class for set $allow_bail to false
7
- * and hide the print of the error
8
- */
9
- public function __construct($dbuser, $dbpassword, $dbname, $dbhost)
10
- {
11
- register_shutdown_function(array($this, '__destruct'));
12
- if (WP_DEBUG && WP_DEBUG_DISPLAY) {
13
- $this->show_errors();
14
- }
15
- if (function_exists('mysqli_connect')) {
16
- if (defined('WP_USE_EXT_MYSQL')) {
17
- $this->use_mysqli = ! WP_USE_EXT_MYSQL;
18
- } elseif (version_compare(phpversion(), '5.5', '>=') || !function_exists('mysql_connect')) {
19
- $this->use_mysqli = true;
20
- } elseif (false !== strpos($GLOBALS['wp_version'], '-')) {
21
- $this->use_mysqli = true;
22
- }
23
- }
24
- $this->dbuser = $dbuser;
25
- $this->dbpassword = $dbpassword;
26
- $this->dbname = $dbname;
27
- $this->dbhost = $dbhost;
28
- // wp-config.php creation will manually connect when ready.
29
- if (defined('WP_SETUP_CONFIG')) {
30
- return;
31
- }
32
-
33
- $this->db_connect(false);
34
- }
35
-
36
- }
1
+ <?php
2
+
3
+ class wpdbCustom extends wpdb
4
+ {
5
+ /*
6
+ * overwrite wpdb class for set $allow_bail to false
7
+ * and hide the print of the error
8
+ */
9
+ public function __construct($dbuser, $dbpassword, $dbname, $dbhost)
10
+ {
11
+ register_shutdown_function(array($this, '__destruct'));
12
+ if (WP_DEBUG && WP_DEBUG_DISPLAY) {
13
+ $this->show_errors();
14
+ }
15
+ if (function_exists('mysqli_connect')) {
16
+ if (defined('WP_USE_EXT_MYSQL')) {
17
+ $this->use_mysqli = ! WP_USE_EXT_MYSQL;
18
+ } elseif (version_compare(phpversion(), '5.5', '>=') || !function_exists('mysql_connect')) {
19
+ $this->use_mysqli = true;
20
+ } elseif (false !== strpos($GLOBALS['wp_version'], '-')) {
21
+ $this->use_mysqli = true;
22
+ }
23
+ }
24
+ $this->dbuser = $dbuser;
25
+ $this->dbpassword = $dbpassword;
26
+ $this->dbname = $dbname;
27
+ $this->dbhost = $dbhost;
28
+ // wp-config.php creation will manually connect when ready.
29
+ if (defined('WP_SETUP_CONFIG')) {
30
+ return;
31
+ }
32
+
33
+ $this->db_connect(false);
34
+ }
35
+
36
+ }
classes/ConstantManager.php CHANGED
@@ -1,89 +1,89 @@
1
- <?php
2
-
3
- class WSAL_ConstantManager {
4
-
5
- protected $_constants = array();
6
-
7
- /**
8
- * Use an existing PHP constant.
9
- * @param string $name Constant name.
10
- * @param string $description Constant description.
11
- */
12
- public function UseConstant($name, $description = ''){
13
- $this->_constants[] = (object)array(
14
- 'name' => $name,
15
- 'value' => constant($name),
16
- 'description' => $description,
17
- );
18
- }
19
-
20
- /**
21
- * Add new PHP constant.
22
- * @param string $name Constant name.
23
- * @param integer|string $value Constant value.
24
- * @param string $description Constant description.
25
- */
26
- public function AddConstant($name, $value, $description = ''){
27
-
28
- // check for constant conflict and define new one if required
29
- if(defined($name) && constant($name) !== $value){
30
- throw new Exception('Constant already defined with a different value.');
31
- }else{
32
- define($name, $value);
33
- }
34
-
35
- // add constant to da list.
36
- $this->UseConstant($name, $description);
37
-
38
- }
39
-
40
- /**
41
- * Add multiple constants in one go.
42
- * @param array $items Array of arrays with name, value, description pairs.
43
- */
44
- public function AddConstants($items){
45
- foreach($items as $item)
46
- $this->AddConstant(
47
- $item['name'],
48
- $item['value'],
49
- $item['description']
50
- );
51
- }
52
-
53
- /**
54
- * Use multiple constants in one go.
55
- * @param array $items Array of arrays with name, description pairs.
56
- */
57
- public function UseConstants($items){
58
- foreach($items as $item)
59
- $this->UseConstant(
60
- $item['name'],
61
- $item['description']
62
- );
63
- }
64
-
65
- /**
66
- * Get constant details by a particular detail.
67
- * @param string $what The type of detail: 'name', 'value'
68
- * @param mixed $value The detail expected value.
69
- * @return mixed Either constant details (props: name, value, description) or $default if not found.
70
- */
71
- public function GetConstantBy($what, $value, $default = null){
72
-
73
- // make sure we do have some constants...
74
- if(count($this->_constants)){
75
-
76
- // make sure that constants do have a $what property
77
- if(!isset($this->_constants[0]->$what))
78
- throw new Exception('Unexpected detail type "' . $what . '".');
79
-
80
- // return constant match the property value
81
- foreach($this->_constants as $constant)
82
- if($constant->$what == $value)
83
- return $constant;
84
-
85
- }
86
-
87
- return $default;
88
- }
89
  }
1
+ <?php
2
+
3
+ class WSAL_ConstantManager {
4
+
5
+ protected $_constants = array();
6
+
7
+ /**
8
+ * Use an existing PHP constant.
9
+ * @param string $name Constant name.
10
+ * @param string $description Constant description.
11
+ */
12
+ public function UseConstant($name, $description = ''){
13
+ $this->_constants[] = (object)array(
14
+ 'name' => $name,
15
+ 'value' => constant($name),
16
+ 'description' => $description,
17
+ );
18
+ }
19
+
20
+ /**
21
+ * Add new PHP constant.
22
+ * @param string $name Constant name.
23
+ * @param integer|string $value Constant value.
24
+ * @param string $description Constant description.
25
+ */
26
+ public function AddConstant($name, $value, $description = ''){
27
+
28
+ // check for constant conflict and define new one if required
29
+ if(defined($name) && constant($name) !== $value){
30
+ throw new Exception('Constant already defined with a different value.');
31
+ }else{
32
+ define($name, $value);
33
+ }
34
+
35
+ // add constant to da list.
36
+ $this->UseConstant($name, $description);
37
+
38
+ }
39
+
40
+ /**
41
+ * Add multiple constants in one go.
42
+ * @param array $items Array of arrays with name, value, description pairs.
43
+ */
44
+ public function AddConstants($items){
45
+ foreach($items as $item)
46
+ $this->AddConstant(
47
+ $item['name'],
48
+ $item['value'],
49
+ $item['description']
50
+ );
51
+ }
52
+
53
+ /**
54
+ * Use multiple constants in one go.
55
+ * @param array $items Array of arrays with name, description pairs.
56
+ */
57
+ public function UseConstants($items){
58
+ foreach($items as $item)
59
+ $this->UseConstant(
60
+ $item['name'],
61
+ $item['description']
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Get constant details by a particular detail.
67
+ * @param string $what The type of detail: 'name', 'value'
68
+ * @param mixed $value The detail expected value.
69
+ * @return mixed Either constant details (props: name, value, description) or $default if not found.
70
+ */
71
+ public function GetConstantBy($what, $value, $default = null){
72
+
73
+ // make sure we do have some constants...
74
+ if(count($this->_constants)){
75
+
76
+ // make sure that constants do have a $what property
77
+ if(!isset($this->_constants[0]->$what))
78
+ throw new Exception('Unexpected detail type "' . $what . '".');
79
+
80
+ // return constant match the property value
81
+ foreach($this->_constants as $constant)
82
+ if($constant->$what == $value)
83
+ return $constant;
84
+
85
+ }
86
+
87
+ return $default;
88
+ }
89
  }
classes/EDD_SL_Plugin_Updater.php CHANGED
@@ -1,170 +1,170 @@
1
- <?php
2
-
3
- // uncomment this line for testing
4
- //set_site_transient( 'update_plugins', null );
5
-
6
- /**
7
- * Allows plugins to use their own update API.
8
- *
9
- * @author Pippin Williamson
10
- * @version 1.2
11
- */
12
- class EDD_SL_Plugin_Updater {
13
- private $api_url = '';
14
- private $api_data = array();
15
- private $name = '';
16
- private $slug = '';
17
- private $do_check = false;
18
-
19
- /**
20
- * Class constructor.
21
- *
22
- * @uses plugin_basename()
23
- * @uses hook()
24
- *
25
- * @param string $_api_url The URL pointing to the custom API endpoint.
26
- * @param string $_plugin_file Path to the plugin file.
27
- * @param array $_api_data Optional data to send with API calls.
28
- * @return void
29
- */
30
- function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
31
- $this->api_url = trailingslashit( $_api_url );
32
- $this->api_data = urlencode_deep( $_api_data );
33
- $this->name = plugin_basename( $_plugin_file );
34
- $this->slug = basename( $_plugin_file, '.php');
35
- $this->version = $_api_data['version'];
36
-
37
- // Set up hooks.
38
- $this->hook();
39
- }
40
-
41
- /**
42
- * Set up WordPress filters to hook into WP's update process.
43
- *
44
- * @uses add_filter()
45
- *
46
- * @return void
47
- */
48
- private function hook() {
49
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
50
- add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
51
- add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
52
- }
53
-
54
- /**
55
- * Check for Updates at the defined API endpoint and modify the update array.
56
- *
57
- * This function dives into the update API just when WordPress creates its update array,
58
- * then adds a custom API call and injects the custom plugin data retrieved from the API.
59
- * It is reassembled from parts of the native WordPress plugin update code.
60
- * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
61
- *
62
- * @uses api_request()
63
- *
64
- * @param array $_transient_data Update array build by WordPress.
65
- * @return array Modified update array with custom plugin data.
66
- */
67
- function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
68
-
69
- if( empty( $_transient_data ) || ! $this->do_check ) {
70
-
71
- // This ensures that the custom API request only runs on the second time that WP fires the update check
72
- $this->do_check = true;
73
-
74
- return $_transient_data;
75
- }
76
-
77
- $to_send = array( 'slug' => $this->slug );
78
-
79
- $api_response = $this->api_request( 'plugin_latest_version', $to_send );
80
-
81
- if( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
82
-
83
- if( version_compare( $this->version, $api_response->new_version, '<' ) ) {
84
- $_transient_data->response[$this->name] = $api_response;
85
- }
86
- }
87
- return $_transient_data;
88
- }
89
-
90
-
91
- /**
92
- * Updates information on the "View version x.x details" page with custom data.
93
- *
94
- * @uses api_request()
95
- *
96
- * @param mixed $_data
97
- * @param string $_action
98
- * @param object $_args
99
- * @return object $_data
100
- */
101
- function plugins_api_filter( $_data, $_action = '', $_args = null ) {
102
- if ( ( $_action != 'plugin_information' ) || !isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) return $_data;
103
-
104
- $to_send = array( 'slug' => $this->slug );
105
-
106
- $api_response = $this->api_request( 'plugin_information', $to_send );
107
- if ( false !== $api_response ) $_data = $api_response;
108
-
109
- return $_data;
110
- }
111
-
112
-
113
- /**
114
- * Disable SSL verification in order to prevent download update failures
115
- *
116
- * @param array $args
117
- * @param string $url
118
- * @return object $array
119
- */
120
- function http_request_args( $args, $url ) {
121
- // If it is an https request and we are performing a package download, disable ssl verification
122
- if( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
123
- $args['sslverify'] = false;
124
- }
125
- return $args;
126
- }
127
-
128
- /**
129
- * Calls the API and, if successfull, returns the object delivered by the API.
130
- *
131
- * @uses get_bloginfo()
132
- * @uses wp_remote_post()
133
- * @uses is_wp_error()
134
- *
135
- * @param string $_action The requested action.
136
- * @param array $_data Parameters for the API action.
137
- * @return false||object
138
- */
139
- private function api_request( $_action, $_data ) {
140
-
141
- global $wp_version;
142
-
143
- $data = array_merge( $this->api_data, $_data );
144
-
145
- if( $data['slug'] != $this->slug )
146
- return;
147
-
148
- if( empty( $data['license'] ) )
149
- return;
150
-
151
- $api_params = array(
152
- 'edd_action' => 'get_version',
153
- 'license' => $data['license'],
154
- 'name' => $data['item_name'],
155
- 'slug' => $this->slug,
156
- 'author' => $data['author'],
157
- 'url' => home_url()
158
- );
159
- $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
160
-
161
- if ( ! is_wp_error( $request ) ):
162
- $request = json_decode( wp_remote_retrieve_body( $request ) );
163
- if( $request && isset( $request->sections ) )
164
- $request->sections = maybe_unserialize( $request->sections );
165
- return $request;
166
- else:
167
- return false;
168
- endif;
169
- }
170
- }
1
+ <?php
2
+
3
+ // uncomment this line for testing
4
+ //set_site_transient( 'update_plugins', null );
5
+
6
+ /**
7
+ * Allows plugins to use their own update API.
8
+ *
9
+ * @author Pippin Williamson
10
+ * @version 1.2
11
+ */
12
+ class EDD_SL_Plugin_Updater {
13
+ private $api_url = '';
14
+ private $api_data = array();
15
+ private $name = '';
16
+ private $slug = '';
17
+ private $do_check = false;
18
+
19
+ /**
20
+ * Class constructor.
21
+ *
22
+ * @uses plugin_basename()
23
+ * @uses hook()
24
+ *
25
+ * @param string $_api_url The URL pointing to the custom API endpoint.
26
+ * @param string $_plugin_file Path to the plugin file.
27
+ * @param array $_api_data Optional data to send with API calls.
28
+ * @return void
29
+ */
30
+ function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
31
+ $this->api_url = trailingslashit( $_api_url );
32
+ $this->api_data = urlencode_deep( $_api_data );
33
+ $this->name = plugin_basename( $_plugin_file );
34
+ $this->slug = basename( $_plugin_file, '.php');
35
+ $this->version = $_api_data['version'];
36
+
37
+ // Set up hooks.
38
+ $this->hook();
39
+ }
40
+
41
+ /**
42
+ * Set up WordPress filters to hook into WP's update process.
43
+ *
44
+ * @uses add_filter()
45
+ *
46
+ * @return void
47
+ */
48
+ private function hook() {
49
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
50
+ add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
51
+ add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
52
+ }
53
+
54
+ /**
55
+ * Check for Updates at the defined API endpoint and modify the update array.
56
+ *
57
+ * This function dives into the update API just when WordPress creates its update array,
58
+ * then adds a custom API call and injects the custom plugin data retrieved from the API.
59
+ * It is reassembled from parts of the native WordPress plugin update code.
60
+ * See wp-includes/update.php line 121 for the original wp_update_plugins() function.
61
+ *
62
+ * @uses api_request()
63
+ *
64
+ * @param array $_transient_data Update array build by WordPress.
65
+ * @return array Modified update array with custom plugin data.
66
+ */
67
+ function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
68
+
69
+ if( empty( $_transient_data ) || ! $this->do_check ) {
70
+
71
+ // This ensures that the custom API request only runs on the second time that WP fires the update check
72
+ $this->do_check = true;
73
+
74
+ return $_transient_data;
75
+ }
76
+
77
+ $to_send = array( 'slug' => $this->slug );
78
+
79
+ $api_response = $this->api_request( 'plugin_latest_version', $to_send );
80
+
81
+ if( false !== $api_response && is_object( $api_response ) && isset( $api_response->new_version ) ) {
82
+
83
+ if( version_compare( $this->version, $api_response->new_version, '<' ) ) {
84
+ $_transient_data->response[$this->name] = $api_response;
85
+ }
86
+ }
87
+ return $_transient_data;
88
+ }
89
+
90
+
91
+ /**
92
+ * Updates information on the "View version x.x details" page with custom data.
93
+ *
94
+ * @uses api_request()
95
+ *
96
+ * @param mixed $_data
97
+ * @param string $_action
98
+ * @param object $_args
99
+ * @return object $_data
100
+ */
101
+ function plugins_api_filter( $_data, $_action = '', $_args = null ) {
102
+ if ( ( $_action != 'plugin_information' ) || !isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) return $_data;
103
+
104
+ $to_send = array( 'slug' => $this->slug );
105
+
106
+ $api_response = $this->api_request( 'plugin_information', $to_send );
107
+ if ( false !== $api_response ) $_data = $api_response;
108
+
109
+ return $_data;
110
+ }
111
+
112
+
113
+ /**
114
+ * Disable SSL verification in order to prevent download update failures
115
+ *
116
+ * @param array $args
117
+ * @param string $url
118
+ * @return object $array
119
+ */
120
+ function http_request_args( $args, $url ) {
121
+ // If it is an https request and we are performing a package download, disable ssl verification
122
+ if( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
123
+ $args['sslverify'] = false;
124
+ }
125
+ return $args;
126
+ }
127
+
128
+ /**
129
+ * Calls the API and, if successfull, returns the object delivered by the API.
130
+ *
131
+ * @uses get_bloginfo()
132
+ * @uses wp_remote_post()
133
+ * @uses is_wp_error()
134
+ *
135
+ * @param string $_action The requested action.
136
+ * @param array $_data Parameters for the API action.
137
+ * @return false||object
138
+ */
139
+ private function api_request( $_action, $_data ) {
140
+
141
+ global $wp_version;
142
+
143
+ $data = array_merge( $this->api_data, $_data );
144
+
145
+ if( $data['slug'] != $this->slug )
146
+ return;
147
+
148
+ if( empty( $data['license'] ) )
149
+ return;
150
+
151
+ $api_params = array(
152
+ 'edd_action' => 'get_version',
153
+ 'license' => $data['license'],
154
+ 'name' => $data['item_name'],
155
+ 'slug' => $this->slug,
156
+ 'author' => $data['author'],
157
+ 'url' => home_url()
158
+ );
159
+ $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
160
+
161
+ if ( ! is_wp_error( $request ) ):
162
+ $request = json_decode( wp_remote_retrieve_body( $request ) );
163
+ if( $request && isset( $request->sections ) )
164
+ $request->sections = maybe_unserialize( $request->sections );
165
+ return $request;
166
+ else:
167
+ return false;
168
+ endif;
169
+ }
170
+ }
classes/Helpers/DataHelper.php CHANGED
@@ -1,23 +1,23 @@
1
- <?php
2
-
3
- class WSAL_Helpers_DataHelper
4
- {
5
-
6
- /**
7
- * A wrapper for JSON encoding that fixes potential issues.
8
- * @param mixed $data The data to encode.
9
- * @return string JSON string.
10
- */
11
- public static function JsonEncode($data){
12
- return @json_encode($data);
13
- }
14
-
15
- /**
16
- * A wrapper for JSON encoding that fixes potential issues.
17
- * @param string $data The JSON string to decode.
18
- * @return mixed Decoded data.
19
- */
20
- public static function JsonDecode($data){
21
- return @json_decode($data);
22
- }
23
  }
1
+ <?php
2
+
3
+ class WSAL_Helpers_DataHelper
4
+ {
5
+
6
+ /**
7
+ * A wrapper for JSON encoding that fixes potential issues.
8
+ * @param mixed $data The data to encode.
9
+ * @return string JSON string.
10
+ */
11
+ public static function JsonEncode($data){
12
+ return @json_encode($data);
13
+ }
14
+
15
+ /**
16
+ * A wrapper for JSON encoding that fixes potential issues.
17
+ * @param string $data The JSON string to decode.
18
+ * @return mixed Decoded data.
19
+ */
20
+ public static function JsonDecode($data){
21
+ return @json_decode($data);
22
+ }
23
  }
classes/LicenseManager.php CHANGED
@@ -1,171 +1,176 @@
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
+
39
+ protected function GetPluginData($pluginFile, $license){
40
+ // A hack since get_plugin_data() is not available now
41
+ $pluginData = get_file_data($pluginFile, array(
42
+ 'Name' => 'Plugin Name',
43
+ 'PluginURI' => 'Plugin URI',
44
+ 'Version' => 'Version',
45
+ 'Description' => 'Description',
46
+ 'Author' => 'Author',
47
+ 'TextDomain' => 'Text Domain',
48
+ 'DomainPath' => 'Domain Path',
49
+ ), 'plugin' );
50
+
51
+ $pluginUpdater = is_null($license)
52
+ ? null
53
+ : new EDD_SL_Plugin_Updater(
54
+ $this->GetStoreUrl(),
55
+ $pluginFile,
56
+ array(
57
+ 'license' => $license,
58
+ 'item_name' => $pluginData['Name'],
59
+ 'author' => $pluginData['Author'],
60
+ 'version' => $pluginData['Version'],
61
+ )
62
+ );
63
+
64
+ return array(
65
+ 'PluginData' => $pluginData,
66
+ 'EddUpdater' => $pluginUpdater,
67
+ );
68
+ }
69
+
70
+ public function AddPremiumPlugin($pluginFile) {
71
+ if (isset($pluginFile)) {
72
+ $name = sanitize_key(basename($pluginFile));
73
+ $license = $this->plugin->settings->GetLicenseKey($name);
74
+ $this->plugins[$name] = $this->GetPluginData($pluginFile, $license);
75
+ }
76
+ }
77
+
78
+ public function AddPlugin($pluginFile) {
79
+ if (isset($pluginFile)) {
80
+ $name = sanitize_key(basename($pluginFile));
81
+ $this->plugins[$name] = $this->GetPluginData($pluginFile, null);
82
+ }
83
+ }
84
+
85
+ protected function GetBlogIds(){
86
+ global $wpdb;
87
+ $sql = 'SELECT blog_id FROM ' . $wpdb->blogs;
88
+ return $wpdb->get_col($sql);
89
+ }
90
+
91
+ public function ActivateLicense($name, $license){
92
+ $this->plugin->settings->SetLicenseKey($name, $license);
93
+
94
+ $plugins = $this->Plugins();
95
+ $api_params = array(
96
+ 'edd_action'=> 'activate_license',
97
+ 'license' => urlencode($license),
98
+ 'item_name' => urlencode($plugins[$name]['PluginData']['Name']),
99
+ 'url' => urlencode(home_url()),
100
+ );
101
+
102
+ $blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array(1);
103
+
104
+ foreach($blog_ids as $blog_id){
105
+
106
+ if($this->plugin->IsMultisite())
107
+ $api_params['url'] = urlencode(get_home_url($blog_id));
108
+
109
+ $response = wp_remote_get(
110
+ esc_url_raw(add_query_arg($api_params, $this->GetStoreUrl())),
111
+ array('timeout' => 15, 'sslverify' => false)
112
+ );
113
+
114
+ if (is_wp_error($response)) {
115
+ $this->plugin->settings->SetLicenseErrors($name, 'Invalid Licensing Server Response: ' . $response->get_error_message());
116
+ $this->DeactivateLicense($name, $license);
117
+ return false;
118
+ }
119
+
120
+ $license_data = json_decode(wp_remote_retrieve_body($response));
121
+
122
+ if(is_object($license_data)){
123
+ $this->plugin->settings->SetLicenseStatus($name, $license_data->license);
124
+ if($license_data->license !== 'valid'){
125
+ $error = 'License Not Valid';
126
+ if (isset($license_data->error)) $error .= ': ' . ucfirst(str_replace('_', ' ', $license_data->error));
127
+ $this->plugin->settings->SetLicenseErrors($name, $error);
128
+ $this->DeactivateLicense($name, $license);
129
+ return false;
130
+ }
131
+ }else{
132
+ $this->plugin->settings->SetLicenseErrors($name, 'Unexpected Licensing Server Response');
133
+ $this->DeactivateLicense($name, $license);
134
+ return false;
135
+ }
136
+ }
137
+
138
+ return true;
139
+ }
140
+
141
+ public function IsLicenseValid($name){
142
+ return trim(strtolower($this->plugin->settings->GetLicenseStatus($name))) === 'valid';
143
+ }
144
+
145
+ public function DeactivateLicense($name, $license = null){
146
+ $this->plugin->settings->SetLicenseStatus($name, '');
147
+
148
+ // deactivate it on the server (if license was given)
149
+ if(!is_null($license)){
150
+ $plugins = $this->Plugins();
151
+ $api_params = array(
152
+ 'edd_action'=> 'deactivate_license',
153
+ 'license' => urlencode($license),
154
+ 'item_name' => urlencode($plugins[$name]['PluginData']['Name']),
155
+ 'url' => urlencode(home_url()),
156
+ );
157
+
158
+ $blog_ids = $this->plugin->IsMultisite() ? $this->GetBlogIds() : array(1);
159
+
160
+ foreach($blog_ids as $blog_id){
161
+
162
+ if($this->plugin->IsMultisite())
163
+ $api_params['url'] = urlencode(get_home_url($blog_id));
164
+
165
+ $response = wp_remote_get(
166
+ esc_url_raw(add_query_arg($api_params, $this->GetStoreUrl())),
167
+ array('timeout' => 15, 'sslverify' => false)
168
+ );
169
+
170
+ if (is_wp_error($response)) return false;
171
+
172
+ wp_remote_retrieve_body($response);
173
+ }
174
+ }
175
+ }
176
+ }
classes/Loggers/Database.php CHANGED
@@ -84,7 +84,7 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger
84
  if (($occurrence->getId() % $count) == 0) {
85
  $promoToSend = $this->GetPromoAlert();
86
  if (!empty($promoToSend)) {
87
- $link = '<a href="'.$promoToSend['link'].'" target="_blank">'.$promoToSend['name'].'</a>';
88
  $this->Log(9999, array(
89
  'ClientIP' => '127.0.0.1',
90
  'Username' => 'Plugin',
@@ -118,84 +118,28 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger
118
  private function GetActivePromoText()
119
  {
120
  $aPromoAlerts = array();
121
- for ($i = 1; $i <= 2; $i++) {
122
- // Generic Premium Update
123
- if ($i == 1) {
124
- $msg = 'Add email alerts, generate compliance reports and add the search functionality to your WordPress audit log with the <strong>%s</strong>.';
125
- } else {
126
- $msg = 'Buy all the WP Security Audit Log premium add-ons as bundle and <strong>benefit from a 60&percnt; discount</strong>. <strong>All %s</strong> for 1 website only cost $89.';
127
- }
128
- $aPromoAlerts[] = array(
129
- 'name' => 'Premium Add-Ons',
130
- 'message' => '<strong>60&percnt; OFF On All Premium Add-Ons and Support Bundle</strong><br>'. $msg,
131
- 'link' => 'http://www.wpsecurityauditlog.com/plugin-extensions/?utm_source=auditviewer&utm_medium=allpromoalert&utm_campaign=plugin'
132
- );
133
- // Email Add-On
134
- if (!class_exists('WSAL_NP_Plugin')) {
135
- if ($i == 1) {
136
- $msg = 'Get notified instantly via email of important changes and actions on your WordPress with the <strong>%s</strong>.';
137
- } else {
138
- $msg = 'Receive an email when a user changes a password, when someone logs in during odd hours or from an unusual location with the <strong>%s</strong>';
139
- }
140
- $aPromoAlerts[] = array(
141
- 'name' => 'Email Notifications Add-on',
142
- 'message' => '<strong>Email Notifications for WordPress</strong><br>'. $msg,
143
- 'link' => 'http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=auditviewer&utm_medium=emailpromoalert&utm_campaign=plugin'
144
- );
145
- }
146
- // Search Add-On
147
- if (!class_exists('WSAL_SearchExtension')) {
148
- if ($i == 1) {
149
- $msg = 'Easily find a specific change or action in the WordPress audit log with the <strong>%s</strong>.';
150
- } else {
151
- $msg = 'Add the Search functionality to the WordPress audit log to find a specific change or action easily within seconds. Use the <strong>%s</strong>';
152
- }
153
- $aPromoAlerts[] = array(
154
- 'name' => 'Search & Filters Add-on',
155
- 'message' => '<strong>Search and Filtering for WordPress Audit Log</strong><br>'. $msg,
156
- 'link' => 'http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=auditviewer&utm_medium=searchpromoalert&utm_campaign=plugin'
157
- );
158
- }
159
- // Reports Add-On
160
- if (!class_exists('WSAL_Rep_Plugin')) {
161
- if ($i == 1) {
162
- $msg = 'Generate WordPress reports for management and to meet regulatory compliance requirements your business needs to adhere to with the <strong>%s</strong>.';
163
- } else {
164
- $msg = 'Generate WordPress reports to ensure users’ productivity and meet legal and regulatory compliance requirements with the <strong>%s</strong>';
165
- }
166
- $aPromoAlerts[] = array(
167
- 'name' => 'Reports Add-on',
168
- 'message' => '<strong>WordPress Reports Add-On</strong><br>'. $msg,
169
- 'link' => 'http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=auditviewer&utm_medium=reportspromoalert&utm_campaign=plugin'
170
- );
171
- }
172
- // External DB Add-On
173
- if (!class_exists('WSAL_Ext_Plugin')) {
174
- if ($i == 1) {
175
- $msg = 'Store the WordPress audit log in an external database to boost the performance and security of your WordPress. <strong>%s</strong>.';
176
- } else {
177
- $msg = 'Meet regulatory compliance requirements your business needs to adhere to. <strong>%s</strong>';
178
- }
179
- $aPromoAlerts[] = array(
180
- 'name' => 'External DB Add-on',
181
- 'message' => '<strong>External Database for WordPress Audit Log</strong><br>'. $msg,
182
- 'link' => 'http://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/?utm_source=auditviewer&utm_medium=extdbpromoalert&utm_campaign=plugin'
183
- );
184
- }
185
- if (count($aPromoAlerts) == 1) {
186
- unset($aPromoAlerts[0]);
187
- }
188
- }
189
- if (count($aPromoAlerts) >= 1) {
190
- return $aPromoAlerts;
191
- } else {
192
- return null;
193
- }
194
  }
195
 
196
  private function CheckPromoToShow()
197
  {
198
  $promoToShow = null;
 
199
  if (!class_exists('WSAL_NP_Plugin')) {
200
  $promoToShow[] = true;
201
  }
@@ -208,10 +152,13 @@ class WSAL_Loggers_Database extends WSAL_AbstractLogger
208
  if (!class_exists('WSAL_Ext_Plugin')) {
209
  $promoToShow[] = true;
210
  }
 
 
 
211
 
212
  if (empty($promoToShow)) {
213
  return null;
214
  }
215
- return (count($promoToShow) == 4) ? 100 : 175;
216
  }
217
  }
84
  if (($occurrence->getId() % $count) == 0) {
85
  $promoToSend = $this->GetPromoAlert();
86
  if (!empty($promoToSend)) {
87
+ $link = '<a href="'.$promoToSend['link'].'" target="_blank">Upgrade Now</a>';
88
  $this->Log(9999, array(
89
  'ClientIP' => '127.0.0.1',
90
  'Username' => 'Plugin',
118
  private function GetActivePromoText()
119
  {
120
  $aPromoAlerts = array();
121
+ $aPromoAlerts[] = array(
122
+ 'name' => 'Upgrade to Premium',
123
+ 'message' => 'Add email alerts, see who is logged in, generate reports, add search and other functionality by upgrading to Premium for just $89. <strong>%s</strong>',
124
+ 'link' => 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=auditviewer&utm_medium=promoalert&utm_campaign=plugin'
125
+ );
126
+ $aPromoAlerts[] = array(
127
+ 'name' => 'Get 70% Discount When You Upgrade to Premium',
128
+ 'message' => 'Benefit from a discount of 70&percnt; upgrade to premium for just $89 and add <strong>Email Alerts</strong>, <strong>User Logins Management</strong>, <strong>Search</strong> and <strong>Reporting</strong> functionality to the plugin. <strong>%s</strong>',
129
+ 'link' => 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=auditviewer&utm_medium=promoalert&utm_campaign=plugin'
130
+ );
131
+ $aPromoAlerts[] = array(
132
+ 'name' => 'Add Email Alerts, Search, Generate Reports and See Who is Logged In',
133
+ 'message' => 'Upgrade to premium and extend the plugin’s features with email alerts, report generator, free-text based search and user logins and sessions management. Benefit from a 70&percnt; discount. Prices starts at just $89 <strong>%s</strong>',
134
+ 'link' => 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=auditviewer&utm_medium=promoalert&utm_campaign=plugin'
135
+ );
136
+ return $aPromoAlerts;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
 
139
  private function CheckPromoToShow()
140
  {
141
  $promoToShow = null;
142
+ // Check: Email Add-On, Search Add-On, Reports Add-On, External DB Add-On, Manage Users Sessions Add-on
143
  if (!class_exists('WSAL_NP_Plugin')) {
144
  $promoToShow[] = true;
145
  }
152
  if (!class_exists('WSAL_Ext_Plugin')) {
153
  $promoToShow[] = true;
154
  }
155
+ if (!class_exists('WSAL_User_Management_Plugin')) {
156
+ $promoToShow[] = true;
157
+ }
158
 
159
  if (empty($promoToShow)) {
160
  return null;
161
  }
162
+ return (count($promoToShow) == 5) ? 80 : null;
163
  }
164
  }
classes/Models/ActiveRecord.php CHANGED
@@ -1,280 +1,280 @@
1
- <?php
2
- require_once(__DIR__ . '/../Connector/ConnectorFactory.php');
3
-
4
- abstract class WSAL_Models_ActiveRecord
5
- {
6
-
7
- /**
8
- * @var_$connector Data connector;
9
- */
10
- protected $connector;
11
-
12
- protected $id = false;
13
-
14
- protected $adapterName = null;
15
-
16
- protected $useDefaultAdapter = false;
17
-
18
- /**
19
- * @return array Returns this records' fields.
20
- */
21
- public function GetFields()
22
- {
23
- if(!isset($this->_column_cache)){
24
- $this->_column_cache = array();
25
- foreach(array_keys(get_object_vars($this)) as $col)
26
- if(trim($col) && $col[0] != '_')
27
- $this->_column_cache[] = $col;
28
- }
29
- return $this->_column_cache;
30
- }
31
-
32
- public function setId($id)
33
- {
34
- $this->id = $id;
35
- }
36
-
37
- public function getId()
38
- {
39
- return $this->id;
40
- }
41
-
42
- const STATE_UNKNOWN = 'unknown';
43
- const STATE_CREATED = 'created';
44
- const STATE_UPDATED = 'updated';
45
- const STATE_DELETED = 'deleted';
46
- const STATE_LOADED = 'loaded';
47
-
48
- protected $_state = self::STATE_UNKNOWN;
49
-
50
- public function __construct($data = null)
51
- {
52
- if (!$this->adapterName) {
53
- throw new Exception('Class "' . __CLASS__ . '" requires "adapterName" to be set.');
54
- }
55
- if (!is_null($data)) {
56
- $this->LoadData($data);
57
- $this->_state = self::STATE_LOADED;
58
- }
59
- }
60
-
61
- protected function getConnector()
62
- {
63
- if (!empty($this->connector)) {
64
- return $this->connector;
65
- }
66
- if ($this->useDefaultAdapter) {
67
- $this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
68
- } else {
69
- $this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
70
- }
71
- return $this->connector;
72
- }
73
-
74
- public function getAdapter()
75
- {
76
- return $this->getConnector()->getAdapter($this->adapterName);
77
- }
78
-
79
-
80
- /**
81
- * Load record from DB.
82
- * @param string $cond (Optional) Load condition.
83
- * @param array $args (Optional) Load condition arguments.
84
- */
85
- public function Load($cond = '%d', $args = array(1)){
86
- $this->_state = self::STATE_UNKNOWN;
87
-
88
- $data = $this->getAdapter()->Load($cond, $args);
89
- if(!is_null($data)){
90
- $this->LoadData($data);
91
- $this->_state = self::STATE_LOADED;
92
- }
93
- }
94
-
95
- /**
96
- * Load object data from variable.
97
- * @param array|object $data Data array or object.
98
- */
99
- public function LoadData($data){
100
- $copy = get_class($this);
101
- $copy = new $copy;
102
- foreach ((array)$data as $key => $val) {
103
- if (isset($copy->$key)) {
104
- switch (true) {
105
- case $this->is_ip_address($val):
106
- $this->$key = (string)$val;
107
- break;
108
- case is_array($copy->$key):
109
- case is_object($copy->$key):
110
- $jsonDecodedVal = WSAL_Helpers_DataHelper::JsonDecode($val);
111
- $this->$key = ($jsonDecodedVal == null) ? $val : $jsonDecodedVal;
112
- break;
113
- case is_int($copy->$key):
114
- $this->$key = (int)$val;
115
- break;
116
- case is_float($copy->$key):
117
- $this->$key = (float)$val;
118
- break;
119
- case is_bool($copy->$key):
120
- $this->$key = (bool)$val;
121
- break;
122
- case is_string($copy->$key):
123
- $this->$key = (string)$val;
124
- break;
125
- default:
126
- throw new Exception('Unsupported type "'.gettype($copy->$key).'"');
127
- }
128
- }
129
- }
130
- return $this;
131
- }
132
-
133
- /**
134
- * Save this active record
135
- * @return integer|boolean Either the number of modified/inserted rows or false on failure.
136
- */
137
- public function Save()
138
- {
139
- $this->_state = self::STATE_UNKNOWN;
140
-
141
- // use today's date if not set up
142
- if (is_null($this->created_on)) {
143
- $this->created_on = $this->GetMicrotime();
144
- }
145
- $updateId = $this->getId();
146
- $result = $this->getAdapter()->Save($this);
147
-
148
- if ($result !== false) {
149
- $this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
150
- }
151
- return $result;
152
- }
153
-
154
- /**
155
- * Deletes this active record
156
- */
157
- public function Delete()
158
- {
159
- $this->_state = self::STATE_UNKNOWN;
160
- $result = $this->getAdapter()->Delete($this);
161
- if($result !== false)
162
- $this->_state = self::STATE_DELETED;
163
-
164
- return $result;
165
- }
166
-
167
- public function Count($cond = '%d', $args = array(1)) {
168
- $result = $this->getAdapter()->Count($cond, $args);
169
- return $result;
170
- }
171
-
172
- /**
173
- * @return boolean
174
- */
175
- public function IsLoaded(){
176
- return $this->_state == self::STATE_LOADED;
177
- }
178
-
179
- /**
180
- * @return boolean
181
- */
182
- public function IsSaved(){
183
- return $this->_state == self::STATE_CREATED
184
- || $this->_state == self::STATE_UPDATED;
185
- }
186
-
187
- /**
188
- * @return boolean
189
- */
190
- public function IsCreated(){
191
- return $this->_state == self::STATE_CREATED;
192
- }
193
-
194
- /**
195
- * @return boolean
196
- */
197
- public function IsUpdated()
198
- {
199
- return $this->_state == self::STATE_UPDATED;
200
- }
201
-
202
- /**
203
- * @return boolean
204
- */
205
- public function IsInstalled()
206
- {
207
- return $this->getAdapter()->IsInstalled();
208
- }
209
-
210
- public function Install()
211
- {
212
- return $this->getAdapter()->Install();
213
- }
214
-
215
- /**
216
- * @return boolean
217
- */
218
- public function IsDeleted()
219
- {
220
- return $this->_state == self::STATE_DELETED;
221
- }
222
-
223
- protected static $_cache = array();
224
-
225
- /**
226
- * Load ActiveRecord from DB or cache.
227
- * @param string $target ActiveRecord class name.
228
- * @param string $query Load condition.
229
- * @param array $args Arguments used in condition.
230
- * @return WSAL_Models_ActiveRecord
231
- */
232
- protected static function CacheLoad($target, $query, $args){
233
- $index = $target . '::' . vsprintf($query, $args);
234
- if(!isset(self::$_cache[$index])){
235
- self::$_cache[$index] = new $target();
236
- self::$_cache[$index]->Load($query, $args);
237
- }
238
- return self::$_cache[$index];
239
- }
240
-
241
- /**
242
- * Remove ActiveRecord cache.
243
- * @param string $target ActiveRecord class name.
244
- * @param string $query Load condition.
245
- * @param array $args Arguments used in condition.
246
- */
247
- protected static function CacheRemove($target, $query, $args){
248
- $index = $target . '::' . sprintf($query, $args);
249
- if(!isset(self::$_cache[$index])){
250
- unset(self::$_cache[$index]);
251
- }
252
- }
253
-
254
- /**
255
- * Clear the cache.
256
- */
257
- protected static function CacheClear()
258
- {
259
- self::$_cache = array();
260
- }
261
-
262
- /**
263
- * Function used in WSAL reporting extension
264
- */
265
- public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp)
266
- {
267
- return $this->getAdapter()->GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp);
268
- }
269
-
270
- /**
271
- * Check if the float is IPv4 instead
272
- */
273
- private function is_ip_address($ip_address)
274
- {
275
- if (filter_var($ip_address, FILTER_VALIDATE_IP) !== false) {
276
- return true;
277
- }
278
- return false;
279
- }
280
- }
1
+ <?php
2
+ //require_once(__DIR__ . '/../Connector/ConnectorFactory.php');
3
+
4
+ abstract class WSAL_Models_ActiveRecord
5
+ {
6
+
7
+ /**
8
+ * @var_$connector Data connector;
9
+ */
10
+ protected $connector;
11
+
12
+ protected $id = false;
13
+
14
+ protected $adapterName = null;
15
+
16
+ protected $useDefaultAdapter = false;
17
+
18
+ /**
19
+ * @return array Returns this records' fields.
20
+ */
21
+ public function GetFields()
22
+ {
23
+ if(!isset($this->_column_cache)){
24
+ $this->_column_cache = array();
25
+ foreach(array_keys(get_object_vars($this)) as $col)
26
+ if(trim($col) && $col[0] != '_')
27
+ $this->_column_cache[] = $col;
28
+ }
29
+ return $this->_column_cache;
30
+ }
31
+
32
+ public function setId($id)
33
+ {
34
+ $this->id = $id;
35
+ }
36
+
37
+ public function getId()
38
+ {
39
+ return $this->id;
40
+ }
41
+
42
+ const STATE_UNKNOWN = 'unknown';
43
+ const STATE_CREATED = 'created';
44
+ const STATE_UPDATED = 'updated';
45
+ const STATE_DELETED = 'deleted';
46
+ const STATE_LOADED = 'loaded';
47
+
48
+ protected $_state = self::STATE_UNKNOWN;
49
+
50
+ public function __construct($data = null)
51
+ {
52
+ if (!$this->adapterName) {
53
+ throw new Exception('Class "' . __CLASS__ . '" requires "adapterName" to be set.');
54
+ }
55
+ if (!is_null($data)) {
56
+ $this->LoadData($data);
57
+ $this->_state = self::STATE_LOADED;
58
+ }
59
+ }
60
+
61
+ protected function getConnector()
62
+ {
63
+ if (!empty($this->connector)) {
64
+ return $this->connector;
65
+ }
66
+ if ($this->useDefaultAdapter) {
67
+ $this->connector = WSAL_Connector_ConnectorFactory::GetDefaultConnector();
68
+ } else {
69
+ $this->connector = WSAL_Connector_ConnectorFactory::GetConnector();
70
+ }
71
+ return $this->connector;
72
+ }
73
+
74
+ public function getAdapter()
75
+ {
76
+ return $this->getConnector()->getAdapter($this->adapterName);
77
+ }
78
+
79
+
80
+ /**
81
+ * Load record from DB.
82
+ * @param string $cond (Optional) Load condition.
83
+ * @param array $args (Optional) Load condition arguments.
84
+ */
85
+ public function Load($cond = '%d', $args = array(1)){
86
+ $this->_state = self::STATE_UNKNOWN;
87
+
88
+ $data = $this->getAdapter()->Load($cond, $args);
89
+ if(!is_null($data)){
90
+ $this->LoadData($data);
91
+ $this->_state = self::STATE_LOADED;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Load object data from variable.
97
+ * @param array|object $data Data array or object.
98
+ */
99
+ public function LoadData($data){
100
+ $copy = get_class($this);
101
+ $copy = new $copy;
102
+ foreach ((array)$data as $key => $val) {
103
+ if (isset($copy->$key)) {
104
+ switch (true) {
105
+ case $this->is_ip_address($val):
106
+ $this->$key = (string)$val;
107
+ break;
108
+ case is_array($copy->$key):
109
+ case is_object($copy->$key):
110
+ $jsonDecodedVal = WSAL_Helpers_DataHelper::JsonDecode($val);
111
+ $this->$key = ($jsonDecodedVal == null) ? $val : $jsonDecodedVal;
112
+ break;
113
+ case is_int($copy->$key):
114
+ $this->$key = (int)$val;
115
+ break;
116
+ case is_float($copy->$key):
117
+ $this->$key = (float)$val;
118
+ break;
119
+ case is_bool($copy->$key):
120
+ $this->$key = (bool)$val;
121
+ break;
122
+ case is_string($copy->$key):
123
+ $this->$key = (string)$val;
124
+ break;
125
+ default:
126
+ throw new Exception('Unsupported type "'.gettype($copy->$key).'"');
127
+ }
128
+ }
129
+ }
130
+ return $this;
131
+ }
132
+
133
+ /**
134
+ * Save this active record
135
+ * @return integer|boolean Either the number of modified/inserted rows or false on failure.
136
+ */
137
+ public function Save()
138
+ {
139
+ $this->_state = self::STATE_UNKNOWN;
140
+
141
+ // use today's date if not set up
142
+ if (is_null($this->created_on)) {
143
+ $this->created_on = $this->GetMicrotime();
144
+ }
145
+ $updateId = $this->getId();
146
+ $result = $this->getAdapter()->Save($this);
147
+
148
+ if ($result !== false) {
149
+ $this->_state = (!empty($updateId))?self::STATE_UPDATED:self::STATE_CREATED;
150
+ }
151
+ return $result;
152
+ }
153
+
154
+ /**
155
+ * Deletes this active record
156
+ */
157
+ public function Delete()
158
+ {
159
+ $this->_state = self::STATE_UNKNOWN;
160
+ $result = $this->getAdapter()->Delete($this);
161
+ if($result !== false)
162
+ $this->_state = self::STATE_DELETED;
163
+
164
+ return $result;
165
+ }
166
+
167
+ public function Count($cond = '%d', $args = array(1)) {
168
+ $result = $this->getAdapter()->Count($cond, $args);
169
+ return $result;
170
+ }
171
+
172
+ /**
173
+ * @return boolean
174
+ */
175
+ public function IsLoaded(){
176
+ return $this->_state == self::STATE_LOADED;
177
+ }
178
+
179
+ /**
180
+ * @return boolean
181
+ */
182
+ public function IsSaved(){
183
+ return $this->_state == self::STATE_CREATED
184
+ || $this->_state == self::STATE_UPDATED;
185
+ }
186
+
187
+ /**
188
+ * @return boolean
189
+ */
190
+ public function IsCreated(){
191
+ return $this->_state == self::STATE_CREATED;
192
+ }
193
+
194
+ /**
195
+ * @return boolean
196
+ */
197
+ public function IsUpdated()
198
+ {
199
+ return $this->_state == self::STATE_UPDATED;
200
+ }
201
+
202
+ /**
203
+ * @return boolean
204
+ */
205
+ public function IsInstalled()
206
+ {
207
+ return $this->getAdapter()->IsInstalled();
208
+ }
209
+
210
+ public function Install()
211
+ {
212
+ return $this->getAdapter()->Install();
213
+ }
214
+
215
+ /**
216
+ * @return boolean
217
+ */
218
+ public function IsDeleted()
219
+ {
220
+ return $this->_state == self::STATE_DELETED;
221
+ }
222
+
223
+ protected static $_cache = array();
224
+
225
+ /**
226
+ * Load ActiveRecord from DB or cache.
227
+ * @param string $target ActiveRecord class name.
228
+ * @param string $query Load condition.
229
+ * @param array $args Arguments used in condition.
230
+ * @return WSAL_Models_ActiveRecord
231
+ */
232
+ protected static function CacheLoad($target, $query, $args){
233
+ $index = $target . '::' . vsprintf($query, $args);
234
+ if(!isset(self::$_cache[$index])){
235
+ self::$_cache[$index] = new $target();
236
+ self::$_cache[$index]->Load($query, $args);
237
+ }
238
+ return self::$_cache[$index];
239
+ }
240
+
241
+ /**
242
+ * Remove ActiveRecord cache.
243
+ * @param string $target ActiveRecord class name.
244
+ * @param string $query Load condition.
245
+ * @param array $args Arguments used in condition.
246
+ */
247
+ protected static function CacheRemove($target, $query, $args){
248
+ $index = $target . '::' . sprintf($query, $args);
249
+ if(!isset(self::$_cache[$index])){
250
+ unset(self::$_cache[$index]);
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Clear the cache.
256
+ */
257
+ protected static function CacheClear()
258
+ {
259
+ self::$_cache = array();
260
+ }
261
+
262
+ /**
263
+ * Function used in WSAL reporting extension
264
+ */
265
+ public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp)
266
+ {
267
+ return $this->getAdapter()->GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp);
268
+ }
269
+
270
+ /**
271
+ * Check if the float is IPv4 instead
272
+ */
273
+ private function is_ip_address($ip_address)
274
+ {
275
+ if (filter_var($ip_address, FILTER_VALIDATE_IP) !== false) {
276
+ return true;
277
+ }
278
+ return false;
279
+ }
280
+ }
classes/Models/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,204 @@
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
+
200
+ public function CheckAlert404($args = array())
201
+ {
202
+ return $this->getAdapter()->CheckAlert404($args);
203
+ }
204
+ }
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,455 @@
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
+ $editorLink = $this->GetEditorLink($new_post);
135
+ if ($new_post->post_status == 'publish') {
136
+ switch ($old_post->post_type) {
137
+ case 'forum':
138
+ $this->plugin->alerts->Trigger(8000, array(
139
+ 'ForumName' => $new_post->post_title,
140
+ 'ForumURL' => get_permalink($new_post->ID),
141
+ $editorLink['name'] => $editorLink['value']
142
+ ));
143
+ break;
144
+ case 'topic':
145
+ $this->plugin->alerts->Trigger(8014, array(
146
+ 'TopicName' => $new_post->post_title,
147
+ 'TopicURL' => get_permalink($new_post->ID),
148
+ $editorLink['name'] => $editorLink['value']
149
+ ));
150
+ break;
151
+ }
152
+ return 1;
153
+ }
154
+ }
155
+ return 0;
156
+ }
157
+
158
+ private function EventForumChangedVisibility($post)
159
+ {
160
+ $result = 0;
161
+ $editorLink = $this->GetEditorLink($post);
162
+ switch ($post->post_type) {
163
+ case 'forum':
164
+ $oldVisibility = !empty($_REQUEST['visibility']) ? $_REQUEST['visibility'] : '';
165
+ $newVisibility = !empty($_REQUEST['bbp_forum_visibility']) ? $_REQUEST['bbp_forum_visibility'] : '';
166
+ $newVisibility = ($newVisibility == 'publish') ? 'public' : $newVisibility;
167
+
168
+ if (!empty($newVisibility) && $oldVisibility != 'auto-draft' && $oldVisibility != $newVisibility) {
169
+ $this->plugin->alerts->Trigger(8002, array(
170
+ 'ForumName' => $post->post_title,
171
+ 'OldVisibility' => $oldVisibility,
172
+ 'NewVisibility' => $newVisibility,
173
+ $editorLink['name'] => $editorLink['value']
174
+ ));
175
+ $result = 1;
176
+ }
177
+ break;
178
+ case 'topic':
179
+ $oldVisibility = !empty($_REQUEST['hidden_post_visibility']) ? $_REQUEST['hidden_post_visibility'] : '';
180
+ $newVisibility = !empty($_REQUEST['visibility']) ? $_REQUEST['visibility'] : '';
181
+ $newVisibility = ($newVisibility == 'password') ? 'password protected' : $newVisibility;
182
+
183
+ if (!empty($newVisibility) && $oldVisibility != 'auto-draft' && $oldVisibility != $newVisibility) {
184
+ $this->plugin->alerts->Trigger(8022, array(
185
+ 'TopicName' => $post->post_title,
186
+ 'OldVisibility' => $oldVisibility,
187
+ 'NewVisibility' => $newVisibility,
188
+ $editorLink['name'] => $editorLink['value']
189
+ ));
190
+ $result = 1;
191
+ }
192
+ break;
193
+ }
194
+ return $result;
195
+ }
196
+
197
+ private function EventForumChangedType($post)
198
+ {
199
+ $result = 0;
200
+ $editorLink = $this->GetEditorLink($post);
201
+ switch ($post->post_type) {
202
+ case 'forum':
203
+ $bbp_forum_type = get_post_meta($post->ID, '_bbp_forum_type', true);
204
+ $oldType = !empty($bbp_forum_type) ? $bbp_forum_type : 'forum';
205
+ $newType = !empty($_POST['bbp_forum_type']) ? $_POST['bbp_forum_type'] : '';
206
+ if (!empty($newType) && $oldType != $newType) {
207
+ $this->plugin->alerts->Trigger(8011, array(
208
+ 'ForumName' => $post->post_title,
209
+ 'OldType' => $oldType,
210
+ 'NewType' => $newType,
211
+ $editorLink['name'] => $editorLink['value']
212
+ ));
213
+ $result = 1;
214
+ }
215
+ break;
216
+ case 'topic':
217
+ if (!empty($_POST['parent_id'])) {
218
+ $post_id = $_POST['parent_id'];
219
+ } else {
220
+ $post_id = $post->ID;
221
+ }
222
+ $bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
223
+ $fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
224
+ $bbp_super_sticky_topics = maybe_unserialize($fn('_bbp_super_sticky_topics'));
225
+ if (!empty($bbp_sticky_topics) && in_array($post->ID, $bbp_sticky_topics)) {
226
+ $oldType = 'sticky';
227
+ } elseif (!empty($bbp_super_sticky_topics) && in_array($post->ID, $bbp_super_sticky_topics)) {
228
+ $oldType = 'super';
229
+ } else {
230
+ $oldType = 'unstick';
231
+ }
232
+ $newType = !empty($_POST['bbp_stick_topic']) ? $_POST['bbp_stick_topic'] : '';
233
+ if (!empty($newType) && $oldType != $newType) {
234
+ $this->plugin->alerts->Trigger(8016, array(
235
+ 'TopicName' => $post->post_title,
236
+ 'OldType' => ($oldType == 'unstick') ? 'normal' : (($oldType == 'super') ? 'super sticky' : $oldType),
237
+ 'NewType' => ($newType == 'unstick') ? 'normal' : (($newType == 'super') ? 'super sticky' : $newType),
238
+ $editorLink['name'] => $editorLink['value']
239
+ ));
240
+ $result = 1;
241
+ }
242
+ break;
243
+ }
244
+ return $result;
245
+ }
246
+
247
+ private function EventForumChangedStatus($post)
248
+ {
249
+ $result = 0;
250
+ $editorLink = $this->GetEditorLink($post);
251
+ switch ($post->post_type) {
252
+ case 'forum':
253
+ $bbp_status = get_post_meta($post->ID, '_bbp_status', true);
254
+ $oldStatus = !empty($bbp_status) ? $bbp_status : 'open';
255
+ $newStatus = !empty($_REQUEST['bbp_forum_status']) ? $_REQUEST['bbp_forum_status'] : '';
256
+ if (!empty($newStatus) && $oldStatus != $newStatus) {
257
+ $this->plugin->alerts->Trigger(8001, array(
258
+ 'ForumName' => $post->post_title,
259
+ 'OldStatus' => $oldStatus,
260
+ 'NewStatus' => $newStatus,
261
+ $editorLink['name'] => $editorLink['value']
262
+ ));
263
+ $result = 1;
264
+ }
265
+ break;
266
+ case 'topic':
267
+ $oldStatus = !empty($_REQUEST['original_post_status']) ? $_REQUEST['original_post_status'] : '';
268
+ $newStatus = !empty($_REQUEST['post_status']) ? $_REQUEST['post_status'] : '';
269
+ // In case of Ajax request Spam/Not spam
270
+ if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_spam') {
271
+ $oldStatus = $post->post_status;
272
+ $newStatus = 'spam';
273
+ if (isset($_GET['post_status']) && $_GET['post_status'] == 'spam') {
274
+ $newStatus = 'publish';
275
+ }
276
+ }
277
+ // In case of Ajax request Close/Open
278
+ if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_close') {
279
+ $oldStatus = $post->post_status;
280
+ $newStatus = 'closed';
281
+ if (isset($_GET['post_status']) && $_GET['post_status'] == 'closed') {
282
+ $newStatus = 'publish';
283
+ }
284
+ }
285
+ if (!empty($newStatus) && $oldStatus != $newStatus) {
286
+ $this->plugin->alerts->Trigger(8015, array(
287
+ 'TopicName' => $post->post_title,
288
+ 'OldStatus' => ($oldStatus == 'publish') ? 'open' : $oldStatus,
289
+ 'NewStatus' => ($newStatus == 'publish') ? 'open' : $newStatus,
290
+ $editorLink['name'] => $editorLink['value']
291
+ ));
292
+ $result = 1;
293
+ }
294
+ break;
295
+ }
296
+ return $result;
297
+ }
298
+
299
+ private function EventForumChanged($old_post, $new_post)
300
+ {
301
+ $editorLink = $this->GetEditorLink($new_post);
302
+ // Changed Order
303
+ if ($old_post->menu_order != $new_post->menu_order) {
304
+ $this->plugin->alerts->Trigger(8004, array(
305
+ 'ForumName' => $new_post->post_title,
306
+ 'OldOrder' => $old_post->menu_order,
307
+ 'NewOrder' => $new_post->menu_order,
308
+ $editorLink['name'] => $editorLink['value']
309
+ ));
310
+ return 1;
311
+ }
312
+ // Changed Parent
313
+ if ($old_post->post_parent != $new_post->post_parent) {
314
+ switch ($old_post->post_type) {
315
+ case 'forum':
316
+ $this->plugin->alerts->Trigger(8008, array(
317
+ 'ForumName' => $new_post->post_title,
318
+ 'OldParent' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
319
+ 'NewParent' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent',
320
+ $editorLink['name'] => $editorLink['value']
321
+ ));
322
+ break;
323
+ case 'topic':
324
+ $this->plugin->alerts->Trigger(8018, array(
325
+ 'TopicName' => $new_post->post_title,
326
+ 'OldForum' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
327
+ 'NewForum' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent',
328
+ $editorLink['name'] => $editorLink['value']
329
+ ));
330
+ break;
331
+ }
332
+ return 1;
333
+ }
334
+ // Changed URL
335
+ $oldLink = $this->_OldLink;
336
+ $newLink = get_permalink($new_post->ID);
337
+ if (!empty($oldLink) && $oldLink != $newLink) {
338
+ switch ($old_post->post_type) {
339
+ case 'forum':
340
+ $this->plugin->alerts->Trigger(8003, array(
341
+ 'ForumName' => $new_post->post_title,
342
+ 'OldUrl' => $oldLink,
343
+ 'NewUrl' => $newLink,
344
+ $editorLink['name'] => $editorLink['value']
345
+ ));
346
+ break;
347
+ case 'topic':
348
+ $this->plugin->alerts->Trigger(8017, array(
349
+ 'TopicName' => $new_post->post_title,
350
+ 'OldUrl' => $oldLink,
351
+ 'NewUrl' => $newLink,
352
+ $editorLink['name'] => $editorLink['value']
353
+ ));
354
+ break;
355
+ }
356
+ return 1;
357
+ }
358
+ return 0;
359
+ }
360
+
361
+ private function EventForumByCode($post, $event)
362
+ {
363
+ $editorLink = $this->GetEditorLink($post);
364
+ $this->plugin->alerts->Trigger($event, array(
365
+ 'ForumID' => $post->ID,
366
+ 'ForumName' => $post->post_title,
367
+ $editorLink['name'] => $editorLink['value']
368
+ ));
369
+ }
370
+
371
+ private function EventTopicByCode($post, $event)
372
+ {
373
+ $editorLink = $this->GetEditorLink($post);
374
+ $this->plugin->alerts->Trigger($event, array(
375
+ 'TopicID' => $post->ID,
376
+ 'TopicName' => $post->post_title,
377
+ $editorLink['name'] => $editorLink['value']
378
+ ));
379
+ }
380
+
381
+ /**
382
+ * Trigger of ajax events generated in the Topic Grid
383
+ */
384
+ public function TriggerAjaxChange()
385
+ {
386
+ if (!empty($_GET['post_type']) && !empty($_GET['topic_id'])) {
387
+ if ($_GET['post_type'] == 'topic') {
388
+ $post = get_post($_GET['topic_id']);
389
+
390
+ // Topic type
391
+ if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_stick') {
392
+ if (!empty($post->post_parent)) {
393
+ $post_id = $post->post_parent;
394
+ } else {
395
+ $post_id = $_GET['topic_id'];
396
+ }
397
+
398
+ $bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
399
+ $fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
400
+ $bbp_super_sticky_topics = maybe_unserialize($fn('_bbp_super_sticky_topics'));
401
+ if (!empty($bbp_sticky_topics) && in_array($_GET['topic_id'], $bbp_sticky_topics)) {
402
+ $oldType = 'sticky';
403
+ } elseif (!empty($bbp_super_sticky_topics) && in_array($_GET['topic_id'], $bbp_super_sticky_topics)) {
404
+ $oldType = 'super sticky';
405
+ } else {
406
+ $oldType = 'normal';
407
+ }
408
+
409
+ switch ($oldType) {
410
+ case 'sticky':
411
+ case 'super sticky':
412
+ $newType = 'normal';
413
+ break;
414
+ case 'normal':
415
+ if (isset($_GET['super']) && $_GET['super'] == 1) {
416
+ $newType = 'super sticky';
417
+ } else {
418
+ $newType = 'sticky';
419
+ }
420
+ break;
421
+ }
422
+ $editorLink = $this->GetEditorLink($post);
423
+
424
+ if (!empty($newType) && $oldType != $newType) {
425
+ $this->plugin->alerts->Trigger(8016, array(
426
+ 'TopicName' => $post->post_title,
427
+ 'OldType' => $oldType,
428
+ 'NewType' => $newType,
429
+ $editorLink['name'] => $editorLink['value']
430
+ ));
431
+ }
432
+ }
433
+ }
434
+ }
435
+ }
436
+
437
+ private function GetEditorLink($post)
438
+ {
439
+ $name = 'EditorLink';
440
+ switch ($post->post_type) {
441
+ case 'forum':
442
+ $name .= 'Forum' ;
443
+ break;
444
+ case 'topic':
445
+ $name .= 'Topic' ;
446
+ break;
447
+ }
448
+ $value = get_edit_post_link($post->ID);
449
+ $aLink = array(
450
+ 'name' => $name,
451
+ 'value' => $value,
452
+ );
453
+ return $aLink;
454
+ }
455
+ }
classes/Sensors/Comments.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Sensors_Comments extends WSAL_AbstractSensor
4
+ {
5
+
6
+ public function HookEvents()
7
+ {
8
+ add_action('edit_comment', array($this, 'EventCommentEdit'), 10, 1);
9
+ add_action('transition_comment_status', array($this, 'EventCommentApprove'), 10, 3);
10
+ add_action('spammed_comment', array($this, 'EventCommentSpam'), 10, 1);
11
+ add_action('unspammed_comment', array($this, 'EventCommentUnspam'), 10, 1);
12
+ add_action('trashed_comment', array($this, 'EventCommentTrash'), 10, 1);
13
+ add_action('untrashed_comment', array($this, 'EventCommentUntrash'), 10, 1);
14
+ add_action('deleted_comment', array($this, 'EventCommentDeleted'), 10, 1);
15
+ add_action('comment_post', array($this, 'EventComment'), 10, 2);
16
+ }
17
+
18
+ public function EventCommentEdit($comment_ID)
19
+ {
20
+ $comment = get_comment($comment_ID);
21
+ $this->EventGeneric($comment_ID, 2093);
22
+ }
23
+
24
+ public function EventCommentApprove($new_status, $old_status, $comment)
25
+ {
26
+ if (!empty($comment) && $old_status != $new_status) {
27
+ $post = get_post($comment->comment_post_ID);
28
+ $comment_link = get_permalink($post->ID) . "#comment-" . $comment->comment_ID;
29
+ $fields = array(
30
+ 'PostTitle' => $post->post_title,
31
+ 'Author' => $comment->comment_author,
32
+ 'Date' => $comment->comment_date,
33
+ 'CommentLink' => '<a target="_blank" href="' . $comment_link . '">' . $comment->comment_date . '</a>'
34
+ );
35
+
36
+ if ($new_status == 'approved') {
37
+ $this->plugin->alerts->Trigger(2090, $fields);
38
+ }
39
+ if ($new_status == 'unapproved') {
40
+ $this->plugin->alerts->Trigger(2091, $fields);
41
+ }
42
+ }
43
+ }
44
+
45
+ public function EventCommentSpam($comment_ID)
46
+ {
47
+ $this->EventGeneric($comment_ID, 2094);
48
+ }
49
+
50
+ public function EventCommentUnspam($comment_ID)
51
+ {
52
+ $this->EventGeneric($comment_ID, 2095);
53
+ }
54
+
55
+ public function EventCommentTrash($comment_ID)
56
+ {
57
+ $this->EventGeneric($comment_ID, 2096);
58
+ }
59
+
60
+ public function EventCommentUntrash($comment_ID)
61
+ {
62
+ $this->EventGeneric($comment_ID, 2097);
63
+ }
64
+
65
+ public function EventCommentDeleted($comment_ID)
66
+ {
67
+ $this->EventGeneric($comment_ID, 2098);
68
+ }
69
+
70
+ /**
71
+ * Fires immediately after a comment is inserted into the database.
72
+ * @param int $comment_ID The comment ID.
73
+ * @param int|string $comment_approved 1 if the comment is approved, 0 if not, 'spam' if spam.
74
+ */
75
+ public function EventComment($comment_ID, $comment_approved)
76
+ {
77
+ if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'replyto-comment') {
78
+ $this->EventGeneric($comment_ID, 2092);
79
+ }
80
+ if (isset($_REQUEST['comment'])) {
81
+ $comment = get_comment($comment_ID);
82
+ if (!empty($comment)) {
83
+ $post = get_post($comment->comment_post_ID);
84
+ $comment_link = get_permalink($post->ID) . "#comment-" . $comment_ID;
85
+ $fields = array(
86
+ 'Date' => $comment->comment_date,
87
+ 'CommentLink' => '<a target="_blank" href="' . $comment_link . '">' . $comment->comment_date . '</a>'
88
+ );
89
+ if (!username_exists($comment->comment_author)) {
90
+ $fields['CommentMsg'] = sprintf("A comment was posted in response to the post <strong>%s</strong>. The comment was posted by <strong>%s</strong>", $post->post_title, $this->CheckAuthor($comment));
91
+ $fields['Username'] = "Website Visitor";
92
+ } else {
93
+ $fields['CommentMsg'] = sprintf("Posted a comment in response to the post <strong>%s</strong>", $post->post_title);
94
+ }
95
+
96
+ $this->plugin->alerts->Trigger(2099, $fields);
97
+ }
98
+ }
99
+ }
100
+
101
+ private function EventGeneric($comment_ID, $alert_code)
102
+ {
103
+ $comment = get_comment($comment_ID);
104
+ if (!empty($comment)) {
105
+ $post = get_post($comment->comment_post_ID);
106
+ $comment_link = get_permalink($post->ID) . "#comment-" . $comment_ID;
107
+ $fields = array(
108
+ 'PostTitle' => $post->post_title,
109
+ 'Author' => $comment->comment_author,
110
+ 'Date' => $comment->comment_date,
111
+ 'CommentLink' => '<a target="_blank" href="' . $comment_link . '">' . $comment->comment_date . '</a>'
112
+ );
113
+
114
+ $this->plugin->alerts->Trigger($alert_code, $fields);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Shows the username if the comment is owned by a user
120
+ * and the email if the comment was posted by a non WordPress user
121
+ */
122
+ private function CheckAuthor($comment)
123
+ {
124
+ if (username_exists($comment->comment_author)) {
125
+ return $comment->comment_author;
126
+ } else {
127
+ return $comment->comment_author_email;
128
+ }
129
+ }
130
+ }
classes/Sensors/Content.php CHANGED
@@ -1,635 +1,697 @@
1
- <?php
2
-
3
- class WSAL_Sensors_Content extends WSAL_AbstractSensor
4
- {
5
-
6
- public function HookEvents()
7
- {
8
- if (current_user_can("edit_posts")) {
9
- add_action('admin_init', array($this, 'EventWordpressInit'));
10
- }
11
- add_action('transition_post_status', array($this, 'EventPostChanged'), 10, 3);
12
- add_action('delete_post', array($this, 'EventPostDeleted'), 10, 1);
13
- add_action('wp_trash_post', array($this, 'EventPostTrashed'), 10, 1);
14
- add_action('untrash_post', array($this, 'EventPostUntrashed'));
15
- add_action('edit_category', array($this, 'EventChangedCategoryParent'));
16
- add_action('save_post', array($this, 'SetRevisionLink'), 10, 3);
17
- add_action('publish_future_post', array($this, 'EventPublishFuture'), 10, 1);
18
- }
19
-
20
- protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
21
- {
22
- switch ($post->post_type) {
23
- case 'page':
24
- return $typePage;
25
- case 'post':
26
- return $typePost;
27
- default:
28
- return $typeCustom;
29
- }
30
- }
31
-
32
- protected $_OldPost = null;
33
- protected $_OldLink = null;
34
- protected $_OldCats = null;
35
- protected $_OldTmpl = null;
36
- protected $_OldStky = null;
37
-
38
- public function EventWordpressInit()
39
- {
40
- // load old data, if applicable
41
- $this->RetrieveOldData();
42
- // check for category changes
43
- $this->CheckCategoryCreation();
44
- $this->CheckCategoryDeletion();
45
- }
46
-
47
- protected function RetrieveOldData()
48
- {
49
- if (isset($_POST) && isset($_POST['post_ID'])
50
- && !(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
51
- && !(isset($_POST['action']) && $_POST['action'] == 'autosave')
52
- ) {
53
- $postID = intval($_POST['post_ID']);
54
- $this->_OldPost = get_post($postID);
55
- $this->_OldLink = get_permalink($postID);
56
- $this->_OldTmpl = $this->GetPostTemplate($this->_OldPost);
57
- $this->_OldCats = $this->GetPostCategories($this->_OldPost);
58
- $this->_OldStky = in_array($postID, get_option('sticky_posts'));
59
- }
60
- }
61
-
62
- protected function GetPostTemplate($post)
63
- {
64
- $id = $post->ID;
65
- $template = get_page_template_slug($id);
66
- $pagename = $post->post_name;
67
-
68
- $templates = array();
69
- if ($template && 0 === validate_file($template)) {
70
- $templates[] = $template;
71
- }
72
- if ($pagename) {
73
- $templates[] = "page-$pagename.php";
74
- }
75
- if ($id) {
76
- $templates[] = "page-$id.php";
77
- }
78
- $templates[] = 'page.php';
79
-
80
- return get_query_template('page', $templates);
81
- }
82
-
83
- protected function GetPostCategories($post)
84
- {
85
- return wp_get_post_categories($post->ID, array('fields' => 'names'));
86
- }
87
-
88
- public function EventPostChanged($newStatus, $oldStatus, $post)
89
- {
90
- // ignorable states
91
- if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
92
- return;
93
- }
94
- if (empty($post->post_type)) {
95
- return;
96
- }
97
- if ($post->post_type == 'revision') {
98
- return;
99
- }
100
-
101
- $original = isset($_POST['original_post_status']) ? $_POST['original_post_status'] : '';
102
-
103
- WSAL_Sensors_Request::SetVars(array(
104
- '$newStatus' => $newStatus,
105
- '$oldStatus' => $oldStatus,
106
- '$original' => $original,
107
- ));
108
- // run checks
109
- if ($this->_OldPost) {
110
- if ($this->CheckBBPress($this->_OldPost)) {
111
- return;
112
- }
113
- if ($oldStatus == 'auto-draft' || $original == 'auto-draft') {
114
- // Handle create post events
115
- $this->CheckPostCreation($this->_OldPost, $post);
116
- } else {
117
- // Handle update post events
118
- $changes = 0
119
- + $this->CheckAuthorChange($this->_OldPost, $post)
120
- + $this->CheckStatusChange($this->_OldPost, $post)
121
- + $this->CheckParentChange($this->_OldPost, $post)
122
- + $this->CheckStickyChange($this->_OldStky, isset($_REQUEST['sticky']), $post)
123
- + $this->CheckVisibilityChange($this->_OldPost, $post, $oldStatus, $newStatus)
124
- + $this->CheckTemplateChange($this->_OldTmpl, $this->GetPostTemplate($post), $post)
125
- + $this->CheckCategoriesChange($this->_OldCats, $this->GetPostCategories($post), $post)
126
- ;
127
- if (!$changes) {
128
- $changes = $this->CheckPermalinkChange($this->_OldLink, get_permalink($post->ID), $post);
129
- }
130
- if (!$changes) {
131
- $changes = $this->CheckModificationChange($post->ID, $this->_OldPost, $post);
132
- }
133
- }
134
- }
135
- }
136
-
137
- protected function CheckPostCreation($oldPost, $newPost)
138
- {
139
- $event = 0;
140
- $is_scheduled = false;
141
- switch ($newPost->post_status) {
142
- case 'publish':
143
- $event = $this->GetEventTypeForPostType($oldPost, 2001, 2005, 2030);
144
- break;
145
- case 'draft':
146
- $event = $this->GetEventTypeForPostType($oldPost, 2000, 2004, 2029);
147
- break;
148
- case 'future':
149
- $event = $this->GetEventTypeForPostType($oldPost, 2074, 2075, 2076);
150
- $is_scheduled = true;
151
- break;
152
- case 'pending':
153
- $event = 2073;
154
- break;
155
- }
156
- if ($event) {
157
- if ($is_scheduled) {
158
- $this->plugin->alerts->Trigger($event, array(
159
- 'PostType' => $newPost->post_type,
160
- 'PostTitle' => $newPost->post_title,
161
- 'PublishingDate' => $newPost->post_date
162
- ));
163
- } else {
164
- $this->plugin->alerts->Trigger($event, array(
165
- 'PostID' => $newPost->ID,
166
- 'PostType' => $newPost->post_type,
167
- 'PostTitle' => $newPost->post_title,
168
- 'PostUrl' => get_permalink($newPost->ID)
169
- ));
170
- }
171
- }
172
- }
173
-
174
- public function EventPublishFuture($post_id)
175
- {
176
- $post = get_post($post_id);
177
- $event = $this->GetEventTypeForPostType($post, 2001, 2005, 2030);
178
-
179
- if ($event) {
180
- $this->plugin->alerts->Trigger($event, array(
181
- 'PostID' => $post->ID,
182
- 'PostType' => $post->post_type,
183
- 'PostTitle' => $post->post_title,
184
- 'PostUrl' => get_permalink($post->ID)
185
- ));
186
- }
187
- }
188
-
189
- protected function CheckCategoryCreation()
190
- {
191
- if (empty($_POST)) {
192
- return;
193
- }
194
- $categoryName = '';
195
- if (!empty($_POST['screen']) && !empty($_POST['tag-name']) &&
196
- $_POST['screen'] == 'edit-category' &&
197
- $_POST['taxonomy'] == 'category' &&
198
- $_POST['action'] == 'add-tag') {
199
- $categoryName = $_POST['tag-name'];
200
- } elseif (!empty($_POST['newcategory']) && $_POST['action'] == 'add-category') {
201
- $categoryName = $_POST['newcategory'];
202
- }
203
-
204
- if ($categoryName) {
205
- $this->plugin->alerts->Trigger(2023, array(
206
- 'CategoryName' => $categoryName,
207
- ));
208
- }
209
- }
210
-
211
- protected function CheckCategoryDeletion()
212
- {
213
- if (empty($_POST)) {
214
- return;
215
- }
216
- $action = !empty($_POST['action']) ? $_POST['action']
217
- : (!empty($_POST['action2']) ? $_POST['action2'] : '');
218
- if (!$action) {
219
- return;
220
- }
221
-
222
- $categoryIds = array();
223
-
224
- if (isset($_POST['taxonomy'])) {
225
- if ($action == 'delete' && $_POST['taxonomy'] == 'category' && !empty($_POST['delete_tags'])) {
226
- // bulk delete
227
- $categoryIds[] = $_POST['delete_tags'];
228
- } elseif ($action == 'delete-tag' && $_POST['taxonomy'] == 'category' && !empty($_POST['tag_ID'])) {
229
- // single delete
230
- $categoryIds[] = $_POST['tag_ID'];
231
- }
232
- }
233
-
234
- foreach ($categoryIds as $categoryID) {
235
- $category = get_category($categoryID);
236
- $this->plugin->alerts->Trigger(2024, array(
237
- 'CategoryID' => $categoryID,
238
- 'CategoryName' => $category->cat_name,
239
- ));
240
- }
241
- }
242
-
243
- public function EventPostDeleted($post_id)
244
- {
245
- $post = get_post($post_id);
246
- if ($this->CheckBBPress($post)) {
247
- return;
248
- }
249
- if (!in_array($post->post_type, array('attachment', 'revision', 'nav_menu_item'))) { // ignore attachments, revisions and menu items
250
- $event = $this->GetEventTypeForPostType($post, 2008, 2009, 2033);
251
- // check WordPress backend operations
252
- if ($this->CheckAutoDraft($event, $post->post_title)) {
253
- return;
254
- }
255
- $this->plugin->alerts->Trigger($event, array(
256
- 'PostID' => $post->ID,
257
- 'PostType' => $post->post_type,
258
- 'PostTitle' => $post->post_title,
259
- ));
260
- }
261
- }
262
-
263
- public function EventPostTrashed($post_id)
264
- {
265
- $post = get_post($post_id);
266
- if ($this->CheckBBPress($post)) {
267
- return;
268
- }
269
- $event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
270
- $this->plugin->alerts->Trigger($event, array(
271
- 'PostID' => $post->ID,
272
- 'PostType' => $post->post_type,
273
- 'PostTitle' => $post->post_title,
274
- ));
275
- }
276
-
277
- public function EventPostUntrashed($post_id)
278
- {
279
- $post = get_post($post_id);
280
- if ($this->CheckBBPress($post)) {
281
- return;
282
- }
283
- $event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
284
- $this->plugin->alerts->Trigger($event, array(
285
- 'PostID' => $post->ID,
286
- 'PostType' => $post->post_type,
287
- 'PostTitle' => $post->post_title,
288
- ));
289
- }
290
-
291
- protected function CheckDateChange($oldpost, $newpost)
292
- {
293
- $from = strtotime($oldpost->post_date);
294
- $to = strtotime($newpost->post_date);
295
- if ($oldpost->post_status == 'draft') {
296
- return 0;
297
- }
298
- $pending = $this->CheckReviewPendingChange($oldpost, $newpost);
299
- if ($pending) {
300
- return 0;
301
- }
302
- if ($from != $to) {
303
- $event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
304
- $this->plugin->alerts->Trigger($event, array(
305
- 'PostID' => $oldpost->ID,
306
- 'PostType' => $oldpost->post_type,
307
- 'PostTitle' => $oldpost->post_title,
308
- 'OldDate' => $oldpost->post_date,
309
- 'NewDate' => $newpost->post_date,
310
- ));
311
- return 1;
312
- }
313
- }
314
-
315
- // Revision used
316
- protected function CheckReviewPendingChange($oldpost, $newpost)
317
- {
318
- if ($oldpost->post_status == 'pending') {
319
- $this->plugin->alerts->Trigger(2072, array(
320
- 'PostID' => $oldpost->ID,
321
- 'PostType' => $oldpost->post_type,
322
- 'PostTitle' => $oldpost->post_title
323
- ));
324
- return 1;
325
- }
326
- return 0;
327
- }
328
-
329
- protected function CheckCategoriesChange($oldCats, $newCats, $post)
330
- {
331
- $oldCats = implode(', ', $oldCats);
332
- $newCats = implode(', ', $newCats);
333
- if ($oldCats != $newCats) {
334
- $event = $this->GetEventTypeForPostType($post, 2016, 0, 2036);
335
- if ($event) {
336
- $this->plugin->alerts->Trigger($event, array(
337
- 'PostID' => $post->ID,
338
- 'PostType' => $post->post_type,
339
- 'PostTitle' => $post->post_title,
340
- 'OldCategories' => $oldCats ? $oldCats : 'no categories',
341
- 'NewCategories' => $newCats ? $newCats : 'no categories',
342
- ));
343
- return 1;
344
- }
345
- }
346
- }
347
-
348
- protected function CheckAuthorChange($oldpost, $newpost)
349
- {
350
- if ($oldpost->post_author != $newpost->post_author) {
351
- $event = $this->GetEventTypeForPostType($oldpost, 2019, 2020, 2038);
352
- $this->plugin->alerts->Trigger($event, array(
353
- 'PostID' => $oldpost->ID,
354
- 'PostType' => $oldpost->post_type,
355
- 'PostTitle' => $oldpost->post_title,
356
- 'OldAuthor' => get_userdata($oldpost->post_author)->user_login,
357
- 'NewAuthor' => get_userdata($newpost->post_author)->user_login,
358
- ));
359
- return 1;
360
- }
361
- }
362
-
363
- protected function CheckStatusChange($oldpost, $newpost)
364
- {
365
- if ($oldpost->post_status != $newpost->post_status) {
366
- if (isset($_REQUEST['publish'])) {
367
- // special case (publishing a post)
368
- $event = $this->GetEventTypeForPostType($oldpost, 2001, 2005, 2030);
369
- $this->plugin->alerts->Trigger($event, array(
370
- 'PostID' => $newpost->ID,
371
- 'PostType' => $newpost->post_type,
372
- 'PostTitle' => $newpost->post_title,
373
- 'PostUrl' => get_permalink($newpost->ID),
374
- ));
375
- } else {
376
- $event = $this->GetEventTypeForPostType($oldpost, 2021, 2022, 2039);
377
- $this->plugin->alerts->Trigger($event, array(
378
- 'PostID' => $oldpost->ID,
379
- 'PostType' => $oldpost->post_type,
380
- 'PostTitle' => $oldpost->post_title,
381
- 'OldStatus' => $oldpost->post_status,
382
- 'NewStatus' => $newpost->post_status,
383
- ));
384
- }
385
- return 1;
386
- }
387
- }
388
-
389
- protected function CheckParentChange($oldpost, $newpost)
390
- {
391
- if ($oldpost->post_parent != $newpost->post_parent) {
392
- $event = $this->GetEventTypeForPostType($oldpost, 0, 2047, 0);
393
- if ($event) {
394
- $this->plugin->alerts->Trigger($event, array(
395
- 'PostID' => $oldpost->ID,
396
- 'PostType' => $oldpost->post_type,
397
- 'PostTitle' => $oldpost->post_title,
398
- 'OldParent' => $oldpost->post_parent,
399
- 'NewParent' => $newpost->post_parent,
400
- 'OldParentName' => $oldpost->post_parent ? get_the_title($oldpost->post_parent) : 'no parent',
401
- 'NewParentName' => $newpost->post_parent ? get_the_title($newpost->post_parent) : 'no parent',
402
- ));
403
- return 1;
404
- }
405
- }
406
- }
407
-
408
- protected function CheckPermalinkChange($oldLink, $newLink, $post)
409
- {
410
- if ($oldLink != $newLink) {
411
- $event = $this->GetEventTypeForPostType($post, 2017, 2018, 2037);
412
- $this->plugin->alerts->Trigger($event, array(
413
- 'PostID' => $post->ID,
414
- 'PostType' => $post->post_type,
415
- 'PostTitle' => $post->post_title,
416
- 'OldUrl' => $oldLink,
417
- 'NewUrl' => $newLink,
418
- ));
419
- return 1;
420
- }
421
- }
422
-
423
- protected function CheckVisibilityChange($oldpost, $newpost, $oldStatus, $newStatus)
424
- {
425
- if ($oldStatus == 'draft' || $newStatus == 'draft') {
426
- return;
427
- }
428
-
429
- $oldVisibility = '';
430
- $newVisibility = '';
431
-
432
- if ($oldpost->post_password) {
433
- $oldVisibility = __('Password Protected', 'wp-security-audit-log');
434
- } elseif ($oldStatus == 'publish') {
435
- $oldVisibility = __('Public', 'wp-security-audit-log');
436
- } elseif ($oldStatus == 'private') {
437
- $oldVisibility = __('Private', 'wp-security-audit-log');
438
- }
439
-
440
- if ($newpost->post_password) {
441
- $newVisibility = __('Password Protected', 'wp-security-audit-log');
442
- } elseif ($newStatus == 'publish') {
443
- $newVisibility = __('Public', 'wp-security-audit-log');
444
- } elseif ($newStatus == 'private') {
445
- $newVisibility = __('Private', 'wp-security-audit-log');
446
- }
447
-
448
- if ($oldVisibility && $newVisibility && ($oldVisibility != $newVisibility)) {
449
- $event = $this->GetEventTypeForPostType($oldpost, 2025, 2026, 2040);
450
- $this->plugin->alerts->Trigger($event, array(
451
- 'PostID' => $oldpost->ID,
452
- 'PostType' => $oldpost->post_type,
453
- 'PostTitle' => $oldpost->post_title,
454
- 'OldVisibility' => $oldVisibility,
455
- 'NewVisibility' => $newVisibility,
456
- ));
457
- return 1;
458
- }
459
- }
460
-
461
- protected function CheckTemplateChange($oldTmpl, $newTmpl, $post)
462
- {
463
- if ($oldTmpl != $newTmpl) {
464
- $event = $this->GetEventTypeForPostType($post, 0, 2048, 0);
465
- if ($event) {
466
- $this->plugin->alerts->Trigger($event, array(
467
- 'PostID' => $post->ID,
468
- 'PostType' => $post->post_type,
469
- 'PostTitle' => $post->post_title,
470
- 'OldTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($oldTmpl, '.php'))),
471
- 'NewTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($newTmpl, '.php'))),
472
- 'OldTemplatePath' => $oldTmpl,
473
- 'NewTemplatePath' => $newTmpl,
474
- ));
475
- return 1;
476
- }
477
- }
478
- }
479
-
480
- protected function CheckStickyChange($oldStky, $newStky, $post)
481
- {
482
- if ($oldStky != $newStky) {
483
- $event = $newStky ? 2049 : 2050;
484
- $this->plugin->alerts->Trigger($event, array(
485
- 'PostID' => $post->ID,
486
- 'PostType' => $post->post_type,
487
- 'PostTitle' => $post->post_title,
488
- ));
489
- return 1;
490
- }
491
- }
492
-
493
- public function CheckModificationChange($post_ID, $oldpost, $newpost)
494
- {
495
- if ($this->CheckBBPress($oldpost)) {
496
- return;
497
- }
498
- $changes = 0 + $this->CheckDateChange($oldpost, $newpost)
499
- + $this->CheckTitleChange($oldpost, $newpost);
500
- if (!$changes) {
501
- $contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
502
-
503
- if ($oldpost->post_modified != $newpost->post_modified) {
504
- $event = 0;
505
- // @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
506
- switch ($oldpost->post_status) { // TODO or should this be $newpost?
507
- case 'draft':
508
- if ($contentChanged) {
509
- $event = $this->GetEventTypeForPostType($newpost, 2068, 2069, 2070);
510
- } else {
511
- $event = $this->GetEventTypeForPostType($newpost, 2003, 2007, 2032);
512
- }
513
- break;
514
- case 'publish':
515
- if ($contentChanged) {
516
- $event = $this->GetEventTypeForPostType($newpost, 2065, 2066, 2067);
517
- } else {
518
- $event = $this->GetEventTypeForPostType($newpost, 2002, 2006, 2031);
519
- }
520
- break;
521
- }
522
- if ($event) {
523
- $this->plugin->alerts->Trigger($event, array(
524
- 'PostID' => $post_ID,
525
- 'PostType' => $oldpost->post_type,
526
- 'PostTitle' => $oldpost->post_title,
527
- 'PostUrl' => get_permalink($post_ID) // TODO or should this be $newpost?
528
- ));
529
- return 1;
530
- }
531
- }
532
- }
533
- }
534
-
535
- public function EventChangedCategoryParent()
536
- {
537
- if (empty($_POST)) {
538
- return;
539
- }
540
- if (!current_user_can("manage_categories")) {
541
- return;
542
- }
543
- if (isset($_POST['name'])) {
544
- $category = get_category($_POST['tag_ID']);
545
- if ($category->parent != 0) {
546
- $oldParent = get_category($category->parent);
547
- $oldParentName = (empty($oldParent))? 'no parent' : $oldParent->name;
548
- } else {
549
- $oldParentName = 'no parent';
550
- }
551
- if (isset($_POST['parent'])) {
552
- $newParent = get_category($_POST['parent']);
553
- $newParentName = (empty($newParent))? 'no parent' : $newParent->name;
554
- }
555
- $this->plugin->alerts->Trigger(2052, array(
556
- 'CategoryName' => $category->name,
557
- 'OldParent' => $oldParentName,
558
- 'NewParent' => $newParentName,
559
- ));
560
- }
561
- }
562
-
563
- private function CheckAutoDraft($code, $title)
564
- {
565
- if ($code == 2008 && $title == "auto-draft") {
566
- // to do check setting else return false
567
- if ($this->plugin->settings->IsWPBackend() == 1) {
568
- return true;
569
- } else {
570
- return false;
571
- }
572
- } else {
573
- return false;
574
- }
575
- }
576
-
577
- private function getRevisionLink($revision_id)
578
- {
579
- if (!empty($revision_id)) {
580
- return admin_url('revision.php?revision='.$revision_id);
581
- } else {
582
- return null;
583
- }
584
- }
585
-
586
- /**
587
- * Ignore post from BBPress Plugin,
588
- * Triggered on the BBPress Sensor
589
- */
590
- private function CheckBBPress($post)
591
- {
592
- switch ($post->post_type) {
593
- case 'forum':
594
- case 'topic':
595
- case 'reply':
596
- return true;
597
- default:
598
- return false;
599
- }
600
- }
601
-
602
- /**
603
- * Triggered after save post for add revision link
604
- */
605
- public function SetRevisionLink($post_id, $post, $update)
606
- {
607
- $revisions = wp_get_post_revisions($post_id);
608
- if (!empty($revisions)) {
609
- $revision = array_shift($revisions);
610
-
611
- $objOcc = new WSAL_Models_Occurrence();
612
- $occ = $objOcc->GetByPostID($post_id);
613
- $occ = count($occ) ? $occ[0] : null;
614
- if (!empty($occ)) {
615
- $revisionLink = $this->getRevisionLink($revision->ID);
616
- if (!empty($revisionLink)) {
617
- $occ->SetMetaValue('RevisionLink', $revisionLink);
618
- }
619
- }
620
- }
621
- }
622
-
623
- private function CheckTitleChange($oldpost, $newpost)
624
- {
625
- if ($oldpost->post_title != $newpost->post_title) {
626
- $event = $this->GetEventTypeForPostType($newpost, 2086, 2087, 2088);
627
- $this->plugin->alerts->Trigger($event, array(
628
- 'OldTitle' => $oldpost->post_title,
629
- 'NewTitle' => $newpost->post_title,
630
- ));
631
- return 1;
632
- }
633
- return 0;
634
- }
635
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Sensors_Content extends WSAL_AbstractSensor
4
+ {
5
+
6
+ public function HookEvents()
7
+ {
8
+ if (current_user_can("edit_posts")) {
9
+ add_action('admin_init', array($this, 'EventWordpressInit'));
10
+ }
11
+ add_action('transition_post_status', array($this, 'EventPostChanged'), 10, 3);
12
+ add_action('delete_post', array($this, 'EventPostDeleted'), 10, 1);
13
+ add_action('wp_trash_post', array($this, 'EventPostTrashed'), 10, 1);
14
+ add_action('untrash_post', array($this, 'EventPostUntrashed'));
15
+ add_action('edit_category', array($this, 'EventChangedCategoryParent'));
16
+ add_action('save_post', array($this, 'SetRevisionLink'), 10, 3);
17
+ add_action('publish_future_post', array($this, 'EventPublishFuture'), 10, 1);
18
+ // to do change with 'create_term' instead 'create_category' for trigger Tags
19
+ add_action('create_category', array($this, 'EventCategoryCreation'), 10, 1);
20
+ }
21
+
22
+ protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
23
+ {
24
+ switch ($post->post_type) {
25
+ case 'page':
26
+ return $typePage;
27
+ case 'post':
28
+ return $typePost;
29
+ default:
30
+ return $typeCustom;
31
+ }
32
+ }
33
+
34
+ protected $_OldPost = null;
35
+ protected $_OldLink = null;
36
+ protected $_OldCats = null;
37
+ protected $_OldTmpl = null;
38
+ protected $_OldStky = null;
39
+
40
+ public function EventWordpressInit()
41
+ {
42
+ // load old data, if applicable
43
+ $this->RetrieveOldData();
44
+ // check for category changes
45
+ $this->CheckCategoryDeletion();
46
+ }
47
+
48
+ protected function RetrieveOldData()
49
+ {
50
+ if (isset($_POST) && isset($_POST['post_ID'])
51
+ && !(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
52
+ && !(isset($_POST['action']) && $_POST['action'] == 'autosave')
53
+ ) {
54
+ $postID = intval($_POST['post_ID']);
55
+ $this->_OldPost = get_post($postID);
56
+ $this->_OldLink = get_permalink($postID);
57
+ $this->_OldTmpl = $this->GetPostTemplate($this->_OldPost);
58
+ $this->_OldCats = $this->GetPostCategories($this->_OldPost);
59
+ $this->_OldStky = in_array($postID, get_option('sticky_posts'));
60
+ }
61
+ }
62
+
63
+ protected function GetPostTemplate($post)
64
+ {
65
+ $id = $post->ID;
66
+ $template = get_page_template_slug($id);
67
+ $pagename = $post->post_name;
68
+
69
+ $templates = array();
70
+ if ($template && 0 === validate_file($template)) {
71
+ $templates[] = $template;
72
+ }
73
+ if ($pagename) {
74
+ $templates[] = "page-$pagename.php";
75
+ }
76
+ if ($id) {
77
+ $templates[] = "page-$id.php";
78
+ }
79
+ $templates[] = 'page.php';
80
+
81
+ return get_query_template('page', $templates);
82
+ }
83
+
84
+ protected function GetPostCategories($post)
85
+ {
86
+ return wp_get_post_categories($post->ID, array('fields' => 'names'));
87
+ }
88
+
89
+ public function EventPostChanged($newStatus, $oldStatus, $post)
90
+ {
91
+ // ignorable states
92
+ if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
93
+ return;
94
+ }
95
+ if (empty($post->post_type)) {
96
+ return;
97
+ }
98
+ if ($post->post_type == 'revision') {
99
+ return;
100
+ }
101
+
102
+ $original = isset($_POST['original_post_status']) ? $_POST['original_post_status'] : '';
103
+
104
+ WSAL_Sensors_Request::SetVars(array(
105
+ '$newStatus' => $newStatus,
106
+ '$oldStatus' => $oldStatus,
107
+ '$original' => $original,
108
+ ));
109
+ // run checks
110
+ if ($this->_OldPost) {
111
+ if ($this->CheckBBPress($this->_OldPost)) {
112
+ return;
113
+ }
114
+ if ($oldStatus == 'auto-draft' || $original == 'auto-draft') {
115
+ // Handle create post events
116
+ $this->CheckPostCreation($this->_OldPost, $post);
117
+ } else {
118
+ // Handle update post events
119
+ $changes = 0
120
+ + $this->CheckAuthorChange($this->_OldPost, $post)
121
+ + $this->CheckStatusChange($this->_OldPost, $post)
122
+ + $this->CheckParentChange($this->_OldPost, $post)
123
+ + $this->CheckStickyChange($this->_OldStky, isset($_REQUEST['sticky']), $post)
124
+ + $this->CheckVisibilityChange($this->_OldPost, $post, $oldStatus, $newStatus)
125
+ + $this->CheckTemplateChange($this->_OldTmpl, $this->GetPostTemplate($post), $post)
126
+ + $this->CheckCategoriesChange($this->_OldCats, $this->GetPostCategories($post), $post)
127
+ ;
128
+ if (!$changes) {
129
+ $changes = $this->CheckPermalinkChange($this->_OldLink, get_permalink($post->ID), $post);
130
+ }
131
+ if (!$changes) {
132
+ $changes = $this->CheckModificationChange($post->ID, $this->_OldPost, $post);
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ protected function CheckPostCreation($oldPost, $newPost)
139
+ {
140
+ $WPActions = array('editpost', 'heartbeat');
141
+ if (isset($_POST['action']) && in_array($_POST['action'], $WPActions)) {
142
+ if (!in_array($newPost->post_type, array('attachment', 'revision', 'nav_menu_item'))) {
143
+ $event = 0;
144
+ $is_scheduled = false;
145
+ switch ($newPost->post_status) {
146
+ case 'publish':
147
+ $event = $this->GetEventTypeForPostType($newPost, 2001, 2005, 2030);
148
+ break;
149
+ case 'draft':
150
+ $event = $this->GetEventTypeForPostType($newPost, 2000, 2004, 2029);
151
+ break;
152
+ case 'future':
153
+ $event = $this->GetEventTypeForPostType($newPost, 2074, 2075, 2076);
154
+ $is_scheduled = true;
155
+ break;
156
+ case 'pending':
157
+ $event = 2073;
158
+ break;
159
+ }
160
+ if ($event) {
161
+ $editorLink = $this->GetEditorLink($newPost);
162
+ if ($is_scheduled) {
163
+ $this->plugin->alerts->Trigger($event, array(
164
+ 'PostType' => $newPost->post_type,
165
+ 'PostTitle' => $newPost->post_title,
166
+ 'PublishingDate' => $newPost->post_date,
167
+ $editorLink['name'] => $editorLink['value']
168
+ ));
169
+ } else {
170
+ $this->plugin->alerts->Trigger($event, array(
171
+ 'PostID' => $newPost->ID,
172
+ 'PostType' => $newPost->post_type,
173
+ 'PostTitle' => $newPost->post_title,
174
+ 'PostUrl' => get_permalink($newPost->ID),
175
+ $editorLink['name'] => $editorLink['value']
176
+ ));
177
+ }
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ public function EventPublishFuture($post_id)
184
+ {
185
+ $post = get_post($post_id);
186
+ $event = $this->GetEventTypeForPostType($post, 2001, 2005, 2030);
187
+
188
+ if ($event) {
189
+ $editorLink = $this->GetEditorLink($newPost);
190
+ $this->plugin->alerts->Trigger($event, array(
191
+ 'PostID' => $post->ID,
192
+ 'PostType' => $post->post_type,
193
+ 'PostTitle' => $post->post_title,
194
+ 'PostUrl' => get_permalink($post->ID),
195
+ $editorLink['name'] => $editorLink['value']
196
+ ));
197
+ }
198
+ }
199
+
200
+ public function EventPostDeleted($post_id)
201
+ {
202
+ $post = get_post($post_id);
203
+ if ($this->CheckBBPress($post)) {
204
+ return;
205
+ }
206
+ $WPActions = array('delete');
207
+ if (isset($_REQUEST['action']) && in_array($_REQUEST['action'], $WPActions)) {
208
+ if (!in_array($post->post_type, array('attachment', 'revision', 'nav_menu_item'))) { // ignore attachments, revisions and menu items
209
+ $event = $this->GetEventTypeForPostType($post, 2008, 2009, 2033);
210
+ // check WordPress backend operations
211
+ if ($this->CheckAutoDraft($event, $post->post_title)) {
212
+ return;
213
+ }
214
+ $editorLink = $this->GetEditorLink($post);
215
+ $this->plugin->alerts->Trigger($event, array(
216
+ 'PostID' => $post->ID,
217
+ 'PostType' => $post->post_type,
218
+ 'PostTitle' => $post->post_title,
219
+ 'PostUrl' => get_permalink($post->ID),
220
+ $editorLink['name'] => $editorLink['value']
221
+ ));
222
+ }
223
+ }
224
+ }
225
+
226
+ public function EventPostTrashed($post_id)
227
+ {
228
+ $post = get_post($post_id);
229
+ if ($this->CheckBBPress($post)) {
230
+ return;
231
+ }
232
+ $event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
233
+ $editorLink = $this->GetEditorLink($post);
234
+ $this->plugin->alerts->Trigger($event, array(
235
+ 'PostID' => $post->ID,
236
+ 'PostType' => $post->post_type,
237
+ 'PostTitle' => $post->post_title,
238
+ 'PostUrl' => get_permalink($post->ID),
239
+ $editorLink['name'] => $editorLink['value']
240
+ ));
241
+ }
242
+
243
+ public function EventPostUntrashed($post_id)
244
+ {
245
+ $post = get_post($post_id);
246
+ if ($this->CheckBBPress($post)) {
247
+ return;
248
+ }
249
+ $event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
250
+ $editorLink = $this->GetEditorLink($post);
251
+ $this->plugin->alerts->Trigger($event, array(
252
+ 'PostID' => $post->ID,
253
+ 'PostType' => $post->post_type,
254
+ 'PostTitle' => $post->post_title,
255
+ $editorLink['name'] => $editorLink['value']
256
+ ));
257
+ }
258
+
259
+ protected function CheckDateChange($oldpost, $newpost)
260
+ {
261
+ $from = strtotime($oldpost->post_date);
262
+ $to = strtotime($newpost->post_date);
263
+ if ($oldpost->post_status == 'draft') {
264
+ return 0;
265
+ }
266
+ $pending = $this->CheckReviewPendingChange($oldpost, $newpost);
267
+ if ($pending) {
268
+ return 0;
269
+ }
270
+ if ($from != $to) {
271
+ $event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
272
+ $editorLink = $this->GetEditorLink($oldpost);
273
+ $this->plugin->alerts->Trigger($event, array(
274
+ 'PostID' => $oldpost->ID,
275
+ 'PostType' => $oldpost->post_type,
276
+ 'PostTitle' => $oldpost->post_title,
277
+ 'OldDate' => $oldpost->post_date,
278
+ 'NewDate' => $newpost->post_date,
279
+ $editorLink['name'] => $editorLink['value']
280
+ ));
281
+ return 1;
282
+ }
283
+ }
284
+
285
+ // Revision used
286
+ protected function CheckReviewPendingChange($oldpost, $newpost)
287
+ {
288
+ if ($oldpost->post_status == 'pending') {
289
+ $editorLink = $this->GetEditorLink($oldpost);
290
+ $this->plugin->alerts->Trigger(2072, array(
291
+ 'PostID' => $oldpost->ID,
292
+ 'PostType' => $oldpost->post_type,
293
+ 'PostTitle' => $oldpost->post_title,
294
+ $editorLink['name'] => $editorLink['value']
295
+ ));
296
+ return 1;
297
+ }
298
+ return 0;
299
+ }
300
+
301
+ protected function CheckCategoriesChange($oldCats, $newCats, $post)
302
+ {
303
+ $oldCats = implode(', ', $oldCats);
304
+ $newCats = implode(', ', $newCats);
305
+ if ($oldCats != $newCats) {
306
+ $event = $this->GetEventTypeForPostType($post, 2016, 0, 2036);
307
+ if ($event) {
308
+ $editorLink = $this->GetEditorLink($post);
309
+ $this->plugin->alerts->Trigger($event, array(
310
+ 'PostID' => $post->ID,
311
+ 'PostType' => $post->post_type,
312
+ 'PostTitle' => $post->post_title,
313
+ 'OldCategories' => $oldCats ? $oldCats : 'no categories',
314
+ 'NewCategories' => $newCats ? $newCats : 'no categories',
315
+ $editorLink['name'] => $editorLink['value']
316
+ ));
317
+ return 1;
318
+ }
319
+ }
320
+ }
321
+
322
+ protected function CheckAuthorChange($oldpost, $newpost)
323
+ {
324
+ if ($oldpost->post_author != $newpost->post_author) {
325
+ $event = $this->GetEventTypeForPostType($oldpost, 2019, 2020, 2038);
326
+ $editorLink = $this->GetEditorLink($oldpost);
327
+ $this->plugin->alerts->Trigger($event, array(
328
+ 'PostID' => $oldpost->ID,
329
+ 'PostType' => $oldpost->post_type,
330
+ 'PostTitle' => $oldpost->post_title,
331
+ 'OldAuthor' => get_userdata($oldpost->post_author)->user_login,
332
+ 'NewAuthor' => get_userdata($newpost->post_author)->user_login,
333
+ $editorLink['name'] => $editorLink['value']
334
+ ));
335
+ return 1;
336
+ }
337
+ }
338
+
339
+ protected function CheckStatusChange($oldpost, $newpost)
340
+ {
341
+ if ($oldpost->post_status != $newpost->post_status) {
342
+ if (isset($_REQUEST['publish'])) {
343
+ // special case (publishing a post)
344
+ $event = $this->GetEventTypeForPostType($oldpost, 2001, 2005, 2030);
345
+ $editorLink = $this->GetEditorLink($newpost);
346
+ $this->plugin->alerts->Trigger($event, array(
347
+ 'PostID' => $newpost->ID,
348
+ 'PostType' => $newpost->post_type,
349
+ 'PostTitle' => $newpost->post_title,
350
+ 'PostUrl' => get_permalink($newpost->ID),
351
+ $editorLink['name'] => $editorLink['value']
352
+ ));
353
+ } else {
354
+ $event = $this->GetEventTypeForPostType($oldpost, 2021, 2022, 2039);
355
+ $editorLink = $this->GetEditorLink($oldpost);
356
+ $this->plugin->alerts->Trigger($event, array(
357
+ 'PostID' => $oldpost->ID,
358
+ 'PostType' => $oldpost->post_type,
359
+ 'PostTitle' => $oldpost->post_title,
360
+ 'OldStatus' => $oldpost->post_status,
361
+ 'NewStatus' => $newpost->post_status,
362
+ $editorLink['name'] => $editorLink['value']
363
+ ));
364
+ }
365
+ return 1;
366
+ }
367
+ }
368
+
369
+ protected function CheckParentChange($oldpost, $newpost)
370
+ {
371
+ if ($oldpost->post_parent != $newpost->post_parent) {
372
+ $event = $this->GetEventTypeForPostType($oldpost, 0, 2047, 0);
373
+ if ($event) {
374
+ $editorLink = $this->GetEditorLink($oldpost);
375
+ $this->plugin->alerts->Trigger($event, array(
376
+ 'PostID' => $oldpost->ID,
377
+ 'PostType' => $oldpost->post_type,
378
+ 'PostTitle' => $oldpost->post_title,
379
+ 'OldParent' => $oldpost->post_parent,
380
+ 'NewParent' => $newpost->post_parent,
381
+ 'OldParentName' => $oldpost->post_parent ? get_the_title($oldpost->post_parent) : 'no parent',
382
+ 'NewParentName' => $newpost->post_parent ? get_the_title($newpost->post_parent) : 'no parent',
383
+ $editorLink['name'] => $editorLink['value']
384
+ ));
385
+ return 1;
386
+ }
387
+ }
388
+ }
389
+
390
+ protected function CheckPermalinkChange($oldLink, $newLink, $post)
391
+ {
392
+ if ($oldLink != $newLink) {
393
+ $event = $this->GetEventTypeForPostType($post, 2017, 2018, 2037);
394
+ $editorLink = $this->GetEditorLink($post);
395
+ $this->plugin->alerts->Trigger($event, array(
396
+ 'PostID' => $post->ID,
397
+ 'PostType' => $post->post_type,
398
+ 'PostTitle' => $post->post_title,
399
+ 'OldUrl' => $oldLink,
400
+ 'NewUrl' => $newLink,
401
+ $editorLink['name'] => $editorLink['value']
402
+ ));
403
+ return 1;
404
+ }
405
+ }
406
+
407
+ protected function CheckVisibilityChange($oldpost, $newpost, $oldStatus, $newStatus)
408
+ {
409
+ if ($oldStatus == 'draft' || $newStatus == 'draft') {
410
+ return;
411
+ }
412
+
413
+ $oldVisibility = '';
414
+ $newVisibility = '';
415
+
416
+ if ($oldpost->post_password) {
417
+ $oldVisibility = __('Password Protected', 'wp-security-audit-log');
418
+ } elseif ($oldStatus == 'publish') {
419
+ $oldVisibility = __('Public', 'wp-security-audit-log');
420
+ } elseif ($oldStatus == 'private') {
421
+ $oldVisibility = __('Private', 'wp-security-audit-log');
422
+ }
423
+
424
+ if ($newpost->post_password) {
425
+ $newVisibility = __('Password Protected', 'wp-security-audit-log');
426
+ } elseif ($newStatus == 'publish') {
427
+ $newVisibility = __('Public', 'wp-security-audit-log');
428
+ } elseif ($newStatus == 'private') {
429
+ $newVisibility = __('Private', 'wp-security-audit-log');
430
+ }
431
+
432
+ if ($oldVisibility && $newVisibility && ($oldVisibility != $newVisibility)) {
433
+ $event = $this->GetEventTypeForPostType($oldpost, 2025, 2026, 2040);
434
+ $editorLink = $this->GetEditorLink($oldpost);
435
+ $this->plugin->alerts->Trigger($event, array(
436
+ 'PostID' => $oldpost->ID,
437
+ 'PostType' => $oldpost->post_type,
438
+ 'PostTitle' => $oldpost->post_title,
439
+ 'OldVisibility' => $oldVisibility,
440
+ 'NewVisibility' => $newVisibility,
441
+ $editorLink['name'] => $editorLink['value']
442
+ ));
443
+ return 1;
444
+ }
445
+ }
446
+
447
+ protected function CheckTemplateChange($oldTmpl, $newTmpl, $post)
448
+ {
449
+ if ($oldTmpl != $newTmpl) {
450
+ $event = $this->GetEventTypeForPostType($post, 0, 2048, 0);
451
+ if ($event) {
452
+ $editorLink = $this->GetEditorLink($post);
453
+ $this->plugin->alerts->Trigger($event, array(
454
+ 'PostID' => $post->ID,
455
+ 'PostType' => $post->post_type,
456
+ 'PostTitle' => $post->post_title,
457
+ 'OldTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($oldTmpl, '.php'))),
458
+ 'NewTemplate' => ucwords(str_replace(array('-' , '_'), ' ', basename($newTmpl, '.php'))),
459
+ 'OldTemplatePath' => $oldTmpl,
460
+ 'NewTemplatePath' => $newTmpl,
461
+ $editorLink['name'] => $editorLink['value']
462
+ ));
463
+ return 1;
464
+ }
465
+ }
466
+ }
467
+
468
+ protected function CheckStickyChange($oldStky, $newStky, $post)
469
+ {
470
+ if ($oldStky != $newStky) {
471
+ $event = $newStky ? 2049 : 2050;
472
+ $editorLink = $this->GetEditorLink($post);
473
+ $this->plugin->alerts->Trigger($event, array(
474
+ 'PostID' => $post->ID,
475
+ 'PostType' => $post->post_type,
476
+ 'PostTitle' => $post->post_title,
477
+ 'PostUrl' => get_permalink($post->ID),
478
+ $editorLink['name'] => $editorLink['value']
479
+ ));
480
+ return 1;
481
+ }
482
+ }
483
+
484
+ public function CheckModificationChange($post_ID, $oldpost, $newpost)
485
+ {
486
+ if ($this->CheckBBPress($oldpost)) {
487
+ return;
488
+ }
489
+ $changes = 0 + $this->CheckDateChange($oldpost, $newpost)
490
+ + $this->CheckTitleChange($oldpost, $newpost);
491
+ if (!$changes) {
492
+ $contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
493
+
494
+ if ($oldpost->post_modified != $newpost->post_modified) {
495
+ $event = 0;
496
+ // @see http://codex.wordpress.org/Class_Reference/WP_Query#Status_Parameters
497
+ switch ($oldpost->post_status) { // TODO or should this be $newpost?
498
+ case 'draft':
499
+ if ($contentChanged) {
500
+ $event = $this->GetEventTypeForPostType($newpost, 2068, 2069, 2070);
501
+ } else {
502
+ $event = $this->GetEventTypeForPostType($newpost, 2003, 2007, 2032);
503
+ }
504
+ break;
505
+ case 'publish':
506
+ if ($contentChanged) {
507
+ $event = $this->GetEventTypeForPostType($newpost, 2065, 2066, 2067);
508
+ } else {
509
+ $event = $this->GetEventTypeForPostType($newpost, 2002, 2006, 2031);
510
+ }
511
+ break;
512
+ }
513
+ if ($event) {
514
+ $editorLink = $this->GetEditorLink($oldpost);
515
+ $this->plugin->alerts->Trigger($event, array(
516
+ 'PostID' => $post_ID,
517
+ 'PostType' => $oldpost->post_type,
518
+ 'PostTitle' => $oldpost->post_title,
519
+ 'PostUrl' => get_permalink($post_ID),
520
+ $editorLink['name'] => $editorLink['value']
521
+ ));
522
+ return 1;
523
+ }
524
+ }
525
+ }
526
+ }
527
+
528
+ public function EventCategoryCreation($category_id)
529
+ {
530
+ $category = get_category($category_id);
531
+ $category_link = $this->getCategoryLink($category_id);
532
+ $this->plugin->alerts->Trigger(2023, array(
533
+ 'CategoryName' => $category->name,
534
+ 'Slug' => $category->slug,
535
+ 'CategoryLink' => $category_link
536
+ ));
537
+ }
538
+
539
+ protected function CheckCategoryDeletion()
540
+ {
541
+ if (empty($_POST)) {
542
+ return;
543
+ }
544
+ $action = !empty($_POST['action']) ? $_POST['action']
545
+ : (!empty($_POST['action2']) ? $_POST['action2'] : '');
546
+ if (!$action) {
547
+ return;
548
+ }
549
+
550
+ $categoryIds = array();
551
+
552
+ if (isset($_POST['taxonomy'])) {
553
+ if ($action == 'delete' && $_POST['taxonomy'] == 'category' && !empty($_POST['delete_tags'])) {
554
+ // bulk delete
555
+ $categoryIds[] = $_POST['delete_tags'];
556
+ } elseif ($action == 'delete-tag' && $_POST['taxonomy'] == 'category' && !empty($_POST['tag_ID'])) {
557
+ // single delete
558
+ $categoryIds[] = $_POST['tag_ID'];
559
+ }
560
+ }
561
+
562
+ foreach ($categoryIds as $categoryID) {
563
+ $category = get_category($categoryID);
564
+ $this->plugin->alerts->Trigger(2024, array(
565
+ 'CategoryID' => $categoryID,
566
+ 'CategoryName' => $category->cat_name,
567
+ 'Slug' => $category->slug
568
+ ));
569
+ }
570
+ }
571
+
572
+ public function EventChangedCategoryParent()
573
+ {
574
+ if (empty($_POST)) {
575
+ return;
576
+ }
577
+ if (!current_user_can("manage_categories")) {
578
+ return;
579
+ }
580
+ if (isset($_POST['name']) && isset($_POST['tag_ID'])) {
581
+ $category = get_category($_POST['tag_ID']);
582
+ $category_link = $this->getCategoryLink($_POST['tag_ID']);
583
+ if ($category->parent != 0) {
584
+ $oldParent = get_category($category->parent);
585
+ $oldParentName = (empty($oldParent))? 'no parent' : $oldParent->name;
586
+ } else {
587
+ $oldParentName = 'no parent';
588
+ }
589
+ if (isset($_POST['parent'])) {
590
+ $newParent = get_category($_POST['parent']);
591
+ $newParentName = (empty($newParent))? 'no parent' : $newParent->name;
592
+ }
593
+ $this->plugin->alerts->Trigger(2052, array(
594
+ 'CategoryName' => $category->name,
595
+ 'OldParent' => $oldParentName,
596
+ 'NewParent' => $newParentName,
597
+ 'CategoryLink' => $category_link
598
+ ));
599
+ }
600
+ }
601
+
602
+ private function CheckAutoDraft($code, $title)
603
+ {
604
+ if ($code == 2008 && $title == "auto-draft") {
605
+ // to do check setting else return false
606
+ if ($this->plugin->settings->IsWPBackend() == 1) {
607
+ return true;
608
+ } else {
609
+ return false;
610
+ }
611
+ } else {
612
+ return false;
613
+ }
614
+ }
615
+
616
+ private function getRevisionLink($revision_id)
617
+ {
618
+ if (!empty($revision_id)) {
619
+ return admin_url('revision.php?revision='.$revision_id);
620
+ } else {
621
+ return null;
622
+ }
623
+ }
624
+
625
+ private function getCategoryLink($category_id)
626
+ {
627
+ if (!empty($category_id)) {
628
+ return admin_url('term.php?taxnomy=category&tag_ID='.$category_id);
629
+ } else {
630
+ return null;
631
+ }
632
+ }
633
+
634
+ /**
635
+ * Ignore post from BBPress Plugin,
636
+ * Triggered on the BBPress Sensor
637
+ */
638
+ private function CheckBBPress($post)
639
+ {
640
+ switch ($post->post_type) {
641
+ case 'forum':
642
+ case 'topic':
643
+ case 'reply':
644
+ return true;
645
+ default:
646
+ return false;
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Triggered after save post for add revision link
652
+ */
653
+ public function SetRevisionLink($post_id, $post, $update)
654
+ {
655
+ $revisions = wp_get_post_revisions($post_id);
656
+ if (!empty($revisions)) {
657
+ $revision = array_shift($revisions);
658
+
659
+ $objOcc = new WSAL_Models_Occurrence();
660
+ $occ = $objOcc->GetByPostID($post_id);
661
+ $occ = count($occ) ? $occ[0] : null;
662
+ if (!empty($occ)) {
663
+ $revisionLink = $this->getRevisionLink($revision->ID);
664
+ if (!empty($revisionLink)) {
665
+ $occ->SetMetaValue('RevisionLink', $revisionLink);
666
+ }
667
+ }
668
+ }
669
+ }
670
+
671
+ private function CheckTitleChange($oldpost, $newpost)
672
+ {
673
+ if ($oldpost->post_title != $newpost->post_title) {
674
+ $event = $this->GetEventTypeForPostType($newpost, 2086, 2087, 2088);
675
+ $editorLink = $this->GetEditorLink($oldpost);
676
+ $this->plugin->alerts->Trigger($event, array(
677
+ 'OldTitle' => $oldpost->post_title,
678
+ 'NewTitle' => $newpost->post_title,
679
+ $editorLink['name'] => $editorLink['value']
680
+ ));
681
+ return 1;
682
+ }
683
+ return 0;
684
+ }
685
+
686
+ private function GetEditorLink($post)
687
+ {
688
+ $name = 'EditorLink';
689
+ $name .= ($post->post_type == 'page') ? 'Page' : 'Post' ;
690
+ $value = get_edit_post_link($post->ID);
691
+ $aLink = array(
692
+ 'name' => $name,
693
+ 'value' => $value,
694
+ );
695
+ return $aLink;
696
+ }
697
+ }
classes/Sensors/CustomHooks.php CHANGED
@@ -1,49 +1,49 @@
1
- <?php
2
- /**
3
- * The Class is used to allow developers to create
4
- * custom alerts
5
- */
6
- class WSAL_Sensors_CustomHooks extends WSAL_AbstractSensor
7
- {
8
- public function HookEvents()
9
- {
10
- /**
11
- * Use add_action() for every hook and pass the following:
12
- * @param string sample_hook_name
13
- * @param string SampleFunction - the name of the function above
14
- * @param int 10 - priority (Optional)
15
- * @param int 2 - number of parameters passed to the function (Optional)(Check the hook documentation)
16
- * @see http://adambrown.info/p/wp_hooks for more information on WordPress hooks
17
- */
18
- add_action('sample_hook_name', array($this, 'SampleFunction'), 10, 2);
19
- }
20
-
21
- /**
22
- * Sample function with 0 or more parameters.
23
- * Create one function for each hook:
24
- * @param anyType $paramname (Optional)
25
- */
26
- public function SampleFunction($value_1 = null, $value_2 = null)
27
- {
28
- /**
29
- * @var int (4 digit) $alertCode Alert code (3 types of criticality level)
30
- * @example Critical 2222, Warning 3333, Notice 4444
31
- */
32
- $alertCode = 2222;
33
-
34
- /**
35
- * @var string: the alert text
36
- */
37
- $alertText = 'Sample alert text';
38
-
39
- /**
40
- * @var array $variables used in the alert (With 1 or more elements)
41
- * { @var string $alertText }
42
- */
43
- $variables = array(
44
- 'CustomAlertText' => $alertText
45
- );
46
-
47
- $this->plugin->alerts->Trigger($alertCode, $variables);
48
- }
49
- }
1
+ <?php
2
+ /**
3
+ * The Class is used to allow developers to create
4
+ * custom alerts
5
+ */
6
+ class WSAL_Sensors_CustomHooks extends WSAL_AbstractSensor
7
+ {
8
+ public function HookEvents()
9
+ {
10
+ /**
11
+ * Use add_action() for every hook and pass the following:
12
+ * @param string sample_hook_name
13
+ * @param string SampleFunction - the name of the function above
14
+ * @param int 10 - priority (Optional)
15
+ * @param int 2 - number of parameters passed to the function (Optional)(Check the hook documentation)
16
+ * @see http://adambrown.info/p/wp_hooks for more information on WordPress hooks
17
+ */
18
+ add_action('sample_hook_name', array($this, 'SampleFunction'), 10, 2);
19
+ }
20
+
21
+ /**
22
+ * Sample function with 0 or more parameters.
23
+ * Create one function for each hook:
24
+ * @param anyType $paramname (Optional)
25
+ */
26
+ public function SampleFunction($value_1 = null, $value_2 = null)
27
+ {
28
+ /**
29
+ * @var int (4 digit) $alertCode Alert code (3 types of criticality level)
30
+ * @example Critical 2222, Warning 3333, Notice 4444
31
+ */
32
+ $alertCode = 2222;
33
+
34
+ /**
35
+ * @var string: the alert text
36
+ */
37
+ $alertText = 'Sample alert text';
38
+
39
+ /**
40
+ * @var array $variables used in the alert (With 1 or more elements)
41
+ * { @var string $alertText }
42
+ */
43
+ $variables = array(
44
+ 'CustomAlertText' => $alertText
45
+ );
46
+
47
+ $this->plugin->alerts->Trigger($alertCode, $variables);
48
+ }
49
+ }
classes/Sensors/Database.php CHANGED
@@ -1,132 +1,132 @@
1
- <?php
2
-
3
- class WSAL_Sensors_Database extends WSAL_AbstractSensor
4
- {
5
- public function HookEvents()
6
- {
7
- add_action('dbdelta_queries', array($this, 'EventDBDeltaQuery'));
8
- add_action('query', array($this, 'EventDropQuery'));
9
- }
10
-
11
- public function EventDropQuery($query)
12
- {
13
- $table_names = array();
14
- $str = explode(" ", $query);
15
-
16
- if (preg_match("|DROP TABLE ([^ ]*)|", $query)) {
17
- if (!empty($str[4])) {
18
- array_push($table_names, $str[4]);
19
- } else {
20
- array_push($table_names, $str[2]);
21
- }
22
- $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
23
- $alertOptions = $this->GetActionType($actype);
24
- }
25
-
26
- if (!empty($table_names)) {
27
- $event_code = $this->GetEventQueryType($actype, "delete");
28
- $alertOptions["TableNames"] = implode(",", $table_names);
29
- $this->plugin->alerts->Trigger($event_code, $alertOptions);
30
- }
31
- return $query;
32
- }
33
-
34
- public function EventDBDeltaQuery($queries)
35
- {
36
- $typeQueries = array(
37
- "create" => array(),
38
- "update" => array(),
39
- "delete" => array()
40
- );
41
- global $wpdb;
42
-
43
- foreach ($queries as $qry) {
44
- $str = explode(" ", $qry);
45
- if (preg_match("|CREATE TABLE ([^ ]*)|", $qry)) {
46
- if ($wpdb->get_var("SHOW TABLES LIKE '" . $str[2] . "'") != $str[2]) {
47
- //some plugins keep trying to create tables even when they already exist- would result in too many alerts
48
- array_push($typeQueries['create'], $str[2]);
49
- }
50
- } else if (preg_match("|ALTER TABLE ([^ ]*)|", $qry)) {
51
- array_push($typeQueries['update'], $str[2]);
52
- } else if (preg_match("|DROP TABLE ([^ ]*)|", $qry)) {
53
- if (!empty($str[4])) {
54
- array_push($typeQueries['delete'], $str[4]);
55
- } else {
56
- array_push($typeQueries['delete'], $str[2]);
57
- }
58
- }
59
- }
60
-
61
- if (!empty($typeQueries["create"]) || !empty($typeQueries["update"]) || !empty($typeQueries["delete"])) {
62
- $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
63
- $alertOptions = $this->GetActionType($actype);
64
-
65
- foreach ($typeQueries as $queryType => $tableNames) {
66
- if (!empty($tableNames)) {
67
- $event_code = $this->GetEventQueryType($actype, $queryType);
68
- $alertOptions["TableNames"] = implode(",", $tableNames);
69
- $this->plugin->alerts->Trigger($event_code, $alertOptions);
70
- }
71
- }
72
- }
73
-
74
- return $queries;
75
- }
76
-
77
- protected function GetEventQueryType($type_action, $type_query)
78
- {
79
- switch ($type_action) {
80
- case 'plugins':
81
- if ($type_query == 'create') return 5010;
82
- else if ($type_query == 'update') return 5011;
83
- else if ($type_query == 'delete') return 5012;
84
- case 'themes':
85
- if ($type_query == 'create') return 5013;
86
- else if ($type_query == 'update') return 5014;
87
- else if ($type_query == 'delete') return 5015;
88
- default:
89
- if ($type_query == 'create') return 5016;
90
- else if ($type_query == 'update') return 5017;
91
- else if ($type_query == 'delete') return 5018;
92
- }
93
- }
94
-
95
- protected function GetActionType($actype)
96
- {
97
- $is_themes = $actype == 'themes';
98
- $is_plugins = $actype == 'plugins';
99
- //Action Plugin Component
100
- $alertOptions = array();
101
- if ($is_plugins) {
102
- if (isset($_REQUEST['plugin'])) {
103
- $pluginFile = $_REQUEST['plugin'];
104
- } else {
105
- $pluginFile = $_REQUEST['checked'][0];
106
- }
107
- $pluginName = basename($pluginFile, '.php');
108
- $pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
109
- $pluginName = ucwords($pluginName);
110
- $alertOptions["Plugin"] = (object)array(
111
- 'Name' => $pluginName,
112
- );
113
- //Action Theme Component
114
- } else if ($is_themes) {
115
- if (isset($_REQUEST['theme'])) {
116
- $themeName = $_REQUEST['theme'];
117
- } else {
118
- $themeName = $_REQUEST['checked'][0];
119
- }
120
- $themeName = str_replace(array('_', '-', ' '), ' ', $themeName);
121
- $themeName = ucwords($themeName);
122
- $alertOptions["Theme"] = (object)array(
123
- 'Name' => $themeName,
124
- );
125
- //Action Unknown Component
126
- } else {
127
- $alertOptions["Component"] = "Unknown";
128
- }
129
-
130
- return $alertOptions;
131
- }
132
- }
1
+ <?php
2
+
3
+ class WSAL_Sensors_Database extends WSAL_AbstractSensor
4
+ {
5
+ public function HookEvents()
6
+ {
7
+ add_action('dbdelta_queries', array($this, 'EventDBDeltaQuery'));
8
+ add_action('query', array($this, 'EventDropQuery'));
9
+ }
10
+
11
+ public function EventDropQuery($query)
12
+ {
13
+ $table_names = array();
14
+ $str = explode(" ", $query);
15
+
16
+ if (preg_match("|DROP TABLE ([^ ]*)|", $query)) {
17
+ if (!empty($str[4])) {
18
+ array_push($table_names, $str[4]);
19
+ } else {
20
+ array_push($table_names, $str[2]);
21
+ }
22
+ $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
23
+ $alertOptions = $this->GetActionType($actype);
24
+ }
25
+
26
+ if (!empty($table_names)) {
27
+ $event_code = $this->GetEventQueryType($actype, "delete");
28
+ $alertOptions["TableNames"] = implode(",", $table_names);
29
+ $this->plugin->alerts->Trigger($event_code, $alertOptions);
30
+ }
31
+ return $query;
32
+ }
33
+
34
+ public function EventDBDeltaQuery($queries)
35
+ {
36
+ $typeQueries = array(
37
+ "create" => array(),
38
+ "update" => array(),
39
+ "delete" => array()
40
+ );
41
+ global $wpdb;
42
+
43
+ foreach ($queries as $qry) {
44
+ $str = explode(" ", $qry);
45
+ if (preg_match("|CREATE TABLE ([^ ]*)|", $qry)) {
46
+ if ($wpdb->get_var("SHOW TABLES LIKE '" . $str[2] . "'") != $str[2]) {
47
+ //some plugins keep trying to create tables even when they already exist- would result in too many alerts
48
+ array_push($typeQueries['create'], $str[2]);
49
+ }
50
+ } else if (preg_match("|ALTER TABLE ([^ ]*)|", $qry)) {
51
+ array_push($typeQueries['update'], $str[2]);
52
+ } else if (preg_match("|DROP TABLE ([^ ]*)|", $qry)) {
53
+ if (!empty($str[4])) {
54
+ array_push($typeQueries['delete'], $str[4]);
55
+ } else {
56
+ array_push($typeQueries['delete'], $str[2]);
57
+ }
58
+ }
59
+ }
60
+
61
+ if (!empty($typeQueries["create"]) || !empty($typeQueries["update"]) || !empty($typeQueries["delete"])) {
62
+ $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
63
+ $alertOptions = $this->GetActionType($actype);
64
+
65
+ foreach ($typeQueries as $queryType => $tableNames) {
66
+ if (!empty($tableNames)) {
67
+ $event_code = $this->GetEventQueryType($actype, $queryType);
68
+ $alertOptions["TableNames"] = implode(",", $tableNames);
69
+ $this->plugin->alerts->Trigger($event_code, $alertOptions);
70
+ }
71
+ }
72
+ }
73
+
74
+ return $queries;
75
+ }
76
+
77
+ protected function GetEventQueryType($type_action, $type_query)
78
+ {
79
+ switch ($type_action) {
80
+ case 'plugins':
81
+ if ($type_query == 'create') return 5010;
82
+ else if ($type_query == 'update') return 5011;
83
+ else if ($type_query == 'delete') return 5012;
84
+ case 'themes':
85
+ if ($type_query == 'create') return 5013;
86
+ else if ($type_query == 'update') return 5014;
87
+ else if ($type_query == 'delete') return 5015;
88
+ default:
89
+ if ($type_query == 'create') return 5016;
90
+ else if ($type_query == 'update') return 5017;
91
+ else if ($type_query == 'delete') return 5018;
92
+ }
93
+ }
94
+
95
+ protected function GetActionType($actype)
96
+ {
97
+ $is_themes = $actype == 'themes';
98
+ $is_plugins = $actype == 'plugins';
99
+ //Action Plugin Component
100
+ $alertOptions = array();
101
+ if ($is_plugins) {
102
+ if (isset($_REQUEST['plugin'])) {
103
+ $pluginFile = $_REQUEST['plugin'];
104
+ } else {
105
+ $pluginFile = $_REQUEST['checked'][0];
106
+ }
107
+ $pluginName = basename($pluginFile, '.php');
108
+ $pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
109
+ $pluginName = ucwords($pluginName);
110
+ $alertOptions["Plugin"] = (object)array(
111
+ 'Name' => $pluginName,
112
+ );
113
+ //Action Theme Component
114
+ } else if ($is_themes) {
115
+ if (isset($_REQUEST['theme'])) {
116
+ $themeName = $_REQUEST['theme'];
117
+ } else {
118
+ $themeName = $_REQUEST['checked'][0];
119
+ }
120
+ $themeName = str_replace(array('_', '-', ' '), ' ', $themeName);
121
+ $themeName = ucwords($themeName);
122
+ $alertOptions["Theme"] = (object)array(
123
+ 'Name' => $themeName,
124
+ );
125
+ //Action Unknown Component
126
+ } else {
127
+ $alertOptions["Component"] = "Unknown";
128
+ }
129
+
130
+ return $alertOptions;
131
+ }
132
+ }
classes/Sensors/Files.php CHANGED
@@ -1,55 +1,55 @@
1
- <?php
2
-
3
- class WSAL_Sensors_Files extends WSAL_AbstractSensor {
4
-
5
- public function HookEvents() {
6
- add_action('add_attachment', array($this, 'EventFileUploaded'));
7
- add_action('delete_attachment', array($this, 'EventFileUploadedDeleted'));
8
- add_action('admin_init', array($this, 'EventAdminInit'));
9
- }
10
-
11
- protected $IsFileUploaded = false;
12
-
13
- public function EventFileUploaded($attachmentID){
14
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
15
- if($action != 'upload-theme' && $action != 'upload-plugin'){
16
- $file = get_attached_file($attachmentID);
17
- $this->plugin->alerts->Trigger(2010, array(
18
- 'AttachmentID' => $attachmentID,
19
- 'FileName' => basename($file),
20
- 'FilePath' => dirname($file),
21
- ));
22
- }
23
- $this->IsFileUploaded = true;
24
- }
25
-
26
- public function EventFileUploadedDeleted($attachmentID){
27
- if($this->IsFileUploaded)return;
28
- $file = get_attached_file($attachmentID);
29
- $this->plugin->alerts->Trigger(2011, array(
30
- 'AttachmentID' => $attachmentID,
31
- 'FileName' => basename($file),
32
- 'FilePath' => dirname($file),
33
- ));
34
- }
35
-
36
- public function EventAdminInit(){
37
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
38
- $is_theme_editor = basename($_SERVER['SCRIPT_NAME']) == 'theme-editor.php';
39
- $is_plugin_editor = basename($_SERVER['SCRIPT_NAME']) == 'plugin-editor.php';
40
-
41
- if($is_theme_editor && $action == 'update'){
42
- $this->plugin->alerts->Trigger(2046, array(
43
- 'File' => $_REQUEST['file'],
44
- 'Theme' => $_REQUEST['theme'],
45
- ));
46
- }
47
-
48
- if($is_plugin_editor && $action == 'update'){
49
- $this->plugin->alerts->Trigger(2051, array(
50
- 'File' => $_REQUEST['file'],
51
- 'Plugin' => $_REQUEST['plugin'],
52
- ));
53
- }
54
- }
55
- }
1
+ <?php
2
+
3
+ class WSAL_Sensors_Files extends WSAL_AbstractSensor {
4
+
5
+ public function HookEvents() {
6
+ add_action('add_attachment', array($this, 'EventFileUploaded'));
7
+ add_action('delete_attachment', array($this, 'EventFileUploadedDeleted'));
8
+ add_action('admin_init', array($this, 'EventAdminInit'));
9
+ }
10
+
11
+ protected $IsFileUploaded = false;
12
+
13
+ public function EventFileUploaded($attachmentID){
14
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
15
+ if($action != 'upload-theme' && $action != 'upload-plugin'){
16
+ $file = get_attached_file($attachmentID);
17
+ $this->plugin->alerts->Trigger(2010, array(
18
+ 'AttachmentID' => $attachmentID,
19
+ 'FileName' => basename($file),
20
+ 'FilePath' => dirname($file),
21
+ ));
22
+ }
23
+ $this->IsFileUploaded = true;
24
+ }
25
+
26
+ public function EventFileUploadedDeleted($attachmentID){
27
+ if($this->IsFileUploaded)return;
28
+ $file = get_attached_file($attachmentID);
29
+ $this->plugin->alerts->Trigger(2011, array(
30
+ 'AttachmentID' => $attachmentID,
31
+ 'FileName' => basename($file),
32
+ 'FilePath' => dirname($file),
33
+ ));
34
+ }
35
+
36
+ public function EventAdminInit(){
37
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
38
+ $is_theme_editor = basename($_SERVER['SCRIPT_NAME']) == 'theme-editor.php';
39
+ $is_plugin_editor = basename($_SERVER['SCRIPT_NAME']) == 'plugin-editor.php';
40
+
41
+ if($is_theme_editor && $action == 'update'){
42
+ $this->plugin->alerts->Trigger(2046, array(
43
+ 'File' => $_REQUEST['file'],
44
+ 'Theme' => $_REQUEST['theme'],
45
+ ));
46
+ }
47
+
48
+ if($is_plugin_editor && $action == 'update'){
49
+ $this->plugin->alerts->Trigger(2051, array(
50
+ 'File' => $_REQUEST['file'],
51
+ 'Plugin' => $_REQUEST['plugin'],
52
+ ));
53
+ }
54
+ }
55
+ }
classes/Sensors/LogInOut.php CHANGED
@@ -1,215 +1,215 @@
1
- <?php
2
-
3
- class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor
4
- {
5
-
6
- public function HookEvents()
7
- {
8
- add_action('wp_login', array($this, 'EventLogin'), 10, 2);
9
- add_action('wp_logout', array($this, 'EventLogout'));
10
- add_action('password_reset', array($this, 'EventPasswordReset'), 10, 2);
11
- add_action('wp_login_failed', array($this, 'EventLoginFailure'));
12
- add_action('clear_auth_cookie', array($this, 'GetCurrentUser'), 10);
13
- add_filter('wp_login_blocked', array($this, 'EventLoginBlocked'), 10, 1);
14
- }
15
-
16
- protected $_current_user = null;
17
-
18
- public function GetCurrentUser()
19
- {
20
- $this->_current_user = wp_get_current_user();
21
- }
22
-
23
- public function EventLogin($user_login, $user = null)
24
- {
25
- if (empty($user)) {
26
- $user = get_user_by('login', $user_login);
27
- }
28
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
29
- if ($this->plugin->settings->IsLoginSuperAdmin($user_login)) {
30
- $userRoles[] = 'superadmin';
31
- }
32
- $this->plugin->alerts->Trigger(1000, array(
33
- 'Username' => $user_login,
34
- 'CurrentUserRoles' => $userRoles,
35
- ), true);
36
- }
37
-
38
- public function EventLogout()
39
- {
40
- if ($this->_current_user->ID != 0) {
41
- $this->plugin->alerts->Trigger(1001, array(
42
- 'CurrentUserID' => $this->_current_user->ID,
43
- 'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($this->_current_user->roles),
44
- ), true);
45
- }
46
- }
47
-
48
- const TRANSIENT_FAILEDLOGINS = 'wsal-failedlogins-known';
49
- const TRANSIENT_FAILEDLOGINS_UNKNOWN = 'wsal-failedlogins-unknown';
50
-
51
- protected function GetLoginFailureLogLimit()
52
- {
53
- return 10;
54
- }
55
-
56
- protected function GetLoginFailureExpiration()
57
- {
58
- return 12 * 60 * 60;
59
- }
60
-
61
- protected function IsPastLoginFailureLimit($ip, $site_id, $user)
62
- {
63
- $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
64
- if ($user) {
65
- $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
66
- return ($dataKnown !== false) && isset($dataKnown[$site_id.":".$user->ID.":".$ip]) && ($dataKnown[$site_id.":".$user->ID.":".$ip] > $this->GetLoginFailureLogLimit());
67
- } else {
68
- $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
69
- return ($dataUnknown !== false) && isset($dataUnknown[$site_id.":".$ip]) && ($dataUnknown[$site_id.":".$ip] > $this->GetLoginFailureLogLimit());
70
- }
71
- }
72
-
73
- protected function IncrementLoginFailure($ip, $site_id, $user)
74
- {
75
- $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
76
- $set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
77
- if ($user) {
78
- $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
79
- if (!$dataKnown) {
80
- $dataKnown = array();
81
- }
82
- if (!isset($dataKnown[$site_id.":".$user->ID.":".$ip])) {
83
- $dataKnown[$site_id.":".$user->ID.":".$ip] = 1;
84
- }
85
- $dataKnown[$site_id.":".$user->ID.":".$ip]++;
86
- $set_fn(self::TRANSIENT_FAILEDLOGINS, $dataKnown, $this->GetLoginFailureExpiration());
87
- } else {
88
- $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
89
- if (!$dataUnknown) {
90
- $dataUnknown = array();
91
- }
92
- if (!isset($dataUnknown[$site_id.":".$ip])) {
93
- $dataUnknown[$site_id.":".$ip] = 1;
94
- }
95
- $dataUnknown[$site_id.":".$ip]++;
96
- $set_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $dataUnknown, $this->GetLoginFailureExpiration());
97
- }
98
- }
99
-
100
- public function EventLoginFailure($username)
101
- {
102
- list($y, $m, $d) = explode('-', date('Y-m-d'));
103
-
104
- $ip = $this->plugin->settings->GetMainClientIP();
105
-
106
- $username = array_key_exists('log', $_POST) ? $_POST["log"] : $username;
107
- $newAlertCode = 1003;
108
- $user = get_user_by('login', $username);
109
- $site_id = (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
110
- if ($user) {
111
- $newAlertCode = 1002;
112
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
113
- if ($this->plugin->settings->IsLoginSuperAdmin($username)) {
114
- $userRoles[] = 'superadmin';
115
- }
116
- }
117
-
118
- if ($this->IsPastLoginFailureLimit($ip, $site_id, $user)) {
119
- return;
120
- }
121
-
122
- $objOcc = new WSAL_Models_Occurrence();
123
-
124
- if ($newAlertCode == 1002) {
125
- if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles)) {
126
- return;
127
- }
128
- $occ = $objOcc->CheckKnownUsers(
129
- array(
130
- $ip,
131
- $username,
132
- 1002,
133
- $site_id,
134
- mktime(0, 0, 0, $m, $d, $y),
135
- mktime(0, 0, 0, $m, $d + 1, $y) - 1
136
- )
137
- );
138
- $occ = count($occ) ? $occ[0] : null;
139
-
140
- if (!empty($occ)) {
141
- // update existing record exists user
142
- $this->IncrementLoginFailure($ip, $site_id, $user);
143
- $new = $occ->GetMetaValue('Attempts', 0) + 1;
144
-
145
- if ($new > $this->GetLoginFailureLogLimit()) {
146
- $new = $this->GetLoginFailureLogLimit() . '+';
147
- }
148
- $occ->UpdateMetaValue('Attempts', $new);
149
- $occ->UpdateMetaValue('Username', $username);
150
- //$occ->SetMetaValue('CurrentUserRoles', $userRoles);
151
- $occ->created_on = null;
152
- $occ->Save();
153
- } else {
154
- // create a new record exists user
155
- $this->plugin->alerts->Trigger($newAlertCode, array(
156
- 'Attempts' => 1,
157
- 'Username' => $username,
158
- 'CurrentUserRoles' => $userRoles
159
- ));
160
- }
161
- } else {
162
- $occUnknown = $objOcc->CheckUnKnownUsers(
163
- array(
164
- $ip,
165
- 1003,
166
- $site_id,
167
- mktime(0, 0, 0, $m, $d, $y),
168
- mktime(0, 0, 0, $m, $d + 1, $y) - 1
169
- )
170
- );
171
-
172
- $occUnknown = count($occUnknown) ? $occUnknown[0] : null;
173
- if (!empty($occUnknown)) {
174
- // update existing record not exists user
175
- $this->IncrementLoginFailure($ip, $site_id, false);
176
- $new = $occUnknown->GetMetaValue('Attempts', 0) + 1;
177
-
178
- if ($new > $this->GetLoginFailureLogLimit()) {
179
- $new = $this->GetLoginFailureLogLimit() . '+';
180
- }
181
- $occUnknown->UpdateMetaValue('Attempts', $new);
182
- $occUnknown->created_on = null;
183
- $occUnknown->Save();
184
- } else {
185
- // create a new record not exists user
186
- $this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1));
187
- }
188
- }
189
- }
190
-
191
- public function EventPasswordReset($user, $new_pass)
192
- {
193
- if (!empty($user)) {
194
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
195
- $this->plugin->alerts->Trigger(4003, array(
196
- 'Username' => $user->user_login,
197
- 'CurrentUserRoles' => $userRoles
198
- ), true);
199
- }
200
- }
201
-
202
- public function EventLoginBlocked($username)
203
- {
204
- $user = get_user_by('login', $username);
205
- $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
206
-
207
- if ($this->plugin->settings->IsLoginSuperAdmin($username)) {
208
- $userRoles[] = 'superadmin';
209
- }
210
- $this->plugin->alerts->Trigger(1004, array(
211
- 'Username' => $username,
212
- 'CurrentUserRoles' => $userRoles
213
- ), true);
214
- }
215
- }
1
+ <?php
2
+
3
+ class WSAL_Sensors_LogInOut extends WSAL_AbstractSensor
4
+ {
5
+
6
+ public function HookEvents()
7
+ {
8
+ add_action('wp_login', array($this, 'EventLogin'), 10, 2);
9
+ add_action('wp_logout', array($this, 'EventLogout'));
10
+ add_action('password_reset', array($this, 'EventPasswordReset'), 10, 2);
11
+ add_action('wp_login_failed', array($this, 'EventLoginFailure'));
12
+ add_action('clear_auth_cookie', array($this, 'GetCurrentUser'), 10);
13
+ add_filter('wp_login_blocked', array($this, 'EventLoginBlocked'), 10, 1);
14
+ }
15
+
16
+ protected $_current_user = null;
17
+
18
+ public function GetCurrentUser()
19
+ {
20
+ $this->_current_user = wp_get_current_user();
21
+ }
22
+
23
+ public function EventLogin($user_login, $user = null)
24
+ {
25
+ if (empty($user)) {
26
+ $user = get_user_by('login', $user_login);
27
+ }
28
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
29
+ if ($this->plugin->settings->IsLoginSuperAdmin($user_login)) {
30
+ $userRoles[] = 'superadmin';
31
+ }
32
+ $this->plugin->alerts->Trigger(1000, array(
33
+ 'Username' => $user_login,
34
+ 'CurrentUserRoles' => $userRoles,
35
+ ), true);
36
+ }
37
+
38
+ public function EventLogout()
39
+ {
40
+ if ($this->_current_user->ID != 0) {
41
+ $this->plugin->alerts->Trigger(1001, array(
42
+ 'CurrentUserID' => $this->_current_user->ID,
43
+ 'CurrentUserRoles' => $this->plugin->settings->GetCurrentUserRoles($this->_current_user->roles),
44
+ ), true);
45
+ }
46
+ }
47
+
48
+ const TRANSIENT_FAILEDLOGINS = 'wsal-failedlogins-known';
49
+ const TRANSIENT_FAILEDLOGINS_UNKNOWN = 'wsal-failedlogins-unknown';
50
+
51
+ protected function GetLoginFailureLogLimit()
52
+ {
53
+ return 10;
54
+ }
55
+
56
+ protected function GetLoginFailureExpiration()
57
+ {
58
+ return 12 * 60 * 60;
59
+ }
60
+
61
+ protected function IsPastLoginFailureLimit($ip, $site_id, $user)
62
+ {
63
+ $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
64
+ if ($user) {
65
+ $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
66
+ return ($dataKnown !== false) && isset($dataKnown[$site_id.":".$user->ID.":".$ip]) && ($dataKnown[$site_id.":".$user->ID.":".$ip] > $this->GetLoginFailureLogLimit());
67
+ } else {
68
+ $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
69
+ return ($dataUnknown !== false) && isset($dataUnknown[$site_id.":".$ip]) && ($dataUnknown[$site_id.":".$ip] > $this->GetLoginFailureLogLimit());
70
+ }
71
+ }
72
+
73
+ protected function IncrementLoginFailure($ip, $site_id, $user)
74
+ {
75
+ $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
76
+ $set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
77
+ if ($user) {
78
+ $dataKnown = $get_fn(self::TRANSIENT_FAILEDLOGINS);
79
+ if (!$dataKnown) {
80
+ $dataKnown = array();
81
+ }
82
+ if (!isset($dataKnown[$site_id.":".$user->ID.":".$ip])) {
83
+ $dataKnown[$site_id.":".$user->ID.":".$ip] = 1;
84
+ }
85
+ $dataKnown[$site_id.":".$user->ID.":".$ip]++;
86
+ $set_fn(self::TRANSIENT_FAILEDLOGINS, $dataKnown, $this->GetLoginFailureExpiration());
87
+ } else {
88
+ $dataUnknown = $get_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN);
89
+ if (!$dataUnknown) {
90
+ $dataUnknown = array();
91
+ }
92
+ if (!isset($dataUnknown[$site_id.":".$ip])) {
93
+ $dataUnknown[$site_id.":".$ip] = 1;
94
+ }
95
+ $dataUnknown[$site_id.":".$ip]++;
96
+ $set_fn(self::TRANSIENT_FAILEDLOGINS_UNKNOWN, $dataUnknown, $this->GetLoginFailureExpiration());
97
+ }
98
+ }
99
+
100
+ public function EventLoginFailure($username)
101
+ {
102
+ list($y, $m, $d) = explode('-', date('Y-m-d'));
103
+
104
+ $ip = $this->plugin->settings->GetMainClientIP();
105
+
106
+ $username = array_key_exists('log', $_POST) ? $_POST["log"] : $username;
107
+ $newAlertCode = 1003;
108
+ $user = get_user_by('login', $username);
109
+ $site_id = (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
110
+ if ($user) {
111
+ $newAlertCode = 1002;
112
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
113
+ if ($this->plugin->settings->IsLoginSuperAdmin($username)) {
114
+ $userRoles[] = 'superadmin';
115
+ }
116
+ }
117
+
118
+ if ($this->IsPastLoginFailureLimit($ip, $site_id, $user)) {
119
+ return;
120
+ }
121
+
122
+ $objOcc = new WSAL_Models_Occurrence();
123
+
124
+ if ($newAlertCode == 1002) {
125
+ if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles)) {
126
+ return;
127
+ }
128
+ $occ = $objOcc->CheckKnownUsers(
129
+ array(
130
+ $ip,
131
+ $username,
132
+ 1002,
133
+ $site_id,
134
+ mktime(0, 0, 0, $m, $d, $y),
135
+ mktime(0, 0, 0, $m, $d + 1, $y) - 1
136
+ )
137
+ );
138
+ $occ = count($occ) ? $occ[0] : null;
139
+
140
+ if (!empty($occ)) {
141
+ // update existing record exists user
142
+ $this->IncrementLoginFailure($ip, $site_id, $user);
143
+ $new = $occ->GetMetaValue('Attempts', 0) + 1;
144
+
145
+ if ($new > $this->GetLoginFailureLogLimit()) {
146
+ $new = $this->GetLoginFailureLogLimit() . '+';
147
+ }
148
+ $occ->UpdateMetaValue('Attempts', $new);
149
+ $occ->UpdateMetaValue('Username', $username);
150
+ //$occ->SetMetaValue('CurrentUserRoles', $userRoles);
151
+ $occ->created_on = null;
152
+ $occ->Save();
153
+ } else {
154
+ // create a new record exists user
155
+ $this->plugin->alerts->Trigger($newAlertCode, array(
156
+ 'Attempts' => 1,
157
+ 'Username' => $username,
158
+ 'CurrentUserRoles' => $userRoles
159
+ ));
160
+ }
161
+ } else {
162
+ $occUnknown = $objOcc->CheckUnKnownUsers(
163
+ array(
164
+ $ip,
165
+ 1003,
166
+ $site_id,
167
+ mktime(0, 0, 0, $m, $d, $y),
168
+ mktime(0, 0, 0, $m, $d + 1, $y) - 1
169
+ )
170
+ );
171
+
172
+ $occUnknown = count($occUnknown) ? $occUnknown[0] : null;
173
+ if (!empty($occUnknown)) {
174
+ // update existing record not exists user
175
+ $this->IncrementLoginFailure($ip, $site_id, false);
176
+ $new = $occUnknown->GetMetaValue('Attempts', 0) + 1;
177
+
178
+ if ($new > $this->GetLoginFailureLogLimit()) {
179
+ $new = $this->GetLoginFailureLogLimit() . '+';
180
+ }
181
+ $occUnknown->UpdateMetaValue('Attempts', $new);
182
+ $occUnknown->created_on = null;
183
+ $occUnknown->Save();
184
+ } else {
185
+ // create a new record not exists user
186
+ $this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1));
187
+ }
188
+ }
189
+ }
190
+
191
+ public function EventPasswordReset($user, $new_pass)
192
+ {
193
+ if (!empty($user)) {
194
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
195
+ $this->plugin->alerts->Trigger(4003, array(
196
+ 'Username' => $user->user_login,
197
+ 'CurrentUserRoles' => $userRoles
198
+ ), true);
199
+ }
200
+ }
201
+
202
+ public function EventLoginBlocked($username)
203
+ {
204
+ $user = get_user_by('login', $username);
205
+ $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles);
206
+
207
+ if ($this->plugin->settings->IsLoginSuperAdmin($username)) {
208
+ $userRoles[] = 'superadmin';
209
+ }
210
+ $this->plugin->alerts->Trigger(1004, array(
211
+ 'Username' => $username,
212
+ 'CurrentUserRoles' => $userRoles
213
+ ), true);
214
+ }
215
+ }
classes/Sensors/Menus.php CHANGED
@@ -1,416 +1,454 @@
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
+
16
+ add_action('wp_update_nav_menu_item', array($this, 'UpdateMenuItem'), 10, 3);
17
+ add_action('admin_menu', array($this, 'ManageMenuLocations'));
18
+
19
+ add_action('admin_init', array($this, 'EventAdminInit'));
20
+ // Customizer trigger
21
+ add_action('customize_register', array($this, 'CustomizeInit'));
22
+ add_action('customize_save_after', array($this, 'CustomizeSave'));
23
+ }
24
+
25
+ public function UpdateMenuItem($menu_id, $menu_item_db_id, $args)
26
+ {
27
+ $oldMenuItems = array();
28
+ if (isset($_POST['menu-item-title']) && isset($_POST['menu-name'])) {
29
+ $is_changed_order = false;
30
+ $is_sub_item = false;
31
+ $newMenuItems = array_keys($_POST['menu-item-title']);
32
+ $items = wp_get_nav_menu_items($menu_id);
33
+ if (!empty($this->_OldMenuItems)) {
34
+ foreach ($this->_OldMenuItems as $oldItem) {
35
+ if ($oldItem['menu_id'] == $menu_id) {
36
+ $item_id = $oldItem['item_id'];
37
+ if ($item_id == $menu_item_db_id) {
38
+ if ($oldItem['menu_order'] != $args['menu-item-position']) {
39
+ $is_changed_order = true;
40
+ }
41
+ if (isset($args['menu-item-parent-id']) && $args['menu-item-parent-id'] != 0) {
42
+ $is_sub_item = true;
43
+ }
44
+ }
45
+ $oldMenuItems[$item_id] = array("type" => $oldItem['object'], "title" => $oldItem['title'], "parent" => $oldItem['menu_item_parent']);
46
+ }
47
+ }
48
+ }
49
+ if ($is_changed_order) {
50
+ $item_name = $oldMenuItems[$menu_item_db_id]['title'];
51
+ $this->EventChangeOrder($item_name, $oldItem['menu_name']);
52
+ }
53
+ if ($is_sub_item) {
54
+ $item_parent_id = $args['menu-item-parent-id'];
55
+ $item_name = $oldMenuItems[$menu_item_db_id]['title'];
56
+ if ($oldMenuItems[$menu_item_db_id]['parent'] != $item_parent_id) {
57
+ $parent_name = $oldMenuItems[$item_parent_id]['title'];
58
+ $this->EventChangeSubItem($item_name, $parent_name, $_POST['menu-name']);
59
+ }
60
+ }
61
+
62
+ $addedItems = array_diff($newMenuItems, array_keys($oldMenuItems));
63
+ // Add Items to the menu
64
+ if (count($addedItems) > 0) {
65
+ if (in_array($menu_item_db_id, $addedItems)) {
66
+ $this->EventAddItems($_POST['menu-item-object'][$menu_item_db_id], $_POST['menu-item-title'][$menu_item_db_id], $_POST['menu-name']);
67
+ }
68
+ }
69
+ $removedItems = array_diff(array_keys($oldMenuItems), $newMenuItems);
70
+ // Remove items from the menu
71
+ if (count($removedItems) > 0) {
72
+ if (array_search($menu_item_db_id, $newMenuItems) == (count($newMenuItems)-1)) {
73
+ foreach ($removedItems as $removed_item_id) {
74
+ $this->EventRemoveItems($oldMenuItems[$removed_item_id]['type'], $oldMenuItems[$removed_item_id]['title'], $_POST['menu-name']);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ public function CreateMenu($term_id, $menu_data)
82
+ {
83
+ $this->plugin->alerts->Trigger(2078, array(
84
+ 'MenuName' => $menu_data['menu-name']
85
+ ));
86
+ }
87
+
88
+ public function ManageMenuLocations()
89
+ {
90
+ // Manage Location tab
91
+ if (isset($_POST['menu-locations'])) {
92
+ $new_locations = $_POST['menu-locations'];
93
+ if (isset($new_locations['primary'])) {
94
+ $this->LocationSetting($new_locations['primary'], 'primary');
95
+ }
96
+ if (isset($new_locations['social'])) {
97
+ $this->LocationSetting($new_locations['social'], 'social');
98
+ }
99
+ }
100
+ }
101
+
102
+ private function LocationSetting($new_location, $type)
103
+ {
104
+ $old_locations = get_nav_menu_locations();
105
+ if ($new_location != 0) {
106
+ $menu = wp_get_nav_menu_object($new_location);
107
+ if (!empty($old_locations[$type]) && $old_locations[$type] != $new_location) {
108
+ $this->EventMenuSetting($menu->name, "Enabled", "Location: ".$type." menu");
109
+ }
110
+ } else {
111
+ if (!empty($old_locations[$type])) {
112
+ $menu = wp_get_nav_menu_object($old_locations[$type]);
113
+ $this->EventMenuSetting($menu->name, "Disabled", "Location: ".$type." menu");
114
+ }
115
+ }
116
+ }
117
+
118
+ public function DeleteMenu($term_id)
119
+ {
120
+ if ($this->_OldMenu) {
121
+ $this->plugin->alerts->Trigger(2081, array(
122
+ 'MenuName' => $this->_OldMenu->name
123
+ ));
124
+ }
125
+ }
126
+
127
+ public function UpdateMenu($menu_id, $menu_data = null)
128
+ {
129
+ if (!empty($menu_data)) {
130
+ $contentNamesOld = array();
131
+ $contentTypesOld = array();
132
+ $contentOrderOld = array();
133
+
134
+ $items = wp_get_nav_menu_items($menu_id);
135
+ if (!empty($items)) {
136
+ foreach ($items as $item) {
137
+ array_push($contentNamesOld, $item->title);
138
+ array_push($contentTypesOld, $item->object);
139
+ $contentOrderOld[$item->ID] = $item->menu_order;
140
+ }
141
+ }
142
+ // Menu changed name
143
+ if (!empty($this->_OldMenuTerms) && isset($_POST['menu']) && isset($_POST['menu-name'])) {
144
+ foreach ($this->_OldMenuTerms as $oldMenuTerm) {
145
+ if ($oldMenuTerm['term_id'] == $_POST['menu']) {
146
+ if ($oldMenuTerm['name'] != $_POST['menu-name']) {
147
+ $this->EventChangeName($oldMenuTerm['name'], $_POST['menu-name']);
148
+ } else {
149
+ // Remove the last menu item
150
+ if (count($contentNamesOld) == 1 && count($contentTypesOld) == 1) {
151
+ $this->EventRemoveItems($contentTypesOld[0], $contentNamesOld[0], $_POST['menu-name']);
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ // Enable/Disable menu setting
158
+ $nav_menu_options = maybe_unserialize(get_option('nav_menu_options'));
159
+ $auto_add = null;
160
+ if (isset($nav_menu_options['auto_add'])) {
161
+ if (in_array($menu_id, $nav_menu_options['auto_add'])) {
162
+ if (empty($_POST['auto-add-pages'])) {
163
+ $auto_add = "Disabled";
164
+ }
165
+ } else {
166
+ if (isset($_POST['auto-add-pages'])) {
167
+ $auto_add = "Enabled";
168
+ }
169
+ }
170
+ } else {
171
+ if (isset($_POST['auto-add-pages'])) {
172
+ $auto_add = "Enabled";
173
+ }
174
+ }
175
+ // Alert 2082 Auto add pages
176
+ if (!empty($auto_add)) {
177
+ $this->EventMenuSetting($menu_data['menu-name'], $auto_add, "Auto add pages");
178
+ }
179
+
180
+ $nav_menu_locations = get_nav_menu_locations();
181
+
182
+ $locationPrimary = null;
183
+ if (isset($this->_OldMenuLocations['primary']) && isset($nav_menu_locations['primary'])) {
184
+ if ($nav_menu_locations['primary'] == $menu_id && $this->_OldMenuLocations['primary'] != $nav_menu_locations['primary']) {
185
+ $locationPrimary = "Enabled";
186
+ }
187
+ } elseif (empty($this->_OldMenuLocations['primary']) && isset($nav_menu_locations['primary'])) {
188
+ if ($nav_menu_locations['primary'] == $menu_id) {
189
+ $locationPrimary = "Enabled";
190
+ }
191
+ } elseif (isset($this->_OldMenuLocations['primary']) && empty($nav_menu_locations['primary'])) {
192
+ if ($this->_OldMenuLocations['primary'] == $menu_id) {
193
+ $locationPrimary = "Disabled";
194
+ }
195
+ }
196
+ // Alert 2082 Primary menu
197
+ if (!empty($locationPrimary)) {
198
+ $this->EventMenuSetting($menu_data['menu-name'], $locationPrimary, "Location: primary menu");
199
+ }
200
+
201
+ $locationSocial = null;
202
+ if (isset($this->_OldMenuLocations['social']) && isset($nav_menu_locations['social'])) {
203
+ if ($nav_menu_locations['social'] == $menu_id && $this->_OldMenuLocations['social'] != $nav_menu_locations['social']) {
204
+ $locationSocial = "Enabled";
205
+ }
206
+ } elseif (empty($this->_OldMenuLocations['social']) && isset($nav_menu_locations['social'])) {
207
+ if ($nav_menu_locations['social'] == $menu_id) {
208
+ $locationSocial = "Enabled";
209
+ }
210
+ } elseif (isset($this->_OldMenuLocations['social']) && empty($nav_menu_locations['social'])) {
211
+ if ($this->_OldMenuLocations['social'] == $menu_id) {
212
+ $locationSocial = "Disabled";
213
+ }
214
+ }
215
+ // Alert 2082 Social links menu
216
+ if (!empty($locationSocial)) {
217
+ $this->EventMenuSetting($menu_data['menu-name'], $locationSocial, "Location: social menu");
218
+ }
219
+ }
220
+ }
221
+
222
+ private function BuildOldMenuTermsAndItems()
223
+ {
224
+ $menus = wp_get_nav_menus();
225
+ if (!empty($menus)) {
226
+ foreach ($menus as $menu) {
227
+ array_push($this->_OldMenuTerms, array("term_id" => $menu->term_id, "name" => $menu->name));
228
+ $items = wp_get_nav_menu_items($menu->term_id);
229
+ if (!empty($items)) {
230
+ foreach ($items as $item) {
231
+ array_push($this->_OldMenuItems, array(
232
+ "menu_id" => $menu->term_id,
233
+ 'item_id' => $item->ID,
234
+ 'title' => $item->title,
235
+ 'object' => $item->object,
236
+ 'menu_name' => $menu->name,
237
+ 'menu_order' => $item->menu_order,
238
+ 'menu_item_parent' => $item->menu_item_parent
239
+ ));
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ public function EventAdminInit()
247
+ {
248
+ $is_nav_menu = basename($_SERVER['SCRIPT_NAME']) == 'nav-menus.php';
249
+ if ($is_nav_menu) {
250
+ if (isset($_GET['action']) && $_GET['action'] == 'delete') {
251
+ if (isset($_GET['menu'])) {
252
+ $this->_OldMenu = wp_get_nav_menu_object($_GET['menu']);
253
+ }
254
+ } else {
255
+ $this->BuildOldMenuTermsAndItems();
256
+ }
257
+ $this->_OldMenuLocations = get_nav_menu_locations();
258
+ }
259
+ }
260
+
261
+ public function CustomizeInit()
262
+ {
263
+ $this->BuildOldMenuTermsAndItems();
264
+ $this->_OldMenuLocations = get_nav_menu_locations();
265
+ }
266
+
267
+ /**
268
+ * Customize Events Function
269
+ */
270
+ public function CustomizeSave()
271
+ {
272
+ $updateMenus = array();
273
+ $menus = wp_get_nav_menus();
274
+ if (!empty($menus)) {
275
+ foreach ($menus as $menu) {
276
+ array_push($updateMenus, array("term_id" => $menu->term_id, "name" => $menu->name));
277
+ }
278
+ }
279
+ // Deleted Menu
280
+ if (isset($updateMenus) && isset($this->_OldMenuTerms)) {
281
+ $terms = array_diff(array_map('serialize', $this->_OldMenuTerms), array_map('serialize', $updateMenus));
282
+ $terms = array_map('unserialize', $terms);
283
+
284
+ if (isset($terms) && count($terms) > 0) {
285
+ foreach ($terms as $term) {
286
+ $this->plugin->alerts->Trigger(2081, array(
287
+ 'MenuName' => $term['name']
288
+ ));
289
+ }
290
+ }
291
+ }
292
+ if (isset($_POST['action']) && $_POST['action'] == 'customize_save') {
293
+ if (isset($_POST['wp_customize'], $_POST['customized'])) {
294
+ $customized = json_decode(wp_unslash($_POST['customized']), true);
295
+ if (is_array($customized)) {
296
+ foreach ($customized as $key => $value) {
297
+ if (!empty($value['nav_menu_term_id'])) {
298
+ $is_occurred_event = false;
299
+ $menu = wp_get_nav_menu_object($value['nav_menu_term_id']);
300
+ $content_name = !empty($value['title']) ? $value['title'] : "no title";
301
+ if (!empty($this->_OldMenuItems)) {
302
+ foreach ($this->_OldMenuItems as $old_item) {
303
+ $item_id = substr(trim($key, ']'), 14);
304
+ if ($old_item['item_id'] == $item_id) {
305
+ // Modified Items in the menu
306
+ if ($old_item['title'] != $content_name) {
307
+ $is_occurred_event = true;
308
+ $this->EventModifiedItems($value['type_label'], $content_name, $menu->name);
309
+ }
310
+ // Moved as a sub-item
311
+ if ($old_item['menu_item_parent'] != $value['menu_item_parent'] && $value['menu_item_parent'] != 0) {
312
+ $is_occurred_event = true;
313
+ $parent_name = $this->GetItemName($value['nav_menu_term_id'], $value['menu_item_parent']);
314
+ $this->EventChangeSubItem($content_name, $parent_name, $menu->name);
315
+ }
316
+ // Changed order of the objects in a menu
317
+ if ($old_item['menu_order'] != $value['position']) {
318
+ $is_occurred_event = true;
319
+ $this->EventChangeOrder($content_name, $menu->name);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ // Add Items to the menu
325
+ if (!$is_occurred_event) {
326
+ $menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : $menu->name;
327
+ $this->EventAddItems($value['type_label'], $content_name, $menu_name);
328
+ }
329
+ } else {
330
+ // Menu changed name
331
+ if (isset($updateMenus) && isset($this->_OldMenuTerms)) {
332
+ foreach ($this->_OldMenuTerms as $old_menu) {
333
+ foreach ($updateMenus as $update_menu) {
334
+ if ($old_menu['term_id'] == $update_menu['term_id'] && $old_menu['name'] != $update_menu['name']) {
335
+ $this->EventChangeName($old_menu['name'], $update_menu['name']);
336
+ }
337
+ }
338
+ }
339
+ }
340
+ // Setting Auto add pages
341
+ if (!empty($value) && isset($value['auto_add'])) {
342
+ if ($value['auto_add']) {
343
+ $this->EventMenuSetting($value['name'], 'Enabled', "Auto add pages");
344
+ } else {
345
+ $this->EventMenuSetting($value['name'], 'Disabled', "Auto add pages");
346
+ }
347
+ }
348
+ // Setting Location
349
+ if (false !== strpos($key, 'nav_menu_locations[')) {
350
+ $loc = substr(trim($key, ']'), 19);
351
+ if (!empty($value)) {
352
+ $menu = wp_get_nav_menu_object($value);
353
+ $menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : (!empty($menu) ? $menu->name : '');
354
+ $this->EventMenuSetting($menu_name, "Enabled", "Location: ".$loc." menu");
355
+ } else {
356
+ if (!empty($this->_OldMenuLocations[$loc])) {
357
+ $menu = wp_get_nav_menu_object($this->_OldMenuLocations[$loc]);
358
+ $menu_name = !empty($customized['new_menu_name']) ? $customized['new_menu_name'] : (!empty($menu) ? $menu->name : '');
359
+ $this->EventMenuSetting($menu_name, "Disabled", "Location: ".$loc." menu");
360
+ }
361
+ }
362
+ }
363
+ // Remove items from the menu
364
+ if (false !== strpos($key, 'nav_menu_item[')) {
365
+ $item_id = substr(trim($key, ']'), 14);
366
+ if (!empty($this->_OldMenuItems)) {
367
+ foreach ($this->_OldMenuItems as $old_item) {
368
+ if ($old_item['item_id'] == $item_id) {
369
+ $this->EventRemoveItems($old_item['object'], $old_item['title'], $old_item['menu_name']);
370
+ }
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
377
+ }
378
+ }
379
+ }
380
+
381
+ private function EventAddItems($content_type, $content_name, $menu_name)
382
+ {
383
+ $this->plugin->alerts->Trigger(2079, array(
384
+ 'ContentType' => $content_type,
385
+ 'ContentName' => $content_name,
386
+ 'MenuName' => $menu_name
387
+ ));
388
+ }
389
+
390
+ private function EventRemoveItems($content_type, $content_name, $menu_name)
391
+ {
392
+ $this->plugin->alerts->Trigger(2080, array(
393
+ 'ContentType' => $content_type,
394
+ 'ContentName' => $content_name,
395
+ 'MenuName' => $menu_name
396
+ ));
397
+ }
398
+
399
+ private function EventMenuSetting($menu_name, $status, $menu_setting)
400
+ {
401
+ $this->plugin->alerts->Trigger(2082, array(
402
+ 'Status' => $status,
403
+ 'MenuSetting' => $menu_setting,
404
+ 'MenuName' => $menu_name
405
+ ));
406
+ }
407
+
408
+ private function EventModifiedItems($content_type, $content_name, $menu_name)
409
+ {
410
+ $this->plugin->alerts->Trigger(2083, array(
411
+ 'ContentType' => $content_type,
412
+ 'ContentName' => $content_name,
413
+ 'MenuName' => $menu_name
414
+ ));
415
+ }
416
+
417
+ private function EventChangeName($old_menu_name, $new_menu_name)
418
+ {
419
+ $this->plugin->alerts->Trigger(2084, array(
420
+ 'OldMenuName' => $old_menu_name,
421
+ 'NewMenuName' => $new_menu_name
422
+ ));
423
+ }
424
+
425
+ private function EventChangeOrder($item_name, $menu_name)
426
+ {
427
+ $this->plugin->alerts->Trigger(2085, array(
428
+ 'ItemName' => $item_name,
429
+ 'MenuName' => $menu_name
430
+ ));
431
+ }
432
+
433
+ private function EventChangeSubItem($item_name, $parent_name, $menu_name)
434
+ {
435
+ $this->plugin->alerts->Trigger(2089, array(
436
+ 'ItemName' => $item_name,
437
+ 'ParentName' => $parent_name,
438
+ 'MenuName' => $menu_name
439
+ ));
440
+ }
441
+
442
+ private function GetItemName($term_id, $item_id)
443
+ {
444
+ $item_name = '';
445
+ $menu_items = wp_get_nav_menu_items($term_id);
446
+ foreach ($menu_items as $menu_item) {
447
+ if ($menu_item->ID == $item_id) {
448
+ $item_name = $menu_item->title;
449
+ break;
450
+ }
451
+ }
452
+ return $item_name;
453
+ }
454
+ }
classes/Sensors/MetaData.php CHANGED
@@ -1,208 +1,265 @@
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
+ if (in_array($custom, $customFields)) {
32
+ return true;
33
+ }
34
+ foreach ($customFields as $field) {
35
+ if (strpos($field, "*") !== false) {
36
+ // wildcard str[any_character] when you enter (str*)
37
+ if (substr($field, -1) == '*') {
38
+ $field = rtrim($field, '*');
39
+ if (preg_match("/^$field/", $custom)) {
40
+ return true;
41
+ }
42
+ }
43
+ // wildcard [any_character]str when you enter (*str)
44
+ if (substr($field, 0, 1) == '*') {
45
+ $field = ltrim($field, '*');
46
+ if (preg_match("/$field$/", $custom)) {
47
+ return true;
48
+ }
49
+ }
50
+ }
51
+ }
52
+ return false;
53
+ //return (in_array($custom, $customFields)) ? true : false;
54
+ }
55
+
56
+ public function EventPostMetaCreated($object_id, $meta_key, $meta_value)
57
+ {
58
+ $post = get_post($object_id);
59
+ if (!$this->CanLogPostMeta($object_id, $meta_key)) return;
60
+
61
+ $WPActions = array('add-meta');
62
+ if (isset($_POST['action']) && in_array($_POST['action'], $WPActions)) {
63
+ $editorLink = $this->GetEditorLink($post);
64
+ switch ($post->post_type) {
65
+ case 'page':
66
+ $this->plugin->alerts->Trigger(2059, array(
67
+ 'PostID' => $object_id,
68
+ 'PostTitle' => $post->post_title,
69
+ 'MetaKey' => $meta_key,
70
+ 'MetaValue' => $meta_value,
71
+ 'MetaLink' => $meta_key,
72
+ $editorLink['name'] => $editorLink['value']
73
+ ));
74
+ break;
75
+ case 'post':
76
+ $this->plugin->alerts->Trigger(2053, array(
77
+ 'PostID' => $object_id,
78
+ 'PostTitle' => $post->post_title,
79
+ 'MetaKey' => $meta_key,
80
+ 'MetaValue' => $meta_value,
81
+ 'MetaLink' => $meta_key,
82
+ $editorLink['name'] => $editorLink['value']
83
+ ));
84
+ break;
85
+ default:
86
+ $this->plugin->alerts->Trigger(2056, array(
87
+ 'PostID' => $object_id,
88
+ 'PostTitle' => $post->post_title,
89
+ 'PostType' => $post->post_type,
90
+ 'MetaKey' => $meta_key,
91
+ 'MetaValue' => $meta_value,
92
+ 'MetaLink' => $meta_key,
93
+ $editorLink['name'] => $editorLink['value']
94
+ ));
95
+ break;
96
+ }
97
+ }
98
+ }
99
+
100
+ public function EventPostMetaUpdating($meta_id, $object_id, $meta_key)
101
+ {
102
+ static $meta_type = 'post';
103
+ $this->old_meta[$meta_id] = (object)array(
104
+ 'key' => ($meta = get_metadata_by_mid($meta_type, $meta_id)) ? $meta->meta_key : $meta_key,
105
+ 'val' => get_metadata($meta_type, $object_id, $meta_key, true),
106
+ );
107
+ }
108
+
109
+ public function EventPostMetaUpdated($meta_id, $object_id, $meta_key, $meta_value)
110
+ {
111
+ $post = get_post($object_id);
112
+
113
+ if (!$this->CanLogPostMeta($object_id, $meta_key)) return;
114
+
115
+ $WPActions = array('add-meta');
116
+ if (isset($_POST['action']) && in_array($_POST['action'], $WPActions)) {
117
+ $editorLink = $this->GetEditorLink($post);
118
+ if (isset($this->old_meta[$meta_id])) {
119
+ // check change in meta key
120
+ if ($this->old_meta[$meta_id]->key != $meta_key) {
121
+ switch ($post->post_type) {
122
+ case 'page':
123
+ $this->plugin->alerts->Trigger(2064, array(
124
+ 'PostID' => $object_id,
125
+ 'PostTitle' => $post->post_title,
126
+ 'MetaID' => $meta_id,
127
+ 'MetaKeyNew' => $meta_key,
128
+ 'MetaKeyOld' => $this->old_meta[$meta_id]->key,
129
+ 'MetaValue' => $meta_value,
130
+ 'MetaLink' => $meta_key,
131
+ $editorLink['name'] => $editorLink['value']
132
+ ));
133
+ break;
134
+ case 'post':
135
+ $this->plugin->alerts->Trigger(2062, array(
136
+ 'PostID' => $object_id,
137
+ 'PostTitle' => $post->post_title,
138
+ 'MetaID' => $meta_id,
139
+ 'MetaKeyNew' => $meta_key,
140
+ 'MetaKeyOld' => $this->old_meta[$meta_id]->key,
141
+ 'MetaValue' => $meta_value,
142
+ 'MetaLink' => $meta_key,
143
+ $editorLink['name'] => $editorLink['value']
144
+ ));
145
+ break;
146
+ default:
147
+ $this->plugin->alerts->Trigger(2063, array(
148
+ 'PostID' => $object_id,
149
+ 'PostTitle' => $post->post_title,
150
+ 'PostType' => $post->post_type,
151
+ 'MetaID' => $meta_id,
152
+ 'MetaKeyNew' => $meta_key,
153
+ 'MetaKeyOld' => $this->old_meta[$meta_id]->key,
154
+ 'MetaValue' => $meta_value,
155
+ 'MetaLink' => $smeta_key,
156
+ $editorLink['name'] => $editorLink['value']
157
+ ));
158
+ break;
159
+ }
160
+ } else if ($this->old_meta[$meta_id]->val != $meta_value) { // check change in meta value
161
+ switch ($post->post_type) {
162
+ case 'page':
163
+ $this->plugin->alerts->Trigger(2060, array(
164
+ 'PostID' => $object_id,
165
+ 'PostTitle' => $post->post_title,
166
+ 'MetaID' => $meta_id,
167
+ 'MetaKey' => $meta_key,
168
+ 'MetaValueNew' => $meta_value,
169
+ 'MetaValueOld' => $this->old_meta[$meta_id]->val,
170
+ 'MetaLink' => $meta_key,
171
+ $editorLink['name'] => $editorLink['value']
172
+ ));
173
+ break;
174
+ case 'post':
175
+ $this->plugin->alerts->Trigger(2054, array(
176
+ 'PostID' => $object_id,
177
+ 'PostTitle' => $post->post_title,
178
+ 'MetaID' => $meta_id,
179
+ 'MetaKey' => $meta_key,
180
+ 'MetaValueNew' => $meta_value,
181
+ 'MetaValueOld' => $this->old_meta[$meta_id]->val,
182
+ 'MetaLink' => $meta_key,
183
+ $editorLink['name'] => $editorLink['value']
184
+ ));
185
+ break;
186
+ default:
187
+ $this->plugin->alerts->Trigger(2057, array(
188
+ 'PostID' => $object_id,
189
+ 'PostTitle' => $post->post_title,
190
+ 'PostType' => $post->post_type,
191
+ 'MetaID' => $meta_id,
192
+ 'MetaKey' => $meta_key,
193
+ 'MetaValueNew' => $meta_value,
194
+ 'MetaValueOld' => $this->old_meta[$meta_id]->val,
195
+ 'MetaLink' => $meta_key,
196
+ $editorLink['name'] => $editorLink['value']
197
+ ));
198
+ break;
199
+ }
200
+ }
201
+ // remove old meta update data
202
+ unset($this->old_meta[$meta_id]);
203
+ }
204
+ }
205
+ }
206
+
207
+ public function EventPostMetaDeleted($meta_ids, $object_id, $meta_key, $meta_value)
208
+ {
209
+ $post = get_post($object_id);
210
+
211
+ $WPActions = array('delete-meta');
212
+ if (isset($_POST['action']) && in_array($_POST['action'], $WPActions)) {
213
+ $editorLink = $this->GetEditorLink($post);
214
+ foreach ($meta_ids as $meta_id) {
215
+ if (!$this->CanLogPostMeta($object_id, $meta_key)) continue;
216
+
217
+ switch ($post->post_type) {
218
+ case 'page':
219
+ $this->plugin->alerts->Trigger(2061, array(
220
+ 'PostID' => $object_id,
221
+ 'PostTitle' => $post->post_title,
222
+ 'MetaID' => $meta_id,
223
+ 'MetaKey' => $meta_key,
224
+ 'MetaValue' => $meta_value,
225
+ $editorLink['name'] => $editorLink['value']
226
+ ));
227
+ break;
228
+ case 'post':
229
+ $this->plugin->alerts->Trigger(2055, array(
230
+ 'PostID' => $object_id,
231
+ 'PostTitle' => $post->post_title,
232
+ 'MetaID' => $meta_id,
233
+ 'MetaKey' => $meta_key,
234
+ 'MetaValue' => $meta_value,
235
+ $editorLink['name'] => $editorLink['value']
236
+ ));
237
+ break;
238
+ default:
239
+ $this->plugin->alerts->Trigger(2058, array(
240
+ 'PostID' => $object_id,
241
+ 'PostTitle' => $post->post_title,
242
+ 'PostType' => $post->post_type,
243
+ 'MetaID' => $meta_id,
244
+ 'MetaKey' => $meta_key,
245
+ 'MetaValue' => $meta_value,
246
+ $editorLink['name'] => $editorLink['value']
247
+ ));
248
+ break;
249
+ }
250
+ }
251
+ }
252
+ }
253
+
254
+ private function GetEditorLink($post)
255
+ {
256
+ $name = 'EditorLink';
257
+ $name .= ($post->post_type == 'page') ? 'Page' : 'Post' ;
258
+ $value = get_edit_post_link($post->ID);
259
+ $aLink = array(
260
+ 'name' => $name,
261
+ 'value' => $value,
262
+ );
263
+ return $aLink;
264
+ }
265
+ }
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,286 @@
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
+
6
+ public function HookEvents() {
7
+ $hasPermission = (current_user_can("install_plugins") || current_user_can("activate_plugins") ||
8
+ current_user_can("delete_plugins") || current_user_can("update_plugins") || current_user_can("install_themes"));
9
+
10
+ add_action('admin_init', array($this, 'EventAdminInit'));
11
+ if($hasPermission)add_action('shutdown', array($this, 'EventAdminShutdown'));
12
+ add_action('switch_theme', array($this, 'EventThemeActivated'));
13
+ // TO DO
14
+ add_action('wp_insert_post', array($this, 'EventPluginPostCreate'), 10, 2);
15
+ add_action('delete_post', array($this, 'EventPluginPostDelete'), 10, 1);
16
+ }
17
+
18
+ protected $old_themes = array();
19
+ protected $old_plugins = array();
20
+
21
+ public function EventAdminInit() {
22
+ $this->old_themes = wp_get_themes();
23
+ $this->old_plugins = get_plugins();
24
+ }
25
+
26
+ public function EventAdminShutdown() {
27
+ $action = (isset($_REQUEST['action']) && $_REQUEST['action'] != "-1") ? $_REQUEST['action'] : '';
28
+ $action = (isset($_REQUEST['action2']) && $_REQUEST['action2'] != "-1") ? $_REQUEST['action2'] : $action;
29
+ $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
30
+ $is_themes = $actype == 'themes';
31
+ $is_plugins = $actype == 'plugins';
32
+
33
+ // install plugin
34
+ if (in_array($action, array('install-plugin', 'upload-plugin')) && current_user_can("install_plugins")) {
35
+ $plugin = array_values(array_diff(array_keys(get_plugins()), array_keys($this->old_plugins)));
36
+ if (count($plugin) != 1) {
37
+ return $this->LogError(
38
+ 'Expected exactly one new plugin but found ' . count($plugin),
39
+ array('NewPlugin' => $plugin, 'OldPlugins' => $this->old_plugins, 'NewPlugins' => get_plugins())
40
+ );
41
+ }
42
+ $pluginPath = $plugin[0];
43
+ $plugin = get_plugins();
44
+ $plugin = $plugin[$pluginPath];
45
+ $pluginPath = plugin_dir_path(WP_PLUGIN_DIR . '/' . $pluginPath[0]);
46
+ $this->plugin->alerts->Trigger(5000, array(
47
+ 'Plugin' => (object)array(
48
+ 'Name' => $plugin['Name'],
49
+ 'PluginURI' => $plugin['PluginURI'],
50
+ 'Version' => $plugin['Version'],
51
+ 'Author' => $plugin['Author'],
52
+ 'Network' => $plugin['Network'] ? 'True' : 'False',
53
+ 'plugin_dir_path' => $pluginPath,
54
+ ),
55
+ ));
56
+ }
57
+
58
+ // activate plugin
59
+ if ($is_plugins && in_array($action, array('activate', 'activate-selected')) && current_user_can("activate_plugins")) {
60
+ if (isset($_REQUEST['plugin'])) {
61
+ if (!isset($_REQUEST['checked'])) {
62
+ $_REQUEST['checked'] = array();
63
+ }
64
+ $_REQUEST['checked'][] = $_REQUEST['plugin'];
65
+ }
66
+ foreach ($_REQUEST['checked'] as $pluginFile) {
67
+ $pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
68
+ $pluginData = get_plugin_data($pluginFile, false, true);
69
+ $this->plugin->alerts->Trigger(5001, array(
70
+ 'PluginFile' => $pluginFile,
71
+ 'PluginData' => (object)array(
72
+ 'Name' => $pluginData['Name'],
73
+ 'PluginURI' => $pluginData['PluginURI'],
74
+ 'Version' => $pluginData['Version'],
75
+ 'Author' => $pluginData['Author'],
76
+ 'Network' => $pluginData['Network'] ? 'True' : 'False',
77
+ ),
78
+ ));
79
+ }
80
+ }
81
+
82
+ // deactivate plugin
83
+ if ($is_plugins && in_array($action, array('deactivate', 'deactivate-selected')) && current_user_can("activate_plugins")) {
84
+ if (isset($_REQUEST['plugin'])) {
85
+ if (!isset($_REQUEST['checked'])) {
86
+ $_REQUEST['checked'] = array();
87
+ }
88
+ $_REQUEST['checked'][] = $_REQUEST['plugin'];
89
+ }
90
+ foreach ($_REQUEST['checked'] as $pluginFile) {
91
+ $pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
92
+ $pluginData = get_plugin_data($pluginFile, false, true);
93
+ $this->plugin->alerts->Trigger(5002, array(
94
+ 'PluginFile' => $pluginFile,
95
+ 'PluginData' => (object)array(
96
+ 'Name' => $pluginData['Name'],
97
+ 'PluginURI' => $pluginData['PluginURI'],
98
+ 'Version' => $pluginData['Version'],
99
+ 'Author' => $pluginData['Author'],
100
+ 'Network' => $pluginData['Network'] ? 'True' : 'False',
101
+ ),
102
+ ));
103
+ }
104
+ }
105
+
106
+ // uninstall plugin
107
+ if ($is_plugins && in_array($action, array('delete-selected')) && current_user_can("delete_plugins")) {
108
+ if (!isset($_REQUEST['verify-delete'])) {
109
+ // first step, before user approves deletion
110
+ // TODO store plugin data in session here
111
+ } else {
112
+ // second step, after deletion approval
113
+ // TODO use plugin data from session
114
+ foreach ($_REQUEST['checked'] as $pluginFile) {
115
+ $pluginName = basename($pluginFile, '.php');
116
+ $pluginName = str_replace(array('_', '-', ' '), ' ', $pluginName);
117
+ $pluginName = ucwords($pluginName);
118
+ $pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
119
+ $this->plugin->alerts->Trigger(5003, array(
120
+ 'PluginFile' => $pluginFile,
121
+ 'PluginData' => (object)array(
122
+ 'Name' => $pluginName,
123
+ ),
124
+ ));
125
+ }
126
+ }
127
+ }
128
+
129
+ // upgrade plugin
130
+ if (in_array($action, array('upgrade-plugin', 'update-plugin', 'update-selected')) && current_user_can("update_plugins")) {
131
+ $plugins = array();
132
+ if (isset($_REQUEST['plugins'])) {
133
+ $plugins = explode(",", $_REQUEST['plugins']);
134
+ } else if (isset($_REQUEST['plugin'])) {
135
+ $plugins[] = $_REQUEST['plugin'];
136
+ }
137
+ if (isset($plugins)) {
138
+ foreach ($plugins as $pluginFile) {
139
+ $pluginFile = WP_PLUGIN_DIR . '/' . $pluginFile;
140
+ $pluginData = get_plugin_data($pluginFile, false, true);
141
+ $this->plugin->alerts->Trigger(5004, array(
142
+ 'PluginFile' => $pluginFile,
143
+ 'PluginData' => (object)array(
144
+ 'Name' => $pluginData['Name'],
145
+ 'PluginURI' => $pluginData['PluginURI'],
146
+ 'Version' => $pluginData['Version'],
147
+ 'Author' => $pluginData['Author'],
148
+ 'Network' => $pluginData['Network'] ? 'True' : 'False',
149
+ ),
150
+ ));
151
+ }
152
+ }
153
+ }
154
+
155
+ // update theme
156
+ if (in_array($action, array('upgrade-theme')) && current_user_can("install_themes")) {
157
+ if (isset($_REQUEST['theme'])) {
158
+ $theme = wp_get_theme($_REQUEST['theme']);
159
+ $this->plugin->alerts->Trigger(5031, array(
160
+ 'Theme' => (object)array(
161
+ 'Name' => $theme->Name,
162
+ 'ThemeURI' => $theme->ThemeURI,
163
+ 'Description' => $theme->Description,
164
+ 'Author' => $theme->Author,
165
+ 'Version' => $theme->Version,
166
+ 'get_template_directory' => $theme->get_template_directory(),
167
+ ),
168
+ ));
169
+ }
170
+ }
171
+
172
+ // install theme
173
+ if (in_array($action, array('install-theme', 'upload-theme')) && current_user_can("install_themes")) {
174
+ $themes = array_diff(wp_get_themes(), $this->old_themes);
175
+ foreach ($themes as $theme) {
176
+ $this->plugin->alerts->Trigger(5005, array(
177
+ 'Theme' => (object)array(
178
+ 'Name' => $theme->Name,
179
+ 'ThemeURI' => $theme->ThemeURI,
180
+ 'Description' => $theme->Description,
181
+ 'Author' => $theme->Author,
182
+ 'Version' => $theme->Version,
183
+ 'get_template_directory' => $theme->get_template_directory(),
184
+ ),
185
+ ));
186
+ }
187
+ }
188
+
189
+ // uninstall theme
190
+ if ($is_themes && in_array($action, array('delete-selected', 'delete')) && current_user_can("install_themes")) {
191
+ foreach ($this->GetRemovedThemes() as $theme) {
192
+ $this->plugin->alerts->Trigger(5007, array(
193
+ 'Theme' => (object)array(
194
+ 'Name' => $theme->Name,
195
+ 'ThemeURI' => $theme->ThemeURI,
196
+ 'Description' => $theme->Description,
197
+ 'Author' => $theme->Author,
198
+ 'Version' => $theme->Version,
199
+ 'get_template_directory' => $theme->get_template_directory(),
200
+ ),
201
+ ));
202
+ }
203
+ }
204
+ }
205
+
206
+ public function EventThemeActivated($themeName){
207
+ $theme = null;
208
+ foreach (wp_get_themes() as $item) {
209
+ if ($item->Name == $themeName) {
210
+ $theme = $item;
211
+ break;
212
+ }
213
+ }
214
+ if ($theme == null) {
215
+ return $this->LogError(
216
+ 'Could not locate theme named "' . $theme . '".',
217
+ array('ThemeName' => $themeName, 'Themes' => wp_get_themes())
218
+ );
219
+ }
220
+ $this->plugin->alerts->Trigger(5006, array(
221
+ 'Theme' => (object)array(
222
+ 'Name' => $theme->Name,
223
+ 'ThemeURI' => $theme->ThemeURI,
224
+ 'Description' => $theme->Description,
225
+ 'Author' => $theme->Author,
226
+ 'Version' => $theme->Version,
227
+ 'get_template_directory' => $theme->get_template_directory(),
228
+ ),
229
+ ));
230
+ }
231
+
232
+ public function EventPluginPostCreate($insert, $post)
233
+ {
234
+ $WPActions = array('editpost', 'heartbeat', 'inline-save');
235
+ if (isset($_REQUEST['action']) && !in_array($_REQUEST['action'], $WPActions)) {
236
+ if (!in_array($post->post_type, array('attachment', 'revision', 'nav_menu_item'))) {
237
+ $event = $this->GetEventTypeForPostType($post, 5019, 5020, 5021);
238
+ $this->plugin->alerts->Trigger($event, array(
239
+ 'PostID' => $post->ID,
240
+ 'PostType' => $post->post_type,
241
+ 'PostTitle' => $post->post_title,
242
+ 'Username' => 'Plugins'
243
+ ));
244
+ }
245
+ }
246
+ }
247
+
248
+ public function EventPluginPostDelete($post_id)
249
+ {
250
+ if (empty($_REQUEST['action']) && isset($_REQUEST['page'])) {
251
+ $post = get_post($post_id);
252
+ if (!in_array($post->post_type, array('attachment', 'revision', 'nav_menu_item'))) {
253
+ $event = $this->GetEventTypeForPostType($post, 5025, 5026, 5027);
254
+ $this->plugin->alerts->Trigger($event, array(
255
+ 'PostID' => $post->ID,
256
+ 'PostType' => $post->post_type,
257
+ 'PostTitle' => $post->post_title,
258
+ 'Username' => 'Plugins'
259
+ ));
260
+ }
261
+ }
262
+ }
263
+
264
+ protected function GetRemovedThemes()
265
+ {
266
+ $result = $this->old_themes;
267
+ foreach ($result as $i => $theme) {
268
+ if (file_exists($theme->get_template_directory())) {
269
+ unset($result[$i]);
270
+ }
271
+ }
272
+ return array_values($result);
273
+ }
274
+
275
+ protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
276
+ {
277
+ switch ($post->post_type) {
278
+ case 'page':
279
+ return $typePage;
280
+ case 'post':
281
+ return $typePost;
282
+ default:
283
+ return $typeCustom;
284
+ }
285
+ }
286
+ }
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,265 @@
1
- <?php
2
-
3
- class WSAL_Sensors_System extends WSAL_AbstractSensor
4
- {
5
-
6
- public function HookEvents()
7
- {
8
- add_action('wsal_prune', array($this, 'EventPruneEvents'), 10, 2);
9
- add_action('admin_init', array($this, 'EventAdminInit'));
10
-
11
- add_action('automatic_updates_complete', array($this, 'WPUpdate'), 10, 1);
12
- }
13
-
14
- /**
15
- * @param int $count The number of deleted events.
16
- * @param string $query Query that selected events for deletion.
17
- */
18
- public function EventPruneEvents($count, $query)
19
- {
20
- $this->plugin->alerts->Trigger(6000, array(
21
- 'EventCount' => $count,
22
- 'PruneQuery' => $query,
23
- ));
24
- }
25
-
26
- public function EventAdminInit()
27
- {
28
- // make sure user can actually modify target options
29
- if (!current_user_can('manage_options')) return;
30
-
31
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
32
- $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
33
- $is_option_page = $actype == 'options';
34
- $is_network_settings = $actype == 'settings';
35
- $is_permalink_page = $actype == 'options-permalink';
36
-
37
- if ($is_option_page && (get_option('users_can_register') xor isset($_POST['users_can_register']))) {
38
- $old = get_option('users_can_register') ? 'Enabled' : 'Disabled';
39
- $new = isset($_POST['users_can_register']) ? 'Enabled' : 'Disabled';
40
- if ($old !== $new) {
41
- $this->plugin->alerts->Trigger(6001, array(
42
- 'OldValue' => $old,
43
- 'NewValue' => $new,
44
- 'CurrentUserID' => wp_get_current_user()->ID,
45
- ));
46
- }
47
- }
48
-
49
- if ($is_option_page && !empty($_POST['default_role'])) {
50
- $old = get_option('default_role');
51
- $new = trim($_POST['default_role']);
52
- if ($old !== $new) {
53
- $this->plugin->alerts->Trigger(6002, array(
54
- 'OldRole' => $old,
55
- 'NewRole' => $new,
56
- 'CurrentUserID' => wp_get_current_user()->ID,
57
- ));
58
- }
59
- }
60
-
61
- if ($is_option_page && !empty($_POST['admin_email'])) {
62
- $old = get_option('admin_email');
63
- $new = trim($_POST['admin_email']);
64
- if ($old !== $new) {
65
- $this->plugin->alerts->Trigger(6003, array(
66
- 'OldEmail' => $old,
67
- 'NewEmail' => $new,
68
- 'CurrentUserID' => wp_get_current_user()->ID,
69
- ));
70
- }
71
- }
72
-
73
- if ($is_network_settings && !empty($_POST['admin_email'])) {
74
- $old = get_site_option('admin_email');
75
- $new = trim($_POST['admin_email']);
76
- if ($old !== $new) {
77
- $this->plugin->alerts->Trigger(6003, array(
78
- 'OldEmail' => $old,
79
- 'NewEmail' => $new,
80
- 'CurrentUserID' => wp_get_current_user()->ID,
81
- ));
82
- }
83
- }
84
-
85
- if ($is_permalink_page && !empty($_POST['permalink_structure'])) {
86
- $old = get_option('permalink_structure');
87
- $new = trim($_POST['permalink_structure']);
88
- if ($old !== $new) {
89
- $this->plugin->alerts->Trigger(6005, array(
90
- 'OldPattern' => $old,
91
- 'NewPattern' => $new,
92
- 'CurrentUserID' => wp_get_current_user()->ID,
93
- ));
94
- }
95
- }
96
-
97
- if ($action == 'do-core-upgrade' && isset($_REQUEST['version'])) {
98
- $oldVersion = get_bloginfo('version');
99
- $newVersion = $_REQUEST['version'];
100
- if ($oldVersion !== $newVersion) {
101
- $this->plugin->alerts->Trigger(6004, array(
102
- 'OldVersion' => $oldVersion,
103
- 'NewVersion' => $newVersion,
104
- ));
105
- }
106
- }
107
-
108
- /* BBPress Forum support Setting */
109
- if ($action == 'update' && isset($_REQUEST['_bbp_default_role'])) {
110
- $oldRole = get_option('_bbp_default_role');
111
- $newRole = $_REQUEST['_bbp_default_role'];
112
- if ($oldRole !== $newRole) {
113
- $this->plugin->alerts->Trigger(8009, array(
114
- 'OldRole' => $oldRole,
115
- 'NewRole' => $newRole
116
- ));
117
- }
118
- }
119
-
120
- if ($action == 'update' && isset($_REQUEST['option_page']) && ($_REQUEST['option_page'] == 'bbpress')) {
121
- // Anonymous posting
122
- $allow_anonymous = get_option('_bbp_allow_anonymous');
123
- $oldStatus = !empty($allow_anonymous) ? 1 : 0;
124
- $newStatus = !empty($_REQUEST['_bbp_allow_anonymous']) ? 1 : 0;
125
- if ($oldStatus != $newStatus) {
126
- $status = ($newStatus == 1) ? 'Enabled' : 'Disabled';
127
- $this->plugin->alerts->Trigger(8010, array(
128
- 'Status' => $status
129
- ));
130
- }
131
- // Disallow editing after
132
- $bbp_edit_lock = get_option('_bbp_edit_lock');
133
- $oldTime = !empty($bbp_edit_lock) ? $bbp_edit_lock : '';
134
- $newTime = !empty($_REQUEST['_bbp_edit_lock']) ? $_REQUEST['_bbp_edit_lock'] : '';
135
- if ($oldTime != $newTime) {
136
- $this->plugin->alerts->Trigger(8012, array(
137
- 'OldTime' => $oldTime,
138
- 'NewTime' => $newTime
139
- ));
140
- }
141
- // Throttle posting every
142
- $bbp_throttle_time = get_option('_bbp_throttle_time');
143
- $oldTime2 = !empty($bbp_throttle_time) ? $bbp_throttle_time : '';
144
- $newTime2 = !empty($_REQUEST['_bbp_throttle_time']) ? $_REQUEST['_bbp_throttle_time'] : '';
145
- if ($oldTime2 != $newTime2) {
146
- $this->plugin->alerts->Trigger(8013, array(
147
- 'OldTime' => $oldTime2,
148
- 'NewTime' => $newTime2
149
- ));
150
- }
151
- }
152
- }
153
-
154
- /**
155
- * WordPress auto core update
156
- */
157
- public function WPUpdate($automatic)
158
- {
159
- if (isset($automatic['core'][0])) {
160
- $obj = $automatic['core'][0];
161
- $oldVersion = get_bloginfo('version');
162
- $this->plugin->alerts->Trigger(6004, array(
163
- 'OldVersion' => $oldVersion,
164
- 'NewVersion' => $obj->item->version.' (auto update)'
165
- ));
166
- }
167
- }
168
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Sensors_System extends WSAL_AbstractSensor
4
+ {
5
+ const TRANSIENT_404 = 'wsal-404-attempts';
6
+
7
+ public function HookEvents()
8
+ {
9
+ add_action('wsal_prune', array($this, 'EventPruneEvents'), 10, 2);
10
+ add_action('admin_init', array($this, 'EventAdminInit'));
11
+
12
+ add_action('automatic_updates_complete', array($this, 'WPUpdate'), 10, 1);
13
+ add_filter('template_redirect', array($this, 'Event404'));
14
+ }
15
+
16
+ /**
17
+ * @param int $count The number of deleted events.
18
+ * @param string $query Query that selected events for deletion.
19
+ */
20
+ public function EventPruneEvents($count, $query)
21
+ {
22
+ $this->plugin->alerts->Trigger(6000, array(
23
+ 'EventCount' => $count,
24
+ 'PruneQuery' => $query,
25
+ ));
26
+ }
27
+
28
+ protected function Get404LogLimit()
29
+ {
30
+ return 10;
31
+ }
32
+
33
+ protected function Get404Expiration()
34
+ {
35
+ return 24 * 60 * 60;
36
+ }
37
+
38
+ protected function IsPast404Limit($site_id, $username, $ip)
39
+ {
40
+ $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
41
+ $data = $get_fn(self::TRANSIENT_404);
42
+ return ($data !== false) && isset($data[$site_id.":".$username.":".$ip]) && ($data[$site_id.":".$username.":".$ip] > $this->Get404LogLimit());
43
+ }
44
+
45
+ protected function Increment404($site_id, $username, $ip)
46
+ {
47
+ $get_fn = $this->IsMultisite() ? 'get_site_transient' : 'get_transient';
48
+ $set_fn = $this->IsMultisite() ? 'set_site_transient' : 'set_transient';
49
+
50
+ $data = $get_fn(self::TRANSIENT_404);
51
+ if (!$data) {
52
+ $data = array();
53
+ }
54
+ if (!isset($data[$site_id.":".$username.":".$ip])) {
55
+ $data[$site_id.":".$username.":".$ip] = 1;
56
+ }
57
+ $data[$site_id.":".$username.":".$ip]++;
58
+ $set_fn(self::TRANSIENT_404, $data, $this->Get404Expiration());
59
+ }
60
+
61
+ public function Event404()
62
+ {
63
+ global $wp_query;
64
+ if (!$wp_query->is_404) {
65
+ return;
66
+ }
67
+ $msg = 'times';
68
+
69
+ list($y, $m, $d) = explode('-', date('Y-m-d'));
70
+
71
+ $site_id = (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
72
+ $ip = $this->plugin->settings->GetMainClientIP();
73
+
74
+ if (!is_user_logged_in()) {
75
+ $username = "Website Visitor";
76
+ } else {
77
+ $username = wp_get_current_user()->user_login;
78
+ }
79
+
80
+ if ($this->IsPast404Limit($site_id, $username, $ip)) {
81
+ return;
82
+ }
83
+
84
+ $objOcc = new WSAL_Models_Occurrence();
85
+
86
+ $occ = $objOcc->CheckAlert404(
87
+ array(
88
+ $ip,
89
+ $username,
90
+ 6007,
91
+ $site_id,
92
+ mktime(0, 0, 0, $m, $d, $y),
93
+ mktime(0, 0, 0, $m, $d + 1, $y) - 1
94
+ )
95
+ );
96
+
97
+ $occ = count($occ) ? $occ[0] : null;
98
+ if (!empty($occ)) {
99
+ // update existing record
100
+ $this->Increment404($site_id, $username, $ip);
101
+ $new = $occ->GetMetaValue('Attempts', 0) + 1;
102
+
103
+ if ($new > $this->Get404LogLimit()) {
104
+ $new = 'more than ' . $this->Get404LogLimit();
105
+ $msg .= ' This could possible be a scan, therefore keep an eye on the activity from this IP Address';
106
+ }
107
+ $occ->UpdateMetaValue('Attempts', $new);
108
+ $occ->UpdateMetaValue('Username', $username);
109
+ $occ->UpdateMetaValue('Msg', $msg);
110
+ $occ->created_on = null;
111
+ $occ->Save();
112
+ } else {
113
+ // create a new record
114
+ $fields = array(
115
+ 'Attempts' => 1,
116
+ 'Username' => $username,
117
+ 'Msg' => $msg
118
+ );
119
+ $this->plugin->alerts->Trigger(6007, $fields);
120
+ }
121
+ }
122
+
123
+ public function EventAdminInit()
124
+ {
125
+ // make sure user can actually modify target options
126
+ if (!current_user_can('manage_options')) return;
127
+
128
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
129
+ $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
130
+ $is_option_page = $actype == 'options';
131
+ $is_network_settings = $actype == 'settings';
132
+ $is_permalink_page = $actype == 'options-permalink';
133
+
134
+ if ($is_option_page && (get_option('users_can_register') xor isset($_POST['users_can_register']))) {
135
+ $old = get_option('users_can_register') ? 'Enabled' : 'Disabled';
136
+ $new = isset($_POST['users_can_register']) ? 'Enabled' : 'Disabled';
137
+ if ($old !== $new) {
138
+ $this->plugin->alerts->Trigger(6001, array(
139
+ 'OldValue' => $old,
140
+ 'NewValue' => $new,
141
+ 'CurrentUserID' => wp_get_current_user()->ID,
142
+ ));
143
+ }
144
+ }
145
+
146
+ if ($is_option_page && !empty($_POST['default_role'])) {
147
+ $old = get_option('default_role');
148
+ $new = trim($_POST['default_role']);
149
+ if ($old !== $new) {
150
+ $this->plugin->alerts->Trigger(6002, array(
151
+ 'OldRole' => $old,
152
+ 'NewRole' => $new,
153
+ 'CurrentUserID' => wp_get_current_user()->ID,
154
+ ));
155
+ }
156
+ }
157
+
158
+ if ($is_option_page && !empty($_POST['admin_email'])) {
159
+ $old = get_option('admin_email');
160
+ $new = trim($_POST['admin_email']);
161
+ if ($old !== $new) {
162
+ $this->plugin->alerts->Trigger(6003, array(
163
+ 'OldEmail' => $old,
164
+ 'NewEmail' => $new,
165
+ 'CurrentUserID' => wp_get_current_user()->ID,
166
+ ));
167
+ }
168
+ }
169
+
170
+ if ($is_network_settings && !empty($_POST['admin_email'])) {
171
+ $old = get_site_option('admin_email');
172
+ $new = trim($_POST['admin_email']);
173
+ if ($old !== $new) {
174
+ $this->plugin->alerts->Trigger(6003, array(
175
+ 'OldEmail' => $old,
176
+ 'NewEmail' => $new,
177
+ 'CurrentUserID' => wp_get_current_user()->ID,
178
+ ));
179
+ }
180
+ }
181
+
182
+ if ($is_permalink_page && !empty($_POST['permalink_structure'])) {
183
+ $old = get_option('permalink_structure');
184
+ $new = trim($_POST['permalink_structure']);
185
+ if ($old !== $new) {
186
+ $this->plugin->alerts->Trigger(6005, array(
187
+ 'OldPattern' => $old,
188
+ 'NewPattern' => $new,
189
+ 'CurrentUserID' => wp_get_current_user()->ID,
190
+ ));
191
+ }
192
+ }
193
+
194
+ if ($action == 'do-core-upgrade' && isset($_REQUEST['version'])) {
195
+ $oldVersion = get_bloginfo('version');
196
+ $newVersion = $_REQUEST['version'];
197
+ if ($oldVersion !== $newVersion) {
198
+ $this->plugin->alerts->Trigger(6004, array(
199
+ 'OldVersion' => $oldVersion,
200
+ 'NewVersion' => $newVersion,
201
+ ));
202
+ }
203
+ }
204
+
205
+ /* BBPress Forum support Setting */
206
+ if ($action == 'update' && isset($_REQUEST['_bbp_default_role'])) {
207
+ $oldRole = get_option('_bbp_default_role');
208
+ $newRole = $_REQUEST['_bbp_default_role'];
209
+ if ($oldRole !== $newRole) {
210
+ $this->plugin->alerts->Trigger(8009, array(
211
+ 'OldRole' => $oldRole,
212
+ 'NewRole' => $newRole
213
+ ));
214
+ }
215
+ }
216
+
217
+ if ($action == 'update' && isset($_REQUEST['option_page']) && ($_REQUEST['option_page'] == 'bbpress')) {
218
+ // Anonymous posting
219
+ $allow_anonymous = get_option('_bbp_allow_anonymous');
220
+ $oldStatus = !empty($allow_anonymous) ? 1 : 0;
221
+ $newStatus = !empty($_REQUEST['_bbp_allow_anonymous']) ? 1 : 0;
222
+ if ($oldStatus != $newStatus) {
223
+ $status = ($newStatus == 1) ? 'Enabled' : 'Disabled';
224
+ $this->plugin->alerts->Trigger(8010, array(
225
+ 'Status' => $status
226
+ ));
227
+ }
228
+ // Disallow editing after
229
+ $bbp_edit_lock = get_option('_bbp_edit_lock');
230
+ $oldTime = !empty($bbp_edit_lock) ? $bbp_edit_lock : '';
231
+ $newTime = !empty($_REQUEST['_bbp_edit_lock']) ? $_REQUEST['_bbp_edit_lock'] : '';
232
+ if ($oldTime != $newTime) {
233
+ $this->plugin->alerts->Trigger(8012, array(
234
+ 'OldTime' => $oldTime,
235
+ 'NewTime' => $newTime
236
+ ));
237
+ }
238
+ // Throttle posting every
239
+ $bbp_throttle_time = get_option('_bbp_throttle_time');
240
+ $oldTime2 = !empty($bbp_throttle_time) ? $bbp_throttle_time : '';
241
+ $newTime2 = !empty($_REQUEST['_bbp_throttle_time']) ? $_REQUEST['_bbp_throttle_time'] : '';
242
+ if ($oldTime2 != $newTime2) {
243
+ $this->plugin->alerts->Trigger(8013, array(
244
+ 'OldTime' => $oldTime2,
245
+ 'NewTime' => $newTime2
246
+ ));
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * WordPress auto core update
253
+ */
254
+ public function WPUpdate($automatic)
255
+ {
256
+ if (isset($automatic['core'][0])) {
257
+ $obj = $automatic['core'][0];
258
+ $oldVersion = get_bloginfo('version');
259
+ $this->plugin->alerts->Trigger(6004, array(
260
+ 'OldVersion' => $oldVersion,
261
+ 'NewVersion' => $obj->item->version.' (auto update)'
262
+ ));
263
+ }
264
+ }
265
+ }
classes/Sensors/UserProfile.php CHANGED
@@ -1,164 +1,166 @@
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
+ $current_user = wp_get_current_user();
32
+ $this->plugin->alerts->Trigger($event, array(
33
+ 'NewUserID' => $user_id,
34
+ 'UserChanger' => !empty($current_user) ? $current_user->user_login : '',
35
+ 'NewUserData' => (object)array(
36
+ 'Username' => $user->user_login,
37
+ 'FirstName' => $user->user_firstname,
38
+ 'LastName' => $user->user_lastname,
39
+ 'Email' => $user->user_email,
40
+ 'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
41
+ ),
42
+ ), true);
43
+ }
44
+
45
+ public function EventUserRoleChanged($user_id, $role, $oldRoles)
46
+ {
47
+ $user = get_userdata($user_id);
48
+ $aBbpRoles = array('bbp_spectator', 'bbp_moderator', 'bbp_participant', 'bbp_keymaster', 'bbp_blocked');
49
+ // remove any BBPress roles
50
+ if (is_array($oldRoles)) {
51
+ foreach ($oldRoles as $value) {
52
+ if (in_array($value, $aBbpRoles)) {
53
+ if ($_POST['bbp-forums-role'] != $value) {
54
+ $current_user = wp_get_current_user();
55
+ $this->plugin->alerts->TriggerIf(4013, array(
56
+ 'TargetUsername' => $user->user_login,
57
+ 'OldRole' => ucfirst(substr($value, 4)),
58
+ 'NewRole' => ucfirst(substr($_POST['bbp-forums-role'], 4)),
59
+ 'UserChanger' => $current_user->user_login
60
+ ));
61
+ }
62
+ }
63
+ }
64
+ $oldRoles = array_diff($oldRoles, $aBbpRoles);
65
+ }
66
+ $oldRole = count($oldRoles) ? implode(', ', $oldRoles) : '';
67
+ $newRole = $role;
68
+ if ($oldRole != $newRole) {
69
+ $this->plugin->alerts->TriggerIf(4002, array(
70
+ 'TargetUserID' => $user_id,
71
+ 'TargetUsername' => $user->user_login,
72
+ 'OldRole' => $oldRole,
73
+ 'NewRole' => $newRole,
74
+ ), array($this, 'MustNotContainUserChanges'));
75
+ }
76
+ }
77
+
78
+ public function EventUserChanged($user_id)
79
+ {
80
+ $user = get_userdata($user_id);
81
+
82
+ // password changed
83
+ if (!empty($_REQUEST['pass1']) && !empty($_REQUEST['pass2'])) {
84
+ if (trim($_REQUEST['pass1']) == trim($_REQUEST['pass2'])) {
85
+ $event = $user_id == get_current_user_id() ? 4003 : 4004;
86
+ $this->plugin->alerts->Trigger($event, array(
87
+ 'TargetUserID' => $user_id,
88
+ 'TargetUserData' => (object)array(
89
+ 'Username' => $user->user_login,
90
+ 'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
91
+ ),
92
+ ));
93
+ }
94
+ }
95
+
96
+ // email changed
97
+ if (!empty($_REQUEST['email'])) {
98
+ $oldEmail = $user->user_email;
99
+ $newEmail = trim($_REQUEST['email']);
100
+ if ($oldEmail != $newEmail) {
101
+ $event = $user_id == get_current_user_id() ? 4005 : 4006;
102
+ $this->plugin->alerts->Trigger($event, array(
103
+ 'TargetUserID' => $user_id,
104
+ 'TargetUsername' => $user->user_login,
105
+ 'OldEmail' => $oldEmail,
106
+ 'NewEmail' => $newEmail,
107
+ ));
108
+ }
109
+ }
110
+
111
+ if ($this->IsMultisite()) {
112
+ $username = $user->user_login;
113
+ $enabled = isset($_REQUEST['super_admin']);
114
+
115
+ if ($user_id != get_current_user_id()) {
116
+ // super admin enabled
117
+ if ($enabled && !in_array($username, $this->old_superadmins)) {
118
+ $this->plugin->alerts->Trigger(4008, array(
119
+ 'TargetUserID' => $user_id,
120
+ 'TargetUsername' => $user->user_login,
121
+ ));
122
+ }
123
+
124
+ // super admin disabled
125
+ if (!$enabled && in_array($username, $this->old_superadmins)) {
126
+ $this->plugin->alerts->Trigger(4009, array(
127
+ 'TargetUserID' => $user_id,
128
+ 'TargetUsername' => $user->user_login,
129
+ ));
130
+ }
131
+
132
+ }
133
+ }
134
+ }
135
+
136
+ public function EventUserDeleted($user_id)
137
+ {
138
+ $user = get_userdata($user_id);
139
+ $role = is_array($user->roles) ? implode(', ', $user->roles) : $user->roles;
140
+ $this->plugin->alerts->TriggerIf(4007, array(
141
+ 'TargetUserID' => $user_id,
142
+ 'TargetUserData' => (object)array(
143
+ 'Username' => $user->user_login,
144
+ 'FirstName' => $user->user_firstname,
145
+ 'LastName' => $user->user_lastname,
146
+ 'Email' => $user->user_email,
147
+ 'Roles' => $role ? $role : 'none',
148
+ ),
149
+ ), array($this, 'MustNotContainCreateUser'));
150
+ }
151
+
152
+ public function MustNotContainCreateUser(WSAL_AlertManager $mgr)
153
+ {
154
+ return !$mgr->WillTrigger(4012);
155
+ }
156
+
157
+ public function MustNotContainUserChanges(WSAL_AlertManager $mgr)
158
+ {
159
+ return !( $mgr->WillOrHasTriggered(4010)
160
+ || $mgr->WillOrHasTriggered(4011)
161
+ || $mgr->WillOrHasTriggered(4012)
162
+ || $mgr->WillOrHasTriggered(4000)
163
+ || $mgr->WillOrHasTriggered(4001)
164
+ );
165
+ }
166
+ }
classes/Sensors/Widgets.php CHANGED
@@ -1,235 +1,235 @@
1
- <?php
2
-
3
- class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
4
-
5
- public function HookEvents() {
6
- if(current_user_can("edit_theme_options")) {
7
- add_action('admin_init', array($this, 'EventWidgetMove'));
8
- add_action('admin_init', array($this, 'EventWidgetPostMove'));
9
- }
10
- add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
11
- }
12
-
13
- protected $_WidgetMoveData = null;
14
-
15
- public function EventWidgetMove(){
16
- if(isset($_POST) && !empty($_POST['sidebars']))
17
- {
18
- $crtSidebars = $_POST['sidebars'];
19
- $sidebars = array();
20
- foreach ( $crtSidebars as $key => $val )
21
- {
22
- $sb = array();
23
- if ( !empty($val) )
24
- {
25
- $val = explode(',', $val);
26
- foreach ( $val as $k => $v )
27
- {
28
- if ( strpos($v, 'widget-') === false ) continue;
29
- $sb[$k] = substr($v, strpos($v, '_') + 1);
30
- }
31
- }
32
- $sidebars[$key] = $sb;
33
- }
34
- $crtSidebars = $sidebars;
35
- $dbSidebars = get_option('sidebars_widgets');
36
- $wName = $fromSidebar = $toSidebar = '';
37
- foreach($crtSidebars as $sidebarName => $values)
38
- {
39
- if(is_array($values) && ! empty($values) && isset($dbSidebars[$sidebarName]))
40
- {
41
- foreach($values as $widgetName)
42
- {
43
- if(! in_array($widgetName, $dbSidebars[$sidebarName]))
44
- {
45
- $toSidebar = $sidebarName;
46
- $wName = $widgetName;
47
- foreach($dbSidebars as $name => $v)
48
- {
49
- if(is_array($v) && !empty($v) && in_array($widgetName, $v))
50
- {
51
- $fromSidebar = $name;
52
- continue;
53
- }
54
- }
55
- }
56
- }
57
- }
58
- }
59
-
60
- if (empty($wName) || empty($fromSidebar) || empty($toSidebar)) return;
61
-
62
- if(preg_match('/^sidebar-/', $fromSidebar) || preg_match('/^sidebar-/', $toSidebar)){
63
- // This option will hold the data needed to trigger the event 2045
64
- // as at this moment the $wp_registered_sidebars variable is not yet populated
65
- // so we cannot retrieve the name for sidebar-1 || sidebar-2
66
- // we will then check for this variable in the EventWidgetPostMove() event
67
- $this->_WidgetMoveData = array('widget' => $wName, 'from' => $fromSidebar, 'to' => $toSidebar);
68
- return;
69
- }
70
-
71
- $this->plugin->alerts->Trigger(2045, array(
72
- 'WidgetName' => $wName,
73
- 'OldSidebar' => $fromSidebar,
74
- 'NewSidebar' => $toSidebar,
75
- ));
76
- }
77
- }
78
-
79
- public function EventWidgetPostMove() {
80
- //#!-- generates the event 2071
81
- if (isset($_REQUEST['action'])&&($_REQUEST['action']=='widgets-order'))
82
- {
83
- if (isset($_REQUEST['sidebars'])) {
84
- // Get the sidebars from $_REQUEST
85
- $requestSidebars = array();
86
- if ($_REQUEST['sidebars']) {
87
- foreach($_REQUEST['sidebars'] as $key => &$value){
88
- if(!empty($value)){
89
- // build the sidebars array
90
- $value = explode(',', $value);
91
- // Cleanup widgets' name
92
- foreach($value as $k => &$widgetName){
93
- $widgetName = preg_replace("/^([a-z]+-[0-9]+)+?_/i",'', $widgetName);
94
- }
95
- $requestSidebars[$key] = $value;
96
- }
97
- }
98
- }
99
-
100
- if ($requestSidebars) {
101
- // Get the sidebars from DATABASE
102
- $sidebar_widgets = wp_get_sidebars_widgets();
103
- // Get global sidebars so we can retrieve the real name of the sidebar
104
- global $wp_registered_sidebars;
105
-
106
- // Check in each array if there's any change
107
- foreach ($requestSidebars as $sidebarName => $widgets) {
108
- if (isset($sidebar_widgets[$sidebarName])) {
109
- foreach ($sidebar_widgets[$sidebarName] as $i => $widgetName) {
110
- $index = array_search($widgetName, $widgets);
111
- // check to see whether or not the widget has been moved
112
- if ($i != $index) {
113
- $sn = $sidebarName;
114
- // Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebarName
115
- if ($wp_registered_sidebars && isset($wp_registered_sidebars[$sidebarName])) {
116
- $sn = $wp_registered_sidebars[$sidebarName]['name'];
117
- }
118
- $this->plugin->alerts->Trigger(2071, array(
119
- 'WidgetName' => $widgetName,
120
- 'OldPosition' => $i+1,
121
- 'NewPosition' => $index+1,
122
- 'Sidebar' => $sn,
123
- ));
124
- }
125
- }
126
- }
127
- }
128
- }
129
- }
130
- }
131
- //#!--
132
-
133
- if($this->_WidgetMoveData){
134
- $wName = $this->_WidgetMoveData['widget'];
135
- $fromSidebar = $this->_WidgetMoveData['from'];
136
- $toSidebar = $this->_WidgetMoveData['to'];
137
-
138
- global $wp_registered_sidebars;
139
-
140
- if(preg_match('/^sidebar-/', $fromSidebar))
141
- $fromSidebar = isset($wp_registered_sidebars[$fromSidebar])
142
- ? $wp_registered_sidebars[$fromSidebar]['name']
143
- : $fromSidebar
144
- ;
145
- if(preg_match('/^sidebar-/', $toSidebar))
146
- $toSidebar = isset($wp_registered_sidebars[$toSidebar])
147
- ? $wp_registered_sidebars[$toSidebar]['name']
148
- : $toSidebar
149
- ;
150
-
151
- $this->plugin->alerts->Trigger(2045, array(
152
- 'WidgetName' => $wName,
153
- 'OldSidebar' => $fromSidebar,
154
- 'NewSidebar' => $toSidebar,
155
- ));
156
- }
157
- }
158
-
159
- public function EventWidgetActivity(){
160
- if(!isset($_POST) || !isset($_POST['widget-id']) || empty($_POST['widget-id'])){
161
- return;
162
- }
163
-
164
- $postData = $_POST;
165
- global $wp_registered_sidebars;
166
- $canCheckSidebar = (empty($wp_registered_sidebars) ? false : true);
167
-
168
- switch(true){
169
-
170
- // added widget
171
- case isset($postData['add_new']) && $postData['add_new'] == 'multi':
172
- $sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
173
- if($canCheckSidebar && preg_match('/^sidebar-/', $sidebar)){
174
- $sidebar = $wp_registered_sidebars[$sidebar]['name'];
175
- }
176
- $this->plugin->alerts->Trigger(2042, array(
177
- 'WidgetName' => $postData['id_base'],
178
- 'Sidebar' => $sidebar,
179
- ));
180
- break;
181
-
182
- // deleted widget
183
- case isset($postData['delete_widget']) && intval($postData['delete_widget']) == 1:
184
- $sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
185
- if($canCheckSidebar && preg_match('/^sidebar-/',$sidebar)){
186
- $sidebar = $wp_registered_sidebars[$sidebar]['name'];
187
- }
188
- $this->plugin->alerts->Trigger(2044, array(
189
- 'WidgetName' => $postData['id_base'],
190
- 'Sidebar' => $sidebar,
191
- ));
192
- break;
193
-
194
- // modified widget
195
- case isset($postData['id_base']) && !empty($postData['id_base']):
196
- $wId = 0;
197
- if(!empty($postData['multi_number'])){
198
- $wId = intval($postData['multi_number']);
199
- }elseif(!empty($postData['widget_number'])){
200
- $wId = intval($postData['widget_number']);
201
- }
202
- if(empty($wId))return;
203
-
204
- $wName = $postData['id_base'];
205
- $sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
206
- $wData = isset($postData["widget-$wName"][$wId])
207
- ? $postData["widget-$wName"][$wId]
208
- : null;
209
-
210
- if(empty($wData))return;
211
-
212
- // get info from db
213
- $wdbData = get_option("widget_".$wName);
214
- if(empty($wdbData[$wId]))return;
215
-
216
- // transform 'on' -> 1
217
- foreach($wData as $k => $v)if($v == 'on')$wData[$k] = 1;
218
-
219
- // compare - checks for any changes inside widgets
220
- $diff = array_diff_assoc($wData, $wdbData[$wId]);
221
- $count = count($diff);
222
- if($count > 0){
223
- if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
224
- $sidebar = $wp_registered_sidebars[$sidebar]['name'];
225
- }
226
- $this->plugin->alerts->Trigger(2043, array(
227
- 'WidgetName' => $wName,
228
- 'Sidebar' => $sidebar,
229
- ));
230
- }
231
- break;
232
-
233
- }
234
- }
235
  }
1
+ <?php
2
+
3
+ class WSAL_Sensors_Widgets extends WSAL_AbstractSensor {
4
+
5
+ public function HookEvents() {
6
+ if(current_user_can("edit_theme_options")) {
7
+ add_action('admin_init', array($this, 'EventWidgetMove'));
8
+ add_action('admin_init', array($this, 'EventWidgetPostMove'));
9
+ }
10
+ add_action('sidebar_admin_setup', array($this, 'EventWidgetActivity'));
11
+ }
12
+
13
+ protected $_WidgetMoveData = null;
14
+
15
+ public function EventWidgetMove(){
16
+ if(isset($_POST) && !empty($_POST['sidebars']))
17
+ {
18
+ $crtSidebars = $_POST['sidebars'];
19
+ $sidebars = array();
20
+ foreach ( $crtSidebars as $key => $val )
21
+ {
22
+ $sb = array();
23
+ if ( !empty($val) )
24
+ {
25
+ $val = explode(',', $val);
26
+ foreach ( $val as $k => $v )
27
+ {
28
+ if ( strpos($v, 'widget-') === false ) continue;
29
+ $sb[$k] = substr($v, strpos($v, '_') + 1);
30
+ }
31
+ }
32
+ $sidebars[$key] = $sb;
33
+ }
34
+ $crtSidebars = $sidebars;
35
+ $dbSidebars = get_option('sidebars_widgets');
36
+ $wName = $fromSidebar = $toSidebar = '';
37
+ foreach($crtSidebars as $sidebarName => $values)
38
+ {
39
+ if(is_array($values) && ! empty($values) && isset($dbSidebars[$sidebarName]))
40
+ {
41
+ foreach($values as $widgetName)
42
+ {
43
+ if(! in_array($widgetName, $dbSidebars[$sidebarName]))
44
+ {
45
+ $toSidebar = $sidebarName;
46
+ $wName = $widgetName;
47
+ foreach($dbSidebars as $name => $v)
48
+ {
49
+ if(is_array($v) && !empty($v) && in_array($widgetName, $v))
50
+ {
51
+ $fromSidebar = $name;
52
+ continue;
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ if (empty($wName) || empty($fromSidebar) || empty($toSidebar)) return;
61
+
62
+ if(preg_match('/^sidebar-/', $fromSidebar) || preg_match('/^sidebar-/', $toSidebar)){
63
+ // This option will hold the data needed to trigger the event 2045
64
+ // as at this moment the $wp_registered_sidebars variable is not yet populated
65
+ // so we cannot retrieve the name for sidebar-1 || sidebar-2
66
+ // we will then check for this variable in the EventWidgetPostMove() event
67
+ $this->_WidgetMoveData = array('widget' => $wName, 'from' => $fromSidebar, 'to' => $toSidebar);
68
+ return;
69
+ }
70
+
71
+ $this->plugin->alerts->Trigger(2045, array(
72
+ 'WidgetName' => $wName,
73
+ 'OldSidebar' => $fromSidebar,
74
+ 'NewSidebar' => $toSidebar,
75
+ ));
76
+ }
77
+ }
78
+
79
+ public function EventWidgetPostMove() {
80
+ //#!-- generates the event 2071
81
+ if (isset($_REQUEST['action'])&&($_REQUEST['action']=='widgets-order'))
82
+ {
83
+ if (isset($_REQUEST['sidebars'])) {
84
+ // Get the sidebars from $_REQUEST
85
+ $requestSidebars = array();
86
+ if ($_REQUEST['sidebars']) {
87
+ foreach($_REQUEST['sidebars'] as $key => &$value){
88
+ if(!empty($value)){
89
+ // build the sidebars array
90
+ $value = explode(',', $value);
91
+ // Cleanup widgets' name
92
+ foreach($value as $k => &$widgetName){
93
+ $widgetName = preg_replace("/^([a-z]+-[0-9]+)+?_/i",'', $widgetName);
94
+ }
95
+ $requestSidebars[$key] = $value;
96
+ }
97
+ }
98
+ }
99
+
100
+ if ($requestSidebars) {
101
+ // Get the sidebars from DATABASE
102
+ $sidebar_widgets = wp_get_sidebars_widgets();
103
+ // Get global sidebars so we can retrieve the real name of the sidebar
104
+ global $wp_registered_sidebars;
105
+
106
+ // Check in each array if there's any change
107
+ foreach ($requestSidebars as $sidebarName => $widgets) {
108
+ if (isset($sidebar_widgets[$sidebarName])) {
109
+ foreach ($sidebar_widgets[$sidebarName] as $i => $widgetName) {
110
+ $index = array_search($widgetName, $widgets);
111
+ // check to see whether or not the widget has been moved
112
+ if ($i != $index) {
113
+ $sn = $sidebarName;
114
+ // Try to retrieve the real name of the sidebar, otherwise fall-back to id: $sidebarName
115
+ if ($wp_registered_sidebars && isset($wp_registered_sidebars[$sidebarName])) {
116
+ $sn = $wp_registered_sidebars[$sidebarName]['name'];
117
+ }
118
+ $this->plugin->alerts->Trigger(2071, array(
119
+ 'WidgetName' => $widgetName,
120
+ 'OldPosition' => $i+1,
121
+ 'NewPosition' => $index+1,
122
+ 'Sidebar' => $sn,
123
+ ));
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ //#!--
132
+
133
+ if($this->_WidgetMoveData){
134
+ $wName = $this->_WidgetMoveData['widget'];
135
+ $fromSidebar = $this->_WidgetMoveData['from'];
136
+ $toSidebar = $this->_WidgetMoveData['to'];
137
+
138
+ global $wp_registered_sidebars;
139
+
140
+ if(preg_match('/^sidebar-/', $fromSidebar))
141
+ $fromSidebar = isset($wp_registered_sidebars[$fromSidebar])
142
+ ? $wp_registered_sidebars[$fromSidebar]['name']
143
+ : $fromSidebar
144
+ ;
145
+ if(preg_match('/^sidebar-/', $toSidebar))
146
+ $toSidebar = isset($wp_registered_sidebars[$toSidebar])
147
+ ? $wp_registered_sidebars[$toSidebar]['name']
148
+ : $toSidebar
149
+ ;
150
+
151
+ $this->plugin->alerts->Trigger(2045, array(
152
+ 'WidgetName' => $wName,
153
+ 'OldSidebar' => $fromSidebar,
154
+ 'NewSidebar' => $toSidebar,
155
+ ));
156
+ }
157
+ }
158
+
159
+ public function EventWidgetActivity(){
160
+ if(!isset($_POST) || !isset($_POST['widget-id']) || empty($_POST['widget-id'])){
161
+ return;
162
+ }
163
+
164
+ $postData = $_POST;
165
+ global $wp_registered_sidebars;
166
+ $canCheckSidebar = (empty($wp_registered_sidebars) ? false : true);
167
+
168
+ switch(true){
169
+
170
+ // added widget
171
+ case isset($postData['add_new']) && $postData['add_new'] == 'multi':
172
+ $sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
173
+ if($canCheckSidebar && preg_match('/^sidebar-/', $sidebar)){
174
+ $sidebar = $wp_registered_sidebars[$sidebar]['name'];
175
+ }
176
+ $this->plugin->alerts->Trigger(2042, array(
177
+ 'WidgetName' => $postData['id_base'],
178
+ 'Sidebar' => $sidebar,
179
+ ));
180
+ break;
181
+
182
+ // deleted widget
183
+ case isset($postData['delete_widget']) && intval($postData['delete_widget']) == 1:
184
+ $sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
185
+ if($canCheckSidebar && preg_match('/^sidebar-/',$sidebar)){
186
+ $sidebar = $wp_registered_sidebars[$sidebar]['name'];
187
+ }
188
+ $this->plugin->alerts->Trigger(2044, array(
189
+ 'WidgetName' => $postData['id_base'],
190
+ 'Sidebar' => $sidebar,
191
+ ));
192
+ break;
193
+
194
+ // modified widget
195
+ case isset($postData['id_base']) && !empty($postData['id_base']):
196
+ $wId = 0;
197
+ if(!empty($postData['multi_number'])){
198
+ $wId = intval($postData['multi_number']);
199
+ }elseif(!empty($postData['widget_number'])){
200
+ $wId = intval($postData['widget_number']);
201
+ }
202
+ if(empty($wId))return;
203
+
204
+ $wName = $postData['id_base'];
205
+ $sidebar = isset($postData['sidebar']) ? $postData['sidebar'] : null;
206
+ $wData = isset($postData["widget-$wName"][$wId])
207
+ ? $postData["widget-$wName"][$wId]
208
+ : null;
209
+
210
+ if(empty($wData))return;
211
+
212
+ // get info from db
213
+ $wdbData = get_option("widget_".$wName);
214
+ if(empty($wdbData[$wId]))return;
215
+
216
+ // transform 'on' -> 1
217
+ foreach($wData as $k => $v)if($v == 'on')$wData[$k] = 1;
218
+
219
+ // compare - checks for any changes inside widgets
220
+ $diff = array_diff_assoc($wData, $wdbData[$wId]);
221
+ $count = count($diff);
222
+ if($count > 0){
223
+ if($canCheckSidebar && preg_match("/^sidebar-/",$sidebar)){
224
+ $sidebar = $wp_registered_sidebars[$sidebar]['name'];
225
+ }
226
+ $this->plugin->alerts->Trigger(2043, array(
227
+ 'WidgetName' => $wName,
228
+ 'Sidebar' => $sidebar,
229
+ ));
230
+ }
231
+ break;
232
+
233
+ }
234
+ }
235
  }
classes/Settings.php CHANGED
@@ -1,639 +1,655 @@
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', esc_html(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', esc_html(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', esc_html(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', esc_html(implode(',', $this->_excluded_ip)));
564
- }
565
- public function GetExcludedMonitoringIP(){
566
- if(empty($this->_excluded_ip)){
567
- $this->_excluded_ip = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('excluded-ip'))));
568
- }
569
- return $this->_excluded_ip;
570
- }
571
-
572
- /**
573
- * Datetime format.
574
- * 24 hours or AM/PM
575
- */
576
- public function GetDatetimeFormat(){
577
- return $this->_plugin->GetGlobalOption('datetime-format', 0);
578
- }
579
-
580
- public function SetDatetimeFormat($newvalue){
581
- return $this->_plugin->SetGlobalOption('datetime-format', $newvalue);
582
- }
583
-
584
- /**
585
- * Alerts Timestamp
586
- * Server's timezone or WordPress' timezone
587
- */
588
- public function GetTimezone(){
589
- return $this->_plugin->GetGlobalOption('timezone', 0);
590
- }
591
-
592
- public function SetTimezone($newvalue){
593
- return $this->_plugin->SetGlobalOption('timezone', $newvalue);
594
- }
595
-
596
- public function GetAdapterConfig($name_field){
597
- return $this->_plugin->GetGlobalOption($name_field);
598
- }
599
-
600
- public function SetAdapterConfig($name_field, $newvalue){
601
- return $this->_plugin->SetGlobalOption($name_field, trim($newvalue));
602
- }
603
-
604
- public function GetColumns(){
605
- $columns = array('alert_code' => '1', 'type' => '1', 'date' => '1', 'username' => '1', 'source_ip' => '1', 'message' => '1');
606
- if ($this->_plugin->IsMultisite()) {
607
- $columns = array_slice($columns, 0, 5, true) + array('site' => '1') + array_slice($columns, 5, null, true);
608
- }
609
- $selected = $this->GetColumnsSelected();
610
- if (!empty($selected)) {
611
- $columns = array('alert_code' => '0', 'type' => '0', 'date' => '0', 'username' => '0', 'source_ip' => '0', 'message' => '0');
612
- if ($this->_plugin->IsMultisite()) {
613
- $columns = array_slice($columns, 0, 5, true) + array('site' => '0') + array_slice($columns, 5, null, true);
614
- }
615
- $selected = (array)json_decode($selected);
616
- $columns = array_merge($columns, $selected);
617
- return $columns;
618
- } else {
619
- return $columns;
620
- }
621
- }
622
-
623
- public function GetColumnsSelected(){
624
- return $this->_plugin->GetGlobalOption('columns');
625
- }
626
-
627
- public function SetColumns($columns){
628
- return $this->_plugin->SetGlobalOption('columns', json_encode($columns));
629
- }
630
-
631
- public function IsWPBackend(){
632
- return $this->_plugin->GetGlobalOption('wp-backend');
633
- }
634
-
635
- public function SetWPBackend($enabled){
636
- return $this->_plugin->SetGlobalOption('wp-backend', $enabled);
637
- }
638
- // </editor-fold>
639
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class WSAL_Settings {
3
+ /**
4
+ * @var WpSecurityAuditLog
5
+ */
6
+ protected $_plugin;
7
+ public function __construct(WpSecurityAuditLog $plugin) {
8
+ $this->_plugin = $plugin;
9
+ }
10
+
11
+ // <editor-fold desc="Developer Options">
12
+ const OPT_DEV_DATA_INSPECTOR = 'd';
13
+ const OPT_DEV_PHP_ERRORS = 'p';
14
+ const OPT_DEV_REQUEST_LOG = 'r';
15
+ const OPT_DEV_BACKTRACE_LOG = 'b';
16
+
17
+ const ERROR_CODE_INVALID_IP = 901;
18
+
19
+ protected $_devoption = null;
20
+ /**
21
+ * @return array Array of developer options to be enabled by default.
22
+ */
23
+ public function GetDefaultDevOptions(){
24
+ return array();
25
+ }
26
+ /**
27
+ * Returns whether a developer option is enabled or not.
28
+ * @param string $option See self::OPT_DEV_* constants.
29
+ * @return boolean If option is enabled or not.
30
+ */
31
+ public function IsDevOptionEnabled($option){
32
+ if(is_null($this->_devoption)){
33
+ $this->_devoption = $this->_plugin->GetGlobalOption(
34
+ 'dev-options',
35
+ implode(',', $this->GetDefaultDevOptions())
36
+ );
37
+ $this->_devoption = explode(',', $this->_devoption);
38
+ }
39
+ return in_array($option, $this->_devoption);
40
+ }
41
+ /**
42
+ * @return boolean Whether any developer option has been enabled or not.
43
+ */
44
+ public function IsAnyDevOptionEnabled(){
45
+ return !!$this->_plugin->GetGlobalOption('dev-options', null);
46
+ }
47
+ /**
48
+ * Sets whether a developer option is enabled or not.
49
+ * @param string $option See self::OPT_DEV_* constants.
50
+ * @param boolean $enabled If option should be enabled or not.
51
+ */
52
+ public function SetDevOptionEnabled($option, $enabled){
53
+ // make sure options have been loaded
54
+ $this->IsDevOptionEnabled('');
55
+ // remove option if it exists
56
+ while(($p = array_search($option, $this->_devoption)) !== false)
57
+ unset($this->_devoption[$p]);
58
+ // add option if callee wants it enabled
59
+ if($enabled)
60
+ $this->_devoption[] = $option;
61
+ // commit option
62
+ $this->_plugin->SetGlobalOption(
63
+ 'dev-options',
64
+ implode(',', $this->_devoption)
65
+ );
66
+ }
67
+ /**
68
+ * Remove all enabled developer options.
69
+ */
70
+ public function ClearDevOptions(){
71
+ $this->_devoption = array();
72
+ $this->_plugin->SetGlobalOption('dev-options', '');
73
+ }
74
+ /**
75
+ * @return boolean Whether to enable data inspector or not.
76
+ */
77
+ public function IsDataInspectorEnabled(){
78
+ return $this->IsDevOptionEnabled(self::OPT_DEV_DATA_INSPECTOR);
79
+ }
80
+ /**
81
+ * @return boolean Whether to PHP error logging or not.
82
+ */
83
+ public function IsPhpErrorLoggingEnabled(){
84
+ return $this->IsDevOptionEnabled(self::OPT_DEV_PHP_ERRORS);
85
+ }
86
+ /**
87
+ * @return boolean Whether to log requests to file or not.
88
+ */
89
+ public function IsRequestLoggingEnabled(){
90
+ return $this->IsDevOptionEnabled(self::OPT_DEV_REQUEST_LOG);
91
+ }
92
+ /**
93
+ * @return boolean Whether to store debug backtrace for PHP alerts or not.
94
+ */
95
+ public function IsBacktraceLoggingEnabled(){
96
+ return $this->IsDevOptionEnabled(self::OPT_DEV_BACKTRACE_LOG);
97
+ }
98
+
99
+ // </editor-fold>
100
+ /**
101
+ * @return boolean Whether dashboard widgets are enabled or not.
102
+ */
103
+ public function IsWidgetsEnabled(){
104
+ return !$this->_plugin->GetGlobalOption('disable-widgets');
105
+ }
106
+ /**
107
+ * @param boolean $newvalue Whether dashboard widgets are enabled or not.
108
+ */
109
+ public function SetWidgetsEnabled($newvalue){
110
+ $this->_plugin->SetGlobalOption('disable-widgets', !$newvalue);
111
+ }
112
+ /**
113
+ * @return boolean Whether alerts in audit log view refresh automatically or not.
114
+ */
115
+ public function IsRefreshAlertsEnabled(){
116
+ return !$this->_plugin->GetGlobalOption('disable-refresh');
117
+ }
118
+ /**
119
+ * @param boolean $newvalue Whether alerts in audit log view refresh automatically or not.
120
+ */
121
+ public function SetRefreshAlertsEnabled($newvalue){
122
+ $this->_plugin->SetGlobalOption('disable-refresh', !$newvalue);
123
+ }
124
+ /**
125
+ * @return int Maximum number of alerts to show in dashboard widget.
126
+ */
127
+ public function GetDashboardWidgetMaxAlerts(){
128
+ return 5;
129
+ }
130
+
131
+ // <editor-fold desc="Pruning Settings">
132
+ /**
133
+ * @return int The maximum number of alerts allowable.
134
+ */
135
+ public function GetMaxAllowedAlerts(){
136
+ return 5000;
137
+ }
138
+ /**
139
+ * @return string The default pruning date.
140
+ */
141
+ public function GetDefaultPruningDate(){
142
+ return '1 month';
143
+ }
144
+ protected $_pruning = 0;
145
+ /**
146
+ * @return string The current pruning date.
147
+ */
148
+ public function GetPruningDate(){
149
+ if(!$this->_pruning){
150
+ $this->_pruning = $this->_plugin->GetGlobalOption('pruning-date');
151
+ if(!strtotime($this->_pruning))
152
+ $this->_pruning = $this->GetDefaultPruningDate();
153
+ }
154
+ return $this->_pruning;
155
+ }
156
+ /**
157
+ * @param string $newvalue The new pruning date.
158
+ */
159
+ public function SetPruningDate($newvalue){
160
+ if(strtotime($newvalue)){
161
+ $this->_plugin->SetGlobalOption('pruning-date', $newvalue);
162
+ $this->_pruning = $newvalue;
163
+ }
164
+ }
165
+ /**
166
+ * @return integer Maximum number of alerts to keep.
167
+ */
168
+ public function GetPruningLimit(){
169
+ $val = (int)$this->_plugin->GetGlobalOption('pruning-limit');
170
+ return $val ? $val : $this->GetMaxAllowedAlerts();
171
+ }
172
+ /**
173
+ * @param integer $newvalue The new maximum number of alerts.
174
+ */
175
+ public function SetPruningLimit($newvalue){
176
+ $newvalue = max(/*min(*/(int)$newvalue/*, $this->GetMaxAllowedAlerts())*/, 1);
177
+ $this->_plugin->SetGlobalOption('pruning-limit', $newvalue);
178
+ }
179
+ public function SetPruningDateEnabled($enabled){
180
+ $this->_plugin->SetGlobalOption('pruning-date-e', $enabled);
181
+ }
182
+ public function SetPruningLimitEnabled($enabled){
183
+ $this->_plugin->SetGlobalOption('pruning-limit-e', $enabled);
184
+ }
185
+ public function IsPruningDateEnabled(){
186
+ return $this->_plugin->GetGlobalOption('pruning-date-e');
187
+ }
188
+ public function IsPruningLimitEnabled(){
189
+ return $this->_plugin->GetGlobalOption('pruning-limit-e');
190
+ }
191
+ public function IsRestrictAdmins(){
192
+ return $this->_plugin->GetGlobalOption('restrict-admins', false);
193
+ }
194
+ /**
195
+ * @deprecated Sandbox functionality is now in an external plugin.
196
+ */
197
+ public function IsSandboxPageEnabled(){
198
+ $plugins = $this->_plugin->licensing->plugins();
199
+ return isset($plugins['wsal-sandbox-extensionphp']);
200
+ }
201
+ public function SetRestrictAdmins($enable){
202
+ $this->_plugin->SetGlobalOption('restrict-admins', (bool)$enable);
203
+ }
204
+
205
+ // </editor-fold>
206
+ protected $_disabled = null;
207
+ public function GetDefaultDisabledAlerts(){
208
+ return array(0000, 0001, 0002, 0003, 0004, 0005);
209
+ }
210
+ /**
211
+ * @return array IDs of disabled alerts.
212
+ */
213
+ public function GetDisabledAlerts(){
214
+ if(!$this->_disabled){
215
+ $this->_disabled = implode(',', $this->GetDefaultDisabledAlerts());
216
+ $this->_disabled = $this->_plugin->GetGlobalOption('disabled-alerts', $this->_disabled);
217
+ $this->_disabled = ($this->_disabled == '') ? array() : explode(',', $this->_disabled);
218
+ $this->_disabled = array_map('intval', $this->_disabled);
219
+ }
220
+ return $this->_disabled;
221
+ }
222
+ /**
223
+ * @param array $types IDs alerts to disable.
224
+ */
225
+ public function SetDisabledAlerts($types){
226
+ $this->_disabled = array_unique(array_map('intval', $types));
227
+ $this->_plugin->SetGlobalOption('disabled-alerts', implode(',', $this->_disabled));
228
+ }
229
+ public function IsIncognito(){
230
+ return $this->_plugin->GetGlobalOption('hide-plugin');
231
+ }
232
+ public function SetIncognito($enabled){
233
+ return $this->_plugin->SetGlobalOption('hide-plugin', $enabled);
234
+ }
235
+
236
+ /**
237
+ * Checking if the data will be removed.
238
+ */
239
+ public function IsDeleteData(){
240
+ return $this->_plugin->GetGlobalOption('delete-data');
241
+ }
242
+
243
+ public function SetDeleteData($enabled){
244
+ return $this->_plugin->SetGlobalOption('delete-data', $enabled);
245
+ }
246
+
247
+ // <editor-fold desc="Access Control">
248
+
249
+ protected $_viewers = null;
250
+ public function SetAllowedPluginViewers($usersOrRoles){
251
+ $this->_viewers = $usersOrRoles;
252
+ $this->_plugin->SetGlobalOption('plugin-viewers', implode(',', $this->_viewers));
253
+ }
254
+ public function GetAllowedPluginViewers(){
255
+ if(is_null($this->_viewers)){
256
+ $this->_viewers = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-viewers'))));
257
+ }
258
+ return $this->_viewers;
259
+ }
260
+ protected $_editors = null;
261
+ public function SetAllowedPluginEditors($usersOrRoles){
262
+ $this->_editors = $usersOrRoles;
263
+ $this->_plugin->SetGlobalOption('plugin-editors', implode(',', $this->_editors));
264
+ }
265
+ public function GetAllowedPluginEditors(){
266
+ if(is_null($this->_editors)){
267
+ $this->_editors = array_unique(array_filter(explode(',', $this->_plugin->GetGlobalOption('plugin-editors'))));
268
+ }
269
+ return $this->_editors;
270
+ }
271
+ protected $_perpage = null;
272
+ public function SetViewPerPage($newvalue){
273
+ $this->_perpage = max($newvalue, 1);
274
+ $this->_plugin->SetGlobalOption('items-per-page', $this->_perpage);
275
+ }
276
+ public function GetViewPerPage(){
277
+ if(is_null($this->_perpage)){
278
+ $this->_perpage = (int)$this->_plugin->GetGlobalOption('items-per-page', 10);
279
+ }
280
+ return $this->_perpage;
281
+ }
282
+ /**
283
+ * @param string $action Type of action, either 'view' or 'edit'.
284
+ * @return boolean If user has access or not.
285
+ */
286
+ public function CurrentUserCan($action){
287
+ return $this->UserCan(wp_get_current_user(), $action);
288
+ }
289
+ /**
290
+ * @return string[] List of superadmin usernames.
291
+ */
292
+ protected function GetSuperAdmins(){
293
+ return $this->_plugin->IsMultisite() ? get_super_admins() : array();
294
+ }
295
+ /**
296
+ * @return string[] List of admin usernames.
297
+ */
298
+ protected function GetAdmins(){
299
+ if($this->_plugin->IsMultisite()){
300
+ // see: https://gist.github.com/1508426/65785a15b8638d43a9905effb59e4d97319ef8f8
301
+ global $wpdb;
302
+ $cap = $wpdb->prefix."capabilities";
303
+ $sql = "SELECT DISTINCT $wpdb->users.user_login"
304
+ . " FROM $wpdb->users"
305
+ . " INNER JOIN $wpdb->usermeta ON ($wpdb->users.ID = $wpdb->usermeta.user_id )"
306
+ . " WHERE $wpdb->usermeta.meta_key = '$cap'"
307
+ . " AND CAST($wpdb->usermeta.meta_value AS CHAR) LIKE '%\"administrator\"%'";
308
+ return $wpdb->get_col($sql);
309
+ }else{
310
+ $result = array();
311
+ $query = 'role=administrator&fields[]=user_login';
312
+ foreach (get_users($query) as $user) $result[] = $user->user_login;
313
+ return $result;
314
+ }
315
+ }
316
+ /**
317
+ * Returns access tokens for a particular action.
318
+ * @param string $action Type of action.
319
+ * @return string[] List of tokens (usernames, roles etc).
320
+ */
321
+ public function GetAccessTokens($action){
322
+ $allowed = array();
323
+ switch($action){
324
+ case 'view':
325
+ $allowed = $this->GetAllowedPluginViewers();
326
+ $allowed = array_merge($allowed, $this->GetAllowedPluginEditors());
327
+ if (!$this->IsRestrictAdmins()) {
328
+ $allowed = array_merge($allowed, $this->GetSuperAdmins());
329
+ $allowed = array_merge($allowed, $this->GetAdmins());
330
+ }
331
+ break;
332
+ case 'edit':
333
+ $allowed = $this->GetAllowedPluginEditors();
334
+ if (!$this->IsRestrictAdmins()) {
335
+ $allowed = array_merge($allowed, $this->_plugin->IsMultisite() ?
336
+ $this->GetSuperAdmins() : $this->GetAdmins()
337
+ );
338
+ }
339
+ break;
340
+ default:
341
+ throw new Exception('Unknown action "'.$action.'".');
342
+ }
343
+ if (!$this->IsRestrictAdmins()) {
344
+ if(is_multisite()){
345
+ $allowed = array_merge($allowed, get_super_admins());
346
+ }else{
347
+ $allowed[] = 'administrator';
348
+ }
349
+ }
350
+ return array_unique($allowed);
351
+ }
352
+ /**
353
+ * @param integer|WP_user $user User object to check.
354
+ * @param string $action Type of action, either 'view' or 'edit'.
355
+ * @return boolean If user has access or not.
356
+ */
357
+ public function UserCan($user, $action){
358
+ if(is_int($user))$user = get_userdata($user);
359
+ $allowed = $this->GetAccessTokens($action);
360
+ $check = array_merge(
361
+ $user->roles,
362
+ array($user->user_login)
363
+ );
364
+ foreach($check as $item){
365
+ if(in_array($item, $allowed)){
366
+ return true;
367
+ }
368
+ }
369
+ return false;
370
+ }
371
+ public function GetCurrentUserRoles($baseRoles = null){
372
+ if ($baseRoles == null) $baseRoles = wp_get_current_user()->roles;
373
+ if (function_exists('is_super_admin') && is_super_admin()) $baseRoles[] = 'superadmin';
374
+ return $baseRoles;
375
+ }
376
+
377
+ public function IsLoginSuperAdmin($username){
378
+ $userId = username_exists($username);
379
+ if ( function_exists('is_super_admin') && is_super_admin($userId) ) return true;
380
+ else return false;
381
+ }
382
+
383
+ // </editor-fold>
384
+
385
+ // <editor-fold desc="Licensing">
386
+ public function GetLicenses(){
387
+ return $this->_plugin->GetGlobalOption('licenses');
388
+ }
389
+ public function GetLicense($name){
390
+ $data = $this->GetLicenses();
391
+ $name = sanitize_key(basename($name));
392
+ return isset($data[$name]) ? $data[$name] : array();
393
+ }
394
+ public function SetLicenses($data){
395
+ $this->_plugin->SetGlobalOption('licenses', $data);
396
+ }
397
+ public function GetLicenseKey($name){
398
+ $data = $this->GetLicense($name);
399
+ return isset($data['key']) ? $data['key'] : '';
400
+ }
401
+ public function GetLicenseStatus($name){
402
+ $data = $this->GetLicense($name);
403
+ return isset($data['sts']) ? $data['sts'] : '';
404
+ }
405
+ public function GetLicenseErrors($name){
406
+ $data = $this->GetLicense($name);
407
+ return isset($data['err']) ? $data['err'] : '';
408
+ }
409
+ public function SetLicenseKey($name, $key){
410
+ $data = $this->GetLicenses();
411
+ if (!isset($data[$name])) $data[$name] = array();
412
+ $data[$name]['key'] = $key;
413
+ $this->SetLicenses($data);
414
+ }
415
+ public function SetLicenseStatus($name, $status){
416
+ $data = $this->GetLicenses();
417
+ if (!isset($data[$name])) $data[$name] = array();
418
+ $data[$name]['sts'] = $status;
419
+ $this->SetLicenses($data);
420
+ }
421
+ public function SetLicenseErrors($name, $errors){
422
+ $data = $this->GetLicenses();
423
+ if (!isset($data[$name])) $data[$name] = array();
424
+ $data[$name]['err'] = $errors;
425
+ $this->SetLicenses($data);
426
+ }
427
+ public function ClearLicenses(){
428
+ $this->SetLicenses(array());
429
+ }
430
+
431
+ // </editor-fold>
432
+
433
+ // <editor-fold desc="Client IP Retrieval">
434
+
435
+ public function IsMainIPFromProxy(){
436
+ return $this->_plugin->GetGlobalOption('use-proxy-ip');
437
+ }
438
+ public function SetMainIPFromProxy($enabled){
439
+ return $this->_plugin->SetGlobalOption('use-proxy-ip', $enabled);
440
+ }
441
+
442
+ public function IsInternalIPsFiltered(){
443
+ return $this->_plugin->GetGlobalOption('filter-internal-ip');
444
+ }
445
+ public function SetInternalIPsFiltering($enabled){
446
+ return $this->_plugin->SetGlobalOption('filter-internal-ip', $enabled);
447
+ }
448
+
449
+ public function GetMainClientIP(){
450
+ $result = null;
451
+ if ($this->IsMainIPFromProxy()) {
452
+ // TODO the algorithm below just gets the first IP in the list...we might want to make this more intelligent somehow
453
+ $result = $this->GetClientIPs();
454
+ $result = reset($result);
455
+ $result = isset($result[0]) ? $result[0] : null;
456
+ } elseif (isset($_SERVER['REMOTE_ADDR'])) {
457
+ $result = $this->NormalizeIP($_SERVER['REMOTE_ADDR']);
458
+ if (!$this->ValidateIP($result)) {
459
+ $result = "Error " . self::ERROR_CODE_INVALID_IP . ": Invalid IP Address";
460
+ }
461
+ }
462
+ return $result;
463
+ }
464
+
465
+ public function GetClientIPs(){
466
+ $ips = array();
467
+ foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key) {
468
+ if (isset($_SERVER[$key])) {
469
+ $ips[$key] = array();
470
+ foreach (explode(',', $_SERVER[$key]) as $ip)
471
+ if ($this->ValidateIP($ip = $this->NormalizeIP($ip)))
472
+ $ips[$key][] = $ip;
473
+ }
474
+ }
475
+ return $ips;
476
+ }
477
+
478
+ protected function NormalizeIP($ip){
479
+ $ip = trim($ip);
480
+ if(strpos($ip, ':') !== false && substr_count($ip, '.') == 3 && strpos($ip, '[') === false){
481
+ // IPv4 with a port (eg: 11.22.33.44:80)
482
+ $ip = explode(':', $ip);
483
+ $ip = $ip[0];
484
+ }else{
485
+ // IPv6 with a port (eg: [::1]:80)
486
+ $ip = explode(']', $ip);
487
+ $ip = ltrim($ip[0], '[');
488
+ }
489
+ return $ip;
490
+ }
491
+
492
+ protected function ValidateIP($ip){
493
+ $opts = FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6;
494
+ if ($this->IsInternalIPsFiltered()) $opts = $opts | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
495
+ $filteredIP = filter_var($ip, FILTER_VALIDATE_IP, $opts);
496
+ if (!$filteredIP || empty($filteredIP)) {
497
+ //Regex IPV4
498
+ if (preg_match("/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $ip)) return $ip;
499
+ //Regex IPV6
500
+ elseif (preg_match("/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/", $ip)) return $ip;
501
+
502
+ error_log("Invalid IP in ValidateIP function: ".$ip);
503
+ return false;
504
+ } else {
505
+ return $filteredIP;
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Users excluded from monitoring
511
+ */
512
+ protected $_excluded_users = array();
513
+ public function SetExcludedMonitoringUsers($users)
514
+ {
515
+ $this->_excluded_users = $users;
516
+ $this->_plugin->SetGlobalOption('excluded-users', esc_html(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', esc_html(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', esc_html(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', esc_html(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
+
639
+ public function SetFromEmail($email_address){
640
+ return $this->_plugin->SetGlobalOption('from-email', trim($email_address));
641
+ }
642
+
643
+ public function GetFromEmail(){
644
+ return $this->_plugin->GetGlobalOption('from-email');
645
+ }
646
+
647
+ public function SetDisplayName($display_name){
648
+ return $this->_plugin->SetGlobalOption('display-name', trim($display_name));
649
+ }
650
+
651
+ public function GetDisplayName(){
652
+ return $this->_plugin->GetGlobalOption('display-name');
653
+ }
654
+ // </editor-fold>
655
+ }
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,245 @@
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
+ if ($this->GetClassNameByView($view->GetName())) {
108
+ continue;
109
+ }
110
+ $view->hook_suffix = add_submenu_page(
111
+ $view->IsVisible() ? $this->views[0]->GetSafeViewName() : null,
112
+ $view->GetTitle(),
113
+ $view->GetName(),
114
+ 'read', // no capability requirement
115
+ $view->GetSafeViewName(),
116
+ array($this, 'RenderViewBody'),
117
+ $view->GetIcon()
118
+ );
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Wordpress Filter
126
+ */
127
+ public function AddPluginShortcuts($old_links){
128
+ $this->ReorderViews();
129
+
130
+ $new_links = array();
131
+ foreach($this->views as $view){
132
+ if($view->HasPluginShortcutLink()){
133
+ $new_links[] =
134
+ '<a href="'
135
+ . admin_url('admin.php?page='
136
+ . $view->GetSafeViewName()
137
+ ) . '">'
138
+ . $view->GetName()
139
+ . '</a>';
140
+ }
141
+ }
142
+ return array_merge($new_links, $old_links);
143
+ }
144
+
145
+ /**
146
+ * @return int Returns page id of current page (or false on error).
147
+ */
148
+ protected function GetBackendPageIndex(){
149
+ if(isset($_REQUEST['page']))
150
+ foreach($this->views as $i => $view)
151
+ if($_REQUEST['page'] == $view->GetSafeViewName())
152
+ return $i;
153
+ return false;
154
+ }
155
+
156
+ /**
157
+ *
158
+ * @var WSAL_AbstractView|null
159
+ */
160
+ protected $_active_view = false;
161
+
162
+ /**
163
+ * @return WSAL_AbstractView|null Returns the current active view or null if none.
164
+ */
165
+ public function GetActiveView(){
166
+ if($this->_active_view === false){
167
+ $this->_active_view = null;
168
+
169
+ if(isset($_REQUEST['page']))
170
+ foreach($this->views as $view)
171
+ if($_REQUEST['page'] == $view->GetSafeViewName())
172
+ $this->_active_view = $view;
173
+
174
+ if($this->_active_view)
175
+ $this->_active_view->is_active = true;
176
+ }
177
+ return $this->_active_view;
178
+ }
179
+
180
+ /**
181
+ * Render header of the current view.
182
+ */
183
+ public function RenderViewHeader(){
184
+ if (!!($view = $this->GetActiveView())) $view->Header();
185
+ }
186
+
187
+ /**
188
+ * Render footer of the current view.
189
+ */
190
+ public function RenderViewFooter(){
191
+ if (!!($view = $this->GetActiveView())) $view->Footer();
192
+ }
193
+
194
+ /**
195
+ * Render content of the current view.
196
+ */
197
+ public function RenderViewBody(){
198
+ $view = $this->GetActiveView();
199
+ ?><div class="wrap"><?php
200
+ $view->RenderIcon();
201
+ $view->RenderTitle();
202
+ $view->RenderContent();
203
+ ?></div><?php
204
+ }
205
+
206
+ /**
207
+ * Returns view instance corresponding to its class name.
208
+ * @param string $className View class name.
209
+ * @return WSAL_AbstractView The view or false on failure.
210
+ */
211
+ public function FindByClassName($className){
212
+ foreach($this->views as $view)
213
+ if($view instanceof $className)
214
+ return $view;
215
+ return false;
216
+ }
217
+
218
+ private function GetClassNameByView($name_view)
219
+ {
220
+ $not_show = false;
221
+ switch ($name_view) {
222
+ case 'Notifications Email':
223
+ if (class_exists('WSAL_NP_Plugin')) {
224
+ $not_show = true;
225
+ }
226
+ break;
227
+ case 'Logged In Users':
228
+ if (class_exists('WSAL_User_Management_Plugin')) {
229
+ $not_show = true;
230
+ }
231
+ break;
232
+ case 'Reports':
233
+ if (class_exists('WSAL_Rep_Plugin')) {
234
+ $not_show = true;
235
+ }
236
+ break;
237
+ case 'Search':
238
+ if (class_exists('WSAL_SearchExtension')) {
239
+ $not_show = true;
240
+ }
241
+ break;
242
+ }
243
+ return $not_show;
244
+ }
245
+ }
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,203 @@
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
+ require_once(ABSPATH . 'wp-admin/includes/plugin.php');
3
+
4
+ class WSAL_Views_AuditLog extends WSAL_AbstractView {
5
+ /**
6
+ * @var WSAL_AuditLogListView
7
+ */
8
+ protected $_listview;
9
+
10
+ protected $_version;
11
+
12
+ public function __construct(WpSecurityAuditLog $plugin) {
13
+ parent::__construct($plugin);
14
+ add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
15
+ add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
16
+ add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
17
+ add_action('wp_ajax_AjaxSearchSite', array($this, 'AjaxSearchSite'));
18
+ add_action('all_admin_notices', array($this, 'AdminNoticesPremium'));
19
+ // Check plugin version for to dismiss the notice only until upgrade
20
+ $plugin_file = trailingslashit(WP_PLUGIN_DIR) . plugin_basename(__FILE__);
21
+ $data = get_plugin_data($plugin_file, false, false);
22
+ $this->_version = isset($data['Version']) ? $data['Version'] : '0.0.0';
23
+ $this->RegisterNotice('premium-wsal-'.$this->_version);
24
+ }
25
+
26
+ public function AdminNoticesPremium()
27
+ {
28
+ $IsCurrentView = $this->_plugin->views->GetActiveView() == $this;
29
+ // Check if any of the extensions is activated
30
+ if (!class_exists('WSAL_NP_Plugin') && !class_exists('WSAL_SearchExtension') && !class_exists('WSAL_Rep_Plugin') && !class_exists('WSAL_Ext_Plugin') && !class_exists('WSAL_User_Management_Plugin')) {
31
+ if ($IsCurrentView && !$this->IsNoticeDismissed('premium-wsal-'.$this->_version)) { ?>
32
+ <div class="updated" data-notice-name="premium-wsal-<?=$this->_version?>">
33
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/ ?utm_source=auditviewer&utm_medium=page&utm_campaign=plugin'; ?>
34
+ <p><a href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Upgrade to Premium', 'wp-security-audit-log'); ?></a>
35
+ <?php _e('and add Email Alerts, Reports, Search and Users Login and Session Management.', 'wp-security-audit-log'); ?>
36
+ <a href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Upgrade Now!', 'wp-security-audit-log'); ?></a>
37
+ <a href="javascript:;" class="wsal-dismiss-notification wsal-premium"><span class="dashicons dashicons-dismiss"></span></a>
38
+ </p>
39
+ </div>
40
+ <?php
41
+ }
42
+ }
43
+ }
44
+
45
+ public function HasPluginShortcutLink() {
46
+ return true;
47
+ }
48
+
49
+ public function GetTitle() {
50
+ return __('Audit Log Viewer', 'wp-security-audit-log');
51
+ }
52
+
53
+ public function GetIcon() {
54
+ return $this->_wpversion < 3.8
55
+ ? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
56
+ : 'dashicons-welcome-view-site';
57
+ }
58
+
59
+ public function GetName() {
60
+ return __('Audit Log Viewer', 'wp-security-audit-log');
61
+ }
62
+
63
+ public function GetWeight() {
64
+ return 1;
65
+ }
66
+
67
+ protected function GetListView() {
68
+ if (is_null($this->_listview)) $this->_listview = new WSAL_AuditLogListView($this->_plugin);
69
+ return $this->_listview;
70
+ }
71
+
72
+ public function Render() {
73
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
74
+ wp_die(__('You do not have sufficient permissions to access this page.', 'wp-security-audit-log'));
75
+ }
76
+
77
+ $this->GetListView()->prepare_items();
78
+ $occ = new WSAL_Models_Occurrence();
79
+
80
+ ?><form id="audit-log-viewer" method="post">
81
+ <div id="audit-log-viewer-content">
82
+ <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
83
+ <input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr(isset($_REQUEST['wsal-cbid']) ? $_REQUEST['wsal-cbid'] : '0'); ?>" />
84
+ <?php do_action('wsal_auditlog_before_view', $this->GetListView()); ?>
85
+ <?php $this->GetListView()->display(); ?>
86
+ <?php do_action('wsal_auditlog_after_view', $this->GetListView()); ?>
87
+ </div>
88
+ </form><?php
89
+
90
+ ?><script type="text/javascript">
91
+ jQuery(document).ready(function(){
92
+ WsalAuditLogInit(<?php echo json_encode(array(
93
+ 'ajaxurl' => admin_url('admin-ajax.php'),
94
+ 'tr8n' => array(
95
+ 'numofitems' => __('Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log'),
96
+ 'searchback' => __('All Sites', 'wp-security-audit-log'),
97
+ 'searchnone' => __('No Results', 'wp-security-audit-log'),
98
+ ),
99
+ 'autorefresh' => array(
100
+ 'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
101
+ 'token' => (int)$occ->Count(),
102
+ ),
103
+ )); ?>);
104
+ });
105
+ </script><?php
106
+ }
107
+
108
+ public function AjaxInspector() {
109
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
110
+ die('Access Denied.');
111
+ if(!isset($_REQUEST['occurrence']))
112
+ die('Occurrence parameter expected.');
113
+ $occ = new WSAL_Models_Occurrence();
114
+ $occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
115
+
116
+ echo '<!DOCTYPE html><html><head>';
117
+ echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
118
+ echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
119
+ echo '<style type="text/css">';
120
+ echo 'html, body { margin: 0; padding: 0; }';
121
+ echo '.nice_r { position: absolute; padding: 8px; }';
122
+ echo '.nice_r a { overflow: visible; }';
123
+ echo '</style>';
124
+ echo '</head><body>';
125
+ $nicer = new WSAL_Nicer($occ->GetMetaArray());
126
+ $nicer->render();
127
+ echo '</body></html>';
128
+ die;
129
+ }
130
+
131
+ public function AjaxRefresh() {
132
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
133
+ die('Access Denied.');
134
+ if(!isset($_REQUEST['logcount']))
135
+ die('Log count parameter expected.');
136
+
137
+ $old = (int)$_REQUEST['logcount'];
138
+ $max = 40; // 40*500msec = 20sec
139
+
140
+ session_write_close(); // fixes session lock issue
141
+
142
+ do{
143
+ $occ = new WSAL_Models_Occurrence();
144
+ $new = $occ->Count();
145
+ usleep(500000); // 500msec
146
+ }while(($old == $new) && (--$max > 0));
147
+
148
+ echo $old == $new ? 'false' : $new;
149
+ die;
150
+ }
151
+
152
+ public function AjaxSetIpp(){
153
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
154
+ die('Access Denied.');
155
+ if(!isset($_REQUEST['count']))
156
+ die('Count parameter expected.');
157
+ $this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
158
+ die;
159
+ }
160
+
161
+ public function AjaxSearchSite(){
162
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
163
+ die('Access Denied.');
164
+ if(!isset($_REQUEST['search']))
165
+ die('Search parameter expected.');
166
+
167
+ $grp1 = array();
168
+ $grp2 = array();
169
+
170
+ $search = $_REQUEST['search'];
171
+
172
+ foreach($this->GetListView()->get_sites() as $site){
173
+ if(stripos($site->blogname, $search) !== false)
174
+ $grp1[] = $site;
175
+ else
176
+ if(stripos($site->domain, $search) !== false)
177
+ $grp2[] = $site;
178
+ }
179
+
180
+ die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
181
+ }
182
+
183
+ public function Header() {
184
+ add_thickbox();
185
+ wp_enqueue_style(
186
+ 'auditlog',
187
+ $this->_plugin->GetBaseUrl() . '/css/auditlog.css',
188
+ array(),
189
+ filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
190
+ );
191
+ }
192
+
193
+ public function Footer() {
194
+ wp_enqueue_script('jquery');
195
+ wp_enqueue_script('suggest');
196
+ wp_enqueue_script(
197
+ 'auditlog',
198
+ $this->_plugin->GetBaseUrl() . '/js/auditlog.js',
199
+ array(),
200
+ filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
201
+ );
202
+ }
203
+ }
classes/Views/EmailNotifications.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Views_EmailNotifications extends WSAL_AbstractView {
4
+
5
+ public function GetTitle()
6
+ {
7
+ return __('Email Notifications Add-On', 'wp-security-audit-log');
8
+ }
9
+
10
+ public function GetIcon()
11
+ {
12
+ return 'dashicons-external';
13
+ }
14
+
15
+ public function GetName()
16
+ {
17
+ return __('Notifications Email', 'wp-security-audit-log');
18
+ }
19
+
20
+ public function GetWeight()
21
+ {
22
+ return 7;
23
+ }
24
+
25
+ public function Header() {
26
+ wp_enqueue_style(
27
+ 'extensions',
28
+ $this->_plugin->GetBaseUrl() . '/css/extensions.css',
29
+ array(),
30
+ filemtime($this->_plugin->GetBaseDir() . '/css/extensions.css')
31
+ );
32
+ }
33
+
34
+ public function Render()
35
+ {
36
+ ?>
37
+ <div class="wrap-advertising-page-single">
38
+ <div class="icon" style='background-image:url("<?=$this->_plugin->GetBaseUrl();?>/img/envelope.jpg");'></div>
39
+ <h3><?php _e('Email Notifications', 'wp-security-audit-log'); ?></h3>
40
+ <p>
41
+ <?php _e('This premium add-on allows you to configure email alerts so you are <br>notified instantly when important changes happen on your WordPress.', 'wp-security-audit-log'); ?>
42
+ </p>
43
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=emailpage&utm_campaign=notifications'; ?>
44
+ <p>
45
+ <a class="button-primary" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Learn More', 'wp-security-audit-log'); ?></a>
46
+ </p>
47
+ <div class="clear"></div>
48
+ <p>
49
+ <span class="description">
50
+ <strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
51
+ </span>
52
+ </p>
53
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
54
+ <a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
55
+ </div>
56
+ <?php
57
+ }
58
+ }
classes/Views/Extensions.php CHANGED
@@ -19,63 +19,110 @@ class WSAL_Views_Extensions extends WSAL_AbstractView
19
  public function GetWeight() {
20
  return 3.5;
21
  }
 
 
 
 
 
 
 
 
 
22
 
23
  public function Render()
24
  {
25
- ?><div class="metabox-holder" style="position: relative;">
26
-
27
- <div class="postbox" style="margin-right: 270px;">
28
- <div class="inside">
29
- <div class="activity-block">
30
- <p><?php _e('The below add-ons allow you to extend the functionality of WP Security Audit Log plugin and enable you to get more benefits out of the WordPress security audit, such as configurable email alerts, ability to search using free text based searches & filters, and generate user activity reports to meet regulatory compliance requirements.', 'wp-security-audit-log'); ?></p>
31
- </div>
32
-
33
- <div class="activity-block">
34
- <h2><?php _e('60% Off All Add-Ons Bundle', 'wp-security-audit-log'); ?></h2>
35
- <strong><?php _e('Add email alerts, generate reports and add the search functionality to your WordPress audit log.', 'wp-security-audit-log'); ?></strong>
36
- <p><?php _e('Buy all the WP Security Audit Log Add-Ons as a bundle and benefit from a 60% discount. The bundle for 1 website only costs $89 and price per website gets lower with bulk pricing.', 'wp-security-audit-log'); ?></p>
37
- <p><a class="button" href="http://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons" target="_blank"><?php _e('More Information', 'wp-security-audit-log'); ?></a></p>
38
- </div>
39
- <?php
40
- if (!class_exists('WSAL_NP_Plugin')) { ?>
41
- <div class="activity-block">
42
- <h2><?php _e('Email Notifications Add-On', 'wp-security-audit-log'); ?></h2>
43
- <strong><?php _e('Get notified instantly via email when important changes are made on your WordPress!', 'wp-security-audit-log'); ?></strong>
44
- <p><?php _e('With the Email Notifications Add-On you can easily configure trigger rules so when a specific change happens on your WordPress you are instantly alerted via email. For example you can configure rules to receive an email when existing content is changed, when a new user is created or when someone logs in to WordPress outside normal office hours or from an odd location.', 'wp-security-audit-log'); ?></p>
45
- <p><a class="button" href="http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=notifications" target="_blank"><?php _e('More Information', 'wp-security-audit-log'); ?></a></p>
46
- </div>
47
- <?php
48
- }
49
- if (!class_exists('WSAL_Ext_Plugin')) { ?>
50
- <div class="activity-block">
51
- <h2><?php _e('External DB Add-On', 'wp-security-audit-log'); ?></h2>
52
- <strong><?php _e('Save the WordPress Audit Log in an external database.', 'wp-security-audit-log'); ?></strong>
53
- <p><?php _e('By saving the WordPress Audit Log in an external database you improve the security and performance of your WordPress websites and blogs. You also ensure that your WordPress is compliant to a number of mandatory regulatory compliance requirements business websites need to adhere to.', 'wp-security-audit-log'); ?></p>
54
- <p><a class="button" href="http://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=externaldb" target="_blank"><?php _e('More Information', 'wp-security-audit-log'); ?></a></p>
55
- </div>
56
- <?php
57
- }
58
- if (!class_exists('WSAL_SearchExtension')) { ?>
59
- <div class="activity-block">
60
- <h2><?php _e('Search Add-On', 'wp-security-audit-log'); ?></h2>
61
- <strong><?php _e('Automatically Search for specific WordPress user and site activity in WordPress Security Audit Log.', 'wp-security-audit-log'); ?></strong>
62
- <p><?php _e('The Search Add-On enables you to easily find specific WordPress activity in the Audit Log with free-text based searches. Filters can also be used in conjunction with free-text based searches to fine tune the search and find what you are looking for easily.', 'wp-security-audit-log'); ?></p>
63
- <p><a class="button" href="http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=search" target="_blank"><?php _e('More Information', 'wp-security-audit-log'); ?></a></p>
64
- </div>
65
- <?php
66
- }
67
- if (!class_exists('WSAL_Rep_Plugin')) { ?>
68
- <div class="activity-block">
69
- <h2><?php _e('Reports Add-Ons', 'wp-security-audit-log'); ?></h2>
70
- <strong><?php _e('Generate User, Site and Regulatory Compliance Reports.', 'wp-security-audit-log'); ?></strong>
71
- <p><?php _e('The Reports Add-On allows you to generate reports and keep track and record of user productivity, and meet any legal and regulatory compliance your business need to adhere to. Unlike other reporting plugins the Reports Add-On does not have any built-in templates that restrict you to specific type of reports, you can generate any type of report using all of the available data.', 'wp-security-audit-log'); ?></p>
72
- <p><a class="button" href="http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=reports" target="_blank"><?php _e('More Information', 'wp-security-audit-log'); ?></a></p>
73
- </div>
74
- <?php
75
- } ?>
76
- </div>
77
  </div>
78
- </div><?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
-
81
  }
19
  public function GetWeight() {
20
  return 3.5;
21
  }
22
+
23
+ public function Header() {
24
+ wp_enqueue_style(
25
+ 'extensions',
26
+ $this->_plugin->GetBaseUrl() . '/css/extensions.css',
27
+ array(),
28
+ filemtime($this->_plugin->GetBaseDir() . '/css/extensions.css')
29
+ );
30
+ }
31
 
32
  public function Render()
33
  {
34
+ ?>
35
+ <p><?php _e('The below add-ons allow you to extend the functionality of WP Security Audit Log plugin and enable you to get more benefits out of the WordPress security audit, such as configurable email alerts, ability to search using free text based searches & filters, and generate user activity reports to meet regulatory compliance requirements.', 'wp-security-audit-log'); ?>
36
+ </p>
37
+ <div class="wrap-advertising-page">
38
+ <div class="extension all">
39
+ <?php $link = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
40
+ <a target="_blank" href="<?php echo esc_attr($link); ?>">
41
+ <h3><?php _e('All Add-Ons Bundle', 'wp-security-audit-log'); ?></h3>
42
+ </a>
43
+ <p><?php _e('Benefit from a 60% discount when you purchase all the add-ons as a single bundle.', 'wp-security-audit-log'); ?>
44
+ </p>
45
+ <p>
46
+ <a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this Bundle', 'wp-security-audit-log'); ?>
47
+ </a>
48
+ </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  </div>
50
+ <?php if (!class_exists('WSAL_User_Management_Plugin')) { ?>
51
+ <div class="extension user-managment">
52
+ <?php $link = 'https://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=logins'; ?>
53
+ <a target="_blank" href="<?php echo esc_attr($link); ?>">
54
+ <h3><?php _e('Users Logins and Management', 'wp-security-audit-log'); ?></h3>
55
+ </a>
56
+ <p><?php _e('See who is logged in to your WordPress and manage user sessions and logins.', 'wp-security-audit-log'); ?>
57
+
58
+ </p>
59
+ <p>
60
+ <a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
61
+ </a>
62
+ </p>
63
+ </div>
64
+ <?php } ?>
65
+ <?php if (!class_exists('WSAL_NP_Plugin')) { ?>
66
+ <div class="extension email-notifications">
67
+ <?php $link = 'https://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=notifications'; ?>
68
+ <a target="_blank" href="<?php echo esc_attr($link); ?>">
69
+ <h3><?php _e('Email Notifications', 'wp-security-audit-log'); ?></h3>
70
+ </a>
71
+ <p><?php _e('Get notified instantly via email when important changes are made on your WordPress!', 'wp-security-audit-log'); ?>
72
+
73
+ </p>
74
+ <p>
75
+ <a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
76
+ </a>
77
+ </p>
78
+ </div>
79
+ <?php } ?>
80
+ <?php if (!class_exists('WSAL_Rep_Plugin')) { ?>
81
+ <div class="extension reports">
82
+ <?php $link = 'https://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=reports'; ?>
83
+ <a target="_blank" href="<?php echo esc_attr($link); ?>">
84
+ <h3><?php _e('Reports', 'wp-security-audit-log'); ?></h3>
85
+ </a>
86
+ <p><?php _e('Generate any type of user,site and activity report to keep track of user productivity and to meet regulatory compliance requirements.', 'wp-security-audit-log'); ?>
87
+
88
+ </p>
89
+ <p>
90
+ <a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
91
+ </a>
92
+ </p>
93
+ </div>
94
+ <?php } ?>
95
+ <?php if (!class_exists('WSAL_SearchExtension')) { ?>
96
+ <div class="extension search-ext">
97
+ <?php $link = 'https://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=search'; ?>
98
+ <a target="_blank" href="<?php echo esc_attr($link); ?>">
99
+ <h3><?php _e('Search', 'wp-security-audit-log'); ?></h3>
100
+ </a>
101
+ <p><?php _e('Do free-text based searches for specific activity in the WordPress audit trail. You can also use filters to fine-tune your searches.', 'wp-security-audit-log'); ?>
102
+
103
+ </p>
104
+ <p>
105
+ <a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
106
+ </a>
107
+ </p>
108
+ </div>
109
+ <?php } ?>
110
+ <?php if (!class_exists('WSAL_Ext_Plugin')) { ?>
111
+ <div class="extension external-db">
112
+ <?php $link = 'https://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=externaldb'; ?>
113
+ <a target="_blank" href="<?php echo esc_attr($link); ?>">
114
+ <h3><?php _e('External DB', 'wp-security-audit-log'); ?></h3>
115
+ </a>
116
+ <p><?php _e('Store the WordPress audit trial in an external database for a more secure and faster WordPress website.', 'wp-security-audit-log'); ?>
117
+
118
+ </p>
119
+ <p>
120
+ <a target="_blank" href="<?php echo esc_attr($link); ?>" class="button-primary"><?php _e('Get this extension', 'wp-security-audit-log'); ?>
121
+ </a>
122
+ </p>
123
+ </div>
124
+ <?php } ?>
125
+ </div>
126
+ <?php
127
  }
 
128
  }
classes/Views/Help.php CHANGED
@@ -1,79 +1,79 @@
1
- <?php
2
-
3
- class WSAL_Views_Help extends WSAL_AbstractView {
4
-
5
- public function GetTitle() {
6
- return __('Help', 'wp-security-audit-log');
7
- }
8
-
9
- public function GetIcon() {
10
- return 'dashicons-sos';
11
- }
12
-
13
- public function GetName() {
14
- return __('Help', 'wp-security-audit-log');
15
- }
16
-
17
- public function GetWeight() {
18
- return 5;
19
- }
20
-
21
- public function Render(){
22
- ?><div class="metabox-holder" style="position: relative;">
23
-
24
- <div class="postbox" style="margin-right: 270px;">
25
- <div class="inside">
26
- <div class="activity-block">
27
- <h2><?php _e('Plugin Support', 'wp-security-audit-log'); ?></h2>
28
- <p>
29
- <?php _e('Have you encountered or noticed any issues while using WP Security Audit Log plugin?', 'wp-security-audit-log'); ?>
30
- <?php _e('Or you want to report something to us? Click any of the options below to post on the plugin\'s forum or contact our support directly.', 'wp-security-audit-log'); ?>
31
- </p><p>
32
- <a class="button" href="https://wordpress.org/support/plugin/wp-security-audit-log" target="_blank"><?php _e('Free Support Forum', 'wp-security-audit-log'); ?></a>
33
- &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=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
45
- &nbsp;&nbsp;&nbsp;&nbsp;
46
- <a class="button" href="https://www.wpsecurityauditlog.com/documentation/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('Plugin Documenation', 'wp-security-audit-log'); ?></a>
47
- &nbsp;&nbsp;&nbsp;&nbsp;
48
- <a class="button" href="https://www.wpsecurityauditlog.com/documentation/frequently-asked-questions-faqs/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('FAQs', 'wp-security-audit-log'); ?></a>
49
- &nbsp;&nbsp;&nbsp;&nbsp;
50
- <a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
51
- </p>
52
- </div>
53
-
54
- <div class="">
55
- <h2><?php _e('Keep Yourself Up-to-Date with WordPress Security', 'wp-security-audit-log'); ?></h2>
56
- <p>
57
- <?php _e('Keep yourself informed with what is happening in the WordPress security ecosystem, which are the new vulnerabilities, which plugins you need to update and what are the latest WordPress security hacks so you can stay one step ahead of the hackers.', 'wp-security-audit-log'); ?>
58
- </p>
59
- <a class="button" href="http://www.wpwhitesecurity.com/blog/" target="_blank"><?php _e('Read the WP White Security Blog', 'wp-security-audit-log'); ?></a>
60
- &nbsp;&nbsp;&nbsp;&nbsp;
61
- <a class="button" href="http://www.wpsecuritybloggers.com" target="_blank"><?php _e('Subscribe to WP Security Bloggers (An Aggregate of WordPress Security Blogs)', 'wp-security-audit-log'); ?></a>
62
- </div>
63
- </div>
64
- </div>
65
-
66
- <div style="position: absolute; right: 70px; width: 180px; top: 10px;">
67
- <div class="postbox">
68
- <h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
69
- <div class="inside">
70
- <?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
71
- <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
72
- </div>
73
- </div>
74
- </div>
75
-
76
- </div><?php
77
- }
78
-
79
  }
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=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
45
+ &nbsp;&nbsp;&nbsp;&nbsp;
46
+ <a class="button" href="https://www.wpsecurityauditlog.com/documentation/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('Plugin Documenation', 'wp-security-audit-log'); ?></a>
47
+ &nbsp;&nbsp;&nbsp;&nbsp;
48
+ <a class="button" href="https://www.wpsecurityauditlog.com/documentation/frequently-asked-questions-faqs/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('FAQs', 'wp-security-audit-log'); ?></a>
49
+ &nbsp;&nbsp;&nbsp;&nbsp;
50
+ <a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=plugin&utm_medium=helppage&utm_campaign=support" target="_blank"><?php _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
51
+ </p>
52
+ </div>
53
+
54
+ <div class="">
55
+ <h2><?php _e('Keep Yourself Up-to-Date with WordPress Security', 'wp-security-audit-log'); ?></h2>
56
+ <p>
57
+ <?php _e('Keep yourself informed with what is happening in the WordPress security ecosystem, which are the new vulnerabilities, which plugins you need to update and what are the latest WordPress security hacks so you can stay one step ahead of the hackers.', 'wp-security-audit-log'); ?>
58
+ </p>
59
+ <a class="button" href="http://www.wpwhitesecurity.com/blog/" target="_blank"><?php _e('Read the WP White Security Blog', 'wp-security-audit-log'); ?></a>
60
+ &nbsp;&nbsp;&nbsp;&nbsp;
61
+ <a class="button" href="http://www.wpsecuritybloggers.com" target="_blank"><?php _e('Subscribe to WP Security Bloggers (An Aggregate of WordPress Security Blogs)', 'wp-security-audit-log'); ?></a>
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <div style="position: absolute; right: 70px; width: 180px; top: 10px;">
67
+ <div class="postbox">
68
+ <h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
69
+ <div class="inside">
70
+ <?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
71
+ <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
72
+ </div>
73
+ </div>
74
+ </div>
75
+
76
+ </div><?php
77
+ }
78
+
79
  }
classes/Views/Licensing.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
-
3
- class WSAL_Views_Licensing extends WSAL_AbstractView {
4
-
5
- public function GetTitle() {
6
- return __('Licensing', 'wp-security-audit-log');
7
- }
8
-
9
- public function GetIcon() {
10
- return 'dashicons-cart';
11
- }
12
-
13
- public function GetName() {
14
- return __('Licensing', 'wp-security-audit-log');
15
- }
16
-
17
- public function GetWeight() {
18
- return 4;
19
- }
20
-
21
- public function IsAccessible(){
22
- return !!$this->_plugin->licensing->CountPlugins();
23
- }
24
-
25
- protected function Save(){
26
- $this->_plugin->settings->ClearLicenses();
27
- if (isset($_REQUEST['license']))
28
- foreach ($_REQUEST['license'] as $name => $key)
29
- $this->_plugin->licensing->ActivateLicense($name, $key);
30
- }
31
-
32
- public function Render(){
33
- if(!$this->_plugin->settings->CurrentUserCan('edit')){
34
- wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
35
- }
36
- if(isset($_POST['submit'])){
37
- try {
38
- $this->Save();
39
- ?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
40
- }catch(Exception $ex){
41
- ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
42
- }
43
- }
44
- ?><form id="audit-log-licensing" method="post">
45
- <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
46
-
47
- <table class="wp-list-table widefat fixed">
48
- <thead>
49
- <tr><th>Plugin</th><th>License</th><th></th></tr>
50
- </thead><tbody>
51
- <?php $counter = 0; ?>
52
- <?php foreach($this->_plugin->licensing->Plugins() as $name => $plugin){ ?>
53
- <?php $licenseKey = trim($this->_plugin->settings->GetLicenseKey($name)); ?>
54
- <?php $licenseStatus = trim($this->_plugin->settings->GetLicenseStatus($name)); ?>
55
- <?php $licenseErrors = trim($this->_plugin->settings->GetLicenseErrors($name)); ?>
56
- <tr class="<?php echo ($counter++ % 2 === 0) ? 'alternate' : ''; ?>">
57
- <td>
58
- <a href="<?php echo esc_attr($plugin['PluginData']['PluginURI']); ?>" target="_blank">
59
- <?php echo esc_html($plugin['PluginData']['Name']); ?>
60
- </a><br/><small><b>
61
- <?php _e('Version', 'wp-security-audit-log'); ?>
62
- <?php echo esc_html($plugin['PluginData']['Version']); ?>
63
- </b></small>
64
- </td><td>
65
- <input type="text" style="width: 360px; margin: 6px 0;"
66
- name="license[<?php echo esc_attr($name); ?>]"
67
- value="<?php echo esc_attr($licenseKey); ?>"/>
68
- </td><td style="vertical-align: middle;">
69
- <?php if($licenseKey){ ?>
70
- <?php if($licenseStatus === 'valid'){ ?>
71
- <?php _e('Active', 'wp-security-audit-log'); ?>
72
- <?php }else{ ?>
73
- <?php _e('Inactive', 'wp-security-audit-log'); ?><br/>
74
- <small><?php echo esc_html($licenseErrors); ?></small>
75
- <?php } ?>
76
- <?php } ?>
77
- </td>
78
- </tr>
79
- <?php } ?>
80
- </tbody><tfoot>
81
- <tr><th>Plugin</th><th>License</th><th></th></tr>
82
- </tfoot>
83
- </table>
84
- <?php submit_button(); ?>
85
- </form><?php
86
- }
87
-
88
  }
1
+ <?php
2
+
3
+ class WSAL_Views_Licensing extends WSAL_AbstractView {
4
+
5
+ public function GetTitle() {
6
+ return __('Licensing', 'wp-security-audit-log');
7
+ }
8
+
9
+ public function GetIcon() {
10
+ return 'dashicons-cart';
11
+ }
12
+
13
+ public function GetName() {
14
+ return __('Licensing', 'wp-security-audit-log');
15
+ }
16
+
17
+ public function GetWeight() {
18
+ return 4;
19
+ }
20
+
21
+ public function IsAccessible(){
22
+ return !!$this->_plugin->licensing->CountPlugins();
23
+ }
24
+
25
+ protected function Save(){
26
+ $this->_plugin->settings->ClearLicenses();
27
+ if (isset($_REQUEST['license']))
28
+ foreach ($_REQUEST['license'] as $name => $key)
29
+ $this->_plugin->licensing->ActivateLicense($name, $key);
30
+ }
31
+
32
+ public function Render(){
33
+ if(!$this->_plugin->settings->CurrentUserCan('edit')){
34
+ wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
35
+ }
36
+ if(isset($_POST['submit'])){
37
+ try {
38
+ $this->Save();
39
+ ?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
40
+ }catch(Exception $ex){
41
+ ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
42
+ }
43
+ }
44
+ ?><form id="audit-log-licensing" method="post">
45
+ <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
46
+
47
+ <table class="wp-list-table widefat fixed">
48
+ <thead>
49
+ <tr><th>Plugin</th><th>License</th><th></th></tr>
50
+ </thead><tbody>
51
+ <?php $counter = 0; ?>
52
+ <?php foreach($this->_plugin->licensing->Plugins() as $name => $plugin){ ?>
53
+ <?php $licenseKey = trim($this->_plugin->settings->GetLicenseKey($name)); ?>
54
+ <?php $licenseStatus = trim($this->_plugin->settings->GetLicenseStatus($name)); ?>
55
+ <?php $licenseErrors = trim($this->_plugin->settings->GetLicenseErrors($name)); ?>
56
+ <tr class="<?php echo ($counter++ % 2 === 0) ? 'alternate' : ''; ?>">
57
+ <td>
58
+ <a href="<?php echo esc_attr($plugin['PluginData']['PluginURI']); ?>" target="_blank">
59
+ <?php echo esc_html($plugin['PluginData']['Name']); ?>
60
+ </a><br/><small><b>
61
+ <?php _e('Version', 'wp-security-audit-log'); ?>
62
+ <?php echo esc_html($plugin['PluginData']['Version']); ?>
63
+ </b></small>
64
+ </td><td>
65
+ <input type="text" style="width: 360px; margin: 6px 0;"
66
+ name="license[<?php echo esc_attr($name); ?>]"
67
+ value="<?php echo esc_attr($licenseKey); ?>"/>
68
+ </td><td style="vertical-align: middle;">
69
+ <?php if($licenseKey){ ?>
70
+ <?php if($licenseStatus === 'valid'){ ?>
71
+ <?php _e('Active', 'wp-security-audit-log'); ?>
72
+ <?php }else{ ?>
73
+ <?php _e('Inactive', 'wp-security-audit-log'); ?><br/>
74
+ <small><?php echo esc_html($licenseErrors); ?></small>
75
+ <?php } ?>
76
+ <?php } ?>
77
+ </td>
78
+ </tr>
79
+ <?php } ?>
80
+ </tbody><tfoot>
81
+ <tr><th>Plugin</th><th>License</th><th></th></tr>
82
+ </tfoot>
83
+ </table>
84
+ <?php submit_button(); ?>
85
+ </form><?php
86
+ }
87
+
88
  }
classes/Views/LogInUsers.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Views_LogInUsers extends WSAL_AbstractView {
4
+
5
+ public function GetTitle()
6
+ {
7
+ return __('User Sessions Management Add-On', 'wp-security-audit-log');
8
+ }
9
+
10
+ public function GetIcon()
11
+ {
12
+ return 'dashicons-external';
13
+ }
14
+
15
+ public function GetName()
16
+ {
17
+ return __('Logged In Users', 'wp-security-audit-log');
18
+ }
19
+
20
+ public function GetWeight()
21
+ {
22
+ return 8;
23
+ }
24
+
25
+ public function Header() {
26
+ wp_enqueue_style(
27
+ 'extensions',
28
+ $this->_plugin->GetBaseUrl() . '/css/extensions.css',
29
+ array(),
30
+ filemtime($this->_plugin->GetBaseDir() . '/css/extensions.css')
31
+ );
32
+ }
33
+
34
+ public function Render()
35
+ {
36
+ ?>
37
+ <div class="wrap-advertising-page-single">
38
+ <div class="icon" style='background-image:url("<?=$this->_plugin->GetBaseUrl();?>/img/monitoring.jpg");'></div>
39
+ <h3><?php _e('Users login and Management', 'wp-security-audit-log'); ?></h3>
40
+ <p>
41
+ <?php _e('This premium add-on allows you to see who is logged in to your WordPress,<br> block multiple same-user WordPress sessions and more.', 'wp-security-audit-log'); ?>
42
+ </p>
43
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/?utm_source=plugin&utm_medium=loginspage&utm_campaign=logins'; ?>
44
+ <p>
45
+ <a class="button-primary" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Learn More', 'wp-security-audit-log'); ?></a>
46
+ </p>
47
+ <div class="clear"></div>
48
+ <p>
49
+ <span class="description">
50
+ <strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
51
+ </span>
52
+ </p>
53
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
54
+ <a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
55
+ </div>
56
+ <?php
57
+ }
58
+ }
classes/Views/Reports.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Views_Reports extends WSAL_AbstractView {
4
+
5
+ public function GetTitle()
6
+ {
7
+ return __('Reports Add-On', 'wp-security-audit-log');
8
+ }
9
+
10
+ public function GetIcon()
11
+ {
12
+ return 'dashicons-external';
13
+ }
14
+
15
+ public function GetName()
16
+ {
17
+ return __('Reports', 'wp-security-audit-log');
18
+ }
19
+
20
+ public function GetWeight()
21
+ {
22
+ return 9;
23
+ }
24
+
25
+ public function Header() {
26
+ wp_enqueue_style(
27
+ 'extensions',
28
+ $this->_plugin->GetBaseUrl() . '/css/extensions.css',
29
+ array(),
30
+ filemtime($this->_plugin->GetBaseDir() . '/css/extensions.css')
31
+ );
32
+ }
33
+
34
+ public function Render()
35
+ {
36
+ ?>
37
+ <div class="wrap-advertising-page-single">
38
+ <div class="icon" style='background-image:url("<?=$this->_plugin->GetBaseUrl();?>/img/file.jpg");'></div>
39
+ <h3><?php _e('Reports', 'wp-security-audit-log'); ?></h3>
40
+ <p>
41
+ <?php _e('Generate any type of user and site activity report to keep track of user productivity<br> and meet regulatory compliance requirements. You can also configure automated weekly or monthly email summary reports.', 'wp-security-audit-log'); ?>
42
+ </p>
43
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=plugin&utm_medium=reportspage&utm_campaign=reports'; ?>
44
+ <p>
45
+ <a class="button-primary" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Learn More', 'wp-security-audit-log'); ?></a>
46
+ </p>
47
+ <div class="clear"></div>
48
+ <p>
49
+ <span class="description">
50
+ <strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
51
+ </span>
52
+ </p>
53
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
54
+ <a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
55
+ </div>
56
+ <?php
57
+ }
58
+ }
classes/Views/Search.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WSAL_Views_Search extends WSAL_AbstractView {
4
+
5
+ public function GetTitle()
6
+ {
7
+ return __('Search Add-On', 'wp-security-audit-log');
8
+ }
9
+
10
+ public function GetIcon()
11
+ {
12
+ return 'dashicons-external';
13
+ }
14
+
15
+ public function GetName()
16
+ {
17
+ return __('Search', 'wp-security-audit-log');
18
+ }
19
+
20
+ public function GetWeight()
21
+ {
22
+ return 9;
23
+ }
24
+
25
+ public function Header() {
26
+ wp_enqueue_style(
27
+ 'extensions',
28
+ $this->_plugin->GetBaseUrl() . '/css/extensions.css',
29
+ array(),
30
+ filemtime($this->_plugin->GetBaseDir() . '/css/extensions.css')
31
+ );
32
+ }
33
+
34
+ public function Render()
35
+ {
36
+ ?>
37
+ <div class="wrap-advertising-page-single">
38
+ <div class="icon" style='background-image:url("<?=$this->_plugin->GetBaseUrl();?>/img/search.jpg");'></div>
39
+ <h3><?php _e('Search', 'wp-security-audit-log'); ?></h3>
40
+ <p>
41
+ <?php _e('Do free-text based searches for specific activity in the WordPress audit trail.<br> You can also use the built-in filters to fine-tune your searches.', 'wp-security-audit-log'); ?>
42
+ </p>
43
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=plugin&utm_medium=searchpage&utm_campaign=search'; ?>
44
+ <p>
45
+ <a class="button-primary" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Learn More', 'wp-security-audit-log'); ?></a>
46
+ </p>
47
+ <div class="clear"></div>
48
+ <p>
49
+ <span class="description">
50
+ <strong><span class="text-red">70% Off</span> when you purchase this add-on as part of the All Add-On bundle.</strong>
51
+ </span>
52
+ </p>
53
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=plugin&utm_medium=extensionspage&utm_campaign=alladdons'; ?>
54
+ <a class="button-blue" href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Buy all Add-Ons Bundle', 'wp-security-audit-log'); ?></a>
55
+ </div>
56
+ <?php
57
+ }
58
+ }
classes/Views/Settings.php CHANGED
@@ -1,682 +1,698 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
56
+ $this->_plugin->settings->SetFromEmail($_REQUEST['FromEmail']);
57
+ $this->_plugin->settings->SetDisplayName($_REQUEST['DisplayName']);
58
+
59
+ $this->_plugin->settings->SetWidgetsEnabled($_REQUEST['EnableDashboardWidgets']);
60
+ $this->_plugin->settings->SetAllowedPluginViewers(isset($_REQUEST['Viewers']) ? $_REQUEST['Viewers'] : array());
61
+ $this->_plugin->settings->SetAllowedPluginEditors(isset($_REQUEST['Editors']) ? $_REQUEST['Editors'] : array());
62
+
63
+ $this->_plugin->settings->SetExcludedMonitoringUsers(isset($_REQUEST['ExUsers']) ? $_REQUEST['ExUsers'] : array());
64
+ $this->_plugin->settings->SetExcludedMonitoringRoles(isset($_REQUEST['ExRoles']) ? $_REQUEST['ExRoles'] : array());
65
+ $this->_plugin->settings->SetExcludedMonitoringCustom(isset($_REQUEST['Customs']) ? $_REQUEST['Customs'] : array());
66
+ $this->_plugin->settings->SetExcludedMonitoringIP(isset($_REQUEST['IpAddrs']) ? $_REQUEST['IpAddrs'] : array());
67
+
68
+ $this->_plugin->settings->SetRestrictAdmins(isset($_REQUEST['RestrictAdmins']));
69
+ $this->_plugin->settings->SetRefreshAlertsEnabled($_REQUEST['EnableAuditViewRefresh']);
70
+ $this->_plugin->settings->SetMainIPFromProxy(isset($_REQUEST['EnableProxyIpCapture']));
71
+ $this->_plugin->settings->SetInternalIPsFiltering(isset($_REQUEST['EnableIpFiltering']));
72
+ $this->_plugin->settings->SetIncognito(isset($_REQUEST['Incognito']));
73
+ $this->_plugin->settings->SetDeleteData(isset($_REQUEST['DeleteData']));
74
+ $this->_plugin->settings->SetDatetimeFormat($_REQUEST['DatetimeFormat']);
75
+ $this->_plugin->settings->SetTimezone($_REQUEST['Timezone']);
76
+ $this->_plugin->settings->SetWPBackend(isset($_REQUEST['WPBackend']));
77
+ if (!empty($_REQUEST['Columns'])) {
78
+ $this->_plugin->settings->SetColumns($_REQUEST['Columns']);
79
+ }
80
+ $this->_plugin->settings->ClearDevOptions();
81
+
82
+ if (isset($_REQUEST['DevOptions'])) {
83
+ foreach ($_REQUEST['DevOptions'] as $opt) {
84
+ $this->_plugin->settings->SetDevOptionEnabled($opt, true);
85
+ }
86
+ }
87
+
88
+ // Database Adapter Settings
89
+ // Temporarily not used
90
+ /* Check Adapter config */
91
+ if (!empty($_REQUEST["AdapterUser"]) && ($_REQUEST['AdapterUser'] != '') && ($_REQUEST['AdapterName'] != '') && ($_REQUEST['AdapterHostname'] != '')) {
92
+ WSAL_Connector_ConnectorFactory::CheckConfig(
93
+ trim($_REQUEST['AdapterType']),
94
+ trim($_REQUEST['AdapterUser']),
95
+ trim($_REQUEST['AdapterPassword']),
96
+ trim($_REQUEST['AdapterName']),
97
+ trim($_REQUEST['AdapterHostname']),
98
+ trim($_REQUEST['AdapterBasePrefix'])
99
+ );
100
+
101
+ /* Setting Adapter config */
102
+ $this->_plugin->settings->SetAdapterConfig('adapter-type', $_REQUEST['AdapterType']);
103
+ $this->_plugin->settings->SetAdapterConfig('adapter-user', $_REQUEST['AdapterUser']);
104
+ $this->_plugin->settings->SetAdapterConfig('adapter-password', $_REQUEST['AdapterPassword']);
105
+ $this->_plugin->settings->SetAdapterConfig('adapter-name', $_REQUEST['AdapterName']);
106
+ $this->_plugin->settings->SetAdapterConfig('adapter-hostname', $_REQUEST['AdapterHostname']);
107
+ $this->_plugin->settings->SetAdapterConfig('adapter-base-prefix', $_REQUEST['AdapterBasePrefix']);
108
+ }
109
+ }
110
+
111
+ public function AjaxCheckSecurityToken()
112
+ {
113
+ if (!$this->_plugin->settings->CurrentUserCan('view'))
114
+ die('Access Denied.');
115
+ if (!isset($_REQUEST['token']))
116
+ die('Token parameter expected.');
117
+ die($this->GetTokenType($_REQUEST['token']));
118
+ }
119
+
120
+ public function AjaxRunCleanup()
121
+ {
122
+ if (!$this->_plugin->settings->CurrentUserCan('view'))
123
+ die('Access Denied.');
124
+ $this->_plugin->CleanUp();
125
+ wp_redirect($this->GetUrl());
126
+ exit;
127
+ }
128
+
129
+ public function Render()
130
+ {
131
+ if (!$this->_plugin->settings->CurrentUserCan('edit')) {
132
+ wp_die(__('You do not have sufficient permissions to access this page.', 'wp-security-audit-log'));
133
+ }
134
+ if (isset($_POST['submit'])) {
135
+ try {
136
+ $this->Save();
137
+ ?><div class="updated">
138
+ <p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p>
139
+ </div><?php
140
+ } catch (Exception $ex) {
141
+ ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
142
+ }
143
+ }
144
+ ?>
145
+ <h2 id="wsal-tabs" class="nav-tab-wrapper">
146
+ <a href="#tab-general" class="nav-tab">General</a>
147
+ <a href="#tab-exclude" class="nav-tab">Exclude Objects</a>
148
+ <!--<a href="#adapter" class="nav-tab">Data Storage Adapter</a>-->
149
+ </h2>
150
+ <script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"/></script>
151
+ <form id="audit-log-settings" method="post">
152
+ <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
153
+ <input type="hidden" id="ajaxurl" value="<?php echo esc_attr(admin_url('admin-ajax.php')); ?>" />
154
+ <?php wp_nonce_field('wsal-settings'); ?>
155
+
156
+ <div id="audit-log-adverts">
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="FromEmail"><?php _e('From Email & Name', 'wp-security-audit-log'); ?></label></th>
210
+ <td>
211
+ <fieldset>
212
+ <label for="FromEmail"><?php _e('Email Address', 'wp-security-audit-log'); ?></label>
213
+ <input type="email" id="FromEmail" name="FromEmail" value="<?php echo esc_attr($this->_plugin->settings->GetFromEmail()); ?>" />
214
+ &nbsp;
215
+ <label for="DisplayName"><?php _e('Display Name', 'wp-security-audit-log'); ?></label>
216
+ <input type="text" id="DisplayName" name="DisplayName" value="<?php echo esc_attr($this->_plugin->settings->GetDisplayName()); ?>" />
217
+ </fieldset>
218
+ <p class="description">
219
+ <?php
220
+ echo sprintf(
221
+ __('These email address and display name will be used as From details in the emails sent by the %s . Please ensure the mail server can relay emails with the domain of the specified email address.', 'wp-security-audit-log'),
222
+ '<a target="_blank" href="https://www.wpsecurityauditlog.com/plugin-extensions/">' . __('(premium add-ons)', 'wp-security-audit-log') . '</a>'
223
+ );
224
+ ?>
225
+ </p>
226
+ </td>
227
+ </tr>
228
+ <tr>
229
+ <th><label for="dwoption_on"><?php _e('Alerts Dashboard Widget', 'wp-security-audit-log'); ?></label></th>
230
+ <td>
231
+ <fieldset>
232
+ <?php $dwe = $this->_plugin->settings->IsWidgetsEnabled(); ?>
233
+ <label for="dwoption_on">
234
+ <input type="radio" name="EnableDashboardWidgets" id="dwoption_on" style="margin-top: 2px;" <?php if($dwe)echo 'checked="checked"'; ?> value="1">
235
+ <span><?php _e('On', 'wp-security-audit-log'); ?></span>
236
+ </label>
237
+ <br/>
238
+ <label for="dwoption_off">
239
+ <input type="radio" name="EnableDashboardWidgets" id="dwoption_off" style="margin-top: 2px;" <?php if(!$dwe)echo 'checked="checked"'; ?> value="0">
240
+ <span><?php _e('Off', 'wp-security-audit-log'); ?></span>
241
+ </label>
242
+ <br/>
243
+ <p class="description"><?php
244
+ echo sprintf(
245
+ __('Display a dashboard widget with the latest %d security alerts.', 'wp-security-audit-log'),
246
+ $this->_plugin->settings->GetDashboardWidgetMaxAlerts()
247
+ );
248
+ ?></p>
249
+ </fieldset>
250
+ </td>
251
+ </tr>
252
+ <tr>
253
+ <th><label for="pioption_on"><?php _e('Reverse Proxy / Firewall Options', 'wp-security-audit-log'); ?></label></th>
254
+ <td>
255
+ <fieldset>
256
+ <label for="EnableProxyIpCapture">
257
+ <input type="checkbox" name="EnableProxyIpCapture" value="1" id="EnableProxyIpCapture"<?php
258
+ if($this->_plugin->settings->IsMainIPFromProxy())echo ' checked="checked"';
259
+ ?>/> <?php _e('WordPress running behind firewall or proxy', 'wp-security-audit-log'); ?><br/>
260
+ <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>
261
+ </label>
262
+ <br/>
263
+ <label for="EnableIpFiltering">
264
+ <input type="checkbox" name="EnableIpFiltering" value="1" id="EnableIpFiltering"<?php
265
+ if($this->_plugin->settings->IsInternalIPsFiltered())echo ' checked="checked"';
266
+ ?>/> <?php _e('Filter Internal IP Addresses', 'wp-security-audit-log'); ?><br/>
267
+ <span class="description"><?php _e('Enable this option to filter internal IP addresses from the proxy headers.', 'wp-security-audit-log'); ?></span>
268
+ </label>
269
+ </fieldset>
270
+ </td>
271
+ </tr>
272
+ <tr>
273
+ <th><label for="ViewerQueryBox"><?php _e('Can View Alerts', 'wp-security-audit-log'); ?></label></th>
274
+ <td>
275
+ <fieldset>
276
+ <input type="text" id="ViewerQueryBox" style="float: left; display: block; width: 250px;">
277
+ <input type="button" id="ViewerQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
278
+ <br style="clear: both;"/>
279
+ <p class="description"><?php
280
+ _e('Users and Roles in this list can view the security alerts', 'wp-security-audit-log');
281
+ ?></p>
282
+ <div id="ViewerList"><?php
283
+ foreach($this->_plugin->settings->GetAllowedPluginViewers() as $item){
284
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
285
+ <input type="hidden" name="Viewers[]" value="<?php echo esc_attr($item); ?>"/>
286
+ <?php echo esc_html($item); ?>
287
+ <a href="javascript:;" title="Remove">&times;</a>
288
+ </span><?php
289
+ }
290
+ ?></div>
291
+ </fieldset>
292
+ </td>
293
+ </tr>
294
+ <tr>
295
+ <th><label for="EditorQueryBox"><?php _e('Can Manage Plugin', 'wp-security-audit-log'); ?></label></th>
296
+ <td>
297
+ <fieldset>
298
+ <input type="text" id="EditorQueryBox" style="float: left; display: block; width: 250px;">
299
+ <input type="button" id="EditorQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
300
+ <br style="clear: both;"/>
301
+ <p class="description"><?php
302
+ _e('Users and Roles in this list can manage the plugin settings', 'wp-security-audit-log');
303
+ ?></p>
304
+ <div id="EditorList"><?php
305
+ foreach($this->_plugin->settings->GetAllowedPluginEditors() as $item){
306
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
307
+ <input type="hidden" name="Editors[]" value="<?php echo esc_attr($item); ?>"/>
308
+ <?php echo esc_html($item); ?>
309
+ <a href="javascript:;" title="Remove">&times;</a>
310
+ </span><?php
311
+ }
312
+ ?></div>
313
+ </fieldset>
314
+ </td>
315
+ </tr>
316
+ <tr>
317
+ <th><label for="RestrictAdmins"><?php _e('Restrict Plugin Access', 'wp-security-audit-log'); ?></label></th>
318
+ <td>
319
+ <fieldset>
320
+ <input type="hidden" id="RestrictAdminsDefaultUser" value="<?php echo esc_attr(wp_get_current_user()->user_login); ?>"/>
321
+ <label for="RestrictAdmins">
322
+ <?php $ira = $this->_plugin->settings->IsRestrictAdmins(); ?>
323
+ <input type="checkbox" name="RestrictAdmins" id="RestrictAdmins"<?php if($ira)echo ' checked="checked"'; ?>/>
324
+ <span class="description">
325
+ <?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'); ?>
326
+ </span>
327
+ </label>
328
+ </fieldset>
329
+ </td>
330
+ </tr>
331
+ <tr>
332
+ <th><label for="aroption_on"><?php _e('Refresh Audit Log Viewer', 'wp-security-audit-log'); ?></label></th>
333
+ <td>
334
+ <fieldset>
335
+ <?php $are = $this->_plugin->settings->IsRefreshAlertsEnabled(); ?>
336
+ <label for="aroption_on">
337
+ <input type="radio" name="EnableAuditViewRefresh" id="aroption_on" style="margin-top: 2px;" <?php if($are)echo 'checked="checked"'; ?> value="1">
338
+ <span><?php _e('Automatic', 'wp-security-audit-log'); ?></span>
339
+ </label>
340
+ <span class="description"> &mdash; <?php _e('Refresh Audit Log Viewer as soon as there are new alerts.', 'wp-security-audit-log'); ?></span>
341
+ <br/>
342
+ <label for="aroption_off">
343
+ <input type="radio" name="EnableAuditViewRefresh" id="aroption_off" style="margin-top: 2px;" <?php if(!$are)echo 'checked="checked"'; ?> value="0">
344
+ <span><?php _e('Manual', 'wp-security-audit-log'); ?></span>
345
+ </label>
346
+ <span class="description"> &mdash; <?php _e('Refresh Audit Log Viewer only when the page is reloaded.', 'wp-security-audit-log'); ?></span>
347
+ <br/>
348
+ </fieldset>
349
+ </td>
350
+ </tr>
351
+ <tr>
352
+ <th><label for="datetime_format_24"><?php _e('Alerts Time Format', 'wp-security-audit-log'); ?></label></th>
353
+ <td>
354
+ <fieldset>
355
+ <?php $datetime = $this->_plugin->settings->GetDatetimeFormat(); ?>
356
+ <label for="datetime_format_24">
357
+ <input type="radio" name="DatetimeFormat" id="datetime_format_24" style="margin-top: 2px;" <?php if($datetime)echo 'checked="checked"'; ?> value="1">
358
+ <span><?php _e('24 hours', 'wp-security-audit-log'); ?></span>
359
+ </label>
360
+ <br/>
361
+ <label for="datetime_format_default">
362
+ <input type="radio" name="DatetimeFormat" id="datetime_format_default" style="margin-top: 2px;" <?php if(!$datetime)echo 'checked="checked"'; ?> value="0">
363
+ <span><?php _e('AM/PM', 'wp-security-audit-log'); ?></span>
364
+ </label>
365
+ <br/>
366
+ </fieldset>
367
+ </td>
368
+ </tr>
369
+ <tr>
370
+ <th><label for="timezone-default"><?php _e('Alerts Timestamp', 'wp-security-audit-log'); ?></label></th>
371
+ <td>
372
+ <fieldset>
373
+ <?php $timezone = $this->_plugin->settings->GetTimezone(); ?>
374
+ <label for="timezone-default">
375
+ <input type="radio" name="Timezone" id="timezone-default" style="margin-top: 2px;" <?php if(!$timezone)echo 'checked="checked"'; ?> value="0">
376
+ <span><?php _e('UTC', 'wp-security-audit-log'); ?></span>
377
+ </label>
378
+ <br/>
379
+ <label for="timezone">
380
+ <input type="radio" name="Timezone" id="timezone" style="margin-top: 2px;" <?php if($timezone)echo 'checked="checked"'; ?> value="1">
381
+ <span><?php _e('WordPress\' timezone', 'wp-security-audit-log'); ?></span>
382
+ </label>
383
+ <br/>
384
+ <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>
385
+ </fieldset>
386
+ </td>
387
+ </tr>
388
+ <tr>
389
+ <th><label for="columns"><?php _e('Audit Log Columns Selection', 'wp-security-audit-log'); ?></label></th>
390
+ <td>
391
+ <fieldset>
392
+ <?php $columns = $this->_plugin->settings->GetColumns(); ?>
393
+ <?php foreach ($columns as $key => $value) { ?>
394
+ <label for="columns">
395
+ <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">
396
+ <span><?php echo ucwords(str_replace("_", " ", $key)); ?></span>
397
+ </label>
398
+ <br/>
399
+ <?php } ?>
400
+ <span class="description"><?php _e('When you disable any of the above such details won’t be shown in the Audit Log
401
+ viewer though the plugin will still record such information in the database.', 'wp-security-audit-log'); ?></span>
402
+ </fieldset>
403
+ </td>
404
+ </tr>
405
+ <tr>
406
+ <th><label><?php _e('Developer Options', 'wp-security-audit-log'); ?></label></th>
407
+ <td>
408
+ <fieldset>
409
+ <?php $any = $this->_plugin->settings->IsAnyDevOptionEnabled(); ?>
410
+ <a href="javascript:;" style="<?php if($any)echo 'display: none;'; ?>"
411
+ onclick="jQuery(this).hide().next().show();">Show Developer Options</a>
412
+ <div style="<?php if(!$any)echo 'display: none;'; ?>">
413
+ <p style="border-left: 3px solid #FFD000; padding: 2px 8px; margin-left: 6px; margin-bottom: 16px;"><?php
414
+ _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');
415
+ ?></p><?php
416
+ foreach (array(
417
+ WSAL_Settings::OPT_DEV_DATA_INSPECTOR => array(
418
+ __('Data Inspector', 'wp-security-audit-log'),
419
+ __('View data logged for each triggered alert.', 'wp-security-audit-log')
420
+ ),
421
+ WSAL_Settings::OPT_DEV_PHP_ERRORS => array(
422
+ __('PHP Errors', 'wp-security-audit-log'),
423
+ __('Enables sensor for alerts generated from PHP.', 'wp-security-audit-log')
424
+ ),
425
+ WSAL_Settings::OPT_DEV_REQUEST_LOG => array(
426
+ __('Request Log', 'wp-security-audit-log'),
427
+ __('Enables logging request to file.', 'wp-security-audit-log')
428
+ ),
429
+ WSAL_Settings::OPT_DEV_BACKTRACE_LOG => array(
430
+ __('Backtrace', 'wp-security-audit-log'),
431
+ __('Log full backtrace for PHP-generated alerts.', 'wp-security-audit-log')
432
+ ),
433
+ ) as $opt => $info) {
434
+ ?><label for="devoption_<?php echo $opt; ?>">
435
+ <input type="checkbox" name="DevOptions[]" id="devoption_<?php echo $opt; ?>" <?php
436
+ if($this->_plugin->settings->IsDevOptionEnabled($opt))echo 'checked="checked"'; ?> value="<?php echo $opt; ?>">
437
+ <span><?php echo $info[0]; ?></span>
438
+ <?php if (isset($info[1]) && $info[1]) { ?>
439
+ <span class="description"> &mdash; <?php echo $info[1]; ?></span>
440
+ <?php }
441
+ ?></label><br/><?php
442
+ }
443
+ ?></div>
444
+ </fieldset>
445
+ </td>
446
+ </tr>
447
+
448
+ <tr>
449
+ <th><label for="Incognito"><?php _e('Hide Plugin in Plugins Page', 'wp-security-audit-log'); ?></label></th>
450
+ <td>
451
+ <fieldset>
452
+ <label for="Incognito">
453
+ <input type="checkbox" name="Incognito" value="1" id="Incognito"<?php
454
+ if ($this->_plugin->settings->IsIncognito()) echo ' checked="checked"';
455
+ ?>/> <?php _e('Hide', 'wp-security-audit-log'); ?>
456
+ </label>
457
+ <br/>
458
+ <span class="description">
459
+ <?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'); ?>
460
+ </span>
461
+ </fieldset>
462
+ </td>
463
+ </tr>
464
+ <tr>
465
+ <th><label for="DeleteData"><?php _e('Disable Alerts for WordPress Background Activity', 'wp-security-audit-log'); ?></label></th>
466
+ <td>
467
+ <fieldset>
468
+ <label for="WPBackend">
469
+ <input type="checkbox" name="WPBackend" value="1" id="WPBackend" <?php
470
+ if ($this->_plugin->settings->IsWPBackend()) echo ' checked="checked"';
471
+ ?>/> <?php _e('Hide activity', 'wp-security-audit-log'); ?>
472
+ </label>
473
+ <br/>
474
+ <span class="description">
475
+ <?php _e('For example do not raise an alert when WordPress deletes the auto drafts.', 'wp-security-audit-log'); ?>
476
+ </span>
477
+ </fieldset>
478
+ </td>
479
+ </tr>
480
+ <tr>
481
+ <th><label for="DeleteData"><?php _e('Remove Data on Uninstall', 'wp-security-audit-log'); ?></label></th>
482
+ <td>
483
+ <fieldset>
484
+ <label for="DeleteData">
485
+ <input type="checkbox" name="DeleteData" value="1" id="DeleteData" onclick="return delete_confirm(this);"<?php
486
+ if ($this->_plugin->settings->IsDeleteData()) echo ' checked="checked"';
487
+ ?>/> <span class="description">Check this box if you would like remove all data when the plugin is deleted.</span>
488
+ </label>
489
+ </fieldset>
490
+ </td>
491
+ </tr>
492
+ </tbody>
493
+ </table>
494
+ <!-- End general Tab-->
495
+ <table class="form-table wsal-tab widefat" id="tab-exclude">
496
+ <tbody>
497
+ <tr>
498
+ <th><h2>Users &amp; Roles</h2></th>
499
+ </tr>
500
+ <tr>
501
+ <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>
502
+ </tr>
503
+ <tr>
504
+ <th><label for="ExUserQueryBox"><?php _e('Excluded Users', 'wp-security-audit-log'); ?></label></th>
505
+ <td>
506
+ <fieldset>
507
+ <input type="text" id="ExUserQueryBox" style="float: left; display: block; width: 250px;">
508
+ <input type="button" id="ExUserQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
509
+ <br style="clear: both;"/>
510
+ <div id="ExUserList"><?php
511
+ foreach($this->_plugin->settings->GetExcludedMonitoringUsers() as $item){
512
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
513
+ <input type="hidden" name="ExUsers[]" value="<?php echo esc_attr($item); ?>"/>
514
+ <?php echo esc_html($item); ?>
515
+ <a href="javascript:;" title="Remove">&times;</a>
516
+ </span><?php
517
+ }
518
+ ?></div>
519
+ </fieldset>
520
+ </td>
521
+ </tr>
522
+ <tr>
523
+ <th><label for="ExRoleQueryBox"><?php _e('Excluded Roles', 'wp-security-audit-log'); ?></label></th>
524
+ <td>
525
+ <fieldset>
526
+ <input type="text" id="ExRoleQueryBox" style="float: left; display: block; width: 250px;">
527
+ <input type="button" id="ExRoleQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
528
+ <br style="clear: both;"/>
529
+ <div id="ExRoleList"><?php
530
+ foreach($this->_plugin->settings->GetExcludedMonitoringRoles() as $item){
531
+ ?><span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
532
+ <input type="hidden" name="ExRoles[]" value="<?php echo esc_attr($item); ?>"/>
533
+ <?php echo esc_html($item); ?>
534
+ <a href="javascript:;" title="Remove">&times;</a>
535
+ </span><?php
536
+ }
537
+ ?></div>
538
+ </fieldset>
539
+ </td>
540
+ </tr>
541
+ <tr>
542
+ <th><h2>Custom Fields</h2></th>
543
+ </tr>
544
+ <tr>
545
+ <td colspan="2">All 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.<br>
546
+ You can use the * wildcard to exclude more than one Custom Field. For example to exclude all the Custom Fields that start with wp123 specify wp123*.</td>
547
+ </tr>
548
+ <tr>
549
+ <th><label for="CustomQueryBox"><?php _e('Excluded Custom Fields', 'wp-security-audit-log'); ?></label></th>
550
+ <td>
551
+ <fieldset>
552
+ <input type="text" id="CustomQueryBox" style="float: left; display: block; width: 250px;">
553
+ <input type="button" id="CustomQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
554
+ <br style="clear: both;"/>
555
+ <div id="CustomList">
556
+ <?php foreach ($this->_plugin->settings->GetExcludedMonitoringCustom() as $item) { ?>
557
+ <span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
558
+ <input type="hidden" name="Customs[]" value="<?php echo esc_attr($item); ?>"/>
559
+ <?php echo esc_html($item); ?>
560
+ <a href="javascript:;" title="Remove">&times;</a>
561
+ </span>
562
+ <?php } ?>
563
+ </div>
564
+ </fieldset>
565
+ </td>
566
+ </tr>
567
+ <tr>
568
+ <th><h2>IP Addresses</h2></th>
569
+ </tr>
570
+ <tr>
571
+ <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>
572
+ </tr>
573
+ <tr>
574
+ <th><label for="IpAddrQueryBox"><?php _e('Excluded IP Addresses', 'wp-security-audit-log'); ?></label></th>
575
+ <td>
576
+ <fieldset>
577
+ <input type="text" id="IpAddrQueryBox" style="float: left; display: block; width: 250px;">
578
+ <input type="button" id="IpAddrQueryAdd" style="float: left; display: block;" class="button-primary" value="Add">
579
+ <br style="clear: both;"/>
580
+ <div id="IpAddrList">
581
+ <?php foreach ($this->_plugin->settings->GetExcludedMonitoringIP() as $item) { ?>
582
+ <span class="sectoken-<?php echo $this->GetTokenType($item); ?>">
583
+ <input type="hidden" name="IpAddrs[]" value="<?php echo esc_attr($item); ?>"/>
584
+ <?php echo esc_html($item); ?>
585
+ <a href="javascript:;" title="Remove">&times;</a>
586
+ </span>
587
+ <?php } ?>
588
+ </div>
589
+ </fieldset>
590
+ </td>
591
+ </tr>
592
+ </tbody>
593
+ </table>
594
+ </div>
595
+ <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes"></p>
596
+ </form>
597
+ <script type="text/javascript">
598
+ <!--
599
+ function delete_confirm(elementRef)
600
+ {
601
+ if ( elementRef.checked )
602
+ {
603
+ if ( window.confirm('Do you want remove all data when the plugin is deleted?') == false )
604
+ elementRef.checked = false;
605
+ }
606
+ }
607
+ // -->
608
+ </script><?php
609
+ }
610
+
611
+ public function Header()
612
+ {
613
+ wp_enqueue_style(
614
+ 'settings',
615
+ $this->_plugin->GetBaseUrl() . '/css/settings.css',
616
+ array(),
617
+ filemtime($this->_plugin->GetBaseDir() . '/css/settings.css')
618
+ );
619
+ ?><style type="text/css">
620
+ .wsal-tab {
621
+ display: none;
622
+ }
623
+ .wsal-tab tr.alert-incomplete td {
624
+ color: #9BE;
625
+ }
626
+ .wsal-tab tr.alert-unavailable td {
627
+ color: #CCC;
628
+ }
629
+ </style><?php
630
+ }
631
+
632
+ public function Footer()
633
+ {
634
+ wp_enqueue_script(
635
+ 'settings',
636
+ $this->_plugin->GetBaseUrl() . '/js/settings.js',
637
+ array(),
638
+ filemtime($this->_plugin->GetBaseDir() . '/js/settings.js')
639
+ );
640
+ ?><script type="text/javascript">
641
+ jQuery(document).ready(function(){
642
+ // tab handling code
643
+ jQuery('#wsal-tabs>a').click(function(){
644
+ jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
645
+ jQuery('table.wsal-tab').hide();
646
+ jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
647
+ });
648
+ // show relevant tab
649
+ var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
650
+ if (hashlink.length) {
651
+ hashlink.click();
652
+ } else {
653
+ jQuery('#wsal-tabs>a:first').click();
654
+ }
655
+
656
+ jQuery(".sel-columns").change(function(){
657
+ var notChecked = 1;
658
+ jQuery(".sel-columns").each(function(){
659
+ if(this.checked) notChecked = 0;
660
+ })
661
+ if(notChecked == 1){
662
+ alert("You have to select at least one column!");
663
+ }
664
+ });
665
+ });
666
+ </script><?php
667
+ }
668
+
669
+ public function AjaxGetAllUsers()
670
+ {
671
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
672
+ die('Access Denied.');
673
+ }
674
+ $users = array();
675
+ foreach (get_users() as $user) {
676
+ if (strpos($user->user_login, $_GET['term']) !== false) {
677
+ array_push($users, $user->user_login);
678
+ }
679
+ }
680
+ echo json_encode($users);
681
+ exit;
682
+ }
683
+
684
+ public function AjaxGetAllRoles()
685
+ {
686
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
687
+ die('Access Denied.');
688
+ }
689
+ $roles = array();
690
+ foreach (get_editable_roles() as $role_name => $role_info) {
691
+ if (strpos($role_name, $_GET['term']) !== false) {
692
+ array_push($roles, $role_name);
693
+ }
694
+ }
695
+ echo json_encode($roles);
696
+ exit;
697
+ }
698
+ }
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,184 @@
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
+ }
181
+ .wsal-premium {
182
+ text-decoration: none;
183
+ float: right;
184
+ }
css/extensions.css ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .extension {
2
+ position:relative;
3
+ float:left;
4
+ box-sizing:border-box;
5
+ width:300px;
6
+ height:250px;
7
+ margin:10px 20px 10px 0;
8
+ border:1px solid #ccc
9
+ }
10
+ .extension p {
11
+ margin:0;padding:10px
12
+ }
13
+ .extension h3 {
14
+ box-sizing:border-box;
15
+ height:110px;
16
+ margin:0;
17
+ padding:20px 10px 0 120px;
18
+ border-bottom:1px solid #ccc;
19
+ background:10px 10px/90px 90px no-repeat #fff
20
+ }
21
+ .extension a {
22
+ text-decoration:none
23
+ }
24
+ .extension a.button-primary {
25
+ position: absolute;
26
+ bottom: 20px;
27
+ }
28
+ .all h3 {
29
+ background-image:url(../img/all.jpg)
30
+ }
31
+ .user-managment h3 {
32
+ background-image:url(../img/monitoring.jpg)
33
+ }
34
+ .email-notifications h3 {
35
+ background-image:url(../img/envelope.jpg);
36
+ }
37
+ .reports h3 {
38
+ background-image:url(../img/file.jpg);
39
+ }
40
+ .search-ext h3 {
41
+ background-image:url(../img/search.jpg);
42
+ }
43
+ .external-db h3 {
44
+ background-image:url(../img/database.jpg);
45
+ }
46
+ .wrap-advertising-page {
47
+ margin-top: 15px;
48
+ padding-top: 9px;
49
+ border-top: 1px solid #ccc;
50
+ }
51
+ .wrap-advertising-page-single {
52
+ margin-top: 15px;
53
+ padding: 20px;
54
+ background-color: #fff;
55
+ border: 1px solid #ccc;
56
+ }
57
+ .wrap-advertising-page-single .icon {
58
+ float:left;
59
+ width: 110px;
60
+ height: 110px;
61
+ margin: 0;
62
+ background: 0px 10px/90px 90px no-repeat #fff
63
+ }
64
+ .clear {
65
+ clear: both;
66
+ }
67
+ .button-blue {
68
+ color: #fff;
69
+ text-decoration: none;
70
+ display: inline-block;
71
+ font-size: 13px;
72
+ line-height: 26px;
73
+ height: 28px;
74
+ margin: 0;
75
+ padding: 0 10px 1px;
76
+ cursor: pointer;
77
+ border-width: 1px;
78
+ border-style: solid;
79
+ -webkit-appearance: none;
80
+ -webkit-border-radius: 3px;
81
+ border-radius: 3px;
82
+ white-space: nowrap;
83
+ -webkit-box-sizing: border-box;
84
+ -moz-box-sizing: border-box;
85
+ box-sizing: border-box;
86
+ background-color: #0026ff;
87
+ }
88
+ .text-red {
89
+ color: red;
90
+ }
91
+ .button-blue:hover,
92
+ .button-blue:focus {
93
+ color: #fff;
94
+ }
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
@@ -36,198 +36,218 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal)
36
  // create list of default alerts
37
  $wsal->alerts->RegisterGroup(array(
38
  __('Other User Activity', 'wp-security-audit-log') => array(
39
- array(1000, E_NOTICE, __('User logs in', 'wp-security-audit-log'), __('Successfully logged in', 'wp-security-audit-log')),
40
- array(1001, E_NOTICE, __('User logs out', 'wp-security-audit-log'), __('Successfully logged out', 'wp-security-audit-log')),
41
- array(1002, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected', 'wp-security-audit-log')),
42
  array(1003, E_WARNING, __('Login failed / non existing user', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected using non existing user.', 'wp-security-audit-log')),
43
- array(1004, E_WARNING, __('Login blocked', 'wp-security-audit-log'), __('Blocked from logging in because another user is logged in from %ClientIP%', 'wp-security-audit-log')),
44
- array(1005, E_WARNING, __('User logs in with existing session(s)', 'wp-security-audit-log'), __('Successfully logged in. Other session(s) from %IPAddress% for this username already exists', 'wp-security-audit-log')),
45
- array(2010, E_NOTICE, __('User uploaded file from Uploads directory', 'wp-security-audit-log'), __('Uploaded the file %FileName% in %FilePath%', 'wp-security-audit-log')),
46
- array(2011, E_WARNING, __('User deleted file from Uploads directory', 'wp-security-audit-log'), __('Deleted the file %FileName% from %FilePath%', 'wp-security-audit-log')),
47
- array(2046, E_CRITICAL, __('User changed a file using the theme editor', 'wp-security-audit-log'), __('Modified %File% with the Theme Editor', 'wp-security-audit-log')),
48
- array(2051, E_CRITICAL, __('User changed a file using the plugin editor', 'wp-security-audit-log'), __('Modified %File% with the Plugin Editor', 'wp-security-audit-log')),
49
- array(2052, E_CRITICAL, __('User changed generic tables', 'wp-security-audit-log'), __('Changed the parent of %CategoryName% category from %OldParent% to %NewParent%', 'wp-security-audit-log')),
50
  ),
51
  __('Blog Posts', 'wp-security-audit-log') => array(
52
- array(2000, E_NOTICE, __('User created a new blog post and saved it as draft', 'wp-security-audit-log'), __('Created a new blog post called %PostTitle%. Blog post ID is %PostID%', 'wp-security-audit-log')),
53
- array(2001, E_NOTICE, __('User published a blog post', 'wp-security-audit-log'), __('Published a blog post called %PostTitle%. Blog post URL is %PostUrl%', 'wp-security-audit-log')),
54
- array(2002, E_NOTICE, __('User modified a published blog post', 'wp-security-audit-log'), __('Modified the published blog post %PostTitle%. Blog post URL is %PostUrl%', 'wp-security-audit-log')),
55
- array(2003, E_NOTICE, __('User modified a draft blog post', 'wp-security-audit-log'), __('Modified the draft blog post %PostTitle%. Blog post ID is %PostID%', 'wp-security-audit-log')),
56
- array(2008, E_NOTICE, __('User permanently deleted a blog post from the trash', 'wp-security-audit-log'), __('Permanently deleted the post %PostTitle%. Blog post ID is %PostID%', 'wp-security-audit-log')),
57
- array(2012, E_WARNING, __('User moved a blog post to the trash', 'wp-security-audit-log'), __('Moved the blog post %PostTitle% to trash', 'wp-security-audit-log')),
58
- array(2014, E_CRITICAL, __('User restored a blog post from trash', 'wp-security-audit-log'), __('Restored post %PostTitle% from trash', 'wp-security-audit-log')),
59
- array(2016, E_NOTICE, __('User changed blog post category', 'wp-security-audit-log'), __('Changed the category of the post %PostTitle% from %OldCategories% to %NewCategories%', 'wp-security-audit-log')),
60
- array(2017, E_NOTICE, __('User changed blog post URL', 'wp-security-audit-log'), __('Changed the URL of the post %PostTitle% from %OldUrl% to %NewUrl%', 'wp-security-audit-log')),
61
- array(2019, E_NOTICE, __('User changed blog post author', 'wp-security-audit-log'), __('Changed the author of %PostTitle% post from %OldAuthor% to %NewAuthor%', 'wp-security-audit-log')),
62
- array(2021, E_NOTICE, __('User changed blog post status', 'wp-security-audit-log'), __('Changed the status of %PostTitle% post from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
63
- array(2023, E_NOTICE, __('User created new category', 'wp-security-audit-log'), __('Created a new category called %CategoryName%', 'wp-security-audit-log')),
64
- array(2024, E_WARNING, __('User deleted category', 'wp-security-audit-log'), __('Deleted the %CategoryName% category', 'wp-security-audit-log')),
65
- array(2025, E_WARNING, __('User changed the visibility of a blog post', 'wp-security-audit-log'), __('Changed the visibility of %PostTitle% blog post from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
66
- array(2027, E_NOTICE, __('User changed the date of a blog post', 'wp-security-audit-log'), __('Changed the date of %PostTitle% blog post from %OldDate% to %NewDate%', 'wp-security-audit-log')),
67
- array(2049, E_NOTICE, __('User sets a post as sticky', 'wp-security-audit-log'), __('Set the post %PostTitle% as Sticky', 'wp-security-audit-log')),
68
- array(2050, E_NOTICE, __('User removes post from sticky', 'wp-security-audit-log'), __('Removed the post %PostTitle% from Sticky', 'wp-security-audit-log')),
69
- array(2053, E_NOTICE, __('User creates a custom field for a post', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
70
- array(2054, E_NOTICE, __('User updates a custom field value for a post', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
71
- array(2055, E_NOTICE, __('User deletes a custom field from a post', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with id %MetaID% from post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
72
- array(2062, E_NOTICE, __('User updates a custom field name for a post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in post %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
73
- array(2065, E_WARNING, __('User modifies content for a published post', 'wp-security-audit-log'), __('Modified the content of published post %PostTitle%.'.'%RevisionLink%', 'wp-security-audit-log')),
74
- 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')),
75
- 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')),
76
- 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')),
77
- array(2074, E_NOTICE, __('User scheduled a post', 'wp-security-audit-log'), __('Scheduled the post %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log')),
78
- 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'))
 
79
  ),
80
  __('Pages', 'wp-security-audit-log') => array(
81
- 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')),
82
- array(2005, E_NOTICE, __('User published a WorPress page', 'wp-security-audit-log'), __('Published a page called %PostTitle%. Page URL is %PostUrl%', 'wp-security-audit-log')),
83
- array(2006, E_NOTICE, __('User modified a published WordPress page', 'wp-security-audit-log'), __('Modified the published page %PostTitle%. Page URL is %PostUrl%', 'wp-security-audit-log')),
84
- array(2007, E_NOTICE, __('User modified a draft WordPress page', 'wp-security-audit-log'), __('Modified the draft page %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
85
- array(2009, E_NOTICE, __('User permanently deleted a page from the trash', 'wp-security-audit-log'), __('Permanently deleted the page %PostTitle%. Page ID is %PostID%', 'wp-security-audit-log')),
86
- array(2013, E_WARNING, __('User moved WordPress page to the trash', 'wp-security-audit-log'), __('Moved the page %PostTitle% to trash', 'wp-security-audit-log')),
87
- array(2015, E_CRITICAL, __('User restored a WordPress page from trash', 'wp-security-audit-log'), __('Restored page %PostTitle% from trash', 'wp-security-audit-log')),
88
- array(2018, E_NOTICE, __('User changed page URL', 'wp-security-audit-log'), __('Changed the URL of the page %PostTitle% from %OldUrl% to %NewUrl%', 'wp-security-audit-log')),
89
- array(2020, E_NOTICE, __('User changed page author', 'wp-security-audit-log'), __('Changed the author of %PostTitle% page from %OldAuthor% to %NewAuthor%', 'wp-security-audit-log')),
90
- array(2022, E_NOTICE, __('User changed page status', 'wp-security-audit-log'), __('Changed the status of %PostTitle% page from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
91
- array(2026, E_WARNING, __('User changed the visibility of a page post', 'wp-security-audit-log'), __('Changed the visibility of %PostTitle% page from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
92
- array(2028, E_NOTICE, __('User changed the date of a page post', 'wp-security-audit-log'), __('Changed the date of %PostTitle% page from %OldDate% to %NewDate%', 'wp-security-audit-log')),
93
- array(2047, E_NOTICE, __('User changed the parent of a page', 'wp-security-audit-log'), __('Changed the parent of %PostTitle% page from %OldParentName% to %NewParentName%', 'wp-security-audit-log')),
94
- array(2048, E_CRITICAL, __('User changes the template of a page', 'wp-security-audit-log'), __('Changed the template of %PostTitle% page from %OldTemplate% to %NewTemplate%', 'wp-security-audit-log')),
95
- array(2059, E_NOTICE, __('User creates a custom field for a page', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
96
- array(2060, E_NOTICE, __('User updates a custom field value for a page', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
97
- array(2061, E_NOTICE, __('User deletes a custom field from a page', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with id %MetaID% from page %PostTitle%'.'%MetaLink%', 'wp-security-audit-log')),
98
- 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')),
99
- 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')),
100
- 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')),
101
- array(2075, E_NOTICE, __('User scheduled a page', 'wp-security-audit-log'), __('Scheduled the page %PostTitle% to be published %PublishingDate%', 'wp-security-audit-log')),
102
- 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'))
103
  ),
104
  __('Custom Posts', 'wp-security-audit-log') => array(
105
- 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')),
106
- array(2030, E_NOTICE, __('User published a post with custom post type', 'wp-security-audit-log'), __('Published a custom post %PostTitle% of type %PostType%. Post URL is %PostUrl%', 'wp-security-audit-log')),
107
- array(2031, E_NOTICE, __('User modified a post with custom post type', 'wp-security-audit-log'), __('Modified custom post %PostTitle% of type %PostType%. Post URL is %PostUrl%', 'wp-security-audit-log')),
108
- array(2032, E_NOTICE, __('User modified a draft post with custom post type', 'wp-security-audit-log'), __('Modified draft custom post %PostTitle% of type is %PostType%. Post URL is %PostUrl%', 'wp-security-audit-log')),
109
- array(2033, E_WARNING, __('User permanently deleted post with custom post type', 'wp-security-audit-log'), __('Permanently Deleted custom post %PostTitle% of type %PostType%', 'wp-security-audit-log')),
110
- array(2034, E_WARNING, __('User moved post with custom post type to trash', 'wp-security-audit-log'), __('Moved custom post %PostTitle% to trash. Post type is %PostType%', 'wp-security-audit-log')),
111
- array(2035, E_CRITICAL, __('User restored post with custom post type from trash', 'wp-security-audit-log'), __('Restored custom post %PostTitle% of type %PostType% from trash', 'wp-security-audit-log')),
112
- array(2036, E_NOTICE, __('User changed the category of a post with custom post type', 'wp-security-audit-log'), __('Changed the category(ies) of custom post %PostTitle% of type %PostType% from %OldCategories% to %NewCategories%', 'wp-security-audit-log')),
113
- array(2037, E_NOTICE, __('User changed the URL of a post with custom post type', 'wp-security-audit-log'), __('Changed the URL of custom post %PostTitle% of type %PostType% from %OldUrl% to %NewUrl%', 'wp-security-audit-log')),
114
- array(2038, E_NOTICE, __('User changed the author or post with custom post type', 'wp-security-audit-log'), __('Changed the author of custom post %PostTitle% of type %PostType% from %OldAuthor% to %NewAuthor%', 'wp-security-audit-log')),
115
- array(2039, E_NOTICE, __('User changed the status of post with custom post type', 'wp-security-audit-log'), __('Changed the status of custom post %PostTitle% of type %PostType% from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
116
- array(2040, E_WARNING, __('User changed the visibility of a post with custom post type', 'wp-security-audit-log'), __('Changed the visibility of custom post %PostTitle% of type %PostType% from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
117
- array(2041, E_NOTICE, __('User changed the date of post with custom post type', 'wp-security-audit-log'), __('Changed the date of custom post %PostTitle% of type %PostType% from %OldDate% to %NewDate%', 'wp-security-audit-log')),
118
- array(2056, E_NOTICE, __('User creates a custom field for a custom post', 'wp-security-audit-log'), __('Created custom field %MetaKey% with value %MetaValue% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
119
- array(2057, E_NOTICE, __('User updates a custom field for a custom post', 'wp-security-audit-log'), __('Modified the value of custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
120
- array(2058, E_NOTICE, __('User deletes a custom field from a custom post', 'wp-security-audit-log'), __('Deleted custom field %MetaKey% with id %MetaID% from custom post %PostTitle% of type %PostType%'.'%MetaLink%', 'wp-security-audit-log')),
121
- 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')),
122
- 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')),
123
- 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')),
124
- 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')),
125
- 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'))
126
  ),
127
  __('Widgets', 'wp-security-audit-log') => array(
128
- array(2042, E_CRITICAL, __('User added a new widget', 'wp-security-audit-log'), __('Added a new %WidgetName% widget in %Sidebar%', 'wp-security-audit-log')),
129
- array(2043, E_WARNING, __('User modified a widget', 'wp-security-audit-log'), __('Modified the %WidgetName% widget in %Sidebar%', 'wp-security-audit-log')),
130
- array(2044, E_CRITICAL, __('User deleted widget', 'wp-security-audit-log'), __('Deleted the %WidgetName% widget from %Sidebar%', 'wp-security-audit-log')),
131
- array(2045, E_NOTICE, __('User moved widget', 'wp-security-audit-log'), __('Moved the %WidgetName% widget from %OldSidebar% to %NewSidebar%', 'wp-security-audit-log')),
132
- array(2071, E_NOTICE, __('User changed widget position', 'wp-security-audit-log'), __('Moved the %WidgetName% widget from position %OldPosition% to position %NewPosition% in sidebar %Sidebar%', 'wp-security-audit-log')),
133
  ),
134
  __('User Profiles', 'wp-security-audit-log') => array(
135
- array(4000, E_CRITICAL, __('A new user was created on WordPress', 'wp-security-audit-log'), __('User %NewUserData->Username% subscribed with a role of %NewUserData->Roles%', 'wp-security-audit-log')),
136
- array(4001, E_CRITICAL, __('A user created another WordPress user', 'wp-security-audit-log'), __('Created a new user %NewUserData->Username% with the role of %NewUserData->Roles%', 'wp-security-audit-log')),
137
- array(4002, E_CRITICAL, __('The role of a user was changed by another WordPress user', 'wp-security-audit-log'), __('Changed the role of user %TargetUsername% from %OldRole% to %NewRole%', 'wp-security-audit-log')),
138
- array(4003, E_CRITICAL, __('User has changed his or her password', 'wp-security-audit-log'), __('Changed the password', 'wp-security-audit-log')),
139
- array(4004, E_CRITICAL, __('A user changed another user\'s password', 'wp-security-audit-log'), __('Changed the password for user %TargetUserData->Username% with the role of %TargetUserData->Roles%', 'wp-security-audit-log')),
140
- array(4005, E_NOTICE, __('User changed his or her email address', 'wp-security-audit-log'), __('Changed the email address from %OldEmail% to %NewEmail%', 'wp-security-audit-log')),
141
- array(4006, E_NOTICE, __('A user changed another user\'s email address', 'wp-security-audit-log'), __('Changed the email address of user account %TargetUsername% from %OldEmail% to %NewEmail%', 'wp-security-audit-log')),
142
- array(4007, E_CRITICAL, __('A user was deleted by another user', 'wp-security-audit-log'), __('Deleted User %TargetUserData->Username% with the role of %TargetUserData->Roles%', 'wp-security-audit-log')),
143
- array(4013, E_CRITICAL, __('The forum role of a user was changed by another WordPress user', 'wp-security-audit-log'), __('The forum role of user %TargetUsername% was changed from %OldRole% to %NewRole% by %UserChanger%', 'wp-security-audit-log')),
144
  ),
145
  __('Plugins & Themes', 'wp-security-audit-log') => array(
146
- array(5000, E_CRITICAL, __('User installed a plugin', 'wp-security-audit-log'), __('Installed the plugin %Plugin->Name% in %Plugin->plugin_dir_path%', 'wp-security-audit-log')),
147
- array(5001, E_CRITICAL, __('User activated a WordPress plugin', 'wp-security-audit-log'), __('Activated the plugin %PluginData->Name% installed in %PluginFile%', 'wp-security-audit-log')),
148
- array(5002, E_CRITICAL, __('User deactivated a WordPress plugin', 'wp-security-audit-log'), __('Deactivated the plugin %PluginData->Name% installed in %PluginFile%', 'wp-security-audit-log')),
149
- array(5003, E_CRITICAL, __('User uninstalled a plugin', 'wp-security-audit-log'), __('Uninstalled the plugin %PluginData->Name% which was installed in %PluginFile%', 'wp-security-audit-log')),
150
- array(5004, E_WARNING, __('User upgraded a plugin', 'wp-security-audit-log'), __('Upgraded the plugin %PluginData->Name% installed in %PluginFile%', 'wp-security-audit-log')),
151
- array(5005, E_CRITICAL, __('User installed a theme', 'wp-security-audit-log'), __('Installed theme "%Theme->Name%" in %Theme->get_template_directory%', 'wp-security-audit-log')),
152
- array(5006, E_CRITICAL, __('User activated a theme', 'wp-security-audit-log'), __('Activated theme "%Theme->Name%", installed in %Theme->get_template_directory%', 'wp-security-audit-log')),
153
- array(5007, E_CRITICAL, __('User uninstalled a theme', 'wp-security-audit-log'), __('Deleted theme "%Theme->Name%" installed in %Theme->get_template_directory%', 'wp-security-audit-log')),
 
 
 
 
 
 
 
 
 
154
  ),
155
  __('System Activity', 'wp-security-audit-log') => array(
156
- array(0000, E_CRITICAL, __('Unknown Error', 'wp-security-audit-log'), __('An unexpected error has occurred', 'wp-security-audit-log')),
157
- array(0001, E_CRITICAL, __('PHP error', 'wp-security-audit-log'), __('%Message%', 'wp-security-audit-log')),
158
- array(0002, E_WARNING, __('PHP warning', 'wp-security-audit-log'), __('%Message%', 'wp-security-audit-log')),
159
- array(0003, E_NOTICE, __('PHP notice', 'wp-security-audit-log'), __('%Message%', 'wp-security-audit-log')),
160
- array(0004, E_CRITICAL, __('PHP exception', 'wp-security-audit-log'), __('%Message%', 'wp-security-audit-log')),
161
- array(0005, E_CRITICAL, __('PHP shutdown error', 'wp-security-audit-log'), __('%Message%', 'wp-security-audit-log')),
162
- array(6000, E_NOTICE, __('Events automatically pruned by system', 'wp-security-audit-log'), __('%EventCount% event(s) automatically deleted by system', 'wp-security-audit-log')),
163
- array(6001, E_CRITICAL, __('Option Anyone Can Register in WordPress settings changed', 'wp-security-audit-log'), __('%NewValue% the option "Anyone can register"', 'wp-security-audit-log')),
164
- array(6002, E_CRITICAL, __('New User Default Role changed', 'wp-security-audit-log'), __('Changed the New User Default Role from %OldRole% to %NewRole%', 'wp-security-audit-log')),
165
- array(6003, E_CRITICAL, __('WordPress Administrator Notification email changed', 'wp-security-audit-log'), __('Changed the WordPress administrator notifications email address from %OldEmail% to %NewEmail%', 'wp-security-audit-log')),
166
- array(6004, E_CRITICAL, __('WordPress was updated', 'wp-security-audit-log'), __('Updated WordPress from version %OldVersion% to %NewVersion%', 'wp-security-audit-log')),
167
- array(6005, E_CRITICAL, __('User changes the WordPress Permalinks', 'wp-security-audit-log'), __('Changed the WordPress permalinks from %OldPattern% to %NewPattern%', 'wp-security-audit-log')),
168
- array(6007, E_CRITICAL, __('User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log'), __(' Is requesting non-existing pages (404 Error Pages)', 'wp-security-audit-log')),
169
- array(9999, E_CRITICAL, __('Advertising Add-ons.', 'wp-security-audit-log'), __('%PromoMessage%', 'wp-security-audit-log')),
170
  ),
171
  __('MultiSite', 'wp-security-audit-log') => array(
172
- array(4008, E_CRITICAL, __('User granted Super Admin privileges', 'wp-security-audit-log'), __('Granted Super Admin privileges to %TargetUsername%', 'wp-security-audit-log')),
173
- array(4009, E_CRITICAL, __('User revoked from Super Admin privileges', 'wp-security-audit-log'), __('Revoked Super Admin privileges from %TargetUsername%', 'wp-security-audit-log')),
174
- array(4010, E_CRITICAL, __('Existing user added to a site', 'wp-security-audit-log'), __('Added existing user %TargetUsername% with %TargetUserRole% role to site %SiteName%', 'wp-security-audit-log')),
175
- array(4011, E_CRITICAL, __('User removed from site', 'wp-security-audit-log'), __('Removed user %TargetUsername% with role %TargetUserRole% from %SiteName% site', 'wp-security-audit-log')),
176
- array(4012, E_CRITICAL, __('New network user created', 'wp-security-audit-log'), __('Created a new network user %NewUserData->Username%', 'wp-security-audit-log')),
177
- array(7000, E_CRITICAL, __('New site added on network', 'wp-security-audit-log'), __('Added site %SiteName% to the network', 'wp-security-audit-log')),
178
- array(7001, E_CRITICAL, __('Existing site archived', 'wp-security-audit-log'), __('Archived site %SiteName%', 'wp-security-audit-log')),
179
- array(7002, E_CRITICAL, __('Archived site has been unarchived', 'wp-security-audit-log'), __('Unarchived site %SiteName%', 'wp-security-audit-log')),
180
- array(7003, E_CRITICAL, __('Deactivated site has been activated', 'wp-security-audit-log'), __('Activated site %SiteName%', 'wp-security-audit-log')),
181
- array(7004, E_CRITICAL, __('Site has been deactivated', 'wp-security-audit-log'), __('Deactivated site %SiteName%', 'wp-security-audit-log')),
182
- array(7005, E_CRITICAL, __('Existing site deleted from network', 'wp-security-audit-log'), __('Deleted site %SiteName%', 'wp-security-audit-log')),
183
- array(5008, E_CRITICAL, __('Activated theme on network', 'wp-security-audit-log'), __('Network activated %Theme->Name% theme installed in %Theme->get_template_directory%', 'wp-security-audit-log')),
184
- array(5009, E_CRITICAL, __('Deactivated theme from network', 'wp-security-audit-log'), __('Network deactivated %Theme->Name% theme installed in %Theme->get_template_directory%', 'wp-security-audit-log')),
 
185
  ),
186
  __('Database', 'wp-security-audit-log') => array(
187
- array(5010, E_CRITICAL, __('Plugin created tables', 'wp-security-audit-log'), __('Plugin %Plugin->Name% created these tables in the database: %TableNames%', 'wp-security-audit-log')),
188
- array(5011, E_CRITICAL, __('Plugin modified tables structure', 'wp-security-audit-log'), __('Plugin %Plugin->Name% modified the structure of these database tables: %TableNames%', 'wp-security-audit-log')),
189
- array(5012, E_CRITICAL, __('Plugin deleted tables', 'wp-security-audit-log'), __('Plugin %Plugin->Name% deleted the following tables from the database: %TableNames%', 'wp-security-audit-log')),
190
- array(5013, E_CRITICAL, __('Theme created tables', 'wp-security-audit-log'), __('Theme %Theme->Name% created these tables in the database: %TableNames%', 'wp-security-audit-log')),
191
- array(5014, E_CRITICAL, __('Theme modified tables structure', 'wp-security-audit-log'), __('Theme %Theme->Name% modified the structure of these database tables: %TableNames%', 'wp-security-audit-log')),
192
- array(5015, E_CRITICAL, __('Theme deleted tables', 'wp-security-audit-log'), __('Theme %Theme->Name% deleted the following tables from the database: %TableNames%', 'wp-security-audit-log')),
193
- array(5016, E_CRITICAL, __('Unknown component created tables', 'wp-security-audit-log'), __('An unknown component created these tables in the database: %TableNames%', 'wp-security-audit-log')),
194
- array(5017, E_CRITICAL, __('Unknown component modified tables structure', 'wp-security-audit-log'), __('An unknown component modified the structure of these database tables: %TableNames%', 'wp-security-audit-log')),
195
- array(5018, E_CRITICAL, __('Unknown component deleted tables', 'wp-security-audit-log'), __('An unknown component deleted the following tables from the database: %TableNames%', 'wp-security-audit-log')),
196
  ),
197
  __('BBPress Forum', 'wp-security-audit-log') => array(
198
- array(8000, E_CRITICAL, __('User created new forum', 'wp-security-audit-log'), __('Created new forum %ForumName%. Forum URL is %ForumURL%', 'wp-security-audit-log')),
199
- array(8001, E_NOTICE, __('User changed status of a forum', 'wp-security-audit-log'), __('Changed the status of forum %ForumName% from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
200
- array(8002, E_NOTICE, __('User changed visibility of a forum', 'wp-security-audit-log'), __('Changed the visibility of forum %ForumName% from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
201
- array(8003, E_CRITICAL, __('User changed the URL of a forum', 'wp-security-audit-log'), __('Changed the URL of forum %ForumName% from %OldUrl% to %NewUrl%', 'wp-security-audit-log')),
202
- array(8004, E_NOTICE, __('User changed order of a forum', 'wp-security-audit-log'), __('Changed the order of forum %ForumName% from %OldOrder% to %NewOrder%', 'wp-security-audit-log')),
203
- array(8005, E_CRITICAL, __('User moved forum to trash', 'wp-security-audit-log'), __('Moved forum %ForumName% to trash. Forum ID is %ForumID%', 'wp-security-audit-log')),
204
- array(8006, E_WARNING, __('User permanently deleted forum', 'wp-security-audit-log'), __('Permanently deleted forum %ForumName%', 'wp-security-audit-log')),
205
- array(8007, E_WARNING, __('User restored forum from trash', 'wp-security-audit-log'), __('Restored forum %ForumName% from trash', 'wp-security-audit-log')),
206
- array(8008, E_NOTICE, __('User changed the parent of a forum', 'wp-security-audit-log'), __('Changed parent of forum %ForumName% from %OldParent% to %NewParent%', 'wp-security-audit-log')),
207
- array(8009, E_WARNING, __('User changed forum\'s role', 'wp-security-audit-log'), __('Changed the forum\'s auto role from %OldRole% to %NewRole%', 'wp-security-audit-log')),
208
- array(8010, E_WARNING, __('User changed option of a forum', 'wp-security-audit-log'), __('%Status% the option for anonymous posting on forum', 'wp-security-audit-log')),
209
- array(8011, E_NOTICE, __('User changed type of a forum', 'wp-security-audit-log'), __('Changed the type of forum %ForumName% from %OldType% to %NewType%', 'wp-security-audit-log')),
210
- array(8012, E_NOTICE, __('User changed time to disallow post editing', 'wp-security-audit-log'), __('Changed the time to disallow post editing from %OldTime% to %NewTime% minutes', 'wp-security-audit-log')),
211
- array(8013, E_WARNING, __('User changed the forum setting posting throttle time', 'wp-security-audit-log'), __('Changed the forum setting posting throttle time from %OldTime% to %NewTime% seconds', 'wp-security-audit-log')),
212
- array(8014, E_NOTICE, __('User created new topic', 'wp-security-audit-log'), __('Created new topic %TopicName%. Topic URL is %TopicURL%', 'wp-security-audit-log')),
213
- array(8015, E_NOTICE, __('User changed status of a topic', 'wp-security-audit-log'), __('Changed the status of topic %TopicName% from %OldStatus% to %NewStatus%', 'wp-security-audit-log')),
214
- array(8016, E_NOTICE, __('User changed type of a topic', 'wp-security-audit-log'), __('Changed the type of topic %TopicName% from %OldType% to %NewType%', 'wp-security-audit-log')),
215
- array(8017, E_CRITICAL, __('User changed URL of a topic', 'wp-security-audit-log'), __('Changed the URL of topic %TopicName% from %OldUrl% to %NewUrl%', 'wp-security-audit-log')),
216
- array(8018, E_NOTICE, __('User changed the forum of a topic', 'wp-security-audit-log'), __('Changed the forum of topic %TopicName% from %OldForum% to %NewForum%', 'wp-security-audit-log')),
217
- array(8019, E_CRITICAL, __('User moved topic to trash', 'wp-security-audit-log'), __('Moved forum %TopicName% to trash. Topic ID is %TopicID%', 'wp-security-audit-log')),
218
- array(8020, E_WARNING, __('User permanently deleted topic', 'wp-security-audit-log'), __('Permanently deleted topic %TopicName%', 'wp-security-audit-log')),
219
- array(8021, E_WARNING, __('User restored topic from trash', 'wp-security-audit-log'), __('Restored topic %TopicName% from trash', 'wp-security-audit-log')),
220
- array(8022, E_NOTICE, __('User changed visibility of a topic', 'wp-security-audit-log'), __('Changed the visibility of topic %TopicName% from %OldVisibility% to %NewVisibility%', 'wp-security-audit-log')),
221
  ),
222
  __('Menus', 'wp-security-audit-log') => array(
223
- array(2078, E_NOTICE, __('User created new menu', 'wp-security-audit-log'), __('Created a new menu called %MenuName%', 'wp-security-audit-log')),
224
- array(2079, E_WARNING, __('User added content to a menu', 'wp-security-audit-log'), __('Added the %ContentType% called %ContentName% to menu %MenuName%', 'wp-security-audit-log')),
225
- array(2080, E_WARNING, __('User removed content from a menu', 'wp-security-audit-log'), __('Removed the %ContentType% called %ContentName% from the menu %MenuName%', 'wp-security-audit-log')),
226
- array(2081, E_CRITICAL, __('User deleted menu', 'wp-security-audit-log'), __('Deleted the menu %MenuName%', 'wp-security-audit-log')),
227
- array(2082, E_WARNING, __('User changed menu setting', 'wp-security-audit-log'), __('%Status% the menu setting %MenuSetting% in %MenuName%', 'wp-security-audit-log')),
228
- array(2083, E_NOTICE, __('User modified content in a menu', 'wp-security-audit-log'), __('Modified the %ContentType% called %ContentName% in menu %MenuName%', 'wp-security-audit-log')),
229
- array(2084, E_WARNING, __('User changed name of a menu', 'wp-security-audit-log'), __('Changed the name of menu %OldMenuName% to %NewMenuName%', 'wp-security-audit-log')),
230
- array(2085, E_NOTICE, __('User changed order of the objects in a menu', 'wp-security-audit-log'), __('Changed the order of the objects in menu %MenuName%', 'wp-security-audit-log'))
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  ),
232
  __('Custom Alerts', 'wp-security-audit-log') => array(
233
  array(2222, E_CRITICAL, __('Custom critical Alert', 'wp-security-audit-log'), __('%CustomAlertText%', 'wp-security-audit-log')),
36
  // create list of default alerts
37
  $wsal->alerts->RegisterGroup(array(
38
  __('Other User Activity', 'wp-security-audit-log') => array(
39
+ array(1000, E_NOTICE, __('User logged in', 'wp-security-audit-log'), __('Successfully logged in.', 'wp-security-audit-log')),
40
+ array(1001, E_NOTICE, __('User logged out', 'wp-security-audit-log'), __('Successfully logged out.', 'wp-security-audit-log')),
41
+ array(1002, E_WARNING, __('Login failed', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected.', 'wp-security-audit-log')),
42
  array(1003, E_WARNING, __('Login failed / non existing user', 'wp-security-audit-log'), __('%Attempts% failed login(s) detected using non existing user.', 'wp-security-audit-log')),
43
+ array(1004, E_WARNING, __('Login blocked', 'wp-security-audit-log'), __('Blocked from logging in because the same WordPress user is logged in from %ClientIP%.', 'wp-security-audit-log')),
44
+ array(1005, E_WARNING, __('User logged in with existing session(s)', 'wp-security-audit-log'), __('Successfully logged in. Another session from %IPAddress% for this user already exist.', 'wp-security-audit-log')),
45
+ array(2010, E_NOTICE, __('User uploaded file from Uploads directory', 'wp-security-audit-log'), __('Uploaded the file %FileName% in %FilePath%.', 'wp-security-audit-log')),
46
+ array(2011, E_WARNING, __('User deleted file from Uploads directory', 'wp-security-audit-log'), __('Deleted the file %FileName% from %FilePath%.', 'wp-security-audit-log'))
 
 
 
47
  ),
48
  __('Blog Posts', 'wp-security-audit-log') => array(
49
+ array(2000, E_NOTICE, __('User created a new blog post and saved it as draft', 'wp-security-audit-log'), __('Created a new post called %PostTitle% and saved it as draft. %EditorLinkPost%.', 'wp-security-audit-log')),
50
+ array(2001, E_NOTICE, __('User published a blog post', 'wp-security-audit-log'), __('Published a post called %PostTitle%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
51
+ array(2002, E_NOTICE, __('User modified a published blog post', 'wp-security-audit-log'), __('Modified the published post %PostTitle%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
52
+ array(2003, E_NOTICE, __('User modified a draft blog post', 'wp-security-audit-log'), __('Modified the draft post with the %PostTitle%. %EditorLinkPost%.', 'wp-security-audit-log')),
53
+ array(2008, E_WARNING, __('User permanently deleted a blog post from the trash', 'wp-security-audit-log'), __('Permanently deleted the post %PostTitle%. Post URL was %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
54
+ array(2012, E_WARNING, __('User moved a blog post to the trash', 'wp-security-audit-log'), __('Moved the post %PostTitle% to trash. Post URL is %PostUrl%.', 'wp-security-audit-log')),
55
+ array(2014, E_CRITICAL, __('User restored a blog post from trash', 'wp-security-audit-log'), __('Post %PostTitle% has been restored from trash. %EditorLinkPost%.', 'wp-security-audit-log')),
56
+ array(2016, E_NOTICE, __('User changed blog post category', 'wp-security-audit-log'), __('Changed the category of the post %PostTitle% from %OldCategories% to %NewCategories%. %EditorLinkPost%.', 'wp-security-audit-log')),
57
+ array(2017, E_NOTICE, __('User changed blog post URL', 'wp-security-audit-log'), __('Changed the URL of the post %PostTitle% from %OldUrl% to %NewUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
58
+ array(2019, E_NOTICE, __('User changed blog post author', 'wp-security-audit-log'), __('Changed the author of %PostTitle% post from %OldAuthor% to %NewAuthor%. %EditorLinkPost%.', 'wp-security-audit-log')),
59
+ array(2021, E_NOTICE, __('User changed blog post status', 'wp-security-audit-log'), __('Changed the status of %PostTitle% post from %OldStatus% to %NewStatus%. %EditorLinkPost%.', 'wp-security-audit-log')),
60
+ array(2023, E_NOTICE, __('User created new category', 'wp-security-audit-log'), __('Created a new category called %CategoryName% .Category slug is %Slug%. %CategoryLink%.', 'wp-security-audit-log')),
61
+ array(2024, E_WARNING, __('User deleted category', 'wp-security-audit-log'), __('Deleted the category %CategoryName%. Category slug was %Slug%.', 'wp-security-audit-log')),
62
+ array(2025, E_WARNING, __('User changed the visibility of a blog post', 'wp-security-audit-log'), __('Changed the visibility of the post %PostTitle% from %OldVisibility% to %NewVisibility%. %EditorLinkPost%.', 'wp-security-audit-log')),
63
+ array(2027, E_NOTICE, __('User changed the date of a blog post', 'wp-security-audit-log'), __('Changed the date of the post %PostTitle% from %OldDate% to %NewDate%. %EditorLinkPost%.', 'wp-security-audit-log')),
64
+ array(2049, E_NOTICE, __('User set a post as sticky', 'wp-security-audit-log'), __('Set the post %PostTitle% as Sticky. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
65
+ array(2050, E_NOTICE, __('User removed post from sticky', 'wp-security-audit-log'), __('Removed the post %PostTitle% from Sticky. %EditorLinkPost%.', 'wp-security-audit-log')),
66
+ array(2052, E_NOTICE, __('User changed generic tables', 'wp-security-audit-log'), __('Changed the parent of the category %CategoryName% from %OldParent% to %NewParent%. %CategoryLink%.', 'wp-security-audit-log')),
67
+ array(2053, E_CRITICAL, __('User created a custom field for a post', 'wp-security-audit-log'), __('Created a new custom field %MetaKey% with value %MetaValue% in the post %PostTitle%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
68
+ array(2054, E_CRITICAL, __('User updated a custom field value for a post', 'wp-security-audit-log'), __('Modified the value of the custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in the post %PostTitle%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
69
+ array(2055, E_CRITICAL, __('User deleted a custom field from a post', 'wp-security-audit-log'), __('Deleted the custom field %MetaKey% with id %MetaID% from the post %PostTitle%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
70
+ array(2062, E_CRITICAL, __('User updated a custom field name for a post', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in the post %PostTitle%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
71
+ array(2065, E_WARNING, __('User modified content for a published post', 'wp-security-audit-log'), __('Modified the content of the published post %PostTitle%.'.'%RevisionLink%'.' %EditorLinkPost%.', 'wp-security-audit-log')),
72
+ array(2068, E_NOTICE, __('User modified content for a draft post', 'wp-security-audit-log'), __('Modified the content of the draft post %PostTitle%.'.'%RevisionLink%'.' %EditorLinkPost%.', 'wp-security-audit-log')),
73
+ array(2072, E_NOTICE, __('User modified content of a post', 'wp-security-audit-log'), __('Modified the content of post %PostTitle% which is submitted for review.'.'%RevisionLink%'.' %EditorLinkPost%.', 'wp-security-audit-log')),
74
+ array(2073, E_NOTICE, __('User submitted a post for review', 'wp-security-audit-log'), __('Submitted the post %PostTitle% for review. %EditorLinkPost%.', '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%. %EditorLinkPost%.', 'wp-security-audit-log')),
76
+ array(2086, E_NOTICE, __('User changed title of a post', 'wp-security-audit-log'), __('Changed the title of the post %OldTitle% to %NewTitle%. %EditorLinkPost%.', '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% and saved it as draft. %EditorLinkPage%.', 'wp-security-audit-log')),
80
+ array(2005, E_NOTICE, __('User published a WorPress page', 'wp-security-audit-log'), __('Published a page called %PostTitle%. Page URL is %PostUrl%. %EditorLinkPage%.', 'wp-security-audit-log')),
81
+ array(2006, E_NOTICE, __('User modified a published WordPress page', 'wp-security-audit-log'), __('Modified the published page %PostTitle%. Page URL is %PostUrl%. %EditorLinkPage%.', 'wp-security-audit-log')),
82
+ array(2007, E_NOTICE, __('User modified a draft WordPress page', 'wp-security-audit-log'), __('Modified the draft page %PostTitle%. Page ID is %PostID%. %EditorLinkPage%.', 'wp-security-audit-log')),
83
+ array(2009, E_WARNING, __('User permanently deleted a page from the trash', 'wp-security-audit-log'), __('Permanently deleted the page %PostTitle%. Page URL was %PostUrl%. %EditorLinkPage%.', 'wp-security-audit-log')),
84
+ array(2013, E_WARNING, __('User moved WordPress page to the trash', 'wp-security-audit-log'), __('Moved the page %PostTitle% to trash. Page URL was %PostUrl%.', 'wp-security-audit-log')),
85
+ array(2015, E_CRITICAL, __('User restored a WordPress page from trash', 'wp-security-audit-log'), __('Page %PostTitle% has been restored from trash. %EditorLinkPage%.', 'wp-security-audit-log')),
86
+ array(2018, E_NOTICE, __('User changed page URL', 'wp-security-audit-log'), __('Changed the URL of the page %PostTitle% from %OldUrl% to %NewUrl%. %EditorLinkPage%.', 'wp-security-audit-log')),
87
+ array(2020, E_NOTICE, __('User changed page author', 'wp-security-audit-log'), __('Changed the author of the page %PostTitle% from %OldAuthor% to %NewAuthor%. %EditorLinkPage%.', 'wp-security-audit-log')),
88
+ array(2022, E_NOTICE, __('User changed page status', 'wp-security-audit-log'), __('Changed the status of the page %PostTitle% from %OldStatus% to %NewStatus%. %EditorLinkPage%.', 'wp-security-audit-log')),
89
+ array(2026, E_WARNING, __('User changed the visibility of a page post', 'wp-security-audit-log'), __('Changed the visibility of the page %PostTitle% from %OldVisibility% to %NewVisibility%. %EditorLinkPage%.', 'wp-security-audit-log')),
90
+ array(2028, E_NOTICE, __('User changed the date of a page post', 'wp-security-audit-log'), __('Changed the date of the page %PostTitle% from %OldDate% to %NewDate%. %EditorLinkPage%.', 'wp-security-audit-log')),
91
+ array(2047, E_NOTICE, __('User changed the parent of a page', 'wp-security-audit-log'), __('Changed the parent of the page %PostTitle% from %OldParentName% to %NewParentName%. %EditorLinkPage%.', 'wp-security-audit-log')),
92
+ array(2048, E_CRITICAL, __('User changed the template of a page', 'wp-security-audit-log'), __('Changed the template of the page %PostTitle% from %OldTemplate% to %NewTemplate%. %EditorLinkPage%.', 'wp-security-audit-log')),
93
+ array(2059, E_CRITICAL, __('User created a custom field for a page', 'wp-security-audit-log'), __('Created a new custom field called %MetaKey% with value %MetaValue% in the page %PostTitle%'.' %EditorLinkPage%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
94
+ array(2060, E_CRITICAL, __('User updated a custom field value for a page', 'wp-security-audit-log'), __('Modified the value of the custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in the page %PostTitle%'.' %EditorLinkPage%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
95
+ array(2061, E_CRITICAL, __('User deleted a custom field from a page', 'wp-security-audit-log'), __('Deleted the custom field %MetaKey% with id %MetaID% from page %PostTitle%'.' %EditorLinkPage%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
96
+ array(2064, E_CRITICAL, __('User updated a custom field name for a page', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in the page %PostTitle%'.' %EditorLinkPage%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
97
+ array(2066, E_WARNING, __('User modified content for a published page', 'wp-security-audit-log'), __('Modified the content of the published page %PostTitle%. Page URL is %PostUrl%.'.'%RevisionLink%'.' %EditorLinkPage%.', 'wp-security-audit-log')),
98
+ array(2069, E_NOTICE, __('User modified content for a draft page', 'wp-security-audit-log'), __('Modified the content of draft page %PostTitle%.'.'%RevisionLink%'.' %EditorLinkPage%.', '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%.'.' %EditorLinkPage%.', 'wp-security-audit-log')),
100
+ array(2087, E_NOTICE, __('User changed title of a page', 'wp-security-audit-log'), __('Changed the title of the page %OldTitle% to %NewTitle%.'.' %EditorLinkPage%.', '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%. %EditorLinkPost%.', 'wp-security-audit-log')),
104
+ array(2030, E_NOTICE, __('User published a post with custom post type', 'wp-security-audit-log'), __('Published a custom post %PostTitle% of type %PostType%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
105
+ array(2031, E_NOTICE, __('User modified a post with custom post type', 'wp-security-audit-log'), __('Modified the custom post %PostTitle% of type %PostType%. Post URL is %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
106
+ array(2032, E_NOTICE, __('User modified a draft post with custom post type', 'wp-security-audit-log'), __('Modified the draft custom post %PostTitle% of type is %PostType%. %EditorLinkPost%.', 'wp-security-audit-log')),
107
+ array(2033, E_WARNING, __('User permanently deleted post with custom post type', 'wp-security-audit-log'), __('Permanently Deleted the custom post %PostTitle% of type %PostType%. The post URL was %PostUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
108
+ array(2034, E_WARNING, __('User moved post with custom post type to trash', 'wp-security-audit-log'), __('Moved the custom post %PostTitle% of type %PostType% to trash. Post URL was %PostUrl%.', 'wp-security-audit-log')),
109
+ array(2035, E_CRITICAL, __('User restored post with custom post type from trash', 'wp-security-audit-log'), __('The custom post %PostTitle% of type %PostType% has been restored from trash. %EditorLinkPost%.', 'wp-security-audit-log')),
110
+ array(2036, E_NOTICE, __('User changed the category of a post with custom post type', 'wp-security-audit-log'), __('Changed the category(ies) of the custom post %PostTitle% of type %PostType% from %OldCategories% to %NewCategories%. %EditorLinkPost%.', 'wp-security-audit-log')),
111
+ array(2037, E_NOTICE, __('User changed the URL of a post with custom post type', 'wp-security-audit-log'), __('Changed the URL of the custom post %PostTitle% of type %PostType% from %OldUrl% to %NewUrl%. %EditorLinkPost%.', 'wp-security-audit-log')),
112
+ array(2038, E_NOTICE, __('User changed the author or post with custom post type', 'wp-security-audit-log'), __('Changed the author of custom post %PostTitle% of type %PostType% from %OldAuthor% to %NewAuthor%. %EditorLinkPost%.', 'wp-security-audit-log')),
113
+ array(2039, E_NOTICE, __('User changed the status of post with custom post type', 'wp-security-audit-log'), __('Changed the status of custom post %PostTitle% of type %PostType% from %OldStatus% to %NewStatus%. %EditorLinkPost%.', 'wp-security-audit-log')),
114
+ array(2040, E_WARNING, __('User changed the visibility of a post with custom post type', 'wp-security-audit-log'), __('Changed the visibility of the custom post %PostTitle% of type %PostType% from %OldVisibility% to %NewVisibility%. %EditorLinkPost%.', 'wp-security-audit-log')),
115
+ array(2041, E_NOTICE, __('User changed the date of post with custom post type', 'wp-security-audit-log'), __('Changed the date of the custom post %PostTitle% of type %PostType% from %OldDate% to %NewDate%. %EditorLinkPost%.', 'wp-security-audit-log')),
116
+ array(2056, E_CRITICAL, __('User created a custom field for a custom post type', 'wp-security-audit-log'), __('Created a new custom field %MetaKey% with value %MetaValue% in custom post %PostTitle% of type %PostType%.'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
117
+ array(2057, E_CRITICAL, __('User updated a custom field for a custom post type', 'wp-security-audit-log'), __('Modified the value of the custom field %MetaKey% from %MetaValueOld% to %MetaValueNew% in custom post %PostTitle% of type %PostType%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
118
+ array(2058, E_CRITICAL, __('User deleted a custom field from a custom post type', 'wp-security-audit-log'), __('Deleted the custom field %MetaKey% with id %MetaID% from custom post %PostTitle% of type %PostType%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
119
+ array(2063, E_CRITICAL, __('User updated a custom field name for a custom post type', 'wp-security-audit-log'), __('Changed the custom field name from %MetaKeyOld% to %MetaKeyNew% in custom post %PostTitle% of type %PostType%'.' %EditorLinkPost%.'.'<br>%MetaLink%.', 'wp-security-audit-log')),
120
+ array(2067, E_WARNING, __('User modified content for a published custom post type', 'wp-security-audit-log'), __('Modified the content of the published custom post type %PostTitle%. Post URL is %PostUrl%.'.'%EditorLinkPost%.', 'wp-security-audit-log')),
121
+ array(2070, E_NOTICE, __('User modified content for a draft custom post type', 'wp-security-audit-log'), __('Modified the content of the draft custom post type %PostTitle%.'.'%EditorLinkPost%.', '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%. %EditorLinkPost%.', 'wp-security-audit-log')),
123
+ array(2088, E_NOTICE, __('User changed title of a custom post type', 'wp-security-audit-log'), __('Changed the title of the custom post %OldTitle% to %NewTitle%. %EditorLinkPost%.', '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')),
127
+ array(2043, E_WARNING, __('User modified a widget', 'wp-security-audit-log'), __('Modified the %WidgetName% widget in %Sidebar%.', 'wp-security-audit-log')),
128
+ array(2044, E_CRITICAL, __('User deleted widget', 'wp-security-audit-log'), __('Deleted the %WidgetName% widget from %Sidebar%.', 'wp-security-audit-log')),
129
+ array(2045, E_NOTICE, __('User moved widget', 'wp-security-audit-log'), __('Moved the %WidgetName% widget from %OldSidebar% to %NewSidebar%.', 'wp-security-audit-log')),
130
+ array(2071, E_NOTICE, __('User changed widget position', 'wp-security-audit-log'), __('Changed the position of the widget %WidgetName% in sidebar %Sidebar%.', 'wp-security-audit-log'))
131
  ),
132
  __('User Profiles', 'wp-security-audit-log') => array(
133
+ array(4000, E_CRITICAL, __('New user was created on WordPress', 'wp-security-audit-log'), __('A new user %NewUserData->Username% was created with role of %NewUserData->Roles%.', 'wp-security-audit-log')),
134
+ array(4001, E_CRITICAL, __('User created another WordPress user', 'wp-security-audit-log'), __('%UserChanger% created a new user %NewUserData->Username% with the role of %NewUserData->Roles%.', 'wp-security-audit-log')),
135
+ array(4002, E_CRITICAL, __('The role of a user was changed by another WordPress user', 'wp-security-audit-log'), __('Changed the role of the user %TargetUsername% from %OldRole% to %NewRole%.', 'wp-security-audit-log')),
136
+ array(4003, E_CRITICAL, __('User has changed his or her password', 'wp-security-audit-log'), __('Changed the password.', 'wp-security-audit-log')),
137
+ array(4004, E_CRITICAL, __('User changed another user\'s password', 'wp-security-audit-log'), __('Changed the password for the user %TargetUserData->Username% with the role of %TargetUserData->Roles%.', 'wp-security-audit-log')),
138
+ array(4005, E_NOTICE, __('User changed his or her email address', 'wp-security-audit-log'), __('Changed the email address from %OldEmail% to %NewEmail%.', 'wp-security-audit-log')),
139
+ array(4006, E_NOTICE, __('User changed another user\'s email address', 'wp-security-audit-log'), __('Changed the email address of the user %TargetUsername% from %OldEmail% to %NewEmail%.', 'wp-security-audit-log')),
140
+ array(4007, E_CRITICAL, __('User was deleted by another user', 'wp-security-audit-log'), __('Deleted the user %TargetUserData->Username% with the role of %TargetUserData->Roles%.', 'wp-security-audit-log'))
 
141
  ),
142
  __('Plugins & Themes', 'wp-security-audit-log') => array(
143
+ array(5000, E_CRITICAL, __('User installed a plugin', 'wp-security-audit-log'), __('Installed the plugin %Plugin->Name% in %Plugin->plugin_dir_path%.', 'wp-security-audit-log')),
144
+ array(5001, E_CRITICAL, __('User activated a WordPress plugin', 'wp-security-audit-log'), __('Activated the plugin %PluginData->Name% installed in %PluginFile%.', 'wp-security-audit-log')),
145
+ array(5002, E_CRITICAL, __('User deactivated a WordPress plugin', 'wp-security-audit-log'), __('Deactivated the plugin %PluginData->Name% installed in %PluginFile%.', 'wp-security-audit-log')),
146
+ array(5003, E_CRITICAL, __('User uninstalled a plugin', 'wp-security-audit-log'), __('Uninstalled the plugin %PluginData->Name% which was installed in %PluginFile%.', 'wp-security-audit-log')),
147
+ array(5004, E_WARNING, __('User upgraded a plugin', 'wp-security-audit-log'), __('Upgraded the plugin %PluginData->Name% installed in %PluginFile%.', 'wp-security-audit-log')),
148
+ array(5005, E_WARNING, __('User installed a theme', 'wp-security-audit-log'), __('Installed the theme "%Theme->Name%" in %Theme->get_template_directory%.', 'wp-security-audit-log')),
149
+ array(5006, E_CRITICAL, __('User activated a theme', 'wp-security-audit-log'), __('Activated the theme "%Theme->Name%", installed in %Theme->get_template_directory%.', 'wp-security-audit-log')),
150
+ array(5007, E_CRITICAL, __('User uninstalled a theme', 'wp-security-audit-log'), __('Deleted the theme "%Theme->Name%" installed in %Theme->get_template_directory%.', 'wp-security-audit-log')),
151
+ array(5019, E_CRITICAL, __('A plugin created a post', 'wp-security-audit-log'), __('A plugin automatically created the following post: %PostTitle%.', 'wp-security-audit-log')),
152
+ array(5020, E_CRITICAL, __('A plugin created a page', 'wp-security-audit-log'), __('A plugin automatically created the following page: %PostTitle%.', 'wp-security-audit-log')),
153
+ array(5021, E_CRITICAL, __('A plugin created a custom post', 'wp-security-audit-log'), __('A plugin automatically created the following custom post: %PostTitle%.', 'wp-security-audit-log')),
154
+ array(5025, E_CRITICAL, __('A plugin deleted a post', 'wp-security-audit-log'), __('A plugin automatically deleted the following post: %PostTitle%.', 'wp-security-audit-log')),
155
+ array(5026, E_CRITICAL, __('A plugin deleted a page', 'wp-security-audit-log'), __('A plugin automatically deleted the following page: %PostTitle%.', 'wp-security-audit-log')),
156
+ array(5027, E_CRITICAL, __('A plugin deleted a custom post', 'wp-security-audit-log'), __('A plugin automatically deleted the following custom post: %PostTitle%.', 'wp-security-audit-log')),
157
+ array(5031, E_WARNING, __('User updated a theme', 'wp-security-audit-log'), __('Updated the theme "%Theme->Name%" installed in %Theme->get_template_directory%.', 'wp-security-audit-log')),
158
+ array(2046, E_CRITICAL, __('User changed a file using the theme editor', 'wp-security-audit-log'), __('Modified %File% with the Theme Editor.', 'wp-security-audit-log')),
159
+ array(2051, E_CRITICAL, __('User changed a file using the plugin editor', 'wp-security-audit-log'), __('Modified %File% with the Plugin Editor.', 'wp-security-audit-log'))
160
  ),
161
  __('System Activity', 'wp-security-audit-log') => array(
162
+ array(0000, E_CRITICAL, __('Unknown Error', 'wp-security-audit-log'), __('An unexpected error has occurred .', 'wp-security-audit-log')),
163
+ array(0001, E_CRITICAL, __('PHP error', 'wp-security-audit-log'), __('%Message%.', 'wp-security-audit-log')),
164
+ array(0002, E_WARNING, __('PHP warning', 'wp-security-audit-log'), __('%Message%.', 'wp-security-audit-log')),
165
+ array(0003, E_NOTICE, __('PHP notice', 'wp-security-audit-log'), __('%Message%.', 'wp-security-audit-log')),
166
+ array(0004, E_CRITICAL, __('PHP exception', 'wp-security-audit-log'), __('%Message%.', 'wp-security-audit-log')),
167
+ array(0005, E_CRITICAL, __('PHP shutdown error', 'wp-security-audit-log'), __('%Message%.', 'wp-security-audit-log')),
168
+ array(6000, E_NOTICE, __('Events automatically pruned by system', 'wp-security-audit-log'), __('System automatically deleted %EventCount% alert(s).', 'wp-security-audit-log')),
169
+ array(6001, E_CRITICAL, __('Option Anyone Can Register in WordPress settings changed', 'wp-security-audit-log'), __('%NewValue% the option "Anyone can register".', 'wp-security-audit-log')),
170
+ array(6002, E_CRITICAL, __('New User Default Role changed', 'wp-security-audit-log'), __('Changed the New User Default Role from %OldRole% to %NewRole%.', 'wp-security-audit-log')),
171
+ array(6003, E_CRITICAL, __('WordPress Administrator Notification email changed', 'wp-security-audit-log'), __('Changed the WordPress administrator notifications email address from %OldEmail% to %NewEmail%.', 'wp-security-audit-log')),
172
+ array(6004, E_CRITICAL, __('WordPress was updated', 'wp-security-audit-log'), __('Updated WordPress from version %OldVersion% to %NewVersion%.', 'wp-security-audit-log')),
173
+ array(6005, E_CRITICAL, __('User changes the WordPress Permalinks', 'wp-security-audit-log'), __('Changed the WordPress permalinks from %OldPattern% to %NewPattern%.', 'wp-security-audit-log')),
174
+ array(6007, E_CRITICAL, __('User requests non-existing pages (404 Error Pages)', 'wp-security-audit-log'), __('Has requested a non existing page (404 Error Pages) %Attempts% %Msg%.', 'wp-security-audit-log')),
175
+ array(9999, E_CRITICAL, __('Advertising Add-ons.', 'wp-security-audit-log'), __('%PromoName% %PromoMessage%', 'wp-security-audit-log'))
176
  ),
177
  __('MultiSite', 'wp-security-audit-log') => array(
178
+ array(4008, E_CRITICAL, __('User granted Super Admin privileges', 'wp-security-audit-log'), __('Granted Super Admin privileges to %TargetUsername%.', 'wp-security-audit-log')),
179
+ array(4009, E_CRITICAL, __('User revoked from Super Admin privileges', 'wp-security-audit-log'), __('Revoked Super Admin privileges from %TargetUsername%.', 'wp-security-audit-log')),
180
+ array(4010, E_CRITICAL, __('Existing user added to a site', 'wp-security-audit-log'), __('Added the existing user %TargetUsername% with %TargetUserRole% role to site %SiteName%.', 'wp-security-audit-log')),
181
+ array(4011, E_CRITICAL, __('User removed from site', 'wp-security-audit-log'), __('Removed the user %TargetUsername% with role %TargetUserRole% from %SiteName% site.', 'wp-security-audit-log')),
182
+ array(4012, E_CRITICAL, __('New network user created', 'wp-security-audit-log'), __('Created a new network user %NewUserData->Username%.', 'wp-security-audit-log')),
183
+ array(4013, E_CRITICAL, __('The forum role of a user was changed by another WordPress user', 'wp-security-audit-log'), __('Change the forum role of the user %TargetUsername% from %OldRole% to %NewRole% by %UserChanger%.', 'wp-security-audit-log')),
184
+ array(7000, E_CRITICAL, __('New site added on the network', 'wp-security-audit-log'), __('Added the site %SiteName% to the network.', 'wp-security-audit-log')),
185
+ array(7001, E_CRITICAL, __('Existing site archived', 'wp-security-audit-log'), __('Archived the site %SiteName%.', 'wp-security-audit-log')),
186
+ array(7002, E_CRITICAL, __('Archived site has been unarchived', 'wp-security-audit-log'), __('Unarchived the site %SiteName%.', 'wp-security-audit-log')),
187
+ array(7003, E_CRITICAL, __('Deactivated site has been activated', 'wp-security-audit-log'), __('Activated the site %SiteName%.', 'wp-security-audit-log')),
188
+ array(7004, E_CRITICAL, __('Site has been deactivated', 'wp-security-audit-log'), __('Deactivated the site %SiteName%.', 'wp-security-audit-log')),
189
+ array(7005, E_CRITICAL, __('Existing site deleted from network', 'wp-security-audit-log'), __('Deleted the site %SiteName%.', 'wp-security-audit-log')),
190
+ array(5008, E_CRITICAL, __('Activated theme on network', 'wp-security-audit-log'), __('Network activated the theme %Theme->Name% installed in %Theme->get_template_directory%.', 'wp-security-audit-log')),
191
+ array(5009, E_CRITICAL, __('Deactivated theme from network', 'wp-security-audit-log'), __('Network deactivated the theme %Theme->Name% installed in %Theme->get_template_directory%.', 'wp-security-audit-log'))
192
  ),
193
  __('Database', 'wp-security-audit-log') => array(
194
+ array(5010, E_CRITICAL, __('Plugin created tables', 'wp-security-audit-log'), __('Plugin %Plugin->Name% created these tables in the database: %TableNames%.', 'wp-security-audit-log')),
195
+ array(5011, E_CRITICAL, __('Plugin modified tables structure', 'wp-security-audit-log'), __('Plugin %Plugin->Name% modified the structure of these database tables: %TableNames%.', 'wp-security-audit-log')),
196
+ array(5012, E_CRITICAL, __('Plugin deleted tables', 'wp-security-audit-log'), __('Plugin %Plugin->Name% deleted the following tables from the database: %TableNames%.', 'wp-security-audit-log')),
197
+ array(5013, E_CRITICAL, __('Theme created tables', 'wp-security-audit-log'), __('Theme %Theme->Name% created these tables in the database: %TableNames%.', 'wp-security-audit-log')),
198
+ array(5014, E_CRITICAL, __('Theme modified tables structure', 'wp-security-audit-log'), __('Theme %Theme->Name% modified the structure of these database tables: %TableNames%.', 'wp-security-audit-log')),
199
+ array(5015, E_CRITICAL, __('Theme deleted tables', 'wp-security-audit-log'), __('Theme %Theme->Name% deleted the following tables from the database: %TableNames%.', 'wp-security-audit-log')),
200
+ array(5016, E_CRITICAL, __('Unknown component created tables', 'wp-security-audit-log'), __('An unknown component created these tables in the database: %TableNames%.', 'wp-security-audit-log')),
201
+ array(5017, E_CRITICAL, __('Unknown component modified tables structure', 'wp-security-audit-log'), __('An unknown component modified the structure of these database tables: %TableNames%.', 'wp-security-audit-log')),
202
+ array(5018, E_CRITICAL, __('Unknown component deleted tables', 'wp-security-audit-log'), __('An unknown component deleted the following tables from the database: %TableNames%.', 'wp-security-audit-log'))
203
  ),
204
  __('BBPress Forum', 'wp-security-audit-log') => array(
205
+ array(8000, E_CRITICAL, __('User created new forum', 'wp-security-audit-log'), __('Created new forum %ForumName%. Forum URL is %ForumURL%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
206
+ array(8001, E_NOTICE, __('User changed status of a forum', 'wp-security-audit-log'), __('Changed the status of the forum %ForumName% from %OldStatus% to %NewStatus%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
207
+ array(8002, E_NOTICE, __('User changed visibility of a forum', 'wp-security-audit-log'), __('Changed the visibility of the forum %ForumName% from %OldVisibility% to %NewVisibility%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
208
+ array(8003, E_CRITICAL, __('User changed the URL of a forum', 'wp-security-audit-log'), __('Changed the URL of the forum %ForumName% from %OldUrl% to %NewUrl%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
209
+ array(8004, E_NOTICE, __('User changed order of a forum', 'wp-security-audit-log'), __('Changed the order of the forum %ForumName% from %OldOrder% to %NewOrder%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
210
+ array(8005, E_CRITICAL, __('User moved forum to trash', 'wp-security-audit-log'), __('Moved the forum %ForumName% to trash.', 'wp-security-audit-log')),
211
+ array(8006, E_WARNING, __('User permanently deleted forum', 'wp-security-audit-log'), __('Permanently deleted the forum %ForumName%.', 'wp-security-audit-log')),
212
+ array(8007, E_WARNING, __('User restored forum from trash', 'wp-security-audit-log'), __('Restored the forum %ForumName% from trash.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
213
+ array(8008, E_NOTICE, __('User changed the parent of a forum', 'wp-security-audit-log'), __('Changed the parent of the forum %ForumName% from %OldParent% to %NewParent%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
214
+ array(8009, E_WARNING, __('User changed forum\'s role', 'wp-security-audit-log'), __('Changed the forum\'s auto role from %OldRole% to %NewRole%.', 'wp-security-audit-log')),
215
+ array(8010, E_WARNING, __('User changed option of a forum', 'wp-security-audit-log'), __('%Status% the option for anonymous posting on forum.', 'wp-security-audit-log')),
216
+ array(8011, E_NOTICE, __('User changed type of a forum', 'wp-security-audit-log'), __('Changed the type of the forum %ForumName% from %OldType% to %NewType%.'.' %EditorLinkForum%.', 'wp-security-audit-log')),
217
+ array(8012, E_NOTICE, __('User changed time to disallow post editing', 'wp-security-audit-log'), __('Changed the time to disallow post editing from %OldTime% to %NewTime% minutes in the forums.', 'wp-security-audit-log')),
218
+ array(8013, E_WARNING, __('User changed the forum setting posting throttle time', 'wp-security-audit-log'), __('Changed the posting throttle time from %OldTime% to %NewTime% seconds in the forums.', 'wp-security-audit-log')),
219
+ array(8014, E_NOTICE, __('User created new topic', 'wp-security-audit-log'), __('Created a new topic %TopicName%.'.' %EditorLinkTopic%.', 'wp-security-audit-log')),
220
+ array(8015, E_NOTICE, __('User changed status of a topic', 'wp-security-audit-log'), __('Changed the status of the topic %TopicName% from %OldStatus% to %NewStatus%.'.' %EditorLinkTopic%.', 'wp-security-audit-log')),
221
+ array(8016, E_NOTICE, __('User changed type of a topic', 'wp-security-audit-log'), __('Changed the type of the topic %TopicName% from %OldType% to %NewType%.'.' %EditorLinkTopic%.', 'wp-security-audit-log')),
222
+ array(8017, E_CRITICAL, __('User changed URL of a topic', 'wp-security-audit-log'), __('Changed the URL of the topic %TopicName% from %OldUrl% to %NewUrl%.', 'wp-security-audit-log')),
223
+ array(8018, E_NOTICE, __('User changed the forum of a topic', 'wp-security-audit-log'), __('Changed the forum of the topic %TopicName% from %OldForum% to %NewForum%.'.' %EditorLinkTopic%.', 'wp-security-audit-log')),
224
+ array(8019, E_CRITICAL, __('User moved topic to trash', 'wp-security-audit-log'), __('Moved the topic %TopicName% to trash.', 'wp-security-audit-log')),
225
+ array(8020, E_WARNING, __('User permanently deleted topic', 'wp-security-audit-log'), __('Permanently deleted the topic %TopicName%.', 'wp-security-audit-log')),
226
+ array(8021, E_WARNING, __('User restored topic from trash', 'wp-security-audit-log'), __('Restored the topic %TopicName% from trash.'.' %EditorLinkTopic%.', 'wp-security-audit-log')),
227
+ array(8022, E_NOTICE, __('User changed visibility of a topic', 'wp-security-audit-log'), __('Changed the visibility of the topic %TopicName% from %OldVisibility% to %NewVisibility%.'.' %EditorLinkTopic%.', 'wp-security-audit-log'))
228
  ),
229
  __('Menus', 'wp-security-audit-log') => array(
230
+ array(2078, E_NOTICE, __('User created new menu', 'wp-security-audit-log'), __('Created a new menu called %MenuName%.', 'wp-security-audit-log')),
231
+ array(2079, E_WARNING, __('User added content to a menu', 'wp-security-audit-log'), __('Added the %ContentType% called %ContentName% to menu %MenuName%.', 'wp-security-audit-log')),
232
+ array(2080, E_WARNING, __('User removed content from a menu', 'wp-security-audit-log'), __('Removed the %ContentType% called %ContentName% from the menu %MenuName%.', 'wp-security-audit-log')),
233
+ array(2081, E_CRITICAL, __('User deleted menu', 'wp-security-audit-log'), __('Deleted the menu %MenuName%.', 'wp-security-audit-log')),
234
+ array(2082, E_WARNING, __('User changed menu setting', 'wp-security-audit-log'), __('%Status% the menu setting %MenuSetting% in %MenuName%.', 'wp-security-audit-log')),
235
+ array(2083, E_NOTICE, __('User modified content in a menu', 'wp-security-audit-log'), __('Modified the %ContentType% called %ContentName% in menu %MenuName%.', 'wp-security-audit-log')),
236
+ array(2084, E_WARNING, __('User changed name of a menu', 'wp-security-audit-log'), __('Changed the name of menu %OldMenuName% to %NewMenuName%.', 'wp-security-audit-log')),
237
+ array(2085, E_NOTICE, __('User changed order of the objects in a menu', 'wp-security-audit-log'), __('Changed the order of the %ItemName% in menu %MenuName%.', 'wp-security-audit-log')),
238
+ array(2089, E_NOTICE, __('User moved objects as a sub-item', 'wp-security-audit-log'), __('Moved %ItemName% as a sub-item of %ParentName% in menu %MenuName%.', 'wp-security-audit-log'))
239
+ ),
240
+ __('Comments', 'wp-security-audit-log') => array(
241
+ array(2090, E_NOTICE, __('User approved a comment', 'wp-security-audit-log'), __('Approved the comment posted in response to the post %PostTitle% by %Author% on %CommentLink%.', 'wp-security-audit-log')),
242
+ array(2091, E_NOTICE, __('User unapproved a comment', 'wp-security-audit-log'), __('Unapproved the comment posted in response to the post %PostTitle% by %Author% on %CommentLink%.', 'wp-security-audit-log')),
243
+ array(2092, E_NOTICE, __('User replied to a comment', 'wp-security-audit-log'), __('Replied to the comment posted in response to the post %PostTitle% by %Author% on %CommentLink%.', 'wp-security-audit-log')),
244
+ array(2093, E_NOTICE, __('User edited a comment', 'wp-security-audit-log'), __('Edited a comment posted in response to the post %PostTitle% by %Author% on %CommentLink%.', 'wp-security-audit-log')),
245
+ array(2094, E_NOTICE, __('User marked a comment as Spam', 'wp-security-audit-log'), __('Marked the comment posted in response to the post %PostTitle% by %Author% on %CommentLink% as Spam.', 'wp-security-audit-log')),
246
+ array(2095, E_NOTICE, __('User marked a comment as Not Spam', 'wp-security-audit-log'), __('Marked the comment posted in response to the post %PostTitle% by %Author% on %CommentLink% as Not Spam.', 'wp-security-audit-log')),
247
+ array(2096, E_NOTICE, __('User moved a comment to trash', 'wp-security-audit-log'), __('Moved the comment posted in response to the post %PostTitle% by %Author% on %Date% to trash.', 'wp-security-audit-log')),
248
+ array(2097, E_NOTICE, __('User restored a comment from the trash', 'wp-security-audit-log'), __('Restored the comment posted in response to the post %PostTitle% by %Author% on %CommentLink% from the trash.', 'wp-security-audit-log')),
249
+ array(2098, E_NOTICE, __('User permanently deleted a comment', 'wp-security-audit-log'), __('Permanently deleted the comment posted in response to the post %PostTitle% by %Author% on %Date%.', 'wp-security-audit-log')),
250
+ array(2099, E_NOTICE, __('User posted a comment', 'wp-security-audit-log'), __('%CommentMsg% on %CommentLink%.', 'wp-security-audit-log'))
251
  ),
252
  __('Custom Alerts', 'wp-security-audit-log') => array(
253
  array(2222, E_CRITICAL, __('Custom critical Alert', 'wp-security-audit-log'), __('%CustomAlertText%', 'wp-security-audit-log')),
img/all.jpg ADDED
Binary file
img/database.jpg ADDED
Binary file
img/envelope.jpg ADDED
Binary file
img/file.jpg ADDED
Binary file
img/monitoring.jpg ADDED
Binary file
img/notifications_250x150.gif DELETED
Binary file
img/reporting_250x150.gif DELETED
Binary file
img/search.jpg ADDED
Binary file
img/search_250x150.gif DELETED
Binary file
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,21 @@
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
+ jQuery("a[href*='page=wsal-emailnotifications']").css('color', '#CC4444');
18
+ jQuery("a[href*='page=wsal-loginusers']").css('color', '#CC4444');
19
+ jQuery("a[href*='page=wsal-reports']").css('color', '#CC4444');
20
+ jQuery("a[href*='page=wsal-search']").css('color', '#CC4444');
21
+ });
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
@@ -7,7 +7,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
8
  Requires at least: 3.6
9
  Tested up to: 4.5
10
- Stable tag: 2.4.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
 
@@ -176,6 +176,45 @@ Please refer to the [FAQs page](https://www.wpsecurityauditlog.com/documentation
176
 
177
  == Changelog ==
178
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  = 2.4.4 (2016-06-27) =
180
 
181
  * **Security fix**
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.5.0
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
 
176
 
177
  == Changelog ==
178
 
179
+ = 2.5.0 (2016-07-12) =
180
+
181
+ Read the [WP Security Audit Log 2.5.0 release notes](https://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/log-wordpress-comments-activity-2-5) for a detailed overview of what is new.
182
+
183
+ * **New Features**
184
+ * Plugin now keeps a record in the audit trail of changes in WordPress comments. Refer to the list of alerts for WordPress comments for the complete list.
185
+ * Audit log alerts for 404 (page not found) requests.
186
+ * Audit log alerts for pages / posts / custom post types automatically created by plugins.
187
+ * Added wildcard (*) support for when excluding Custom Fields.
188
+ * New setting to customize From email address and display name (The [Reports](https://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/), [Email Alerts](https://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/) and [Users Sessions Management](https://www.wpsecurityauditlog.com/extensions/user-sessions-management-wp-security-audit-log/) add-ons have been updated to use the configured email address).
189
+
190
+ * **New WordPress Audit Trail Alert for Changes in Comments**
191
+ * 2090: User approved a comment
192
+ * 2091: User unapproved a comment
193
+ * 2092: User replied to a comment
194
+ * 2093: User edited a comment
195
+ * 2094: User marked a comment as Spam
196
+ * 2095: User marked a comment as not Spam
197
+ * 2096: User moved a comment to trash
198
+ * 2097: User moved a comment out from the trash
199
+ * 2098: User permanently deleted a comment
200
+ * 2099: Website visitor / User posted a comment (disabled by default. Enable it from the Enable/Disable Alerts node in the plugin menu)
201
+
202
+ * **New WordPress Audit Trail Alerts for Plugins Activity**
203
+ * 5019: Plugin automatically created a post
204
+ * 5020: Plugin automatically created a page
205
+ * 5021: Plugin automatically created a custom post type
206
+ * 5025: Plugin automatically deleted a post
207
+ * 5026: Plugin automatically deleted a page
208
+ * 5027: Plugin automatically deleted a custom post type
209
+
210
+ * **Other New WordPress Audit Trail Alerts**
211
+ * 5031: User updated a theme
212
+ * 2089: User moved an object as a sub-object in a menu
213
+ * 6007: User / website visitor requested a non-existing page (404 ERROR)
214
+
215
+ * **Improvements**
216
+ * Standardized all alerts messages / Improved the text of all of them. Each post / page / custom post type alert has a linkt to the Editor now
217
+
218
  = 2.4.4 (2016-06-27) =
219
 
220
  * **Security fix**
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_once('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_once('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.4
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
@@ -284,6 +284,12 @@ class WpSecurityAuditLog {
284
  $pruningLimit = $this->settings->GetPruningLimit();
285
  $this->settings->SetPruningLimit($pruningLimit);
286
 
 
 
 
 
 
 
287
  // install cleanup hook (remove older one if it exists)
288
  wp_clear_scheduled_hook('wsal_cleanup');
289
  wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
@@ -442,15 +448,11 @@ class WpSecurityAuditLog {
442
  * @internal To be called in admin header for hiding plugin form Plugins list.
443
  */
444
  public function HidePlugin() {
445
- $selectr = '';
446
  $plugins = array('wp-security-audit-log');
447
- foreach ($this->licensing->Plugins() as $plugin) {
448
  $plugins[] = strtolower(str_replace(' ', '-', $plugin['PluginData']['Name']));
449
- }
450
- foreach ($plugins as $value) {
451
- $selectr .= '.wp-list-table.plugins tr[data-slug="' . $value . '"], ';
452
- }
453
- ?><style type="text/css"> <?php echo rtrim($selectr, ", "); ?> { display: none; }</style><?php
454
  }
455
 
456
  /**
@@ -549,7 +551,6 @@ class WpSecurityAuditLog {
549
 
550
  public static function getConnector($config = null)
551
  {
552
- require_once('classes/Connector/ConnectorFactory.php');
553
  return WSAL_Connector_ConnectorFactory::getConnector($config);
554
  }
555
 
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.5.0
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
284
  $pruningLimit = $this->settings->GetPruningLimit();
285
  $this->settings->SetPruningLimit($pruningLimit);
286
 
287
+ $oldDisabled = $this->GetGlobalOption('disabled-alerts');
288
+ // If old setting is empty disable alert 2099 by default
289
+ if (empty($oldDisabled)) {
290
+ $this->settings->SetDisabledAlerts(array(2099));
291
+ }
292
+
293
  // install cleanup hook (remove older one if it exists)
294
  wp_clear_scheduled_hook('wsal_cleanup');
295
  wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
448
  * @internal To be called in admin header for hiding plugin form Plugins list.
449
  */
450
  public function HidePlugin() {
451
+ $selectr = '.wp-list-table.plugins #';
452
  $plugins = array('wp-security-audit-log');
453
+ foreach ($this->licensing->Plugins() as $plugin)
454
  $plugins[] = strtolower(str_replace(' ', '-', $plugin['PluginData']['Name']));
455
+ ?><style type="text/css"> <?php echo $selectr . implode(', ' . $selectr, $plugins); ?> { display: none; }</style><?php
 
 
 
 
456
  }
457
 
458
  /**
551
 
552
  public static function getConnector($config = null)
553
  {
 
554
  return WSAL_Connector_ConnectorFactory::getConnector($config);
555
  }
556