Simple History - Version 2.9

Version Description

(August 2016) =

  • Added custom date ranges to the dates filter. Just select "Custom date range..." in the dates dropdown and you can choose to se the log between any two exact dates.
  • The values in the statistics graph can now be clicked and when clicked the log is filtered to only show logged events from that day. Very convenient if you have a larger number of events logged for one day and quickly want to find out what exactly was logged that day.
  • Dates filter no longer accepts multi values. It was indeed a bit confusing that you could select both "Last 7 days" and "Last 3 days".
  • Fix for empty previous plugin version (the {plugin_prev_version} placeholder) when updating plugins.
  • Post and pages updates done in the WordPress apps for Ios and Android should be logged again.
Download this release

Release Info

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

Code changes from version 2.8 to 2.9

dropins/SimpleHistoryFilterDropin.css CHANGED
@@ -63,7 +63,7 @@
63
 
64
  /* set height on date input or it will "jump" during page load */
65
  .wp-admin select[multiple].SimpleHistory__filters__filter--date {
66
- height: 2.2em;
67
  overflow: hidden;
68
  }
69
 
@@ -134,3 +134,36 @@
134
  margin-left: 13px;
135
  margin-right: 13px;
136
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
  /* set height on date input or it will "jump" during page load */
65
  .wp-admin select[multiple].SimpleHistory__filters__filter--date {
66
+ height: 2.25em;
67
  overflow: hidden;
68
  }
69
 
134
  margin-left: 13px;
135
  margin-right: 13px;
136
  }
