WP Security Audit Log - Version 2.3

Version Description

(2016-01-12) = * New Features * Keep track of changes on bbPress forums. For more detailed information read the WP Security Audit Log 2.3 Release Notes

  • New WordPress Security Alerts

    • 8000: User published a new forum
    • 8001: User changed the status of a forum
    • 8002: User changed the visibility of a forum
    • 8003: User changed the URL of a forum
    • 8004: User changed the order of a forum
    • 8005: User moved forum to trash
    • 8006: User permanently deleted a fourm
    • 8007: User restored a forum from trash
    • 8008: User changed the parent of a forum
    • 8009: User changed the role of forum auto user role
    • 8010: User changed the option for anonymous posting on forum
    • 8011: User changed the forum type
    • 8012: User changed the time setting to disallow editing of posts
    • 8013: User changed the time setting for post throttling
    • 8014: User created new forum topic
    • 8015: User changed the status of a forum topic
    • 8016: User changed the type of a forum topic
    • 8017: User changed the URL of a forum topic
    • 8018: User changed the forum for a topic
    • 8019: User moved a forum topic to trash
    • 8020: User permanently deleted a forum topic
    • 8021: User restored a forum topic from trash
    • 8022: User changed the visibility of a forum topic
  • Improvements

    • Improved the performance / queries of the Audit Log Viewer, hence now it is faster when retrieving alerts from bigger databases
    • Rewritten and improved the reporting engine for the Reports Add-On
  • Bug Fix

    • Fixed an issue where administrators of sub domain websites could see the alerts of other websites from the dashboard widget in a multisite installation. Ticket
Download this release

Release Info

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

Code changes from version 2.2 to 2.3

classes/AuditLogListView.php CHANGED
@@ -213,6 +213,10 @@ class WSAL_AuditLogListView extends WP_List_Table {
213
  } else {
214
  $roles = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
215
  }
 
 
 
 
216
  } else {
217
  $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
218
  $uhtml = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
@@ -268,6 +272,12 @@ class WSAL_AuditLogListView extends WP_List_Table {
268
  case $name == '%Message%':
269
  return esc_html($value);
270
 
 
 
 
 
 
 
271
  case $name == '%MetaLink%':
272
  if (!empty($value)) {
273
  return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
@@ -400,10 +410,21 @@ class WSAL_AuditLogListView extends WP_List_Table {
400
 
401
  $this->items = $query->getAdapter()->Execute($query);
402
 
403
- $this->set_pagination_args( array(
404
  'total_items' => $total_items,
405
  'per_page' => $per_page,
406
  'total_pages' => ceil($total_items / $per_page)
407
- ) );
 
 
 
 
 
 
 
 
 
 
 
408
  }
409
  }
213
  } else {
214
  $roles = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>';
215
  }
216
+ } elseif ($username == 'Plugin') {
217
+ $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/plugin-logo.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
218
+ $uhtml = '<i>' . __('Plugin', 'wp-security-audit-log') . '</i>';
219
+ $roles = '';
220
  } else {
221
  $image = '<img src="'. $this->_plugin->GetBaseUrl() . '/img/wordpress-logo-32.png" class="avatar avatar-32 photo" width="32" height="32" alt=""/>';
222
  $uhtml = '<i>' . __('System', 'wp-security-audit-log') . '</i>';
272
  case $name == '%Message%':
273
  return esc_html($value);
274
 
275
+ case $name == '%PromoMessage%':
276
+ return '<p class="promo-alert">' . $value .'</p>';
277
+
278
+ case $name == '%PromoLink%':
279
+ return $value;
280
+
281
  case $name == '%MetaLink%':
282
  if (!empty($value)) {
283
  return "<a href=\"#\" onclick=\"WsalDisableCustom(this, '".$value."');\"> Exclude Custom Field from the Monitoring</a>";
410
 
411
  $this->items = $query->getAdapter()->Execute($query);
412
 
413
+ $this->set_pagination_args(array(
414
  'total_items' => $total_items,
415
  'per_page' => $per_page,
416
  'total_pages' => ceil($total_items / $per_page)
417
+ ));
418
+ }
419
+
420
+ public function single_row($item)
421
+ {
422
+ if ($item->alert_id == 9999) {
423
+ echo '<tr style="background-color: #D5E46E">';
424
+ $this->single_row_columns($item);
425
+ echo '</tr>';
426
+ } else {
427
+ parent::single_row($item);
428
+ }
429
  }
430
  }
classes/Connector/ConnectorFactory.php CHANGED
@@ -43,7 +43,7 @@ abstract class WSAL_Connector_ConnectorFactory
43
 
44
  public static function GetConfig()
45
  {
46
- $conf = new WSAL_Settings(new WpSecurityAuditLog());
47
  $type = $conf->GetAdapterConfig('adapter-type');
48
  if (empty($type)) {
49
  return null;
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;
classes/Loggers/Database.php CHANGED
@@ -1,71 +1,215 @@
1
  <?php
2
 
3
- class WSAL_Loggers_Database extends WSAL_AbstractLogger {
4
-
5
- public function __construct(WpSecurityAuditLog $plugin) {
6
- parent::__construct($plugin);
7
- $plugin->AddCleanupHook(array($this, 'CleanUp'));
8
- }
9
-
10
- public function Log($type, $data = array(), $date = null, $siteid = null, $migrated = false) {
11
- // is this a php alert, and if so, are we logging such alerts?
12
- if ($type < 0010 && !$this->plugin->settings->IsPhpErrorLoggingEnabled()) return;
13
-
14
- // create new occurrence
15
- $occ = new WSAL_Models_Occurrence();
16
- $occ->is_migrated = $migrated;
17
- $occ->created_on = $date;
18
- $occ->alert_id = $type;
19
- $occ->site_id = !is_null($siteid) ? $siteid
20
- : (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
21
- $occ->Save();
22
-
23
- // set up meta data
24
- $occ->SetMeta($data);
25
- }
26
-
27
- public function CleanUp() {
28
- $now = current_time('timestamp');
29
- $max_sdate = $this->plugin->settings->GetPruningDate();
30
- $max_count = $this->plugin->settings->GetPruningLimit();
31
- $is_date_e = $this->plugin->settings->IsPruningDateEnabled();
32
- $is_limt_e = $this->plugin->settings->IsPruningLimitEnabled();
 
 
 
 
 
 
33
 
34
  if (!$is_date_e && !$is_limt_e) {
35
  return;
36
  } // pruning disabled
37
  $occ = new WSAL_Models_Occurrence();
38
- $cnt_items = $occ->Count();
39
 
40
  // Check if there is something to delete
41
- if($is_limt_e && ($cnt_items < $max_count)){
42
  return;
43
  }
44
 
45
  $max_stamp = $now - (strtotime($max_sdate) - $now);
46
- $max_items = (int)max(($cnt_items - $max_count) + 1, 0);
47
 
48
- $query = new WSAL_Models_OccurrenceQuery();
49
- $query->addOrderBy("created_on", false);
50
- // TO DO Fixing data
51
- if ($is_date_e) $query->addCondition('created_on <= %s', intval($max_stamp));
52
- if ($is_limt_e) $query->setLimit($max_items);
53
 
54
- if (($max_items-1) == 0) return; // nothing to delete
55
 
56
- $result = $query->getAdapter()->GetSqlDelete($query);
57
- $deletedCount = $query->getAdapter()->Delete($query);
58
 
59
- if ($deletedCount == 0) return; // nothing to delete
60
- // keep track of what we're doing
61
- $this->plugin->alerts->Trigger(0003, array(
62
- 'Message' => 'Running system cleanup.',
63
- 'Query SQL' => $result['sql'],
64
- 'Query Args' => $result['args'],
65
- ), true);
66
 
67
- // notify system
68
- do_action('wsal_prune', $deletedCount, vsprintf($result['sql'], $result['args']));
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- }
1
  <?php
2
 
3
+ class WSAL_Loggers_Database extends WSAL_AbstractLogger
4
+ {
5
+
6
+ public function __construct(WpSecurityAuditLog $plugin)
7
+ {
8
+ parent::__construct($plugin);
9
+ $plugin->AddCleanupHook(array($this, 'CleanUp'));
10
+ }
11
+
12
+ public function Log($type, $data = array(), $date = null, $siteid = null, $migrated = false)
13
+ {
14
+ // is this a php alert, and if so, are we logging such alerts?
15
+ if ($type < 0010 && !$this->plugin->settings->IsPhpErrorLoggingEnabled()) return;
16
+
17
+ // create new occurrence
18
+ $occ = new WSAL_Models_Occurrence();
19
+ $occ->is_migrated = $migrated;
20
+ $occ->created_on = $date;
21
+ $occ->alert_id = $type;
22
+ $occ->site_id = !is_null($siteid) ? $siteid
23
+ : (function_exists('get_current_blog_id') ? get_current_blog_id() : 0);
24
+ $occ->Save();
25
+
26
+ // set up meta data
27
+ $occ->SetMeta($data);
28
+ // Inject for promoting the paid add-ons
29
+ $this->AlertInject($occ);
30
+ }
31
+
32
+ public function CleanUp()
33
+ {
34
+ $now = current_time('timestamp');
35
+ $max_sdate = $this->plugin->settings->GetPruningDate();
36
+ $max_count = $this->plugin->settings->GetPruningLimit();
37
+ $is_date_e = $this->plugin->settings->IsPruningDateEnabled();
38
+ $is_limt_e = $this->plugin->settings->IsPruningLimitEnabled();
39
 
40
  if (!$is_date_e && !$is_limt_e) {
41
  return;
42
  } // pruning disabled
43
  $occ = new WSAL_Models_Occurrence();
44
+ $cnt_items = $occ->Count();
45
 
46
  // Check if there is something to delete
47
+ if ($is_limt_e && ($cnt_items < $max_count)) {
48
  return;
49
  }
50
 
51
  $max_stamp = $now - (strtotime($max_sdate) - $now);
52
+ $max_items = (int)max(($cnt_items - $max_count) + 1, 0);
53
 
54
+ $query = new WSAL_Models_OccurrenceQuery();
55
+ $query->addOrderBy("created_on", false);
56
+ // TO DO Fixing data
57
+ if ($is_date_e) $query->addCondition('created_on <= %s', intval($max_stamp));
58
+ if ($is_limt_e) $query->setLimit($max_items);
59
 
60
+ if (($max_items-1) == 0) return; // nothing to delete
61
 
62
+ $result = $query->getAdapter()->GetSqlDelete($query);
63
+ $deletedCount = $query->getAdapter()->Delete($query);
64
 
65
+ if ($deletedCount == 0) return; // nothing to delete
66
+ // keep track of what we're doing
67
+ $this->plugin->alerts->Trigger(0003, array(
68
+ 'Message' => 'Running system cleanup.',
69
+ 'Query SQL' => $result['sql'],
70
+ 'Query Args' => $result['args'],
71
+ ), true);
72
 
73
+ // notify system
74
+ do_action('wsal_prune', $deletedCount, vsprintf($result['sql'], $result['args']));
75
+ }
76
+
77
+ private function AlertInject($occurrence)
78
+ {
79
+ $count = $this->CheckPromoToShow();
80
+ if ($count) {
81
+ if (($occurrence->getId() % $count) == 0) {
82
+ $promoToSend = $this->GetPromoAlert();
83
+ if (!empty($promoToSend)) {
84
+ $link = '<a href="'.$promoToSend['link'].'" target="_blank">'.$promoToSend['name'].'</a>';
85
+ $this->log(9999, array(
86
+ 'ClientIP' => '127.0.0.1',
87
+ 'Username' => 'Plugin',
88
+ 'PromoMessage' => sprintf($promoToSend['message'], $link),
89
+ 'PromoName' => $promoToSend['name']
90
+ ));
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ private function GetPromoAlert()
97
+ {
98
+ $lastPromoSentId = $this->plugin->GetGlobalOption('promo-send-id');
99
+ $lastPromoSentId = empty($lastPromoSentId) ? 0 : $lastPromoSentId;
100
+ $promoToSend = null;
101
+ $aPromoAlerts = $this->GetActivePromoText();
102
+ if (!empty($aPromoAlerts)) {
103
+ $promoToSend = isset($aPromoAlerts[$lastPromoSentId]) ? $aPromoAlerts[$lastPromoSentId] : $aPromoAlerts[0];
104
+
105
+ if ($lastPromoSentId < count($aPromoAlerts)-1) {
106
+ $lastPromoSentId++;
107
+ } else {
108
+ $lastPromoSentId = 0;
109
+ }
110
+ $this->plugin->SetGlobalOption('promo-send-id', $lastPromoSentId);
111
+ }
112
+ return $promoToSend;
113
+ }
114
+
115
+ private function GetActivePromoText()
116
+ {
117
+ $aPromoAlerts = array();
118
+ for ($i = 1; $i <= 2; $i++) {
119
+ // Generic Premium Update
120
+ if ($i == 1) {
121
+ $msg = 'Add email alerts, generate compliance reports and add the search functionality to your WordPress audit log with the <strong>%s</strong>.';
122
+ } else {
123
+ $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.';
124
+ }
125
+ $aPromoAlerts[] = array(
126
+ 'name' => 'Premium Add-Ons',
127
+ 'message' => '<strong>60&percnt; OFF On All Premium Add-Ons and Support Bundle</strong><br>'. $msg,
128
+ 'link' => 'http://www.wpsecurityauditlog.com/plugin-extensions/?utm_source=promoalert&utm_medium=auditviewer&utm_campaign=alladdons'
129
+ );
130
+ // Email Add-On
131
+ if (!class_exists('WSAL_NP_Plugin')) {
132
+ if ($i == 1) {
133
+ $msg = 'Get notified instantly via email of important changes and actions on your WordPress with the <strong>%s</strong>.';
134
+ } else {
135
+ $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>';
136
+ }
137
+ $aPromoAlerts[] = array(
138
+ 'name' => 'Email Notifications Add-on',
139
+ 'message' => '<strong>Email Notifications for WordPress</strong><br>'. $msg,
140
+ 'link' => 'http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=promoalert&utm_medium=auditviewer&utm_campaign=emailnotifications'
141
+ );
142
+ }
143
+ // Search Add-On
144
+ if (!class_exists('WSAL_SearchExtension')) {
145
+ if ($i == 1) {
146
+ $msg = 'Easily find a specific change or action in the WordPress audit log with the <strong>%s</strong>.';
147
+ } else {
148
+ $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>';
149
+ }
150
+ $aPromoAlerts[] = array(
151
+ 'name' => 'Search & Filters Add-on',
152
+ 'message' => '<strong>Search and Filtering for WordPress Audit Log</strong><br>'. $msg,
153
+ 'link' => 'http://www.wpsecurityauditlog.com/extensions/search-add-on-for-wordpress-security-audit-log/?utm_source=promoalert&utm_medium=auditviewer&utm_campaign=search'
154
+ );
155
+ }
156
+ // Reports Add-On
157
+ if (!class_exists('WSAL_Rep_Plugin')) {
158
+ if ($i == 1) {
159
+ $msg = 'Generate WordPress reports for management and to meet regulatory compliance requirements your business needs to adhere to with the <strong>%s</strong>.';
160
+ } else {
161
+ $msg = 'Generate WordPress reports to ensure users’ productivity and meet legal and regulatory compliance requirements with the <strong>%s</strong>';
162
+ }
163
+ $aPromoAlerts[] = array(
164
+ 'name' => 'Reports Add-on',
165
+ 'message' => '<strong>WordPress Reports Add-On</strong><br>'. $msg,
166
+ 'link' => 'http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/?utm_source=promoalert&utm_medium=auditviewer&utm_campaign=reports'
167
+ );
168
+ }
169
+ // External DB Add-On
170
+ if (!class_exists('WSAL_Ext_Plugin')) {
171
+ if ($i == 1) {
172
+ $msg = 'Store the WordPress audit log in an external database to boost the performance and security of your WordPress. <strong>%s</strong>.';
173
+ } else {
174
+ $msg = 'Meet regulatory compliance requirements your business needs to adhere to. <strong>%s</strong>';
175
+ }
176
+ $aPromoAlerts[] = array(
177
+ 'name' => 'External DB Add-on',
178
+ 'message' => '<strong>External Database for WordPress Audit Log</strong><br>'. $msg,
179
+ 'link' => 'http://www.wpsecurityauditlog.com/extensions/external-database-for-wp-security-audit-log/?utm_source=promoalert&utm_medium=auditviewer&utm_campaign=externaldb'
180
+ );
181
+ }
182
+ if (count($aPromoAlerts) == 1) {
183
+ unset($aPromoAlerts[0]);
184
+ }
185
+ }
186
+ if (count($aPromoAlerts) >= 1) {
187
+ return $aPromoAlerts;
188
+ } else {
189
+ return null;
190
+ }
191
+ }
192
+
193
+ private function CheckPromoToShow()
194
+ {
195
+ $promoToShow = null;
196
+ if (!class_exists('WSAL_NP_Plugin')) {
197
+ $promoToShow[] = true;
198
+ }
199
+ if (!class_exists('WSAL_SearchExtension')) {
200
+ $promoToShow[] = true;
201
+ }
202
+ if (!class_exists('WSAL_Rep_Plugin')) {
203
+ $promoToShow[] = true;
204
+ }
205
+ if (!class_exists('WSAL_Ext_Plugin')) {
206
+ $promoToShow[] = true;
207
+ }
208
+
209
+ if (empty($promoToShow)) {
210
+ return null;
211
+ }
212
+ return (count($promoToShow) == 4) ? 150 : 250;
213
+ }
214
 
215
+ }
classes/Models/Adapters/MySQL/ActiveRecordAdapter.php CHANGED
@@ -353,8 +353,9 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
353
  /**
354
  * Function used in WSAL reporting extension
355
  */
356
- public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp)
357
  {
 
358
  global $wpdb;
359
  $tableUsers = $wpdb->users;
360
  $_wpdb = $this->connection;
@@ -375,7 +376,8 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
375
  }
376
  $user_names = implode(', ', $aUsers);
377
  }
378
-
 
379
  $sql = "SELECT DISTINCT
380
  occ.id,
381
  occ.alert_id,
@@ -403,15 +405,21 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
403
  AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
404
  AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
405
  AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
 
406
  ORDER BY
407
  site_id, created_on DESC
408
  ";
 
409
  $_wpdb->query("SET @siteId = $_siteId");
410
  $_wpdb->query("SET @userId = $_userId");
411
  $_wpdb->query("SET @roleName = $_roleName");
412
  $_wpdb->query("SET @alertCode = $_alertCode");
413
  $_wpdb->query("SET @startTimestamp = $_startTimestamp");
414
  $_wpdb->query("SET @endTimestamp = $_endTimestamp");
 
 
 
 
415
  $results = $_wpdb->get_results($sql);
416
 
417
  foreach ($results as $row) {
@@ -422,7 +430,9 @@ class WSAL_Adapters_MySQL_ActiveRecord implements WSAL_Adapters_ActiveRecordInte
422
  $userId = $wpdb->get_var($sql);
423
  }
424
  $row->user_id = $userId;
 
425
  }
 
426
  return $results;
427
  /*
428
  $query = <<<query
353
  /**
354
  * Function used in WSAL reporting extension
355
  */
356
+ public function GetReporting($_siteId, $_userId, $_roleName, $_alertCode, $_startTimestamp, $_endTimestamp, $_nextId = null, $_limit = 0)
357
  {
358
+
359
  global $wpdb;
360
  $tableUsers = $wpdb->users;
361
  $_wpdb = $this->connection;
376
  }
377
  $user_names = implode(', ', $aUsers);
378
  }
379
+ $conditionID = !empty($_nextId) ? ' AND occ.id < '.$_nextId : '';
380
+
381
  $sql = "SELECT DISTINCT
382
  occ.id,
383
  occ.alert_id,
405
  AND (@alertCode is NULL OR find_in_set(occ.alert_id, @alertCode) > 0)
406
  AND (@startTimestamp is NULL OR occ.created_on >= @startTimestamp)
407
  AND (@endTimestamp is NULL OR occ.created_on <= @endTimestamp)
408
+ {$conditionID}
409
  ORDER BY
410
  site_id, created_on DESC
411
  ";
412
+
413
  $_wpdb->query("SET @siteId = $_siteId");
414
  $_wpdb->query("SET @userId = $_userId");
415
  $_wpdb->query("SET @roleName = $_roleName");
416
  $_wpdb->query("SET @alertCode = $_alertCode");
417
  $_wpdb->query("SET @startTimestamp = $_startTimestamp");
418
  $_wpdb->query("SET @endTimestamp = $_endTimestamp");
419
+
420
+ if (!empty($_limit)) {
421
+ $sql .= " LIMIT {$_limit}";
422
+ }
423
  $results = $_wpdb->get_results($sql);
424
 
425
  foreach ($results as $row) {
430
  $userId = $wpdb->get_var($sql);
431
  }
432
  $row->user_id = $userId;
433
+ $results['lastId'] = $row->id;
434
  }
435
+
436
  return $results;
437
  /*
438
  $query = <<<query
classes/Models/Adapters/MySQL/OccurrenceAdapter.php CHANGED
@@ -125,13 +125,13 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
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
  }
@@ -166,5 +166,22 @@ class WSAL_Adapters_MySQL_Occurrence extends WSAL_Adapters_MySQL_ActiveRecord im
166
  return $searchConditions;
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
  }
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
  }
166
  return $searchConditions;
167
  }
168
 
169
+ /**
170
+ * Gets occurrence by Post_id
171
+ * @param int $post_id
172
+ */
173
+ public function GetByPostID($post_id)
174
+ {
175
+ $tt2 = new WSAL_Adapters_MySQL_Meta($this->connection);
176
+ return self::LoadMultiQuery(
177
+ 'SELECT occurrence.* FROM `' . $this->GetTable() . '`AS occurrence
178
+ INNER JOIN `' . $tt2->GetTable() . '`AS postMeta ON postMeta.occurrence_id = occurrence.id
179
+ and postMeta.name = "PostID"
180
+ and postMeta.value = %d
181
+ GROUP BY occurrence.id
182
+ ORDER BY created_on DESC',
183
+ array($post_id)
184
+ );
185
+ }
186
 
187
  }
classes/Models/Occurrence.php CHANGED
@@ -190,4 +190,9 @@ class WSAL_Models_Occurrence extends WSAL_Models_ActiveRecord
190
  {
191
  return $this->getAdapter()->CheckUnKnownUsers($args);
192
  }
 
 
 
 
 
193
  }
190
  {
191
  return $this->getAdapter()->CheckUnKnownUsers($args);
192
  }
193
+
194
+ public function GetByPostID($post_id)
195
+ {
196
+ return $this->getAdapter()->GetByPostID($post_id);
197
+ }
198
  }
