WP Security Audit Log - Version 2.6.7

Version Description

(2017-09-09) =

  • Improvements
    • Added a new property in WSAL main class to store the current plugin version.
    • Added a new function in WSAL main class to define constants (to be used throughout the plugin)
    • Improved the code formatting in AuditLog.php
Download this release

Release Info

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

Code changes from version 2.6.6 to 2.6.7

Files changed (3) hide show
  1. classes/Views/AuditLog.php +278 -247
  2. readme.txt +9 -2
  3. wp-security-audit-log.php +847 -805
classes/Views/AuditLog.php CHANGED
@@ -1,280 +1,311 @@
1
  <?php
2
- require_once(ABSPATH . 'wp-admin/includes/plugin.php');
3
  /**
4
- * @package Wsal
 
 
5
  *
 
 
 
 
 
 
 
 
 
 
 
 
6
  * Audit Log Viewer Page
 
 
7
  */
8
- class WSAL_Views_AuditLog extends WSAL_AbstractView
9
- {
10
- /**
11
- * @var WSAL_AuditLogListView
12
- */
13
- protected $_listview;
 
 
14
 
15
- protected $_version;
 
 
 
 
 
16
 
17
- public function __construct(WpSecurityAuditLog $plugin)
18
- {
19
- parent::__construct($plugin);
20
- add_action('wp_ajax_AjaxInspector', array($this, 'AjaxInspector'));
21
- add_action('wp_ajax_AjaxRefresh', array($this, 'AjaxRefresh'));
22
- add_action('wp_ajax_AjaxSetIpp', array($this, 'AjaxSetIpp'));
23
- add_action('wp_ajax_AjaxSearchSite', array($this, 'AjaxSearchSite'));
24
- add_action('wp_ajax_AjaxSwitchDB', array($this, 'AjaxSwitchDB'));
25
- add_action('all_admin_notices', array($this, 'AdminNoticesPremium'));
26
- // Check plugin version for to dismiss the notice only until upgrade
27
- $plugin_file = trailingslashit(WP_PLUGIN_DIR) . plugin_basename(__FILE__);
28
- $data = get_plugin_data($plugin_file, false, false);
29
- $this->_version = isset($data['Version']) ? $data['Version'] : '0.0.0';
30
- $this->RegisterNotice('premium-wsal-'.$this->_version);
31
- }
 
 
 
 
32
 
33
- public function AdminNoticesPremium()
34
- {
35
- $IsCurrentView = $this->_plugin->views->GetActiveView() == $this;
36
- // Check if any of the extensions is activated
37
- if (!class_exists('WSAL_NP_Plugin') && !class_exists('WSAL_SearchExtension') && !class_exists('WSAL_Rep_Plugin') && !class_exists('WSAL_Ext_Plugin') && !class_exists('WSAL_User_Management_Plugin')) {
38
- if ($IsCurrentView && !$this->IsNoticeDismissed('premium-wsal-'.$this->_version)) { ?>
39
- <div class="updated" data-notice-name="premium-wsal-<?=$this->_version?>">
40
- <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/ ?utm_source=auditviewer&utm_medium=page&utm_campaign=plugin'; ?>
41
- <p><a href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Upgrade to Premium', 'wp-security-audit-log'); ?></a>
42
- <?php _e('and add Email Alerts, Reports, Search and Users Login and Session Management.', 'wp-security-audit-log'); ?>
43
- <a href="<?php echo esc_attr($url); ?>" target="_blank"><?php _e('Upgrade Now!', 'wp-security-audit-log'); ?></a>
44
- <a href="javascript:;" class="wsal-dismiss-notification wsal-premium"><span class="dashicons dashicons-dismiss"></span></a>
45
- </p>
46
- </div>
47
- <?php
48
- }
49
- }
50
- }
 
 
 
 
 
51
 
52
- public function HasPluginShortcutLink()
53
- {
54
- return true;
55
- }
56
 
57
- public function GetTitle()
58
- {
59
- return __('Audit Log Viewer', 'wp-security-audit-log');
60
- }
61
 
62
- public function GetIcon()
63
- {
64
- return $this->_wpversion < 3.8
65
- ? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
66
- : 'dashicons-welcome-view-site';
67
- }
68
 
69
- public function GetName()
70
- {
71
- return __('Audit Log Viewer', 'wp-security-audit-log');
72
- }
73
 
74
- public function GetWeight()
75
- {
76
- return 1;
77
- }
78
 
79
- protected function GetListView()
80
- {
81
- if (is_null($this->_listview)) {
82
- $this->_listview = new WSAL_AuditLogListView($this->_plugin);
83
- }
84
- return $this->_listview;
85
- }
86
 
87
- /**
88
- * Render view table of Audit Log.
89
- *
90
- * @since 1.0.0
91
- */
92
- public function Render() {
93
- if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
94
- wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
95
- }
96
 
97
- $this->GetListView()->prepare_items();
98
- $occ = new WSAL_Models_Occurrence();
99
 
100
- ?><form id="audit-log-viewer" method="post">
101
- <div id="audit-log-viewer-content">
102
- <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
103
- <input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr( isset( $_REQUEST['wsal-cbid'] ) ? $_REQUEST['wsal-cbid'] : '0' ); ?>" />
104
- <?php do_action( 'wsal_auditlog_before_view', $this->GetListView() ); ?>
105
- <?php $this->GetListView()->display(); ?>
106
- <?php do_action( 'wsal_auditlog_after_view', $this->GetListView() ); ?>
107
- </div>
108
- </form>
109
 
110
- <?php if ( class_exists( 'WSAL_SearchExtension' ) &&
111
- ( isset( $_REQUEST['Filters'] ) || ( isset( $_REQUEST['s'] ) && trim( $_REQUEST['s'] ) ) ) ) : ?>
112
- <script type="text/javascript">
113
- jQuery(document).ready( function() {
114
- WsalAuditLogInit(
115
- <?php echo json_encode( array(
116
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
117
- 'tr8n' => array(
118
- 'numofitems' => __( 'Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log' ),
119
- 'searchback' => __( 'All Sites', 'wp-security-audit-log' ),
120
- 'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
121
- ),
122
- 'autorefresh' => array(
123
- 'enabled' => false,
124
- 'token' => (int) $occ->Count(),
125
- ),
126
- ) );
127
- ?>
128
- );
129
- } );
130
- </script>
131
- <?php else : ?>
132
- <script type="text/javascript">
133
- jQuery(document).ready( function() {
134
- WsalAuditLogInit(
135
- <?php echo json_encode( array(
136
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
137
- 'tr8n' => array(
138
- 'numofitems' => __( 'Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log' ),
139
- 'searchback' => __( 'All Sites', 'wp-security-audit-log' ),
140
- 'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
141
- ),
142
- 'autorefresh' => array(
143
- 'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
144
- 'token' => (int) $occ->Count(),
145
- ),
146
- ) );
147
- ?>
148
- );
149
- } );
150
- </script>
151
- <?php endif;
152
- }
153
 
154
- public function AjaxInspector()
155
- {
156
- if (!$this->_plugin->settings->CurrentUserCan('view')) {
157
- die('Access Denied.');
158
- }
159
- if (!isset($_REQUEST['occurrence'])) {
160
- die('Occurrence parameter expected.');
161
- }
162
- $occ = new WSAL_Models_Occurrence();
163
- $occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
164
 
165
- echo '<!DOCTYPE html><html><head>';
166
- echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
167
- echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
168
- echo '<style type="text/css">';
169
- echo 'html, body { margin: 0; padding: 0; }';
170
- echo '.nice_r { position: absolute; padding: 8px; }';
171
- echo '.nice_r a { overflow: visible; }';
172
- echo '</style>';
173
- echo '</head><body>';
174
- $nicer = new WSAL_Nicer($occ->GetMetaArray());
175
- $nicer->render();
176
- echo '</body></html>';
177
- die;
178
- }
179
 
180
- public function AjaxRefresh()
181
- {
182
- if (!$this->_plugin->settings->CurrentUserCan('view')) {
183
- die('Access Denied.');
184
- }
185
- if (!isset($_REQUEST['logcount'])) {
186
- die('Log count parameter expected.');
187
- }
188
 
189
- $old = (int)$_REQUEST['logcount'];
190
- $max = 40; // 40*500msec = 20sec
191
 
192
- $is_archive = false;
193
- if ($this->_plugin->settings->IsArchivingEnabled()) {
194
- $selected_db = get_transient('wsal_wp_selected_db');
195
- if ($selected_db && $selected_db == 'archive') {
196
- $is_archive = true;
197
- }
198
- }
199
 
200
- do {
201
- $occ = new WSAL_Models_Occurrence();
202
- $new = $occ->Count();
203
- usleep(500000); // 500msec
204
- } while (($old == $new) && (--$max > 0));
205
 
206
- if ($is_archive) {
207
- echo 'false';
208
- } else {
209
- echo $old == $new ? 'false' : $new;
210
- }
211
- die;
212
- }
213
 
214
- public function AjaxSetIpp()
215
- {
216
- if (!$this->_plugin->settings->CurrentUserCan('view')) {
217
- die('Access Denied.');
218
- }
219
- if (!isset($_REQUEST['count'])) {
220
- die('Count parameter expected.');
221
- }
222
- $this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
223
- die;
224
- }
225
 
226
- public function AjaxSearchSite()
227
- {
228
- if (!$this->_plugin->settings->CurrentUserCan('view')) {
229
- die('Access Denied.');
230
- }
231
- if (!isset($_REQUEST['search'])) {
232
- die('Search parameter expected.');
233
- }
234
- $grp1 = array();
235
- $grp2 = array();
236
 
237
- $search = $_REQUEST['search'];
238
 
239
- foreach ($this->GetListView()->get_sites() as $site) {
240
- if (stripos($site->blogname, $search) !== false) {
241
- $grp1[] = $site;
242
- } elseif (stripos($site->domain, $search) !== false) {
243
- $grp2[] = $site;
244
- }
245
- }
246
- die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
247
- }
248
 
249
- public function AjaxSwitchDB()
250
- {
251
- if (isset($_REQUEST['selected_db'])) {
252
- set_transient('wsal_wp_selected_db', $_REQUEST['selected_db'], HOUR_IN_SECONDS);
253
- }
254
- }
255
 
256
- public function Header()
257
- {
258
- add_thickbox();
259
- wp_enqueue_style('darktooltip', $this->_plugin->GetBaseUrl() . '/css/darktooltip.css', array(), '');
260
- wp_enqueue_style(
261
- 'auditlog',
262
- $this->_plugin->GetBaseUrl() . '/css/auditlog.css',
263
- array(),
264
- filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
265
- );
266
- }
267
 
