WP Security Audit Log - Version 4.0.1

Version Description

(2020-02-13) =

Release notes: Update 4.0.1 - activity logs for WPForms

  • New features

    • Activity logs for WPForms
    • One-click installation and activation feature for new third party plugins add-ons.
    • New Third Party Plugins tab in Enable/Disable Events section to allow users to install add-ons for third party plugins.
    • Added the new event types "Renamed" and "Duplicated" (more on activity log event types).
    • Added several new hooks in the plugin, mainly to allow custom editor link, to add custom column to the logs viewer, to add new event types and objects.
  • Improvements

    • Updated event IDs 2123, 2062, 2084, 9077 and 9071 so they now use the "Renamed" event type.
    • Updated the activity log severity levels definitions in defaults.php)
    • Updated / improved some of the help text messages.
    • Plugin does not automatically retrieve the IP addresses and latest change of logged in users if there are 100+ sessions (performance improvement).
    • Localized text in JS files.
    • Started removing obsolete code.
    • Added new filter to allow custom %EditorLinkWPForm% from custom events add-ons.
  • Bug fixes

    • Only the path of the added, modified or deleted file was reported in daily summary email.
Download this release

Release Info

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

Code changes from version 4.0.0 to 4.0.1

classes/AlertManager.php CHANGED
@@ -433,27 +433,56 @@ final class WSAL_AlertManager {
433
  * Register a whole group of items.
434
  *
435
  * @param array $groups - An array with group name as the index and an array of group items as the value.
436
- * Item values is an array of [type, code, description, message] respectively.
437
  */
438
  public function RegisterGroup( $groups ) {
439
  foreach ( $groups as $name => $group ) {
440
  foreach ( $group as $subname => $subgroup ) {
441
- foreach ( $subgroup as $item ) {
442
- if ( ! isset( $item[4] ) ) {
443
- $item[4] = ''; // Set default event object.
444
- }
 
 
 
 
 
 
445
 
446
- if ( ! isset( $item[5] ) ) {
447
- $item[5] = ''; // Set default event type.
448
  }
 
 
 
 
 
 
 
 
 
 
449
 
450
- list( $type, $code, $desc, $mesg, $object, $event_type ) = $item;
451
- $this->Register( array( $type, $code, $name, $subname, $desc, $mesg, $object, $event_type ) );
 
452
  }
453
  }
454
  }
455
  }
456
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  /**
458
  * Duplicate Event Notice
459
  *
@@ -1187,7 +1216,7 @@ final class WSAL_AlertManager {
1187
  break;
1188
  }
1189
 
1190
- return $display;
1191
  }
1192
 
1193
  /**
@@ -1223,6 +1252,8 @@ final class WSAL_AlertManager {
1223
  'stopped' => __( 'Stopped', 'wp-security-audit-log' ),
1224
  'removed' => __( 'Removed', 'wp-security-audit-log' ),
1225
  'unblocked' => __( 'Unblocked', 'wp-security-audit-log' ),
 
 
1226
  );
1227
  // sort the types alphabetically.
1228
  asort( $types );
@@ -1320,11 +1351,17 @@ final class WSAL_AlertManager {
1320
  case 'unblocked':
1321
  $display = __( 'Unblocked', 'wp-security-audit-log' );
1322
  break;
 
 
 
 
 
 
1323
  default:
1324
  break;
1325
  }
1326
 
1327
- return $display;
1328
  }
1329
 
1330
  /**
433
  * Register a whole group of items.
434
  *
435
  * @param array $groups - An array with group name as the index and an array of group items as the value.
436
+ * Item values is an array of [type, code, description, message, object, event type] respectively.
437
  */
438
  public function RegisterGroup( $groups ) {
439
  foreach ( $groups as $name => $group ) {
440
  foreach ( $group as $subname => $subgroup ) {
441
+ // Check to see if this ground has any subgroups
442
+ if( $this->GetArrayDepth( $group ) > 1 ) {
443
+ foreach ( $subgroup as $item ) {
444
+ if ( ! isset( $item[4] ) ) {
445
+ $item[4] = ''; // Set default event object.
446
+ }
447
+
448
+ if ( ! isset( $item[5] ) ) {
449
+ $item[5] = ''; // Set default event type.
450
+ }
451
 
452
+ list( $type, $code, $desc, $mesg, $object, $event_type ) = $item;
453
+ $this->Register( array( $type, $code, $name, $subname, $desc, $mesg, $object, $event_type ) );
454
  }
455
+ // If no subgroups are found, process them accordingly.
456
+ } else {
457
+ foreach ( $group as $item ) {
458
+ if ( ! isset( $item[4] ) ) {
459
+ $item[4] = ''; // Set default event object.
460
+ }
461
+
462
+ if ( ! isset( $item[5] ) ) {
463
+ $item[5] = ''; // Set default event type.
464
+ }
465
 
466
+ list( $type, $code, $desc, $mesg, $object, $event_type ) = $item;
467
+ $this->Register( array( $type, $code, $name, $subname, $desc, $mesg, $object, $event_type ) );
468
+ }
469
  }
470
  }
471
  }
472
  }
473
 
474
+ public function GetArrayDepth( $array ) {
475
+ $depth = 0;
476
+ $iteIte = new RecursiveIteratorIterator( new RecursiveArrayIterator( $array ) );
477
+
478
+ foreach ($iteIte as $ite) {
479
+ $d = $iteIte->getDepth();
480
+ $depth = $d > $depth ? $d : $depth;
481
+ }
482
+
483
+ return $depth;
484
+ }
485
+
486
  /**
487
  * Duplicate Event Notice
488
  *
1216
  break;
1217
  }
1218
 
1219
+ return apply_filters( 'wsal_event_object_text', $display, $object );
1220
  }
1221
 
1222
  /**
1252
  'stopped' => __( 'Stopped', 'wp-security-audit-log' ),
1253
  'removed' => __( 'Removed', 'wp-security-audit-log' ),
1254
  'unblocked' => __( 'Unblocked', 'wp-security-audit-log' ),
1255
+ 'renamed' => __( 'Renamed', 'wp-security-audit-log' ),
1256
+ 'duplicated' => __( 'Duplicated', 'wp-security-audit-log' ),
1257
  );
1258
  // sort the types alphabetically.
1259
  asort( $types );
1351
  case 'unblocked':
1352
  $display = __( 'Unblocked', 'wp-security-audit-log' );
1353
  break;
1354
+ case 'renamed':
1355
+ $display = __( 'Renamed', 'wp-security-audit-log' );
1356
+ break;
1357
+ case 'duplicated':
1358
+ $display = __( 'Duplicated', 'wp-security-audit-log' );
1359
+ break;
1360
  default:
1361
  break;
1362
  }
1363
 
1364
+ return apply_filters( 'wsal_event_type_text', $display, $event_type );
1365
  }
1366
 
1367
  /**
classes/Sensors/Content.php CHANGED
@@ -541,6 +541,7 @@ class WSAL_Sensors_Content extends WSAL_AbstractSensor {
541
  'old_name' => $old_name,
542
  'new_name' => $new_name,
543
  'TagLink' => $term_link,
 
544
  )
545
  );
546
  }
541
  'old_name' => $old_name,
542
  'new_name' => $new_name,
543
  'TagLink' => $term_link,
544
+ 'Slug' => $new_slug,
545
  )
546
  );
547
  }
classes/Settings.php CHANGED
@@ -1748,7 +1748,12 @@ class WSAL_Settings {
1748
 
1749
  case strncmp( $value, 'http://', 7 ) === 0:
1750
  case strncmp( $value, 'https://', 8 ) === 0:
1751
- return '<a href="' . esc_html( $value ) . '" title="' . esc_html( $value ) . '" target="_blank">' . esc_html( $value ) . '</a>';
 
 
 
 
 
1752
 
1753
  case in_array( $name, array( '%PostStatus%', '%ProductStatus%' ), true ):
1754
  if ( ! empty( $value ) && 'publish' === $value ) {
@@ -1802,7 +1807,9 @@ class WSAL_Settings {
1802
  return $highlight_start_tag . dirname( $value ) . $highlight_end_tag;
1803
 
1804
  default:
1805
- return $highlight_start_tag . esc_html( $value ) . $highlight_end_tag;
 
 
1806
  }
1807
  }
1808
 
1748
 
1749
  case strncmp( $value, 'http://', 7 ) === 0:
1750
  case strncmp( $value, 'https://', 8 ) === 0:
1751
+ $updated_line = apply_filters( 'wsal_link_filter', $value, $name );
1752
+ if ( $updated_line !== $value ) {
1753
+ return $updated_line;
1754
+ } else {
1755
+ return '<a href="' . esc_html( $value ) . '" title="' . esc_html( $value ) . '" target="_blank">' . esc_html( $value ) . '</a>';
1756
+ }
1757
 
1758
  case in_array( $name, array( '%PostStatus%', '%ProductStatus%' ), true ):
1759
  if ( ! empty( $value ) && 'publish' === $value ) {
1807
  return $highlight_start_tag . dirname( $value ) . $highlight_end_tag;
1808
 
1809
  default:
1810
+ // if we didn't get a match already try get one via a filter.
1811
+ $filtered_formatted_value = apply_filters( 'wsal_meta_formatter_custom_formatter', $value, $name );
1812
+ return ( $value !== $filtered_formatted_value ) ? $filtered_formatted_value : $highlight_start_tag . esc_html( $value ) . $highlight_end_tag;
1813
  }
1814
  }
1815
 
classes/Utilities/PluginInstallAndActivate.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handler to install activate plugins.
4
+ *
5
+ * Provides the allowed plugins data as well as a render method to display the
6
+ * items inside of a table with install/actiavte buttons.
7
+ *
8
+ * @package Wsal
9
+ * @since 4.0.1
10
+ */
11
+
12
+ if ( ! class_exists( 'WSAL_PluginInstallAndActivate' ) ) {
13
+
14
+ /**
15
+ * Class to handle checking plugin status and rendering data about any that
16
+ * are installable.
17
+ *
18
+ * @since 4.0.1
19
+ */
20
+ class WSAL_PluginInstallAndActivate {
21
+
22
+ /**
23
+ * Checks if the plugin is already available/installed on the site.
24
+ *
25
+ * @method is_plugin_installed
26
+ * @since 4.0.1
27
+ * @param string $plugin_slug installed plugin slug.
28
+ * @return void|bool
29
+ */
30
+ public function is_plugin_installed( $plugin_slug = '' ) {
31
+ // bail early if we don't have a slug to work with.
32
+ if ( empty( $plugin_slug ) ) {
33
+ return;
34
+ }
35
+
36
+ // check if the slug is in the installable list.
37
+ $is_allowed_slug = false;
38
+ $allowed_plugins = self::get_installable_plugins();
39
+ if ( is_array( $allowed_plugins ) ) {
40
+ foreach ( $allowed_plugins as $allowed_plugin ) {
41
+ // if we alredy found an allowed slug then break.
42
+ if ( true === $is_allowed_slug ) {
43
+ break;
44
+ }
45
+ $is_allowed_slug = ( isset( $allowed_plugin['plugin_slug'] ) && $allowed_plugin['plugin_slug'] === $plugin_slug ) ? true : false;
46
+ }
47
+ }
48
+
49
+ // bail early if this is not an allowed plugin slug.
50
+ if ( ! $is_allowed_slug ) {
51
+ return;
52
+ }
53
+
54
+ // get core plugin functions if they are not already in runtime.
55
+ if ( ! function_exists( 'get_plugins' ) ) {
56
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
57
+ }
58
+ $all_plugins = get_plugins();
59
+
60
+ if ( ! empty( $all_plugins[ $plugin_slug ] ) ) {
61
+ return true;
62
+ } else {
63
+ return false;
64
+ }
65
+ }
66
+
67
+
68
+ /**
69
+ * Renders a table containing info about each of the installable
70
+ * plugins and a button to install them.
71
+ *
72
+ * @method render
73
+ * @since 4.0.1
74
+ */
75
+ public function render() {
76
+ $our_plugins = $this->get_installable_plugins();
77
+ ?>
78
+ <table id="tab-third-party-plugins" class="form-table wp-list-table wsal-tab widefat fixed" style="display: table;" cellspacing="0">
79
+ <p class="description"><?php esc_html_e( 'WP Security Audit Log can keep a log of changes done on other plugins. Install the relevant add-on from the below list to keep a log of changes done on that plugin.', 'wp-security-audit-log' ); ?></p>
80
+ <tbody>
81
+ <tr>
82
+ <td class="addon-td">
83
+ <?php
84
+ // Create a nonce to pass through via data attr.
85
+ $nonce = wp_create_nonce( 'wsal-install-addon' );
86
+ // Loop through plugins and output.
87
+ foreach ( $our_plugins as $details ) {
88
+ $disable_button = '';
89
+ if ( is_plugin_active( $details['plugin_slug'] ) ) {
90
+ $disable_button = 'disabled';
91
+ }
92
+ ?>
93
+
94
+ <div class="addon-wrapper">
95
+ <img src="<?php echo esc_url( trailingslashit( WSAL_BASE_URL ) . 'img/addons/' . $details['image_filename'] ); ?>">
96
+ <h4><?php esc_html_e( 'Add-on for ', 'wp-security-audit-log' ); ?><?php echo esc_html( $details['title'] ); ?></h4>
97
+ <p><?php echo sanitize_text_field( $details['plugin_description'] ); ?></p><br>
98
+ <p><button class="install-addon button button-primary <?php echo esc_attr( $disable_button ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>" data-plugin-slug="<?php echo esc_attr( $details['plugin_slug'] ); ?>" data-plugin-download-url="<?php echo esc_url( $details['plugin_url'] ); ?>" data-plugin-event-tab-id="<?php echo esc_attr( $details['event_tab_id'] ); ?>">
99
+ <?php
100
+ if ( $this->is_plugin_installed( $details['plugin_slug'] ) && ! is_plugin_active( $details['plugin_slug'] ) ) {
101
+ esc_html_e( 'Add-on installed, activate now?', 'wp-security-audit-log' );
102
+ } elseif ( $this->is_plugin_installed( $details['plugin_slug'] ) && is_plugin_active( $details['plugin_slug'] ) ) {
103
+ esc_html_e( 'Add-on installed', 'wp-security-audit-log' );
104
+ } else {
105
+ esc_html_e( 'Install Add-on', 'wp-security-audit-log' );
106
+ }
107
+ ?>
108
+ </button><span class="spinner" style="display: none; visibility: visible; float: none; margin: 0 0 0 8px;"></span></p>
109
+ </div>
110
+
111
+ <?php
112
+ }
113
+ ?>
114
+ </td>
115
+ </tr>
116
+ </tbody>
117
+ </table>
118
+ <?php
119
+ }
120
+
121
+ /**
122
+ * Get a list of the data for the plugins that are allowable.
123
+ *
124
+ * @method get_installable_plugins
125
+ * @since 4.0.1
126
+ */
127
+ public static function get_installable_plugins() {
128
+ $plugins = array(
129
+ // array(
130
+ // 'title' => 'BBPress Add-on',
131
+ // 'image_filename' => 'bbpress.png',
132
+ // 'plugin_slug' => 'wp-bootstrap-blocks/wp-bootstrap-blocks.php',
133
+ // 'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-bootstrap-blocks.latest-stable.zip', // TODO: make this match live url.
134
+ // 'event_tab_id' => '#tab-bbpress-forums',
135
+ // ),
136
+ array(
137
+ 'title' => 'WPForms',
138
+ 'image_filename' => 'wpforms.png',
139
+ 'plugin_slug' => 'wp-security-audit-log-add-on-for-wpforms/wsal-wpforms.php',
140
+ 'plugin_url' => 'https://downloads.wordpress.org/plugin/wp-security-audit-log-add-on-for-wpforms.latest-stable.zip',
141
+ 'event_tab_id' => '#tab-wpforms',
142
+ 'plugin_description' => 'Keep a record of when someone adds, modified or delete forms, entries and more in the WPForms plugin.',
143
+ ),
144
+ );
145
+ // runs through a filter so it can be added to programatically.
146
+ // NOTE: this means when using we need to test it's still an array.
147
+ return apply_filters( 'wsal_filter_installable_plugins', $plugins );
148
+ }
149
+ }
150
+ }
classes/Utilities/PluginInstallerAction.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin installer action
4
+ *
5
+ * Class file for installing plugins from the repo.
6
+ *
7
+ * @since 4.0.1
8
+ * @package Wsal
9
+ */
10
+
11
+ if ( ! class_exists( 'WSAL_PluginInstallerAction' ) ) {
12
+
13
+ /**
14
+ * Class to handle the installtion and activation of plugins.
15
+ *
16
+ * @since 4.0.1
17
+ */
18
+ class WSAL_PluginInstallerAction {
19
+
20
+ /**
21
+ * Register the ajax action.
22
+ *
23
+ * @method register
24
+ * @since 4.0.1
25
+ */
26
+ public function register() {
27
+ add_action( 'wp_ajax_run_addon_install', array( $this, 'run_addon_install' ) );
28
+ }
29
+
30
+ /**
31
+ * Run the installer.
32
+ *
33
+ * @method run_addon_install
34
+ * @since 4.0.1
35
+ */
36
+ public function run_addon_install() {
37
+ check_ajax_referer( 'wsal-install-addon' );
38
+
39
+ $plugin_zip = ( isset( $_POST['plugin_url'] ) ) ? esc_url_raw( wp_unslash( $_POST['plugin_url'] ) ) : '';
40
+ $plugin_slug = ( isset( $_POST['plugin_slug'] ) ) ? sanitize_textarea_field( wp_unslash( $_POST['plugin_slug'] ) ) : '';
41
+
42
+ $predefined_plugins = WSAL_PluginInstallAndActivate::get_installable_plugins();
43
+
44
+ // validate that the plugin is in the allowed list.
45
+ $valid = false;
46
+ foreach ( $predefined_plugins as $plugin ) {
47
+ // if we have a valid plugin then break.
48
+ if ( $valid ) {
49
+ break;
50
+ }
51
+ $valid = ( $plugin_zip === $plugin['plugin_url'] && $plugin_slug === $plugin['plugin_slug'] ) ? true : false;
52
+ }
53
+
54
+ // bail early if we didn't get a valid url and slug to install.
55
+ if ( ! $valid ) {
56
+ wp_send_json_error(
57
+ array(
58
+ 'message' => esc_html__( 'Tried to install a zip or slug that was not in the allowed list', 'wp-security-audit-log' ),
59
+ )
60
+ );
61
+ }
62
+
63
+ // Check if the plugin is installed.
64
+ if ( $this->is_plugin_installed( $plugin_slug ) ) {
65
+ // If plugin is installed but not active, activate it.
66
+ if ( ! is_plugin_active( $plugin_zip ) ) {
67
+ $this->run_activate( $plugin_slug );
68
+ $this->activate( $plugin_zip );
69
+ $result = 'activated';
70
+ } else {
71
+ $result = 'already_installed';
72
+ }
73
+ } else {
74
+ // No plugin found or plugin not present to be activated, so lets install it.
75
+ $this->install_plugin( $plugin_zip );
76
+ $this->run_activate( $plugin_slug );
77
+ $this->activate( $plugin_zip );
78
+ $result = 'success';
79
+ }
80
+
81
+ wp_send_json( $result );
82
+ }
83
+
84
+ /**
85
+ * Install a plugin given a slug.
86
+ *
87
+ * @method install
88
+ * @since 4.0.1
89
+ * @param string $plugin_zip URL to the direct zip file.
90
+ */
91
+ public function install_plugin( $plugin_zip = '' ) {
92
+ // bail early if we don't have a slug to work with.
93
+ if ( empty( $plugin_zip ) ) {
94
+ return;
95
+ }
96
+ // get the core plugin upgrader if not already in the runtime.
97
+ if ( ! class_exists( 'Plugin_Upgrader' ) ) {
98
+ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
99
+ }
100
+ // clear the cache so we're using fresh data.
101
+ wp_cache_flush();
102
+ $upgrader = new Plugin_Upgrader();
103
+ $install_result = $upgrader->install( $plugin_zip );
104
+ if ( ! $install_result || is_wp_error( $install_result ) ) {
105
+ if ( is_wp_error( $install_result ) ) {
106
+ return $install_result->get_error_message();
107
+ }
108
+ die();
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Activates a plugin that is available on the site.
114
+ *
115
+ * @method activate
116
+ * @since 4.0.1
117
+ * @param string $plugin_zip URL to the direct zip file.
118
+ * @return void
119
+ */
120
+ public function activate( $plugin_zip = '' ) {
121
+ // bail early if we don't have a slug to work with.
122
+ if ( empty( $plugin_zip ) ) {
123
+ return;
124
+ }
125
+
126
+ // get core plugin functions if they are not already in runtime.
127
+ if ( ! function_exists( 'activate_plugin' ) ) {
128
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
129
+ }
130
+
131
+ if ( ! is_plugin_active( $plugin_zip ) ) {
132
+ activate_plugin( $plugin_zip );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Activates a plugin that is available on the site.
138
+ *
139
+ * @method run_activate
140
+ * @since 4.0.1
141
+ * @param string $plugin_slug slug for plugin.
142
+ */
143
+ public function run_activate( $plugin_slug = '' ) {
144
+ // bail early if we don't have a slug to work with.
145
+ if ( empty( $plugin_slug ) ) {
146
+ return;
147
+ }
148
+
149
+ $current = get_option( 'active_plugins' );
150
+ $plugin = plugin_basename( trim( $plugin_slug ) );
151
+
152
+ if ( ! in_array( $plugin_slug, $current, true ) ) {
153
+ $current[] = $plugin_slug;
154
+ activate_plugin( $plugin_slug );
155
+ }
156
+ return null;
157
+ }
158
+
159
+ /**
160
+ * Check if a plugin is installed.
161
+ *
162
+ * @method is_plugin_installed
163
+ * @since 4.0.1
164
+ * @param string $plugin_slug slug for plugin.
165
+ */
166
+ public function is_plugin_installed( $plugin_slug = '' ) {
167
+ // bail early if we don't have a slug to work with.
168
+ if ( empty( $plugin_slug ) ) {
169
+ return;
170
+ }
171
+
172
+ // get core plugin functions if not already in the runtime.
173
+ if ( ! function_exists( 'get_plugins' ) ) {
174
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
175
+ }
176
+ $all_plugins = get_plugins();
177
+
178
+ // true if plugin is already installed or false if not.
179
+ if ( ! empty( $all_plugins[ $plugin_slug ] ) ) {
180
+ return true;
181
+ } else {
182
+ return false;
183
+ }
184
+
185
+ }
186
+ }
187
+ }
classes/Views/ToggleAlerts.php CHANGED
@@ -225,6 +225,9 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
225
  </a>
226
  <?php endif; ?>
227
  <?php endforeach; ?>
 
 
 
228
  </h2>
229
  <form id="audit-log-viewer" method="post">
230
  <input type="hidden" name="page" value="<?php echo isset( $_GET['page'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) : false; ?>" />
@@ -667,6 +670,10 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
667
  </tr>
668
  </tbody>
669
  </table>
 
 
 
 
670
  </div>
671
  <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php echo esc_attr( __( 'Save Changes', 'wp-security-audit-log' ) ); ?>"></p>
672
  </form>
@@ -780,6 +787,22 @@ class WSAL_Views_ToggleAlerts extends WSAL_AbstractView {
780
  table#tab-frontend-events tr:nth-child(12) td:first-child {
781
  padding-left: 10px;
782
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
783
  </style>
784
  <?php
785
  }
225
  </a>
226
  <?php endif; ?>
227
  <?php endforeach; ?>
228
+ <a href="#tab-third-party-plugins" class="nav-tab">
229
+ <?php esc_html_e( 'Third party plugins', 'wp-security-audit-log' ); ?>
230
+ </a>
231
  </h2>
232
  <form id="audit-log-viewer" method="post">
233
  <input type="hidden" name="page" value="<?php echo isset( $_GET['page'] ) ? esc_attr( sanitize_text_field( wp_unslash( $_GET['page'] ) ) ) : false; ?>" />
670
  </tr>
671
  </tbody>
672
  </table>
673
+ <?php
674
+ $addons = new WSAL_PluginInstallAndActivate();
675
+ $addons->render();
676
+ ?>
677
  </div>
678
  <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php echo esc_attr( __( 'Save Changes', 'wp-security-audit-log' ) ); ?>"></p>
679
  </form>
787
  table#tab-frontend-events tr:nth-child(12) td:first-child {
788
  padding-left: 10px;
789
  }
790
+ [href="#tab-0" i], [data-parent="tab-wpforms"] {
791
+ display: none;
792
+ }
793
+ .addon-wrapper img {
794
+ max-width: 200px;
795
+ }
796
+ .addon-wrapper {
797
+ max-width: 25%;
798
+ display: inline-block;
799
+ border: 1px solid #eee;
800
+ padding: 20px;
801
+ text-align: center;
802
+ }
803
+ .addon-wrapper:hover {
804
+ border: 1px solid #ccc;
805
+ }
806
  </style>
807
  <?php
808
  }
defaults.php CHANGED
@@ -154,11 +154,11 @@ function wsaldefaults_wsal_init() {
154
  )
155
  );
156
 
157
- $wsal->constants->AddConstant( 'WSAL_CRITICAL', 1, __( 'Critical, high-impact messages.', 'wp-security-audit-log' ) );
158
- $wsal->constants->AddConstant( 'WSAL_HIGH', 6, __( 'High severity messages.', 'wp-security-audit-log' ) );
159
- $wsal->constants->AddConstant( 'WSAL_MEDIUM', 10, __( 'Medium severity messages.', 'wp-security-audit-log' ) );
160
- $wsal->constants->AddConstant( 'WSAL_LOW', 15, __( 'Low severity messages.', 'wp-security-audit-log' ) );
161
- $wsal->constants->AddConstant( 'WSAL_INFORMATIONAL', 20, __( 'Run-time notice.', 'wp-security-audit-log' ) );
162
 
163
  // Create list of default alerts.
164
  $wsal->alerts->RegisterGroup(
@@ -212,7 +212,7 @@ function wsaldefaults_wsal_init() {
212
  array( 2120, WSAL_INFORMATIONAL, __( 'User removed post tag', 'wp-security-audit-log' ), __( 'Removed tag(s) from the post %PostTitle% %LineBreak% ID: %PostID% %LineBreak% Type: %PostType% %LineBreak% Status: %PostStatus% %LineBreak% Removed tag(s): %tag% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost%', 'wp-security-audit-log' ), 'post', 'modified' ),
213
  array( 2121, WSAL_INFORMATIONAL, __( 'User created new tag', 'wp-security-audit-log' ), __( 'Created the tag %TagName% %LineBreak% Slug: %Slug% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'created' ),
214
  array( 2122, WSAL_LOW, __( 'User deleted tag', 'wp-security-audit-log' ), __( 'Deleted the tag %TagName% %LineBreak% Slug: %Slug%', 'wp-security-audit-log' ), 'tag', 'deleted' ),
215
- array( 2123, WSAL_INFORMATIONAL, __( 'User renamed tag', 'wp-security-audit-log' ), __( 'Renamed the tag %old_name% %LineBreak% New name: %new_name% %LineBreak% Slug: %Slug% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'modified' ),
216
  array( 2124, WSAL_INFORMATIONAL, __( 'User changed tag slug', 'wp-security-audit-log' ), __( 'Changed the slug of the tag %tag% %LineBreak% Previous slug: %old_slug% %LineBreak% New slug: %new_slug% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'modified' ),
217
  array( 2125, WSAL_INFORMATIONAL, __( 'User changed tag description', 'wp-security-audit-log' ), __( 'Changed the description of the tag %tag% %LineBreak% Slug: %Slug% %LineBreak% Previous description: %old_desc% %LineBreak% New description: %new_desc% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'modified' ),
218
  ),
@@ -230,7 +230,7 @@ function wsaldefaults_wsal_init() {
230
  array( 2053, WSAL_LOW, __( 'User created a custom field for a post', 'wp-security-audit-log' ), __( 'Created a new custom field called %MetaKey% in the post %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %LineBreak% Custom field value: %MetaValue% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost% %LineBreak% %MetaLink%', 'wp-security-audit-log' ), 'post', 'modified' ),
231
  array( 2054, WSAL_LOW, __( 'User updated a custom field value for a post', 'wp-security-audit-log' ), __( 'Modified the value of the custom field %MetaKey% in the post %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %LineBreak% Previous custom field value: %MetaValueOld% %LineBreak% New custom field value: %MetaValueNew% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost% %LineBreak% %MetaLink%.', 'wp-security-audit-log' ), 'custom-field', 'modified' ),
232
  array( 2055, WSAL_MEDIUM, __( 'User deleted a custom field from a post', 'wp-security-audit-log' ), __( 'Deleted the custom field %MetaKey% from the post %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost%', 'wp-security-audit-log' ), 'custom-field', 'deleted' ),
233
- array( 2062, WSAL_LOW, __( 'User updated a custom field name for a post', 'wp-security-audit-log' ), __( 'Renamed the custom field %MetaKeyOld% in the post %PostTitle% %LineBreak% New name: %MetaKeyNew% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost% %LineBreak% %MetaLink%', 'wp-security-audit-log' ), 'custom-field', 'modified' ),
234
  ),
235
 
236
  /**
@@ -275,7 +275,7 @@ function wsaldefaults_wsal_init() {
275
  array( 2081, WSAL_MEDIUM, __( 'User deleted menu', 'wp-security-audit-log' ), __( 'Deleted the menu %MenuName%', 'wp-security-audit-log' ), 'menu', 'deleted' ),
276
  array( 2082, WSAL_LOW, __( 'User changed menu setting', 'wp-security-audit-log' ), __( 'The setting in the %MenuName% %LineBreak% Setting: %MenuSetting%', 'wp-security-audit-log' ), 'menu', 'enabled' ),
277
  array( 2083, WSAL_LOW, __( 'User modified content in a menu', 'wp-security-audit-log' ), __( 'Modified an item in the menu %MenuName% %LineBreak% Item type: %ContentType% %LineBreak% Item name: %ContentName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
278
- array( 2084, WSAL_LOW, __( 'User changed name of a menu', 'wp-security-audit-log' ), __( 'Renamed the menu %OldMenuName% %LineBreak% New name: %NewMenuName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
279
  array( 2085, WSAL_LOW, __( 'User changed order of the objects in a menu', 'wp-security-audit-log' ), __( 'Changed the order of the items in the menu %MenuName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
280
  array( 2089, WSAL_LOW, __( 'User moved objects as a sub-item', 'wp-security-audit-log' ), __( 'Menu name: %MenuName% %LineBreak% Moved item %ItemName% as a sub-item of %ParentName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
281
  ),
@@ -550,7 +550,7 @@ function wsaldefaults_wsal_init() {
550
  array( 9015, WSAL_MEDIUM, __( 'User changed status of a product', 'wp-security-audit-log' ), __( 'Changed the status of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Previous status: %OldStatus% %LineBreak% New status: %NewStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
551
  array( 9072, WSAL_INFORMATIONAL, __( 'User opened a product in the editor', 'wp-security-audit-log' ), __( 'Opened the product %ProductTitle% in the editor %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'opened' ),
552
  array( 9073, WSAL_INFORMATIONAL, __( 'User viewed a product', 'wp-security-audit-log' ), __( 'Viewed the product %ProductTitle% page %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'viewed' ),
553
- array( 9077, WSAL_MEDIUM, __( 'User renamed a product', 'wp-security-audit-log' ), __( 'Renamed the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous name: %OldTitle% %LineBreak% New name: %NewTitle% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
554
  array( 9016, WSAL_MEDIUM, __( 'User changed type of a price', 'wp-security-audit-log' ), __( 'Changed the %PriceType% of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous price: %OldPrice% %LineBreak% New price: %NewPrice% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
555
  array( 9017, WSAL_MEDIUM, __( 'User changed the SKU of a product', 'wp-security-audit-log' ), __( 'Changed the SKU of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous SKU: %OldSku% %LineBreak% New SKU: %NewSku% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
556
  array( 9018, WSAL_LOW, __( 'User changed the stock status of a product', 'wp-security-audit-log' ), __( 'Changed the stock status of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous stock status: %OldStatus% %LineBreak% New stock status: %NewStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
@@ -626,7 +626,7 @@ function wsaldefaults_wsal_init() {
626
  array( 9068, WSAL_LOW, __( 'User changed the usage limits settings of a coupon', 'wp-security-audit-log' ), __( 'Changed the Usage Limits of the coupon %CouponName% %LineBreak% Previous usage limits: %OldMetaValue% %LineBreak% New usage limits: %NewMetaValue% %LineBreak% %EditorLinkCoupon%', 'wp-security-audit-log' ), 'woocommerce-store', 'modified' ),
627
  array( 9069, WSAL_INFORMATIONAL, __( 'User changed the description of a coupon', 'wp-security-audit-log' ), __( 'Changed the description of the coupon %CouponName% %LineBreak% Previous description: %OldDescription% %LineBreak% New description: %NewDescription% %LineBreak% %EditorLinkCoupon%', 'wp-security-audit-log' ), 'woocommerce-store', 'modified' ),
628
  array( 9070, E_WARNING, __( 'User changed the status of a coupon', 'wp-security-audit-log' ), __( 'Changed the Status of the WooCommerce coupon %CouponName% from %OldStatus% to %NewStatus%.', 'wp-security-audit-log' ), 'woocommerce-store' ),
629
- array( 9071, WSAL_INFORMATIONAL, __( 'User renamed a WooCommerce coupon', 'wp-security-audit-log' ), __( 'Renamed the coupon %OldName% %LineBreak% New name: %NewName% %LineBreak% %LineBreak% %EditorLinkCoupon%', 'wp-security-audit-log' ), 'woocommerce-store', 'modified' ),
630
  ),
631
 
632
  __( 'Orders', 'wp-security-audit-log' ) => array(
154
  )
155
  );
156
 
157
+ $wsal->constants->AddConstant( 'WSAL_CRITICAL', 1, __( 'Critical severity events.', 'wp-security-audit-log' ) );
158
+ $wsal->constants->AddConstant( 'WSAL_HIGH', 6, __( 'High severity events.', 'wp-security-audit-log' ) );
159
+ $wsal->constants->AddConstant( 'WSAL_MEDIUM', 10, __( 'Medium severity events.', 'wp-security-audit-log' ) );
160
+ $wsal->constants->AddConstant( 'WSAL_LOW', 15, __( 'Low severity events.', 'wp-security-audit-log' ) );
161
+ $wsal->constants->AddConstant( 'WSAL_INFORMATIONAL', 20, __( 'Informational events.', 'wp-security-audit-log' ) );
162
 
163
  // Create list of default alerts.
164
  $wsal->alerts->RegisterGroup(
212
  array( 2120, WSAL_INFORMATIONAL, __( 'User removed post tag', 'wp-security-audit-log' ), __( 'Removed tag(s) from the post %PostTitle% %LineBreak% ID: %PostID% %LineBreak% Type: %PostType% %LineBreak% Status: %PostStatus% %LineBreak% Removed tag(s): %tag% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost%', 'wp-security-audit-log' ), 'post', 'modified' ),
213
  array( 2121, WSAL_INFORMATIONAL, __( 'User created new tag', 'wp-security-audit-log' ), __( 'Created the tag %TagName% %LineBreak% Slug: %Slug% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'created' ),
214
  array( 2122, WSAL_LOW, __( 'User deleted tag', 'wp-security-audit-log' ), __( 'Deleted the tag %TagName% %LineBreak% Slug: %Slug%', 'wp-security-audit-log' ), 'tag', 'deleted' ),
215
+ array( 2123, WSAL_INFORMATIONAL, __( 'User renamed tag', 'wp-security-audit-log' ), __( 'Old name: %old_name% %LineBreak% New name: %new_name% %LineBreak% Slug: %Slug% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'renamed' ),
216
  array( 2124, WSAL_INFORMATIONAL, __( 'User changed tag slug', 'wp-security-audit-log' ), __( 'Changed the slug of the tag %tag% %LineBreak% Previous slug: %old_slug% %LineBreak% New slug: %new_slug% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'modified' ),
217
  array( 2125, WSAL_INFORMATIONAL, __( 'User changed tag description', 'wp-security-audit-log' ), __( 'Changed the description of the tag %tag% %LineBreak% Slug: %Slug% %LineBreak% Previous description: %old_desc% %LineBreak% New description: %new_desc% %LineBreak% %TagLink%', 'wp-security-audit-log' ), 'tag', 'modified' ),
218
  ),
230
  array( 2053, WSAL_LOW, __( 'User created a custom field for a post', 'wp-security-audit-log' ), __( 'Created a new custom field called %MetaKey% in the post %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %LineBreak% Custom field value: %MetaValue% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost% %LineBreak% %MetaLink%', 'wp-security-audit-log' ), 'post', 'modified' ),
231
  array( 2054, WSAL_LOW, __( 'User updated a custom field value for a post', 'wp-security-audit-log' ), __( 'Modified the value of the custom field %MetaKey% in the post %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %LineBreak% Previous custom field value: %MetaValueOld% %LineBreak% New custom field value: %MetaValueNew% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost% %LineBreak% %MetaLink%.', 'wp-security-audit-log' ), 'custom-field', 'modified' ),
232
  array( 2055, WSAL_MEDIUM, __( 'User deleted a custom field from a post', 'wp-security-audit-log' ), __( 'Deleted the custom field %MetaKey% from the post %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type: %PostType% %LineBreak% Post Status: %PostStatus% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost%', 'wp-security-audit-log' ), 'custom-field', 'deleted' ),
233
+ array( 2062, WSAL_LOW, __( 'User updated a custom field name for a post', 'wp-security-audit-log' ), __( 'Old custom field name: %MetaKeyOld% %LineBreak% New custom field name: %MetaKeyNew% %LineBreak% Post: %PostTitle% %LineBreak% Post ID: %PostID% %LineBreak% Post Type:%PostType% %LineBreak% Post Status: %PostStatus% %PostUrlIfPlublished% %LineBreak% %EditorLinkPost%', 'wp-security-audit-log' ), 'custom-field', 'renamed' ),
234
  ),
235
 
236
  /**
275
  array( 2081, WSAL_MEDIUM, __( 'User deleted menu', 'wp-security-audit-log' ), __( 'Deleted the menu %MenuName%', 'wp-security-audit-log' ), 'menu', 'deleted' ),
276
  array( 2082, WSAL_LOW, __( 'User changed menu setting', 'wp-security-audit-log' ), __( 'The setting in the %MenuName% %LineBreak% Setting: %MenuSetting%', 'wp-security-audit-log' ), 'menu', 'enabled' ),
277
  array( 2083, WSAL_LOW, __( 'User modified content in a menu', 'wp-security-audit-log' ), __( 'Modified an item in the menu %MenuName% %LineBreak% Item type: %ContentType% %LineBreak% Item name: %ContentName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
278
+ array( 2084, WSAL_LOW, __( 'User changed name of a menu', 'wp-security-audit-log' ), __( 'Old name: %OldMenuName% %LineBreak% New name: %NewMenuName%', 'wp-security-audit-log' ), 'menu', 'renamed' ),
279
  array( 2085, WSAL_LOW, __( 'User changed order of the objects in a menu', 'wp-security-audit-log' ), __( 'Changed the order of the items in the menu %MenuName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
280
  array( 2089, WSAL_LOW, __( 'User moved objects as a sub-item', 'wp-security-audit-log' ), __( 'Menu name: %MenuName% %LineBreak% Moved item %ItemName% as a sub-item of %ParentName%', 'wp-security-audit-log' ), 'menu', 'modified' ),
281
  ),
550
  array( 9015, WSAL_MEDIUM, __( 'User changed status of a product', 'wp-security-audit-log' ), __( 'Changed the status of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Previous status: %OldStatus% %LineBreak% New status: %NewStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
551
  array( 9072, WSAL_INFORMATIONAL, __( 'User opened a product in the editor', 'wp-security-audit-log' ), __( 'Opened the product %ProductTitle% in the editor %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'opened' ),
552
  array( 9073, WSAL_INFORMATIONAL, __( 'User viewed a product', 'wp-security-audit-log' ), __( 'Viewed the product %ProductTitle% page %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'viewed' ),
553
+ array( 9077, WSAL_MEDIUM, __( 'User renamed a product', 'wp-security-audit-log' ), __( 'Old name: %OldTitle% %LineBreak% New name: %NewTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'renamed' ),
554
  array( 9016, WSAL_MEDIUM, __( 'User changed type of a price', 'wp-security-audit-log' ), __( 'Changed the %PriceType% of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous price: %OldPrice% %LineBreak% New price: %NewPrice% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
555
  array( 9017, WSAL_MEDIUM, __( 'User changed the SKU of a product', 'wp-security-audit-log' ), __( 'Changed the SKU of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous SKU: %OldSku% %LineBreak% New SKU: %NewSku% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
556
  array( 9018, WSAL_LOW, __( 'User changed the stock status of a product', 'wp-security-audit-log' ), __( 'Changed the stock status of the product %ProductTitle% %LineBreak% ID: %PostID% %LineBreak% Status: %ProductStatus% %LineBreak% Previous stock status: %OldStatus% %LineBreak% New stock status: %NewStatus% %LineBreak% %EditorLinkProduct%', 'wp-security-audit-log' ), 'woocommerce-product', 'modified' ),
626
  array( 9068, WSAL_LOW, __( 'User changed the usage limits settings of a coupon', 'wp-security-audit-log' ), __( 'Changed the Usage Limits of the coupon %CouponName% %LineBreak% Previous usage limits: %OldMetaValue% %LineBreak% New usage limits: %NewMetaValue% %LineBreak% %EditorLinkCoupon%', 'wp-security-audit-log' ), 'woocommerce-store', 'modified' ),
627
  array( 9069, WSAL_INFORMATIONAL, __( 'User changed the description of a coupon', 'wp-security-audit-log' ), __( 'Changed the description of the coupon %CouponName% %LineBreak% Previous description: %OldDescription% %LineBreak% New description: %NewDescription% %LineBreak% %EditorLinkCoupon%', 'wp-security-audit-log' ), 'woocommerce-store', 'modified' ),
628
  array( 9070, E_WARNING, __( 'User changed the status of a coupon', 'wp-security-audit-log' ), __( 'Changed the Status of the WooCommerce coupon %CouponName% from %OldStatus% to %NewStatus%.', 'wp-security-audit-log' ), 'woocommerce-store' ),
629
+ array( 9071, WSAL_INFORMATIONAL, __( 'User renamed a WooCommerce coupon', 'wp-security-audit-log' ), __( 'Old coupon name: %OldName% %LineBreak% New coupon name: %NewName% %LineBreak% %EditorLinkCoupon%', 'wp-security-audit-log' ), 'woocommerce-store', 'renamed' ),
630
  ),
631
 
632
  __( 'Orders', 'wp-security-audit-log' ) => array(
img/addons/bbpress.png ADDED
Binary file
img/addons/wpforms.png ADDED
Binary file
img/addons/yoast.png ADDED
Binary file
js/common.js CHANGED
@@ -52,4 +52,72 @@ jQuery( document ).ready( function() {
52
  });
53
 
54
  jQuery( 'head' ).append( '<style>.wp-submenu .dashicons-external:before{vertical-align: bottom;}</style>' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  });
52
  });
53
 
54
  jQuery( 'head' ).append( '<style>.wp-submenu .dashicons-external:before{vertical-align: bottom;}</style>' );
55
+
56
+ // Add on installer
57
+ jQuery(".install-addon").not('.disabled').click( function(e) {
58
+ // Disable other buttons whilst the process is happening.
59
+ jQuery(".install-addon").not(this).prop('disabled', true);
60
+
61
+ jQuery(this).html( wsalCommonData.installing );
62
+ var currentButton = jQuery(this);
63
+ var PluginSlug = jQuery(this).attr('data-plugin-slug');
64
+ var nonceValue = jQuery(this).attr('data-nonce');
65
+ var PluginDownloadUrl = jQuery(this).attr('data-plugin-download-url');
66
+ var RedirectToTab = jQuery(this).attr('data-plugin-event-tab-id');
67
+ jQuery(currentButton).next('.spinner').show('200');
68
+ e.preventDefault();
69
+ jQuery.ajax({
70
+ type: 'POST',
71
+ dataType : "json",
72
+ url: wsalCommonData.ajaxURL,
73
+ data : {
74
+ action: "run_addon_install",
75
+ plugin_slug: PluginSlug,
76
+ plugin_url: PluginDownloadUrl,
77
+ _wpnonce: nonceValue
78
+ },
79
+ complete: function( data ) {
80
+ if( data.responseText == '"already_installed"' ) {
81
+ jQuery(currentButton).html( wsalCommonData.already_installed ).addClass('disabled');
82
+ jQuery(currentButton).next('.spinner').hide('200');
83
+ window.location.href="admin.php?page=wsal-togglealerts" + RedirectToTab;
84
+ jQuery('[href="' + RedirectToTab + '"]').trigger('click');
85
+ jQuery(currentButton).addClass('disabled');
86
+ } else if ( data.responseText == '"activated"' ) {
87
+ jQuery(currentButton).html( wsalCommonData.activated ).addClass('disabled');
88
+ jQuery(currentButton).next('.spinner').hide('200');
89
+ window.location.href="admin.php?page=wsal-togglealerts" + RedirectToTab;
90
+ jQuery('[href="' + RedirectToTab + '"]').trigger('click');
91
+ jQuery(currentButton).addClass('disabled');
92
+ } else if ( JSON.stringify(data.responseText).toLowerCase().indexOf('failed') >= 0 ) {
93
+ jQuery(currentButton).html( wsalCommonData.failed ).addClass('disabled');
94
+ jQuery(currentButton).next('.spinner').hide('200');
95
+ } else if ( data.responseText == '"success"' || JSON.stringify(data.responseText).toLowerCase().indexOf('success') >= 0 ) {
96
+ jQuery(currentButton).html( wsalCommonData.installed ).addClass('disabled');
97
+ jQuery(currentButton).next('.spinner').hide('200');
98
+ window.location.href="admin.php?page=wsal-togglealerts" + RedirectToTab;
99
+ // Reload as tabs are not present on page.
100
+ location.reload();
101
+ }
102
+ jQuery(".install-addon").not(this).prop('disabled', false);
103
+ },
104
+ });
105
+ });
106
+
107
+ // Totally disabling the button.
108
+ jQuery(".install-addon.disabled").prop('disabled', true);
109
+
110
+ // Hide save button when 3rd party plugins tab is Opened
111
+ jQuery('.nav-tab').click(function(){
112
+ if( jQuery('[href="#tab-third-party-plugins"]').hasClass('nav-tab-active') ) {
113
+ jQuery('.submit #submit').hide(0);
114
+ } else {
115
+ jQuery('.submit #submit').show(0);
116
+ }
117
+ });
118
+ if( jQuery('[href="#tab-third-party-plugins"]').hasClass('nav-tab-active') ) {
119
+ jQuery('.submit #submit').hide(0);
120
+ } else {
121
+ jQuery('.submit #submit').show(0);
122
+ }
123
  });
languages/wp-security-audit-log.pot CHANGED
@@ -3,14 +3,14 @@ msgid ""
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: WP Security Audit Log\n"
6
- "POT-Creation-Date: 2020-01-08 20:06+0100\n"
7
- "PO-Revision-Date: 2020-01-08 20:06+0100\n"
8
  "Last-Translator: \n"
9
  "Language-Team: \n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
- "X-Generator: Poedit 2.2.4\n"
14
  "X-Poedit-Basepath: ..\n"
15
  "X-Poedit-Flags-xgettext: --add-comments=translators:\n"
16
  "X-Poedit-WPHeader: wp-security-audit-log.php\n"
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: WP Security Audit Log\n"
6
+ "POT-Creation-Date: 2020-02-10 20:16+0100\n"
7
+ "PO-Revision-Date: 2020-02-10 20:16+0100\n"
8
  "Last-Translator: \n"
9
  "Language-Team: \n"
10
  "MIME-Version: 1.0\n"
11
  "Content-Type: text/plain; charset=UTF-8\n"
12
  "Content-Transfer-Encoding: 8bit\n"
13
+ "X-Generator: Poedit 2.3\n"
14
  "X-Poedit-Basepath: ..\n"
15
  "X-Poedit-Flags-xgettext: --add-comments=translators:\n"
16
  "X-Poedit-WPHeader: wp-security-audit-log.php\n"
readme.txt CHANGED
@@ -6,7 +6,7 @@ License URI: https://www.gnu.org/licenses/gpl.html
6
  Tags: wordpress security plugin, wordpress security audit log, audit log, activity logs, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, SMS messages, tracking, user tracking, user activity report, wordpress audit trail
7
  Requires at least: 3.6
8
  Tested up to: 5.3.2
9
- Stable tag: 4.0.0
10
  Requires PHP: 5.5
11
 
12
  An easy to use & comprehensive WordPress activity log plugin to log all changes on WordPress sites & multisite networks.
@@ -154,9 +154,10 @@ We need help translating the plugin and the WordPress Security Alerts. Please vi
154
  * Spanish translation by the [WP Body team](https://wpbody.com/)
155
  * French translations by Denis Moscato
156
 
157
- #### Activity Log Extensions
158
 
159
- * <strong>[Activity Log for MainWP](https://www.wpsecurityauditlog.com/activity-log-mainwp-extension/?utm_source=wordpress.org&utm_medium=referral&utm_campaign=WSAL&utm_content=plugin+repos+description)</strong>: This extension allows you to keep a log of MainWP network changes and to view the activity logs of all child sites from one central location - the MainWP dashboard.
 
160
 
161
  #### Related Links and Documentation
162
 
@@ -203,31 +204,31 @@ Please refer to our [Support & Documentation pages](https://www.wpsecurityauditl
203
 
204
  == Changelog ==
205
 
206
- = 4.0.0 (2020-01-08) =
207
 
208
- Release notes: [Update 4.0.0 - The all new more comprehensive yet easier to read WordPress activity log](https://www.wpsecurityauditlog.com/releases/update-4/)
209
 
210
  * **New features**
211
 
212
- * New activity log viewer with two different view modes: grid and list view.
213
- * Two new types of [WodPress activity log metadata](https://www.wpsecurityauditlog.com/support-documentation/metadata-wordpress-activity-log-events/): event type and object. OPTIONAL: [Upgrade old activity log data to v4](https://www.wpsecurityauditlog.com/support-documentation/activity-log-data-upgrade-plugin/).
214
- * New [WordPress activity log severity levels](https://www.wpsecurityauditlog.com/support-documentation/severity-levels-wordpress-activity-log/) (and icons).
215
- * New UI / UX for the [WordPress activity log search & filters](https://www.wpsecurityauditlog.com/premium-features/search-filters-wordpress-activity-log/).
216
- * Added search filters for the two new metadata types in the activity logs: event type and object.
217
 
218
  * **Improvements**
219
 
220
- * Updated the severity levels of all activity log events.
221
- * Included the two new metadata types in the email notification templates (event type and object metadata).
222
- * Updated the Freemius SDK to version 2.3.2.
223
- * Added a notification to refresh search when the filters change.
224
- * Added several new reference links in the plugin's help text.
225
-
 
 
226
  * **Bug fixes**
227
 
228
- * Addressed a warning message in the logs generated by the connector when using PHP 7.4.
229
- * Fixed an issue which was triggered when using the User Switching filter hook.
230
- * Few spelling mistakes in the plugin's UI and settings pages.
231
 
232
  = Earlier versions =
233
 
6
  Tags: wordpress security plugin, wordpress security audit log, audit log, activity logs, event log wordpress, wordpress user tracking, wordpress activity log, wordpress audit, security event log, audit trail, wordpress security monitor, wordpress admin, wordpress admin monitoring, user activity, admin, multisite, dashboard, notification, wordpress monitoring, email notification, wordpress email alerts, SMS messages, tracking, user tracking, user activity report, wordpress audit trail
7
  Requires at least: 3.6
8
  Tested up to: 5.3.2
9
+ Stable tag: 4.0.1
10
  Requires PHP: 5.5
11
 
12
  An easy to use & comprehensive WordPress activity log plugin to log all changes on WordPress sites & multisite networks.
154
  * Spanish translation by the [WP Body team](https://wpbody.com/)
155
  * French translations by Denis Moscato
156
 
157
+ #### Activity Log add-ons for third party plugins
158
 
159
+ * <strong>[Activity Log for MainWP](https://www.wpsecurityauditlog.com/activity-log-mainwp-extension/)</strong>: This MainWP extension allows you to keep a log of MainWP network changes and to view the activity logs of all child sites from one central location - the MainWP dashboard.
160
+ * <strong>[Activity Log add-on for WPForms](https://www.wpsecurityauditlog.com/integrations/activity-log-wpforms/)</strong>: Install this add-on with the WP Security Audit Log to keep a log of changes in WPForms plugin, forms, form files, entries (leads) and more.
161
 
162
  #### Related Links and Documentation
163
 
204
 
205
  == Changelog ==
206
 
207
+ = 4.0.1 (2020-02-13) =
208
 
209
+ Release notes: [Update 4.0.1 - activity logs for WPForms](https://www.wpsecurityauditlog.com/releases/update-4-0-1/)
210
 
211
  * **New features**
212
 
213
+ * [Activity logs for WPForms](http://www.wpsecurityauditlog.com/integrations/activity-log-wpforms/)
214
+ * One-click installation and activation feature for new third party plugins add-ons.
215
+ * New Third Party Plugins tab in Enable/Disable Events section to allow users to install add-ons for third party plugins.
216
+ * Added the new event types "Renamed" and "Duplicated" (more on [activity log event types](https://www.wpsecurityauditlog.com/support-documentation/objects-event-types-wordpress-activity-log/)).
217
+ * Added several new [hooks in the plugin](https://www.wpsecurityauditlog.com/support-documentation/list-hooks/), mainly to allow custom editor link, to add custom column to the logs viewer, to add new event types and objects.
218
 
219
  * **Improvements**
220
 
221
+ * Updated event IDs 2123, 2062, 2084, 9077 and 9071 so they now use the "Renamed" event type.
222
+ * Updated the [activity log severity levels](https://www.wpsecurityauditlog.com/support-documentation/severity-levels-wordpress-activity-log/) definitions in defaults.php)
223
+ * Updated / improved some of the help text messages.
224
+ * Plugin does not automatically retrieve the IP addresses and latest change of logged in users if there are 100+ sessions (performance improvement).
225
+ * Localized text in JS files.
226
+ * Started removing obsolete code.
227
+ * Added new filter to allow custom %EditorLinkWPForm% from custom events add-ons.
228
+
229
  * **Bug fixes**
230
 
231
+ * Only the path of the added, modified or deleted file was reported in daily summary email.
 
 
232
 
233
  = Earlier versions =
234
 
wp-security-audit-log.php CHANGED
@@ -4,7 +4,7 @@
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: 4.0.0
8
  * Text Domain: wp-security-audit-log
9
  * Author URI: http://www.wpwhitesecurity.com/
10
  * License: GPL2
@@ -46,7 +46,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
46
  *
47
  * @var string
48
  */
49
- public $version = '4.0.0';
50
 
51
  // Plugin constants.
52
  const PLG_CLS_PRFX = 'WSAL_';
@@ -351,6 +351,10 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
351
  require_once 'classes/Views/Search.php';
352
  require_once 'classes/Views/Settings.php';
353
  require_once 'classes/Views/ToggleAlerts.php';
 
 
 
 
354
  }
355
 
356
  // Connectors.
@@ -420,6 +424,11 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
420
  add_action( 'wsal_freemius_loaded', array( $this, 'adjust_freemius_strings' ) );
421
 
422
  $this->init_freemius();
 
 
 
 
 
423
  }
424
 
425
  /**
@@ -880,7 +889,7 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
880
  */
881
  public function adjust_freemius_strings() {
882
  // only update these messages if using premium plugin.
883
- if ( ! wsal_freemius()->is_premium() ) {
884
  return;
885
  }
886
  wsal_freemius()->override_i18n(
@@ -1108,8 +1117,13 @@ if ( ! function_exists( 'wsal_freemius' ) ) {
1108
 
1109
  // Set data array for common script.
1110
  $script_data = array(
1111
- 'ajaxURL' => admin_url( 'admin-ajax.php' ),
1112
- 'liveEvents' => $live_events_enabled,
 
 
 
 
 
1113
  );
1114
  if ( $live_events_enabled ) {
1115
  $occurrence = new WSAL_Models_Occurrence();
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: 4.0.1
8
  * Text Domain: wp-security-audit-log
9
  * Author URI: http://www.wpwhitesecurity.com/
10
  * License: GPL2
46
  *
47
  * @var string
48
  */
49
+ public $version = '4.0.1';
50
 
51
  // Plugin constants.
52
  const PLG_CLS_PRFX = 'WSAL_';
351
  require_once 'classes/Views/Search.php';
352
  require_once 'classes/Views/Settings.php';
353
  require_once 'classes/Views/ToggleAlerts.php';
354
+
355
+ // Utilities.
356
+ require_once 'classes/Utilities/PluginInstallAndActivate.php';
357
+ require_once 'classes/Utilities/PluginInstallerAction.php';
358
  }
359
 
360
  // Connectors.
424
  add_action( 'wsal_freemius_loaded', array( $this, 'adjust_freemius_strings' ) );
425
 
426
  $this->init_freemius();
427
+
428
+ if ( is_admin() ) {
429
+ $plugin_installer_ajax = new WSAL_PluginInstallerAction();
430
+ $plugin_installer_ajax->register();
431
+ }
432
  }
433
 
434
  /**
889
  */
890
  public function adjust_freemius_strings() {
891
  // only update these messages if using premium plugin.
892
+ if ( ( ! wsal_freemius()->is_premium() ) || ( ! method_exists( wsal_freemius(), 'override_il8n' ) ) ) {
893
  return;
894
  }
895
  wsal_freemius()->override_i18n(
1117
 
1118
  // Set data array for common script.
1119
  $script_data = array(
1120
+ 'ajaxURL' => admin_url( 'admin-ajax.php' ),
1121
+ 'liveEvents' => $live_events_enabled,
1122
+ 'installing' => __( 'Installing, please wait', 'wp-security-audit-log' ),
1123
+ 'already_installed' => __( 'Already installed', 'wp-security-audit-log' ),
1124
+ 'installed' => __( 'Add-on installed', 'wp-security-audit-log' ),
1125
+ 'activated' => __( 'Add-on activated', 'wp-security-audit-log' ),
1126
+ 'failed' => __( 'Install failed', 'wp-security-audit-log' ),
1127
  );
1128
  if ( $live_events_enabled ) {
1129
  $occurrence = new WSAL_Models_Occurrence();