Simple History - Version 2.10

Version Description

(September 2016) =

  • Available updates to plugins, themes, and WordPress itself is now logged. Pretty great if you subscribe to the RSS feed to get the changes on a site. No need to manually check the updates-page to see if there are any updates.
  • Changed to logic used to determine if a post edit should be logged or not. Version 2.9 used a version that started to log a bit to much for some plugins. This should fix the problems with the Nextgen Gallery, All-In-One Events Calendar, and Membership 2 plugins. If you still have problems with a plugin that is causing to many events to be logged, please let me know!
Download this release

Release Info

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

Code changes from version 2.9.1 to 2.10

dropins/SimpleHistoryPluginPatchesDropin.php CHANGED
@@ -18,10 +18,50 @@ class SimpleHistoryPluginPatchesDropin {
18
 
19
  $this->patch_captcha_on_login();
20
 
21
- $this->patch_nextgen_gallery();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  }
24
 
 
25
  /**
26
  *
27
  * Nextgen Gallery and Nextgen Gallery Plus updates posts every 30 minutes or so when accessing
@@ -71,6 +111,7 @@ class SimpleHistoryPluginPatchesDropin {
71
  }
72
 
73
  // There. All checked. Now cancel the logging.
 
74
  $doLog = false;
75
 
76
  #error_log(simpleHistory::json_encode( $context ));
18
 
19
  $this->patch_captcha_on_login();
20
 
21
+ #$this->patch_nextgen_gallery();
22
+
23
+ #$this->patch_aio_events_calendar();
24
+
25
+ }
26
+
27
+ /**
28
+ * All-in-one events calendar imports ical/rss events with a cron job
29
+ * which can lead to a lot of posts chnaged
30
+ */
31
+ function patch_aio_events_calendar() {
32
+
33
+ // feature/fix-AIOEventsCalendar
34
+ add_action( "simple_history/log/do_log", array( $this, "patch_aio_events_calendar_on_log" ), 10, 5 );
35
+
36
+ }
37
+
38
+
39
+ function patch_aio_events_calendar_on_log( $doLog, $level = null, $message = null, $context = null, $loggerInstance = null ) {
40
+
41
+ // this happens when posts are updated
42
+ if ( ! isset( $context["_message_key"]) || $context["_message_key"] !== "post_updated" ) {
43
+ return $doLog;
44
+ }
45
+
46
+ // this happens when post type is ai1ec_event
47
+ if ( ! isset( $context["post_type"]) || $context["post_type"] !== "ai1ec_event" ) {
48
+ return $doLog;
49
+ }
50
+
51
+ // we don't log when is happens in admin, only when it's a cron job
52
+ if ( ! defined('DOING_CRON') || ! DOING_CRON || is_admin() ) {
53
+ return $doLog;
54
+ }
55
+
56
+ // ok, this is a non-admin, cron-running post update for the ai1ec_event post type, so cancel the logging
57
+ error_log("ok, cancel ai1ec_event log");
58
+ $doLog = false;
59
+
60
+ return $doLog;
61
 
62
  }
63
 