classes/Sensors/BBPress.php ADDED
@@ -0,0 +1,410 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ $bbp_super_sticky_topics = maybe_unserialize(get_option('_bbp_super_sticky_topics'));
216
+ if (!empty($bbp_sticky_topics) && in_array($post->ID, $bbp_sticky_topics)) {
217
+ $oldType = 'sticky';
218
+ } elseif (!empty($bbp_super_sticky_topics) && in_array($post->ID, $bbp_super_sticky_topics)) {
219
+ $oldType = 'super';
220
+ } else {
221
+ $oldType = 'unstick';
222
+ }
223
+ $newType = !empty($_POST['bbp_stick_topic']) ? $_POST['bbp_stick_topic'] : '';
224
+ if (!empty($newType) && $oldType != $newType) {
225
+ $this->plugin->alerts->Trigger(8016, array(
226
+ 'TopicName' => $post->post_title,
227
+ 'OldType' => ($oldType == 'unstick') ? 'normal' : (($oldType == 'super') ? 'super sticky' : $oldType),
228
+ 'NewType' => ($newType == 'unstick') ? 'normal' : (($newType == 'super') ? 'super sticky' : $newType)
229
+ ));
230
+ $result = 1;
231
+ }
232
+ break;
233
+ }
234
+ return $result;
235
+ }
236
+
237
+ private function EventForumChangedStatus($post)
238
+ {
239
+ $result = 0;
240
+ switch ($post->post_type) {
241
+ case 'forum':
242
+ $bbp_status = get_post_meta($post->ID, '_bbp_status', true);
243
+ $oldStatus = !empty($bbp_status) ? $bbp_status : 'open';
244
+ $newStatus = !empty($_REQUEST['bbp_forum_status']) ? $_REQUEST['bbp_forum_status'] : '';
245
+ if (!empty($newStatus) && $oldStatus != $newStatus) {
246
+ $this->plugin->alerts->Trigger(8001, array(
247
+ 'ForumName' => $post->post_title,
248
+ 'OldStatus' => $oldStatus,
249
+ 'NewStatus' => $newStatus
250
+ ));
251
+ $result = 1;
252
+ }
253
+ break;
254
+ case 'topic':
255
+ $oldStatus = !empty($_REQUEST['original_post_status']) ? $_REQUEST['original_post_status'] : '';
256
+ $newStatus = !empty($_REQUEST['post_status']) ? $_REQUEST['post_status'] : '';
257
+ // In case of Ajax request Spam/Not spam
258
+ if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_spam') {
259
+ $oldStatus = $post->post_status;
260
+ $newStatus = 'spam';
261
+ if (isset($_GET['post_status']) && $_GET['post_status'] == 'spam') {
262
+ $newStatus = 'publish';
263
+ }
264
+ }
265
+ // In case of Ajax request Close/Open
266
+ if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_close') {
267
+ $oldStatus = $post->post_status;
268
+ $newStatus = 'closed';
269
+ if (isset($_GET['post_status']) && $_GET['post_status'] == 'closed') {
270
+ $newStatus = 'publish';
271
+ }
272
+ }
273
+ if (!empty($newStatus) && $oldStatus != $newStatus) {
274
+ $this->plugin->alerts->Trigger(8015, array(
275
+ 'TopicName' => $post->post_title,
276
+ 'OldStatus' => ($oldStatus == 'publish') ? 'open' : $oldStatus,
277
+ 'NewStatus' => ($newStatus == 'publish') ? 'open' : $newStatus
278
+ ));
279
+ $result = 1;
280
+ }
281
+ break;
282
+ }
283
+ return $result;
284
+ }
285
+
286
+ private function EventForumChanged($old_post, $new_post)
287
+ {
288
+ // Changed Order
289
+ if ($old_post->menu_order != $new_post->menu_order) {
290
+ $this->plugin->alerts->Trigger(8004, array(
291
+ 'ForumName' => $new_post->post_title,
292
+ 'OldOrder' => $old_post->menu_order,
293
+ 'NewOrder' => $new_post->menu_order
294
+ ));
295
+ return 1;
296
+ }
297
+ // Changed Parent
298
+ if ($old_post->post_parent != $new_post->post_parent) {
299
+ switch ($old_post->post_type) {
300
+ case 'forum':
301
+ $this->plugin->alerts->Trigger(8008, array(
302
+ 'ForumName' => $new_post->post_title,
303
+ 'OldParent' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
304
+ 'NewParent' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent'
305
+ ));
306
+ break;
307
+ case 'topic':
308
+ $this->plugin->alerts->Trigger(8018, array(
309
+ 'TopicName' => $new_post->post_title,
310
+ 'OldForum' => $old_post->post_parent ? get_the_title($old_post->post_parent) : 'no parent',
311
+ 'NewForum' => $new_post->post_parent ? get_the_title($new_post->post_parent) : 'no parent'
312
+ ));
313
+ break;
314
+ }
315
+ return 1;
316
+ }
317
+ // Changed URL
318
+ $oldLink = $this->_OldLink;
319
+ $newLink = get_permalink($new_post->ID);
320
+ if (!empty($oldLink) && $oldLink != $newLink) {
321
+ switch ($old_post->post_type) {
322
+ case 'forum':
323
+ $this->plugin->alerts->Trigger(8003, array(
324
+ 'ForumName' => $new_post->post_title,
325
+ 'OldUrl' => $oldLink,
326
+ 'NewUrl' => $newLink
327
+ ));
328
+ break;
329
+ case 'topic':
330
+ $this->plugin->alerts->Trigger(8017, array(
331
+ 'TopicName' => $new_post->post_title,
332
+ 'OldUrl' => $oldLink,
333
+ 'NewUrl' => $newLink
334
+ ));
335
+ break;
336
+ }
337
+ return 1;
338
+ }
339
+ return 0;
340
+ }
341
+
342
+ private function EventForumByCode($post, $event)
343
+ {
344
+ $this->plugin->alerts->Trigger($event, array(
345
+ 'ForumID' => $post->ID,
346
+ 'ForumName' => $post->post_title
347
+ ));
348
+ }
349
+
350
+ private function EventTopicByCode($post, $event)
351
+ {
352
+ $this->plugin->alerts->Trigger($event, array(
353
+ 'TopicID' => $post->ID,
354
+ 'TopicName' => $post->post_title
355
+ ));
356
+ }
357
+
358
+ /**
359
+ * Trigger of ajax events generated in the Topic Grid
360
+ */
361
+ public function TriggerAjaxChange()
362
+ {
363
+ if (!empty($_GET['post_type']) && !empty($_GET['topic_id'])) {
364
+ if ($_GET['post_type'] == 'topic') {
365
+ $post = get_post($_GET['topic_id']);
366
+
367
+ // Topic type
368
+ if (isset($_GET['action']) && $_GET['action'] == 'bbp_toggle_topic_stick') {
369
+ if (!empty($post->post_parent)) {
370
+ $post_id = $post->post_parent;
371
+ } else {
372
+ $post_id = $_GET['topic_id'];
373
+ }
374
+
375
+ $bbp_sticky_topics = maybe_unserialize(get_post_meta($post_id, '_bbp_sticky_topics', true));
376
+ $bbp_super_sticky_topics = maybe_unserialize(get_option('_bbp_super_sticky_topics'));
377
+ if (!empty($bbp_sticky_topics) && in_array($_GET['topic_id'], $bbp_sticky_topics)) {
378
+ $oldType = 'sticky';
379
+ } elseif (!empty($bbp_super_sticky_topics) && in_array($_GET['topic_id'], $bbp_super_sticky_topics)) {
380
+ $oldType = 'super sticky';
381
+ } else {
382
+ $oldType = 'normal';
383
+ }
384
+
385
+ switch ($oldType) {
386
+ case 'sticky':
387
+ case 'super sticky':
388
+ $newType = 'normal';
389
+ break;
390
+ case 'normal':
391
+ if (isset($_GET['super']) && $_GET['super'] == 1) {
392
+ $newType = 'super sticky';
393
+ } else {
394
+ $newType = 'sticky';
395
+ }
396
+ break;
397
+ }
398
+
399
+ if (!empty($newType) && $oldType != $newType) {
400
+ $this->plugin->alerts->Trigger(8016, array(
401
+ 'TopicName' => $post->post_title,
402
+ 'OldType' => $oldType,
403
+ 'NewType' => $newType
404
+ ));
405
+ }
406
+ }
407
+ }
408
+ }
409
+ }
410
+ }
classes/Sensors/Content.php CHANGED
@@ -9,11 +9,11 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
9
  add_action('admin_init', array($this, 'EventWordpressInit'));
