WP Security Audit Log - Version 2.4.4

Version Description

(2016-06-27) =

  • Security fix

    • Fixed a cross-site scripting vulnerability in the function AjaxDisableCustomField()
  • Bug fix

    • Fixed the hide plugin setting which was not working in some scenarios. Support Ticket
Download this release

Release Info

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

Code changes from version 2.4.3 to 2.4.4

Files changed (4) hide show
  1. classes/Settings.php +4 -4
  2. readme.txt +9 -1
  3. uninstall.php +1 -1
  4. wp-security-audit-log.php +609 -604
classes/Settings.php CHANGED
@@ -513,7 +513,7 @@ class WSAL_Settings {
513
  public function SetExcludedMonitoringUsers($users)
514
  {
515
  $this->_excluded_users = $users;
516
- $this->_plugin->SetGlobalOption('excluded-users', implode(',', $this->_excluded_users));
517
  }
518
  public function GetExcludedMonitoringUsers()
519
  {
@@ -529,7 +529,7 @@ class WSAL_Settings {
529
  protected $_excluded_roles = array();
530
  public function SetExcludedMonitoringRoles($roles){
531
  $this->_excluded_roles = $roles;
532
- $this->_plugin->SetGlobalOption('excluded-roles', implode(',', $this->_excluded_roles));
533
  }
534
  public function GetExcludedMonitoringRoles(){
535
  if(empty($this->_excluded_roles)){
@@ -544,7 +544,7 @@ class WSAL_Settings {
544
  protected $_excluded_custom = array();
545
  public function SetExcludedMonitoringCustom($custom){
546
  $this->_excluded_custom = $custom;
547
- $this->_plugin->SetGlobalOption('excluded-custom', implode(',', $this->_excluded_custom));
548
  }
549
  public function GetExcludedMonitoringCustom(){
550
  if(empty($this->_excluded_custom)){
@@ -560,7 +560,7 @@ class WSAL_Settings {
560
  protected $_excluded_ip = array();
561
  public function SetExcludedMonitoringIP($ip){
562
  $this->_excluded_ip = $ip;
563
- $this->_plugin->SetGlobalOption('excluded-ip', implode(',', $this->_excluded_ip));
564
  }
565
  public function GetExcludedMonitoringIP(){
566
  if(empty($this->_excluded_ip)){
513
  public function SetExcludedMonitoringUsers($users)
514
  {
515
  $this->_excluded_users = $users;
516
+ $this->_plugin->SetGlobalOption('excluded-users', esc_html(implode(',', $this->_excluded_users)));
517
  }
518
  public function GetExcludedMonitoringUsers()
519
  {
529
  protected $_excluded_roles = array();
530
  public function SetExcludedMonitoringRoles($roles){
531
  $this->_excluded_roles = $roles;
532
+ $this->_plugin->SetGlobalOption('excluded-roles', esc_html(implode(',', $this->_excluded_roles)));
533
  }
534
  public function GetExcludedMonitoringRoles(){
535
  if(empty($this->_excluded_roles)){
544
  protected $_excluded_custom = array();
545
  public function SetExcludedMonitoringCustom($custom){
546
  $this->_excluded_custom = $custom;
547
+ $this->_plugin->SetGlobalOption('excluded-custom', esc_html(implode(',', $this->_excluded_custom)));
548
  }
549
  public function GetExcludedMonitoringCustom(){
550
  if(empty($this->_excluded_custom)){
560
  protected $_excluded_ip = array();
561
  public function SetExcludedMonitoringIP($ip){
562
  $this->_excluded_ip = $ip;
563
+ $this->_plugin->SetGlobalOption('excluded-ip', esc_html(implode(',', $this->_excluded_ip)));
564
  }
565
  public function GetExcludedMonitoringIP(){
566
  if(empty($this->_excluded_ip)){
readme.txt CHANGED
@@ -7,7 +7,7 @@ License URI: http://www.gnu.org/licenses/gpl.html
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
8
  Requires at least: 3.6
9
  Tested up to: 4.5
10
- Stable tag: 2.4.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
 
@@ -176,6 +176,14 @@ Please refer to the [FAQs page](https://www.wpsecurityauditlog.com/documentation
176
 
177
  == Changelog ==
178
 
 
 
 
 
 
 
 
 
179
  = 2.4.3 (2016-06-01) =
180
 
181
  * **New Add-On Support**
7
  Tags: wordpress security plugin, wordpress security audit log, audit log, wordpress log, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, security audit trail, wordpress security alerts, wordpress monitor, wordpress security monitor, wordpress admin, wordpress admin monitoring, analytics, activity, admin, multisite, wordpress multisite, actions, dashboard, log, notification, wordpress monitoring, email notification, wordpress email alerts, tracking, user tracking, user activity report, wordpress audit trail
8
  Requires at least: 3.6
9
  Tested up to: 4.5
10
+ Stable tag: 2.4.4
11
 
12
  Keep an audit trail of all changes and under the hood WordPress activity to ensure productivity and thwart possible WordPress hacker attacks.
13
 
176
 
177
  == Changelog ==
178
 
179
+ = 2.4.4 (2016-06-27) =
180
+
181
+ * **Security fix**
182
+ * Fixed a [cross-site scripting vulnerability](http://www.wpwhitesecurity.com/wordpress-security/wordpress-security-glossary-terms-keywords/#cross-site-scripting) in the function AjaxDisableCustomField()
183
+
184
+ * **Bug fix**
185
+ * Fixed the hide plugin setting which was not working in some scenarios. [Support Ticket](https://wordpress.org/support/topic/hide-plugin-in-plugins-page-not-working)
186
+
187
  = 2.4.3 (2016-06-01) =
188
 
189
  * **New Add-On Support**
uninstall.php CHANGED
@@ -3,5 +3,5 @@
3
  // if uninstall not called from WordPress exit
4
  if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) exit();
5
 
6
- require('wp-security-audit-log.php');
7
  WpSecurityAuditLog::GetInstance()->Uninstall();
3
  // if uninstall not called from WordPress exit
4
  if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) exit();
5
 
6
+ require_once('wp-security-audit-log.php');
7
  WpSecurityAuditLog::GetInstance()->Uninstall();
wp-security-audit-log.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: WP Security Audit Log
4
  Plugin URI: http://www.wpsecurityauditlog.com/
5
  Description: Identify WordPress security issues before they become a problem. Keep track of everything happening on your WordPress including WordPress users activity. Similar to Windows Event Log and Linux Syslog, WP Security Audit Log generates a security alert for everything that happens on your WordPress blogs and websites. Use the Audit Log Viewer included in the plugin to see all the security alerts.
6
  Author: WP White Security
7
- Version: 2.4.3
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
@@ -27,612 +27,617 @@ License: GPL2
27
  */
28
 
29
  class WpSecurityAuditLog {
30
-
31
- // <editor-fold desc="Properties & Constants">
32
-
33
- const PLG_CLS_PRFX = 'WSAL_';
34
-
35
- const MIN_PHP_VERSION = '5.3.0';
36
-
37
- const OPT_PRFX = 'wsal-';
38
-
39
- /**
40
- * Views supervisor.
41
- * @var WSAL_ViewManager
42
- */
43
- public $views;
44
-
45
- /**
46
- * Logger supervisor.
47
- * @var WSAL_AlertManager
48
- */
49
- public $alerts;
50
-
51
- /**
52
- * Sensors supervisor.
53
- * @var WSAL_SensorManager
54
- */
55
- public $sensors;
56
-
57
- /**
58
- * Settings manager.
59
- * @var WSAL_Settings
60
- */
61
- public $settings;
62
-
63
- /**
64
- * Class loading manager.
65
- * @var WSAL_Autoloader
66
- */
67
- public $autoloader;
68
-
69
- /**
70
- * Constants manager.
71
- * @var WSAL_ConstantManager
72
- */
73
- public $constants;
74
-
75
- /**
76
- * Licenses manager.
77
- * @var WSAL_LicenseManager
78
- */
79
- public $licensing;
80
-
81
- /**
82
- * Simple profiler.
83
- * @var WSAL_SimpleProfiler
84
- */
85
- public $profiler;
86
-
87
- /**
88
- * Options.
89
- * @var WSAL_DB_Option
90
- */
91
- public $options;
92
-
93
- /**
94
- * Contains a list of cleanup callbacks.
95
- * @var callable[]
96
- */
97
- protected $_cleanup_hooks = array();
98
-
99
- // </editor-fold>
100
-
101
- // <editor-fold desc="Entry Points">
102
-
103
- /**
104
- * Standard singleton pattern.
105
- * WARNING! To ensure the system always works as expected, AVOID using this method.
106
- * Instead, make use of the plugin instance provided by 'wsal_init' action.
107
- * @return WpSecurityAuditLog Returns the current plugin instance.
108
- */
109
- public static function GetInstance(){
110
- static $instance = null;
111
- if(!$instance)$instance = new self();
112
- return $instance;
113
- }
114
-
115
- /**
116
- * Initialize plugin.
117
- */
118
- public function __construct(){
119
-
120
- require_once('classes/Helpers/DataHelper.php');
121
- // profiler has to be loaded manually
122
- require_once('classes/SimpleProfiler.php');
123
- $this->profiler = new WSAL_SimpleProfiler();
124
- require_once('classes/Models/ActiveRecord.php');
125
- require_once('classes/Models/Query.php');
126
- require_once('classes/Models/OccurrenceQuery.php');
127
- require_once('classes/Models/Option.php');
128
-
129
- // load autoloader and register base paths
130
- require_once('classes/Autoloader.php');
131
- $this->autoloader = new WSAL_Autoloader($this);
132
- $this->autoloader->Register(self::PLG_CLS_PRFX, $this->GetBaseDir() . 'classes' . DIRECTORY_SEPARATOR);
133
-
134
- // load dependencies
135
- $this->views = new WSAL_ViewManager($this);
136
- $this->alerts = new WSAL_AlertManager($this);
137
- $this->sensors = new WSAL_SensorManager($this);
138
- $this->settings = new WSAL_Settings($this);
139
- $this->constants = new WSAL_ConstantManager($this);
140
- $this->licensing = new WSAL_LicenseManager($this);
141
- $this->widgets = new WSAL_WidgetManager($this);
142
-
143
- // listen for installation event
144
- register_activation_hook(__FILE__, array($this, 'Install'));
145
-
146
- // listen for init event
147
- add_action('init', array($this, 'Init'));
148
-
149
- // listen for cleanup event
150
- add_action('wsal_cleanup', array($this, 'CleanUp'));
151
-
152
- // render wsal header
153
- add_action('admin_enqueue_scripts', array($this, 'RenderHeader'));
154
-
155
- // render wsal footer
156
- add_action('admin_footer', array($this, 'RenderFooter'));
157
-
158
- // handle admin Disable Custom Field
159
- add_action('wp_ajax_AjaxDisableCustomField', array($this, 'AjaxDisableCustomField'));
160
- }
161
-
162
- /**
163
- * @internal Start to trigger the events after installation.
164
- */
165
- public function Init(){
166
- WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
167
- }
168
-
169
-
170
- /**
171
- * @internal Render plugin stuff in page header.
172
- */
173
- public function RenderHeader(){
174
- // common.css?
175
- }
176
-
177
- /**
178
- * Disable Custom Field through ajax.
179
- * @internal
180
- */
181
- public function AjaxDisableCustomField(){
182
- $fields = $this->GetGlobalOption('excluded-custom');
183
- if ( isset($fields) && $fields != "") {
184
- $fields .= ",".$_POST['notice'];
185
- } else {
186
- $fields = $_POST['notice'];
187
- }
188
- $this->SetGlobalOption('excluded-custom', $fields);
189
- echo 'Custom Field '.$_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';
190
- die;
191
- }
192
-
193
- /**
194
- * @internal Render plugin stuff in page footer.
195
- */
196
- public function RenderFooter(){
197
- wp_enqueue_script(
198
- 'wsal-common',
199
- $this->GetBaseUrl() . '/js/common.js',
200
- array('jquery'),
201
- filemtime($this->GetBaseDir() . '/js/common.js')
202
- );
203
- }
204
-
205
- /**
206
- * @internal Load the rest of the system.
207
- */
208
- public function Load(){
209
-
210
- $optionsTable = new WSAL_Models_Option();
211
- if (!$optionsTable->IsInstalled()) {
212
- $optionsTable->Install();
213
- //setting the prunig date with the old value or the default value
214
- $pruningDate = $this->settings->GetPruningDate();
215
- $this->settings->SetPruningDate($pruningDate);
216
-
217
- $pruningEnabled = $this->settings->IsPruningLimitEnabled();
218
- $this->settings->SetPruningLimitEnabled($pruningEnabled);
219
- //setting the prunig limit with the old value or the default value
220
- $pruningLimit = $this->settings->GetPruningLimit();
221
- $this->settings->SetPruningLimit($pruningLimit);
222
- }
223
- // load translations
224
- load_plugin_textdomain('wp-security-audit-log', false, basename( dirname( __FILE__ ) ) . '/languages/');
225
-
226
- // tell the world we've just finished loading
227
- $s = $this->profiler->Start('WSAL Init Hook');
228
- do_action('wsal_init', $this);
229
- $s->Stop();
230
-
231
- // hide plugin
232
- if($this->settings->IsIncognito())
233
- add_action('admin_head', array($this, 'HidePlugin'));
234
- }
235
-
236
- /**
237
- * Install all assets required for a useable system.
238
- */
239
- public function Install(){
240
- if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
241
- ?><html>
242
- <head>
243
- <link rel="stylesheet" href="<?php
244
- echo esc_attr($this->GetBaseUrl() . '/css/install-error.css?v=' . filemtime($this->GetBaseDir() . '/css/install-error.css'));
245
- ?>" type="text/css" media="all"/>
246
- </head><body>
247
- <div class="warn-wrap">
248
- <div class="warn-icon-tri"></div><div class="warn-icon-chr">!</div><div class="warn-icon-cir"></div>
249
- <?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); ?>
250
- </div>
251
- </body>
252
- </html><?php
253
- die(1);
254
- }
255
-
256
- // ensure that the system is installed and schema is correct
257
- self::getConnector()->installAll();
258
-
259
- $PreInstalled = $this->IsInstalled();
260
-
261
- // if system already installed, do updates now (if any)
262
- $OldVersion = $this->GetOldVersion();
263
- $NewVersion = $this->GetNewVersion();
264
- if ($PreInstalled && $OldVersion != $NewVersion) $this->Update($OldVersion, $NewVersion);
265
-
266
- // Load options from wp_options table or wp_sitemeta in multisite enviroment
267
- $data = $this->read_options_prefixed("wsal-");
268
- if (!empty($data)) {
269
- $this->SetOptions($data);
270
- }
271
- $this->deleteAllOptions();
272
-
273
- // if system wasn't installed, try migration now
274
- if (!$PreInstalled && $this->CanMigrate()) $this->Migrate();
275
-
276
- //setting the prunig date with the old value or the default value
277
- $pruningDate = $this->settings->GetPruningDate();
278
- $this->settings->SetPruningDate($pruningDate);
279
-
280
- //$pruningEnabled = $this->settings->IsPruningLimitEnabled();
 
281
  $this->settings->SetPruningLimitEnabled(true);
282
- //setting the prunig limit with the old value or the default value
283
- $pruningLimit = $this->settings->GetPruningLimit();
284
- $this->settings->SetPruningLimit($pruningLimit);
285
-
286
- // install cleanup hook (remove older one if it exists)
287
- wp_clear_scheduled_hook('wsal_cleanup');
288
- wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
289
- }
290
-
291
- /**
292
- * Run some code that updates critical components required for a newwer version.
293
- * @param string $old_version The old version.
294
- * @param string $new_version The new version.
295
- */
296
- public function Update($old_version, $new_version){
297
- // update version in db
298
- $this->GetGlobalOption('version', $new_version);
299
-
300
- // disable all developer options
301
- //$this->settings->ClearDevOptions();
302
-
303
- // do version-to-version specific changes
304
- if(version_compare($old_version, '1.2.3') == -1){
305
- // ... an example
306
- }
307
- }
308
-
309
- /**
310
- * Uninstall plugin.
311
- */
312
- public function Uninstall(){
313
- if ($this->GetGlobalOption("delete-data") == 1) {
314
- self::getConnector()->uninstallAll();
315
- $this->deleteAllOptions();
316
- }
317
- wp_clear_scheduled_hook('wsal_cleanup');
318
- }
319
-
320
- public function delete_options_prefixed( $prefix ) {
321
- global $wpdb;
322
-
323
- if ( $this->IsMultisite() ) {
324
- $table_name = $wpdb->prefix .'sitemeta';
325
- $result = $wpdb->query( "DELETE FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'" );
326
- } else {
327
- $result = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'" );
328
- }
329
- return ($result) ? true : false;
330
- }
331
-
332
- private function deleteAllOptions() {
333
- $flag = true;
334
- while ( $flag ) {
335
- $flag = $this->delete_options_prefixed( 'wsal-' );
336
- }
337
- }
338
-
339
- public function read_options_prefixed( $prefix ) {
340
- global $wpdb;
341
- if ( $this->IsMultisite() ) {
342
- $table_name = $wpdb->prefix .'sitemeta';
343
- $results = $wpdb->get_results( "SELECT site_id,meta_key,meta_value FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'", ARRAY_A );
344
- } else {
345
- $results = $wpdb->get_results( "SELECT option_name,option_value FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'", ARRAY_A );
346
- }
347
- return $results;
348
- }
349
-
350
- public function SetOptions($data){
351
- foreach($data as $key => $option) {
352
- $this->options = new WSAL_Models_Option();
353
- if ( $this->IsMultisite() ) {
354
- $this->options->SetOptionValue($option['meta_key'], $option['meta_value']);
355
- } else {
356
- $this->options->SetOptionValue($option['option_name'], $option['option_value']);
357
- }
358
- }
359
- }
360
-
361
- /**
362
- * Migrate data from old plugin.
363
- */
364
- public function Migrate(){
365
- global $wpdb;
366
- static $migTypes = array(
367
- 3000 => 5006
368
- );
369
-
370
- // load data
371
- $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog_events';
372
- $events = array();
373
- foreach($wpdb->get_results($sql, ARRAY_A) as $item)
374
- $events[$item['EventID']] = $item;
375
- $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog';
376
- $auditlog = $wpdb->get_results($sql, ARRAY_A);
377
-
378
- // migrate using db logger
379
- foreach($auditlog as $entry){
380
- $data = array(
381
- 'ClientIP' => $entry['UserIP'],
382
- 'UserAgent' => '',
383
- 'CurrentUserID' => $entry['UserID'],
384
- );
385
- if($entry['UserName'])
386
- $data['Username'] = base64_decode($entry['UserName']);
387
- $mesg = $events[$entry['EventID']]['EventDescription'];
388
- $date = strtotime($entry['EventDate']);
389
- $type = $entry['EventID'];
390
- if(isset($migTypes[$type]))$type = $migTypes[$type];
391
- // convert message from '<strong>%s</strong>' to '%Arg1%' format
392
- $c = 0; $n = '<strong>%s</strong>'; $l = strlen($n);
393
- while(($pos = strpos($mesg, $n)) !== false){
394
- $mesg = substr_replace($mesg, '%MigratedArg' . ($c++) .'%', $pos, $l);
395
- }
396
- $data['MigratedMesg'] = $mesg;
397
- // generate new meta data args
398
- $temp = unserialize(base64_decode($entry['EventData']));
399
- foreach((array)$temp as $i => $item)
400
- $data['MigratedArg' . $i] = $item;
401
- // send event data to logger!
402
- foreach($this->alerts->GetLoggers() as $logger){
403
- $logger->Log($type, $data, $date, $entry['BlogId'], true);
404
- }
405
- }
406
-
407
- // migrate settings
408
- $this->settings->SetAllowedPluginEditors(
409
- get_option('WPPH_PLUGIN_ALLOW_CHANGE')
410
- );
411
- $this->settings->SetAllowedPluginViewers(
412
- get_option('WPPH_PLUGIN_ALLOW_ACCESS')
413
- );
414
- $s = get_option('wpph_plugin_settings');
415
- //$this->settings->SetPruningDate(($s->daysToKeep ? $s->daysToKeep : 30) . ' days');
416
- //$this->settings->SetPruningLimit(min($s->eventsToKeep, 1));
417
- $this->settings->SetViewPerPage(max($s->showEventsViewList, 5));
418
- $this->settings->SetWidgetsEnabled(!!$s->showDW);
419
- }
420
-
421
- // </editor-fold>
422
-
423
- // <editor-fold desc="Utility Methods">
424
-
425
- /**
426
- * @return string The current plugin version (according to plugin file metadata).
427
- */
428
- public function GetNewVersion(){
429
- $version = get_plugin_data(__FILE__, false, false);
430
- return isset($version['Version']) ? $version['Version'] : '0.0.0';
431
- }
432
-
433
- /**
434
- * @return string The plugin version as stored in DB (will be the old version during an update/install).
435
- */
436
- public function GetOldVersion(){
437
- return $this->GetGlobalOption('version', '0.0.0');
438
- }
439
-
440
- /**
441
- * @internal To be called in admin header for hiding plugin form Plugins list.
442
- */
443
- public function HidePlugin(){
444
- $selectr = '.wp-list-table.plugins #';
445
- $plugins = array('wp-security-audit-log');
446
- foreach ($this->licensing->Plugins() as $plugin)
447
- $plugins[] = strtolower(str_replace(' ', '-', $plugin['PluginData']['Name']));
448
- ?><style type="text/css"> <?php echo $selectr . implode(', ' . $selectr, $plugins); ?> { display: none; }</style><?php
449
- }
450
-
451
- /**
452
- * Returns the class name of a particular file that contains the class.
453
- * @param string $file File name.
454
- * @return string Class name.
455
- * @deprecated since 1.2.5 Use autoloader->GetClassFileClassName() instead.
456
- */
457
- public function GetClassFileClassName($file){
458
- return $this->autoloader->GetClassFileClassName($file);
459
- }
460
-
461
- /**
462
- * @return boolean Whether we are running on multisite or not.
463
- */
464
- public function IsMultisite(){
465
- return function_exists('is_multisite') && is_multisite();
466
- }
467
-
468
- /**
469
- * Get a global option.
470
- * @param string $option Option name.
471
- * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
472
- * @param string $prefix (Optional) A prefix used before option name.
473
- * @return mixed Option's value or $default if option not set.
474
- */
475
- public function GetGlobalOption($option, $default = false, $prefix = self::OPT_PRFX){
476
- //$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
477
- //var_dump($fn($prefix . $option, $default));
478
- //return $fn($prefix . $option, $default);
479
- $this->options = new WSAL_Models_Option();
480
- return $this->options->GetOptionValue($prefix . $option, $default);
481
- }
482
-
483
- /**
484
- * Set a global option.
485
- * @param string $option Option name.
486
- * @param mixed $value New value for option.
487
- * @param string $prefix (Optional) A prefix used before option name.
488
- */
489
- public function SetGlobalOption($option, $value, $prefix = self::OPT_PRFX){
490
- //$fn = $this->IsMultisite() ? 'update_site_option' : 'update_option';
491
- //$fn($prefix . $option, $value);
492
- $this->options = new WSAL_Models_Option();
493
- $this->options->SetOptionValue($prefix . $option, $value);
494
- }
495
-
496
- /**
497
- * Get a user-specific option.
498
- * @param string $option Option name.
499
- * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
500
- * @param string $prefix (Optional) A prefix used before option name.
501
- * @return mixed Option's value or $default if option not set.
502
- */
503
- public function GetUserOption($option, $default = false, $prefix = self::OPT_PRFX){
504
- $result = get_user_option($prefix . $option, get_current_user_id());
505
- return $result === false ? $default : $result;
506
- }
507
-
508
- /**
509
- * Set a user-specific option.
510
- * @param string $option Option name.
511
- * @param mixed $value New value for option.
512
- * @param string $prefix (Optional) A prefix used before option name.
513
- */
514
- public function SetUserOption($option, $value, $prefix = self::OPT_PRFX){
515
- update_user_option(get_current_user_id(), $prefix . $option, $value, false);
516
- }
517
-
518
- /**
519
- * Run cleanup routines.
520
- */
521
- public function CleanUp(){
522
- $s = $this->profiler->Start('Clean Up');
523
- foreach($this->_cleanup_hooks as $hook)
524
- call_user_func($hook);
525
- $s->Stop();
526
- }
527
-
528
- /**
529
- * Add callback to be called when a cleanup operation is required.
530
- * @param callable $hook
531
- */
532
- public function AddCleanupHook($hook){
533
- $this->_cleanup_hooks[] = $hook;
534
- }
535
-
536
- /**
537
- * Remove a callback from the cleanup callbacks list.
538
- * @param callable $hook
539
- */
540
- public function RemoveCleanupHook($hook){
541
- while(($pos = array_search($hook, $this->_cleanup_hooks)) !== false)
542
- unset($this->_cleanup_hooks[$pos]);
543
- }
544
-
545
- public static function getConnector($config = null)
546
- {
547
- require_once('classes/Connector/ConnectorFactory.php');
548
- return WSAL_Connector_ConnectorFactory::getConnector($config);
549
- }
550
-
551
- /**
552
- * Do we have an existing installation? This only applies for version 1.0 onwards.
553
- * @return boolean
554
- */
555
- public function IsInstalled(){
556
- return self::getConnector()->isInstalled();
557
- }
558
-
559
- /**
560
- * @return boolean Whether the old plugin was present or not.
561
- */
562
- public function CanMigrate(){
563
- return self::getConnector()->canMigrate();
564
- }
565
-
566
- /**
567
- * @return string Absolute URL to plugin directory WITHOUT final slash.
568
- */
569
- public function GetBaseUrl(){
570
- return plugins_url('', __FILE__);
571
- }
572
-
573
- /**
574
- * @return string Full path to plugin directory WITH final slash.
575
- */
576
- public function GetBaseDir(){
577
- return plugin_dir_path(__FILE__);
578
- }
579
-
580
- /**
581
- * @return string Plugin directory name.
582
- */
583
- public function GetBaseName(){
584
- return plugin_basename(__FILE__);
585
- }
586
-
587
- /**
588
- * Load default configuration / data.
589
- */
590
- public function LoadDefaults(){
591
- $s = $this->profiler->Start('Load Defaults');
592
- require_once('defaults.php');
593
- $s->Stop();
594
- }
595
-
596
- /**
597
- * WSAL-Notifications-Extension Functions.
598
- */
599
- public function GetNotificationsSetting($opt_prefix)
600
- {
601
- $this->options = new WSAL_Models_Option();
602
- return $this->options->GetNotificationsSetting(self::OPT_PRFX . $opt_prefix);
603
- }
604
-
605
- public function GetNotification($id)
 
 
 
 
606
  {
607
  $this->options = new WSAL_Models_Option();
608
- return $this->options->GetNotification($id);
609
- }
610
-
611
- public function DeleteByName($name)
612
- {
613
- $this->options = new WSAL_Models_Option();
614
- return $this->options->DeleteByName($name);
615
- }
616
-
617
- public function DeleteByPrefix($opt_prefix)
618
- {
619
- $this->options = new WSAL_Models_Option();
620
- return $this->options->DeleteByPrefix(self::OPT_PRFX . $opt_prefix);
621
- }
622
-
623
- public function CountNotifications($opt_prefix)
624
- {
625
- $this->options = new WSAL_Models_Option();
626
- return $this->options->CountNotifications(self::OPT_PRFX . $opt_prefix);
627
- }
628
-
629
- public function UpdateGlobalOption($option, $value)
630
- {
631
- $this->options = new WSAL_Models_Option();
632
- return $this->options->SetOptionValue($option, $value);
633
- }
634
-
635
- // </editor-fold>
636
  }
637
 
638
  // 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.4.4
8
  Text Domain: wp-security-audit-log
9
  Author URI: http://www.wpsecurityauditlog.com/
10
  License: GPL2
27
  */
28
 
29
  class WpSecurityAuditLog {
30
+
31
+ // <editor-fold desc="Properties & Constants">
32
+
33
+ const PLG_CLS_PRFX = 'WSAL_';
34
+
35
+ const MIN_PHP_VERSION = '5.3.0';
36
+
37
+ const OPT_PRFX = 'wsal-';
38
+
39
+ /**
40
+ * Views supervisor.
41
+ * @var WSAL_ViewManager
42
+ */
43
+ public $views;
44
+
45
+ /**
46
+ * Logger supervisor.
47
+ * @var WSAL_AlertManager
48
+ */
49
+ public $alerts;
50
+
51
+ /**
52
+ * Sensors supervisor.
53
+ * @var WSAL_SensorManager
54
+ */
55
+ public $sensors;
56
+
57
+ /**
58
+ * Settings manager.
59
+ * @var WSAL_Settings
60
+ */
61
+ public $settings;
62
+
63
+ /**
64
+ * Class loading manager.
65
+ * @var WSAL_Autoloader
66
+ */
67
+ public $autoloader;
68
+
69
+ /**
70
+ * Constants manager.
71
+ * @var WSAL_ConstantManager
72
+ */
73
+ public $constants;
74
+
75
+ /**
76
+ * Licenses manager.
77
+ * @var WSAL_LicenseManager
78
+ */
79
+ public $licensing;
80
+
81
+ /**
82
+ * Simple profiler.
83
+ * @var WSAL_SimpleProfiler
84
+ */
85
+ public $profiler;
86
+
87
+ /**
88
+ * Options.
89
+ * @var WSAL_DB_Option
90
+ */
91
+ public $options;
92
+
93
+ /**
94
+ * Contains a list of cleanup callbacks.
95
+ * @var callable[]
96
+ */
97
+ protected $_cleanup_hooks = array();
98
+
99
+ // </editor-fold>
100
+
101
+ // <editor-fold desc="Entry Points">
102
+
103
+ /**
104
+ * Standard singleton pattern.
105
+ * WARNING! To ensure the system always works as expected, AVOID using this method.
106
+ * Instead, make use of the plugin instance provided by 'wsal_init' action.
107
+ * @return WpSecurityAuditLog Returns the current plugin instance.
108
+ */
109
+ public static function GetInstance(){
110
+ static $instance = null;
111
+ if(!$instance)$instance = new self();
112
+ return $instance;
113
+ }
114
+
115
+ /**
116
+ * Initialize plugin.
117
+ */
118
+ public function __construct(){
119
+
120
+ require_once('classes/Helpers/DataHelper.php');
121
+ // profiler has to be loaded manually
122
+ require_once('classes/SimpleProfiler.php');
123
+ $this->profiler = new WSAL_SimpleProfiler();
124
+ require_once('classes/Models/ActiveRecord.php');
125
+ require_once('classes/Models/Query.php');
126
+ require_once('classes/Models/OccurrenceQuery.php');
127
+ require_once('classes/Models/Option.php');
128
+
129
+ // load autoloader and register base paths
130
+ require_once('classes/Autoloader.php');
131
+ $this->autoloader = new WSAL_Autoloader($this);
132
+ $this->autoloader->Register(self::PLG_CLS_PRFX, $this->GetBaseDir() . 'classes' . DIRECTORY_SEPARATOR);
133
+
134
+ // load dependencies
135
+ $this->views = new WSAL_ViewManager($this);
136
+ $this->alerts = new WSAL_AlertManager($this);
137
+ $this->sensors = new WSAL_SensorManager($this);
138
+ $this->settings = new WSAL_Settings($this);
139
+ $this->constants = new WSAL_ConstantManager($this);
140
+ $this->licensing = new WSAL_LicenseManager($this);
141
+ $this->widgets = new WSAL_WidgetManager($this);
142
+
143
+ // listen for installation event
144
+ register_activation_hook(__FILE__, array($this, 'Install'));
145
+
146
+ // listen for init event
147
+ add_action('init', array($this, 'Init'));
148
+
149
+ // listen for cleanup event
150
+ add_action('wsal_cleanup', array($this, 'CleanUp'));
151
+
152
+ // render wsal header
153
+ add_action('admin_enqueue_scripts', array($this, 'RenderHeader'));
154
+
155
+ // render wsal footer
156
+ add_action('admin_footer', array($this, 'RenderFooter'));
157
+
158
+ // handle admin Disable Custom Field
159
+ add_action('wp_ajax_AjaxDisableCustomField', array($this, 'AjaxDisableCustomField'));
160
+ }
161
+
162
+ /**
163
+ * @internal Start to trigger the events after installation.
164
+ */
165
+ public function Init(){
166
+ WpSecurityAuditLog::GetInstance()->sensors->HookEvents();
167
+ }
168
+
169
+
170
+ /**
171
+ * @internal Render plugin stuff in page header.
172
+ */
173
+ public function RenderHeader(){
174
+ // common.css?
175
+ }
176
+
177
+ /**
178
+ * Disable Custom Field through ajax.
179
+ * @internal
180
+ */
181
+ public function AjaxDisableCustomField(){
182
+ $fields = $this->GetGlobalOption('excluded-custom');
183
+ if (isset($fields) && $fields != "") {
184
+ $fields .= "," . esc_html($_POST['notice']);
185
+ } else {
186
+ $fields = esc_html($_POST['notice']);
187
+ }
188
+ $this->SetGlobalOption('excluded-custom', $fields);
189
+ echo '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';
190
+ die;
191
+ }
192
+
193
+ /**
194
+ * @internal Render plugin stuff in page footer.
195
+ */
196
+ public function RenderFooter(){
197
+ wp_enqueue_script(
198
+ 'wsal-common',
199
+ $this->GetBaseUrl() . '/js/common.js',
200
+ array('jquery'),
201
+ filemtime($this->GetBaseDir() . '/js/common.js')
202
+ );
203
+ }
204
+
205
+ /**
206
+ * @internal Load the rest of the system.
207
+ */
208
+ public function Load(){
209
+
210
+ $optionsTable = new WSAL_Models_Option();
211
+ if (!$optionsTable->IsInstalled()) {
212
+ $optionsTable->Install();
213
+ //setting the prunig date with the old value or the default value
214
+ $pruningDate = $this->settings->GetPruningDate();
215
+ $this->settings->SetPruningDate($pruningDate);
216
+
217
+ $pruningEnabled = $this->settings->IsPruningLimitEnabled();
218
+ $this->settings->SetPruningLimitEnabled($pruningEnabled);
219
+ //setting the prunig limit with the old value or the default value
220
+ $pruningLimit = $this->settings->GetPruningLimit();
221
+ $this->settings->SetPruningLimit($pruningLimit);
222
+ }
223
+ // load translations
224
+ load_plugin_textdomain('wp-security-audit-log', false, basename(dirname(__FILE__)) . '/languages/');
225
+
226
+ // tell the world we've just finished loading
227
+ $s = $this->profiler->Start('WSAL Init Hook');
228
+ do_action('wsal_init', $this);
229
+ $s->Stop();
230
+
231
+ // hide plugin
232
+ if ($this->settings->IsIncognito()) {
233
+ add_action('admin_head', array($this, 'HidePlugin'));
234
+ }
235
+ }
236
+
237
+ /**
238
+ * Install all assets required for a useable system.
239
+ */
240
+ public function Install(){
241
+ if (version_compare(PHP_VERSION, self::MIN_PHP_VERSION) < 0) {
242
+ ?><html>
243
+ <head>
244
+ <link rel="stylesheet" href="<?php
245
+ echo esc_attr($this->GetBaseUrl() . '/css/install-error.css?v=' . filemtime($this->GetBaseDir() . '/css/install-error.css'));
246
+ ?>" type="text/css" media="all"/>
247
+ </head><body>
248
+ <div class="warn-wrap">
249
+ <div class="warn-icon-tri"></div><div class="warn-icon-chr">!</div><div class="warn-icon-cir"></div>
250
+ <?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); ?>
251
+ </div>
252
+ </body>
253
+ </html><?php
254
+ die(1);
255
+ }
256
+
257
+ // ensure that the system is installed and schema is correct
258
+ self::getConnector()->installAll();
259
+
260
+ $PreInstalled = $this->IsInstalled();
261
+
262
+ // if system already installed, do updates now (if any)
263
+ $OldVersion = $this->GetOldVersion();
264
+ $NewVersion = $this->GetNewVersion();
265
+ if ($PreInstalled && $OldVersion != $NewVersion) $this->Update($OldVersion, $NewVersion);
266
+
267
+ // Load options from wp_options table or wp_sitemeta in multisite enviroment
268
+ $data = $this->read_options_prefixed("wsal-");
269
+ if (!empty($data)) {
270
+ $this->SetOptions($data);
271
+ }
272
+ $this->deleteAllOptions();
273
+
274
+ // if system wasn't installed, try migration now
275
+ if (!$PreInstalled && $this->CanMigrate()) $this->Migrate();
276
+
277
+ //setting the prunig date with the old value or the default value
278
+ $pruningDate = $this->settings->GetPruningDate();
279
+ $this->settings->SetPruningDate($pruningDate);
280
+
281
+ //$pruningEnabled = $this->settings->IsPruningLimitEnabled();
282
  $this->settings->SetPruningLimitEnabled(true);
283
+ //setting the prunig limit with the old value or the default value
284
+ $pruningLimit = $this->settings->GetPruningLimit();
285
+ $this->settings->SetPruningLimit($pruningLimit);
286
+
287
+ // install cleanup hook (remove older one if it exists)
288
+ wp_clear_scheduled_hook('wsal_cleanup');
289
+ wp_schedule_event(current_time('timestamp') + 600, 'hourly', 'wsal_cleanup');
290
+ }
291
+
292
+ /**
293
+ * Run some code that updates critical components required for a newwer version.
294
+ * @param string $old_version The old version.
295
+ * @param string $new_version The new version.
296
+ */
297
+ public function Update($old_version, $new_version){
298
+ // update version in db
299
+ $this->GetGlobalOption('version', $new_version);
300
+
301
+ // disable all developer options
302
+ //$this->settings->ClearDevOptions();
303
+
304
+ // do version-to-version specific changes
305
+ if(version_compare($old_version, '1.2.3') == -1){
306
+ // ... an example
307
+ }
308
+ }
309
+
310
+ /**
311
+ * Uninstall plugin.
312
+ */
313
+ public function Uninstall(){
314
+ if ($this->GetGlobalOption("delete-data") == 1) {
315
+ self::getConnector()->uninstallAll();
316
+ $this->deleteAllOptions();
317
+ }
318
+ wp_clear_scheduled_hook('wsal_cleanup');
319
+ }
320
+
321
+ public function delete_options_prefixed( $prefix ) {
322
+ global $wpdb;
323
+
324
+ if ( $this->IsMultisite() ) {
325
+ $table_name = $wpdb->prefix .'sitemeta';
326
+ $result = $wpdb->query( "DELETE FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'" );
327
+ } else {
328
+ $result = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'" );
329
+ }
330
+ return ($result) ? true : false;
331
+ }
332
+
333
+ private function deleteAllOptions() {
334
+ $flag = true;
335
+ while ( $flag ) {
336
+ $flag = $this->delete_options_prefixed( 'wsal-' );
337
+ }
338
+ }
339
+
340
+ public function read_options_prefixed( $prefix ) {
341
+ global $wpdb;
342
+ if ( $this->IsMultisite() ) {
343
+ $table_name = $wpdb->prefix .'sitemeta';
344
+ $results = $wpdb->get_results( "SELECT site_id,meta_key,meta_value FROM {$table_name} WHERE meta_key LIKE '{$prefix}%'", ARRAY_A );
345
+ } else {
346
+ $results = $wpdb->get_results( "SELECT option_name,option_value FROM {$wpdb->options} WHERE option_name LIKE '{$prefix}%'", ARRAY_A );
347
+ }
348
+ return $results;
349
+ }
350
+
351
+ public function SetOptions($data){
352
+ foreach($data as $key => $option) {
353
+ $this->options = new WSAL_Models_Option();
354
+ if ( $this->IsMultisite() ) {
355
+ $this->options->SetOptionValue($option['meta_key'], $option['meta_value']);
356
+ } else {
357
+ $this->options->SetOptionValue($option['option_name'], $option['option_value']);
358
+ }
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Migrate data from old plugin.
364
+ */
365
+ public function Migrate(){
366
+ global $wpdb;
367
+ static $migTypes = array(
368
+ 3000 => 5006
369
+ );
370
+
371
+ // load data
372
+ $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog_events';
373
+ $events = array();
374
+ foreach($wpdb->get_results($sql, ARRAY_A) as $item)
375
+ $events[$item['EventID']] = $item;
376
+ $sql = 'SELECT * FROM ' . $wpdb->base_prefix . 'wordpress_auditlog';
377
+ $auditlog = $wpdb->get_results($sql, ARRAY_A);
378
+
379
+ // migrate using db logger
380
+ foreach($auditlog as $entry){
381
+ $data = array(
382
+ 'ClientIP' => $entry['UserIP'],
383
+ 'UserAgent' => '',
384
+ 'CurrentUserID' => $entry['UserID'],
385
+ );
386
+ if($entry['UserName'])
387
+ $data['Username'] = base64_decode($entry['UserName']);
388
+ $mesg = $events[$entry['EventID']]['EventDescription'];
389
+ $date = strtotime($entry['EventDate']);
390
+ $type = $entry['EventID'];
391
+ if(isset($migTypes[$type]))$type = $migTypes[$type];
392
+ // convert message from '<strong>%s</strong>' to '%Arg1%' format
393
+ $c = 0; $n = '<strong>%s</strong>'; $l = strlen($n);
394
+ while(($pos = strpos($mesg, $n)) !== false){
395
+ $mesg = substr_replace($mesg, '%MigratedArg' . ($c++) .'%', $pos, $l);
396
+ }
397
+ $data['MigratedMesg'] = $mesg;
398
+ // generate new meta data args
399
+ $temp = unserialize(base64_decode($entry['EventData']));
400
+ foreach((array)$temp as $i => $item)
401
+ $data['MigratedArg' . $i] = $item;
402
+ // send event data to logger!
403
+ foreach($this->alerts->GetLoggers() as $logger){
404
+ $logger->Log($type, $data, $date, $entry['BlogId'], true);
405
+ }
406
+ }
407
+
408
+ // migrate settings
409
+ $this->settings->SetAllowedPluginEditors(
410
+ get_option('WPPH_PLUGIN_ALLOW_CHANGE')
411
+ );
412
+ $this->settings->SetAllowedPluginViewers(
413
+ get_option('WPPH_PLUGIN_ALLOW_ACCESS')
414
+ );
415
+ $s = get_option('wpph_plugin_settings');
416
+ //$this->settings->SetPruningDate(($s->daysToKeep ? $s->daysToKeep : 30) . ' days');
417
+ //$this->settings->SetPruningLimit(min($s->eventsToKeep, 1));
418
+ $this->settings->SetViewPerPage(max($s->showEventsViewList, 5));
419
+ $this->settings->SetWidgetsEnabled(!!$s->showDW);
420
+ }
421
+
422
+ // </editor-fold>
423
+
424
+ // <editor-fold desc="Utility Methods">
425
+
426
+ /**
427
+ * @return string The current plugin version (according to plugin file metadata).
428
+ */
429
+ public function GetNewVersion(){
430
+ $version = get_plugin_data(__FILE__, false, false);
431
+ return isset($version['Version']) ? $version['Version'] : '0.0.0';
432
+ }
433
+
434
+ /**
435
+ * @return string The plugin version as stored in DB (will be the old version during an update/install).
436
+ */
437
+ public function GetOldVersion(){
438
+ return $this->GetGlobalOption('version', '0.0.0');
439
+ }
440
+
441
+ /**
442
+ * @internal To be called in admin header for hiding plugin form Plugins list.
443
+ */
444
+ public function HidePlugin() {
445
+ $selectr = '';
446
+ $plugins = array('wp-security-audit-log');
447
+ foreach ($this->licensing->Plugins() as $plugin) {
448
+ $plugins[] = strtolower(str_replace(' ', '-', $plugin['PluginData']['Name']));
449
+ }
450
+ foreach ($plugins as $value) {
451
+ $selectr .= '.wp-list-table.plugins tr[data-slug="' . $value . '"], ';
452
+ }
453
+ ?><style type="text/css"> <?php echo rtrim($selectr, ", "); ?> { display: none; }</style><?php
454
+ }
455
+
456
+ /**
457
+ * Returns the class name of a particular file that contains the class.
458
+ * @param string $file File name.
459
+ * @return string Class name.
460
+ * @deprecated since 1.2.5 Use autoloader->GetClassFileClassName() instead.
461
+ */
462
+ public function GetClassFileClassName($file){
463
+ return $this->autoloader->GetClassFileClassName($file);
464
+ }
465
+
466
+ /**
467
+ * @return boolean Whether we are running on multisite or not.
468
+ */
469
+ public function IsMultisite(){
470
+ return function_exists('is_multisite') && is_multisite();
471
+ }
472
+
473
+ /**
474
+ * Get a global option.
475
+ * @param string $option Option name.
476
+ * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
477
+ * @param string $prefix (Optional) A prefix used before option name.
478
+ * @return mixed Option's value or $default if option not set.
479
+ */
480
+ public function GetGlobalOption($option, $default = false, $prefix = self::OPT_PRFX){
481
+ //$fn = $this->IsMultisite() ? 'get_site_option' : 'get_option';
482
+ //var_dump($fn($prefix . $option, $default));
483
+ //return $fn($prefix . $option, $default);
484
+ $this->options = new WSAL_Models_Option();
485
+ return $this->options->GetOptionValue($prefix . $option, $default);
486
+ }
487
+
488
+ /**
489
+ * Set a global option.
490
+ * @param string $option Option name.
491
+ * @param mixed $value New value for option.
492
+ * @param string $prefix (Optional) A prefix used before option name.
493
+ */
494
+ public function SetGlobalOption($option, $value, $prefix = self::OPT_PRFX){
495
+ //$fn = $this->IsMultisite() ? 'update_site_option' : 'update_option';
496
+ //$fn($prefix . $option, $value);
497
+ $this->options = new WSAL_Models_Option();
498
+ $this->options->SetOptionValue($prefix . $option, $value);
499
+ }
500
+
501
+ /**
502
+ * Get a user-specific option.
503
+ * @param string $option Option name.
504
+ * @param mixed $default (Optional) Value returned when option is not set (defaults to false).
505
+ * @param string $prefix (Optional) A prefix used before option name.
506
+ * @return mixed Option's value or $default if option not set.
507
+ */
508
+ public function GetUserOption($option, $default = false, $prefix = self::OPT_PRFX){
509
+ $result = get_user_option($prefix . $option, get_current_user_id());
510
+ return $result === false ? $default : $result;
511
+ }
512
+
513
+ /**
514
+ * Set a user-specific option.
515
+ * @param string $option Option name.
516
+ * @param mixed $value New value for option.
517
+ * @param string $prefix (Optional) A prefix used before option name.
518
+ */
519
+ public function SetUserOption($option, $value, $prefix = self::OPT_PRFX){
520
+ update_user_option(get_current_user_id(), $prefix . $option, $value, false);
521
+ }
522
+
523
+ /**
524
+ * Run cleanup routines.
525
+ */
526
+ public function CleanUp(){
527
+ $s = $this->profiler->Start('Clean Up');
528
+ foreach($this->_cleanup_hooks as $hook)
529
+ call_user_func($hook);
530
+ $s->Stop();
531
+ }
532
+
533
+ /**
534
+ * Add callback to be called when a cleanup operation is required.
535
+ * @param callable $hook
536
+ */
537
+ public function AddCleanupHook($hook){
538
+ $this->_cleanup_hooks[] = $hook;
539
+ }
540
+
541
+ /**
542
+ * Remove a callback from the cleanup callbacks list.
543
+ * @param callable $hook
544
+ */
545
+ public function RemoveCleanupHook($hook){
546
+ while(($pos = array_search($hook, $this->_cleanup_hooks)) !== false)
547
+ unset($this->_cleanup_hooks[$pos]);
548
+ }
549
+
550
+ public static function getConnector($config = null)
551
+ {
552
+ require_once('classes/Connector/ConnectorFactory.php');
553
+ return WSAL_Connector_ConnectorFactory::getConnector($config);
554
+ }
555
+
556
+ /**
557
+ * Do we have an existing installation? This only applies for version 1.0 onwards.
558
+ * @return boolean
559
+ */
560
+ public function IsInstalled(){
561
+ return self::getConnector()->isInstalled();
562
+ }
563
+
564
+ /**
565
+ * @return boolean Whether the old plugin was present or not.
566
+ */
567
+ public function CanMigrate(){
568
+ return self::getConnector()->canMigrate();
569
+ }
570
+
571
+ /**
572
+ * @return string Absolute URL to plugin directory WITHOUT final slash.
573
+ */
574
+ public function GetBaseUrl(){
575
+ return plugins_url('', __FILE__);
576
+ }
577
+
578
+ /**
579
+ * @return string Full path to plugin directory WITH final slash.
580
+ */
581
+ public function GetBaseDir(){
582
+ return plugin_dir_path(__FILE__);
583
+ }
584
+
585
+ /**
586
+ * @return string Plugin directory name.
587
+ */
588
+ public function GetBaseName(){
589
+ return plugin_basename(__FILE__);
590
+ }
591
+
592
+ /**
593
+ * Load default configuration / data.
594
+ */
595
+ public function LoadDefaults(){
596
+ $s = $this->profiler->Start('Load Defaults');
597
+ require_once('defaults.php');
598
+ $s->Stop();
599
+ }
600
+
601
+ /**
602
+ * WSAL-Notifications-Extension Functions.
603
+ */
604
+ public function GetNotificationsSetting($opt_prefix)
605
+ {
606
+ $this->options = new WSAL_Models_Option();
607
+ return $this->options->GetNotificationsSetting(self::OPT_PRFX . $opt_prefix);
608
+ }
609
+
610
+ public function GetNotification($id)
611
  {
612
  $this->options = new WSAL_Models_Option();
613
+ return $this->options->GetNotification($id);
614
+ }
615
+
616
+ public function DeleteByName($name)
617
+ {
618
+ $this->options = new WSAL_Models_Option();
619
+ return $this->options->DeleteByName($name);
620
+ }
621
+
622
+ public function DeleteByPrefix($opt_prefix)
623
+ {
624
+ $this->options = new WSAL_Models_Option();
625
+ return $this->options->DeleteByPrefix(self::OPT_PRFX . $opt_prefix);
626
+ }
627
+
628
+ public function CountNotifications($opt_prefix)
629
+ {
630
+ $this->options = new WSAL_Models_Option();
631
+ return $this->options->CountNotifications(self::OPT_PRFX . $opt_prefix);
632
+ }
633
+
634
+ public function UpdateGlobalOption($option, $value)
635
+ {
636
+ $this->options = new WSAL_Models_Option();
637
+ return $this->options->SetOptionValue($option, $value);
638
+ }
639
+
640
+ // </editor-fold>
641
  }
642
 
643
  // Profile WSAL load time