64
+
65
  /**
66
  *
67
  * Nextgen Gallery and Nextgen Gallery Plus updates posts every 30 minutes or so when accessing
111
  }
112
 
113
  // There. All checked. Now cancel the logging.
114
+ error_log("ok, cancel nextgen gallery log");
115
  $doLog = false;
116
 
117
  #error_log(simpleHistory::json_encode( $context ));
inc/SimpleHistory.php CHANGED
@@ -154,7 +154,9 @@ class SimpleHistory {
154
  $postdata = file_get_contents( "php://input" );
155
  $context["_debug_http_raw_post_data"] = $sh->json_encode( $postdata );
156
 
157
- $context["_debug_wp_debug_backtrace_summary"] = wp_debug_backtrace_summary();
 
 
158
 
159
  return $context;
160
 
@@ -839,6 +841,7 @@ class SimpleHistory {
839
  $loggersDir . "SimpleThemeLogger.php",
840
  $loggersDir . "SimpleUserLogger.php",
841
  $loggersDir . "SimpleCategoriesLogger.php",
 
842
 
843
  // Loggers for third party plugins
844
  $loggersDir . "PluginUserSwitchingLogger.php",
154
  $postdata = file_get_contents( "php://input" );
155
  $context["_debug_http_raw_post_data"] = $sh->json_encode( $postdata );
156
 
157
+ $context["_debug_wp_debug_backtrace_summary"] = wp_debug_backtrace_summary();
158
+ $context["_debug_is_admin"] = json_encode( is_admin() );
159
+ $context["_debug_is_doing_cron"] = json_encode( defined('DOING_CRON') && DOING_CRON );
160
 
161
  return $context;
162
 
841
  $loggersDir . "SimpleThemeLogger.php",
842
  $loggersDir . "SimpleUserLogger.php",
843
  $loggersDir . "SimpleCategoriesLogger.php",
844
+ $loggersDir . "AvailableUpdatesLogger.php",
845
 
846
  // Loggers for third party plugins
847
  $loggersDir . "PluginUserSwitchingLogger.php",
index.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://simple-history.com
5
  Text Domain: simple-history
6
  Domain Path: /languages
7
  Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
8
- Version: 2.9.1
9
  Author: Pär Thernström
10
  Author URI: http://simple-history.com/
11
  License: GPL2
@@ -42,7 +42,7 @@ if ( version_compare( phpversion(), "5.3", ">=") ) {
42
  // register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
43
 
44
  if ( ! defined( 'SIMPLE_HISTORY_VERSION' ) ) {
45
- define( 'SIMPLE_HISTORY_VERSION', '2.9.1' );
46
  }
47
 
48
  if ( ! defined( 'SIMPLE_HISTORY_PATH' ) ) {
5
  Text Domain: simple-history
6
  Domain Path: /languages
7
  Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
8
+ Version: 2.10
9
  Author: Pär Thernström
10
  Author URI: http://simple-history.com/
11
  License: GPL2
42
  // register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
43
 
44
  if ( ! defined( 'SIMPLE_HISTORY_VERSION' ) ) {
45
+ define( 'SIMPLE_HISTORY_VERSION', '2.10' );
46
  }
47
 
48
  if ( ! defined( 'SIMPLE_HISTORY_PATH' ) ) {
loggers/AvailableUpdatesLogger.php ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Logs available updates to themes, plugins and WordPress core
5
+ */
6
+ if ( ! class_exists("AvailableUpdatesLogger") ) {
7
+
8
+ class AvailableUpdatesLogger extends SimpleLogger {
9
+
10
+ public $slug = __CLASS__;
11
+
12
+ function getInfo() {
13
+
14
+ $arr_info = array(
15
+ "name" => "AvailableUpdatesLogger",
16
+ "description" => "Logs found updates to WordPress, plugins, and themes",
17
+ "capability" => "manage_options",
18
+ "messages" => array(
19
+ "core_update_available" => __( 'Found an update to WordPress.', "simple-history" ),
20
+ "plugin_update_available" => __( 'Found an update to plugin "{plugin_name}"', "simple-history" ),
21
+ "theme_update_available" => __( 'Found an update to theme "{theme_name}"', "simple-history" ),
22
+ ),
23
+ "labels" => array(
24
+ "search" => array(
25
+ "label" => _x("WordPress and plugins updates found", "Plugin logger: updates found", "simple-history"),
26
+ "label_all" => _x("All found updates", "Plugin logger: updates found", "simple-history"),
27
+ "options" => array(
28
+ _x("WordPress updates found", "Plugin logger: updates found", "simple-history") => array(
29
+ 'core_update_available'
30
+ ),
31
+ _x("Plugin updates found", "Plugin logger: updates found", "simple-history") => array(
32
+ 'plugin_update_available',
33
+ ),
34
+ _x("Theme updates found", "Plugin logger: updates found", "simple-history") => array(
35
+ 'theme_update_available'
36
+ ),
37
+ )
38
+ ) // search array
39
+ ) // labels
40
+ );
41
+
42
+ return $arr_info;
43
+
44
+ }
45
+
46
+ function loaded() {
47
+
48
+ // When WP is done checking for core updates it sets a site transient called "update_core"
49
+ // set_site_transient( 'update_core', null ); // Uncomment to test
50
+ add_action( "set_site_transient_update_core", array( $this, "on_setted_update_core_transient" ), 10, 1 );
51
+
52
+ // Dito for plugins
53
+ // set_site_transient( 'update_plugins', null ); // Uncomment to test
54
+ add_action( "set_site_transient_update_plugins", array( $this, "on_setted_update_plugins_transient" ), 10, 1 );
55
+
56
+ add_action( "set_site_transient_update_themes", array( $this, "on_setted_update_update_themes" ), 10, 1 );
57
+
58
+ }
59
+
60
+ function on_setted_update_core_transient( $updates ) {
61
+
62
+ global $wp_version;
63
+
64
+ $last_version_checked = get_option( "simplehistory_{$this->slug}_wp_core_version_available" );
65
+
66
+ // During update of network sites this was not set, so make sure to check
67
+ if ( empty( $updates->updates[0]->current ) ) {
68
+ return;
69
+ }
70
+
71
+ $new_wp_core_version = $updates->updates[0]->current; // The new WP core version
72
+
73
+ // Some plugins can mess with version, so get fresh from the version file.
74
+ require_once ABSPATH . WPINC . '/version.php';
75
+
76
+ // If found version is same version as we have logged about before then don't continue
77
+ if ( $last_version_checked == $new_wp_core_version ) {
78
+ return;
79
+ }
80
+
81
+ // is WP core update available?
82
+ if ( 'upgrade' == $updates->updates[0]->response ) {
83
+
84
+ $this->noticeMessage( "core_update_available", array(
85
+ "wp_core_current_version" => $wp_version,
86
+ "wp_core_new_version" => $new_wp_core_version,
87
+ "_initiator" => SimpleLoggerLogInitiators::WORDPRESS
88
+ ) );
89
+
90
+ // Store updated version available, so we don't log that version again
91
+ update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
92
+
93
+ }
94
+
95
+ }
96
+
97
+
98
+ function on_setted_update_plugins_transient( $updates ) {
99
+
100
+ if ( empty( $updates->response ) || ! is_array( $updates->response ) ) {
101
+ return;
102
+ }
103
+
104
+ // If we only want to notify about active plugins
105
+ /*
106
+ $active_plugins = get_option( 'active_plugins' );
107
+ $active_plugins = array_flip( $active_plugins ); // find which plugins are active
108
+ $plugins_need_update = array_intersect_key( $plugins_need_update, $active_plugins ); // only keep plugins that are active
109
+ */
110
+
111
+ //update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
112
+ $option_key = "simplehistory_{$this->slug}_plugin_updates_available";
113
+ $checked_updates = get_option( $option_key );
114
+
115
+ if ( ! is_array( $checked_updates ) ) {
116
+ $checked_updates = array();
117
+ }
118
+
119
+ // File needed plugin API
120
+ if ( ! function_exists("get_plugin_data") ) {
121
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
122
+ }
123
+
124
+ // For each available update
125
+ foreach ( $updates->response as $key => $data ) {
126
+
127
+ $plugin_info = get_plugin_data( WP_PLUGIN_DIR . "/" . $key, true, false );
128
+
129
+ $plugin_new_version = isset( $data->new_version ) ? $data->new_version : "";
130
+
131
+ // check if this plugin and this version has been checked/logged already
132
+ if ( ! array_key_exists( $key, $checked_updates ) ) {
133
+ $checked_updates[ $key ] = array(
134
+ "checked_version" => null
135
+ );
136
+ }
137
+
138
+ if ( $checked_updates[ $key ]["checked_version"] == $plugin_new_version ) {
139
+ // This version has been checked/logged already
140
+ continue;
141
+ }
142
+
143
+ $checked_updates[ $key ]["checked_version"] = $plugin_new_version;
144
+
145
+ $this->noticeMessage( "plugin_update_available", array(
146
+ "plugin_name" => isset( $plugin_info['Name'] ) ? $plugin_info['Name'] : "",
147
+ "plugin_current_version" => isset( $plugin_info['Version'] ) ? $plugin_info['Version'] : "",
148
+ "plugin_new_version" => $plugin_new_version,
149
+ "_initiator" => SimpleLoggerLogInitiators::WORDPRESS,
150
+ //"plugin_info" => $plugin_info,
151
+ // "remote_plugin_info" => $remote_plugin_info,
152
+ // "active_plugins" => $active_plugins,
153
+ // "updates" => $updates
154
+ ) );
155
+
156
+ } // foreach
157
+
158
+ update_option( $option_key, $checked_updates );
159
+
160
+ } // function
161
+
162
+
163
+ function on_setted_update_update_themes( $updates ) {
164
+
165
+ if ( empty( $updates->response ) || ! is_array( $updates->response ) ) {
166
+ return;
167
+ }
168
+
169
+ //update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
170
+ $option_key = "simplehistory_{$this->slug}_theme_updates_available";
171
+ $checked_updates = get_option( $option_key );
172
+
173
+ if ( ! is_array( $checked_updates ) ) {
174
+ $checked_updates = array();
175
+ }
176
+
177
+ // For each available update
178
+ foreach ( $updates->response as $key => $data ) {
179
+
180
+ $theme_info = wp_get_theme( $key );
181
+
182
+ #$message .= "\n" . sprintf( __( "Theme: %s is out of date. Please update from version %s to %s", "wp-updates-notifier" ), $theme_info['Name'], $theme_info['Version'], $data['new_version'] ) . "\n";
183
+
184
+ $settings['notified']['theme'][$key] = $data['new_version']; // set theme version we are notifying about
185
+
186
+ $theme_new_version = isset( $data["new_version"] ) ? $data["new_version"] : "";
187
+
188
+ // check if this plugin and this version has been checked/logged already
189
+ if ( ! array_key_exists( $key, $checked_updates ) ) {
190
+ $checked_updates[ $key ] = array(
191
+ "checked_version" => null
192
+ );
193
+ }
194
+
195
+ if ( $checked_updates[ $key ]["checked_version"] == $theme_new_version ) {
196
+ // This version has been checked/logged already
197
+ continue;
198
+ }
199
+
200
+ $checked_updates[ $key ]["checked_version"] = $theme_new_version;
201
+
202
+ $this->noticeMessage( "theme_update_available", array(
203
+ "theme_name" => isset( $theme_info['Name'] ) ? $theme_info['Name'] : "" ,
204
+ "theme_current_version" => isset( $theme_info['Version'] ) ? $theme_info['Version'] : "",
205
+ "theme_new_version" => $theme_new_version,
206
+ "_initiator" => SimpleLoggerLogInitiators::WORDPRESS
207
+ //"plugin_info" => $plugin_info,
208
+ // "remote_plugin_info" => $remote_plugin_info,
209
+ // "active_plugins" => $active_plugins,
210
+ // "updates" => $updates,
211
+ ) );
212
+
213
+ } // foreach
214
+
215
+ update_option( $option_key, $checked_updates );
216
+
217
+ } // function
218
+
219
+ /**
220
+ * Append prev and current version of update object as details in the output
221
+ */
222
+ function getLogRowDetailsOutput( $row ) {
223
+
224
+ $output = "";
225
+
226
+ $current_version = null;
227
+ $new_version = null;
228
+
229
+ $context = isset( $row->context ) ? $row->context : array();
230
+
231
+ switch ( $row->context_message_key ) {
232
+
233
+ case "core_update_available":
234
+ $current_version = isset( $context["wp_core_current_version"] ) ? $context["wp_core_current_version"] : null;
235
+ $new_version = isset( $context["wp_core_new_version"] ) ? $context["wp_core_new_version"] : null;
236
+ break;
237
+
238
+ case "plugin_update_available":
239
+ $current_version = isset( $context["plugin_current_version"] ) ? $context["plugin_current_version"] : null;
240
+ $new_version = isset( $context["plugin_new_version"] ) ? $context["plugin_new_version"] : null;
241
+ break;
242
+
243
+ case "theme_update_available":
244
+ $current_version = isset( $context["theme_current_version"] ) ? $context["theme_current_version"] : null;
245
+ $new_version = isset( $context["theme_new_version"] ) ? $context["theme_new_version"] : null;
246
+ break;
247
+
248
+ }
249
+
250
+ if ( $current_version && $new_version ) {
251
+
252
+ $output .= '<p>';
253
+ $output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
254
+ $output .= "<em>" . __( 'Available version', "simple-history" ) . "</em> " . esc_html( $new_version );
255
+ $output .= '</span> ';
256
+
257
+ $output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
258
+ $output .= "<em>" . __( 'Installed version', "simple-history" ) . "</em> " . esc_html( $current_version );
259
+ $output .= '</span>';
260
+
261
+ $output .= '</p>';
262
+
263
+ // Add link to update-page
264
+ $output .= sprintf( '<p><a href="%1$s">', admin_url("update-core.php") );
265
+ $output .= __( 'View all updates', "simple-history" );
266
+ $output .= '</a></p>';
267
+
268
+ }
269
+
270
+ return $output;
271
+
272
+ }
273
+
274
+ } // class
275
+
276
+ } // class exists
loggers/SimplePostLogger.php CHANGED
@@ -302,11 +302,33 @@ class SimplePostLogger extends SimpleLogger
302
 