10
  }
11
  add_action('transition_post_status', array($this, 'EventPostChanged'), 10, 3);
12
- add_action('post_updated', array($this, 'CheckModificationChange'), 10, 3);
13
  add_action('delete_post', array($this, 'EventPostDeleted'), 10, 1);
14
  add_action('wp_trash_post', array($this, 'EventPostTrashed'), 10, 1);
15
  add_action('untrash_post', array($this, 'EventPostUntrashed'));
16
  add_action('edit_category', array($this, 'EventChangedCategoryParent'));
 
17
  }
18
 
19
  protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
@@ -106,10 +106,12 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
106
  ));
107
  // run checks
108
  if ($this->_OldPost) {
 
 
 
109
  if ($oldStatus == 'auto-draft' || $original == 'auto-draft') {
110
  // Handle create post events
111
  $this->CheckPostCreation($this->_OldPost, $post);
112
-
113
  } else {
114
  // Handle update post events
115
  $changes = 0
@@ -124,6 +126,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
124
  if (!$changes) {
125
  $changes = $this->CheckPermalinkChange($this->_OldLink, get_permalink($post->ID), $post);
126
  }
 
 
 
127
  }
128
  }
129
  }
@@ -209,6 +214,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
209
  public function EventPostDeleted($post_id)
210
  {
211
  $post = get_post($post_id);
 
 
 
212
  if (!in_array($post->post_type, array('attachment', 'revision'))) { // ignore attachments and revisions
213
  $event = $this->GetEventTypeForPostType($post, 2008, 2009, 2033);
214
  // check WordPress backend operations
@@ -226,6 +234,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
226
  public function EventPostTrashed($post_id)
227
  {
228
  $post = get_post($post_id);
 
 
 
229
  $event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
230
  $this->plugin->alerts->Trigger($event, array(
231
  'PostID' => $post->ID,
@@ -237,6 +248,9 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
237
  public function EventPostUntrashed($post_id)
238
  {
239
  $post = get_post($post_id);
 
 
 
240
  $event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
241
  $this->plugin->alerts->Trigger($event, array(
242
  'PostID' => $post->ID,
@@ -250,11 +264,11 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
250
  $from = strtotime($oldpost->post_date);
251
  $to = strtotime($newpost->post_date);
252
  if ($oldpost->post_status == 'draft') {
253
- return;
254
  }
255
  $pending = $this->CheckReviewPendingChange($oldpost, $newpost);
256
  if ($pending) {
257
- return;
258
  }
259
  if ($from != $to) {
260
  $event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
@@ -269,18 +283,14 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
269
  }
270
  }
271
 
 
272
  protected function CheckReviewPendingChange($oldpost, $newpost)
273
  {
274
  if ($oldpost->post_status == 'pending') {
275
- $revisions = wp_get_post_revisions($newpost->ID, ARRAY_A);
276
- if (!empty($revisions)) {
277
- $revision = array_shift($revisions);
278
- }
279
  $this->plugin->alerts->Trigger(2072, array(
280
  'PostID' => $oldpost->ID,
281
  'PostType' => $oldpost->post_type,
282
- 'PostTitle' => $oldpost->post_title,
283
- 'RevisionLink' => (!empty($revision)) ? $this->getRevisionLink($revision->ID) : null
284
  ));
285
  return 1;
286
  }
@@ -451,8 +461,11 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
451
  }
452
  }
453
 
454
- public function CheckModificationChange($post_ID, $newpost, $oldpost)
455
  {
 
 
 
456
  $changes = 0 + $this->CheckDateChange($oldpost, $newpost);
457
  if (!$changes) {
458
  $contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
@@ -477,17 +490,13 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
477
  break;
478
  }
479
  if ($event) {
480
- $revisions = wp_get_post_revisions($post_ID, ARRAY_A);
481
- if (!empty($revisions)) {
482
- $revision = array_shift($revisions);
483
- }
484
  $this->plugin->alerts->Trigger($event, array(
485
  'PostID' => $post_ID,
486
  'PostType' => $oldpost->post_type,
487
  'PostTitle' => $oldpost->post_title,
488
- 'PostUrl' => get_permalink($post_ID), // TODO or should this be $newpost?
489
- 'RevisionLink' => (!empty($revision)) ? $this->getRevisionLink($revision->ID) : null
490
  ));
 
491
  }
492
  }
493
  }
@@ -540,7 +549,42 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor
540
  if (!empty($revision_id)) {
541
  return admin_url('revision.php?revision='.$revision_id);
542
  } else {
543
- return null;
544
  }
545
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  }
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
  }
18
 
19
  protected function GetEventTypeForPostType($post, $typePost, $typePage, $typeCustom)
106
  ));
107
  // run checks
108
  if ($this->_OldPost) {
109
+ if ($this->CheckBBPress($this->_OldPost)) {
110
+ return;
111
+ }
112
  if ($oldStatus == 'auto-draft' || $original == 'auto-draft') {
113
  // Handle create post events
114
  $this->CheckPostCreation($this->_OldPost, $post);
 
115
  } else {
116
  // Handle update post events
117
  $changes = 0
126
  if (!$changes) {
127
  $changes = $this->CheckPermalinkChange($this->_OldLink, get_permalink($post->ID), $post);
128
  }
129
+ if (!$changes) {
130
+ $changes = $this->CheckModificationChange($post->ID, $this->_OldPost, $post);
131
+ }
132
  }
133
  }
134
  }
214
  public function EventPostDeleted($post_id)