268
- public function Footer()
269
- {
270
- wp_enqueue_script('jquery');
271
- wp_enqueue_script('darktooltip', $this->_plugin->GetBaseUrl() . '/js/jquery.darktooltip.js', array('jquery'), '');
272
- wp_enqueue_script('suggest');
273
- wp_enqueue_script(
274
- 'auditlog',
275
- $this->_plugin->GetBaseUrl() . '/js/auditlog.js',
276
- array(),
277
- filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
278
- );
279
- }
280
  }
1
  <?php
 
2
  /**
3
+ * Audit Log View Class
4
+ *
5
+ * Class file for Audit Log View.
6
  *
7
+ * @since 1.0.0
8
+ * @package wsal
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
17
+
18
+ /**
19
  * Audit Log Viewer Page
20
+ *
21
+ * @package Wsal
22
  */
23
+ class WSAL_Views_AuditLog extends WSAL_AbstractView {
24
+
25
+ /**
26
+ * Listing view object (Instance of WSAL_AuditLogListView).
27
+ *
28
+ * @var object
29
+ */
30
+ protected $_listview;
31
 
32
+ /**
33
+ * Plugin version.
34
+ *
35
+ * @var string
36
+ */
37
+ protected $_version;
38
 
39
+ /**
40
+ * Method: Constructor
41
+ *
42
+ * @param object $plugin - Instance of WpSecurityAuditLog.
43
+ * @author Ashar Irfan
44
+ * @since 1.0.0
45
+ */
46
+ public function __construct( WpSecurityAuditLog $plugin ) {
47
+ parent::__construct( $plugin );
48
+ add_action( 'wp_ajax_AjaxInspector', array( $this, 'AjaxInspector' ) );
49
+ add_action( 'wp_ajax_AjaxRefresh', array( $this, 'AjaxRefresh' ) );
50
+ add_action( 'wp_ajax_AjaxSetIpp', array( $this, 'AjaxSetIpp' ) );
51
+ add_action( 'wp_ajax_AjaxSearchSite', array( $this, 'AjaxSearchSite' ) );
52
+ add_action( 'wp_ajax_AjaxSwitchDB', array( $this, 'AjaxSwitchDB' ) );
53
+ add_action( 'all_admin_notices', array( $this, 'AdminNoticesPremium' ) );
54
+ // Check plugin version for to dismiss the notice only until upgrade.
55
+ $this->_version = WSAL_VERSION;
56
+ $this->RegisterNotice( 'premium-wsal-' . $this->_version );
57
+ }
58
 
59
+ /**
60
+ * Method: Add premium extensions notice.
61
+ *
62
+ * @author Ashar Irfan
63
+ * @since 1.0.0
64
+ */
65
+ public function AdminNoticesPremium() {
66
+ $is_current_view = $this->_plugin->views->GetActiveView() == $this;
67
+ // Check if any of the extensions is activated.
68
+ if ( ! class_exists( 'WSAL_NP_Plugin' ) && ! class_exists( 'WSAL_SearchExtension' ) && ! class_exists( 'WSAL_Rep_Plugin' ) && ! class_exists( 'WSAL_Ext_Plugin' ) && ! class_exists( 'WSAL_User_Management_Plugin' ) ) {
69
+ if ( current_user_can( 'manage_options' ) && $is_current_view && ! $this->IsNoticeDismissed( 'premium-wsal-' . $this->_version ) ) { ?>
70
+ <div class="updated" data-notice-name="premium-wsal-<?php echo esc_attr( $this->_version ) ?>">
71
+ <?php $url = 'https://www.wpsecurityauditlog.com/extensions/all-add-ons-60-off/?utm_source=auditviewer&utm_medium=page&utm_campaign=plugin'; ?>
72
+ <p><a href="<?php echo esc_attr( $url ); ?>" target="_blank"><?php esc_html_e( 'Upgrade to Premium', 'wp-security-audit-log' ); ?></a>
73
+ <?php esc_html_e( 'and add Email Alerts, Reports, Search and Users Login and Session Management.', 'wp-security-audit-log' ); ?>
74
+ <a href="<?php echo esc_attr( $url ); ?>" target="_blank"><?php esc_html_e( 'Upgrade Now!', 'wp-security-audit-log' ); ?></a>
75
+ <a href="javascript:;" class="wsal-dismiss-notification wsal-premium"><span class="dashicons dashicons-dismiss"></span></a>
76
+ </p>
77
+ </div>
78
+ <?php
79
+ }
80
+ }
81
+ }
82
 
83
+ public function HasPluginShortcutLink()
84
+ {
85
+ return true;
86
+ }
87
 
88
+ public function GetTitle()
89
+ {
90
+ return __('Audit Log Viewer', 'wp-security-audit-log');
91
+ }
92
 
93
+ public function GetIcon()
94
+ {
95
+ return $this->_wpversion < 3.8
96
+ ? $this->_plugin->GetBaseUrl() . '/img/logo-main-menu.png'
97
+ : 'dashicons-welcome-view-site';
98
+ }
99
 
100
+ public function GetName()
101
+ {
102
+ return __('Audit Log Viewer', 'wp-security-audit-log');
103
+ }
104
 
105
+ public function GetWeight()
106
+ {
107
+ return 1;
108
+ }
109
 
110
+ protected function GetListView()
111
+ {
112
+ if (is_null($this->_listview)) {
113
+ $this->_listview = new WSAL_AuditLogListView($this->_plugin);
114
+ }
115
+ return $this->_listview;
116
+ }
117
 
118
+ /**
119
+ * Render view table of Audit Log.
120
+ *
121
+ * @since 1.0.0
122
+ */
123
+ public function Render() {
124
+ if ( ! $this->_plugin->settings->CurrentUserCan( 'view' ) ) {
125
+ wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wp-security-audit-log' ) );
126
+ }
127
 
128
+ $this->GetListView()->prepare_items();
129
+ $occ = new WSAL_Models_Occurrence();
130
 
131
+ ?><form id="audit-log-viewer" method="post">
132
+ <div id="audit-log-viewer-content">
133
+ <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
134
+ <input type="hidden" id="wsal-cbid" name="wsal-cbid" value="<?php echo esc_attr( isset( $_REQUEST['wsal-cbid'] ) ? $_REQUEST['wsal-cbid'] : '0' ); ?>" />
135
+ <?php do_action( 'wsal_auditlog_before_view', $this->GetListView() ); ?>
136
+ <?php $this->GetListView()->display(); ?>
137
+ <?php do_action( 'wsal_auditlog_after_view', $this->GetListView() ); ?>
138
+ </div>
139
+ </form>
140
 
141
+ <?php if ( class_exists( 'WSAL_SearchExtension' ) &&
142
+ ( isset( $_REQUEST['Filters'] ) || ( isset( $_REQUEST['s'] ) && trim( $_REQUEST['s'] ) ) ) ) : ?>
143
+ <script type="text/javascript">
144
+ jQuery(document).ready( function() {
145
+ WsalAuditLogInit(
146
+ <?php echo json_encode( array(
147
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
148
+ 'tr8n' => array(
149
+ 'numofitems' => __( 'Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log' ),
150
+ 'searchback' => __( 'All Sites', 'wp-security-audit-log' ),
151
+ 'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
152
+ ),
153
+ 'autorefresh' => array(
154
+ 'enabled' => false,
155
+ 'token' => (int) $occ->Count(),
156
+ ),
157
+ ) );
158
+ ?>
159
+ );
160
+ } );
161
+ </script>
162
+ <?php else : ?>
163
+ <script type="text/javascript">
164
+ jQuery(document).ready( function() {
165
+ WsalAuditLogInit(
166
+ <?php echo json_encode( array(
167
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
168
+ 'tr8n' => array(
169
+ 'numofitems' => __( 'Please enter the number of alerts you would like to see on one page:', 'wp-security-audit-log' ),
170
+ 'searchback' => __( 'All Sites', 'wp-security-audit-log' ),
171
+ 'searchnone' => __( 'No Results', 'wp-security-audit-log' ),
172
+ ),
173
+ 'autorefresh' => array(
174
+ 'enabled' => $this->_plugin->settings->IsRefreshAlertsEnabled(),
175
+ 'token' => (int) $occ->Count(),
176
+ ),
177
+ ) );
178
+ ?>
179
+ );
180
+ } );
181
+ </script>
182
+ <?php endif;
183
+ }
184
 
185
+ public function AjaxInspector()
186
+ {
187
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
188
+ die('Access Denied.');
189
+ }
190
+ if (!isset($_REQUEST['occurrence'])) {
191
+ die('Occurrence parameter expected.');
192
+ }
193
+ $occ = new WSAL_Models_Occurrence();
194
+ $occ->Load('id = %d', array((int)$_REQUEST['occurrence']));
195
 
196
+ echo '<!DOCTYPE html><html><head>';
197
+ echo '<link rel="stylesheet" id="open-sans-css" href="' . $this->_plugin->GetBaseUrl() . '/css/nice_r.css" type="text/css" media="all">';
198
+ echo '<script type="text/javascript" src="'.$this->_plugin->GetBaseUrl() . '/js/nice_r.js"></script>';
199
+ echo '<style type="text/css">';
200
+ echo 'html, body { margin: 0; padding: 0; }';
201
+ echo '.nice_r { position: absolute; padding: 8px; }';
202
+ echo '.nice_r a { overflow: visible; }';
203
+ echo '</style>';
204
+ echo '</head><body>';
205
+ $nicer = new WSAL_Nicer($occ->GetMetaArray());
206
+ $nicer->render();
207
+ echo '</body></html>';
208
+ die;
209
+ }
210
 
211
+ public function AjaxRefresh()
212
+ {
213
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
214
+ die('Access Denied.');
215
+ }
216
+ if (!isset($_REQUEST['logcount'])) {
217
+ die('Log count parameter expected.');
218
+ }
219
 
220
+ $old = (int)$_REQUEST['logcount'];
221
+ $max = 40; // 40*500msec = 20sec
222
 
223
+ $is_archive = false;
224
+ if ($this->_plugin->settings->IsArchivingEnabled()) {
225
+ $selected_db = get_transient('wsal_wp_selected_db');
226
+ if ($selected_db && $selected_db == 'archive') {
227
+ $is_archive = true;
228
+ }
229
+ }
230
 
231
+ do {
232
+ $occ = new WSAL_Models_Occurrence();
233
+ $new = $occ->Count();
234
+ usleep(500000); // 500msec
235
+ } while (($old == $new) && (--$max > 0));
236
 
237
+ if ($is_archive) {
238
+ echo 'false';
239
+ } else {
240
+ echo $old == $new ? 'false' : $new;
241
+ }
242
+ die;
243
+ }
244
 