303
  /**
304
  * Fired when a post has changed status
 
 
 
305
  */
306
- function on_transition_post_status($new_status, $old_status, $post) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
  // Don't log revisions
309
  if ( wp_is_post_revision( $post ) ) {
 
 
 
 
310
  return;
311
  }
312
 
302
 
303
  /**
304
  * Fired when a post has changed status
305
+ * Only run in certain cases,
306
+ * because when always enabled it catches a lots of edits made by plugins during cron jobs etc,
307
+ * which by definition is not wrong, but perhaps not wanted/annoying
308
  */
309
+ function on_transition_post_status( $new_status, $old_status, $post ) {
310
+
311
+ $ok_to_log = true;
312
+
313
+ // calls from the WordPress ios app/jetpack comes from non-admin-area
314
+ // i.e. is_admin() is false
315
+ // so don't log when outside admin area
316
+ if ( ! is_admin() ) {
317
+ $ok_to_log = false;
318
+ }
319
+
320
+ // except when calls are from/for jetpack/wordpress apps
321
+ // seems to be jetpack/app request when $_GET["for"] == "jetpack
322
+ if ( defined("XMLRPC_REQUEST") && XMLRPC_REQUEST && isset( $_GET["for"] ) && $_GET["for"] === "jetpack" ) {
323
+ $ok_to_log = true;
324
+ }
325
 
326
  // Don't log revisions
327
  if ( wp_is_post_revision( $post ) ) {
328
+ $ok_to_log = false;
329
+ }
330
+
331
+ if ( ! $ok_to_log ) {
332
  return;
333
  }
334
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: eskapism
3
  Donate link: http://eskapism.se/sida/donate/
4
  Tags: history, log, changes, changelog, audit, trail, pages, attachments, users, dashboard, admin, syslog, feed, activity, stream, audit trail, brute-force
5
  Requires at least: 4.5.1
6
- Tested up to: 4.5.3
7
- Stable tag: 2.9.1
8
 
9
  View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
10
 
@@ -153,6 +153,12 @@ A simple way to see any uncommon activity, for example an increased number of lo
153
 
154
  ## Changelog
155
 
 
 
 
 
 
 
156
  = 2.9.1 (August 2016) =
157
 
158
  - Fixed an issue where the logged time was off by some hours, due to timezone being manually set elsewhere.
3
  Donate link: http://eskapism.se/sida/donate/
4
  Tags: history, log, changes, changelog, audit, trail, pages, attachments, users, dashboard, admin, syslog, feed, activity, stream, audit trail, brute-force
5
  Requires at least: 4.5.1
6
+ Tested up to: 4.6
7
+ Stable tag: 2.10
8
 
9
  View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
10
 
153
 
154
  ## Changelog
155
 
156
+ = 2.10 (September 2016) =
157
+
158
+ - Available updates to plugins, themes, and WordPress itself is now logged.
159
+ Pretty great if you subscribe to the RSS feed to get the changes on a site. No need to manually check the updates-page to see if there are any updates.
160
+ - Changed to logic used to determine if a post edit should be logged or not. Version 2.9 used a version that started to log a bit to much for some plugins. This should fix the problems with the Nextgen Gallery, All-In-One Events Calendar, and Membership 2 plugins. If you still have problems with a plugin that is causing to many events to be logged, please let me know!
161
+
162
  = 2.9.1 (August 2016) =
163
 
164
  - Fixed an issue where the logged time was off by some hours, due to timezone being manually set elsewhere.