215
  {
216
  $post = get_post($post_id);
217
+ if ($this->CheckBBPress($post)) {
218
+ return;
219
+ }
220
  if (!in_array($post->post_type, array('attachment', 'revision'))) { // ignore attachments and revisions
221
  $event = $this->GetEventTypeForPostType($post, 2008, 2009, 2033);
222
  // check WordPress backend operations
234
  public function EventPostTrashed($post_id)
235
  {
236
  $post = get_post($post_id);
237
+ if ($this->CheckBBPress($post)) {
238
+ return;
239
+ }
240
  $event = $this->GetEventTypeForPostType($post, 2012, 2013, 2034);
241
  $this->plugin->alerts->Trigger($event, array(
242
  'PostID' => $post->ID,
248
  public function EventPostUntrashed($post_id)
249
  {
250
  $post = get_post($post_id);
251
+ if ($this->CheckBBPress($post)) {
252
+ return;
253
+ }
254
  $event = $this->GetEventTypeForPostType($post, 2014, 2015, 2035);
255
  $this->plugin->alerts->Trigger($event, array(
256
  'PostID' => $post->ID,
264
  $from = strtotime($oldpost->post_date);
265
  $to = strtotime($newpost->post_date);
266
  if ($oldpost->post_status == 'draft') {
267
+ return 0;
268
  }
269
  $pending = $this->CheckReviewPendingChange($oldpost, $newpost);
270
  if ($pending) {
271
+ return 0;
272
  }
273
  if ($from != $to) {
274
  $event = $this->GetEventTypeForPostType($oldpost, 2027, 2028, 2041);
283
  }
284
  }
285
 
286
+ // Revision used
287
  protected function CheckReviewPendingChange($oldpost, $newpost)
288
  {
289
  if ($oldpost->post_status == 'pending') {
 
 
 
 
290
  $this->plugin->alerts->Trigger(2072, array(
291
  'PostID' => $oldpost->ID,
292
  'PostType' => $oldpost->post_type,
293
+ 'PostTitle' => $oldpost->post_title
 
294
  ));
295
  return 1;
296
  }
461
  }
462
  }
463
 
464
+ public function CheckModificationChange($post_ID, $oldpost, $newpost)
465
  {
466
+ if ($this->CheckBBPress($oldpost)) {
467
+ return;
468
+ }
469
  $changes = 0 + $this->CheckDateChange($oldpost, $newpost);
470
  if (!$changes) {
471
  $contentChanged = $oldpost->post_content != $newpost->post_content; // TODO what about excerpts?
490
  break;
491
  }
492
  if ($event) {
 
 
 
 
493
  $this->plugin->alerts->Trigger($event, array(
494
  'PostID' => $post_ID,
495
  'PostType' => $oldpost->post_type,
496
  'PostTitle' => $oldpost->post_title,
497
+ 'PostUrl' => get_permalink($post_ID) // TODO or should this be $newpost?
 
498
  ));
499
+ return 1;
500
  }
501
  }
502
  }
549
  if (!empty($revision_id)) {
550
  return admin_url('revision.php?revision='.$revision_id);
551
  } else {
552
+ return '';
553
  }
554
  }
555
+
556
+ /**
557
+ * Ignore post from BBPress Plugin,
558
+ * Triggered on the BBPress Sensor
559
+ */
560
+ private function CheckBBPress($post)
561
+ {
562
+ switch ($post->post_type) {
563
+ case 'forum':
564
+ case 'topic':
565
+ case 'reply':
566
+ return true;
567
+ default:
568
+ return false;
569
+ }
570
+ }
571
+
572
+ /**
573
+ * Triggered after save post for add revision link
574
+ */
575
+ public function SetRevisionLink($post_id, $post, $update)
576
+ {
577
+ $revisions = wp_get_post_revisions($post_id);
578
+ if (!empty($revisions)) {
579
+ $revision = array_shift($revisions);
580
+
581
+ $objOcc = new WSAL_Models_Occurrence();
582
+ $occ = $objOcc->GetByPostID($post_id);
583
+ $occ = count($occ) ? $occ[0] : null;
584
+ if (!empty($occ)) {
585
+ $occ->SetMetaValue('RevisionLink', $this->getRevisionLink($revision->ID));
586
+ }
587
+ }
588
+ }
589
+
590
  }
classes/Sensors/System.php CHANGED
@@ -1,104 +1,152 @@
1
  <?php
2
 
3
- class WSAL_Sensors_System extends WSAL_AbstractSensor {
 
4
 
5
- public function HookEvents() {
6
- add_action('wsal_prune', array($this, 'EventPruneEvents'), 10, 2);
7
- add_action('admin_init', array($this, 'EventAdminInit'));
8
- }
9
-
10
- /**
11
- * @param int $count The number of deleted events.
12
- * @param string $query Query that selected events for deletion.
13
- */
14
- public function EventPruneEvents($count, $query){
15
- $this->plugin->alerts->Trigger(6000, array(
16
- 'EventCount' => $count,
17
- 'PruneQuery' => $query,
18
- ));
19
- }
20
-
21
- public function EventAdminInit(){
22
-
23
- // make sure user can actually modify target options
24
- if(!current_user_can('manage_options'))return;
25
-
26
- $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
27
- $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
28
- $is_option_page = $actype == 'options';
29
- $is_network_settings = $actype == 'settings';
30
- $is_permalink_page = $actype == 'options-permalink';
31
-
32
- if($is_option_page && (get_option('users_can_register') xor isset($_POST['users_can_register']))){
33
- $old = get_option('users_can_register') ? 'Enabled' : 'Disabled';
34
- $new = isset($_POST['users_can_register']) ? 'Enabled' : 'Disabled';
35
- if($old !== $new){
36
- $this->plugin->alerts->Trigger(6001, array(
37
- 'OldValue' => $old,
38
- 'NewValue' => $new,
39
- 'CurrentUserID' => wp_get_current_user()->ID,
40
- ));
41
- }
42
- }
 
 
 
43
 
44
- if($is_option_page && !empty($_POST['default_role'])){
45
- $old = get_option('default_role');
46
- $new = trim($_POST['default_role']);
47
- if($old !== $new){
48
- $this->plugin->alerts->Trigger(6002, array(
49
- 'OldRole' => $old,
50
- 'NewRole' => $new,
51
- 'CurrentUserID' => wp_get_current_user()->ID,
52
- ));
53
- }
54
- }
55
 
56
- if($is_option_page && !empty($_POST['admin_email'])){
57
- $old = get_option('admin_email');
58
- $new = trim($_POST['admin_email']);
59
- if($old !== $new){
60
- $this->plugin->alerts->Trigger(6003, array(
61
- 'OldEmail' => $old,
62
- 'NewEmail' => $new,
63
- 'CurrentUserID' => wp_get_current_user()->ID,
64
- ));
65
- }
66
- }
67
-
68
- if($is_network_settings && !empty($_POST['admin_email'])){
69
- $old = get_site_option('admin_email');
70
- $new = trim($_POST['admin_email']);
71
- if($old !== $new){
72
- $this->plugin->alerts->Trigger(6003, array(
73
- 'OldEmail' => $old,
74
- 'NewEmail' => $new,
75
- 'CurrentUserID' => wp_get_current_user()->ID,
76
- ));
77
- }
78
- }
79
-
80
- if($is_permalink_page && !empty($_POST['permalink_structure'])){
81
- $old = get_option('permalink_structure');
82
- $new = trim($_POST['permalink_structure']);
83
- if($old !== $new){
84
- $this->plugin->alerts->Trigger(6005, array(
85
- 'OldPattern' => $old,
86
- 'NewPattern' => $new,
87
- 'CurrentUserID' => wp_get_current_user()->ID,
88
- ));
89
- }
90
- }
91
-
92
- if($action == 'do-core-upgrade' && isset($_REQUEST['version'])){
93
- $oldVersion = get_bloginfo('version');
94
- $newVersion = $_REQUEST['version'];
95
- if($oldVersion !== $newVersion){
96
- $this->plugin->alerts->Trigger(6004, array(
97
- 'OldVersion' => $oldVersion,
98
- 'NewVersion' => $newVersion,
99
- ));
100
- }
101
- }
102
- }
103
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  }
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
+
12
+ /**
13
+ * @param int $count The number of deleted events.
14
+ * @param string $query Query that selected events for deletion.
15
+ */
16
+ public function EventPruneEvents($count, $query)
17
+ {
18
+ $this->plugin->alerts->Trigger(6000, array(
19
+ 'EventCount' => $count,
20
+ 'PruneQuery' => $query,
21
+ ));
22
+ }
23
+
24
+ public function EventAdminInit()
25
+ {
26
+
27
+ // make sure user can actually modify target options
28
+ if (!current_user_can('manage_options')) return;
29
+
30
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
31
+ $actype = basename($_SERVER['SCRIPT_NAME'], '.php');
32
+ $is_option_page = $actype == 'options';
33
+ $is_network_settings = $actype == 'settings';
34
+ $is_permalink_page = $actype == 'options-permalink';
35
+
36
+ if ($is_option_page && (get_option('users_can_register') xor isset($_POST['users_can_register']))) {
37
+ $old = get_option('users_can_register') ? 'Enabled' : 'Disabled';
38
+ $new = isset($_POST['users_can_register']) ? 'Enabled' : 'Disabled';
39
+ if ($old !== $new) {
40
+ $this->plugin->alerts->Trigger(6001, array(
41
+ 'OldValue' => $old,
42
+ 'NewValue' => $new,
43
+ 'CurrentUserID' => wp_get_current_user()->ID,
44
+ ));
45
+ }
46
+ }
47
 
48
+ if ($is_option_page && !empty($_POST['default_role'])) {
49
+ $old = get_option('default_role');
50
+ $new = trim($_POST['default_role']);
51
+ if ($old !== $new) {
52
+ $this->plugin->alerts->Trigger(6002, array(
53
+ 'OldRole' => $old,
54
+ 'NewRole' => $new,
55
+ 'CurrentUserID' => wp_get_current_user()->ID,
56
+ ));
57
+ }
58
+ }
59
 
60
+ if ($is_option_page && !empty($_POST['admin_email'])) {
61
+ $old = get_option('admin_email');
62
+ $new = trim($_POST['admin_email']);
63
+ if ($old !== $new) {
64
+ $this->plugin->alerts->Trigger(6003, array(
65
+ 'OldEmail' => $old,
66
+ 'NewEmail' => $new,
67
+ 'CurrentUserID' => wp_get_current_user()->ID,
68
+ ));
69
+ }
70
+ }
71
+
72
+ if ($is_network_settings && !empty($_POST['admin_email'])) {
73
+ $old = get_site_option('admin_email');
74
+ $new = trim($_POST['admin_email']);
75
+ if ($old !== $new) {
76
+ $this->plugin->alerts->Trigger(6003, array(
77
+ 'OldEmail' => $old,
78
+ 'NewEmail' => $new,
79
+ 'CurrentUserID' => wp_get_current_user()->ID,
80
+ ));
81
+ }
82
+ }
83
+
84
+ if ($is_permalink_page && !empty($_POST['permalink_structure'])) {
85
+ $old = get_option('permalink_structure');
86
+ $new = trim($_POST['permalink_structure']);
87
+ if ($old !== $new) {
88
+ $this->plugin->alerts->Trigger(6005, array(
89
+ 'OldPattern' => $old,
90
+ 'NewPattern' => $new,
91
+ 'CurrentUserID' => wp_get_current_user()->ID,
92
+ ));
93
+ }
94
+ }
95
+
96
+ if ($action == 'do-core-upgrade' && isset($_REQUEST['version'])) {
97
+ $oldVersion = get_bloginfo('version');
98
+ $newVersion = $_REQUEST['version'];
99
+ if ($oldVersion !== $newVersion) {
100
+ $this->plugin->alerts->Trigger(6004, array(
101
+ 'OldVersion' => $oldVersion,
102
+ 'NewVersion' => $newVersion,
103
+ ));
104
+ }
105
+ }
106
+
107
+ /* BBPress Forum support Setting */
108
+ if ($action == 'update' && isset($_REQUEST['_bbp_default_role'])) {
109
+ $oldRole = get_option('_bbp_default_role');
110
+ $newRole = $_REQUEST['_bbp_default_role'];
111
+ if ($oldRole !== $newRole) {
112
+ $this->plugin->alerts->Trigger(8009, array(
113
+ 'OldRole' => $oldRole,
114
+ 'NewRole' => $newRole
115
+ ));
116
+ }
117
+ }
118
+
119
+ if ($action == 'update' && isset($_REQUEST['option_page']) && ($_REQUEST['option_page'] == 'bbpress')) {
120
+ // Anonymous posting
121
+ $allow_anonymous = get_option('_bbp_allow_anonymous');
122
+ $oldStatus = !empty($allow_anonymous) ? 1 : 0;
123
+ $newStatus = !empty($_REQUEST['_bbp_allow_anonymous']) ? 1 : 0;
124
+ if ($oldStatus != $newStatus) {
125
+ $status = ($newStatus == 1) ? 'Enabled' : 'Disabled';
126
+ $this->plugin->alerts->Trigger(8010, array(
127
+ 'Status' => $status
128
+ ));
129
+ }
130
+ // Disallow editing after
131
+ $bbp_edit_lock = get_option('_bbp_edit_lock');
132
+ $oldTime = !empty($bbp_edit_lock) ? $bbp_edit_lock : '';
133
+ $newTime = !empty($_REQUEST['_bbp_edit_lock']) ? $_REQUEST['_bbp_edit_lock'] : '';
134
+ if ($oldTime != $newTime) {
135
+ $this->plugin->alerts->Trigger(8012, array(
136
+ 'OldTime' => $oldTime,
137
+ 'NewTime' => $newTime
138
+ ));
139
+ }
140
+ // Throttle posting every
141
+ $bbp_throttle_time = get_option('_bbp_throttle_time');
142
+ $oldTime2 = !empty($bbp_throttle_time) ? $bbp_throttle_time : '';
143
+ $newTime2 = !empty($_REQUEST['_bbp_throttle_time']) ? $_REQUEST['_bbp_throttle_time'] : '';
144
+ if ($oldTime2 != $newTime2) {
145
+ $this->plugin->alerts->Trigger(8013, array(
146
+ 'OldTime' => $oldTime2,
147
+ 'NewTime' => $newTime2
148
+ ));
149
+ }
150
+ }
151
+ }
152
  }
classes/Sensors/UserProfile.php CHANGED
@@ -1,157 +1,169 @@
1
  <?php
2
 
3
- class WSAL_Sensors_UserProfile extends WSAL_AbstractSensor {
 
4
 
5
- public function HookEvents() {
6
- add_action('admin_init', array($this, 'EventAdminInit'));
7
- add_action('user_register', array($this, 'EventUserRegister'));
 
8
  add_action('edit_user_profile_update', array($this, 'EventUserChanged'));
9
  add_action('personal_options_update', array($this, 'EventUserChanged'));
10
  add_action('delete_user', array($this, 'EventUserDeleted'));
11
  add_action('wpmu_delete_user', array($this, 'EventUserDeleted'));
12
  add_action('set_user_role', array($this, 'EventUserRoleChanged'), 10, 3);
13
- }
14
-
15
- protected $old_superadmins;
16
-
17
- protected function IsMultisite(){
18
- return function_exists('is_multisite') && is_multisite();
19
- }
20
-
21
- public function EventAdminInit(){
22
- if($this->IsMultisite()){
23
- $this->old_superadmins = get_super_admins();
24
- }
25
- }
26
-
27
- public function EventUserRegister($user_id){
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
- $user = get_userdata($user_id);
45
-
46
- $oldRole = count($oldRoles) ? implode(', ', $oldRoles) : '';
47
- $newRole = $role;
48
- if($oldRole != $newRole){
49
- $this->plugin->alerts->TriggerIf(4002, array(
50
- 'TargetUserID' => $user_id,
51
- 'TargetUsername' => $user->user_login,
52
- 'OldRole' => $oldRole,
53
- 'NewRole' => $newRole,
54
- ), array($this, 'MustNotContainUserChanges'));
55
- }
56
- }
57
-
58
- public function EventUserChanged($user_id){
59
- $user = get_userdata($user_id);
60
-
61
- // roles changed
62
- /*if(!empty($_REQUEST['role'])){
63
- $oldRole = count($user->roles) ? $user->roles[0] : '';
64
- $newRole = trim($_REQUEST['role']);
65
- if($oldRole != $newRole){
66
- $this->plugin->alerts->Trigger(4002, array(
67
- 'TargetUserID' => $user_id,
68
- 'TargetUsername' => $user->user_login,
69
- 'OldRole' => $oldRole,
70
- 'NewRole' => $newRole,
71
- ), true);
72
  }
73
- }*/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  // password changed
76
- if(!empty($_REQUEST['pass1']) && !empty($_REQUEST['pass2'])){
77
- if (trim($_REQUEST['pass1']) == trim($_REQUEST['pass2'])) {
78
- $event = $user_id == get_current_user_id() ? 4003 : 4004;
79
- $this->plugin->alerts->Trigger($event, array(
80
- 'TargetUserID' => $user_id,
81
- 'TargetUserData' => (object)array(
82
- 'Username' => $user->user_login,
83
- 'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
84
- ),
85
- ));
86
- }
87
  }
88
 
89
  // email changed
90
- if(!empty($_REQUEST['email'])){
91
- $oldEmail = $user->user_email;
92
  $newEmail = trim($_REQUEST['email']);
93
- if($oldEmail != $newEmail){
94
- $event = $user_id == get_current_user_id() ? 4005 : 4006;
95
- $this->plugin->alerts->Trigger($event, array(
96
- 'TargetUserID' => $user_id,
97
- 'TargetUsername' => $user->user_login,
98
- 'OldEmail' => $oldEmail,
99
- 'NewEmail' => $newEmail,
100
- ));
101
  }
102
  }
103
-
104
- if($this->IsMultisite()){
105
- $username = $user->user_login;
106
- $enabled = isset($_REQUEST['super_admin']);
107
-
108
- if($user_id != get_current_user_id()){
109
-
110
- // super admin enabled
111
- if($enabled && !in_array($username, $this->old_superadmins)){
112
- $this->plugin->alerts->Trigger(4008, array(
113
- 'TargetUserID' => $user_id,
114
- 'TargetUsername' => $user->user_login,
115
- ));
116
- }
117
 
118
- // super admin disabled
119
- if(!$enabled && in_array($username, $this->old_superadmins)){
120
- $this->plugin->alerts->Trigger(4009, array(
121
- 'TargetUserID' => $user_id,
122
- 'TargetUsername' => $user->user_login,
123
- ));
124
- }
125
-
126
- }
127
- }
128
- }
129
-
130
- public function EventUserDeleted($user_id){
131
- $user = get_userdata($user_id);
132
- $role = is_array($user->roles) ? implode(', ', $user->roles) : $user->roles;
133
- $this->plugin->alerts->TriggerIf(4007, array(
134
- 'TargetUserID' => $user_id,
135
- 'TargetUserData' => (object)array(
136
- 'Username' => $user->user_login,
137
- 'FirstName' => $user->user_firstname,
138
- 'LastName' => $user->user_lastname,
139
- 'Email' => $user->user_email,
140
- 'Roles' => $role ? $role : 'none',
141
- ),
142
- ), array($this, 'MustNotContainCreateUser'));
143
- }
144
-
145
- public function MustNotContainCreateUser(WSAL_AlertManager $mgr){
146
- return !$mgr->WillTrigger(4012);
147
- }
148
-
149
- public function MustNotContainUserChanges(WSAL_AlertManager $mgr){
150
- return !( $mgr->WillOrHasTriggered(4010)
151
- || $mgr->WillOrHasTriggered(4011)
152
- || $mgr->WillOrHasTriggered(4012)
153
- || $mgr->WillOrHasTriggered(4000)
154
- || $mgr->WillOrHasTriggered(4001)
155
- );
156
- }
 
 
 
157
  }
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
+ protected function IsMultisite()
20
+ {
21
+ return function_exists('is_multisite') && is_multisite();
22
+ }
23
+
24
+ public function EventAdminInit()
25
+ {
26
+ if ($this->IsMultisite()) {
27
+ $this->old_superadmins = get_super_admins();
28
+ }
29
+ }
30
+
31
+ public function EventUserRegister($user_id)
32
+ {
33
+ $user = get_userdata($user_id);
34
+ $ismu = function_exists('is_multisite') && is_multisite();
35
+ $event = $ismu ? 4012 : (is_user_logged_in() ? 4001 : 4000);
36
+ $this->plugin->alerts->Trigger($event, array(
37
+ 'NewUserID' => $user_id,
38
+ 'NewUserData' => (object)array(
39
+ 'Username' => $user->user_login,
40
+ 'FirstName' => $user->user_firstname,
41
+ 'LastName' => $user->user_lastname,
42
+ 'Email' => $user->user_email,
43
+ 'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
44
+ ),
45
+ ), true);
46
+ }
47
+
48
+ public function EventUserRoleChanged($user_id, $role, $oldRoles)
49
+ {
50
+ $user = get_userdata($user_id);
51
+ $aBbpRoles = array('bbp_spectator', 'bbp_moderator', 'bbp_participant', 'bbp_keymaster', 'bbp_blocked');
52
+ // remove any BBPress roles
53
+ if (is_array($oldRoles)) {
54
+ foreach ($oldRoles as $value) {
55
+ if (in_array($value, $aBbpRoles)) {
56
+ if ($_POST['bbp-forums-role'] != $value) {
57
+ $current_user = wp_get_current_user();
58
+ $this->plugin->alerts->TriggerIf(4013, array(
59
+ 'TargetUsername' => $user->user_login,
60
+ 'OldRole' => ucfirst(substr($value, 4)),
61
+ 'NewRole' => ucfirst(substr($_POST['bbp-forums-role'], 4)),
62
+ 'UserChanger' => $current_user->user_login
63
+ ));
64
+ }
65
+ }
 
 
 
 
 
 
 
 
66
  }
67
+ $oldRoles = array_diff($oldRoles, $aBbpRoles);
68
+ }
69
+ $oldRole = count($oldRoles) ? implode(', ', $oldRoles) : '';
70
+ $newRole = $role;
71
+ if ($oldRole != $newRole) {
72
+ $this->plugin->alerts->TriggerIf(4002, array(
73
+ 'TargetUserID' => $user_id,
74
+ 'TargetUsername' => $user->user_login,
75
+ 'OldRole' => $oldRole,
76
+ 'NewRole' => $newRole,
77
+ ), array($this, 'MustNotContainUserChanges'));
78
+ }
79
+ }
80
+
81
+ public function EventUserChanged($user_id)
82
+ {
83
+ $user = get_userdata($user_id);
84
 
85
  // password changed
86
+ if (!empty($_REQUEST['pass1']) && !empty($_REQUEST['pass2'])) {
87
+ if (trim($_REQUEST['pass1']) == trim($_REQUEST['pass2'])) {
88
+ $event = $user_id == get_current_user_id() ? 4003 : 4004;
89
+ $this->plugin->alerts->Trigger($event, array(
90
+ 'TargetUserID' => $user_id,
91
+ 'TargetUserData' => (object)array(
92
+ 'Username' => $user->user_login,
93
+ 'Roles' => is_array($user->roles) ? implode(', ', $user->roles) : $user->roles,
94
+ ),
95
+ ));
96
+ }
97
  }
98
 
99
  // email changed
100
+ if (!empty($_REQUEST['email'])) {
101
+ $oldEmail = $user->user_email;
102
  $newEmail = trim($_REQUEST['email']);
103
+ if ($oldEmail != $newEmail) {
104
+ $event = $user_id == get_current_user_id() ? 4005 : 4006;
105
+ $this->plugin->alerts->Trigger($event, array(
106
+ 'TargetUserID' => $user_id,
107
+ 'TargetUsername' => $user->user_login,
108
+ 'OldEmail' => $oldEmail,
109
+ 'NewEmail' => $newEmail,
110
+ ));
111
  }
112
  }
113
+
114
+ if ($this->IsMultisite()) {
115
+ $username = $user->user_login;
116
+ $enabled = isset($_REQUEST['super_admin']);
117
+
118
+ if ($user_id != get_current_user_id()) {
119
+ // super admin enabled
120
+ if ($enabled && !in_array($username, $this->old_superadmins)) {
121
+ $this->plugin->alerts->Trigger(4008, array(
122
+ 'TargetUserID' => $user_id,
123
+ 'TargetUsername' => $user->user_login,
124
+ ));
125
+ }
 
126
 
127
+ // super admin disabled
128
+ if (!$enabled && in_array($username, $this->old_superadmins)) {
129
+ $this->plugin->alerts->Trigger(4009, array(
130
+ 'TargetUserID' => $user_id,
131
+ 'TargetUsername' => $user->user_login,
132
+ ));
133
+ }
134
+
135
+ }
136
+ }
137
+ }
138
+
139
+ public function EventUserDeleted($user_id)
140
+ {
141
+ $user = get_userdata($user_id);
142
+ $role = is_array($user->roles) ? implode(', ', $user->roles) : $user->roles;
143
+ $this->plugin->alerts->TriggerIf(4007, array(
144
+ 'TargetUserID' => $user_id,
145
+ 'TargetUserData' => (object)array(
146
+ 'Username' => $user->user_login,
147
+ 'FirstName' => $user->user_firstname,
148
+ 'LastName' => $user->user_lastname,
149
+ 'Email' => $user->user_email,
150
+ 'Roles' => $role ? $role : 'none',
151
+ ),
152
+ ), array($this, 'MustNotContainCreateUser'));
153
+ }
154
+
155
+ public function MustNotContainCreateUser(WSAL_AlertManager $mgr)
156
+ {
157
+ return !$mgr->WillTrigger(4012);
158
+ }
159
+
160
+ public function MustNotContainUserChanges(WSAL_AlertManager $mgr)
161
+ {
162
+ return !( $mgr->WillOrHasTriggered(4010)
163
+ || $mgr->WillOrHasTriggered(4011)
164
+ || $mgr->WillOrHasTriggered(4012)
165
+ || $mgr->WillOrHasTriggered(4000)
166
+ || $mgr->WillOrHasTriggered(4001)
167
+ );
168
+ }
169
  }
classes/Settings.php CHANGED
@@ -594,7 +594,6 @@ class WSAL_Settings {
594
  if ($this->_plugin->IsMultisite()) {
595
  $columns = array_slice($columns, 0, 5, true) + array('site' => '1') + array_slice($columns, 5, null, true);
596
  }
597
- error_log(print_r($columns, true));
598
  $selected = $this->GetColumnsSelected();
599
  if (!empty($selected)) {
600
  $columns = array('alert_code' => '0', 'type' => '0', 'date' => '0', 'username' => '0', 'source_ip' => '0', 'message' => '0');
594
  if ($this->_plugin->IsMultisite()) {
595
  $columns = array_slice($columns, 0, 5, true) + array('site' => '1') + array_slice($columns, 5, null, true);
596
  }
 
597
  $selected = $this->GetColumnsSelected();
598
  if (!empty($selected)) {
599
  $columns = array('alert_code' => '0', 'type' => '0', 'date' => '0', 'username' => '0', 'source_ip' => '0', 'message' => '0');
classes/ViewManager.php CHANGED
@@ -1,215 +1,215 @@
1
  <?php
2
 
3
  class WSAL_ViewManager {
4
-
5
- /**
6
- * @var WSAL_AbstractView[]
7
- */
8
- public $views = array();
9
-
10
- /**
11
- * @var WpSecurityAuditLog
12
- */
13
- protected $_plugin;
14
 
15
- public function __construct(WpSecurityAuditLog $plugin){
16
- $this->_plugin = $plugin;
17
-
18
- // load views
19
- foreach(glob(dirname(__FILE__) . '/Views/*.php') as $file)
20
- $this->AddFromFile($file);
21
-
22
- // add menus
23
- add_action('admin_menu', array($this, 'AddAdminMenus'));
24
- add_action('network_admin_menu', array($this, 'AddAdminMenus'));
25
-
26
- // add plugin shortcut links
27
- add_filter('plugin_action_links_' . $plugin->GetBaseName(), array($this, 'AddPluginShortcuts'));
28
-
29
- // render header
30
- add_action('admin_enqueue_scripts', array($this, 'RenderViewHeader'));
31
-
32
- // render footer
33
- add_action('admin_footer', array($this, 'RenderViewFooter'));
34
- }
35
-
36
- /**
37
- * Add new view from file inside autoloader path.
38
- * @param string $file Path to file.
39
- */
40
- public function AddFromFile($file){
41
- $this->AddFromClass($this->_plugin->GetClassFileClassName($file));
42
- }
43
-
44
- /**
45
- * Add new view given class name.
46
- * @param string $class Class name.
47
- */
48
- public function AddFromClass($class){
49
- $this->AddInstance(new $class($this->_plugin));
50
- }
51
-
52
- /**
53
- * Add newly created view to list.
54
- * @param WSAL_AbstractView $view The new view.
55
- */
56
- public function AddInstance(WSAL_AbstractView $view){
57
- $this->views[] = $view;
58
- }
59
-
60
- /**
61
- * Order views by their declared weight.
62
- */
63
- public function ReorderViews(){
64
- usort($this->views, array($this, 'OrderByWeight'));
65
- }
66
-
67
- /**
68
- * @internal This has to be public for PHP to call it.
69
- * @param WSAL_AbstractView $a
70
- * @param WSAL_AbstractView $b
71
- * @return int
72
- */
73
- public function OrderByWeight(WSAL_AbstractView $a, WSAL_AbstractView $b){
74
- $wa = $a->GetWeight();
75
- $wb = $b->GetWeight();
76
- switch(true){
77
- case $wa < $wb:
78
- return -1;
79
- case $wa > $wb:
80
- return 1;
81
- default:
82
- return 0;
83
- }
84
- }
85
-
86
- /**
87
- * Wordpress Action
88
- */
89
- public function AddAdminMenus(){
90
- $this->ReorderViews();
91
-
92
- if($this->_plugin->settings->CurrentUserCan('view') && count($this->views)){
93
- // add main menu
94
- $this->views[0]->hook_suffix = add_menu_page(
95
- 'WP Security Audit Log',
96
- 'Audit Log',
97
- 'read', // no capability requirement
98
- $this->views[0]->GetSafeViewName(),
99
- array($this, 'RenderViewBody'),
100
- $this->views[0]->GetIcon(),
101
- '2.5' // right after dashboard
102
- );
103
 
104
- // add menu items
105
- foreach($this->views as $view){
106
- if($view->IsAccessible()){
107
- $view->hook_suffix = add_submenu_page(
108
- $view->IsVisible() ? $this->views[0]->GetSafeViewName() : null,
109
- $view->GetTitle(),
110
- $view->GetName(),
111
- 'read', // no capability requirement
112
- $view->GetSafeViewName(),
113
- array($this, 'RenderViewBody'),
114
- $view->GetIcon()
115
- );
116
- }
117
- }
118
- }
119
- }
120
-
121
- /**
122
- * Wordpress Filter
123
- */
124
- public function AddPluginShortcuts($old_links){
125
- $this->ReorderViews();
126
-
127
- $new_links = array();
128
- foreach($this->views as $view){
129
- if($view->HasPluginShortcutLink()){
130
- $new_links[] =
131
- '<a href="'
132
- . admin_url('admin.php?page='
133
- . $view->GetSafeViewName()
134
- ) . '">'
135
- . $view->GetName()
136
- . '</a>';
137
- }
138
- }
139
- return array_merge($new_links, $old_links);
140
- }
141
-
142
- /**
143
- * @return int Returns page id of current page (or false on error).
144
- */
145
- protected function GetBackendPageIndex(){
146
- if(isset($_REQUEST['page']))
147
- foreach($this->views as $i => $view)
148
- if($_REQUEST['page'] == $view->GetSafeViewName())
149
- return $i;
150
- return false;
151
- }
152
-
153
- /**
154
- *
155
- * @var WSAL_AbstractView|null
156
- */
157
- protected $_active_view = false;
158
-
159
- /**
160
- * @return WSAL_AbstractView|null Returns the current active view or null if none.
161
- */
162
- public function GetActiveView(){
163
- if($this->_active_view === false){
164
- $this->_active_view = null;
165
-
166
- if(isset($_REQUEST['page']))
167
- foreach($this->views as $view)
168
- if($_REQUEST['page'] == $view->GetSafeViewName())
169
- $this->_active_view = $view;
170
-
171
- if($this->_active_view)
172
- $this->_active_view->is_active = true;
173
- }
174
- return $this->_active_view;
175
- }
176
-
177
- /**
178
- * Render header of the current view.
179
- */
180
- public function RenderViewHeader(){
181
- if (!!($view = $this->GetActiveView())) $view->Header();
182
- }
183
-
184
- /**
185
- * Render footer of the current view.
186
- */
187
- public function RenderViewFooter(){
188
- if (!!($view = $this->GetActiveView())) $view->Footer();
189
- }
190
-
191
- /**
192
- * Render content of the current view.
193
- */
194
- public function RenderViewBody(){
195
- $view = $this->GetActiveView();
196
- ?><div class="wrap"><?php
197
- $view->RenderIcon();
198
- $view->RenderTitle();
199
- $view->RenderContent();
200
- ?></div><?php
201
- }
202
-
203
- /**
204
- * Returns view instance corresponding to its class name.
205
- * @param string $className View class name.
206
- * @return WSAL_AbstractView The view or false on failure.
207
- */
208
- public function FindByClassName($className){
209
- foreach($this->views as $view)
210
- if($view instanceof $className)
211
- return $view;
212
- return false;
213
- }
214
-
215
  }
1
  <?php
2
 
3
  class WSAL_ViewManager {
4
+
5
+ /**
6
+ * @var WSAL_AbstractView[]
7
+ */
8
+ public $views = array();
9
+
10
+ /**
11
+ * @var WpSecurityAuditLog
12
+ */
13
+ protected $_plugin;
14
 
15
+ public function __construct(WpSecurityAuditLog $plugin){
16
+ $this->_plugin = $plugin;
17
+
18
+ // load views
19
+ foreach(glob(dirname(__FILE__) . '/Views/*.php') as $file)
20
+ $this->AddFromFile($file);
21
+
22
+ // add menus
23
+ add_action('admin_menu', array($this, 'AddAdminMenus'));
24
+ add_action('network_admin_menu', array($this, 'AddAdminMenus'));
25
+
26
+ // add plugin shortcut links
27
+ add_filter('plugin_action_links_' . $plugin->GetBaseName(), array($this, 'AddPluginShortcuts'));
28
+
29
+ // render header
30
+ add_action('admin_enqueue_scripts', array($this, 'RenderViewHeader'));
31
+
32
+ // render footer
33
+ add_action('admin_footer', array($this, 'RenderViewFooter'));
34
+ }
35
+
36
+ /**
37
+ * Add new view from file inside autoloader path.
38
+ * @param string $file Path to file.
39
+ */
40
+ public function AddFromFile($file){
41
+ $this->AddFromClass($this->_plugin->GetClassFileClassName($file));
42
+ }
43
+
44
+ /**
45
+ * Add new view given class name.
46
+ * @param string $class Class name.
47
+ */
48
+ public function AddFromClass($class){
49
+ $this->AddInstance(new $class($this->_plugin));
50
+ }
51
+
52
+ /**
53
+ * Add newly created view to list.
54
+ * @param WSAL_AbstractView $view The new view.
55
+ */
56
+ public function AddInstance(WSAL_AbstractView $view){
57
+ $this->views[] = $view;
58
+ }
59
+
60
+ /**
61
+ * Order views by their declared weight.
62
+ */
63
+ public function ReorderViews(){
64
+ usort($this->views, array($this, 'OrderByWeight'));
65
+ }
66
+
67
+ /**
68
+ * @internal This has to be public for PHP to call it.
69
+ * @param WSAL_AbstractView $a
70
+ * @param WSAL_AbstractView $b
71
+ * @return int
72
+ */
73
+ public function OrderByWeight(WSAL_AbstractView $a, WSAL_AbstractView $b){
74
+ $wa = $a->GetWeight();
75
+ $wb = $b->GetWeight();
76
+ switch(true){
77
+ case $wa < $wb:
78
+ return -1;
79
+ case $wa > $wb:
80
+ return 1;
81
+ default:
82
+ return 0;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Wordpress Action
88
+ */
89
+ public function AddAdminMenus(){
90
+ $this->ReorderViews();
91
+
92
+ if($this->_plugin->settings->CurrentUserCan('view') && count($this->views)){
93
+ // add main menu
94
+ $this->views[0]->hook_suffix = add_menu_page(
95
+ 'WP Security Audit Log',
96
+ 'Audit Log',
97
+ 'read', // no capability requirement
98
+ $this->views[0]->GetSafeViewName(),
99
+ array($this, 'RenderViewBody'),
100
+ $this->views[0]->GetIcon(),
101
+ '2.5' // right after dashboard
102
+ );
103
 
104
+ // add menu items
105
+ foreach($this->views as $view){
106
+ if($view->IsAccessible()){
107
+ $view->hook_suffix = add_submenu_page(
108
+ $view->IsVisible() ? $this->views[0]->GetSafeViewName() : null,
109
+ $view->GetTitle(),
110
+ $view->GetName(),
111
+ 'read', // no capability requirement
112
+ $view->GetSafeViewName(),
113
+ array($this, 'RenderViewBody'),
114
+ $view->GetIcon()
115
+ );
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Wordpress Filter
123
+ */
124
+ public function AddPluginShortcuts($old_links){
125
+ $this->ReorderViews();
126
+
127
+ $new_links = array();
128
+ foreach($this->views as $view){
129
+ if($view->HasPluginShortcutLink()){
130
+ $new_links[] =
131
+ '<a href="'
132
+ . admin_url('admin.php?page='
133
+ . $view->GetSafeViewName()
134
+ ) . '">'
135
+ . $view->GetName()
136
+ . '</a>';
137
+ }
138
+ }
139
+ return array_merge($new_links, $old_links);
140
+ }
141
+
142
+ /**
143
+ * @return int Returns page id of current page (or false on error).
144
+ */
145
+ protected function GetBackendPageIndex(){
146
+ if(isset($_REQUEST['page']))
147
+ foreach($this->views as $i => $view)
148
+ if($_REQUEST['page'] == $view->GetSafeViewName())
149
+ return $i;
150
+ return false;
151
+ }
152
+
153
+ /**
154
+ *
155
+ * @var WSAL_AbstractView|null
156
+ */
157
+ protected $_active_view = false;
158
+
159
+ /**
160
+ * @return WSAL_AbstractView|null Returns the current active view or null if none.
161
+ */
162
+ public function GetActiveView(){
163
+ if($this->_active_view === false){
164
+ $this->_active_view = null;
165
+
166
+ if(isset($_REQUEST['page']))
167
+ foreach($this->views as $view)
168
+ if($_REQUEST['page'] == $view->GetSafeViewName())
169
+ $this->_active_view = $view;
170
+
171
+ if($this->_active_view)
172
+ $this->_active_view->is_active = true;
173
+ }
174
+ return $this->_active_view;
175
+ }
176
+
177
+ /**
178
+ * Render header of the current view.
179
+ */
180
+ public function RenderViewHeader(){
181
+ if (!!($view = $this->GetActiveView())) $view->Header();
182
+ }
183
+
184
+ /**
185
+ * Render footer of the current view.
186
+ */
187
+ public function RenderViewFooter(){
188
+ if (!!($view = $this->GetActiveView())) $view->Footer();
189
+ }
190
+
191
+ /**
192
+ * Render content of the current view.
193
+ */
194
+ public function RenderViewBody(){
195
+ $view = $this->GetActiveView();
196
+ ?><div class="wrap"><?php
197
+ $view->RenderIcon();
198
+ $view->RenderTitle();
199
+ $view->RenderContent();
200
+ ?></div><?php
201
+ }
202
+
203
+ /**
204
+ * Returns view instance corresponding to its class name.
205
+ * @param string $className View class name.
206
+ * @return WSAL_AbstractView The view or false on failure.
207
+ */
208
+ public function FindByClassName($className){
209
+ foreach($this->views as $view)
210
+ if($view instanceof $className)
211
+ return $view;
212
+ return false;
213
+ }
214
+
215
  }
classes/Views/About.php CHANGED
@@ -15,7 +15,7 @@ class WSAL_Views_About extends WSAL_AbstractView {
15
  }
16
 
17
  public function GetWeight(){
18
- return 4;
19
  }
20
 
21
  public function Render(){
15
  }
16
 
17
  public function GetWeight(){
18
+ return 6;
19
  }
20
 
21
  public function Render(){
classes/Views/AuditLog.php CHANGED
@@ -1,193 +1,177 @@
1
  <?php
2
 
3
  class WSAL_Views_AuditLog extends WSAL_AbstractView {
4
- /**
5
- * @var WSAL_AuditLogListView
6
- */
7
- protected $_listview;
8
-
9
- public function __construct(WpSecurityAuditLog $plugin) {
10
- parent::__construct($plugin);
11
- add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
12
- add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
13
- add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
14
- add_action('wp_ajax_AjaxSearchSite', array($this, 'AjaxSearchSite'));
15
- add_action('all_admin_notices', array($this, 'AdminNoticesNotificationsExtension'));
16
-
17
- $this->RegisterNotice('notifications-extension');
18
- }
19
-
20
- public function AdminNoticesNotificationsExtension() {
21
- $NotificationExtensionInstalled = $this->_plugin->licensing->IsLicenseValid('wsal-notifications-extension.php');
22
- $IsCurrentView = $this->_plugin->views->GetActiveView() == $this;
23
- if($IsCurrentView && !$this->IsNoticeDismissed('notifications-extension') && !$NotificationExtensionInstalled){
24
- ?><div class="updated" data-notice-name="notifications-extension">
25
- <p><?php _e('Get notified instantly via email of important changes on your WordPress', 'wp-security-audit-log'); ?></p>
26
- <p>
27
- <?php $url = 'http://www.wpsecurityauditlog.com/extensions/wordpress-email-notifications-add-on/?utm_source=plugin&utm_medium=auditlogviewer&utm_campaign=notifications'; ?>
28
- <a href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Learn More', 'wp-security-audit-log'); ?></a>
29
- | <a href="javascript:;" class="wsal-dismiss-notification"><?php _e('Dismiss this notice', 'wp-security-audit-log'); ?></a>
30
- </p>
31
- </div><?php
32
- }
33
- }
34
-
35
- public function HasPluginShortcutLink(){
36
- return true;
37
- }
38
-
39
- public function GetTitle() {
40
- return __('Audit Log Viewer', 'wp-security-audit-log');
41
- }
42
-
43
- public function GetIcon() {
44
- return $this->_wpversion < 3.8
45
- ? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
46
- : 'dashicons-welcome-view-site';
47
- }
48
-
49
- public function GetName() {
50
- return __('Audit Log Viewer', 'wp-security-audit-log');
51
- }
52
-
53
- public function GetWeight(){
54
- return 1;
55
- }
56
-
57
- protected function GetListView(){
58
- if (is_null($this->_listview)) $this->_listview = new WSAL_AuditLogListView($this->_plugin);
59
- return $this->_listview;
60
- }
61
-
62
- public function Render(){
63
- if(!$this->_plugin->settings->CurrentUserCan('view')){
64
- wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
65
- }
66
-
67
- $this->GetListView()->prepare_items();
68
- $occ = new WSAL_Models_Occurrence();
69
-
70
- ?><form id="audit-log-viewer" method="post">
71
- <div id="audit-log-viewer-content">
72
- <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
73
- <input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr(isset($_REQUEST['wsal-cbid']) ? $_REQUEST['wsal-cbid'] : '0'); ?>" />
74
- <?php do_action('wsal_auditlog_before_view', $this->GetListView()); ?>
75
- <?php $this->GetListView()->display(); ?>
76
- <?php do_action('wsal_auditlog_after_view', $this->GetListView()); ?>
77
- </div>
78
- </form><?php
79
-
80
- ?><script type="text/javascript">
81
- jQuery(document).ready(function(){
82
- WsalAuditLogInit(<?php echo json_encode(array(
83
- 'ajaxurl' => admin_url('admin-ajax.php'),
84
- 'tr8n' => array(
85
- 'numofitems' => __('Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log'),
86
- 'searchback' => __('All Sites', 'wp-security-audit-log'),
87
- 'searchnone' => __('No Results', 'wp-security-audit-log'),
88
- ),
89
- 'autorefresh' => array(
90
- 'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
91
- 'token' => (int)$occ->Count(),
92
- ),
93
- )); ?>);
94
- });
95
- </script><?php
96
- }
97
-
98
- public function AjaxInspector(){
99
- if(!$this->_plugin->settings->CurrentUserCan('view'))
100
- die('Access Denied.');
101
- if(!isset($_REQUEST['occurrence']))
102
- die('Occurrence parameter expected.');
103
- $occ = new WSAL_Models_Occurrence();
104
- $occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
105
 
106
- echo '<!DOCTYPE html><html><head>';
107
- echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
108
- echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
109
- echo '<style type="text/css">';
110
- echo 'html, body { margin: 0; padding: 0; }';
111
- echo '.nice_r { position: absolute; padding: 8px; }';
112
- echo '.nice_r a { overflow: visible; }';
113
- echo '</style>';
114
- echo '</head><body>';
115
- $nicer = new WSAL_Nicer($occ->GetMetaArray());
116
- $nicer->render();
117
- echo '</body></html>';
118
- die;
119
- }
120
-
121
- public function AjaxRefresh(){
122
- if(!$this->_plugin->settings->CurrentUserCan('view'))
123
- die('Access Denied.');
124
- if(!isset($_REQUEST['logcount']))
125
- die('Log count parameter expected.');
126
-
127
- $old = (int)$_REQUEST['logcount'];
128
- $max = 40; // 40*500msec = 20sec
129
-
130
- session_write_close(); // fixes session lock issue
131
-
132
- do{
133
- $occ = new WSAL_Models_Occurrence();
134
- $new = $occ->Count();
135
- usleep(500000); // 500msec
136
- }while(($old == $new) && (--$max > 0));
137
-
138
- echo $old == $new ? 'false' : $new;
139
- die;
140
- }
141
-
142
- public function AjaxSetIpp(){
143
- if(!$this->_plugin->settings->CurrentUserCan('view'))
144
- die('Access Denied.');
145
- if(!isset($_REQUEST['count']))
146
- die('Count parameter expected.');
147
- $this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
148
- die;
149
- }
150
-
151
- public function AjaxSearchSite(){
152
- if(!$this->_plugin->settings->CurrentUserCan('view'))
153
- die('Access Denied.');
154
- if(!isset($_REQUEST['search']))
155
- die('Search parameter expected.');
156
-
157
- $grp1 = array();
158
- $grp2 = array();
159
-
160
- $search = $_REQUEST['search'];
161
-
162
- foreach($this->GetListView()->get_sites() as $site){
163
- if(stripos($site->blogname, $search) !== false)
164
- $grp1[] = $site;
165
- else
166
- if(stripos($site->domain, $search) !== false)
167
- $grp2[] = $site;
168
- }
169
-
170
- die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
171
- }
172
-
173
- public function Header(){
174
- add_thickbox();
175
- wp_enqueue_style(
176
- 'auditlog',
177
- $this->_plugin->GetBaseUrl() . '/css/auditlog.css',
178
- array(),
179
- filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
180
- );
181
- }
182
-
183
- public function Footer() {
184
- wp_enqueue_script('jquery');
185
- wp_enqueue_script('suggest');
186
- wp_enqueue_script(
187
- 'auditlog',
188
- $this->_plugin->GetBaseUrl() . '/js/auditlog.js',
189
- array(),
190
- filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
191
- );
192
- }
193
  }
1
  <?php
2
 
3
  class WSAL_Views_AuditLog extends WSAL_AbstractView {
4
+ /**
5
+ * @var WSAL_AuditLogListView
6
+ */
7
+ protected $_listview;
8
+
9
+ public function __construct(WpSecurityAuditLog $plugin) {
10
+ parent::__construct($plugin);
11
+ add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
12
+ add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
13
+ add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
14
+ add_action('wp_ajax_AjaxSearchSite', array($this, 'AjaxSearchSite'));
15
+
16
+ $this->RegisterNotice('notifications-extension');
17
+ }
18
+
19
+ public function HasPluginShortcutLink(){
20
+ return true;
21
+ }
22
+
23
+ public function GetTitle() {
24
+ return __('Audit Log Viewer', 'wp-security-audit-log');
25
+ }
26
+
27
+ public function GetIcon() {
28
+ return $this->_wpversion < 3.8
29
+ ? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
30
+ : 'dashicons-welcome-view-site';
31
+ }
32
+
33
+ public function GetName() {
34
+ return __('Audit Log Viewer', 'wp-security-audit-log');
35
+ }
36
+
37
+ public function GetWeight(){
38
+ return 1;
39
+ }
40
+
41
+ protected function GetListView(){
42
+ if (is_null($this->_listview)) $this->_listview = new WSAL_AuditLogListView($this->_plugin);
43
+ return $this->_listview;
44
+ }
45
+
46
+ public function Render(){
47
+ if(!$this->_plugin->settings->CurrentUserCan('view')){
48
+ wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
49
+ }
50
+
51
+ $this->GetListView()->prepare_items();
52
+ $occ = new WSAL_Models_Occurrence();
53
+
54
+ ?><form id="audit-log-viewer" method="post">
55
+ <div id="audit-log-viewer-content">
56
+ <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
57
+ <input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr(isset($_REQUEST['wsal-cbid']) ? $_REQUEST['wsal-cbid'] : '0'); ?>" />
58
+ <?php do_action('wsal_auditlog_before_view', $this->GetListView()); ?>
59
+ <?php $this->GetListView()->display(); ?>
60
+ <?php do_action('wsal_auditlog_after_view', $this->GetListView()); ?>
61
+ </div>
62
+ </form><?php
63
+
64
+ ?><script type="text/javascript">
65
+ jQuery(document).ready(function(){
66
+ WsalAuditLogInit(<?php echo json_encode(array(
67
+ 'ajaxurl' => admin_url('admin-ajax.php'),
68
+ 'tr8n' => array(
69
+ 'numofitems' => __('Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log'),
70
+ 'searchback' => __('All Sites', 'wp-security-audit-log'),
71
+ 'searchnone' => __('No Results', 'wp-security-audit-log'),
72
+ ),
73
+ 'autorefresh' => array(
74
+ 'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
75
+ 'token' => (int)$occ->Count(),
76
+ ),
77
+ )); ?>);
78
+ });
79
+ </script><?php
80
+ }
81
+
82
+ public function AjaxInspector(){
83
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
84
+ die('Access Denied.');
85
+ if(!isset($_REQUEST['occurrence']))
86
+ die('Occurrence parameter expected.');
87
+ $occ = new WSAL_Models_Occurrence();
88
+ $occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
+ echo '<!DOCTYPE html><html><head>';
91
+ echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
92
+ echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
93
+ echo '<style type="text/css">';
94
+ echo 'html, body { margin: 0; padding: 0; }';
95
+ echo '.nice_r { position: absolute; padding: 8px; }';
96
+ echo '.nice_r a { overflow: visible; }';
97
+ echo '</style>';
98
+ echo '</head><body>';
99
+ $nicer = new WSAL_Nicer($occ->GetMetaArray());
100
+ $nicer->render();
101
+ echo '</body></html>';
102
+ die;
103
+ }
104
+
105
+ public function AjaxRefresh(){
106
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
107
+ die('Access Denied.');
108
+ if(!isset($_REQUEST['logcount']))
109
+ die('Log count parameter expected.');
110
+
111
+ $old = (int)$_REQUEST['logcount'];
112
+ $max = 40; // 40*500msec = 20sec
113
+
114
+ session_write_close(); // fixes session lock issue
115
+
116
+ do{
117
+ $occ = new WSAL_Models_Occurrence();
118
+ $new = $occ->Count();
119
+ usleep(500000); // 500msec
120
+ }while(($old == $new) && (--$max > 0));
121
+
122
+ echo $old == $new ? 'false' : $new;
123
+ die;
124
+ }
125
+
126
+ public function AjaxSetIpp(){
127
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
128
+ die('Access Denied.');
129
+ if(!isset($_REQUEST['count']))
130
+ die('Count parameter expected.');
131
+ $this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
132
+ die;
133
+ }
134
+
135
+ public function AjaxSearchSite(){
136
+ if(!$this->_plugin->settings->CurrentUserCan('view'))
137
+ die('Access Denied.');
138
+ if(!isset($_REQUEST['search']))
139
+ die('Search parameter expected.');
140
+
141
+ $grp1 = array();
142
+ $grp2 = array();
143
+
144
+ $search = $_REQUEST['search'];
145
+
146
+ foreach($this->GetListView()->get_sites() as $site){
147
+ if(stripos($site->blogname, $search) !== false)
148
+ $grp1[] = $site;
149
+ else
150
+ if(stripos($site->domain, $search) !== false)
151
+ $grp2[] = $site;
152
+ }
153
+
154
+ die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
155
+ }
156
+
157
+ public function Header(){
158
+ add_thickbox();
159
+ wp_enqueue_style(
160
+ 'auditlog',
161
+ $this->_plugin->GetBaseUrl() . '/css/auditlog.css',
162
+ array(),
163
+ filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
164
+ );
165
+ }
166
+
167
+ public function Footer() {
168
+ wp_enqueue_script('jquery');
169
+ wp_enqueue_script('suggest');
170
+ wp_enqueue_script(
171
+ 'auditlog',
172
+ $this->_plugin->GetBaseUrl() . '/js/auditlog.js',
173
+ array(),
174
+ filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
175
+ );
176
+ }
177
  }
classes/Views/Extensions.php CHANGED
@@ -1,62 +1,81 @@
1
  <?php
2
 
3
- class WSAL_Views_Extensions extends WSAL_AbstractView {
4
-
5
- public function GetTitle() {
6
- return __('WP Security Audit Log Add-Ons', 'wp-security-audit-log');
7
- }
8
-
9
- public function GetIcon() {
10
- return 'admin-plugins';
11
- }
12
-
13
- public function GetName() {
14
- return __('Extensions', 'wp-security-audit-log');
15
- }
16
-
17
- public function GetWeight() {
18
- return 3.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
- <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>
28
- </div>
29
-
30
- <div class="activity-block">
31
- <h2><?php _e('Email Notifications Add-On', 'wp-security-audit-log'); ?></h2>
32
- <strong><?php _e('Get notified instantly via email when important changes are made on your WordPress!', 'wp-security-audit-log'); ?></strong>
33
- <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>
34
- <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>
35
- </div>
36
-
37
- <div class="activity-block">
38
- <h2><?php _e('External DB Add-On', 'wp-security-audit-log'); ?></h2>
39
- <strong><?php _e('Save the WordPress Audit Log in an external database.', 'wp-security-audit-log'); ?></strong>
40
- <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>
41
- <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>
42
- </div>
43
-
44
- <div class="activity-block">
45
- <h2><?php _e('Search Add-On', 'wp-security-audit-log'); ?></h2>
46
- <strong><?php _e('Automatically Search for specific WordPress user and site activity in WordPress Security Audit Log.', 'wp-security-audit-log'); ?></strong>
47
- <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>
48
- <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>
49
- </div>
50
-
51
- <div class="activity-block">
52
- <h2><?php _e('Reports Add-Ons', 'wp-security-audit-log'); ?></h2>
53
- <strong><?php _e('Generate User, Site and Regulatory Compliance Reports.', 'wp-security-audit-log'); ?></strong>
54
- <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>
55
- <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>
56
- </div>
57
- </div>
58
- </div>
59
- </div><?php
60
- }
61
-
62
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+
4
+ class WSAL_Views_Extensions extends WSAL_AbstractView
5
+ {
6
+
7
+ public function GetTitle() {
8
+ return __('WP Security Audit Log Add-Ons', 'wp-security-audit-log');
9
+ }
10
+
11
+ public function GetIcon() {
12
+ return 'dashicons-external';
13
+ }
14
+
15
+ public function GetName() {
16
+ return __(' Add Functionality', 'wp-security-audit-log');
17
+ }
18
+
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
+ }
classes/Views/Help.php CHANGED
@@ -1,77 +1,77 @@
1
  <?php
2
 
3
  class WSAL_Views_Help extends WSAL_AbstractView {
4
-
5
- public function GetTitle() {
6
- return __('Help', 'wp-security-audit-log');
7
- }
8
-
9
- public function GetIcon() {
10
- return 'dashicons-sos';
11
- }
12
-
13
- public function GetName() {
14
- return __('Help', 'wp-security-audit-log');
15
- }
16
-
17
- public function GetWeight() {
18
- return 5;
19
- }
20
-
21
- public function Render(){
22
- ?><div class="metabox-holder" style="position: relative;">
23
-
24
- <div class="postbox" style="margin-right: 270px;">
25
- <div class="inside">
26
- <div class="activity-block">
27
- <h2><?php _e('Plugin Support', 'wp-security-audit-log'); ?></h2>
28
- <p>
29
- <?php _e('Have you encountered or noticed any issues while using WP Security Audit Log plugin?', 'wp-security-audit-log'); ?>
30
- <?php _e('Or you want to report something to us? Click any of the options below to post on the plugin\'s forum or contact our support directly.', 'wp-security-audit-log'); ?>
31
- </p><p>
32
- <a class="button" href="https://wordpress.org/support/plugin/wp-security-audit-log" target="_blank"><?php _e('Free Support Forum', 'wp-security-audit-log'); ?></a>
33
- &nbsp;&nbsp;&nbsp;&nbsp;
34
- <a class="button" href="http://www.wpsecurityauditlog.com/contact/" target="_blank"><?php _e('Free Support Email', 'wp-security-audit-log'); ?></a>
35
- </p>
36
- </div>
37
 
38
- <div class="activity-block">
39
- <h2><?php _e('Plugin Documentation', 'wp-security-audit-log'); ?></h2>
40
- <p>
41
- <?php _e('For more detailed information about WP Security Audit Log you can visit the plugin website.', 'wp-security-audit-log'); ?>
42
- <?php _e('You can also visit the official list of WordPress Security Alerts for more information about all of the WordPress activity and changes you can monitor with WP Security Audit Log.', 'wp-security-audit-log'); ?>
43
- </p><p>
44
- <a class="button" href="http://www.wpsecurityauditlog.com/?utm_source=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
45
- &nbsp;&nbsp;&nbsp;&nbsp;
46
- <a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
47
- </p>
48
- </div>
49
 
50
- <div class="">
51
- <h2><?php _e('WordPress Security Blog', 'wp-security-audit-log'); ?></h2>
52
- <p>
53
- <?php _e('New to WordPress security?', 'wp-security-audit-log'); ?>
54
- <?php _e('Do not know from where to start or which is the best services for you?', 'wp-security-audit-log'); ?>
55
- <?php _e('Visit our WordPress security blog or the WordPress Security category directly for more information and a number of tips and tricks about WordPress security.', 'wp-security-audit-log'); ?>
56
- </p>
57
- <a class="button" href="http://www.wpwhitesecurity.com/blog/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WP White Security Blog', 'wp-security-audit-log'); ?></a>
58
- &nbsp;&nbsp;&nbsp;&nbsp;
59
- <a class="button" href="http://www.wpwhitesecurity.com/wordpress-security/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WordPress Security Category', 'wp-security-audit-log'); ?></a>
60
- </div>
61
- </div>
62
- </div>
63
 
64
- <div style="position: absolute; right: 70px; width: 180px; top: 10px;">
65
- <div class="postbox">
66
- <h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
67
- <div class="inside">
68
- <?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
69
- <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
70
- </div>
71
- </div>
72
- </div>
73
-
74
- </div><?php
75
- }
76
-
77
  }
1
  <?php
2
 
3
  class WSAL_Views_Help extends WSAL_AbstractView {
4
+
5
+ public function GetTitle() {
6
+ return __('Help', 'wp-security-audit-log');
7
+ }
8
+
9
+ public function GetIcon() {
10
+ return 'dashicons-sos';
11
+ }
12
+
13
+ public function GetName() {
14
+ return __('Help', 'wp-security-audit-log');
15
+ }
16
+
17
+ public function GetWeight() {
18
+ return 5;
19
+ }
20
+
21
+ public function Render(){
22
+ ?><div class="metabox-holder" style="position: relative;">
23
+
24
+ <div class="postbox" style="margin-right: 270px;">
25
+ <div class="inside">
26
+ <div class="activity-block">
27
+ <h2><?php _e('Plugin Support', 'wp-security-audit-log'); ?></h2>
28
+ <p>
29
+ <?php _e('Have you encountered or noticed any issues while using WP Security Audit Log plugin?', 'wp-security-audit-log'); ?>
30
+ <?php _e('Or you want to report something to us? Click any of the options below to post on the plugin\'s forum or contact our support directly.', 'wp-security-audit-log'); ?>
31
+ </p><p>
32
+ <a class="button" href="https://wordpress.org/support/plugin/wp-security-audit-log" target="_blank"><?php _e('Free Support Forum', 'wp-security-audit-log'); ?></a>
33
+ &nbsp;&nbsp;&nbsp;&nbsp;
34
+ <a class="button" href="http://www.wpsecurityauditlog.com/contact/" target="_blank"><?php _e('Free Support Email', 'wp-security-audit-log'); ?></a>
35
+ </p>
36
+ </div>
37
 
38
+ <div class="activity-block">
39
+ <h2><?php _e('Plugin Documentation', 'wp-security-audit-log'); ?></h2>
40
+ <p>
41
+ <?php _e('For more detailed information about WP Security Audit Log you can visit the plugin website.', 'wp-security-audit-log'); ?>
42
+ <?php _e('You can also visit the official list of WordPress Security Alerts for more information about all of the WordPress activity and changes you can monitor with WP Security Audit Log.', 'wp-security-audit-log'); ?>
43
+ </p><p>
44
+ <a class="button" href="http://www.wpsecurityauditlog.com/?utm_source=wpsalabt&utm_medium=txtlink&utm_campaign=wpsal" target="_blank"><?php _e('Plugin Website', 'wp-security-audit-log'); ?></a>
45
+ &nbsp;&nbsp;&nbsp;&nbsp;
46
+ <a class="button" href="http://www.wpsecurityauditlog.com/documentation/list-monitoring-wordpress-security-alerts-audit-log/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('List of WordPress Security Alerts', 'wp-security-audit-log'); ?></a>
47
+ </p>
48
+ </div>
49
 
50
+ <div class="">
51
+ <h2><?php _e('WordPress Security Blog', 'wp-security-audit-log'); ?></h2>
52
+ <p>
53
+ <?php _e('New to WordPress security?', 'wp-security-audit-log'); ?>
54
+ <?php _e('Do not know from where to start or which is the best services for you?', 'wp-security-audit-log'); ?>
55
+ <?php _e('Visit our WordPress security blog or the WordPress Security category directly for more information and a number of tips and tricks about WordPress security.', 'wp-security-audit-log'); ?>
56
+ </p>
57
+ <a class="button" href="http://www.wpwhitesecurity.com/blog/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WP White Security Blog', 'wp-security-audit-log'); ?></a>
58
+ &nbsp;&nbsp;&nbsp;&nbsp;
59
+ <a class="button" href="http://www.wpwhitesecurity.com/wordpress-security/?utm_source=wsalabt&utm_medium=txtlink&utm_campaign=wsal" target="_blank"><?php _e('WordPress Security Category', 'wp-security-audit-log'); ?></a>
60
+ </div>
61
+ </div>
62
+ </div>
63
 
64
+ <div style="position: absolute; right: 70px; width: 180px; top: 10px;">
65
+ <div class="postbox">
66
+ <h3 class="hndl"><span><?php _e('WP Security Audit Log in your Language!', 'wp-security-audit-log'); ?></span></h3>
67
+ <div class="inside">
68
+ <?php _e('If you are interested in translating our plugin please drop us an email on', 'wp-security-audit-log'); ?>
69
+ <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a>.
70
+ </div>
71
+ </div>
72
+ </div>
73
+
74
+ </div><?php
75
+ }
76
+
77
  }
classes/Views/ToggleAlerts.php CHANGED
@@ -1,143 +1,150 @@
1
  <?php
2
- class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
3
-
4
- public function GetTitle() {
5
- return __('Enable/Disable Alerts', 'wp-security-audit-log');
6
- }
7
-
8
- public function GetIcon() {
9
- return 'dashicons-forms';
10
- }
11
-
12
- public function GetName() {
13
- return __('Enable/Disable Alerts', 'wp-security-audit-log');
14
- }
15
-
16
- public function GetWeight() {
17
- return 2;
18
- }
19
-
20
- protected function GetSafeCatgName($name){
21
- return strtolower(
22
- preg_replace('/[^A-Za-z0-9\-]/', '-', $name)
23
- );
24
- }
25
-
26
- public function Render(){
27
- if(!$this->_plugin->settings->CurrentUserCan('edit')){
28
- wp_die( __( 'You do not have sufficient permissions to access this page.' , 'wp-security-audit-log') );
29
- }
30
- $alert = new WSAL_Alert(); // IDE type hinting
31
- $groupedAlerts = $this->_plugin->alerts->GetCategorizedAlerts();
32
- $safeNames = array_map(array($this, 'GetSafeCatgName'), array_keys($groupedAlerts));
33
- $safeNames = array_combine(array_keys($groupedAlerts), $safeNames);
34
- if(isset($_POST['submit']) && isset($_POST['alert'])){
35
- check_admin_referer('wsal-togglealerts');
36
- try {
37
- $enabled = array_map('intval', $_POST['alert']);
38
- $disabled = array();
39
- foreach($this->_plugin->alerts->GetAlerts() as $alert)
40
- if(!in_array($alert->type, $enabled))
41
- $disabled[] = $alert->type;
42
- $this->_plugin->alerts->SetDisabledAlerts($disabled);
43
- ?><div class="updated"><p><?php _e('Settings have been saved.', 'wp-security-audit-log'); ?></p></div><?php
44
- }catch(Exception $ex){
45
- ?><div class="error"><p><?php _e('Error: ', 'wp-security-audit-log'); ?><?php echo $ex->getMessage(); ?></p></div><?php
46
- }
47
- }
48
- ?><h2 id="wsal-tabs" class="nav-tab-wrapper"><?php
49
- foreach($safeNames as $name => $safe){
50
- ?><a href="#tab-<?php echo $safe; ?>" class="nav-tab"><?php echo $name; ?></a><?php
51
- }
52
- ?></h2>
53
- <form id="audit-log-viewer" method="post">
54
- <input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>" />
55
- <?php wp_nonce_field('wsal-togglealerts'); ?>
56
-
57
- <div class="nav-tabs"><?php
58
- foreach($groupedAlerts as $name => $alerts){
59
- $active = array(); $allactive = true;
60
- foreach($alerts as $alert){
61
- if ($alert->type <= 0006) continue; // <- ignore php alerts
62
- $active[$alert->type] = $this->_plugin->alerts->IsEnabled($alert->type);
63
- if (!$active[$alert->type]) $allactive = false;
64
- }
65
- ?><table class="wp-list-table wsal-tab widefat fixed" cellspacing="0" id="tab-<?php echo $safeNames[$name]; ?>">
66
- <thead>
67
- <tr>
68
- <th width="48"><input type="checkbox"<?php if($allactive)echo 'checked="checked"'; ?>/></th>
69
- <th width="80"><?php _e('Code', 'wp-security-audit-log'); ?></th>
70
- <th width="100"><?php _e('Type', 'wp-security-audit-log'); ?></th>
71
- <th><?php _e('Description', 'wp-security-audit-log'); ?></th>
72
- </tr>
73
- </thead>
74
- <tbody><?php
75
- foreach($alerts as $alert){
76
- if ($alert->type <= 0006) continue; // <- ignore php alerts
77
- $attrs = '';
78
- switch(true){
79
- case !$alert->mesg:
80
- $attrs = ' title="'. __('Not Implemented', 'wp-security-audit-log') . '" class="alert-incomplete"';
81
- break;
82
- case false:
83
- $attrs = ' title="'. __('Not Available', 'wp-security-audit-log') . '" class="alert-unavailable"';
84
- break;
85
- }
86
- ?><tr<?php echo $attrs; ?>>
87
- <th><input name="alert[]" type="checkbox" <?php if($active[$alert->type])echo 'checked="checked"'; ?> value="<?php echo (int)$alert->type; ?>"></th>
88
- <td><?php echo str_pad($alert->type, 4, '0', STR_PAD_LEFT); ?></td>
89
- <td><?php echo $this->_plugin->constants->GetConstantBy('value', $alert->code)->name; ?></td>
90
- <td><?php echo esc_html($alert->desc); ?></td>
91
- </tr><?php
92
- }
93
- ?></tbody>
94
- </table><?php
95
- }
96
- ?></div>
97
- <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>
98
- </form><?php
99
- }
100
-
101
- public function Header() {
102
- ?><style type="text/css">
103
- .wsal-tab {
104
- display: none;
105
- }
106
- .wsal-tab tr.alert-incomplete td {
107
- color: #9BE;
108
- }
109
- .wsal-tab tr.alert-unavailable td {
110
- color: #CCC;
111
- }
112
- </style><?php
113
- }
114
-
115
- public function Footer() {
116
- ?><script type="text/javascript">
117
- jQuery(document).ready(function(){
118
- // tab handling code
119
- jQuery('#wsal-tabs>a').click(function(){
120
- jQuery('#wsal-tabs>a').removeClass('nav-tab-active');
121
- jQuery('table.wsal-tab').hide();
122
- jQuery(jQuery(this).addClass('nav-tab-active').attr('href')).show();
123
- });
124
- // checkbox handling code
125
- jQuery('table.wsal-tab>thead>tr>th>:checkbox').change(function(){
126
- jQuery(this).parents('table:first').find('tbody>tr>th>:checkbox').attr('checked', this.checked);
127
- });
128
- jQuery('table.wsal-tab>tbody>tr>th>:checkbox').change(function(){
129
- var allchecked = jQuery(this).parents('tbody:first').find('th>:checkbox:not(:checked)').length === 0;
130
- jQuery(this).parents('table:first').find('thead>tr>th:first>:checkbox:first').attr('checked', allchecked);
131
- });
132
- // show relevant tab
133
- var hashlink = jQuery('#wsal-tabs>a[href="' + location.hash + '"]');
134
- if(hashlink.length){
135
- hashlink.click();
136
- }else{
137
- jQuery('#wsal-tabs>a:first').click();
138
- }
139
- });
140
- </script><?php
141
- }
142
-
 
 
 
 
 
 
 
143
  }
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,61 +1,79 @@
1
  <?php
2
 
3
- class WSAL_WidgetManager {
4
- /**
5
- * @var WpSecurityAuditLog
6
- */
7
- protected $_plugin;
8
-
9
- public function __construct(WpSecurityAuditLog $plugin){
10
- $this->_plugin = $plugin;
11
- add_action('wp_dashboard_setup', array($this, 'AddWidgets'));
12
- }
13
-
14
- public function AddWidgets(){
15
- if($this->_plugin->settings->IsWidgetsEnabled()
16
- && $this->_plugin->settings->CurrentUserCan('view')){
17
- wp_add_dashboard_widget(
18
- 'wsal',
19
- __('Latest Alerts', 'wp-security-audit-log') . ' | WP Security Audit Log',
20
- array($this, 'RenderWidget')
21
- );
22
- }
23
- }
24
-
25
- public function RenderWidget(){
26
- $query = new WSAL_Models_OccurrenceQuery();
27
- $query->addOrderBy("created_on", true);
28
- $query->setLimit($this->_plugin->settings->GetDashboardWidgetMaxAlerts());
29
- $results = $query->getAdapter()->Execute($query);
30
-
31
- ?><div><?php
32
- if(!count($results)){
33
- ?><p><?php _e('No alerts found.', 'wp-security-audit-log'); ?></p><?php
34
- }else{
35
- ?><table class="wp-list-table widefat" cellspacing="0" cellpadding="0"
36
- style="display: block; overflow-x: auto;">
37
- <thead>
38
- <th class="manage-column" style="width: 15%;" scope="col"><?php _e('User', 'wp-security-audit-log'); ?></th>
39
- <th class="manage-column" style="width: 85%;" scope="col"><?php _e('Description', 'wp-security-audit-log'); ?></th>
40
- </thead>
41
- <tbody><?php
42
- $url = 'admin.php?page=' . $this->_plugin->views->views[0]->GetSafeViewName();
43
- $fmt = array(new WSAL_AuditLogListView($this->_plugin), 'meta_formatter');
44
- foreach($results as $entry){
45
- ?><tr>
46
- <td><?php
47
- echo ($un = $entry->GetUsername()) ? esc_html($un) : '<i>unknown</i>';
48
- ?></td>
49
- <td>
50
- <a href="<?php echo $url . '#Event' . $entry->id; ?>"><?php
51
- echo $entry->GetMessage($fmt);
52
- ?></a>
53
- </td>
54
- </tr><?php
55
- }
56
- ?></tbody>
57
- </table><?php
58
- }
59
- ?></div><?php
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
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
  }
defaults.php CHANGED
@@ -131,6 +131,7 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
131
  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')),
132
  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')),
133
  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')),
 
134
  ),
135
  __('Plugins & Themes', 'wp-security-audit-log') => array(
136
  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')),
@@ -155,6 +156,7 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
155
  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')),
156
  array(6004, E_CRITICAL, __('WordPress was updated', 'wp-security-audit-log'), __('Updated WordPress from version %OldVersion% to %NewVersion%', 'wp-security-audit-log')),
157
  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')),
 
158
  ),
159
  __('MultiSite', 'wp-security-audit-log') => array(
160
  array(4008, E_CRITICAL, __('User granted Super Admin privileges', 'wp-security-audit-log'), __('Granted Super Admin privileges to %TargetUsername%', 'wp-security-audit-log')),
@@ -182,6 +184,31 @@ function wsaldefaults_wsal_init(WpSecurityAuditLog $wsal){
182
  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')),
183
  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')),
184
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  ));
186
  }
187
  add_action('wsal_init', 'wsaldefaults_wsal_init');
131
  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')),
132
  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')),
133
  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')),
134
+ 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')),
135
  ),
136
  __('Plugins & Themes', 'wp-security-audit-log') => array(
137
  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')),
156
  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')),
157
  array(6004, E_CRITICAL, __('WordPress was updated', 'wp-security-audit-log'), __('Updated WordPress from version %OldVersion% to %NewVersion%', 'wp-security-audit-log')),
158
  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')),
159
+ array(9999, E_CRITICAL, __('Advertising Add-ons.', 'wp-security-audit-log'), __('%PromoMessage%', 'wp-security-audit-log')),
160
  ),
161
  __('MultiSite', 'wp-security-audit-log') => array(
162
  array(4008, E_CRITICAL, __('User granted Super Admin privileges', 'wp-security-audit-log'), __('Granted Super Admin privileges to %TargetUsername%', 'wp-security-audit-log')),
184
  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')),
185
  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')),
186
  ),
187
+ __('BBPress Forum', 'wp-security-audit-log') => array(
188
+ array(8000, E_CRITICAL, __('User created new forum', 'wp-security-audit-log'), __('Created new forum %ForumName%. Forum URL is %ForumURL%', 'wp-security-audit-log')),
189
+ 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')),
190
+ 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')),
191
+ 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')),
192
+ 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')),
193
+ 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')),
194
+ array(8006, E_WARNING, __('User permanently deleted forum', 'wp-security-audit-log'), __('Permanently deleted forum %ForumName%', 'wp-security-audit-log')),
195
+ array(8007, E_WARNING, __('User restored forum from trash', 'wp-security-audit-log'), __('Restored forum %ForumName% from trash', 'wp-security-audit-log')),
196
+ 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')),
197
+ 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')),
198
+ 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')),
199
+ 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')),
200
+ 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')),
201
+ 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')),
202
+ array(8014, E_NOTICE, __('User created new topic', 'wp-security-audit-log'), __('Created new topic %TopicName%. Topic URL is %TopicURL%', 'wp-security-audit-log')),
203
+ 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')),
204
+ 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')),
205
+ 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')),
206
+ 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')),
207
+ 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')),
208
+ array(8020, E_WARNING, __('User permanently deleted topic', 'wp-security-audit-log'), __('Permanently deleted topic %TopicName%', 'wp-security-audit-log')),
209
+ array(8021, E_WARNING, __('User restored topic from trash', 'wp-security-audit-log'), __('Restored topic %TopicName% from trash', 'wp-security-audit-log')),
210
+ 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')),
211
+ )
212
  ));
213
  }
214
  add_action('wsal_init', 'wsaldefaults_wsal_init');
img/plugin-logo.png ADDED
Binary file
js/common.js CHANGED
@@ -11,4 +11,7 @@ jQuery(document).ready(function(){
11
  });
12
  nfe.fadeOut();
13
  });
 
 
 
14
  });
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
  });