245
+ public function AjaxSetIpp()
246
+ {
247
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
248
+ die('Access Denied.');
249
+ }
250
+ if (!isset($_REQUEST['count'])) {
251
+ die('Count parameter expected.');
252
+ }
253
+ $this->_plugin->settings->SetViewPerPage((int)$_REQUEST['count']);
254
+ die;
255
+ }
256
 
257
+ public function AjaxSearchSite()
258
+ {
259
+ if (!$this->_plugin->settings->CurrentUserCan('view')) {
260
+ die('Access Denied.');
261
+ }
262
+ if (!isset($_REQUEST['search'])) {
263
+ die('Search parameter expected.');
264
+ }
265
+ $grp1 = array();
266
+ $grp2 = array();
267
 
268
+ $search = $_REQUEST['search'];
269
 
270
+ foreach ($this->GetListView()->get_sites() as $site) {
271
+ if (stripos($site->blogname, $search) !== false) {
272
+ $grp1[] = $site;
273
+ } elseif (stripos($site->domain, $search) !== false) {
274
+ $grp2[] = $site;
275
+ }
276
+ }
277
+ die(json_encode(array_slice($grp1 + $grp2, 0, 7)));
278
+ }
279
 
280
+ public function AjaxSwitchDB()
281
+ {
282
+ if (isset($_REQUEST['selected_db'])) {
283
+ set_transient('wsal_wp_selected_db', $_REQUEST['selected_db'], HOUR_IN_SECONDS);
284
+ }
285
+ }
286
 
287
+ public function Header()
288
+ {
289
+ add_thickbox();
290
+ wp_enqueue_style('darktooltip', $this->_plugin->GetBaseUrl() . '/css/darktooltip.css', array(), '');
291
+ wp_enqueue_style(
292
+ 'auditlog',
293
+ $this->_plugin->GetBaseUrl() . '/css/auditlog.css',
294
+ array(),
295
+ filemtime($this->_plugin->GetBaseDir() . '/css/auditlog.css')
296
+ );
297
+ }
298
 
299
+ public function Footer()
300
+ {
301
+ wp_enqueue_script('jquery');
302
+ wp_enqueue_script('darktooltip', $this->_plugin->GetBaseUrl() . '/js/jquery.darktooltip.js', array('jquery'), '');
303
+ wp_enqueue_script('suggest');
304
+ wp_enqueue_script(
305
+ 'auditlog',
306
+ $this->_plugin->GetBaseUrl() . '/js/auditlog.js',
307
+ array(),
308
+ filemtime($this->_plugin->GetBaseDir() . '/js/auditlog.js')
309
+ );
310
+ }
311
  }
readme.txt CHANGED
@@ -7,7 +7,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
8
  Requires at least: 3.6
9
  Tested up to: 4.8.1
10
- Stable tag: 2.6.6
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
 
