Simple History - Version 2.39.0

Version Description

(January 2021) =

  • Added: Logging of events that a user performs via the WP Crontrol plugin (requires WP Crontrol version 1.9.0 or later). Simple History will log when cron events are added, edited, deleted, and manually ran, and when cron schedules are added and deleted. Props https://github.com/johnbillion.
Download this release

Release Info

Developer eskapism
Plugin Icon 128x128 Simple History
Version 2.39.0
Comparing to
See all releases

Code changes from version 2.38.0 to 2.39.0

inc/SimpleHistory.php CHANGED
@@ -896,6 +896,7 @@ class SimpleHistory
896
 
897
  // Loggers for third party plugins.
898
  $loggersDir . 'PluginUserSwitchingLogger.php',
 
899
  $loggersDir . 'PluginEnableMediaReplaceLogger.php',
900
  $loggersDir . 'Plugin_UltimateMembers_Logger.php',
901
  $loggersDir . 'Plugin_LimitLoginAttempts.php',
896
 
897
  // Loggers for third party plugins.
898
  $loggersDir . 'PluginUserSwitchingLogger.php',
899
+ $loggersDir . 'PluginWPCrontrolLogger.php',
900
  $loggersDir . 'PluginEnableMediaReplaceLogger.php',
901
  $loggersDir . 'Plugin_UltimateMembers_Logger.php',
902
  $loggersDir . 'Plugin_LimitLoginAttempts.php',
index.php CHANGED
@@ -6,7 +6,7 @@
6
  * Text Domain: simple-history
7
  * Domain Path: /languages
8
  * Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
9
- * Version: 2.38.0
10
  * Author: Pär Thernström
11
  * Author URI: http://simple-history.com/
12
  * License: GPL2