readme.txt CHANGED
@@ -6,10 +6,10 @@ License: GPLv3
6
  License URI: http://www.gnu.org/licenses/gpl.html
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report
8
  Requires at least: 3.6
9
- Tested up to: 4.3.1
10
- Stable tag: 2.2
11
 
12
- Keep an audit log of all changes and under the hood WordPress activity to ensure productivity and thwart possible WordPress hacker attacks.
13
 
14
  == Description ==
15
  Keep an audit log of everything that is happening on your WordPress and [WordPress multisite](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/) with WP Security Audit Log to ensure user productivity and identify WordPress security issues before they become a security problem. WP Security Audit Log, WordPress' most comprehensive user monitoring and audit log plugin already helps thousands of WordPress administrators, owners and security professionals ensure the security of their websites and blogs. Ensure the security of your WordPress too by installing WP Security Audit Log. The community's favourite WordPress user monitoring monitoring and security auditing plugin is developed by WordPress Security Consultants and Professionals [WP White Security](http://www.wpwhitesecurity.com/).
@@ -121,6 +121,7 @@ WP Security Audit Log plugin also has a number of features that make WordPress a
121
  * [WPLift](http://wplift.com/wordpress-event-tracking)
122
  * [Tourqe News](http://torquemag.io/5-awesome-wordpress-plugins-you-may-not-have-heard-of/)
123
  * [Shout Me Loud](http://www.shoutmeloud.com/how-to-monitor-user-activities-wordpress-dashboard.html)
 
124
  * [The Darknet](http://www.darknet.org.uk/2015/10/wp-security-audit-log-a-complete-audit-log-plugin-for-wordpress/)
125
 
126
  = WordPress Security Audit Log in your Language! =
@@ -202,6 +203,42 @@ Yes. To exclude an IP address you can specify it in the Excluded Objects section
202
 
203
  == Changelog ==
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  = 2.2 (2015-11-10) =
206
  * **New Features**
207
  * Aded the revision link in content change security alerts allowing you to see the actual content changes that took place on posts, pages and custom post types. [Learn More](http://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/record-all-wordpress-content-changes-wp-security-audit-log-plugin/)
6
  License URI: http://www.gnu.org/licenses/gpl.html
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report
8
  Requires at least: 3.6
9
+ Tested up to: 4.4.1
10
+ Stable tag: 2.3
11
 
12
+ Keep an audit trail of all changes and under the hood WordPress activity to ensure productivity and thwart possible WordPress hacker attacks.
13
 
14
  == Description ==
15
  Keep an audit log of everything that is happening on your WordPress and [WordPress multisite](http://www.wpsecurityauditlog.com/documentation/wordpress-multisite-plugin-features-support/) with WP Security Audit Log to ensure user productivity and identify WordPress security issues before they become a security problem. WP Security Audit Log, WordPress' most comprehensive user monitoring and audit log plugin already helps thousands of WordPress administrators, owners and security professionals ensure the security of their websites and blogs. Ensure the security of your WordPress too by installing WP Security Audit Log. The community's favourite WordPress user monitoring monitoring and security auditing plugin is developed by WordPress Security Consultants and Professionals [WP White Security](http://www.wpwhitesecurity.com/).
121
  * [WPLift](http://wplift.com/wordpress-event-tracking)
122
  * [Tourqe News](http://torquemag.io/5-awesome-wordpress-plugins-you-may-not-have-heard-of/)
123
  * [Shout Me Loud](http://www.shoutmeloud.com/how-to-monitor-user-activities-wordpress-dashboard.html)
124
+ * [Monster Post](http://blog.templatemonster.com/2015/12/15/wp-security-audit-log-plugin-review/)
125
  * [The Darknet](http://www.darknet.org.uk/2015/10/wp-security-audit-log-a-complete-audit-log-plugin-for-wordpress/)
126
 
127
  = WordPress Security Audit Log in your Language! =
203
 
204
  == Changelog ==
205
 
206
+ = 2.3 (2016-01-12) =
207
+ * **New Features**
208
+ * Keep track of changes on bbPress forums. For more detailed information read the [WP Security Audit Log 2.3 Release Notes](http://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/track-bbpress-forums-changes-with-wp-security-audit-log/)
209
+
210
+ * **New WordPress Security Alerts**
211
+ * 8000: User published a new forum
212
+ * 8001: User changed the status of a forum
213
+ * 8002: User changed the visibility of a forum
214
+ * 8003: User changed the URL of a forum
215
+ * 8004: User changed the order of a forum
216
+ * 8005: User moved forum to trash
217
+ * 8006: User permanently deleted a fourm
218
+ * 8007: User restored a forum from trash
219
+ * 8008: User changed the parent of a forum
220
+ * 8009: User changed the role of forum auto user role
221
+ * 8010: User changed the option for anonymous posting on forum
222
+ * 8011: User changed the forum type
223
+ * 8012: User changed the time setting to disallow editing of posts
224
+ * 8013: User changed the time setting for post throttling
225
+ * 8014: User created new forum topic
226
+ * 8015: User changed the status of a forum topic
227
+ * 8016: User changed the type of a forum topic
228
+ * 8017: User changed the URL of a forum topic
229
+ * 8018: User changed the forum for a topic
230
+ * 8019: User moved a forum topic to trash
231
+ * 8020: User permanently deleted a forum topic
232
+ * 8021: User restored a forum topic from trash
233
+ * 8022: User changed the visibility of a forum topic
234
+
235
+ * **Improvements**
236
+ * Improved the performance / queries of the Audit Log Viewer, hence now it is faster when retrieving alerts from bigger databases
237
+ * Rewritten and improved the reporting engine for the [Reports Add-On](http://www.wpsecurityauditlog.com/extensions/compliance-reports-add-on-for-wordpress/)
238
+
239
+ * **Bug Fix**
240
+ * Fixed an issue where administrators of sub domain websites could see the alerts of other websites from the dashboard widget in a multisite installation. [Ticket](https://wordpress.org/support/topic/in-wordpress-mu-all-users-can-view-the-widget-log-bug)
241
+
242
  = 2.2 (2015-11-10) =
243
  * **New Features**
244
  * Aded the revision link in content change security alerts allowing you to see the actual content changes that took place on posts, pages and custom post types. [Learn More](http://www.wpsecurityauditlog.com/wordpress-user-monitoring-plugin-releases/record-all-wordpress-content-changes-wp-security-audit-log-plugin/)
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.2
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
4
  Plugin URI: http://www.wpsecurityauditlog.com/
5
  Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
+ Version: 2.3
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2