137
+
138
+
139
+ /* day filter */
140
+ /* hidden by default, shown by js when selecting "custom range" in dates picker */
141
+ .SimpleHistory__filters__filter--dayValuesWrap {
142
+ display: block;
143
+ visibility: hidden;
144
+ opacity: 0;
145
+ margin-left: 155px;
146
+ margin-top: 1em;
147
+ max-height: 0;
148
+ overflow: hidden;
149
+ transition: max-height .25s ease-in-out, opacity .25s ease-in-out, visibility 0s 1s;
150
+ }
151
+
152
+ .is-customDateFilterActive .SimpleHistory__filters__filter--dayValuesWrap {
153
+ visibility: visible;
154
+ opacity: 1;
155
+ max-height: 150px;
156
+ transition: max-height .25s ease-in-out, opacity .25s ease-in-out, visibility 0s 0s;
157
+ }
158
+
159
+ .postbox .SimpleHistory__filters__filter--dayValuesWrap {
160
+ margin-left: 0;
161
+ }
162
+
163
+ .SimpleHistory__filters__filter--day {
164
+ display: block;
165
+ }
166
+
167
+ .SimpleHistory__filters__filter--day select {
168
+ width: 200px;
169
+ }
dropins/SimpleHistoryFilterDropin.js CHANGED
@@ -14,7 +14,7 @@ var SimpleHistoryFilterDropin = (function($) {
14
  addFetchListener();
15
 
16
  }
17
-
18
  function onDomReadyInit() {
19
 
20
  enhanceSelects();
@@ -41,7 +41,7 @@ var SimpleHistoryFilterDropin = (function($) {
41
  }
42
 
43
  function onClickMoreFilters() {
44
-
45
  //$elms.more_filters_container.toggleClass("is-visible");
46
  $elms.filter_container.toggleClass("is-showingMoreFilters");
47
 
@@ -57,6 +57,14 @@ var SimpleHistoryFilterDropin = (function($) {
57
  var $users = $elms.filter_form.find("[name='users']");
58
  var $dates = $elms.filter_form.find("[name='dates']");
59
 
 
 
 
 
 
 
 
 
60
  // If any of our search boxes are filled in we consider ourself to be in search mode
61
  isFilteringActive = false;
62
  activeFilters = {};
@@ -81,16 +89,26 @@ var SimpleHistoryFilterDropin = (function($) {
81
  activeFilters.users = $users.val();
82
  }
83
 
 
84
  if ( $dates.val() && $dates.val().length ) {
 
85
  isFilteringActive = true;
86
- activeFilters.dates = $dates.val();
 
 
 
 
 
 
 
 
87
  }
88
  }
89
 
90
  function onSubmitForm(e) {
91
 
92
  e.preventDefault();
93
-
94
  // updateFilters();
95
 
96
  // Reload the log rows collection
@@ -166,7 +184,7 @@ var SimpleHistoryFilterDropin = (function($) {
166
  var $elm = $(elm);
167
  var value = $elm.val();
168
  var default_user_data = $elms.filter_user.data("default-user-data");
169
-
170
  callback(default_user_data);
171
 
172
  },
@@ -180,9 +198,11 @@ var SimpleHistoryFilterDropin = (function($) {
180
  $(".SimpleHistory__filters__filter--logger").select2({
181
  });
182
 
183
- $(".SimpleHistory__filters__filter--date").select2({
 
184
  //width: "element"
185
  });
 
186
 
187
  $(".SimpleHistory__filters__filter--loglevel").select2({
188
  formatResult: formatLoglevel,
@@ -190,6 +210,27 @@ var SimpleHistoryFilterDropin = (function($) {
190
  escapeMarkup: function(m) { return m; }
191
  });
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  }
194
 
195
  function formatUsers(userdata) {
@@ -205,7 +246,7 @@ var SimpleHistoryFilterDropin = (function($) {
205
  html += "<div class='SimpleHistory__filters__userfilter__secondary'>";
206
  html += userdata.user_login;
207
  html += "</div>";
208
-
209
  return html;
210
 
211
  }
@@ -223,7 +264,8 @@ var SimpleHistoryFilterDropin = (function($) {
223
 
224
  return {
225
  init: init,
226
- onDomReadyInit: onDomReadyInit
 
227
  };
228
 
229
  })(jQuery);
14
  addFetchListener();
15
 
16
  }
17
+
18
  function onDomReadyInit() {
19
 
20
  enhanceSelects();
41
  }
42
 
43
  function onClickMoreFilters() {
44
+
45
  //$elms.more_filters_container.toggleClass("is-visible");
46
  $elms.filter_container.toggleClass("is-showingMoreFilters");
47
 
57
  var $users = $elms.filter_form.find("[name='users']");
58
  var $dates = $elms.filter_form.find("[name='dates']");
59
 
60
+ // Custom date range
61
+ var $customDateRangeFromMM = $elms.filter_form.find("[name='from_mm']");
62
+ var $customDateRangeFromJJ = $elms.filter_form.find("[name='from_jj']");
63
+ var $customDateRangeFromAA = $elms.filter_form.find("[name='from_aa']");
64
+ var $customDateRangeToMM = $elms.filter_form.find("[name='to_mm']");
65
+ var $customDateRangeToJJ = $elms.filter_form.find("[name='to_jj']");
66
+ var $customDateRangeToAA = $elms.filter_form.find("[name='to_aa']");
67
+
68
  // If any of our search boxes are filled in we consider ourself to be in search mode
69
  isFilteringActive = false;
70
  activeFilters = {};
89
  activeFilters.users = $users.val();
90
  }
91
 
92
+ // Something is selected in the Dates dropdown
93
  if ( $dates.val() && $dates.val().length ) {
94
+
95
  isFilteringActive = true;
96
+
97
+ // if dates val is selected but is "customRange" then dates is not active, but dateRange is
98
+ if ("customRange" == $dates.val()) {
99
+ activeFilters.date_from = $customDateRangeFromAA.val() + "-" + $customDateRangeFromMM.val() + "-" + $customDateRangeFromJJ.val() + " 00:00:00";
100
+ activeFilters.date_to = $customDateRangeToAA.val() + "-" + $customDateRangeToMM.val() + "-" + $customDateRangeToJJ.val() + " 23:59:59";
101
+ } else {
102
+ activeFilters.dates = $dates.val();
103
+ }
104
+
105
  }
106
  }
107
 
108
  function onSubmitForm(e) {
109
 
110
  e.preventDefault();
111
+
112
  // updateFilters();
113
 
114
  // Reload the log rows collection
184
  var $elm = $(elm);
185
  var value = $elm.val();
186
  var default_user_data = $elms.filter_user.data("default-user-data");
187
+
188
  callback(default_user_data);
189
 
190
  },
198
  $(".SimpleHistory__filters__filter--logger").select2({
199
  });
200
 
201
+ var $filterDate = $(".SimpleHistory__filters__filter--date");
202
+ $filterDate.select2({
203
  //width: "element"
204
  });
205
+ $filterDate.on("select2-selecting change", onDatesFilterSelect);
206
 
207
  $(".SimpleHistory__filters__filter--loglevel").select2({
208
  formatResult: formatLoglevel,
210
  escapeMarkup: function(m) { return m; }
211
  });
212
 
213
+ }
214
+
215
+ /**
216
+ * Fired when something is selected in the date filter
217
+ * When "Custom range..." is selected then we show the "from" .. "to" date fields
218
+ */
219
+ function onDatesFilterSelect(e, elm) {
220
+
221
+ var $filterDate = $("select.SimpleHistory__filters__filter--date");
222
+ var val = $filterDate.val();
223
+
224
+ if (val === "customRange") {
225
+ // show custom date fields
226
+ $elms.filter_container.addClass("is-customDateFilterActive");
227
+ } else {
228
+ // hide custom date fields
229
+ $elms.filter_container.removeClass("is-customDateFilterActive");
230
+ }
231
+
232
+
233
+
234
  }
235
 
236
  function formatUsers(userdata) {
246
  html += "<div class='SimpleHistory__filters__userfilter__secondary'>";
247
  html += userdata.user_login;
248
  html += "</div>";
249
+
250
  return html;
251
 
252
  }
264
 
265
  return {
266
  init: init,
267
+ onDomReadyInit: onDomReadyInit,
268
+ $elms: $elms
269
  };
270
 
271
  })(jQuery);
dropins/SimpleHistoryFilterDropin.php CHANGED
@@ -169,9 +169,20 @@ class SimpleHistoryFilterDropin {
169
 
170
  <select class="SimpleHistory__filters__filter SimpleHistory__filters__filter--date"
171
  name="dates"
172
- placeholder="<?php echo _e("All dates", "simple-history") ?>" multiple>
 
 
173
  <?php
174
 
 
 
 
 
 
 
 
 
 
175
  // One day+ Last week + two weeks back + 30 days back
176
 
177
  printf(
@@ -220,9 +231,20 @@ class SimpleHistoryFilterDropin {
220
  );
221
 
222
  }
 
223
  ?>
224
  </select>
225
 
 
 
 
 
 
 
 
 
 
 
226
  </p><!-- end months -->
227
 
228
  <?php
@@ -406,6 +428,7 @@ class SimpleHistoryFilterDropin {
406
  </p>
407
  <?php
408
  }
 
409
  ?>
410
 
411
  <p class="SimpleHistory__filters__filterSubmitWrap">
@@ -540,4 +563,69 @@ class SimpleHistoryFilterDropin {
540
 
541
  }
542
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  } // end class
169
 
170
  <select class="SimpleHistory__filters__filter SimpleHistory__filters__filter--date"
171
  name="dates"
172
+ placeholder="<?php echo _e("All dates", "simple-history") ?>"
173
+ NOTmultiple
174
+ >
175
  <?php
176
 
177
+ // custom date range
178
+ // since 2.8.1
179
+ printf(
180
+ '<option value="%1$s" %3$s>%2$s</option>',
181
+ "customRange", // 1 - value
182
+ _x("Custom date range...", "Filter dropin: filter custom range", "simple-history"), // 2 text
183
+ selected( $daysToShow, "customRange", 0 )
184
+ );
185
+
186
  // One day+ Last week + two weeks back + 30 days back
187
 
188
  printf(
231
  );
232
 
233
  }
234
+
235
  ?>
236
  </select>
237
 
238
+ <!-- <p> -->
239
+ <!-- <label class="SimpleHistory__filters__filterLabel"><?php _ex("Between dates:", "Filter label", "simple-history") ?></label> -->
240
+ <span class="SimpleHistory__filters__filter--dayValuesWrap">
241
+ <?php
242
+ $this->touch_time("from");
243
+ $this->touch_time("to");
244
+ ?>
245
+ </span>
246
+ <!-- </p> -->
247
+
248
  </p><!-- end months -->
249
 
250
  <?php
428
  </p>
429
  <?php
430
  }
431
+
432
  ?>
433
 
434
  <p class="SimpleHistory__filters__filterSubmitWrap">
563
 
564
  }
565
 
566
+
567
+ /**
568
+ * Print out HTML form date elements for editing post or comment publish date.
569
+ *
570
+ * Based on the wordpress function touch_time();
571
+ *
572
+ * @global WP_Locale $wp_locale
573
+ *
574
+ * @param int|bool $edit Accepts 1|true for editing the date, 0|false for adding the date.
575
+ * @param int|bool $for_post Accepts 1|true for applying the date to a post, 0|false for a comment.
576
+ * @param int $tab_index The tabindex attribute to add. Default 0.
577
+ * @param int|bool $multi Optional. Whether the additional fields and buttons should be added.
578
+ * Default 0|false.
579
+ */
580
+ function touch_time( $from_or_to, $edit = 1 ) {
581
+
582
+ global $wp_locale;
583
+
584
+ // Prefix = text before the inputs
585
+ $prefix = "";
586
+ $input_prefix = "";
587
+ if ( "from" == $from_or_to ) {
588
+ $prefix = _x("From", "Filter dropin, custom date range", "simple-history");
589
+ $input_prefix = "from_";
590
+ } else if ( "to" == $from_or_to ) {
591
+ $prefix = _x("To", "Filter dropin, custom date range", "simple-history");
592
+ $input_prefix = "to_";
593
+ }
594
+
595
+ // The default date to show in the inputs
596
+ $date = date("Y-m-d");
597
+
598
+ $jj = mysql2date( 'd', $date, false );
599
+ $mm = mysql2date( 'm', $date, false );
600
+ $aa = mysql2date( 'Y', $date, false );
601
+
602
+ $month = "<select name='{$input_prefix}mm'>";
603
+
604
+ for ( $i = 1; $i < 13; $i = $i +1 ) {
605
+ $monthnum = zeroise($i, 2);
606
+ $monthtext = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) );
607
+ $month .= "\t\t\t" . '<option value="' . $monthnum . '" data-text="' . $monthtext . '" ' . selected( $monthnum, $mm, false ) . '>';
608
+ /* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
609
+ $month .= sprintf( __( '%1$s-%2$s' ), $monthnum, $monthtext ) . "</option>\n";
610
+ }
611
+ $month .= '</select>';
612
+ $month .= '</label>';
613
+
614
+ $day = '<label><span class="screen-reader-text">' . __( 'Day' ) . '</span><input type="text" name="'.$input_prefix.'jj" value="' . $jj . '" size="2" maxlength="2" autocomplete="off" /></label>';
615
+ $year = '<label><span class="screen-reader-text">' . __( 'Year' ) . '</span><input type="text" name="'.$input_prefix.'aa" value="' . $aa . '" size="4" maxlength="4" autocomplete="off" /></label>';
616
+
617
+ echo '<span class="SimpleHistory__filters__filter SimpleHistory__filters__filter--day">';
618
+
619
+ echo $prefix . "<br>";
620
+
621
+ /* translators: 1: month, 2: day, 3: year, 4: hour, 5: minute */
622
+ printf( __( '%1$s %2$s, %3$s ' ), $month, $day, $year );
623
+
624
+ echo '</span>';
625
+
626
+ ?>
627
+
628
+ <?php
629
+ } // func
630
+
631
  } // end class
dropins/SimpleHistorySidebarStats.php CHANGED
@@ -13,7 +13,7 @@ class SimpleHistorySidebarStats {
13
  private $sh;
14
 
15
  function __construct( $sh ) {
16
-
17
  $this->init( $sh );
18
 
19
  }
@@ -40,6 +40,7 @@ class SimpleHistorySidebarStats {
40
 
41
  ?>
42
  <script>
 
43
  /**
44
  * JavaScript for SimpleHistory_SidebarChart
45
  */
@@ -48,12 +49,13 @@ class SimpleHistorySidebarStats {
48
  $(function() {
49
 
50
  var ctx = $(".SimpleHistory_SidebarChart_ChartCanvas");
51
-
52
  if ( ! ctx.length ) {
53
  return;
54
  }
55
 
56
  var chartLabels = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabels").val() );
 
57
  var chartDatasetData = JSON.parse( $(".SimpleHistory_SidebarChart_ChartDatasetData").val() );
58
 
59
  var myChart = new Chart(ctx, {
@@ -79,17 +81,61 @@ class SimpleHistorySidebarStats {
79
  xAxes: [{
80
  display: false
81
  }]
82
- }
83
- }
84
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  });
87
 
88
  })(jQuery);
89
 
90
-
91
  </script>
92
-
93
  <?php
94
 
95
  }
@@ -107,15 +153,15 @@ class SimpleHistorySidebarStats {
107
  $period = new DatePeriod($period_start_date, $interval, $period_end_date->add( date_interval_create_from_date_string('1 days') ) );
108
 
109
  ?>
110
-
111
  <div class="postbox">
112
 
113
  <h3 class="hndle"><?php _e("Stats", "simple-history") ?></h3>
114
 
115
  <div class="inside">
116
-
117
  <p>
118
- <?php
119
 
120
  printf(
121
  __('<b>%1$s events</b> have been logged the last <b>%2$s days</b>.', "simple-history"),
@@ -125,7 +171,7 @@ class SimpleHistorySidebarStats {
125
 
126
  ?>
127
  </p>
128
-
129
  <!-- wrapper div so sidebar does not "jump" when loading. so annoying. -->
130
  <div style="position: relative; height: 0; overflow: hidden; padding-bottom: 40%;">
131
  <canvas style="position: absolute; left: 0; right: 0;" class="SimpleHistory_SidebarChart_ChartCanvas" width="100" height="40"></canvas>
@@ -138,12 +184,14 @@ class SimpleHistorySidebarStats {
138
  <?php
139
 
140
  $arr_labels = array();
 
141
  $arr_dataset_data = array();
142
 
143
  foreach ( $period as $dt ) {
144
-
145
  $datef = _x( 'M j', "stats: date in rows per day chart", "simple-history" );
146
  $str_date = date_i18n( $datef, $dt->getTimestamp() );
 
147
 
148
  // Get data for this day, if exist
149
  // Day in object is in format '2014-09-07'
@@ -152,6 +200,11 @@ class SimpleHistorySidebarStats {
152
 
153
  $arr_labels[] = $str_date;
154
 
 
 
 
 
 
155
  if ( $day_data ) {
156
 
157
  $day_data = reset( $day_data );
@@ -165,12 +218,27 @@ class SimpleHistorySidebarStats {
165
 
166
  ?>
167
 
168
- <input type="hidden" class="SimpleHistory_SidebarChart_ChartLabels" value="<?php esc_attr_e( json_encode( $arr_labels ) ) ?>">
169
- <input type="hidden" class="SimpleHistory_SidebarChart_ChartDatasetData" value="<?php esc_attr_e( json_encode( $arr_dataset_data ) ) ?>">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  </div>
172
  </div>
173
-
174
  <?php
175
 
176
  }
13
  private $sh;
14
 
15
  function __construct( $sh ) {
16
+
17
  $this->init( $sh );
18
 
19
  }
40
 
41
  ?>
42
  <script>
43
+
44
  /**
45
  * JavaScript for SimpleHistory_SidebarChart
46
  */
49
  $(function() {
50
 
51
  var ctx = $(".SimpleHistory_SidebarChart_ChartCanvas");
52
+
53
  if ( ! ctx.length ) {
54
  return;
55
  }
56
 
57
  var chartLabels = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabels").val() );
58
+ var chartLabelsToDates = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabelsToDates").val() );
59
  var chartDatasetData = JSON.parse( $(".SimpleHistory_SidebarChart_ChartDatasetData").val() );
60
 
61
  var myChart = new Chart(ctx, {
81
  xAxes: [{
82
  display: false
83
  }]
84
+ },
85
+ onClick: clickChart
86
+ },
87
+ });
88
+
89
+
90
+ // when chart is clicked determine what value/day was clicked
91
+ function clickChart(e) {
92
+
93
+ var chartElmClicked = this.getElementAtEvent(e)[0];
94
+
95
+ if (!chartElmClicked || !chartElmClicked._index) {
96
+ console.log("No value found for click");
97
+ return;
98
+ }
99
+
100
+ var label = this.data.labels[chartElmClicked._index];
101
+ // var value = this.data.datasets[chartElmClicked._datasetIndex].data[chartElmClicked._index];
102
+
103
+ // now we have the label which is like "July 23" or "23 juli" depending on language
104
+ // look for that label value in chartLabelsToDates and there we get the date in format Y-m-d
105
+ //console.log("chartLabelsToDates", chartLabelsToDates);
106
+ var labelDate;
107
+ for (idx in chartLabelsToDates) {
108
+ if (label == chartLabelsToDates[idx].label) {
109
+ //console.log(chartLabelsToDates[idx]);
110
+ labelDate = chartLabelsToDates[idx];
111
+ }
112
+ }
113
+
114
+ if (!labelDate) {
115
+ return;
116
+ }
117
+
118
+ // got a date, now reload the history/post search filter form again
119
+ var labelDateParts = labelDate.date.split("-"); ["2016", "07", "18"]
120
+
121
+ // show custom date range
122
+ $(".SimpleHistory__filters__filter--date").val("customRange").trigger("change");
123
+
124
+ // set values, same for both from and to because we only want to show one day
125
+ SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_aa'], [name='to_aa']").val(labelDateParts[0]);
126
+ SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_jj'], [name='to_jj']").val(labelDateParts[2]);
127
+ SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_mm'], [name='to_mm']").val(labelDateParts[1]);
128
+
129
+ SimpleHistoryFilterDropin.$elms.filter_form.trigger("submit");
130
+
131
+ }
132
 
133
  });
134
 
135
  })(jQuery);
136
 
 
137
  </script>
138
+
139
  <?php
140
 
141
  }
153
  $period = new DatePeriod($period_start_date, $interval, $period_end_date->add( date_interval_create_from_date_string('1 days') ) );
154
 
155
  ?>
156
+
157
  <div class="postbox">
158
 
159
  <h3 class="hndle"><?php _e("Stats", "simple-history") ?></h3>
160
 
161
  <div class="inside">
162
+
163
  <p>
164
+ <?php
165
 
166
  printf(
167
  __('<b>%1$s events</b> have been logged the last <b>%2$s days</b>.', "simple-history"),
171
 
172
  ?>
173
  </p>
174
+
175
  <!-- wrapper div so sidebar does not "jump" when loading. so annoying. -->
176
  <div style="position: relative; height: 0; overflow: hidden; padding-bottom: 40%;">
177
  <canvas style="position: absolute; left: 0; right: 0;" class="SimpleHistory_SidebarChart_ChartCanvas" width="100" height="40"></canvas>
184
  <?php
185
 
186
  $arr_labels = array();
187
+ $arr_labels_to_datetime = array();
188
  $arr_dataset_data = array();
189
 
190
  foreach ( $period as $dt ) {
191
+
192
  $datef = _x( 'M j', "stats: date in rows per day chart", "simple-history" );
193
  $str_date = date_i18n( $datef, $dt->getTimestamp() );
194
+ $str_date_ymd = date("Y-m-d", $dt->getTimestamp() );
195
 
196
  // Get data for this day, if exist
197
  // Day in object is in format '2014-09-07'
200
 
201
  $arr_labels[] = $str_date;
202
 
203
+ $arr_labels_to_datetime[] = array(
204
+ "label" => $str_date,
205
+ "date" => $str_date_ymd
206
+ );
207
+
208
  if ( $day_data ) {
209
 
210
  $day_data = reset( $day_data );
218
 
219
  ?>
220
 
221
+ <input
222
+ type="hidden"
223
+ class="SimpleHistory_SidebarChart_ChartLabels"
224
+ value="<?php esc_attr_e( json_encode( $arr_labels ) ) ?>"
225
+ />
226
+
227
+ <input
228
+ type="hidden"
229
+ class="SimpleHistory_SidebarChart_ChartLabelsToDates"
230
+ value="<?php esc_attr_e( json_encode( $arr_labels_to_datetime ) ) ?>"
231
+ />
232
+
233
+ <input
234
+ type="hidden"
235
+ class="SimpleHistory_SidebarChart_ChartDatasetData"
236
+ value="<?php esc_attr_e( json_encode( $arr_dataset_data ) ) ?>"
237
+ />
238
 
239
  </div>
240
  </div>
241
+
242
  <?php
243
 
244
  }
inc/SimpleHistoryLogQuery.php CHANGED
@@ -54,7 +54,7 @@ class SimpleHistoryLogQuery {
54
  // array or comma separated
55
  "months" => null,
56
 
57
- // dates in format
58
  // "month:2015-06" for june 2015
59
  // "lastdays:7" for the last 7 days
60
  "dates" => null,
@@ -149,7 +149,7 @@ class SimpleHistoryLogQuery {
149
 
150
  FROM %3$s AS h
151
 
152
- LEFT OUTER JOIN %5$s AS c1 ON (c1.history_id = h.id AND c1.key = "_message_key")
153
 
154
  INNER JOIN (
155
  SELECT
@@ -160,9 +160,9 @@ class SimpleHistoryLogQuery {
160
  FROM %3$s AS h2
161
 
162
  # First/inner where
163
- WHERE
164
  %4$s
165
-
166
  ORDER BY id DESC, date DESC
167
  ) AS t ON t.id = h.id
168
 
@@ -268,11 +268,11 @@ class SimpleHistoryLogQuery {
268
  );
269
 
270
  }
271
-
272
  // Append date where
273
  if ( ! empty( $args["date_from"] ) ) {
274
 
275
- // date_to=2014-08-01
276
  // if date is not numeric assume Y-m-d H:i-format
277
  $date_from = $args["date_from"];
278
  if ( ! is_numeric( $date_from ) ) {
@@ -296,6 +296,11 @@ class SimpleHistoryLogQuery {
296
 
297
  }
298
 
 
 
 
 
 
299
  // dats
300
  // if months they translate to $args["months"] because we already have support for that
301
  // can't use months and dates and the same time
@@ -311,7 +316,7 @@ class SimpleHistoryLogQuery {
311
  $args["lastdays"] = 0;
312
 
313
  foreach ( $arr_dates as $one_date ) {
314
-
315
  // If begins with "month:" then strip string and keep only month numbers
316
  if ( strpos($one_date, "month:") === 0 ) {
317
  $args["months"][] = substr($one_date, strlen("month:"));
@@ -333,7 +338,7 @@ class SimpleHistoryLogQuery {
333
  # lastdays
334
  AND date >= DATE(NOW()) - INTERVAL %d DAY
335
  ', $args["lastdays"]);
336
-
337
  }
338
 
339
  // months, in format "Y-m"
@@ -654,9 +659,9 @@ class SimpleHistoryLogQuery {
654
 
655
  $users = explode(",", $args["users"]);
656
  $users = array_map("intval", $users);
657
-
658
  if ( $users ) {
659
-
660
  $users_in = implode(",", $users);
661
 
662
  $sql_user = sprintf(
54
  // array or comma separated
55
  "months" => null,
56
 
57
+ // dates in format
58
  // "month:2015-06" for june 2015
59
  // "lastdays:7" for the last 7 days
60
  "dates" => null,
149
 
150
  FROM %3$s AS h
151
 
152
+ LEFT OUTER JOIN %5$s AS c1 ON (c1.history_id = h.id AND c1.key = "_message_key")
153
 
154
  INNER JOIN (
155
  SELECT
160
  FROM %3$s AS h2
161
 
162
  # First/inner where
163
+ WHERE
164
  %4$s
165
+
166
  ORDER BY id DESC, date DESC
167
  ) AS t ON t.id = h.id
168
 
268
  );
269
 
270
  }
271
+
272
  // Append date where
273
  if ( ! empty( $args["date_from"] ) ) {
274
 
275
+ // date_from=2014-08-01
276
  // if date is not numeric assume Y-m-d H:i-format
277
  $date_from = $args["date_from"];
278
  if ( ! is_numeric( $date_from ) ) {
296
 
297
  }
298
 
299
+ /*
300
+ AND date >= "2015-01-01 00:00:00" AND date <= "2015-01-31 00:00:00"
301
+ */
302
+ #echo $inner_where;exit;
303
+
304
  // dats
305
  // if months they translate to $args["months"] because we already have support for that
306
  // can't use months and dates and the same time
316
  $args["lastdays"] = 0;
317
 
318
  foreach ( $arr_dates as $one_date ) {
319
+
320
  // If begins with "month:" then strip string and keep only month numbers
321
  if ( strpos($one_date, "month:") === 0 ) {
322
  $args["months"][] = substr($one_date, strlen("month:"));
338
  # lastdays
339
  AND date >= DATE(NOW()) - INTERVAL %d DAY
340
  ', $args["lastdays"]);
341
+
342
  }
343
 
344
  // months, in format "Y-m"
659
 
660
  $users = explode(",", $args["users"]);
661
  $users = array_map("intval", $users);
662
+
663
  if ( $users ) {
664
+
665
  $users_in = implode(",", $users);
666
 
667
  $sql_user = sprintf(
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.8
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.8' );
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.9
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.9' );
46
  }
47
 
48
  if ( ! defined( 'SIMPLE_HISTORY_PATH' ) ) {
loggers/SimplePluginLogger.php CHANGED
@@ -5,8 +5,7 @@ defined( 'ABSPATH' ) or die();
5
  /**
6
  * Logs plugin installs, updates, and deletions
7
  */
8
- class SimplePluginLogger extends SimpleLogger
9
- {
10
 
11
  // The logger slug. Defaulting to the class name is nice and logical I think
12
  public $slug = __CLASS__;
@@ -129,12 +128,6 @@ class SimplePluginLogger extends SimpleLogger
129
 
130
  public function loaded() {
131
 
132
- #sf_d(get_plugins(), 'get_plugins()');
133
-
134
- //do_action( 'current_screen', $current_screen );
135
- // The first hook where current screen is available
136
- //add_action( 'current_screen', array( $this, "save_versions_before_update" ) );
137
-
138
  /**
139
  * At least the plugin bulk upgrades fires this action before upgrade
140
  * We use it to fetch the current version of all plugins, before they are upgraded
@@ -142,7 +135,8 @@ class SimplePluginLogger extends SimpleLogger
142
  add_filter( 'upgrader_pre_install', array( $this, "save_versions_before_update"), 10, 2);
143
 
144
  // Clear our transient after an update is done
145
- add_action( 'delete_site_transient_update_plugins', array( $this, "remove_saved_versions" ) );
 
146
 
147
  // Fires after a plugin has been activated.
148
  // If a plugin is silently activated (such as during an update),
@@ -169,7 +163,7 @@ class SimplePluginLogger extends SimpleLogger
169
  // Ajax function to get info from GitHub repo. Used by "View plugin info"-link for plugin installs
170
  add_action("wp_ajax_SimplePluginLogger_GetGitHubPluginInfo", array($this, "ajax_GetGitHubPluginInfo"));
171
 
172
- // If the Github Update plugin is not installed we will not get extra fields used by it.
173
  // So need to hook filter "extra_plugin_headers" ourself.
174
  add_filter( "extra_plugin_headers", function($arr_headers) {
175
  $arr_headers[] = "GitHub Plugin URI";
@@ -183,7 +177,6 @@ class SimplePluginLogger extends SimpleLogger
183
  }
184
 
185
  /**
186
- *
187
  * There is no way to ue a filter and detect a plugin that is disabled because it can't be found or similar error.
188
  * we hook into gettext and look for the usage of the error that is returned when this happens.
189
  */
@@ -194,9 +187,9 @@ class SimplePluginLogger extends SimpleLogger
194
  // return new WP_Error('plugin_not_found', __('Plugin file does not exist.'));
195
  // return new WP_Error('no_plugin_header', __('The plugin does not have a valid header.'));
196
 
197
- // We only act on page plugins.php
198
  global $pagenow;
199
 
 
200
  if ( ! isset( $pagenow ) || $pagenow !== "plugins.php" ) {
201
  return $translation;
202
  }
@@ -225,7 +218,7 @@ class SimplePluginLogger extends SimpleLogger
225
 
226
  return $translation;
227
 
228
- } //on_gettext
229
 
230
 
231
  /**
@@ -359,7 +352,10 @@ class SimplePluginLogger extends SimpleLogger
359
 
360
  $plugins = get_plugins();
361
 
362
- update_option( $this->slug . "_plugin_info_before_update", SimpleHistory::json_encode( $plugins ) );
 
 
 
363
 
364
  return $bool;
365
 
@@ -549,13 +545,12 @@ class SimplePluginLogger extends SimpleLogger
549
  * be a Theme_Upgrader or Core_Upgrade instance.
550
  * @param array $data {
551
  * Array of bulk item update data.
552
-
553
  */
554
  function on_upgrader_process_complete( $plugin_upgrader_instance, $arr_data ) {
555
 
556
  // Can't use get_plugins() here to get version of plugins updated from
557
  // Tested that, and it will get the new version (and that's the correct answer I guess. but too bad for us..)
558
- // $plugs = get_plugins();
559
 
560
  /*
561
  If an update fails then $plugin_upgrader_instance->skin->result->errors contains something like:
@@ -571,7 +566,9 @@ class SimplePluginLogger extends SimpleLogger
571
 
572
  /*
573
 
574
- # WordPress core update
 
 
575
 
576
  $arr_data:
577
  Array
@@ -591,7 +588,7 @@ class SimplePluginLogger extends SimpleLogger
591
  )
592
 
593
 
594
- # Plugin update
595
 
596
  $arr_data:
597
  Array
@@ -600,7 +597,7 @@ class SimplePluginLogger extends SimpleLogger
600
  [action] => install
601
  )
602
 
603
- # Bulk actions
604
 
605
  array(
606
  'action' => 'update',
@@ -934,114 +931,10 @@ class SimplePluginLogger extends SimpleLogger
934
  #exit;
935
  }
936
 
937
- }
938
-
939
- /*
940
- * Called from filter 'upgrader_post_install'.
941
- *
942
- * Used to log bulk plugin installs and updates
943
- *
944
- * Filter docs:
945
- *
946
- * Filter the install response after the installation has finished.
947
- *
948
- * @param bool $response Install response.
949
- * @param array $hook_extra Extra arguments passed to hooked filters.
950
- * @param array $result Installation result data.
951
- */
952
- public function on_upgrader_post_install( $response, $hook_extra, $result ) {
953
-
954
- #echo "on_upgrader_post_install";
955
- /*
956
-
957
- # Plugin update:
958
- $hook_extra
959
- Array
960
- (
961
- [plugin] => plugin-folder/plugin-name.php
962
- [type] => plugin
963
- [action] => update
964
- )
965
-
966
- # Plugin install, i.e. download/install, but not activation:
967
- $hook_extra:
968
- Array
969
- (
970
- [type] => plugin
971
- [action] => install
972
- )
973
-
974
- */
975
-
976
- if ( isset( $hook_extra["action"] ) && $hook_extra["action"] == "install" && isset( $hook_extra["type"] ) && $hook_extra["type"] == "plugin" ) {
977
-
978
- // It's a plugin install
979
- #error_log("plugin install");
980
-
981
-
982
- } else if ( isset( $hook_extra["action"] ) && $hook_extra["action"] == "update" && isset( $hook_extra["type"] ) && $hook_extra["type"] == "plugin" ) {
983
-
984
- // It's a plugin upgrade
985
- #echo "plugin update!";
986
- //error_log("plugin update");
987
-
988
- } else {
989
-
990
- //error_log("other");
991
-
992
- }
993
-
994
- #sf_d($response, '$response');
995
- #sf_d($hook_extra, '$hook_extra');
996
- #sf_d($result, '$result');
997
- #exit;
998
-
999
- return $response;
1000
-
1001
- }
1002
-
1003
- /*
1004
-
1005
- * Filter the list of action links available following bulk plugin updates.
1006
- *
1007
- * @since 3.0.0
1008
- *
1009
- * @param array $update_actions Array of plugin action links.
1010
- * @param array $plugin_info Array of information for the last-updated plugin.
1011
-
1012
- $update_actions = apply_filters( 'update_bulk_plugins_complete_actions', $update_actions, $this->plugin_info );
1013
-
1014
- */
1015
-
1016
- /*
1017
-
1018
-
1019
- *
1020
- * Fires when the bulk upgrader process is complete.
1021
- *
1022
- * @since 3.6.0
1023
- *
1024
- * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might
1025
- * be a Theme_Upgrader or Core_Upgrade instance.
1026
- * @param array $data {
1027
- * Array of bulk item update data.
1028
- *
1029
- * @type string $action Type of action. Default 'update'.
1030
- * @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'.
1031
- * @type bool $bulk Whether the update process is a bulk update. Default true.
1032
- * @type array $packages Array of plugin, theme, or core packages to update.
1033
- * }
1034
- *
1035
- do_action( 'upgrader_process_complete', $this, array(
1036
- 'action' => 'update',
1037
- 'type' => 'plugin',
1038
- 'bulk' => true,
1039
- 'plugins' => $plugins,
1040
- ) );
1041
 
 
1042
 
1043
- do_action( 'upgrader_process_complete', $this, array( 'action' => 'update', 'type' => 'core' ) );
1044
- */
1045
 
1046
  /**
1047
  * Plugin is activated
@@ -1082,7 +975,7 @@ class SimplePluginLogger extends SimpleLogger
1082
 
1083
  $this->infoMessage( 'plugin_activated', $context );
1084
 
1085
- }
1086
 
1087
  /**
1088
  * Plugin is deactivated
@@ -1109,7 +1002,7 @@ class SimplePluginLogger extends SimpleLogger
1109
 
1110
  $this->infoMessage( 'plugin_deactivated', $context );
1111
 
1112
- }
1113
 
1114
 
1115
  /**
@@ -1319,7 +1212,6 @@ class SimplePluginLogger extends SimpleLogger
1319
 
1320
  return $output;
1321
 
1322
- }
1323
-
1324
 
1325
- }
5
  /**
6
  * Logs plugin installs, updates, and deletions
7
  */
8
+ class SimplePluginLogger extends SimpleLogger {
 
9
 
10
  // The logger slug. Defaulting to the class name is nice and logical I think
11
  public $slug = __CLASS__;
128
 
129
  public function loaded() {
130
 
 
 
 
 
 
 
131
  /**
132
  * At least the plugin bulk upgrades fires this action before upgrade
133
  * We use it to fetch the current version of all plugins, before they are upgraded
135
  add_filter( 'upgrader_pre_install', array( $this, "save_versions_before_update"), 10, 2);
136
 
137
  // Clear our transient after an update is done
138
+ // Removed because something probably changed in core and this was fired earlier than it used to be
139
+ // add_action( 'delete_site_transient_update_plugins', array( $this, "remove_saved_versions" ) );
140
 
141
  // Fires after a plugin has been activated.
142
  // If a plugin is silently activated (such as during an update),
163
  // Ajax function to get info from GitHub repo. Used by "View plugin info"-link for plugin installs
164
  add_action("wp_ajax_SimplePluginLogger_GetGitHubPluginInfo", array($this, "ajax_GetGitHubPluginInfo"));
165
 
166
+ // If the Github Update plugin is not installed we need to get extra fields used by it.
167
  // So need to hook filter "extra_plugin_headers" ourself.
168
  add_filter( "extra_plugin_headers", function($arr_headers) {
169
  $arr_headers[] = "GitHub Plugin URI";
177
  }
178
 
179
  /**
 
180
  * There is no way to ue a filter and detect a plugin that is disabled because it can't be found or similar error.
181
  * we hook into gettext and look for the usage of the error that is returned when this happens.
182
  */
187
  // return new WP_Error('plugin_not_found', __('Plugin file does not exist.'));
188
  // return new WP_Error('no_plugin_header', __('The plugin does not have a valid header.'));
189
 
 
190
  global $pagenow;
191
 
192
+ // We only act on page plugins.php
193
  if ( ! isset( $pagenow ) || $pagenow !== "plugins.php" ) {
194
  return $translation;
195
  }
218
 
219
  return $translation;
220
 
221
+ } // on_gettext
222
 
223
 
224
  /**
352
 
353
  $plugins = get_plugins();
354
 
355
+ // does not work
356
+ $option_name = $this->slug . "_plugin_info_before_update";
357
+
358
+ $r = update_option( $option_name, SimpleHistory::json_encode( $plugins ) );
359
 
360
  return $bool;
361
 
545
  * be a Theme_Upgrader or Core_Upgrade instance.
546
  * @param array $data {
547
  * Array of bulk item update data.
548
+ *
549
  */
550
  function on_upgrader_process_complete( $plugin_upgrader_instance, $arr_data ) {
551
 
552
  // Can't use get_plugins() here to get version of plugins updated from
553
  // Tested that, and it will get the new version (and that's the correct answer I guess. but too bad for us..)
 
554
 
555
  /*
556
  If an update fails then $plugin_upgrader_instance->skin->result->errors contains something like:
566
 
567
  /*
568
 
569
+ # Contents of $arr_data in different scenarios
570
+
571
+ ## WordPress core update
572
 
573
  $arr_data:
574
  Array
588
  )
589
 
590
 
591
+ ## Plugin update
592
 
593
  $arr_data:
594
  Array
597
  [action] => install
598
  )
599
 
600
+ ## Bulk actions
601
 
602
  array(
603
  'action' => 'update',
931
  #exit;
932
  }
933
 
934
+ $this->remove_saved_versions();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
935
 
936
+ } // on upgrader_process_complete
937
 
 
 
938
 
939
  /**
940
  * Plugin is activated
975
 
976
  $this->infoMessage( 'plugin_activated', $context );
977
 
978
+ } // on_activated_plugin
979
 
980
  /**
981
  * Plugin is deactivated
1002
 
1003
  $this->infoMessage( 'plugin_deactivated', $context );
1004
 
1005
+ } // on_deactivated_plugin
1006
 
1007
 
1008
  /**
1212
 
1213
  return $output;
1214
 
1215
+ } // getLogRowDetailsOutput
 
1216
 
1217
+ } // class SimplePluginLogger
loggers/SimplePostLogger.php CHANGED
@@ -17,7 +17,10 @@ class SimplePostLogger extends SimpleLogger
17
 
18
  public function loaded() {
19
 
20
- add_action("admin_init", array($this, "on_admin_init"));
 
 
 
21
 
22
  $this->add_xml_rpc_hooks();
23
 
@@ -51,7 +54,7 @@ class SimplePostLogger extends SimpleLogger
51
  }
52
 
53
  function on_xmlrpc_call($method) {
54
-
55
  $arr_methods_to_act_on = array(
56
  "wp.deletePost"
57
  );
@@ -95,7 +98,7 @@ class SimplePostLogger extends SimpleLogger
95
  );
96
 
97
  $this->infoMessage( "post_trashed", $context );
98
-
99
 
100
  } // if delete post
101
 
@@ -152,16 +155,6 @@ class SimplePostLogger extends SimpleLogger
152
 
153
  }
154
 
155
- function on_admin_init() {
156
-
157
- add_action("admin_action_editpost", array($this, "on_admin_action_editpost"));
158
-
159
- add_action("transition_post_status", array($this, "on_transition_post_status"), 10, 3);
160
- add_action("delete_post", array($this, "on_delete_post"));
161
- add_action("untrash_post", array($this, "on_untrash_post"));
162
-
163
- }
164
-
165
  /**
166
  * Get and store old info about a post that is being edited.
167
  * Needed to later compare old data with new data, to detect differences.
@@ -172,7 +165,7 @@ class SimplePostLogger extends SimpleLogger
172
  * @since 2.0.29
173
  */
174
  function on_admin_action_editpost() {
175
-
176
  $post_ID = isset( $_POST["post_ID"] ) ? (int) $_POST["post_ID"] : 0;
177
 
178
  if ( ! $post_ID ) {
@@ -182,14 +175,14 @@ class SimplePostLogger extends SimpleLogger
182
  if ( ! current_user_can( 'edit_post', $post_ID ) ) {
183
  return;
184
  };
185
-
186
  $prev_post_data = get_post( $post_ID );
187
 
188
  $this->old_post_data[$post_ID] = array(
189
  "post_data" => $prev_post_data,
190
  "post_meta" => get_post_custom( $post_ID )
191
  );
192
-
193
  }
194
 
195
  /**
@@ -397,9 +390,9 @@ class SimplePostLogger extends SimpleLogger
397
 
398
  /*
399
  * Adds diff data to the context array. Is called just before the event is logged.
400
- *
401
  * Since 2.0.29
402
- *
403
  * To detect
404
  * - post thumb (part of custom fields)
405
  * - categories
@@ -407,7 +400,7 @@ class SimplePostLogger extends SimpleLogger
407
  * @return array $context with diff data added
408
  */
409
  function add_post_data_diff_to_context($context, $old_post_data, $new_post_data) {
410
-
411
  $old_data = $old_post_data["post_data"];
412
  $new_data = $new_post_data["post_data"];
413
 
@@ -439,30 +432,30 @@ class SimplePostLogger extends SimpleLogger
439
 
440
  // If changes where detected
441
  if ( $post_data_diff ) {
442
-
443
  // $context["_post_data_diff"] = $this->simpleHistory->json_encode( $post_data_diff );
444
  // Save at least 2 values for each detected value change, i.e. the old value and the new value
445
  foreach ( $post_data_diff as $diff_key => $diff_values ) {
446
-
447
  $context["post_prev_{$diff_key}"] = $diff_values["old"];
448
  $context["post_new_{$diff_key}"] = $diff_values["new"];
449
 
450
  // If post_author then get more author info
451
  // Because just a user ID does not get us far
452
  if ( "post_author" == $diff_key ) {
453
-
454
  $old_author_user = get_userdata( (int) $diff_values["old"] );
455
  $new_author_user = get_userdata( (int) $diff_values["new"] );
456
 
457
  if ( is_a( $old_author_user, "WP_User" ) && is_a( $new_author_user, "WP_User" ) ) {
458
-
459
  $context["post_prev_{$diff_key}/user_login"] = $old_author_user->user_login;
460
  $context["post_prev_{$diff_key}/user_email"] = $old_author_user->user_email;
461
  $context["post_prev_{$diff_key}/display_name"] = $old_author_user->display_name;
462
 
463
  $context["post_new_{$diff_key}/user_login"] = $new_author_user->user_login;
464
  $context["post_new_{$diff_key}/user_email"] = $new_author_user->user_email;
465
- $context["post_new_{$diff_key}/display_name"] = $new_author_user->display_name;
466
 
467
  }
468
 
@@ -478,9 +471,9 @@ class SimplePostLogger extends SimpleLogger
478
  [new] => 25556
479
  )
480
  */
481
-
482
 
483
-
 
484
  }
485
 
486
  } // post_data_diff
@@ -504,19 +497,19 @@ class SimplePostLogger extends SimpleLogger
504
 
505
  $old_meta = $old_post_data["post_meta"];
506
  $new_meta = $new_post_data["post_meta"];
507
-
508
  // @todo: post thumb is stored in _thumbnail_id
509
 
510
  // page template is stored in _wp_page_template
511
  if ( isset( $old_meta["_wp_page_template"][0] ) && isset( $new_meta["_wp_page_template"][0] ) ) {
512
-
513
  /*
514
  Var is string with length 7: default
515
  Var is string with length 20: template-builder.php
516
  */
517
 
518
  if ( $old_meta["_wp_page_template"][0] != $new_meta["_wp_page_template"][0] ) {
519
-
520
  // prev page template is different from new page template
521
 
522
  // store template php file name
@@ -536,13 +529,13 @@ class SimplePostLogger extends SimpleLogger
536
  if ( isset( $theme_templates[ $context["post_prev_page_template"] ] ) ) {
537
  $context["post_prev_page_template_name"] = $theme_templates[$context["post_prev_page_template"]];
538
  }
539
-
540
  if ( isset( $theme_templates[ $context["post_new_page_template"] ] ) ) {
541
  $context["post_new_page_template_name"] = $theme_templates[$context["post_new_page_template"]];
542
  }
543
 
544
  }
545
-
546
  }
547
 
548
  // Remove fields that we have checked already and other that should be ignored
@@ -550,10 +543,10 @@ class SimplePostLogger extends SimpleLogger
550
  unset( $old_meta[ $key_to_ignore ] );
551
  unset( $new_meta[ $key_to_ignore ] );
552
  }
553
-
554
  // Look for added custom fields
555
  foreach ( $new_meta as $meta_key => $meta_value ) {
556
-
557
  if ( ! isset( $old_meta[ $meta_key ] ) ) {
558
  $meta_changes["added"][ $meta_key ] = true;
559
  }
@@ -564,7 +557,7 @@ class SimplePostLogger extends SimpleLogger
564
  // Does not work, if user clicks "delete" in edit screen then meta is removed using ajax
565
  /*
566
  foreach ( $old_meta as $meta_key => $meta_value ) {
567
-
568
  if ( ! isset($new_meta[ $meta_key ] ) ) {
569
  $meta_changes["removed"][ $meta_key ] = true;
570
  }
@@ -574,7 +567,7 @@ class SimplePostLogger extends SimpleLogger
574
 
575
  // Look for changed meta
576
  foreach ( $old_meta as $meta_key => $meta_value ) {
577
-
578
  if ( isset( $new_meta[ $meta_key ] ) ) {
579
 
580
  if ( json_encode( $old_meta[ $meta_key ] ) != json_encode( $new_meta[ $meta_key ] ) ) {
@@ -619,7 +612,7 @@ class SimplePostLogger extends SimpleLogger
619
  continue;
620
  $page_templates[ $file ] = _cleanup_header_comment( $header[1] );
621
  }
622
-
623
  return $page_templates;
624
 
625
  }
@@ -729,7 +722,7 @@ class SimplePostLogger extends SimpleLogger
729
  foreach ( $context as $key => $val ) {
730
 
731
  if ( strpos($key, "post_prev_") !== false ) {
732
-
733
  // Old value exists, new value must also exist for diff to be calculates
734
  $key_to_diff = substr($key, strlen("post_prev_"));
735
 
@@ -748,8 +741,8 @@ class SimplePostLogger extends SimpleLogger
748
  $has_diff_values = true;
749
 
750
  $diff_table_output .= sprintf(
751
- '<tr><td>%1$s</td><td>%2$s</td></tr>',
752
- __("Title", "simple-history"),
753
  simple_history_text_diff($post_old_value, $post_new_value)
754
  );
755
 
@@ -762,8 +755,8 @@ class SimplePostLogger extends SimpleLogger
762
  $has_diff_values = true;
763
 
764
  $diff_table_output .= sprintf(
765
- '<tr><td>%1$s</td><td>%2$s</td></tr>',
766
- __("Content", "simple-history"),
767
  simple_history_text_diff($post_old_value, $post_new_value)
768
  );
769
 
@@ -776,8 +769,8 @@ class SimplePostLogger extends SimpleLogger
776
  '<tr>
777
  <td>%1$s</td>
778
  <td>Changed from %2$s to %3$s</td>
779
- </tr>',
780
- __("Status", "simple-history"),
781
  esc_html($post_old_value),
782
  esc_html($post_new_value)
783
  );
@@ -791,8 +784,8 @@ class SimplePostLogger extends SimpleLogger
791
  '<tr>
792
  <td>%1$s</td>
793
  <td>Changed from %2$s to %3$s</td>
794
- </tr>',
795
- __("Publish date", "simple-history"),
796
  esc_html($post_old_value),
797
  esc_html($post_new_value)
798
  );
@@ -806,8 +799,8 @@ class SimplePostLogger extends SimpleLogger
806
  '<tr>
807
  <td>%1$s</td>
808
  <td>%2$s</td>
809
- </tr>',
810
- __("Permalink", "simple-history"),
811
  simple_history_text_diff($post_old_value, $post_new_value)
812
  );
813
 
@@ -820,8 +813,8 @@ class SimplePostLogger extends SimpleLogger
820
  '<tr>
821
  <td>%1$s</td>
822
  <td>Changed from %2$s to %3$s</td>
823
- </tr>',
824
- __("Comment status", "simple-history"),
825
  esc_html($post_old_value),
826
  esc_html($post_new_value)
827
  );
@@ -832,7 +825,7 @@ class SimplePostLogger extends SimpleLogger
832
 
833
  // wp post edit screen uses display_name so we should use it too
834
  if ( isset( $context["post_prev_post_author/display_name"] ) && isset( $context["post_new_post_author/display_name"] ) ) {
835
-
836
  $prev_user_display_name = $context["post_prev_post_author/display_name"];
837
  $new_user_display_name = $context["post_new_post_author/display_name"];
838
 
@@ -843,15 +836,15 @@ class SimplePostLogger extends SimpleLogger
843
  '<tr>
844
  <td>%1$s</td>
845
  <td>%2$s</td>
846
- </tr>',
847
- __("Author", "simple-history"),
848
- $this->interpolate(
849
- __('Changed from {prev_user_display_name} ({prev_user_email}) to {new_user_display_name} ({new_user_email})', "simple-history"),
850
  array(
851
  "prev_user_display_name" => esc_html( $prev_user_display_name ),
852
  "prev_user_email" => esc_html( $prev_user_user_email ),
853
  "new_user_display_name" => esc_html( $new_user_display_name ),
854
- "new_user_email" => esc_html( $new_user_user_email )
855
  )
856
  )
857
  );
@@ -889,10 +882,10 @@ class SimplePostLogger extends SimpleLogger
889
  '<tr>
890
  <td>%1$s</td>
891
  <td>%2$s</td>
892
- </tr>',
893
- __("Template", "simple-history"),
894
- $this->interpolate(
895
- $message,
896
  array(
897
  "prev_page_template" => "<code>" . esc_html( $prev_page_template ) . "</code>",
898
  "new_page_template" => "<code>" . esc_html( $new_page_template ) . "</code>",
@@ -939,7 +932,7 @@ class SimplePostLogger extends SimpleLogger
939
  );
940
 
941
  }
942
-
943
  /*
944
  $diff_table_output .= "
945
  <p>
@@ -969,7 +962,7 @@ class SimplePostLogger extends SimpleLogger
969
 
970
  /**
971
  * Modify RSS links to they go directly to the correct post in wp admin
972
- *
973
  * @since 2.0.23
974
  * @param string $link
975
  * @param array $row
@@ -983,7 +976,7 @@ class SimplePostLogger extends SimpleLogger
983
  if ( isset( $row->context["post_id"] ) ) {
984
 
985
  $permalink = add_query_arg(array("action" => "edit", "post" => $row->context["post_id"]), admin_url( "post.php" ) );
986
-
987
  if ( $permalink ) {
988
  $link = $permalink;
989
  }
@@ -1014,8 +1007,8 @@ class SimplePostLogger extends SimpleLogger
1014
  color: rgb(75, 75, 75);
1015
  font-family: "Open Sans", sans-serif;
1016
  }
1017
-
1018
- </style>
1019
  <?php
1020
 
1021
  }
17
 
18
  public function loaded() {
19
 
20
+ add_action("admin_action_editpost", array($this, "on_admin_action_editpost"));
21
+ add_action("transition_post_status", array($this, "on_transition_post_status"), 10, 3);
22
+ add_action("delete_post", array($this, "on_delete_post"));
23
+ add_action("untrash_post", array($this, "on_untrash_post"));
24
 
25
  $this->add_xml_rpc_hooks();
26
 
54
  }
55
 
56
  function on_xmlrpc_call($method) {
57
+
58
  $arr_methods_to_act_on = array(
59
  "wp.deletePost"
60
  );
98
  );
99
 
100
  $this->infoMessage( "post_trashed", $context );
101
+
102
 
103
  } // if delete post
104
 
155
 
156
  }
157
 
 
 
 
 
 
 
 
 
 
 
158
  /**
159
  * Get and store old info about a post that is being edited.
160
  * Needed to later compare old data with new data, to detect differences.
165
  * @since 2.0.29
166
  */
167
  function on_admin_action_editpost() {
168
+
169
  $post_ID = isset( $_POST["post_ID"] ) ? (int) $_POST["post_ID"] : 0;
170
 
171
  if ( ! $post_ID ) {
175
  if ( ! current_user_can( 'edit_post', $post_ID ) ) {
176
  return;
177
  };
178
+
179
  $prev_post_data = get_post( $post_ID );
180
 
181
  $this->old_post_data[$post_ID] = array(
182
  "post_data" => $prev_post_data,
183
  "post_meta" => get_post_custom( $post_ID )
184
  );
185
+
186
  }
187
 
188
  /**
390
 
391
  /*
392
  * Adds diff data to the context array. Is called just before the event is logged.
393
+ *
394
  * Since 2.0.29
395
+ *
396
  * To detect
397
  * - post thumb (part of custom fields)
398
  * - categories
400
  * @return array $context with diff data added
401
  */
402
  function add_post_data_diff_to_context($context, $old_post_data, $new_post_data) {
403
+
404
  $old_data = $old_post_data["post_data"];
405
  $new_data = $new_post_data["post_data"];
406
 
432
 
433
  // If changes where detected
434
  if ( $post_data_diff ) {
435
+
436
  // $context["_post_data_diff"] = $this->simpleHistory->json_encode( $post_data_diff );
437
  // Save at least 2 values for each detected value change, i.e. the old value and the new value
438
  foreach ( $post_data_diff as $diff_key => $diff_values ) {
439
+
440
  $context["post_prev_{$diff_key}"] = $diff_values["old"];
441
  $context["post_new_{$diff_key}"] = $diff_values["new"];
442
 
443
  // If post_author then get more author info
444
  // Because just a user ID does not get us far
445
  if ( "post_author" == $diff_key ) {
446
+
447
  $old_author_user = get_userdata( (int) $diff_values["old"] );
448
  $new_author_user = get_userdata( (int) $diff_values["new"] );
449
 
450
  if ( is_a( $old_author_user, "WP_User" ) && is_a( $new_author_user, "WP_User" ) ) {
451
+
452
  $context["post_prev_{$diff_key}/user_login"] = $old_author_user->user_login;
453
  $context["post_prev_{$diff_key}/user_email"] = $old_author_user->user_email;
454
  $context["post_prev_{$diff_key}/display_name"] = $old_author_user->display_name;
455
 
456
  $context["post_new_{$diff_key}/user_login"] = $new_author_user->user_login;
457
  $context["post_new_{$diff_key}/user_email"] = $new_author_user->user_email;
458
+ $context["post_new_{$diff_key}/display_name"] = $new_author_user->display_name;
459
 
460
  }
461
 
471
  [new] => 25556
472
  )
473
  */
 
474
 
475
+
476
+
477
  }
478
 
479
  } // post_data_diff
497
 
498
  $old_meta = $old_post_data["post_meta"];
499
  $new_meta = $new_post_data["post_meta"];
500
+
501
  // @todo: post thumb is stored in _thumbnail_id
502
 
503
  // page template is stored in _wp_page_template
504
  if ( isset( $old_meta["_wp_page_template"][0] ) && isset( $new_meta["_wp_page_template"][0] ) ) {
505
+
506
  /*
507
  Var is string with length 7: default
508
  Var is string with length 20: template-builder.php
509
  */
510
 
511
  if ( $old_meta["_wp_page_template"][0] != $new_meta["_wp_page_template"][0] ) {
512
+
513
  // prev page template is different from new page template
514
 
515
  // store template php file name
529
  if ( isset( $theme_templates[ $context["post_prev_page_template"] ] ) ) {
530
  $context["post_prev_page_template_name"] = $theme_templates[$context["post_prev_page_template"]];
531
  }
532
+
533
  if ( isset( $theme_templates[ $context["post_new_page_template"] ] ) ) {
534
  $context["post_new_page_template_name"] = $theme_templates[$context["post_new_page_template"]];
535
  }
536
 
537
  }
538
+
539
  }
540
 
541
  // Remove fields that we have checked already and other that should be ignored
543
  unset( $old_meta[ $key_to_ignore ] );
544
  unset( $new_meta[ $key_to_ignore ] );
545
  }
546
+
547
  // Look for added custom fields
548
  foreach ( $new_meta as $meta_key => $meta_value ) {
549
+
550
  if ( ! isset( $old_meta[ $meta_key ] ) ) {
551
  $meta_changes["added"][ $meta_key ] = true;
552
  }
557
  // Does not work, if user clicks "delete" in edit screen then meta is removed using ajax
558
  /*
559
  foreach ( $old_meta as $meta_key => $meta_value ) {
560
+
561
  if ( ! isset($new_meta[ $meta_key ] ) ) {
562
  $meta_changes["removed"][ $meta_key ] = true;
563
  }
567
 
568
  // Look for changed meta
569
  foreach ( $old_meta as $meta_key => $meta_value ) {
570
+
571
  if ( isset( $new_meta[ $meta_key ] ) ) {
572
 
573
  if ( json_encode( $old_meta[ $meta_key ] ) != json_encode( $new_meta[ $meta_key ] ) ) {
612
  continue;
613
  $page_templates[ $file ] = _cleanup_header_comment( $header[1] );
614
  }
615
+
616
  return $page_templates;
617
 
618
  }
722
  foreach ( $context as $key => $val ) {
723
 
724
  if ( strpos($key, "post_prev_") !== false ) {
725
+
726
  // Old value exists, new value must also exist for diff to be calculates
727
  $key_to_diff = substr($key, strlen("post_prev_"));
728
 
741
  $has_diff_values = true;
742
 
743
  $diff_table_output .= sprintf(
744
+ '<tr><td>%1$s</td><td>%2$s</td></tr>',
745
+ __("Title", "simple-history"),
746
  simple_history_text_diff($post_old_value, $post_new_value)
747
  );
748
 
755
  $has_diff_values = true;
756
 
757
  $diff_table_output .= sprintf(
758
+ '<tr><td>%1$s</td><td>%2$s</td></tr>',
759
+ __("Content", "simple-history"),
760
  simple_history_text_diff($post_old_value, $post_new_value)
761
  );
762
 
769
  '<tr>
770
  <td>%1$s</td>
771
  <td>Changed from %2$s to %3$s</td>
772
+ </tr>',
773
+ __("Status", "simple-history"),
774
  esc_html($post_old_value),
775
  esc_html($post_new_value)
776
  );
784
  '<tr>
785
  <td>%1$s</td>
786
  <td>Changed from %2$s to %3$s</td>
787
+ </tr>',
788
+ __("Publish date", "simple-history"),
789
  esc_html($post_old_value),
790
  esc_html($post_new_value)
791
  );
799
  '<tr>
800
  <td>%1$s</td>
801
  <td>%2$s</td>
802
+ </tr>',
803
+ __("Permalink", "simple-history"),
804
  simple_history_text_diff($post_old_value, $post_new_value)
805
  );
806
 
813
  '<tr>
814
  <td>%1$s</td>
815
  <td>Changed from %2$s to %3$s</td>
816
+ </tr>',
817
+ __("Comment status", "simple-history"),
818
  esc_html($post_old_value),
819
  esc_html($post_new_value)
820
  );
825
 
826
  // wp post edit screen uses display_name so we should use it too
827
  if ( isset( $context["post_prev_post_author/display_name"] ) && isset( $context["post_new_post_author/display_name"] ) ) {
828
+
829
  $prev_user_display_name = $context["post_prev_post_author/display_name"];
830
  $new_user_display_name = $context["post_new_post_author/display_name"];
831
 
836
  '<tr>
837
  <td>%1$s</td>
838
  <td>%2$s</td>
839
+ </tr>',
840
+ __("Author", "simple-history"),
841
+ $this->interpolate(
842
+ __('Changed from {prev_user_display_name} ({prev_user_email}) to {new_user_display_name} ({new_user_email})', "simple-history"),
843
  array(
844
  "prev_user_display_name" => esc_html( $prev_user_display_name ),
845
  "prev_user_email" => esc_html( $prev_user_user_email ),
846
  "new_user_display_name" => esc_html( $new_user_display_name ),
847
+ "new_user_email" => esc_html( $new_user_user_email )
848
  )
849
  )
850
  );
882
  '<tr>
883
  <td>%1$s</td>
884
  <td>%2$s</td>
885
+ </tr>',
886
+ __("Template", "simple-history"),
887
+ $this->interpolate(
888
+ $message,
889
  array(
890
  "prev_page_template" => "<code>" . esc_html( $prev_page_template ) . "</code>",
891
  "new_page_template" => "<code>" . esc_html( $new_page_template ) . "</code>",
932
  );
933
 
934
  }
935
+
936
  /*
937
  $diff_table_output .= "
938
  <p>
962
 
963
  /**
964
  * Modify RSS links to they go directly to the correct post in wp admin
965
+ *
966
  * @since 2.0.23
967
  * @param string $link
968
  * @param array $row
976
  if ( isset( $row->context["post_id"] ) ) {
977
 
978
  $permalink = add_query_arg(array("action" => "edit", "post" => $row->context["post_id"]), admin_url( "post.php" ) );
979
+
980
  if ( $permalink ) {
981
  $link = $permalink;
982
  }
1007
  color: rgb(75, 75, 75);
1008
  font-family: "Open Sans", sans-serif;
1009
  }
1010
+
1011
+ </style>
1012
  <?php
1013
 
1014
  }
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.2
7
- Stable tag: 2.8
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,14 @@ A simple way to see any uncommon activity, for example an increased number of lo
153
 
154
  ## Changelog
155
 
 
 
 
 
 
 
 
 
156
  = 2.8 (August 2016) =
157
 
158
  - Theme installs are now logged
@@ -167,7 +175,8 @@ A simple way to see any uncommon activity, for example an increased number of lo
167
  = 2.7.5 (August 2016) =
168
 
169
  - User logins using e-mail are now logged correctly. Previously the user would be logged in successfully but the log said that they failed.
170
- - Now only users with [`list_users`](https://codex.wordpress.org/Roles_and_Capabilities#list_users) capability can view the users filter and use the autocomplete api for users.
 
171
  - Add labels to search filters. (I do really hate label-less forms so it's kinda very strange that this was not in place before.)
172
  - Misc other internal fixes
173
 
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
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.9 (August 2016) =
157
+
158
+ - Added custom date ranges to the dates filter. Just select "Custom date range..." in the dates dropdown and you can choose to se the log between any two exact dates.
159
+ - The values in the statistics graph can now be clicked and when clicked the log is filtered to only show logged events from that day. Very convenient if you have a larger number of events logged for one day and quickly want to find out what exactly was logged that day.
160
+ - Dates filter no longer accepts multi values. It was indeed a bit confusing that you could select both "Last 7 days" and "Last 3 days".
161
+ - Fix for empty previous plugin version (the `{plugin_prev_version}` placeholder) when updating plugins.
162
+ - Post and pages updates done in the WordPress apps for Ios and Android should be logged again.
163
+
164
  = 2.8 (August 2016) =
165
 
166
  - Theme installs are now logged
175
  = 2.7.5 (August 2016) =
176
 
177
  - User logins using e-mail are now logged correctly. Previously the user would be logged in successfully but the log said that they failed.
178
+ - Security fix: only users with [`list_users`](https://codex.wordpress.org/Roles_and_Capabilities#list_users) capability can view the users filter and use the autocomplete api for users.
179
+ Previously the autocomplete function could be used by all logged in users.
180
  - Add labels to search filters. (I do really hate label-less forms so it's kinda very strange that this was not in place before.)
181
  - Misc other internal fixes
182