@@ -45,7 +45,7 @@ if ($ok_php_version && $ok_wp_version) {
45
  * @TODO: make activation multi site aware, as in https://github.com/scribu/wp-proper-network-activation
46
  * register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
47
  */
48
- define('SIMPLE_HISTORY_VERSION', '2.38.0');
49
  define('SIMPLE_HISTORY_PATH', plugin_dir_path(__FILE__));
50
  define('SIMPLE_HISTORY_BASENAME', plugin_basename(__FILE__));
51
  define('SIMPLE_HISTORY_DIR_URL', plugin_dir_url(__FILE__));
6
  * Text Domain: simple-history
7
  * Domain Path: /languages
8
  * Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
9
+ * Version: 2.39.0
10
  * Author: Pär Thernström
11
  * Author URI: http://simple-history.com/
12
  * License: GPL2
45
  * @TODO: make activation multi site aware, as in https://github.com/scribu/wp-proper-network-activation
46
  * register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
47
  */
48
+ define('SIMPLE_HISTORY_VERSION', '2.39.0');
49
  define('SIMPLE_HISTORY_PATH', plugin_dir_path(__FILE__));
50
  define('SIMPLE_HISTORY_BASENAME', plugin_basename(__FILE__));
51
  define('SIMPLE_HISTORY_DIR_URL', plugin_dir_url(__FILE__));
loggers/PluginWPCrontrolLogger.php ADDED
@@ -0,0 +1,428 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ defined('ABSPATH') or die();
4
+
5
+ /**
6
+ * Logs cron event management from the WP Crontrol plugin
7
+ * Plugin URL: https://wordpress.org/plugins/wp-crontrol/
8
+ *
9
+ * Requires WP Crontrol 1.9.0 or later.
10
+ *
11
+ * @since x.x
12
+ */
13
+ class PluginWPCrontrolLogger extends SimpleLogger
14
+ {
15
+
16
+ public $slug = __CLASS__;
17
+
18
+ /**
19
+ * Get array with information about this logger
20
+ *
21
+ * @return array
22
+ */
23
+ public function getInfo()
24
+ {
25
+
26
+ $arr_info = array(
27
+ 'name' => _x('WP Crontrol Logger', 'PluginWPCrontrolLogger', 'simple-history'),
28
+ 'description' => _x('Logs management of cron events', 'PluginWPCrontrolLogger', 'simple-history'),
29
+ 'name_via' => _x('Using plugin WP Crontrol', 'PluginWPCrontrolLogger', 'simple-history'),
30
+ 'capability' => 'manage_options',
31
+ 'messages' => array(
32
+ 'added_new_event' => _x('Added cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history'),
33
+ 'ran_event' => _x('Manually ran cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history'),
34
+ 'deleted_event' => _x('Deleted cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history'),
35
+ 'deleted_all_with_hook' => _x('Deleted all "{event_hook}" cron events', 'PluginWPCrontrolLogger', 'simple-history'),
36
+ 'edited_event' => _x('Edited cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history'),
37
+ 'added_new_schedule' => _x('Added cron schedule "{schedule_name}"', 'PluginWPCrontrolLogger', 'simple-history'),
38
+ 'deleted_schedule' => _x('Deleted cron schedule "{schedule_name}"', 'PluginWPCrontrolLogger', 'simple-history'),
39
+ ),
40
+ );
41
+
42
+ return $arr_info;
43
+ }
44
+
45
+ public function loaded()
46
+ {
47
+
48
+ add_action('crontrol/added_new_event', array( $this, 'added_new_event' ));
49
+ add_action('crontrol/added_new_php_event', array( $this, 'added_new_event' ));
50
+ add_action('crontrol/ran_event', array( $this, 'ran_event' ));
51
+ add_action('crontrol/deleted_event', array( $this, 'deleted_event' ));
52
+ add_action('crontrol/deleted_all_with_hook', array( $this, 'deleted_all_with_hook' ), 10, 2);
53
+ add_action('crontrol/edited_event', array( $this, 'edited_event' ), 10, 2);
54
+ add_action('crontrol/edited_php_event', array( $this, 'edited_event' ), 10, 2);
55
+ add_action('crontrol/added_new_schedule', array( $this, 'added_new_schedule' ), 10, 3);
56
+ add_action('crontrol/deleted_schedule', array( $this, 'deleted_schedule' ));
57
+ }
58
+
59
+ /**
60
+ * Fires after a new cron event is added.
61
+ *
62
+ * @param object $event {
63
+ * An object containing the event's data.
64
+ *
65
+ * @type string $hook Action hook to execute when the event is run.
66
+ * @type int $timestamp Unix timestamp (UTC) for when to next run the event.
67
+ * @type string|false $schedule How often the event should subsequently recur.
68
+ * @type array $args Array containing each separate argument to pass to the hook's callback function.
69
+ * @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
70
+ * }
71
+ */
72
+ public function added_new_event($event)
73
+ {
74
+ $context = array(
75
+ 'event_hook' => $event->hook,
76
+ 'event_timestamp' => $event->timestamp,
77
+ 'event_args' => $event->args,
78
+ );
79
+
80
+ if ( $event->schedule ) {
81
+ $context['event_schedule_name'] = $event->schedule;
82
+
83
+ if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
84
+ $context['event_schedule_name'] = \Crontrol\Event\get_schedule_name( $event );
85
+ }
86
+ } else {
87
+ $context['event_schedule_name'] = _x('None', 'PluginWPCrontrolLogger', 'simple-history');
88
+ }
89
+
90
+ $this->infoMessage(
91
+ 'added_new_event',
92
+ $context
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Fires after a cron event is ran manually.
98
+ *
99
+ * @param object $event {
100
+ * An object containing the event's data.
101
+ *
102
+ * @type string $hook Action hook to execute when the event is run.
103
+ * @type int $timestamp Unix timestamp (UTC) for when to next run the event.
104
+ * @type string|false $schedule How often the event should subsequently recur.
105
+ * @type array $args Array containing each separate argument to pass to the hook's callback function.
106
+ * @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
107
+ * }
108
+ */
109
+ public function ran_event($event)
110
+ {
111
+ $context = array(
112
+ 'event_hook' => $event->hook,
113
+ 'event_args' => $event->args,
114
+ );
115
+
116
+ $this->infoMessage(
117
+ 'ran_event',
118
+ $context
119
+ );
120
+ }
121
+
122
+ /**
123
+ * Fires after a cron event is deleted.
124
+ *
125
+ * @param object $event {
126
+ * An object containing the event's data.
127
+ *
128
+ * @type string $hook Action hook to execute when the event is run.
129
+ * @type int $timestamp Unix timestamp (UTC) for when to next run the event.
130
+ * @type string|false $schedule How often the event should subsequently recur.
131
+ * @type array $args Array containing each separate argument to pass to the hook's callback function.
132
+ * @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
133
+ * }
134
+ */
135
+ public function deleted_event($event)
136
+ {
137
+ $context = array(
138
+ 'event_hook' => $event->hook,
139
+ 'event_timestamp' => $event->timestamp,
140
+ 'event_args' => $event->args,
141
+ );
142
+
143
+ if ( $event->schedule ) {
144
+ $context['event_schedule_name'] = $event->schedule;
145
+
146
+ if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
147
+ $context['event_schedule_name'] = \Crontrol\Event\get_schedule_name( $event );
148
+ }
149
+ } else {
150
+ $context['event_schedule_name'] = _x('None', 'PluginWPCrontrolLogger', 'simple-history');
151
+ }
152
+
153
+ $this->infoMessage(
154
+ 'deleted_event',
155
+ $context
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Fires after all cron events with the given hook are deleted.
161
+ *
162
+ * @param string $hook The hook name.
163
+ * @param int $deleted The number of events that were deleted.
164
+ */
165
+ public function deleted_all_with_hook($hook, $deleted)
166
+ {
167
+ $context = array(
168
+ 'event_hook' => $hook,
169
+ 'events_deleted' => $deleted,
170
+ );
171
+
172
+ $this->infoMessage(
173
+ 'deleted_all_with_hook',
174
+ $context
175
+ );
176
+ }
177
+
178
+ /**
179
+ * Fires after a cron event is edited.
180
+ *
181
+ * @param object $event {
182
+ * An object containing the new event's data.
183
+ *
184
+ * @type string $hook Action hook to execute when the event is run.
185
+ * @type int $timestamp Unix timestamp (UTC) for when to next run the event.
186
+ * @type string|false $schedule How often the event should subsequently recur.
187
+ * @type array $args Array containing each separate argument to pass to the hook's callback function.
188
+ * @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
189
+ * }
190
+ * @param object $original {
191
+ * An object containing the original event's data.
192
+ *
193
+ * @type string $hook Action hook to execute when the event is run.
194
+ * @type int $timestamp Unix timestamp (UTC) for when to next run the event.
195
+ * @type string|false $schedule How often the event should subsequently recur.
196
+ * @type array $args Array containing each separate argument to pass to the hook's callback function.
197
+ * @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
198
+ * }
199
+ */
200
+ public function edited_event($event, $original)
201
+ {
202
+ $context = array(
203
+ 'event_hook' => $event->hook,
204
+ 'event_timestamp' => $event->timestamp,
205
+ 'event_args' => $event->args,
206
+ 'event_original_hook' => $original->hook,
207
+ 'event_original_timestamp' => $original->timestamp,
208
+ 'event_original_args' => $original->args,
209
+ );
210
+
211
+ if ( $event->schedule ) {
212
+ $context['event_schedule_name'] = $event->schedule;
213
+
214
+ if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
215
+ $context['event_schedule_name'] = \Crontrol\Event\get_schedule_name( $event );
216
+ }
217
+ } else {
218
+ $context['event_schedule_name'] = _x('None', 'PluginWPCrontrolLogger', 'simple-history');
219
+ }
220
+
221
+ if ( $original->schedule ) {
222
+ $context['event_original_schedule_name'] = $original->schedule;
223
+
224
+ if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
225
+ $context['event_original_schedule_name'] = \Crontrol\Event\get_schedule_name( $original );
226
+ }
227
+ } else {
228
+ $context['event_original_schedule_name'] = _x('None', 'PluginWPCrontrolLogger', 'simple-history');
229
+ }
230
+
231
+ $this->infoMessage(
232
+ 'edited_event',
233
+ $context
234
+ );
235
+ }
236
+
237
+ /**
238
+ * Fires after a new cron schedule is added.
239
+ *
240
+ * @param string $name The internal name of the schedule.
241
+ * @param int $interval The interval between executions of the new schedule.
242
+ * @param string $display The display name of the schedule.
243
+ */
244
+ public function added_new_schedule( $name, $interval, $display ) {
245
+ $context = array(
246
+ 'schedule_name' => $name,
247
+ 'schedule_interval' => $interval,
248
+ 'schedule_display' => $display,
249
+ );
250
+
251
+ $this->infoMessage(
252
+ 'added_new_schedule',
253
+ $context
254
+ );
255
+ }
256
+
257
+ /**
258
+ * Fires after a cron schedule is deleted.
259
+ *
260
+ * @param string $name The internal name of the schedule.
261
+ */
262
+ public function deleted_schedule( $name ) {
263
+ $context = array(
264
+ 'schedule_name' => $name,
265
+ );
266
+
267
+ $this->infoMessage(
268
+ 'deleted_schedule',
269
+ $context
270
+ );
271
+ }
272
+
273
+ public function getLogRowDetailsOutput($row) {
274
+ switch ( $row->context_message_key ) {
275
+ case 'added_new_event':
276
+ case 'ran_event':
277
+ case 'deleted_event':
278
+ case 'deleted_all_with_hook':
279
+ case 'edited_event':
280
+ return $this->cronEventDetailsOutput( $row );
281
+ break;
282
+ case 'added_new_schedule':
283
+ case 'deleted_schedule':
284
+ return $this->cronScheduleDetailsOutput( $row );
285
+ break;
286
+ }
287
+
288
+ return '';
289
+ }
290
+
291
+ protected function cronEventDetailsOutput($row) {
292
+ $tmpl_row = '
293
+ <tr>
294
+ <td>%1$s</td>
295
+ <td>%2$s</td>
296
+ </tr>
297
+ ';
298
+ $context = $row->context;
299
+ $output = '<table class="SimpleHistoryLogitem__keyValueTable">';
300
+
301
+ if ( isset( $context['event_original_hook'] ) && ( $context['event_original_hook'] !== $context['event_hook'] ) ) {
302
+ $key_text_diff = simple_history_text_diff(
303
+ $context['event_original_hook'],
304
+ $context['event_hook']
305
+ );
306
+
307
+ if ($key_text_diff) {
308
+ $output .= sprintf(
309
+ $tmpl_row,
310
+ _x('Hook', 'PluginWPCrontrolLogger', 'simple-history'),
311
+ $key_text_diff
312
+ );
313
+ }
314
+ }
315
+
316
+ if ( isset( $context['event_original_args'] ) && ( $context['event_original_args'] !== $context['event_args'] ) ) {
317
+ $key_text_diff = simple_history_text_diff(
318
+ $context['event_original_args'],
319
+ $context['event_args']
320
+ );
321
+
322
+ if ($key_text_diff) {
323
+ $output .= sprintf(
324
+ $tmpl_row,
325
+ _x('Arguments', 'PluginWPCrontrolLogger', 'simple-history'),
326
+ $key_text_diff
327
+ );
328
+ }
329
+ } else if ( isset( $context['event_args'] ) ) {
330
+ if ( '[]' !== $context['event_args'] ) {
331
+ $args = $context['event_args'];
332
+ } else {
333
+ $args = _x('None', 'PluginWPCrontrolLogger', 'simple-history');
334
+ }
335
+
336
+ $output .= sprintf(
337
+ $tmpl_row,
338
+ _x('Arguments', 'PluginWPCrontrolLogger', 'simple-history'),
339
+ esc_html( $args )
340
+ );
341
+ }
342
+
343
+ if ( isset( $context['event_original_timestamp'] ) && ( $context['event_original_timestamp'] !== $context['event_timestamp'] ) ) {
344
+ $key_text_diff = simple_history_text_diff(
345
+ gmdate( 'Y-m-d H:i:s', $context['event_original_timestamp'] ),
346
+ gmdate( 'Y-m-d H:i:s', $context['event_timestamp'] )
347
+ );
348
+
349
+ if ($key_text_diff) {
350
+ $output .= sprintf(
351
+ $tmpl_row,
352
+ _x('Next Run', 'PluginWPCrontrolLogger', 'simple-history'),
353
+ $key_text_diff
354
+ );
355
+ }
356
+ } else if ( isset( $context['event_timestamp'] ) ) {
357
+ $output .= sprintf(
358
+ $tmpl_row,
359
+ _x('Next Run', 'PluginWPCrontrolLogger', 'simple-history'),
360
+ esc_html( gmdate( 'Y-m-d H:i:s', $context['event_timestamp'] ) . ' UTC' )
361
+ );
362
+ }
363
+
364
+ if ( isset( $context['event_original_schedule_name'] ) && ( $context['event_original_schedule_name'] !== $context['event_schedule_name'] ) ) {
365
+ $key_text_diff = simple_history_text_diff(
366
+ $context['event_original_schedule_name'],
367
+ $context['event_schedule_name']
368
+ );
369
+
370
+ if ($key_text_diff) {
371
+ $output .= sprintf(
372
+ $tmpl_row,
373
+ _x('Recurrence', 'PluginWPCrontrolLogger', 'simple-history'),
374
+ $key_text_diff
375
+ );
376
+ }
377
+ } else if ( isset( $context['event_schedule_name'] ) ) {
378
+ $output .= sprintf(
379
+ $tmpl_row,
380
+ _x('Recurrence', 'PluginWPCrontrolLogger', 'simple-history'),
381
+ esc_html( $context['event_schedule_name'] )
382
+ );
383
+ }
384
+
385
+ $output .= '</table>';
386
+
387
+ return $output;
388
+ }
389
+
390
+ protected function cronScheduleDetailsOutput($row) {
391
+ $tmpl_row = '
392
+ <tr>
393
+ <td>%1$s</td>
394
+ <td>%2$s</td>
395
+ </tr>
396
+ ';
397
+ $context = $row->context;
398
+ $output = '<table class="SimpleHistoryLogitem__keyValueTable">';
399
+
400
+ if ( isset( $context['schedule_name'] ) ) {
401
+ $output .= sprintf(
402
+ $tmpl_row,
403
+ _x('Name', 'PluginWPCrontrolLogger', 'simple-history'),
404
+ esc_html( $context['schedule_name'] )
405
+ );
406
+ }
407
+
408
+ if ( isset( $context['schedule_interval'] ) ) {
409
+ $output .= sprintf(
410
+ $tmpl_row,
411
+ _x('Interval', 'PluginWPCrontrolLogger', 'simple-history'),
412
+ esc_html( $context['schedule_interval'] )
413
+ );
414
+ }
415
+
416
+ if ( isset( $context['schedule_display'] ) ) {
417
+ $output .= sprintf(
418
+ $tmpl_row,
419
+ _x('Display Name', 'PluginWPCrontrolLogger', 'simple-history'),
420
+ esc_html( $context['schedule_display'] )
421
+ );
422
+ }
423
+
424
+ $output .= '</table>';
425
+
426
+ return $output;
427
+ }
428
+ }
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: eskapism
3
  Donate link: https://www.paypal.me/eskapism
4
  Tags: history, log, changes, changelog, audit, audit log, event log, user tracking, trail, pages, attachments, users, dashboard, admin, syslog, feed, activity, stream, audit trail, brute-force
5
  Requires at least: 5.2
6
- Tested up to: 5.5
7
  Requires PHP: 5.6
8
- Stable tag: 2.38.0
9
 
10
  View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
11
 
@@ -62,6 +62,10 @@ Simple History will log changes made to the field groups and the fields inside f
62
  The [User Switching plugin](https://wordpress.org/plugins/user-switching/) allows you to quickly swap between user accounts in WordPress at the click of a button.
63
  Simple History will log each user switch being made.
64
 
 
 
 
 
65
  **Enable Media Replace**<br>
66
  The [Enable Media Replace plugin](https://wordpress.org/plugins/enable-media-replace/) allows you to replace a file in your media library by uploading a new file in its place.
67
  Simple history will log details about the file being replaced and details about the new file.
@@ -71,16 +75,16 @@ The plugin [Limit Login Attempts](https://wordpress.org/plugins/limit-login-atte
71
  and has not been updated for 4 years. However it still has +1 million installs, so many users will benefit from
72
  Simple History logging login attempts, lockouts, and configuration changes made in the plugin Limit Login Attempts.
73
 
74
- **Redirection**
75
  The [redirection plugin](https://wordpress.org/plugins/redirection/) manages url redirections, using a nice GUI.
76
  Simple History will log redirects and groups that are created, changed, enabled or disabled and also when the global plugin settings have been modified.
77
 
78
- **Duplicate Post**
79
  The plugin [Duplicate Post](https://wordpress.org/plugins/duplicate-post/) allows users to
80
  clone posts of any type.
81
  Simple History will log when a clone of a post or page is done.
82
 
83
- **Beaver Builder**
84
  The plugin [Beaver Build](https://wordpress.org/plugins/beaver-builder-lite-version/) is a page builder for WordPress that adds a flexible drag and drop page builder to the front end of your WordPress website.
85
  Simple History will log when a Beaver Builder layout or template is saved or when the settings for the plugins are saved.
86
 
@@ -189,7 +193,11 @@ Events in the log are stored for 60 days by default. Events older than this will
189
 
190
  == Changelog ==
191
 
192
- = 2.38.0 Unreleased =
 
 
 
 
193
 
194
  - Changed: It's now possible to log things before the `after_setup_theme` hook by using the `SimpleLogger()` function. Before this change calling `SimpleLogger()` before `after_setup_theme`, or on `after_setup_theme` with a prio smaller than 10, would result in a fatal error (`Fatal error: Uncaught Error: Class 'SimpleLogger' not found`). Props https://github.com/JoryHogeveen.
195
 
3
  Donate link: https://www.paypal.me/eskapism
4
  Tags: history, log, changes, changelog, audit, audit log, event log, user tracking, trail, pages, attachments, users, dashboard, admin, syslog, feed, activity, stream, audit trail, brute-force
5
  Requires at least: 5.2
6
+ Tested up to: 5.6
7
  Requires PHP: 5.6
8
+ Stable tag: 2.39.0
9
 
10
  View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
11
 
62
  The [User Switching plugin](https://wordpress.org/plugins/user-switching/) allows you to quickly swap between user accounts in WordPress at the click of a button.
63
  Simple History will log each user switch being made.
64
 
65
+ **WP Crontrol**<br>
66
+ The [WP Crontrol plugin](https://wordpress.org/plugins/wp-crontrol/) enables you to view and control what's happening in the WP-Cron system.
67
+ Simple History will log when cron events are added, edited, deleted, and manually ran, and when cron schedules are added and deleted.
68
+
69
  **Enable Media Replace**<br>
70
  The [Enable Media Replace plugin](https://wordpress.org/plugins/enable-media-replace/) allows you to replace a file in your media library by uploading a new file in its place.
71
  Simple history will log details about the file being replaced and details about the new file.
75
  and has not been updated for 4 years. However it still has +1 million installs, so many users will benefit from
76
  Simple History logging login attempts, lockouts, and configuration changes made in the plugin Limit Login Attempts.
77
 
78
+ **Redirection**<br>
79
  The [redirection plugin](https://wordpress.org/plugins/redirection/) manages url redirections, using a nice GUI.
80
  Simple History will log redirects and groups that are created, changed, enabled or disabled and also when the global plugin settings have been modified.
81
 
82
+ **Duplicate Post**<br>
83
  The plugin [Duplicate Post](https://wordpress.org/plugins/duplicate-post/) allows users to
84
  clone posts of any type.
85
  Simple History will log when a clone of a post or page is done.
86
 
87
+ **Beaver Builder**<br>
88
  The plugin [Beaver Build](https://wordpress.org/plugins/beaver-builder-lite-version/) is a page builder for WordPress that adds a flexible drag and drop page builder to the front end of your WordPress website.
89
  Simple History will log when a Beaver Builder layout or template is saved or when the settings for the plugins are saved.
90
 
193
 
194
  == Changelog ==
195
 
196
+ = 2.39.0 (January 2021) =
197
+
198
+ - Added: Logging of events that a user performs via the [WP Crontrol](https://wordpress.org/plugins/wp-crontrol/) plugin (requires WP Crontrol version 1.9.0 or later). Simple History will log when cron events are added, edited, deleted, and manually ran, and when cron schedules are added and deleted. Props https://github.com/johnbillion.
199
+
200
+ = 2.38.0 (November 2020) =
201
 
202
  - Changed: It's now possible to log things before the `after_setup_theme` hook by using the `SimpleLogger()` function. Before this change calling `SimpleLogger()` before `after_setup_theme`, or on `after_setup_theme` with a prio smaller than 10, would result in a fatal error (`Fatal error: Uncaught Error: Class 'SimpleLogger' not found`). Props https://github.com/JoryHogeveen.
203