@@ -188,7 +188,14 @@ Please refer to the [FAQs page](https://www.wpsecurityauditlog.com/documentation
188
 
189
  == Changelog ==
190
 
191
- = 2.6.6 (2017-08-30 =
 
 
 
 
 
 
 
192
 
193
  * **New Audit Trail Alerts**
194
  * Alert 4015 for when a user creates a custom field in a user profile.
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
8
  Requires at least: 3.6
9
  Tested up to: 4.8.1
10
+ Stable tag: 2.6.7
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
 
188
 
189
  == Changelog ==
190
 
191
+ = 2.6.7 (2017-09-09) =
192
+
193
+ * **Improvements**
194
+ * Added a new property in WSAL main class to store the current plugin version.
195
+ * Added a new function in WSAL main class to define constants (to be used throughout the plugin)
196
+ * Improved the code formatting in AuditLog.php
197
+
198
+ = 2.6.6 (2017-08-30) =
199
 
200
  * **New Audit Trail Alerts**
201
  * Alert 4015 for when a user creates a custom field in a user profile.
wp-security-audit-log.php CHANGED
@@ -4,26 +4,26 @@ 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.6.6
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
11
 
12
- WP Security Audit Log
13
- Copyright(c) 2014 Robert Abela (email : robert@wpwhitesecurity.com)
14
 
15
- This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License, version 2, as
17
- published by the Free Software Foundation.
18
 
19
- This program is distributed in the hope that it will be useful,
20
- but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- GNU General Public License for more details.
23
 
24
- You should have received a copy of the GNU General Public License
25
- along with this program; if not, write to the Free Software
26
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
  /**
@@ -31,798 +31,840 @@ License: GPL2
31
  */
32
  class WpSecurityAuditLog {
33
 
34
- // <editor-fold desc="Properties & Constants">
35
-
36
- const PLG_CLS_PRFX = 'WSAL_';
37
-
38
- const MIN_PHP_VERSION = '5.3.0';
39
-
40
- const OPT_PRFX = 'wsal-';
41
-
42
- /**
43
- * Views supervisor.
44
- * @var WSAL_ViewManager
45
- */
46
- public $views;
47
-
48
- /**
49
- * Logger supervisor.
50
- * @var WSAL_AlertManager
51
- */
52
- public $alerts;
53
-
54
- /**
55
- * Sensors supervisor.
56
- * @var WSAL_SensorManager
57
- */
58
- public $sensors;
59
-
60
- /**
61
- * Settings manager.
62
- * @var WSAL_Settings
63
- */
64
- public $settings;
65
-
66
- /**
67
- * Class loading manager.
68
- * @var WSAL_Autoloader
69
- */
70
- public $autoloader;
71
-
72
- /**
73
- * Constants manager.
74
- * @var WSAL_ConstantManager
75
- */
76
- public $constants;
77
-
78
- /**
79
- * Licenses manager.
80
- * @var WSAL_LicenseManager
81
- */
82
- public $licensing;
83
-
84
- /**
85
- * Simple profiler.
86
- * @var WSAL_SimpleProfiler
87
- */
88
- public $profiler;
89
-
90
- /**
91
- * Options.
92
- * @var WSAL_DB_Option
93
- */
94
- public $options;
95
-
96
- /**
97
- * Contains a list of cleanup callbacks.
98
- * @var callable[]
99
- */
100
- protected $_cleanup_hooks = array();
101
-
102
- // </editor-fold>
103
-
104
- // <editor-fold desc="Entry Points">
105
-
106
- /**
107
- * Standard singleton pattern.
108
- * WARNING! To ensure the system always works as expected, AVOID using this method.
109
- * Instead, make use of the plugin instance provided by 'wsal_init' action.
110
- * @return WpSecurityAuditLog Returns the current plugin instance.
111
- */
112
- public static function GetInstance()
113
- {
114
- static $instance = null;
115
- if (!$instance) {
116
- $instance = new self();
117
- }
118
- return $instance;
119
- }
120
-
121
- /**
122
- * Initialize plugin.
123
- */
124
- public function __construct()
125
- {
126
- require_once('classes/Helpers/DataHelper.php');
127
- // profiler has to be loaded manually
128
- require_once('classes/SimpleProfiler.php');
129
- $this->profiler = new WSAL_SimpleProfiler();
130
- require_once('classes/Models/ActiveRecord.php');
131
- require_once('classes/Models/Query.php');
132
- require_once('classes/Models/OccurrenceQuery.php');
133
- require_once('classes/Models/Option.php');
134
- require_once('classes/Models/TmpUser.php');
135
-
136
- // load autoloader and register base paths
137
- require_once('classes/Autoloader.php');
138
- $this->autoloader = new WSAL_Autoloader($this);
139
- $this->autoloader->Register(self::PLG_CLS_PRFX, $this->GetBaseDir() . 'classes' . DIRECTORY_SEPARATOR);
140
-
141
- // load dependencies
142
- $this->views = new WSAL_ViewManager($this);
143
- $this->alerts = new WSAL_AlertManager($this);
144
- $this->sensors = new WSAL_SensorManager($this);
145
- $this->settings = new WSAL_Settings($this);
146
- $this->constants = new WSAL_ConstantManager($this);
147
- $this->licensing = new WSAL_LicenseManager($this);
148
- $this->widgets = new WSAL_WidgetManager($this);
149
-
150
- // Listen for installation event.
151
- register_activation_hook( __FILE__, array( $this, 'Install' ) );
152
-
153
- // listen for init event
154
- add_action('init', array($this, 'Init'));
155
-
156
- // listen for cleanup event
157
- add_action('wsal_cleanup', array($this, 'CleanUp'));
158
-
159
- // render wsal header
160
- add_action('admin_enqueue_scripts', array($this, 'RenderHeader'));
161
-
162
- // render wsal footer
163
- add_action('admin_footer', array($this, 'RenderFooter'));
164
-
165
- // handle admin Disable Custom Field
166
- add_action('wp_ajax_AjaxDisableCustomField', array($this, 'AjaxDisableCustomField'));
167
-
168
- // handle admin Disable Alerts
169
- add_action('wp_ajax_AjaxDisableByCode', array($this, 'AjaxDisableByCode'));
170
- }
171
-
172
- /**
173
- * @internal Start to trigger the events after installation.
174
- */
175
- public function Init()
176
- {
177
- // Start listening to events
178
- WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
179
-
180
- if ($this->settings->IsArchivingEnabled()) {
181
- // Check the current page
182
- if ((!isset($_REQUEST['page']) || $_REQUEST['page'] != 'wsal-auditlog') && (!defined('DOING_AJAX') || !DOING_AJAX)) {
183
- $selected_db = get_transient('wsal_wp_selected_db');
184
- if ($selected_db) {
185
- // Delete the transient
186
- delete_transient('wsal_wp_selected_db');
187
- }
188
- }
189
- }
190
- }
191
-
192
-
193
- /**
194
- * @internal Render plugin stuff in page header.
195
- */
196
- public function RenderHeader()
197
- {
198
- // common.css?
199
- }
200
-
201
- /**
202
- * Disable Custom Field through ajax.
203
- * @internal
204
- */
205
- public function AjaxDisableCustomField()
206
- {
207
- $fields = $this->GetGlobalOption('excluded-custom');
208
- if (isset($fields) && $fields != "") {
209
- $fields .= "," . esc_html($_POST['notice']);
210
- } else {
211
- $fields = esc_html($_POST['notice']);
212
- }
213
- $this->SetGlobalOption('excluded-custom', $fields);
214
- echo '<p>Custom Field '.esc_html($_POST['notice']).' is no longer being monitored.<br />Enable the monitoring of this custom field again from the <a href="admin.php?page=wsal-settings#tab-exclude"> Excluded Objects </a> tab in the plugin settings</p>';
215
- die;
216
- }
217
-
218
- /**
219
- * Disable Alert through ajax.
220
- * @internal
221
- */
222
- public function AjaxDisableByCode()
223
- {
224
- $sAlerts = $this->GetGlobalOption('disabled-alerts');
225
- if (isset($sAlerts) && $sAlerts != "") {
226
- $sAlerts .= "," . esc_html($_POST['code']);
227
- } else {
228
- $sAlerts = esc_html($_POST['code']);
229
- }
230
- $this->SetGlobalOption('disabled-alerts', $sAlerts);
231
- echo '<p>Alert '.esc_html($_POST['code']).' is no longer being monitored.<br />';
232
- echo 'You can enable this alert again from the Enable/Disable Alerts node in the plugin menu.</p>';
233
- die;
234
- }
235
-
236
- /**
237
- * @internal Render plugin stuff in page footer.
238
- */
239
- public function RenderFooter()
240
- {
241
- wp_enqueue_script(
242
- 'wsal-common',
243
- $this->GetBaseUrl() . '/js/common.js',
244
- array('jquery'),
245
- filemtime($this->GetBaseDir() . '/js/common.js')
246
- );
247
- }
248
-
249
- /**
250
- * @internal Load the rest of the system.
251
- */
252
- public function Load()
253
- {
254
- $optionsTable = new WSAL_Models_Option();
255
- if (!$optionsTable->IsInstalled()) {
256
- $optionsTable->Install();
257
- //setting the prunig date with the old value or the default value
258
- $pruningDate = $this->settings->GetPruningDate();
259
- $this->settings->SetPruningDate($pruningDate);
260
-
261
- $pruningEnabled = $this->settings->IsPruningLimitEnabled();
262
- $this->settings->SetPruningLimitEnabled($pruningEnabled);
263
- //setting the prunig limit with the old value or the default value
264
- $pruningLimit = $this->settings->GetPruningLimit();
265
- $this->settings->SetPruningLimit($pruningLimit);
266
- }
267
- $log_404 = $this->GetGlobalOption('log-404');
268
- // If old setting is empty enable 404 logging by default
269
- if ($log_404 === false) {
270
- $this->SetGlobalOption('log-404', 'on');
271
- }
272
-
273
- $purge_log_404 = $this->GetGlobalOption('purge-404-log');
274
- // If old setting is empty enable 404 purge log by default
275
- if ($purge_log_404 === false) {
276
- $this->SetGlobalOption('purge-404-log', 'on');
277
- }
278
- // load translations
279
- load_plugin_textdomain('wp-security-audit-log', false, basename(dirname(__FILE__)) . '/languages/');
280
-
281
- // tell the world we've just finished loading
282
- $s = $this->profiler->Start('WSAL Init Hook');
283
- do_action('wsal_init', $this);
284
- $s->Stop();
285
-
286
- // hide plugin
287
- if ($this->settings->IsIncognito()) {
288
- add_action('admin_head', array($this, 'HidePlugin'));
289
- }
290
-
291
- // Update routine.
292
- $old_version = $this->GetOldVersion();
293
- $new_version = $this->GetNewVersion();
294
- if ( $old_version !== $new_version ) {
295
- $this->Update( $old_version, $new_version );
296
- }
297
- }
298
-
299
- /**
300
- * Install all assets required for a useable system.
301
- */
302
- public function Install()
303
- {
304
- if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
305
- ?><html>
306
- <head>
307
- <link rel="stylesheet" href="<?php
308
- echo esc_attr($this->GetBaseUrl() . '/css/install-error.css?v=' . filemtime($this->GetBaseDir() . '/css/install-error.css'));
309
- ?>" type="text/css" media="all"/>
310
- </head><body>
311
- <div class="warn-wrap">
312
- <div class="warn-icon-tri"></div><div class="warn-icon-chr">!</div><div class="warn-icon-cir"></div>
313
- <?php echo sprintf(__('You are using a version of PHP that is older than %s, which is no longer supported.<br/>Contact us on <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a> to help you switch the version of PHP you are using.'), self::MIN_PHP_VERSION); ?>
314
- </div>
315
- </body>
316
- </html><?php
317
- die(1);
318
- }
319
-
320
- // ensure that the system is installed and schema is correct
321
- self::getConnector()->installAll();
322
-
323
- $PreInstalled = $this->IsInstalled();
324
-
325
- // if system already installed, do updates now (if any)
326
- $OldVersion = $this->GetOldVersion();
327
- $NewVersion = $this->GetNewVersion();
328
-
329
- if ( $PreInstalled && $OldVersion != $NewVersion ) {
330
- $this->Update( $OldVersion, $NewVersion );
331
- }
332
-
333
- // Load options from wp_options table or wp_sitemeta in multisite enviroment
334
- $data = $this->read_options_prefixed("wsal-");
335
- if (!empty($data)) {
336
- $this->SetOptions($data);
337
- }
338
- $this->deleteAllOptions();
339
-
340
- // if system wasn't installed, try migration now
341
- if (!$PreInstalled && $this->CanMigrate()) {
342
- $this->Migrate();
343
- }
344
-
345
- // setting the prunig date with the old value or the default value
346
- $pruningDate = $this->settings->GetPruningDate();
347
- $this->settings->SetPruningDate($pruningDate);
348
-
349
- //$pruningEnabled = $this->settings->IsPruningLimitEnabled();
350
- $this->settings->SetPruningLimitEnabled(true);
351
- //setting the prunig limit with the old value or the default value
352
- $pruningLimit = $this->settings->GetPruningLimit();
353
- $this->settings->SetPruningLimit($pruningLimit);
354
-
355
- $oldDisabled = $this->GetGlobalOption('disabled-alerts');
356
- // If old setting is empty disable alert 2099 by default
357
- if (empty($oldDisabled)) {
358
- $this->settings->SetDisabledAlerts(array(2099));
359
- }
360
-
361
- $log_404 = $this->GetGlobalOption('log-404');
362
- // If old setting is empty enable 404 logging by default
363
- if ($log_404 === false) {
364
- $this->SetGlobalOption('log-404', 'on');
365
- }
366
-
367
- $purge_log_404 = $this->GetGlobalOption('purge-404-log');
368
- // If old setting is empty enable 404 purge log by default
369
- if ($purge_log_404 === false) {
370
- $this->SetGlobalOption('purge-404-log', 'on');
371
- }
372
-
373
- // install cleanup hook (remove older one if it exists)
374
- wp_clear_scheduled_hook('wsal_cleanup');
375
- wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
376
- }
377
-
378
- /**
379
- * Run some code that updates critical components required for a newwer version.
380
- *
381
- * @param string $old_version The old version.
382
- * @param string $new_version The new version.
383
- */
384
- public function Update( $old_version, $new_version ) {
385
- // Update version in db.
386
- $this->SetGlobalOption( 'version', $new_version );
387
-
388
- // Disable all developer options.
389
- //$this->settings->ClearDevOptions();
390
-
391
- // Do version-to-version specific changes.
392
- if ( -1 === version_compare( $old_version, $new_version ) ) {
393
- $this->update_external_db_password();
394
- }
395
- }
396
-
397
- /**
398
- * Method: Update external DB password.
399
- *
400
- * @since 2.6.3
401
- */
402
- public function update_external_db_password() {
403
-
404
- // Get the passwords.
405
- $external_password = $this->settings->GetAdapterConfig( 'adapter-password' );
406
- $mirror_password = $this->settings->GetAdapterConfig( 'mirror-password' );
407
- $archive_password = $this->settings->GetAdapterConfig( 'archive-password' );
408
-
409
- // Update external db password.
410
- if ( ! empty( $external_password ) ) {
411
- // Decrypt the password using fallback method.
412
- $password = $this->getConnector()->decryptString_fallback( $external_password );
413
-
414
- // Encrypt the password with latest encryption method.
415
- $encrypted_password = $this->getConnector()->encryptString( $password );
416
-
417
- // Store the new password.
418
- $this->settings->SetAdapterConfig( 'adapter-password', $encrypted_password );
419
- }
420
-
421
- // Update mirror db password.
422
- if ( ! empty( $mirror_password ) ) {
423
- // Decrypt the password using fallback method.
424
- $password = $this->getConnector()->decryptString_fallback( $mirror_password );
425
-
426
- // Encrypt the password with latest encryption method.
427
- $encrypted_password = $this->getConnector()->encryptString( $password );
428
-
429
- // Store the new password.
430
- $this->settings->SetAdapterConfig( 'mirror-password', $encrypted_password );
431
- }
432
-
433
- // Update archive db password.
434
- if ( ! empty( $archive_password ) ) {
435
- // Decrypt the password using fallback method.
436
- $password = $this->getConnector()->decryptString_fallback( $archive_password );
437
-
438
- // Encrypt the password with latest encryption method.
439
- $encrypted_password = $this->getConnector()->encryptString( $password );
440
-
441
- // Store the new password.
442
- $this->settings->SetAdapterConfig( 'archive-password', $encrypted_password );
443
- }
444
-
445
- }
446
-
447
- /**
448
- * Uninstall plugin.
449
- */
450
- public function Uninstall()
451
- {
452
- if ($this->GetGlobalOption("delete-data") == 1) {
453
- self::getConnector()->uninstallAll();
454
- $this->deleteAllOptions();
455
- }
456
- wp_clear_scheduled_hook('wsal_cleanup');
457
- }
458
-
459
- /**
460
- * Delete from the options table of WP.
461
- * @param string $prefix table prefix
462
- * @return boolean query result
463
- */
464
- public function delete_options_prefixed($prefix)
465
- {
466
- global $wpdb;
467
- if ($this->IsMultisite()) {
468
- $table_name = $wpdb->prefix .'sitemeta';
469
- $result = $wpdb->query("DELETE FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'");
470
- } else {
471
- $result = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'");
472
- }
473
- return ($result) ? true : false;
474
- }
475
-
476
- /**
477
- * Delete all the Wsal options from the options table of WP.
478
- */
479
- private function deleteAllOptions()
480
- {
481
- $flag = true;
482
- while ($flag) {
483
- $flag = $this->delete_options_prefixed(self::OPT_PRFX);
484
- }
485
- }
486
-
487
- /**
488
- * Read options from the options table of WP.
489
- * @param string $prefix table prefix
490
- * @return boolean query result
491
- */
492
- public function read_options_prefixed($prefix)
493
- {
494
- global $wpdb;
495
- if ($this->IsMultisite()) {
496
- $table_name = $wpdb->prefix .'sitemeta';
497
- $results = $wpdb->get_results("SELECT site_id,meta_key,meta_value FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'", ARRAY_A);
498
- } else {
499
- $results = $wpdb->get_results("SELECT option_name,option_value FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'", ARRAY_A);
500
- }
501
- return $results;
502
- }
503
-
504
- /**
505
- * Set options in the Wsal options table.
506
- * @param array $data table prefix
507
- */
508
- public function SetOptions($data)
509
- {
510
- foreach ($data as $key => $option) {
511
- $this->options = new WSAL_Models_Option();
512
- if ($this->IsMultisite()) {
513
- $this->options->SetOptionValue($option['meta_key'], $option['meta_value']);
514
- } else {
515
- $this->options->SetOptionValue($option['option_name'], $option['option_value']);
516
- }
517
- }
518
- }
519
-
520
- /**
521
- * Migrate data from old plugin.
522
- */
523
- public function Migrate()
524
- {
525
- global $wpdb;
526
- static $migTypes = array(
527
- 3000 => 5006
528
- );
529
-
530
- // load data
531
- $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog_events';
532
- $events = array();
533
- foreach ($wpdb->get_results($sql, ARRAY_A) as $item) {
534
- $events[$item['EventID']] = $item;
535
- }
536
- $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog';
537
- $auditlog = $wpdb->get_results($sql, ARRAY_A);
538
-
539
- // migrate using db logger
540
- foreach ($auditlog as $entry) {
541
- $data = array(
542
- 'ClientIP' => $entry['UserIP'],
543
- 'UserAgent' => '',
544
- 'CurrentUserID' => $entry['UserID'],
545
- );
546
- if ($entry['UserName']) {
547
- $data['Username'] = base64_decode($entry['UserName']);
548
- }
549
- $mesg = $events[$entry['EventID']]['EventDescription'];
550
- $date = strtotime($entry['EventDate']);
551
- $type = $entry['EventID'];
552
- if (isset($migTypes[$type])) {
553
- $type = $migTypes[$type];
554
- }
555
- // convert message from '<strong>%s</strong>' to '%Arg1%' format
556
- $c = 0;
557
- $n = '<strong>%s</strong>';
558
- $l = strlen($n);
559
- while (($pos = strpos($mesg, $n)) !== false) {
560
- $mesg = substr_replace($mesg, '%MigratedArg' . ($c++) .'%', $pos, $l);
561
- }
562
- $data['MigratedMesg'] = $mesg;
563
- // generate new meta data args
564
- $temp = unserialize(base64_decode($entry['EventData']));
565
- foreach ((array)$temp as $i => $item) {
566
- $data['MigratedArg' . $i] = $item;
567
- }
568
- // send event data to logger!
569
- foreach ($this->alerts->GetLoggers() as $logger) {
570
- $logger->Log($type, $data, $date, $entry['BlogId'], true);
571
- }
572
- }
573
-
574
- // migrate settings
575
- $this->settings->SetAllowedPluginEditors(
576
- get_option('WPPH_PLUGIN_ALLOW_CHANGE')
577
- );
578
- $this->settings->SetAllowedPluginViewers(
579
- get_option('WPPH_PLUGIN_ALLOW_ACCESS')
580
- );
581
- $s = get_option('wpph_plugin_settings');
582
- //$this->settings->SetPruningDate(($s->daysToKeep ? $s->daysToKeep : 30) . ' days');
583
- //$this->settings->SetPruningLimit(min($s->eventsToKeep, 1));
584
- $this->settings->SetViewPerPage(max($s->showEventsViewList, 5));
585
- $this->settings->SetWidgetsEnabled(!!$s->showDW);
586
- }
587
-
588
- // </editor-fold>
589
-
590
- // <editor-fold desc="Utility Methods">
591
-
592
- /**
593
- * @return string The current plugin version (according to plugin file metadata).
594
- */
595
- public function GetNewVersion()
596
- {
597
- $version = get_plugin_data(__FILE__, false, false);
598
- return isset($version['Version']) ? $version['Version'] : '0.0.0';
599
- }
600
-
601
- /**
602
- * @return string The plugin version as stored in DB (will be the old version during an update/install).
603
- */
604
- public function GetOldVersion()
605
- {
606
- return $this->GetGlobalOption('version', '0.0.0');
607
- }
608
-
609
- /**
610
- * @internal To be called in admin header for hiding plugin form Plugins list.
611
- */
612
- public function HidePlugin()
613
- {
614
- $selectr = '';
615
- $plugins = array('wp-security-audit-log');
616
- foreach ($this->licensing->Plugins() as $plugin) {
617
- $plugins[] = strtolower(str_replace(' ', '-', $plugin['PluginData']['Name']));
618
- }
619
- foreach ($plugins as $value) {
620
- $selectr .= '.wp-list-table.plugins tr[data-slug="' . $value . '"], ';
621
- }
622
- ?><style type="text/css"> <?php echo rtrim($selectr, ", "); ?> { display: none; }</style><?php
623
- }
624
-
625
- /**
626
- * Returns the class name of a particular file that contains the class.
627
- * @param string $file File name.
628
- * @return string Class name.
629
- * @deprecated since 1.2.5 Use autoloader->GetClassFileClassName() instead.
630
- */
631
- public function GetClassFileClassName($file)
632
- {
633
- return $this->autoloader->GetClassFileClassName($file);
634
- }
635
-
636
- /**
637
- * @return boolean Whether we are running on multisite or not.
638
- */
639
- public function IsMultisite()
640
- {
641
- return function_exists('is_multisite') && is_multisite();
642
- }
643
-
644
- /**
645
- * Get a global option.
646
- * @param string $option Option name.
647
- * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
648
- * @param string $prefix (Optional) A prefix used before option name.
649
- * @return mixed Option's value or $default if option not set.
650
- */
651
- public function GetGlobalOption($option, $default = false, $prefix = self::OPT_PRFX)
652
- {
653
- $this->options = new WSAL_Models_Option();
654
- return $this->options->GetOptionValue($prefix . $option, $default);
655
- }
656
-
657
- /**
658
- * Set a global option.
659
- * @param string $option Option name.
660
- * @param mixed $value New value for option.
661
- * @param string $prefix (Optional) A prefix used before option name.
662
- */
663
- public function SetGlobalOption($option, $value, $prefix = self::OPT_PRFX)
664
- {
665
- $this->options = new WSAL_Models_Option();
666
- $this->options->SetOptionValue($prefix . $option, $value);
667
- }
668
-
669
- /**
670
- * Get a user-specific option.
671
- * @param string $option Option name.
672
- * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
673
- * @param string $prefix (Optional) A prefix used before option name.
674
- * @return mixed Option's value or $default if option not set.
675
- */
676
- public function GetUserOption($option, $default = false, $prefix = self::OPT_PRFX)
677
- {
678
- $result = get_user_option($prefix . $option, get_current_user_id());
679
- return $result === false ? $default : $result;
680
- }
681
-
682
- /**
683
- * Set a user-specific option.
684
- * @param string $option Option name.
685
- * @param mixed $value New value for option.
686
- * @param string $prefix (Optional) A prefix used before option name.
687
- */
688
- public function SetUserOption($option, $value, $prefix = self::OPT_PRFX)
689
- {
690
- update_user_option(get_current_user_id(), $prefix . $option, $value, false);
691
- }
692
-
693
- /**
694
- * Run cleanup routines.
695
- */
696
- public function CleanUp()
697
- {
698
- $s = $this->profiler->Start('Clean Up');
699
- foreach ($this->_cleanup_hooks as $hook) {
700
- call_user_func($hook);
701
- }
702
- $s->Stop();
703
- }
704
-
705
- /**
706
- * Add callback to be called when a cleanup operation is required.
707
- * @param callable $hook
708
- */
709
- public function AddCleanupHook($hook)
710
- {
711
- $this->_cleanup_hooks[] = $hook;
712
- }
713
-
714
- /**
715
- * Remove a callback from the cleanup callbacks list.
716
- * @param callable $hook
717
- */
718
- public function RemoveCleanupHook($hook)
719
- {
720
- while (($pos = array_search($hook, $this->_cleanup_hooks)) !== false) {
721
- unset($this->_cleanup_hooks[$pos]);
722
- }
723
- }
724
-
725
- /**
726
- * DB connection.
727
- * @param mixed $config DB configuration.
728
- * @return WSAL_Connector_ConnectorInterface
729
- */
730
- public static function getConnector($config = null, $reset = false)
731
- {
732
- return WSAL_Connector_ConnectorFactory::getConnector($config, $reset);
733
- }
734
-
735
- /**
736
- * Do we have an existing installation? This only applies for version 1.0 onwards.
737
- * @return boolean
738
- */
739
- public function IsInstalled()
740
- {
741
- return self::getConnector()->isInstalled();
742
- }
743
-
744
- /**
745
- * @return boolean Whether the old plugin was present or not.
746
- */
747
- public function CanMigrate()
748
- {
749
- return self::getConnector()->canMigrate();
750
- }
751
-
752
- /**
753
- * @return string Absolute URL to plugin directory WITHOUT final slash.
754
- */
755
- public function GetBaseUrl()
756
- {
757
- return plugins_url('', __FILE__);
758
- }
759
-
760
- /**
761
- * @return string Full path to plugin directory WITH final slash.
762
- */
763
- public function GetBaseDir()
764
- {
765
- return plugin_dir_path(__FILE__);
766
- }
767
-
768
- /**
769
- * @return string Plugin directory name.
770
- */
771
- public function GetBaseName()
772
- {
773
- return plugin_basename(__FILE__);
774
- }
775
-
776
- /**
777
- * Load default configuration / data.
778
- */
779
- public function LoadDefaults()
780
- {
781
- $s = $this->profiler->Start('Load Defaults');
782
- require_once('defaults.php');
783
- $s->Stop();
784
- }
785
-
786
- /**
787
- * WSAL-Notifications-Extension Functions.
788
- */
789
- public function GetNotificationsSetting($opt_prefix)
790
- {
791
- $this->options = new WSAL_Models_Option();
792
- return $this->options->GetNotificationsSetting(self::OPT_PRFX . $opt_prefix);
793
- }
794
-
795
- public function GetNotification($id)
796
- {
797
- $this->options = new WSAL_Models_Option();
798
- return $this->options->GetNotification($id);
799
- }
800
-
801
- public function DeleteByName($name)
802
- {
803
- $this->options = new WSAL_Models_Option();
804
- return $this->options->DeleteByName($name);
805
- }
806
-
807
- public function DeleteByPrefix($opt_prefix)
808
- {
809
- $this->options = new WSAL_Models_Option();
810
- return $this->options->DeleteByPrefix(self::OPT_PRFX . $opt_prefix);
811
- }
812
-
813
- public function CountNotifications($opt_prefix)
814
- {
815
- $this->options = new WSAL_Models_Option();
816
- return $this->options->CountNotifications(self::OPT_PRFX . $opt_prefix);
817
- }
818
-
819
- public function UpdateGlobalOption($option, $value)
820
- {
821
- $this->options = new WSAL_Models_Option();
822
- return $this->options->SetOptionValue($option, $value);
823
- }
824
-
825
- // </editor-fold>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
826
  }
827
 
828
  // Profile WSAL load time
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.6.7
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
11
 
12
+ WP Security Audit Log
13
+ Copyright(c) 2014 Robert Abela (email : robert@wpwhitesecurity.com)
14
 
15
+ This program is free software; you can redistribute it and/or modify
16
+ it under the terms of the GNU General Public License, version 2, as
17
+ published by the Free Software Foundation.
18
 
19
+ This program is distributed in the hope that it will be useful,
20
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
+ GNU General Public License for more details.
23
 
24
+ You should have received a copy of the GNU General Public License
25
+ along with this program; if not, write to the Free Software
26
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
  */
28
 
29
  /**
31
  */
32
  class WpSecurityAuditLog {
33
 
34
+ /**
35
+ * Plugin version.
36
+ *
37
+ * @var string
38
+ */
39
+ public $version = '2.6.7';
40
+
41
+ // Plugin constants.
42
+ const PLG_CLS_PRFX = 'WSAL_';
43
+ const MIN_PHP_VERSION = '5.3.0';
44
+ const OPT_PRFX = 'wsal-';
45
+
46
+ /**
47
+ * Views supervisor.
48
+ * @var WSAL_ViewManager
49
+ */
50
+ public $views;
51
+
52
+ /**
53
+ * Logger supervisor.
54
+ * @var WSAL_AlertManager
55
+ */
56
+ public $alerts;
57
+
58
+ /**
59
+ * Sensors supervisor.
60
+ * @var WSAL_SensorManager
61
+ */
62
+ public $sensors;
63
+
64
+ /**
65
+ * Settings manager.
66
+ * @var WSAL_Settings
67
+ */
68
+ public $settings;
69
+
70
+ /**
71
+ * Class loading manager.
72
+ * @var WSAL_Autoloader
73
+ */
74
+ public $autoloader;
75
+
76
+ /**
77
+ * Constants manager.
78
+ * @var WSAL_ConstantManager
79
+ */
80
+ public $constants;
81
+
82
+ /**
83
+ * Licenses manager.
84
+ * @var WSAL_LicenseManager
85
+ */
86
+ public $licensing;
87
+
88
+ /**
89
+ * Simple profiler.
90
+ * @var WSAL_SimpleProfiler
91
+ */
92
+ public $profiler;
93
+
94
+ /**
95
+ * Options.
96
+ * @var WSAL_DB_Option
97
+ */
98
+ public $options;
99
+
100
+ /**
101
+ * Contains a list of cleanup callbacks.
102
+ * @var callable[]
103
+ */
104
+ protected $_cleanup_hooks = array();
105
+
106
+ // </editor-fold>
107
+
108
+ // <editor-fold desc="Entry Points">
109
+
110
+ /**
111
+ * Standard singleton pattern.
112
+ * WARNING! To ensure the system always works as expected, AVOID using this method.
113
+ * Instead, make use of the plugin instance provided by 'wsal_init' action.
114
+ * @return WpSecurityAuditLog Returns the current plugin instance.
115
+ */
116
+ public static function GetInstance()
117
+ {
118
+ static $instance = null;
119
+ if (!$instance) {
120
+ $instance = new self();
121
+ }
122
+ return $instance;
123
+ }
124
+
125
+ /**
126
+ * Initialize plugin.
127
+ */
128
+ public function __construct() {
129
+
130
+ // Define important plugin constants.
131
+ $this->define_constants();
132
+
133
+ require_once( 'classes/Helpers/DataHelper.php' );
134
+
135
+ // Profiler has to be loaded manually.
136
+ require_once( 'classes/SimpleProfiler.php' );
137
+ $this->profiler = new WSAL_SimpleProfiler();
138
+ require_once( 'classes/Models/ActiveRecord.php' );
139
+ require_once( 'classes/Models/Query.php' );
140
+ require_once( 'classes/Models/OccurrenceQuery.php' );
141
+ require_once( 'classes/Models/Option.php' );
142
+ require_once( 'classes/Models/TmpUser.php' );
143
+
144
+ // Load autoloader and register base paths.
145
+ require_once( 'classes/Autoloader.php' );
146
+ $this->autoloader = new WSAL_Autoloader( $this );
147
+ $this->autoloader->Register( self::PLG_CLS_PRFX, $this->GetBaseDir() . 'classes' . DIRECTORY_SEPARATOR );
148
+
149
+ // Load dependencies.
150
+ $this->views = new WSAL_ViewManager( $this );
151
+ $this->alerts = new WSAL_AlertManager( $this );
152
+ $this->sensors = new WSAL_SensorManager( $this );
153
+ $this->settings = new WSAL_Settings( $this );
154
+ $this->constants = new WSAL_ConstantManager( $this );
155
+ $this->licensing = new WSAL_LicenseManager( $this );
156
+ $this->widgets = new WSAL_WidgetManager( $this );
157
+
158
+ // Listen for installation event.
159
+ register_activation_hook( __FILE__, array( $this, 'Install' ) );
160
+
161
+ // Listen for init event.
162
+ add_action( 'init', array( $this, 'Init' ) );
163
+
164
+ // Listen for cleanup event.
165
+ add_action( 'wsal_cleanup', array( $this, 'CleanUp' ) );
166
+
167
+ // Render wsal header.
168
+ add_action( 'admin_enqueue_scripts', array( $this, 'RenderHeader' ) );
169
+
170
+ // Render wsal footer.
171
+ add_action( 'admin_footer', array( $this, 'RenderFooter' ) );
172
+
173
+ // Handle admin Disable Custom Field.
174
+ add_action( 'wp_ajax_AjaxDisableCustomField', array( $this, 'AjaxDisableCustomField' ) );
175
+
176
+ // Handle admin Disable Alerts.
177
+ add_action( 'wp_ajax_AjaxDisableByCode', array( $this, 'AjaxDisableByCode' ) );
178
+ }
179
+
180
+ /**
181
+ * Method: Define constants.
182
+ *
183
+ * @since 2.6.6
184
+ */
185
+ public function define_constants() {
186
+
187
+ // Plugin version.
188
+ if ( ! defined( 'WSAL_VERSION' ) ) {
189
+ define( 'WSAL_VERSION', $this->version );
190
+ }
191
+ // Plugin Name.
192
+ if ( ! defined( 'WSAL_BASE_NAME' ) ) {
193
+ define( 'WSAL_BASE_NAME', plugin_basename( __FILE__ ) );
194
+ }
195
+ // Plugin Directory URL.
196
+ if ( ! defined( 'WSAL_BASE_URL' ) ) {
197
+ define( 'WSAL_BASE_URL', plugin_dir_url( __FILE__ ) );
198
+ }
199
+ // Plugin Directory Path.
200
+ if ( ! defined( 'WSAL_BASE_DIR' ) ) {
201
+ define( 'WSAL_BASE_DIR', plugin_dir_path( __FILE__ ) );
202
+ }
203
+ // Plugin Docs URL.
204
+ if ( ! defined( 'WSAL_DOCS_URL' ) ) {
205
+ define( 'WSAL_DOCS_URL', 'https://www.wpsecurityauditlog.com/support-documentation/' );
206
+ }
207
+ // Plugin Issue Reporting URL.
208
+ if ( ! defined( 'WSAL_ISSUE_URL' ) ) {
209
+ define( 'WSAL_ISSUE_URL', 'https://wordpress.org/support/plugin/wp-security-audit-log' );
210
+ }
211
+
212
+ }
213
+
214
+ /**
215
+ * @internal Start to trigger the events after installation.
216
+ */
217
+ public function Init()
218
+ {
219
+ // Start listening to events
220
+ WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
221
+
222
+ if ($this->settings->IsArchivingEnabled()) {
223
+ // Check the current page
224
+ if ((!isset($_REQUEST['page']) || $_REQUEST['page'] != 'wsal-auditlog') && (!defined('DOING_AJAX') || !DOING_AJAX)) {
225
+ $selected_db = get_transient('wsal_wp_selected_db');
226
+ if ($selected_db) {
227
+ // Delete the transient
228
+ delete_transient('wsal_wp_selected_db');
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+
235
+ /**
236
+ * @internal Render plugin stuff in page header.
237
+ */
238
+ public function RenderHeader()
239
+ {
240
+ // common.css?
241
+ }
242
+
243
+ /**
244
+ * Disable Custom Field through ajax.
245
+ * @internal
246
+ */
247
+ public function AjaxDisableCustomField()
248
+ {
249
+ $fields = $this->GetGlobalOption('excluded-custom');
250
+ if (isset($fields) && $fields != "") {
251
+ $fields .= "," . esc_html($_POST['notice']);
252
+ } else {
253
+ $fields = esc_html($_POST['notice']);
254
+ }
255
+ $this->SetGlobalOption('excluded-custom', $fields);
256
+ echo '<p>Custom Field '.esc_html($_POST['notice']).' is no longer being monitored.<br />Enable the monitoring of this custom field again from the <a href="admin.php?page=wsal-settings#tab-exclude"> Excluded Objects </a> tab in the plugin settings</p>';
257
+ die;
258
+ }
259
+
260
+ /**
261
+ * Disable Alert through ajax.
262
+ * @internal
263
+ */
264
+ public function AjaxDisableByCode()
265
+ {
266
+ $sAlerts = $this->GetGlobalOption('disabled-alerts');
267
+ if (isset($sAlerts) && $sAlerts != "") {
268
+ $sAlerts .= "," . esc_html($_POST['code']);
269
+ } else {
270
+ $sAlerts = esc_html($_POST['code']);
271
+ }
272
+ $this->SetGlobalOption('disabled-alerts', $sAlerts);
273
+ echo '<p>Alert '.esc_html($_POST['code']).' is no longer being monitored.<br />';
274
+ echo 'You can enable this alert again from the Enable/Disable Alerts node in the plugin menu.</p>';
275
+ die;
276
+ }
277
+
278
+ /**
279
+ * @internal Render plugin stuff in page footer.
280
+ */
281
+ public function RenderFooter()
282
+ {
283
+ wp_enqueue_script(
284
+ 'wsal-common',
285
+ $this->GetBaseUrl() . '/js/common.js',
286
+ array('jquery'),
287
+ filemtime($this->GetBaseDir() . '/js/common.js')
288
+ );
289
+ }
290
+
291
+ /**
292
+ * @internal Load the rest of the system.
293
+ */
294
+ public function Load()
295
+ {
296
+ $optionsTable = new WSAL_Models_Option();
297
+ if (!$optionsTable->IsInstalled()) {
298
+ $optionsTable->Install();
299
+ //setting the prunig date with the old value or the default value
300
+ $pruningDate = $this->settings->GetPruningDate();
301
+ $this->settings->SetPruningDate($pruningDate);
302
+
303
+ $pruningEnabled = $this->settings->IsPruningLimitEnabled();
304
+ $this->settings->SetPruningLimitEnabled($pruningEnabled);
305
+ //setting the prunig limit with the old value or the default value
306
+ $pruningLimit = $this->settings->GetPruningLimit();
307
+ $this->settings->SetPruningLimit($pruningLimit);
308
+ }
309
+ $log_404 = $this->GetGlobalOption('log-404');
310
+ // If old setting is empty enable 404 logging by default
311
+ if ($log_404 === false) {
312
+ $this->SetGlobalOption('log-404', 'on');
313
+ }
314
+
315
+ $purge_log_404 = $this->GetGlobalOption('purge-404-log');
316
+ // If old setting is empty enable 404 purge log by default
317
+ if ($purge_log_404 === false) {
318
+ $this->SetGlobalOption('purge-404-log', 'on');
319
+ }
320
+ // load translations
321
+ load_plugin_textdomain('wp-security-audit-log', false, basename(dirname(__FILE__)) . '/languages/');
322
+
323
+ // tell the world we've just finished loading
324
+ $s = $this->profiler->Start('WSAL Init Hook');
325
+ do_action('wsal_init', $this);
326
+ $s->Stop();
327
+
328
+ // hide plugin
329
+ if ($this->settings->IsIncognito()) {
330
+ add_action('admin_head', array($this, 'HidePlugin'));
331
+ }
332
+
333
+ // Update routine.
334
+ $old_version = $this->GetOldVersion();
335
+ $new_version = $this->GetNewVersion();
336
+ if ( $old_version !== $new_version ) {
337
+ $this->Update( $old_version, $new_version );
338
+ }
339
+ }
340
+
341
+ /**
342
+ * Install all assets required for a useable system.
343
+ */
344
+ public function Install()
345
+ {
346
+ if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
347
+ ?><html>
348
+ <head>
349
+ <link rel="stylesheet" href="<?php
350
+ echo esc_attr($this->GetBaseUrl() . '/css/install-error.css?v=' . filemtime($this->GetBaseDir() . '/css/install-error.css'));
351
+ ?>" type="text/css" media="all"/>
352
+ </head><body>
353
+ <div class="warn-wrap">
354
+ <div class="warn-icon-tri"></div><div class="warn-icon-chr">!</div><div class="warn-icon-cir"></div>
355
+ <?php echo sprintf(__('You are using a version of PHP that is older than %s, which is no longer supported.<br/>Contact us on <a href="mailto:plugins@wpwhitesecurity.com">plugins@wpwhitesecurity.com</a> to help you switch the version of PHP you are using.'), self::MIN_PHP_VERSION); ?>
356
+ </div>
357
+ </body>
358
+ </html><?php
359
+ die(1);
360
+ }
361
+
362
+ // ensure that the system is installed and schema is correct
363
+ self::getConnector()->installAll();
364
+
365
+ $PreInstalled = $this->IsInstalled();
366
+
367
+ // if system already installed, do updates now (if any)
368
+ $OldVersion = $this->GetOldVersion();
369
+ $NewVersion = $this->GetNewVersion();
370
+
371
+ if ( $PreInstalled && $OldVersion != $NewVersion ) {
372
+ $this->Update( $OldVersion, $NewVersion );
373
+ }
374
+
375
+ // Load options from wp_options table or wp_sitemeta in multisite enviroment
376
+ $data = $this->read_options_prefixed("wsal-");
377
+ if (!empty($data)) {
378
+ $this->SetOptions($data);
379
+ }
380
+ $this->deleteAllOptions();
381
+
382
+ // if system wasn't installed, try migration now
383
+ if (!$PreInstalled && $this->CanMigrate()) {
384
+ $this->Migrate();
385
+ }
386
+
387
+ // setting the prunig date with the old value or the default value
388
+ $pruningDate = $this->settings->GetPruningDate();
389
+ $this->settings->SetPruningDate($pruningDate);
390
+
391
+ //$pruningEnabled = $this->settings->IsPruningLimitEnabled();
392
+ $this->settings->SetPruningLimitEnabled(true);
393
+ //setting the prunig limit with the old value or the default value
394
+ $pruningLimit = $this->settings->GetPruningLimit();
395
+ $this->settings->SetPruningLimit($pruningLimit);
396
+
397
+ $oldDisabled = $this->GetGlobalOption('disabled-alerts');
398
+ // If old setting is empty disable alert 2099 by default
399
+ if (empty($oldDisabled)) {
400
+ $this->settings->SetDisabledAlerts(array(2099));
401
+ }
402
+
403
+ $log_404 = $this->GetGlobalOption('log-404');
404
+ // If old setting is empty enable 404 logging by default
405
+ if ($log_404 === false) {
406
+ $this->SetGlobalOption('log-404', 'on');
407
+ }
408
+
409
+ $purge_log_404 = $this->GetGlobalOption('purge-404-log');
410
+ // If old setting is empty enable 404 purge log by default
411
+ if ($purge_log_404 === false) {
412
+ $this->SetGlobalOption('purge-404-log', 'on');
413
+ }
414
+
415
+ // install cleanup hook (remove older one if it exists)
416
+ wp_clear_scheduled_hook('wsal_cleanup');
417
+ wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
418
+ }
419
+
420
+ /**
421
+ * Run some code that updates critical components required for a newwer version.
422
+ *
423
+ * @param string $old_version The old version.
424
+ * @param string $new_version The new version.
425
+ */
426
+ public function Update( $old_version, $new_version ) {
427
+ // Update version in db.
428
+ $this->SetGlobalOption( 'version', $new_version );
429
+
430
+ // Disable all developer options.
431
+ //$this->settings->ClearDevOptions();
432
+
433
+ // Do version-to-version specific changes.
434
+ if ( -1 === version_compare( $old_version, $new_version ) ) {
435
+ $this->update_external_db_password();
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Method: Update external DB password.
441
+ *
442
+ * @since 2.6.3
443
+ */
444
+ public function update_external_db_password() {
445
+
446
+ // Get the passwords.
447
+ $external_password = $this->settings->GetAdapterConfig( 'adapter-password' );
448
+ $mirror_password = $this->settings->GetAdapterConfig( 'mirror-password' );
449
+ $archive_password = $this->settings->GetAdapterConfig( 'archive-password' );
450
+
451
+ // Update external db password.
452
+ if ( ! empty( $external_password ) ) {
453
+ // Decrypt the password using fallback method.
454
+ $password = $this->getConnector()->decryptString_fallback( $external_password );
455
+
456
+ // Encrypt the password with latest encryption method.
457
+ $encrypted_password = $this->getConnector()->encryptString( $password );
458
+
459
+ // Store the new password.
460
+ $this->settings->SetAdapterConfig( 'adapter-password', $encrypted_password );
461
+ }
462
+
463
+ // Update mirror db password.
464
+ if ( ! empty( $mirror_password ) ) {
465
+ // Decrypt the password using fallback method.
466
+ $password = $this->getConnector()->decryptString_fallback( $mirror_password );
467
+
468
+ // Encrypt the password with latest encryption method.
469
+ $encrypted_password = $this->getConnector()->encryptString( $password );
470
+
471
+ // Store the new password.
472
+ $this->settings->SetAdapterConfig( 'mirror-password', $encrypted_password );
473
+ }
474
+
475
+ // Update archive db password.
476
+ if ( ! empty( $archive_password ) ) {
477
+ // Decrypt the password using fallback method.
478
+ $password = $this->getConnector()->decryptString_fallback( $archive_password );
479
+
480
+ // Encrypt the password with latest encryption method.
481
+ $encrypted_password = $this->getConnector()->encryptString( $password );
482
+
483
+ // Store the new password.
484
+ $this->settings->SetAdapterConfig( 'archive-password', $encrypted_password );
485
+ }
486
+
487
+ }
488
+
489
+ /**
490
+ * Uninstall plugin.
491
+ */
492
+ public function Uninstall()
493
+ {
494
+ if ($this->GetGlobalOption("delete-data") == 1) {
495
+ self::getConnector()->uninstallAll();
496
+ $this->deleteAllOptions();
497
+ }
498
+ wp_clear_scheduled_hook('wsal_cleanup');
499
+ }
500
+
501
+ /**
502
+ * Delete from the options table of WP.
503
+ * @param string $prefix table prefix
504
+ * @return boolean query result
505
+ */
506
+ public function delete_options_prefixed($prefix)
507
+ {
508
+ global $wpdb;
509
+ if ($this->IsMultisite()) {
510
+ $table_name = $wpdb->prefix .'sitemeta';
511
+ $result = $wpdb->query("DELETE FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'");
512
+ } else {
513
+ $result = $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'");
514
+ }
515
+ return ($result) ? true : false;
516
+ }
517
+
518
+ /**
519
+ * Delete all the Wsal options from the options table of WP.
520
+ */
521
+ private function deleteAllOptions()
522
+ {
523
+ $flag = true;
524
+ while ($flag) {
525
+ $flag = $this->delete_options_prefixed(self::OPT_PRFX);
526
+ }
527
+ }
528
+
529
+ /**
530
+ * Read options from the options table of WP.
531
+ * @param string $prefix table prefix
532
+ * @return boolean query result
533
+ */
534
+ public function read_options_prefixed($prefix)
535
+ {
536
+ global $wpdb;
537
+ if ($this->IsMultisite()) {
538
+ $table_name = $wpdb->prefix .'sitemeta';
539
+ $results = $wpdb->get_results("SELECT site_id,meta_key,meta_value FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'", ARRAY_A);
540
+ } else {
541
+ $results = $wpdb->get_results("SELECT option_name,option_value FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'", ARRAY_A);
542
+ }
543
+ return $results;
544
+ }
545
+
546
+ /**
547
+ * Set options in the Wsal options table.
548
+ * @param array $data table prefix
549
+ */
550
+ public function SetOptions($data)
551
+ {
552
+ foreach ($data as $key => $option) {
553
+ $this->options = new WSAL_Models_Option();
554
+ if ($this->IsMultisite()) {
555
+ $this->options->SetOptionValue($option['meta_key'], $option['meta_value']);
556
+ } else {
557
+ $this->options->SetOptionValue($option['option_name'], $option['option_value']);
558
+ }
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Migrate data from old plugin.
564
+ */
565
+ public function Migrate()
566
+ {
567
+ global $wpdb;
568
+ static $migTypes = array(
569
+ 3000 => 5006
570
+ );
571
+
572
+ // load data
573
+ $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog_events';
574
+ $events = array();
575
+ foreach ($wpdb->get_results($sql, ARRAY_A) as $item) {
576
+ $events[$item['EventID']] = $item;
577
+ }
578
+ $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog';
579
+ $auditlog = $wpdb->get_results($sql, ARRAY_A);
580
+
581
+ // migrate using db logger
582
+ foreach ($auditlog as $entry) {
583
+ $data = array(
584
+ 'ClientIP' => $entry['UserIP'],
585
+ 'UserAgent' => '',
586
+ 'CurrentUserID' => $entry['UserID'],
587
+ );
588
+ if ($entry['UserName']) {
589
+ $data['Username'] = base64_decode($entry['UserName']);
590
+ }
591
+ $mesg = $events[$entry['EventID']]['EventDescription'];
592
+ $date = strtotime($entry['EventDate']);
593
+ $type = $entry['EventID'];
594
+ if (isset($migTypes[$type])) {
595
+ $type = $migTypes[$type];
596
+ }
597
+ // convert message from '<strong>%s</strong>' to '%Arg1%' format
598
+ $c = 0;
599
+ $n = '<strong>%s</strong>';
600
+ $l = strlen($n);
601
+ while (($pos = strpos($mesg, $n)) !== false) {
602
+ $mesg = substr_replace($mesg, '%MigratedArg' . ($c++) .'%', $pos, $l);
603
+ }
604
+ $data['MigratedMesg'] = $mesg;
605
+ // generate new meta data args
606
+ $temp = unserialize(base64_decode($entry['EventData']));
607
+ foreach ((array)$temp as $i => $item) {
608
+ $data['MigratedArg' . $i] = $item;
609
+ }
610
+ // send event data to logger!
611
+ foreach ($this->alerts->GetLoggers() as $logger) {
612
+ $logger->Log($type, $data, $date, $entry['BlogId'], true);
613
+ }
614
+ }
615
+
616
+ // migrate settings
617
+ $this->settings->SetAllowedPluginEditors(
618
+ get_option('WPPH_PLUGIN_ALLOW_CHANGE')
619
+ );
620
+ $this->settings->SetAllowedPluginViewers(
621
+ get_option('WPPH_PLUGIN_ALLOW_ACCESS')
622
+ );
623
+ $s = get_option('wpph_plugin_settings');
624
+ //$this->settings->SetPruningDate(($s->daysToKeep ? $s->daysToKeep : 30) . ' days');
625
+ //$this->settings->SetPruningLimit(min($s->eventsToKeep, 1));
626
+ $this->settings->SetViewPerPage(max($s->showEventsViewList, 5));
627
+ $this->settings->SetWidgetsEnabled(!!$s->showDW);
628
+ }
629
+
630
+ // </editor-fold>
631
+
632
+ // <editor-fold desc="Utility Methods">
633
+
634
+ /**
635
+ * @return string The current plugin version (according to plugin file metadata).
636
+ */
637
+ public function GetNewVersion()
638
+ {
639
+ $version = get_plugin_data(__FILE__, false, false);
640
+ return isset($version['Version']) ? $version['Version'] : '0.0.0';
641
+ }
642
+
643
+ /**
644
+ * @return string The plugin version as stored in DB (will be the old version during an update/install).
645
+ */
646
+ public function GetOldVersion()
647
+ {
648
+ return $this->GetGlobalOption('version', '0.0.0');
649
+ }
650
+
651
+ /**
652
+ * @internal To be called in admin header for hiding plugin form Plugins list.
653
+ */
654
+ public function HidePlugin()
655
+ {
656
+ $selectr = '';
657
+ $plugins = array('wp-security-audit-log');
658
+ foreach ($this->licensing->Plugins() as $plugin) {
659
+ $plugins[] = strtolower(str_replace(' ', '-', $plugin['PluginData']['Name']));
660
+ }
661
+ foreach ($plugins as $value) {
662
+ $selectr .= '.wp-list-table.plugins tr[data-slug="' . $value . '"], ';
663
+ }
664
+ ?><style type="text/css"> <?php echo rtrim($selectr, ", "); ?> { display: none; }</style><?php
665
+ }
666
+
667
+ /**
668
+ * Returns the class name of a particular file that contains the class.
669
+ * @param string $file File name.
670
+ * @return string Class name.
671
+ * @deprecated since 1.2.5 Use autoloader->GetClassFileClassName() instead.
672
+ */
673
+ public function GetClassFileClassName($file)
674
+ {
675
+ return $this->autoloader->GetClassFileClassName($file);
676
+ }
677
+
678
+ /**
679
+ * @return boolean Whether we are running on multisite or not.
680
+ */
681
+ public function IsMultisite()
682
+ {
683
+ return function_exists('is_multisite') && is_multisite();
684
+ }
685
+
686
+ /**
687
+ * Get a global option.
688
+ * @param string $option Option name.
689
+ * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
690
+ * @param string $prefix (Optional) A prefix used before option name.
691
+ * @return mixed Option's value or $default if option not set.
692
+ */
693
+ public function GetGlobalOption($option, $default = false, $prefix = self::OPT_PRFX)
694
+ {
695
+ $this->options = new WSAL_Models_Option();
696
+ return $this->options->GetOptionValue($prefix . $option, $default);
697
+ }
698
+
699
+ /**
700
+ * Set a global option.
701
+ * @param string $option Option name.
702
+ * @param mixed $value New value for option.
703
+ * @param string $prefix (Optional) A prefix used before option name.
704
+ */
705
+ public function SetGlobalOption($option, $value, $prefix = self::OPT_PRFX)
706
+ {
707
+ $this->options = new WSAL_Models_Option();
708
+ $this->options->SetOptionValue($prefix . $option, $value);
709
+ }
710
+
711
+ /**
712
+ * Get a user-specific option.
713
+ * @param string $option Option name.
714
+ * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
715
+ * @param string $prefix (Optional) A prefix used before option name.
716
+ * @return mixed Option's value or $default if option not set.
717
+ */
718
+ public function GetUserOption($option, $default = false, $prefix = self::OPT_PRFX)
719
+ {
720
+ $result = get_user_option($prefix . $option, get_current_user_id());
721
+ return $result === false ? $default : $result;
722
+ }
723
+
724
+ /**
725
+ * Set a user-specific option.
726
+ * @param string $option Option name.
727
+ * @param mixed $value New value for option.
728
+ * @param string $prefix (Optional) A prefix used before option name.
729
+ */
730
+ public function SetUserOption($option, $value, $prefix = self::OPT_PRFX)
731
+ {
732
+ update_user_option(get_current_user_id(), $prefix . $option, $value, false);
733
+ }
734
+
735
+ /**
736
+ * Run cleanup routines.
737
+ */
738
+ public function CleanUp()
739
+ {
740
+ $s = $this->profiler->Start('Clean Up');
741
+ foreach ($this->_cleanup_hooks as $hook) {
742
+ call_user_func($hook);
743
+ }
744
+ $s->Stop();
745
+ }
746
+
747
+ /**
748
+ * Add callback to be called when a cleanup operation is required.
749
+ * @param callable $hook
750
+ */
751
+ public function AddCleanupHook($hook)
752
+ {
753
+ $this->_cleanup_hooks[] = $hook;
754
+ }
755
+
756
+ /**
757
+ * Remove a callback from the cleanup callbacks list.
758
+ * @param callable $hook
759
+ */
760
+ public function RemoveCleanupHook($hook)
761
+ {
762
+ while (($pos = array_search($hook, $this->_cleanup_hooks)) !== false) {
763
+ unset($this->_cleanup_hooks[$pos]);
764
+ }
765
+ }
766
+
767
+ /**
768
+ * DB connection.
769
+ * @param mixed $config DB configuration.
770
+ * @return WSAL_Connector_ConnectorInterface
771
+ */
772
+ public static function getConnector($config = null, $reset = false)
773
+ {
774
+ return WSAL_Connector_ConnectorFactory::getConnector($config, $reset);
775
+ }
776
+
777
+ /**
778
+ * Do we have an existing installation? This only applies for version 1.0 onwards.
779
+ * @return boolean
780
+ */
781
+ public function IsInstalled()
782
+ {
783
+ return self::getConnector()->isInstalled();
784
+ }
785
+
786
+ /**
787
+ * @return boolean Whether the old plugin was present or not.
788
+ */
789
+ public function CanMigrate()
790
+ {
791
+ return self::getConnector()->canMigrate();
792
+ }
793
+
794
+ /**
795
+ * @return string Absolute URL to plugin directory WITHOUT final slash.
796
+ */
797
+ public function GetBaseUrl()
798
+ {
799
+ return plugins_url('', __FILE__);
800
+ }
801
+
802
+ /**
803
+ * @return string Full path to plugin directory WITH final slash.
804
+ */
805
+ public function GetBaseDir()
806
+ {
807
+ return plugin_dir_path(__FILE__);
808
+ }
809
+
810
+ /**
811
+ * @return string Plugin directory name.
812
+ */
813
+ public function GetBaseName()
814
+ {
815
+ return plugin_basename(__FILE__);
816
+ }
817
+
818
+ /**
819
+ * Load default configuration / data.
820
+ */
821
+ public function LoadDefaults()
822
+ {
823
+ $s = $this->profiler->Start('Load Defaults');
824
+ require_once('defaults.php');
825
+ $s->Stop();
826
+ }
827
+
828
+ /**
829
+ * WSAL-Notifications-Extension Functions.
830
+ */
831
+ public function GetNotificationsSetting($opt_prefix)
832
+ {
833
+ $this->options = new WSAL_Models_Option();
834
+ return $this->options->GetNotificationsSetting(self::OPT_PRFX . $opt_prefix);
835
+ }
836
+
837
+ public function GetNotification($id)
838
+ {
839
+ $this->options = new WSAL_Models_Option();
840
+ return $this->options->GetNotification($id);
841
+ }
842
+
843
+ public function DeleteByName($name)
844
+ {
845
+ $this->options = new WSAL_Models_Option();
846
+ return $this->options->DeleteByName($name);
847
+ }
848
+
849
+ public function DeleteByPrefix($opt_prefix)
850
+ {
851
+ $this->options = new WSAL_Models_Option();
852
+ return $this->options->DeleteByPrefix(self::OPT_PRFX . $opt_prefix);
853
+ }
854
+
855
+ public function CountNotifications($opt_prefix)
856
+ {
857
+ $this->options = new WSAL_Models_Option();
858
+ return $this->options->CountNotifications(self::OPT_PRFX . $opt_prefix);
859
+ }
860
+
861
+ public function UpdateGlobalOption($option, $value)
862
+ {
863
+ $this->options = new WSAL_Models_Option();
864
+ return $this->options->SetOptionValue($option, $value);
865
+ }
866
+
867
+ // </editor-fold>
868
  }
869
 
870
  // Profile WSAL load time