Version Description
(May 2015) =
- Added: Export! Now it's possible to export the events log to a JSON or CSV formatted file. It's your data so you should be able to export it any time you want or need. And now you can do that. You will find the export function in the Simple History settings page (Settings -> Simple History).
- Added: Filter
simple_history/add_custom_logger
and functionregister_logger
that together are used to load external custom loggers. See example-logger.php for usage example. - Added: Filter
simple_history/header_initiator_use_you
. - Fixed: Fixed an undefined variable in get_avatar(). Fixes https://github.com/bonny/WordPress-Simple-History/issues/74.
- Fixed: When using HyperDB only one event was returned. Fixed by using adding
NO_SELECT_FOUND_ROWS
to the query. Should fix problems for users using HyperDB and also users using for example wpengine.com (that probably also is using HyperDB or a similar approach). - Changed: Loggers now get default capability "manage_options" if they have no capability set.
- Changed: Misc internal cleanup.
- Removed: filter
simple_history/loggers_dir
removed, because loggers are loaded from array instead of file listing generated fromglob()
. Should be (however to the eye non-noticable) faster.
Download this release
Release Info
Developer | eskapism |
Plugin | Simple History |
Version | 2.1 |
Comparing to | |
See all releases |
Code changes from version 2.0.30 to 2.1
- dropins/SimpleHistoryExportDropin.php +274 -0
- examples/example-logger.php +96 -0
- inc/SimpleHistory.php +74 -25
- inc/SimpleHistoryLogQuery.php +62 -54
- index.php +4 -2
- loggers/SimpleLogger.php +34 -20
- loggers/SimpleMediaLogger.php +3 -3
- readme.txt +14 -3
- templates/settings-statsForGeeks.php +1 -1
dropins/SimpleHistoryExportDropin.php
ADDED
@@ -0,0 +1,274 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
Dropin Name: Export
|
5 |
+
Dropin Description: Adds a tab with export options
|
6 |
+
Dropin URI: http://simple-history.com/
|
7 |
+
Author: Pär Thernström
|
8 |
+
*/
|
9 |
+
|
10 |
+
class SimpleHistoryExportDropin {
|
11 |
+
|
12 |
+
// Simple History instance
|
13 |
+
private $sh;
|
14 |
+
|
15 |
+
public function __construct($sh) {
|
16 |
+
|
17 |
+
// Since it's not quite done yet, it's for da devs only for now
|
18 |
+
if ( ! defined("SIMPLE_HISTORY_DEV") || ! SIMPLE_HISTORY_DEV ) {
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
// Set simple history variable
|
23 |
+
$this->sh = $sh;
|
24 |
+
|
25 |
+
// Add tab to settings page
|
26 |
+
$sh->registerSettingsTab(array(
|
27 |
+
"slug" => "export",
|
28 |
+
"name" => _x("Export", "Export dropin: Tab name on settings page", "simple-history"),
|
29 |
+
"function" => array($this, "output")
|
30 |
+
));
|
31 |
+
|
32 |
+
add_action("init", array($this, "downloadExport"));
|
33 |
+
|
34 |
+
}
|
35 |
+
|
36 |
+
public function downloadExport() {
|
37 |
+
|
38 |
+
global $wpdb;
|
39 |
+
|
40 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
41 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
42 |
+
|
43 |
+
if ( isset($_POST["simple-history-action"]) && $_POST["simple-history-action"] === "export-history" ) {
|
44 |
+
|
45 |
+
// Will die if nonce not valid
|
46 |
+
check_admin_referer( __CLASS__ . "-action-export" );
|
47 |
+
|
48 |
+
$export_format = isset( $_POST["format"] ) ? $_POST["format"] : "json";
|
49 |
+
|
50 |
+
// Disable relative time output in header
|
51 |
+
add_filter("simple_history/header_time_ago_max_time", "__return_zero");
|
52 |
+
add_filter("simple_history/header_just_now_max_time", "__return_zero");
|
53 |
+
|
54 |
+
// Don't use "You" if event is initiated by the same user that does the export
|
55 |
+
add_filter("simple_history/header_initiator_use_you", "__return_false");
|
56 |
+
|
57 |
+
$query = new SimpleHistoryLogQuery();
|
58 |
+
|
59 |
+
$query_args = array(
|
60 |
+
"paged" => 1,
|
61 |
+
"posts_per_page" => 3000
|
62 |
+
);
|
63 |
+
|
64 |
+
$events = $query->query($query_args);
|
65 |
+
|
66 |
+
// $events->total_row_count;
|
67 |
+
$pages_count = $events["pages_count"];
|
68 |
+
$page_current = $events["page_current"];
|
69 |
+
|
70 |
+
$fp = fopen('php://output', 'w');
|
71 |
+
|
72 |
+
#header("Content-Type: application/octet-stream");
|
73 |
+
if ( "csv" == $export_format ) {
|
74 |
+
|
75 |
+
$filename = "simple-history-export-" . time() . ".csv";
|
76 |
+
header("Content-Type: text/plain");
|
77 |
+
header("Content-Disposition: attachment; filename='{$filename}'");
|
78 |
+
|
79 |
+
} else if ( "json" == $export_format ) {
|
80 |
+
|
81 |
+
$filename = "simple-history-export-" . time() . ".json";
|
82 |
+
header("Content-Type: application/json");
|
83 |
+
header("Content-Disposition: attachment; filename='{$filename}'");
|
84 |
+
|
85 |
+
} else if ( "html" == $export_format ) {
|
86 |
+
|
87 |
+
$filename = "simple-history-export-" . time() . ".html";
|
88 |
+
header("Content-Type: text/html");
|
89 |
+
#header("Content-Disposition: attachment; filename='{$filename}'");
|
90 |
+
|
91 |
+
}
|
92 |
+
|
93 |
+
// Some formats need to output some stuff before the actual loops
|
94 |
+
if ( "json" == $export_format ) {
|
95 |
+
|
96 |
+
$json_row = "[";
|
97 |
+
fwrite($fp, $json_row);
|
98 |
+
|
99 |
+
} else if ( "html" == $export_format ) {
|
100 |
+
|
101 |
+
$html = sprintf(
|
102 |
+
'
|
103 |
+
<!doctype html>
|
104 |
+
<meta charset="utf-8">
|
105 |
+
<title>Simple History export</title>
|
106 |
+
<ul>
|
107 |
+
');
|
108 |
+
fwrite($fp, $html);
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
// Paginate through all pages and all their rows
|
113 |
+
$row_loop = 0;
|
114 |
+
while ( $page_current <= $pages_count + 1 ) {
|
115 |
+
|
116 |
+
// if ($page_current > 1) { break; } # To debug/test
|
117 |
+
|
118 |
+
foreach ( $events["log_rows"] as $one_row ) {
|
119 |
+
|
120 |
+
// if ( $row_loop > 10) { break; } # To debug/test
|
121 |
+
|
122 |
+
set_time_limit(30);
|
123 |
+
|
124 |
+
if ( "csv" == $export_format ) {
|
125 |
+
|
126 |
+
$header_output = strip_tags( html_entity_decode( $this->sh->getLogRowHeaderOutput( $one_row ), ENT_QUOTES, 'UTF-8') );
|
127 |
+
$header_output = trim(preg_replace('/\s\s+/', ' ', $header_output));
|
128 |
+
|
129 |
+
$message_output = strip_tags( html_entity_decode( $this->sh->getLogRowPlainTextOutput( $one_row ), ENT_QUOTES, 'UTF-8') );
|
130 |
+
|
131 |
+
fputcsv($fp, array(
|
132 |
+
$one_row->date,
|
133 |
+
$one_row->logger,
|
134 |
+
$one_row->level,
|
135 |
+
$one_row->initiator,
|
136 |
+
$one_row->context_message_key,
|
137 |
+
$header_output,
|
138 |
+
$message_output,
|
139 |
+
$one_row->subsequentOccasions
|
140 |
+
));
|
141 |
+
|
142 |
+
} else if ( "json" == $export_format ) {
|
143 |
+
|
144 |
+
// If not first loop then add a comma between all json objects
|
145 |
+
if ( $row_loop == 0 ) {
|
146 |
+
$comma = "\n";
|
147 |
+
} else {
|
148 |
+
$comma = ",\n";
|
149 |
+
}
|
150 |
+
|
151 |
+
$json_row = $comma . $this->sh->json_encode($one_row);
|
152 |
+
fwrite($fp, $json_row);
|
153 |
+
|
154 |
+
} else if ( "html" == $export_format ) {
|
155 |
+
|
156 |
+
$html = sprintf(
|
157 |
+
'
|
158 |
+
<li>
|
159 |
+
<div>%1$s</div>
|
160 |
+
<div>%2$s</div>
|
161 |
+
<div>%3$s</div>
|
162 |
+
</li>
|
163 |
+
',
|
164 |
+
$this->sh->getLogRowHeaderOutput( $one_row ),
|
165 |
+
$this->sh->getLogRowPlainTextOutput( $one_row ),
|
166 |
+
$this->sh->getLogRowDetailsOutput( $one_row )
|
167 |
+
);
|
168 |
+
|
169 |
+
fwrite($fp, $html);
|
170 |
+
|
171 |
+
}
|
172 |
+
|
173 |
+
$row_loop++;
|
174 |
+
|
175 |
+
}
|
176 |
+
|
177 |
+
#echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
178 |
+
#echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
179 |
+
#echo "<br>fetch next page";
|
180 |
+
|
181 |
+
flush();
|
182 |
+
|
183 |
+
// Fetch next page
|
184 |
+
// @TODO: must take into consideration that new items can be added while we do the fetch
|
185 |
+
$page_current++;
|
186 |
+
$query_args["paged"] = $page_current;
|
187 |
+
$events = $query->query($query_args);
|
188 |
+
|
189 |
+
#echo "<br>did fetch next page";
|
190 |
+
#echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
191 |
+
#echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
192 |
+
|
193 |
+
|
194 |
+
}
|
195 |
+
|
196 |
+
if ("json" == $export_format) {
|
197 |
+
|
198 |
+
$json_row = "]";
|
199 |
+
fwrite($fp, $json_row);
|
200 |
+
|
201 |
+
} else if ("html" == $export_format) {
|
202 |
+
|
203 |
+
$html = sprintf('</ul>');
|
204 |
+
fwrite($fp, $html);
|
205 |
+
|
206 |
+
}
|
207 |
+
|
208 |
+
fclose($fp);
|
209 |
+
flush();
|
210 |
+
|
211 |
+
exit;
|
212 |
+
|
213 |
+
#echo "<br>done";
|
214 |
+
|
215 |
+
}
|
216 |
+
|
217 |
+
}
|
218 |
+
|
219 |
+
|
220 |
+
public function output() {
|
221 |
+
|
222 |
+
|
223 |
+
?>
|
224 |
+
<!-- <h2>Export</h2> -->
|
225 |
+
|
226 |
+
<p><?php _ex("The export function will export the full history.", "Export dropin: introtext", "simple-history" ) ?></p>
|
227 |
+
|
228 |
+
<form method="post">
|
229 |
+
|
230 |
+
<h3><?php _ex("Choose format to export to", "Export dropin: format", "simple-history" ) ?></h3>
|
231 |
+
|
232 |
+
<p>
|
233 |
+
<label>
|
234 |
+
<input type="radio" name="format" value="json" checked>
|
235 |
+
<?php _ex("JSON", "Export dropin: export format", "simple-history" ) ?>
|
236 |
+
</label>
|
237 |
+
</p>
|
238 |
+
|
239 |
+
<p>
|
240 |
+
<label>
|
241 |
+
<input type="radio" name="format" value="csv">
|
242 |
+
<?php _ex("CSV", "Export dropin: export format", "simple-history" ) ?>
|
243 |
+
</label>
|
244 |
+
</p>
|
245 |
+
|
246 |
+
<!-- <br> -->
|
247 |
+
|
248 |
+
<!--<label>
|
249 |
+
<input type="radio" name="format" value="html">
|
250 |
+
HTML
|
251 |
+
</label>
|
252 |
+
<br> -->
|
253 |
+
|
254 |
+
<!-- <label>
|
255 |
+
<input type="radio" name="format" value="xml">
|
256 |
+
XML
|
257 |
+
</label> -->
|
258 |
+
|
259 |
+
<p>
|
260 |
+
<button type="submit" class="button button-primary"><?php _ex("Download Export File", "Export dropin: submit button", "simple-history" ) ?></button>
|
261 |
+
<input type="hidden" name="simple-history-action" value="export-history">
|
262 |
+
</p>
|
263 |
+
|
264 |
+
<?php
|
265 |
+
wp_nonce_field( __CLASS__ . "-action-export" );
|
266 |
+
?>
|
267 |
+
|
268 |
+
</form>
|
269 |
+
|
270 |
+
<?php
|
271 |
+
|
272 |
+
}
|
273 |
+
|
274 |
+
}
|
examples/example-logger.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// No external calls allowed to test file
|
4 |
+
exit;
|
5 |
+
|
6 |
+
|
7 |
+
/**
|
8 |
+
* This example shows how to create a simple logger that will
|
9 |
+
* log 404-errors on your website.
|
10 |
+
*/
|
11 |
+
|
12 |
+
// We use the function "register_logger" to tell tell SimpleHistory that our custom logger exists.
|
13 |
+
// We call it from inside the filter "simple_history/add_custom_logger".
|
14 |
+
add_action("simple_history/add_custom_logger", function($simpleHistory) {
|
15 |
+
|
16 |
+
$simpleHistory->register_logger("FourOhFourLogger");
|
17 |
+
|
18 |
+
});
|
19 |
+
|
20 |
+
// We make sure that the SimpleLogger class exists before trying to extend it.
|
21 |
+
// This prevents error if the Simple History plugin gets inactivated.
|
22 |
+
if (class_exists("SimpleLogger")) {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This is the class that does the main work!
|
26 |
+
*/
|
27 |
+
class FourOhFourLogger extends SimpleLogger {
|
28 |
+
|
29 |
+
/**
|
30 |
+
* The slug is ised to identify this logger in various places.
|
31 |
+
* We use the name of the class too keep it simple.
|
32 |
+
*/
|
33 |
+
public $slug = __CLASS__;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Return information about this logger.
|
37 |
+
* Used to show info about the logger at various places.
|
38 |
+
*/
|
39 |
+
function getInfo() {
|
40 |
+
|
41 |
+
$arr_info = array(
|
42 |
+
"name" => "404 Logger",
|
43 |
+
"description" => "Logs access to pages that result in page not found errors (error code 404)",
|
44 |
+
"capability" => "edit_pages",
|
45 |
+
"messages" => array(
|
46 |
+
'page_not_found' => __('Got a 404-page when trying to visit "{request_uri}"', "simple-history"),
|
47 |
+
),
|
48 |
+
"labels" => array(
|
49 |
+
"search" => array(
|
50 |
+
"label" => _x("Pages not found (404 errors)", "User logger: 404", "simple-history"),
|
51 |
+
"options" => array(
|
52 |
+
_x("Pages not found", "User logger: 404", "simple-history") => array(
|
53 |
+
"page_not_found",
|
54 |
+
),
|
55 |
+
),
|
56 |
+
), // end search
|
57 |
+
), // end labels
|
58 |
+
);
|
59 |
+
|
60 |
+
return $arr_info;
|
61 |
+
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* When Simple History has loaded this logger it automagically
|
66 |
+
* calls a loaded() function. This is where you add your actions
|
67 |
+
* and other logger functionality.
|
68 |
+
*/
|
69 |
+
function loaded() {
|
70 |
+
|
71 |
+
// Call a function when WordPress finds a 404 page
|
72 |
+
add_action("404_template", array($this, "on_404_template"), 10, 1);
|
73 |
+
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Function that is called when WordPress finds a 404 page.
|
78 |
+
* It collects some info and then it logs a warning message
|
79 |
+
* to the log.
|
80 |
+
*/
|
81 |
+
function on_404_template($template) {
|
82 |
+
|
83 |
+
$context = array(
|
84 |
+
"_initiator" => SimpleLoggerLogInitiators::WEB_USER,
|
85 |
+
'request_uri' => isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : "",
|
86 |
+
'http_referer' => isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : "",
|
87 |
+
);
|
88 |
+
|
89 |
+
$this->warningMessage("page_not_found", $context);
|
90 |
+
|
91 |
+
return $template;
|
92 |
+
|
93 |
+
}
|
94 |
+
|
95 |
+
}
|
96 |
+
}
|
inc/SimpleHistory.php
CHANGED
@@ -10,7 +10,7 @@ class SimpleHistory {
|
|
10 |
const NAME = "Simple History";
|
11 |
|
12 |
// Dont use this any more! Will be removed in future versions. Use global SIMPLE_HISTORY_VERSION instead.
|
13 |
-
const VERSION = "2.
|
14 |
|
15 |
/**
|
16 |
* For singleton
|
@@ -27,6 +27,11 @@ class SimpleHistory {
|
|
27 |
*/
|
28 |
private $view_settings_capability;
|
29 |
|
|
|
|
|
|
|
|
|
|
|
30 |
/**
|
31 |
* Array with all instantiated loggers
|
32 |
*/
|
@@ -37,8 +42,6 @@ class SimpleHistory {
|
|
37 |
*/
|
38 |
private $instantiatedDropins;
|
39 |
|
40 |
-
public $pluginBasename;
|
41 |
-
|
42 |
/**
|
43 |
* Bool if gettext filter function should be active
|
44 |
* Should only be active during the load of a logger
|
@@ -82,13 +85,13 @@ class SimpleHistory {
|
|
82 |
*/
|
83 |
do_action("simple_history/before_init", $this);
|
84 |
|
85 |
-
$this->
|
86 |
|
87 |
// Actions and filters, ordered by order specified in codex: http://codex.wordpress.org/Plugin_API/Action_Reference
|
88 |
add_action('after_setup_theme', array($this, 'load_plugin_textdomain'));
|
89 |
add_action('after_setup_theme', array($this, 'add_default_settings_tabs'));
|
90 |
-
add_action('after_setup_theme', array($this, '
|
91 |
-
add_action('after_setup_theme', array($this, '
|
92 |
|
93 |
// Run before loading of loggers and before menu items are added
|
94 |
add_action('after_setup_theme', array($this, 'check_for_upgrade'), 5);
|
@@ -532,7 +535,11 @@ class SimpleHistory {
|
|
532 |
/**
|
533 |
* Setup variables and things
|
534 |
*/
|
535 |
-
public function
|
|
|
|
|
|
|
|
|
536 |
|
537 |
// Capability required to view history = for who will the History page be added
|
538 |
$this->view_history_capability = "edit_pages";
|
@@ -586,30 +593,50 @@ class SimpleHistory {
|
|
586 |
|
587 |
}
|
588 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
/**
|
590 |
* Load built in loggers from all files in /loggers
|
591 |
* and instantiates them
|
592 |
*/
|
593 |
-
public function
|
594 |
|
595 |
$loggersDir = SIMPLE_HISTORY_PATH . "loggers/";
|
596 |
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
|
|
|
|
|
|
|
|
|
|
609 |
include_once $loggersDir . "SimpleLogger.php";
|
610 |
|
611 |
/**
|
612 |
-
* Filter the array with absolute paths to files
|
|
|
613 |
* Each file will be loaded and will be assumed to be a logger with a classname
|
614 |
* the same as the filename.
|
615 |
*
|
@@ -619,8 +646,10 @@ class SimpleHistory {
|
|
619 |
*/
|
620 |
$loggersFiles = apply_filters("simple_history/loggers_files", $loggersFiles);
|
621 |
|
|
|
|
|
622 |
$arrLoggersToInstantiate = array();
|
623 |
-
|
624 |
foreach ( $loggersFiles as $oneLoggerFile ) {
|
625 |
|
626 |
$load_logger = true;
|
@@ -633,7 +662,7 @@ class SimpleHistory {
|
|
633 |
* @since 2.0.22
|
634 |
*
|
635 |
* @param bool if to load the logger. return false to not load it.
|
636 |
-
* @param
|
637 |
*/
|
638 |
$load_logger = apply_filters("simple_history/logger/load_logger", $load_logger, $basename_no_suffix );
|
639 |
|
@@ -647,9 +676,29 @@ class SimpleHistory {
|
|
647 |
|
648 |
}
|
649 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
650 |
/**
|
651 |
* Filter the array with names of loggers to instantiate.
|
652 |
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
653 |
* @since 2.0
|
654 |
*
|
655 |
* @param array $arrLoggersToInstantiate Array with class names
|
@@ -716,7 +765,7 @@ class SimpleHistory {
|
|
716 |
* Load built in dropins from all files in /dropins
|
717 |
* and instantiates them
|
718 |
*/
|
719 |
-
public function
|
720 |
|
721 |
$dropinsDir = SIMPLE_HISTORY_PATH . "dropins/";
|
722 |
|
@@ -2462,7 +2511,7 @@ class SimpleHistory {
|
|
2462 |
* @param string $alt Alternative text to use in the avatar image tag.
|
2463 |
* Default empty.
|
2464 |
*/
|
2465 |
-
$avatar = apply_filters( 'get_avatar', $avatar, $
|
2466 |
|
2467 |
return $avatar;
|
2468 |
|
10 |
const NAME = "Simple History";
|
11 |
|
12 |
// Dont use this any more! Will be removed in future versions. Use global SIMPLE_HISTORY_VERSION instead.
|
13 |
+
const VERSION = "2.1";
|
14 |
|
15 |
/**
|
16 |
* For singleton
|
27 |
*/
|
28 |
private $view_settings_capability;
|
29 |
|
30 |
+
/**
|
31 |
+
* Array with external loggers to load
|
32 |
+
*/
|
33 |
+
private $externalLoggers;
|
34 |
+
|
35 |
/**
|
36 |
* Array with all instantiated loggers
|
37 |
*/
|
42 |
*/
|
43 |
private $instantiatedDropins;
|
44 |
|
|
|
|
|
45 |
/**
|
46 |
* Bool if gettext filter function should be active
|
47 |
* Should only be active during the load of a logger
|
85 |
*/
|
86 |
do_action("simple_history/before_init", $this);
|
87 |
|
88 |
+
$this->setup_variables();
|
89 |
|
90 |
// Actions and filters, ordered by order specified in codex: http://codex.wordpress.org/Plugin_API/Action_Reference
|
91 |
add_action('after_setup_theme', array($this, 'load_plugin_textdomain'));
|
92 |
add_action('after_setup_theme', array($this, 'add_default_settings_tabs'));
|
93 |
+
add_action('after_setup_theme', array($this, 'load_loggers'));
|
94 |
+
add_action('after_setup_theme', array($this, 'load_dropins'));
|
95 |
|
96 |
// Run before loading of loggers and before menu items are added
|
97 |
add_action('after_setup_theme', array($this, 'check_for_upgrade'), 5);
|
535 |
/**
|
536 |
* Setup variables and things
|
537 |
*/
|
538 |
+
public function setup_variables() {
|
539 |
+
|
540 |
+
$this->externalLoggers = array();
|
541 |
+
$this->instantiatedLoggers = array();
|
542 |
+
$this->instantiatedDropins = array();
|
543 |
|
544 |
// Capability required to view history = for who will the History page be added
|
545 |
$this->view_history_capability = "edit_pages";
|
593 |
|
594 |
}
|
595 |
|
596 |
+
/**
|
597 |
+
* Register an external logger so Simple History knows about it.
|
598 |
+
* Does not load the logger, so file with logger must be loaded already.
|
599 |
+
*
|
600 |
+
* See example-logger.php for an example on how to use this.
|
601 |
+
*
|
602 |
+
* @since 2.1
|
603 |
+
*/
|
604 |
+
function register_logger($loggerClassName) {
|
605 |
+
|
606 |
+
$this->externalLoggers[] = $loggerClassName;
|
607 |
+
|
608 |
+
}
|
609 |
+
|
610 |
/**
|
611 |
* Load built in loggers from all files in /loggers
|
612 |
* and instantiates them
|
613 |
*/
|
614 |
+
public function load_loggers() {
|
615 |
|
616 |
$loggersDir = SIMPLE_HISTORY_PATH . "loggers/";
|
617 |
|
618 |
+
$loggersFiles = array(
|
619 |
+
$loggersDir . "SimpleCommentsLogger.php",
|
620 |
+
$loggersDir . "SimpleCoreUpdatesLogger.php",
|
621 |
+
$loggersDir . "SimpleExportLogger.php",
|
622 |
+
$loggersDir . "SimpleLegacyLogger.php",
|
623 |
+
$loggersDir . "SimpleLogger.php",
|
624 |
+
$loggersDir . "SimpleMediaLogger.php",
|
625 |
+
$loggersDir . "SimpleMenuLogger.php",
|
626 |
+
$loggersDir . "SimpleOptionsLogger.php",
|
627 |
+
$loggersDir . "SimplePluginLogger.php",
|
628 |
+
$loggersDir . "SimplePostLogger.php",
|
629 |
+
$loggersDir . "SimpleThemeLogger.php",
|
630 |
+
$loggersDir . "SimpleUserLogger.php",
|
631 |
+
);
|
632 |
+
|
633 |
+
// SimpleLogger.php must be loaded first and always since the other loggers extend it
|
634 |
+
// Include it manually so risk of anyone using filters or similar disables it
|
635 |
include_once $loggersDir . "SimpleLogger.php";
|
636 |
|
637 |
/**
|
638 |
+
* Filter the array with absolute paths to logger files to be loaded.
|
639 |
+
*
|
640 |
* Each file will be loaded and will be assumed to be a logger with a classname
|
641 |
* the same as the filename.
|
642 |
*
|
646 |
*/
|
647 |
$loggersFiles = apply_filters("simple_history/loggers_files", $loggersFiles);
|
648 |
|
649 |
+
// Array with slug of loggers to instantiate
|
650 |
+
// Slug of logger must also be the name of the logger class
|
651 |
$arrLoggersToInstantiate = array();
|
652 |
+
|
653 |
foreach ( $loggersFiles as $oneLoggerFile ) {
|
654 |
|
655 |
$load_logger = true;
|
662 |
* @since 2.0.22
|
663 |
*
|
664 |
* @param bool if to load the logger. return false to not load it.
|
665 |
+
* @param string slug of logger
|
666 |
*/
|
667 |
$load_logger = apply_filters("simple_history/logger/load_logger", $load_logger, $basename_no_suffix );
|
668 |
|
676 |
|
677 |
}
|
678 |
|
679 |
+
/**
|
680 |
+
* Action that plugins should use to add their custom loggers.
|
681 |
+
* See register_logger() for more info.
|
682 |
+
*
|
683 |
+
* @since 2.1
|
684 |
+
*
|
685 |
+
* @param array $arrLoggersToInstantiate Array with class names
|
686 |
+
*/
|
687 |
+
|
688 |
+
do_action("simple_history/add_custom_logger", $this);
|
689 |
+
|
690 |
+
$arrLoggersToInstantiate = array_merge($arrLoggersToInstantiate, $this->externalLoggers);
|
691 |
+
|
692 |
/**
|
693 |
* Filter the array with names of loggers to instantiate.
|
694 |
*
|
695 |
+
* Array
|
696 |
+
* (
|
697 |
+
* [0] => SimpleCommentsLogger
|
698 |
+
* [1] => SimpleCoreUpdatesLogger
|
699 |
+
* ...
|
700 |
+
* )
|
701 |
+
*
|
702 |
* @since 2.0
|
703 |
*
|
704 |
* @param array $arrLoggersToInstantiate Array with class names
|
765 |
* Load built in dropins from all files in /dropins
|
766 |
* and instantiates them
|
767 |
*/
|
768 |
+
public function load_dropins() {
|
769 |
|
770 |
$dropinsDir = SIMPLE_HISTORY_PATH . "dropins/";
|
771 |
|
2511 |
* @param string $alt Alternative text to use in the avatar image tag.
|
2512 |
* Default empty.
|
2513 |
*/
|
2514 |
+
$avatar = apply_filters( 'get_avatar', $avatar, $email, $size, $default, $alt );
|
2515 |
|
2516 |
return $avatar;
|
2517 |
|
inc/SimpleHistoryLogQuery.php
CHANGED
@@ -4,9 +4,9 @@ defined( 'ABSPATH' ) or die();
|
|
4 |
|
5 |
/**
|
6 |
* Queries the Simple History Log
|
7 |
-
*/
|
8 |
class SimpleHistoryLogQuery {
|
9 |
-
|
10 |
public function __construct() {
|
11 |
|
12 |
/*
|
@@ -20,7 +20,7 @@ class SimpleHistoryLogQuery {
|
|
20 |
}
|
21 |
|
22 |
public function query($args) {
|
23 |
-
|
24 |
$defaults = array(
|
25 |
|
26 |
// overview | occasions
|
@@ -44,7 +44,7 @@ class SimpleHistoryLogQuery {
|
|
44 |
|
45 |
// if since_id is set the rows returned will only be rows with an ID greater than (i.e. more recent than) since_id
|
46 |
"since_id" => null,
|
47 |
-
|
48 |
// date range
|
49 |
// in unix datetime or Y-m-d H:i (or format compatible with strtotime())
|
50 |
"date_from" => null,
|
@@ -56,10 +56,10 @@ class SimpleHistoryLogQuery {
|
|
56 |
|
57 |
// search
|
58 |
"search" => null,
|
59 |
-
|
60 |
// log levels to include. comma separated or as array. defaults to all.
|
61 |
"loglevels" => null,
|
62 |
-
|
63 |
// loggers to include. comma separated. defaults to all the user can read
|
64 |
"loggers" => null,
|
65 |
|
@@ -73,6 +73,9 @@ class SimpleHistoryLogQuery {
|
|
73 |
// occasionsCountMaxReturn
|
74 |
// occasionsID
|
75 |
|
|
|
|
|
|
|
76 |
);
|
77 |
|
78 |
$args = wp_parse_args( $args, $defaults );
|
@@ -81,7 +84,7 @@ class SimpleHistoryLogQuery {
|
|
81 |
$cache_key = "SimpleHistoryLogQuery_" . md5(serialize( $args )) . "_get_" . md5(serialize( $_GET )) . "_userid_" . get_current_user_id();
|
82 |
$cache_group = "simple-history-" . SimpleHistory::get_cache_incrementor();
|
83 |
$arr_return = wp_cache_get($cache_key, $cache_group);
|
84 |
-
|
85 |
if ( false !== $arr_return ) {
|
86 |
return $arr_return;
|
87 |
}
|
@@ -120,7 +123,8 @@ class SimpleHistoryLogQuery {
|
|
120 |
// 4 = where for inner calc sql query thingie
|
121 |
// 5 = db name contexts
|
122 |
$sql_tmpl = '
|
123 |
-
|
|
|
124 |
SQL_CALC_FOUND_ROWS
|
125 |
t.id,
|
126 |
t.logger,
|
@@ -135,29 +139,29 @@ class SimpleHistoryLogQuery {
|
|
135 |
t.repeated,
|
136 |
t.occasionsIDType,
|
137 |
c1.value AS context_message_key
|
138 |
-
FROM
|
139 |
(
|
140 |
-
SELECT
|
141 |
-
id,
|
142 |
-
logger,
|
143 |
-
level,
|
144 |
-
message,
|
145 |
type,
|
146 |
initiator,
|
147 |
-
occasionsID,
|
148 |
-
date,
|
149 |
IF(@a=occasionsID,@counter:=@counter+1,@counter:=1) AS rep,
|
150 |
IF(@counter=1,@groupby:=@groupby+1,@groupby) AS repeated,
|
151 |
-
@a:=occasionsID occasionsIDType
|
152 |
FROM %3$s
|
153 |
|
154 |
# Add where here
|
155 |
-
WHERE 1 = 1
|
156 |
%4$s
|
157 |
|
158 |
ORDER BY id DESC
|
159 |
) AS t
|
160 |
-
|
161 |
LEFT OUTER JOIN %5$s AS c1 ON c1.history_id = t.id AND c1.key = "_message_key"
|
162 |
|
163 |
WHERE %1$s
|
@@ -168,7 +172,7 @@ class SimpleHistoryLogQuery {
|
|
168 |
|
169 |
$sh = SimpleHistory::get_instance();
|
170 |
|
171 |
-
// Only include loggers that the current user can view
|
172 |
$sql_loggers_user_can_view = $sh->getLoggersThatUserCanRead(get_current_user_id(), "sql");
|
173 |
$inner_where = " AND logger IN {$sql_loggers_user_can_view}";
|
174 |
|
@@ -209,7 +213,7 @@ class SimpleHistoryLogQuery {
|
|
209 |
// [occasionsCount] => 18
|
210 |
|
211 |
}
|
212 |
-
|
213 |
// Determine limit
|
214 |
// Both posts_per_page and paged must be set
|
215 |
$is_limit_query = ( is_numeric( $args["posts_per_page"] ) && $args["posts_per_page"] > 0 );
|
@@ -229,7 +233,7 @@ class SimpleHistoryLogQuery {
|
|
229 |
// If max_id_first_page is then then only include rows
|
230 |
// with id equal to or earlier
|
231 |
if ( isset($args["max_id_first_page"]) && is_numeric($args["max_id_first_page"]) ) {
|
232 |
-
|
233 |
$max_id_first_page = (int) $args["max_id_first_page"];
|
234 |
$where .= sprintf(
|
235 |
' AND t.id <= %1$d',
|
@@ -239,7 +243,7 @@ class SimpleHistoryLogQuery {
|
|
239 |
}
|
240 |
|
241 |
if ( isset($args["since_id"]) && is_numeric($args["since_id"]) ) {
|
242 |
-
|
243 |
$since_id = (int) $args["since_id"];
|
244 |
/*
|
245 |
$where .= sprintf(
|
@@ -255,9 +259,9 @@ class SimpleHistoryLogQuery {
|
|
255 |
|
256 |
}
|
257 |
|
258 |
-
// Append date where
|
259 |
if ( ! empty( $args["date_from"] ) ) {
|
260 |
-
|
261 |
// date_to=2014-08-01
|
262 |
// if date is not numeric assume Y-m-d H:i-format
|
263 |
$date_from = $args["date_from"];
|
@@ -293,11 +297,11 @@ class SimpleHistoryLogQuery {
|
|
293 |
|
294 |
$sql_months = '
|
295 |
# sql_months
|
296 |
-
AND (
|
297 |
';
|
298 |
|
299 |
foreach ( $arr_months as $one_month ) {
|
300 |
-
|
301 |
// beginning of month
|
302 |
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08") ) . "\n";
|
303 |
// >> 2014-08-01 00:00
|
@@ -307,7 +311,7 @@ class SimpleHistoryLogQuery {
|
|
307 |
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08 + 1 month") ) . "\n";'
|
308 |
// >> 2014-09-01 00:00
|
309 |
$date_month_end = strtotime( "{$one_month} + 1 month" );
|
310 |
-
|
311 |
$sql_months .= sprintf(
|
312 |
'
|
313 |
(
|
@@ -315,8 +319,8 @@ class SimpleHistoryLogQuery {
|
|
315 |
AND UNIX_TIMESTAMP(date) <= %2$d
|
316 |
)
|
317 |
|
318 |
-
OR
|
319 |
-
',
|
320 |
$date_month_beginning, // 1
|
321 |
$date_month_end // 2
|
322 |
|
@@ -339,22 +343,22 @@ class SimpleHistoryLogQuery {
|
|
339 |
|
340 |
// search
|
341 |
if ( ! empty( $args["search"] ) ) {
|
342 |
-
|
343 |
$search_words = $args["search"];
|
344 |
$str_search_conditions = "";
|
345 |
$arr_search_words = preg_split("/[\s,]+/", $search_words);
|
346 |
-
|
347 |
// create array of all searched words
|
348 |
// split both spaces and commas and such
|
349 |
$arr_sql_like_cols = array("message", "logger", "level");
|
350 |
|
351 |
foreach ($arr_sql_like_cols as $one_col) {
|
352 |
-
|
353 |
$str_sql_search_words = "";
|
354 |
|
355 |
|
356 |
foreach ($arr_search_words as $one_search_word) {
|
357 |
-
|
358 |
if ( method_exists($wpdb, "esc_like") ) {
|
359 |
$str_like = esc_sql( $wpdb->esc_like( $one_search_word ) );
|
360 |
} else {
|
@@ -370,7 +374,7 @@ class SimpleHistoryLogQuery {
|
|
370 |
}
|
371 |
|
372 |
$str_sql_search_words = ltrim($str_sql_search_words, ' AND ');
|
373 |
-
|
374 |
$str_search_conditions .= "\n" . sprintf(
|
375 |
' OR ( %1$s ) ',
|
376 |
$str_sql_search_words
|
@@ -411,7 +415,7 @@ class SimpleHistoryLogQuery {
|
|
411 |
// comma separated
|
412 |
// http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&type=overview&format=&posts_per_page=10&paged=1&max_id_first_page=27273&SimpleHistoryLogQuery-showDebug=0&loglevel=error,warn
|
413 |
if ( ! empty( $args["loglevels"] ) ) {
|
414 |
-
|
415 |
$sql_loglevels = "";
|
416 |
|
417 |
if ( is_array( $args["loglevels"] ) ) {
|
@@ -419,7 +423,7 @@ class SimpleHistoryLogQuery {
|
|
419 |
} else {
|
420 |
$arr_loglevels = explode(",", $args["loglevels"]);
|
421 |
}
|
422 |
-
|
423 |
foreach ( $arr_loglevels as $one_loglevel ) {
|
424 |
$sql_loglevels .= sprintf(' "%s", ', esc_sql( $one_loglevel ));
|
425 |
}
|
@@ -430,12 +434,12 @@ class SimpleHistoryLogQuery {
|
|
430 |
}
|
431 |
|
432 |
$inner_where .= $sql_loglevels;
|
433 |
-
|
434 |
}
|
435 |
|
436 |
// messages
|
437 |
if ( ! empty( $args["messages"] ) ) {
|
438 |
-
|
439 |
#print_r($args["messages"]);exit;
|
440 |
/*
|
441 |
Array
|
@@ -444,7 +448,7 @@ class SimpleHistoryLogQuery {
|
|
444 |
[1] => SimpleCommentsLogger:SimpleCommentsLogger:comment_status_spam,SimpleCommentsLogger:trackback_status_spam,SimpleCommentsLogger:pingback_status_spam
|
445 |
)
|
446 |
*/
|
447 |
-
|
448 |
// Array with loggers and messages
|
449 |
$arr_loggers_and_messages = array();
|
450 |
|
@@ -492,7 +496,7 @@ class SimpleHistoryLogQuery {
|
|
492 |
}
|
493 |
// remove last or
|
494 |
$sql_messages_where = preg_replace('/OR $/', "", $sql_messages_where);
|
495 |
-
|
496 |
$sql_messages_where .= "\n )";
|
497 |
#echo $sql_messages_where;exit;
|
498 |
$where .= $sql_messages_where;
|
@@ -548,7 +552,7 @@ class SimpleHistoryLogQuery {
|
|
548 |
// comma separated
|
549 |
// http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&type=overview&format=&posts_per_page=10&paged=1&max_id_first_page=27273&SimpleHistoryLogQuery-showDebug=0&loggers=SimpleCommentsLogger,SimpleCoreUpdatesLogger
|
550 |
if ( ! empty( $args["loggers"] ) ) {
|
551 |
-
|
552 |
$sql_loggers = "";
|
553 |
if ( is_array( $args["loggers"] ) ) {
|
554 |
$arr_loggers = $args["loggers"];
|
@@ -566,7 +570,7 @@ class SimpleHistoryLogQuery {
|
|
566 |
[1] => SimpleUserLogger:user_deleted
|
567 |
)
|
568 |
*/
|
569 |
-
|
570 |
foreach ( $arr_loggers as $one_logger ) {
|
571 |
$sql_loggers .= sprintf(' "%s", ', esc_sql( $one_logger ));
|
572 |
}
|
@@ -577,12 +581,12 @@ class SimpleHistoryLogQuery {
|
|
577 |
}
|
578 |
|
579 |
$inner_where .= $sql_loggers;
|
580 |
-
|
581 |
}
|
582 |
|
583 |
// user, a single userID
|
584 |
if ( ! empty( $args["user"] ) && is_numeric( $args["user"] ) ) {
|
585 |
-
|
586 |
$userID = (int) $args["user"];
|
587 |
$sql_user = sprintf(
|
588 |
'
|
@@ -635,13 +639,13 @@ class SimpleHistoryLogQuery {
|
|
635 |
|
636 |
$sql = sprintf(
|
637 |
$sql_tmpl, // sprintf template
|
638 |
-
$where, // 1
|
639 |
$limit, // 2
|
640 |
$table_name, // 3
|
641 |
$inner_where,// 4
|
642 |
$table_name_contexts // 5
|
643 |
);
|
644 |
-
|
645 |
|
646 |
/**
|
647 |
* Filter the final sql query
|
@@ -663,6 +667,11 @@ class SimpleHistoryLogQuery {
|
|
663 |
|
664 |
}
|
665 |
|
|
|
|
|
|
|
|
|
|
|
666 |
$log_rows = $wpdb->get_results($sql, OBJECT_K);
|
667 |
$num_rows = sizeof($log_rows);
|
668 |
|
@@ -670,7 +679,7 @@ class SimpleHistoryLogQuery {
|
|
670 |
// This is the number of rows with occasions taken into consideration
|
671 |
$sql_found_rows = 'SELECT FOUND_ROWS()';
|
672 |
$total_found_rows = (int) $wpdb->get_var( $sql_found_rows );
|
673 |
-
|
674 |
// Add context
|
675 |
$post_ids = wp_list_pluck( $log_rows, "id" );
|
676 |
|
@@ -710,13 +719,13 @@ class SimpleHistoryLogQuery {
|
|
710 |
$min_id = $last_row->id;
|
711 |
|
712 |
} else {
|
713 |
-
|
714 |
// Last row did have occaions, so fetch all occasions, and find id of last one
|
715 |
$db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
716 |
$sql = sprintf(
|
717 |
'
|
718 |
SELECT id, date, occasionsID
|
719 |
-
FROM %1$s
|
720 |
WHERE id <= %2$s
|
721 |
ORDER BY id DESC
|
722 |
LIMIT %3$s
|
@@ -725,14 +734,14 @@ class SimpleHistoryLogQuery {
|
|
725 |
$last_row->id,
|
726 |
$last_row_occasions_count + 1
|
727 |
);
|
728 |
-
|
729 |
$results = $wpdb->get_results( $sql );
|
730 |
|
731 |
// the last occasion has the id we consider last in this paged result
|
732 |
$min_id = end($results)->id;
|
733 |
|
734 |
}
|
735 |
-
|
736 |
}
|
737 |
|
738 |
// Calc pages
|
@@ -764,8 +773,7 @@ class SimpleHistoryLogQuery {
|
|
764 |
wp_cache_set($cache_key, $arr_return, $cache_group);
|
765 |
|
766 |
return $arr_return;
|
767 |
-
|
768 |
} // query
|
769 |
|
770 |
} // class
|
771 |
-
|
4 |
|
5 |
/**
|
6 |
* Queries the Simple History Log
|
7 |
+
*/
|
8 |
class SimpleHistoryLogQuery {
|
9 |
+
|
10 |
public function __construct() {
|
11 |
|
12 |
/*
|
20 |
}
|
21 |
|
22 |
public function query($args) {
|
23 |
+
|
24 |
$defaults = array(
|
25 |
|
26 |
// overview | occasions
|
44 |
|
45 |
// if since_id is set the rows returned will only be rows with an ID greater than (i.e. more recent than) since_id
|
46 |
"since_id" => null,
|
47 |
+
|
48 |
// date range
|
49 |
// in unix datetime or Y-m-d H:i (or format compatible with strtotime())
|
50 |
"date_from" => null,
|
56 |
|
57 |
// search
|
58 |
"search" => null,
|
59 |
+
|
60 |
// log levels to include. comma separated or as array. defaults to all.
|
61 |
"loglevels" => null,
|
62 |
+
|
63 |
// loggers to include. comma separated. defaults to all the user can read
|
64 |
"loggers" => null,
|
65 |
|
73 |
// occasionsCountMaxReturn
|
74 |
// occasionsID
|
75 |
|
76 |
+
// If rows should be returned, or the actualy sql query used
|
77 |
+
"returnQuery" => false
|
78 |
+
|
79 |
);
|
80 |
|
81 |
$args = wp_parse_args( $args, $defaults );
|
84 |
$cache_key = "SimpleHistoryLogQuery_" . md5(serialize( $args )) . "_get_" . md5(serialize( $_GET )) . "_userid_" . get_current_user_id();
|
85 |
$cache_group = "simple-history-" . SimpleHistory::get_cache_incrementor();
|
86 |
$arr_return = wp_cache_get($cache_key, $cache_group);
|
87 |
+
|
88 |
if ( false !== $arr_return ) {
|
89 |
return $arr_return;
|
90 |
}
|
123 |
// 4 = where for inner calc sql query thingie
|
124 |
// 5 = db name contexts
|
125 |
$sql_tmpl = '
|
126 |
+
/*NO_SELECT_FOUND_ROWS*/
|
127 |
+
SELECT
|
128 |
SQL_CALC_FOUND_ROWS
|
129 |
t.id,
|
130 |
t.logger,
|
139 |
t.repeated,
|
140 |
t.occasionsIDType,
|
141 |
c1.value AS context_message_key
|
142 |
+
FROM
|
143 |
(
|
144 |
+
SELECT
|
145 |
+
id,
|
146 |
+
logger,
|
147 |
+
level,
|
148 |
+
message,
|
149 |
type,
|
150 |
initiator,
|
151 |
+
occasionsID,
|
152 |
+
date,
|
153 |
IF(@a=occasionsID,@counter:=@counter+1,@counter:=1) AS rep,
|
154 |
IF(@counter=1,@groupby:=@groupby+1,@groupby) AS repeated,
|
155 |
+
@a:=occasionsID occasionsIDType
|
156 |
FROM %3$s
|
157 |
|
158 |
# Add where here
|
159 |
+
WHERE 1 = 1
|
160 |
%4$s
|
161 |
|
162 |
ORDER BY id DESC
|
163 |
) AS t
|
164 |
+
|
165 |
LEFT OUTER JOIN %5$s AS c1 ON c1.history_id = t.id AND c1.key = "_message_key"
|
166 |
|
167 |
WHERE %1$s
|
172 |
|
173 |
$sh = SimpleHistory::get_instance();
|
174 |
|
175 |
+
// Only include loggers that the current user can view
|
176 |
$sql_loggers_user_can_view = $sh->getLoggersThatUserCanRead(get_current_user_id(), "sql");
|
177 |
$inner_where = " AND logger IN {$sql_loggers_user_can_view}";
|
178 |
|
213 |
// [occasionsCount] => 18
|
214 |
|
215 |
}
|
216 |
+
|
217 |
// Determine limit
|
218 |
// Both posts_per_page and paged must be set
|
219 |
$is_limit_query = ( is_numeric( $args["posts_per_page"] ) && $args["posts_per_page"] > 0 );
|
233 |
// If max_id_first_page is then then only include rows
|
234 |
// with id equal to or earlier
|
235 |
if ( isset($args["max_id_first_page"]) && is_numeric($args["max_id_first_page"]) ) {
|
236 |
+
|
237 |
$max_id_first_page = (int) $args["max_id_first_page"];
|
238 |
$where .= sprintf(
|
239 |
' AND t.id <= %1$d',
|
243 |
}
|
244 |
|
245 |
if ( isset($args["since_id"]) && is_numeric($args["since_id"]) ) {
|
246 |
+
|
247 |
$since_id = (int) $args["since_id"];
|
248 |
/*
|
249 |
$where .= sprintf(
|
259 |
|
260 |
}
|
261 |
|
262 |
+
// Append date where
|
263 |
if ( ! empty( $args["date_from"] ) ) {
|
264 |
+
|
265 |
// date_to=2014-08-01
|
266 |
// if date is not numeric assume Y-m-d H:i-format
|
267 |
$date_from = $args["date_from"];
|
297 |
|
298 |
$sql_months = '
|
299 |
# sql_months
|
300 |
+
AND (
|
301 |
';
|
302 |
|
303 |
foreach ( $arr_months as $one_month ) {
|
304 |
+
|
305 |
// beginning of month
|
306 |
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08") ) . "\n";
|
307 |
// >> 2014-08-01 00:00
|
311 |
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08 + 1 month") ) . "\n";'
|
312 |
// >> 2014-09-01 00:00
|
313 |
$date_month_end = strtotime( "{$one_month} + 1 month" );
|
314 |
+
|
315 |
$sql_months .= sprintf(
|
316 |
'
|
317 |
(
|
319 |
AND UNIX_TIMESTAMP(date) <= %2$d
|
320 |
)
|
321 |
|
322 |
+
OR
|
323 |
+
',
|
324 |
$date_month_beginning, // 1
|
325 |
$date_month_end // 2
|
326 |
|
343 |
|
344 |
// search
|
345 |
if ( ! empty( $args["search"] ) ) {
|
346 |
+
|
347 |
$search_words = $args["search"];
|
348 |
$str_search_conditions = "";
|
349 |
$arr_search_words = preg_split("/[\s,]+/", $search_words);
|
350 |
+
|
351 |
// create array of all searched words
|
352 |
// split both spaces and commas and such
|
353 |
$arr_sql_like_cols = array("message", "logger", "level");
|
354 |
|
355 |
foreach ($arr_sql_like_cols as $one_col) {
|
356 |
+
|
357 |
$str_sql_search_words = "";
|
358 |
|
359 |
|
360 |
foreach ($arr_search_words as $one_search_word) {
|
361 |
+
|
362 |
if ( method_exists($wpdb, "esc_like") ) {
|
363 |
$str_like = esc_sql( $wpdb->esc_like( $one_search_word ) );
|
364 |
} else {
|
374 |
}
|
375 |
|
376 |
$str_sql_search_words = ltrim($str_sql_search_words, ' AND ');
|
377 |
+
|
378 |
$str_search_conditions .= "\n" . sprintf(
|
379 |
' OR ( %1$s ) ',
|
380 |
$str_sql_search_words
|
415 |
// comma separated
|
416 |
// http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&type=overview&format=&posts_per_page=10&paged=1&max_id_first_page=27273&SimpleHistoryLogQuery-showDebug=0&loglevel=error,warn
|
417 |
if ( ! empty( $args["loglevels"] ) ) {
|
418 |
+
|
419 |
$sql_loglevels = "";
|
420 |
|
421 |
if ( is_array( $args["loglevels"] ) ) {
|
423 |
} else {
|
424 |
$arr_loglevels = explode(",", $args["loglevels"]);
|
425 |
}
|
426 |
+
|
427 |
foreach ( $arr_loglevels as $one_loglevel ) {
|
428 |
$sql_loglevels .= sprintf(' "%s", ', esc_sql( $one_loglevel ));
|
429 |
}
|
434 |
}
|
435 |
|
436 |
$inner_where .= $sql_loglevels;
|
437 |
+
|
438 |
}
|
439 |
|
440 |
// messages
|
441 |
if ( ! empty( $args["messages"] ) ) {
|
442 |
+
|
443 |
#print_r($args["messages"]);exit;
|
444 |
/*
|
445 |
Array
|
448 |
[1] => SimpleCommentsLogger:SimpleCommentsLogger:comment_status_spam,SimpleCommentsLogger:trackback_status_spam,SimpleCommentsLogger:pingback_status_spam
|
449 |
)
|
450 |
*/
|
451 |
+
|
452 |
// Array with loggers and messages
|
453 |
$arr_loggers_and_messages = array();
|
454 |
|
496 |
}
|
497 |
// remove last or
|
498 |
$sql_messages_where = preg_replace('/OR $/', "", $sql_messages_where);
|
499 |
+
|
500 |
$sql_messages_where .= "\n )";
|
501 |
#echo $sql_messages_where;exit;
|
502 |
$where .= $sql_messages_where;
|
552 |
// comma separated
|
553 |
// http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&type=overview&format=&posts_per_page=10&paged=1&max_id_first_page=27273&SimpleHistoryLogQuery-showDebug=0&loggers=SimpleCommentsLogger,SimpleCoreUpdatesLogger
|
554 |
if ( ! empty( $args["loggers"] ) ) {
|
555 |
+
|
556 |
$sql_loggers = "";
|
557 |
if ( is_array( $args["loggers"] ) ) {
|
558 |
$arr_loggers = $args["loggers"];
|
570 |
[1] => SimpleUserLogger:user_deleted
|
571 |
)
|
572 |
*/
|
573 |
+
|
574 |
foreach ( $arr_loggers as $one_logger ) {
|
575 |
$sql_loggers .= sprintf(' "%s", ', esc_sql( $one_logger ));
|
576 |
}
|
581 |
}
|
582 |
|
583 |
$inner_where .= $sql_loggers;
|
584 |
+
|
585 |
}
|
586 |
|
587 |
// user, a single userID
|
588 |
if ( ! empty( $args["user"] ) && is_numeric( $args["user"] ) ) {
|
589 |
+
|
590 |
$userID = (int) $args["user"];
|
591 |
$sql_user = sprintf(
|
592 |
'
|
639 |
|
640 |
$sql = sprintf(
|
641 |
$sql_tmpl, // sprintf template
|
642 |
+
$where, // 1
|
643 |
$limit, // 2
|
644 |
$table_name, // 3
|
645 |
$inner_where,// 4
|
646 |
$table_name_contexts // 5
|
647 |
);
|
648 |
+
|
649 |
|
650 |
/**
|
651 |
* Filter the final sql query
|
667 |
|
668 |
}
|
669 |
|
670 |
+
// Only return sql query
|
671 |
+
if ( $args["returnQuery"] ) {
|
672 |
+
return $sql;
|
673 |
+
}
|
674 |
+
|
675 |
$log_rows = $wpdb->get_results($sql, OBJECT_K);
|
676 |
$num_rows = sizeof($log_rows);
|
677 |
|
679 |
// This is the number of rows with occasions taken into consideration
|
680 |
$sql_found_rows = 'SELECT FOUND_ROWS()';
|
681 |
$total_found_rows = (int) $wpdb->get_var( $sql_found_rows );
|
682 |
+
|
683 |
// Add context
|
684 |
$post_ids = wp_list_pluck( $log_rows, "id" );
|
685 |
|
719 |
$min_id = $last_row->id;
|
720 |
|
721 |
} else {
|
722 |
+
|
723 |
// Last row did have occaions, so fetch all occasions, and find id of last one
|
724 |
$db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
725 |
$sql = sprintf(
|
726 |
'
|
727 |
SELECT id, date, occasionsID
|
728 |
+
FROM %1$s
|
729 |
WHERE id <= %2$s
|
730 |
ORDER BY id DESC
|
731 |
LIMIT %3$s
|
734 |
$last_row->id,
|
735 |
$last_row_occasions_count + 1
|
736 |
);
|
737 |
+
|
738 |
$results = $wpdb->get_results( $sql );
|
739 |
|
740 |
// the last occasion has the id we consider last in this paged result
|
741 |
$min_id = end($results)->id;
|
742 |
|
743 |
}
|
744 |
+
|
745 |
}
|
746 |
|
747 |
// Calc pages
|
773 |
wp_cache_set($cache_key, $arr_return, $cache_group);
|
774 |
|
775 |
return $arr_return;
|
776 |
+
|
777 |
} // query
|
778 |
|
779 |
} // class
|
|
index.php
CHANGED
@@ -2,8 +2,10 @@
|
|
2 |
/*
|
3 |
Plugin Name: Simple History
|
4 |
Plugin URI: http://simple-history.com
|
|
|
|
|
5 |
Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
|
6 |
-
Version: 2.
|
7 |
Author: Pär Thernström
|
8 |
Author URI: http://simple-history.com/
|
9 |
License: GPL2
|
@@ -42,7 +44,7 @@ if ( version_compare( phpversion(), "5.3", ">=") ) {
|
|
42 |
*/
|
43 |
// register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
|
44 |
|
45 |
-
define( 'SIMPLE_HISTORY_VERSION', '2.
|
46 |
|
47 |
define( 'SIMPLE_HISTORY_FILE', __FILE__ );
|
48 |
define( 'SIMPLE_HISTORY_PATH', plugin_dir_path( SIMPLE_HISTORY_FILE ) );
|
2 |
/*
|
3 |
Plugin Name: Simple History
|
4 |
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.1
|
9 |
Author: Pär Thernström
|
10 |
Author URI: http://simple-history.com/
|
11 |
License: GPL2
|
44 |
*/
|
45 |
// register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
|
46 |
|
47 |
+
define( 'SIMPLE_HISTORY_VERSION', '2.1' );
|
48 |
|
49 |
define( 'SIMPLE_HISTORY_FILE', __FILE__ );
|
50 |
define( 'SIMPLE_HISTORY_PATH', plugin_dir_path( SIMPLE_HISTORY_FILE ) );
|
loggers/SimpleLogger.php
CHANGED
@@ -102,7 +102,13 @@ class SimpleLogger {
|
|
102 |
|
103 |
$arr_info = $this->getInfo();
|
104 |
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
}
|
108 |
|
@@ -168,15 +174,23 @@ class SimpleLogger {
|
|
168 |
|
169 |
$user_display_name = $user->display_name;
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
|
175 |
$tmpl_initiator_html = '
|
176 |
<a href="%6$s" class="SimpleHistoryLogitem__headerUserProfileLink">
|
177 |
<strong class="SimpleHistoryLogitem__inlineDivided">%5$s</strong>
|
178 |
</a>
|
179 |
-
'
|
|
|
180 |
} else {
|
181 |
|
182 |
$tmpl_initiator_html = '
|
@@ -274,14 +288,14 @@ class SimpleLogger {
|
|
274 |
|
275 |
// single ip address
|
276 |
$iplookup_link = sprintf('https://ipinfo.io/%1$s', esc_attr($context["_server_remote_addr"]));
|
277 |
-
|
278 |
$initiator_html .= sprintf(
|
279 |
__('Anonymous user from %1$s', "simple-history"),
|
280 |
"<a target='_blank' href={$iplookup_link} class='SimpleHistoryLogitem__anonUserWithIp__theIp'>" . esc_html($context["_server_remote_addr"]) . "</a>"
|
281 |
);
|
282 |
|
283 |
#} // multiple ip
|
284 |
-
|
285 |
$initiator_html .= "</strong> ";
|
286 |
|
287 |
// $initiator_html .= "<strong>" . __("<br><br>Unknown user from {$context["_server_remote_addr"]}") . "</strong>";
|
@@ -294,7 +308,7 @@ class SimpleLogger {
|
|
294 |
break;
|
295 |
|
296 |
case "other":
|
297 |
-
$initiator_html .= "<strong class='SimpleHistoryLogitem__inlineDivided'>Other</strong>";
|
298 |
break;
|
299 |
|
300 |
// no initiator
|
@@ -594,8 +608,8 @@ class SimpleLogger {
|
|
594 |
* return $this->logByMessageKey(SimpleLoggerLogLevels::EMERGENCY, $message, $context);
|
595 |
*/
|
596 |
private function logByMessageKey($SimpleLoggerLogLevelsLevel, $messageKey, $context) {
|
597 |
-
|
598 |
-
// When logging by message then the key must exist
|
599 |
if ( ! isset( $this->messages[ $messageKey ]["untranslated_text"] ) ) {
|
600 |
return;
|
601 |
}
|
@@ -613,7 +627,7 @@ class SimpleLogger {
|
|
613 |
* @return bool false to abort logging
|
614 |
*/
|
615 |
$doLog = apply_filters("simple_history/simple_logger/log_message_key", true, $this->slug, $messageKey, $SimpleLoggerLogLevelsLevel, $context);
|
616 |
-
|
617 |
if ( ! $doLog ) {
|
618 |
return;
|
619 |
}
|
@@ -839,16 +853,16 @@ class SimpleLogger {
|
|
839 |
|
840 |
// Check if $message is a translated message, and if so then fetch original
|
841 |
$sh_latest_translations = $this->simpleHistory->gettextLatestTranslations;
|
842 |
-
|
843 |
if ( ! empty( $sh_latest_translations ) ) {
|
844 |
|
845 |
if ( isset( $sh_latest_translations[ $message ] ) ) {
|
846 |
-
|
847 |
// Translation of this phrase was found, so use original phrase instead of translated one
|
848 |
|
849 |
// Store textdomain since it's required to translate
|
850 |
$context["_gettext_domain"] = $sh_latest_translations[$message]["domain"];
|
851 |
-
|
852 |
// These are good to keep when debugging
|
853 |
// $context["_gettext_org_message"] = $sh_latest_translations[$message]["text"];
|
854 |
// $context["_gettext_translated_message"] = $sh_latest_translations[$message]["translation"];
|
@@ -988,12 +1002,12 @@ class SimpleLogger {
|
|
988 |
|
989 |
// If running as CLI and WP_CLI_PHP_USED is set then it is WP CLI that is doing it
|
990 |
// How to log this? Is this a user, is it WordPress, or what?
|
991 |
-
// I'm thinking:
|
992 |
// - it is a user that is manually doing this, on purpose, with intent, so not auto wordpress
|
993 |
// - it is a specific user, but we don't know who
|
994 |
// - sounds like a special case, set initiator to wp_cli
|
995 |
if ( isset( $_SERVER["WP_CLI_PHP_USED"] ) && "cli" == php_sapi_name() ) {
|
996 |
-
|
997 |
$data["initiator"] = SimpleLoggerLogInitiators::WP_CLI;
|
998 |
|
999 |
}
|
@@ -1128,7 +1142,7 @@ class SimpleLogger {
|
|
1128 |
* @param array $data Array with data used for parent row.
|
1129 |
*/
|
1130 |
$context = apply_filters("simple_history/log_insert_context", $context, $data);
|
1131 |
-
|
1132 |
// Insert all context values into db
|
1133 |
foreach ($context as $key => $value) {
|
1134 |
|
@@ -1161,7 +1175,7 @@ class SimpleLogger {
|
|
1161 |
public function get_ip_number_header_keys() {
|
1162 |
|
1163 |
$arr = array(
|
1164 |
-
'HTTP_CLIENT_IP',
|
1165 |
'HTTP_X_FORWARDED_FOR',
|
1166 |
'HTTP_X_FORWARDED',
|
1167 |
'HTTP_X_CLUSTER_CLIENT_IP',
|
@@ -1185,7 +1199,7 @@ class SimpleLogger {
|
|
1185 |
$context = $row->context;
|
1186 |
|
1187 |
foreach ( $ip_keys as $one_ip_header_key ) {
|
1188 |
-
|
1189 |
$one_ip_header_key_lower = strtolower($one_ip_header_key);
|
1190 |
|
1191 |
foreach ( $context as $context_key => $context_val ) {
|
@@ -1200,7 +1214,7 @@ class SimpleLogger {
|
|
1200 |
} // foreach context key for this ip header key
|
1201 |
|
1202 |
} // foreach ip header key
|
1203 |
-
|
1204 |
return $arr_found_additional_ip_headers;
|
1205 |
|
1206 |
}
|
102 |
|
103 |
$arr_info = $this->getInfo();
|
104 |
|
105 |
+
$capability = "manage_options";
|
106 |
+
|
107 |
+
if ( ! empty( $arr_info["capability"] ) ) {
|
108 |
+
$capability = $arr_info["capability"];
|
109 |
+
}
|
110 |
+
|
111 |
+
return $capability;
|
112 |
|
113 |
}
|
114 |
|
174 |
|
175 |
$user_display_name = $user->display_name;
|
176 |
|
177 |
+
/*
|
178 |
+
* If user who logged this is the currently logged in user
|
179 |
+
* skip name and email and use just "You"
|
180 |
+
*
|
181 |
+
* @param bool If you should be used
|
182 |
+
* @since 2.1
|
183 |
+
*/
|
184 |
+
$use_you = apply_filters("simple_history/header_initiator_use_you", true);
|
185 |
+
|
186 |
+
if ( $use_you && $is_current_user ) {
|
187 |
|
188 |
$tmpl_initiator_html = '
|
189 |
<a href="%6$s" class="SimpleHistoryLogitem__headerUserProfileLink">
|
190 |
<strong class="SimpleHistoryLogitem__inlineDivided">%5$s</strong>
|
191 |
</a>
|
192 |
+
';
|
193 |
+
|
194 |
} else {
|
195 |
|
196 |
$tmpl_initiator_html = '
|
288 |
|
289 |
// single ip address
|
290 |
$iplookup_link = sprintf('https://ipinfo.io/%1$s', esc_attr($context["_server_remote_addr"]));
|
291 |
+
|
292 |
$initiator_html .= sprintf(
|
293 |
__('Anonymous user from %1$s', "simple-history"),
|
294 |
"<a target='_blank' href={$iplookup_link} class='SimpleHistoryLogitem__anonUserWithIp__theIp'>" . esc_html($context["_server_remote_addr"]) . "</a>"
|
295 |
);
|
296 |
|
297 |
#} // multiple ip
|
298 |
+
|
299 |
$initiator_html .= "</strong> ";
|
300 |
|
301 |
// $initiator_html .= "<strong>" . __("<br><br>Unknown user from {$context["_server_remote_addr"]}") . "</strong>";
|
308 |
break;
|
309 |
|
310 |
case "other":
|
311 |
+
$initiator_html .= "<strong class='SimpleHistoryLogitem__inlineDivided'>" . _x("Other", "Event header output, when initiator is unknown", "simple-history") . "</strong>";
|
312 |
break;
|
313 |
|
314 |
// no initiator
|
608 |
* return $this->logByMessageKey(SimpleLoggerLogLevels::EMERGENCY, $message, $context);
|
609 |
*/
|
610 |
private function logByMessageKey($SimpleLoggerLogLevelsLevel, $messageKey, $context) {
|
611 |
+
|
612 |
+
// When logging by message then the key must exist
|
613 |
if ( ! isset( $this->messages[ $messageKey ]["untranslated_text"] ) ) {
|
614 |
return;
|
615 |
}
|
627 |
* @return bool false to abort logging
|
628 |
*/
|
629 |
$doLog = apply_filters("simple_history/simple_logger/log_message_key", true, $this->slug, $messageKey, $SimpleLoggerLogLevelsLevel, $context);
|
630 |
+
|
631 |
if ( ! $doLog ) {
|
632 |
return;
|
633 |
}
|
853 |
|
854 |
// Check if $message is a translated message, and if so then fetch original
|
855 |
$sh_latest_translations = $this->simpleHistory->gettextLatestTranslations;
|
856 |
+
|
857 |
if ( ! empty( $sh_latest_translations ) ) {
|
858 |
|
859 |
if ( isset( $sh_latest_translations[ $message ] ) ) {
|
860 |
+
|
861 |
// Translation of this phrase was found, so use original phrase instead of translated one
|
862 |
|
863 |
// Store textdomain since it's required to translate
|
864 |
$context["_gettext_domain"] = $sh_latest_translations[$message]["domain"];
|
865 |
+
|
866 |
// These are good to keep when debugging
|
867 |
// $context["_gettext_org_message"] = $sh_latest_translations[$message]["text"];
|
868 |
// $context["_gettext_translated_message"] = $sh_latest_translations[$message]["translation"];
|
1002 |
|
1003 |
// If running as CLI and WP_CLI_PHP_USED is set then it is WP CLI that is doing it
|
1004 |
// How to log this? Is this a user, is it WordPress, or what?
|
1005 |
+
// I'm thinking:
|
1006 |
// - it is a user that is manually doing this, on purpose, with intent, so not auto wordpress
|
1007 |
// - it is a specific user, but we don't know who
|
1008 |
// - sounds like a special case, set initiator to wp_cli
|
1009 |
if ( isset( $_SERVER["WP_CLI_PHP_USED"] ) && "cli" == php_sapi_name() ) {
|
1010 |
+
|
1011 |
$data["initiator"] = SimpleLoggerLogInitiators::WP_CLI;
|
1012 |
|
1013 |
}
|
1142 |
* @param array $data Array with data used for parent row.
|
1143 |
*/
|
1144 |
$context = apply_filters("simple_history/log_insert_context", $context, $data);
|
1145 |
+
|
1146 |
// Insert all context values into db
|
1147 |
foreach ($context as $key => $value) {
|
1148 |
|
1175 |
public function get_ip_number_header_keys() {
|
1176 |
|
1177 |
$arr = array(
|
1178 |
+
'HTTP_CLIENT_IP',
|
1179 |
'HTTP_X_FORWARDED_FOR',
|
1180 |
'HTTP_X_FORWARDED',
|
1181 |
'HTTP_X_CLUSTER_CLIENT_IP',
|
1199 |
$context = $row->context;
|
1200 |
|
1201 |
foreach ( $ip_keys as $one_ip_header_key ) {
|
1202 |
+
|
1203 |
$one_ip_header_key_lower = strtolower($one_ip_header_key);
|
1204 |
|
1205 |
foreach ( $context as $context_key => $context_val ) {
|
1214 |
} // foreach context key for this ip header key
|
1215 |
|
1216 |
} // foreach ip header key
|
1217 |
+
|
1218 |
return $arr_found_additional_ip_headers;
|
1219 |
|
1220 |
}
|
loggers/SimpleMediaLogger.php
CHANGED
@@ -199,7 +199,7 @@ class SimpleMediaLogger extends SimpleLogger
|
|
199 |
|
200 |
$context["full_image_width"] = $full_image_width;
|
201 |
$context["full_image_height"] = $full_image_height;
|
202 |
-
$context["attachment_thumb"] = sprintf('<div class="SimpleHistoryLogitemThumbnail"><img src="%1$s"></div>', $thumb_src[0] );
|
203 |
|
204 |
}
|
205 |
|
@@ -340,7 +340,7 @@ class SimpleMediaLogger extends SimpleLogger
|
|
340 |
|
341 |
/**
|
342 |
* Modify RSS links so they go directly to the correct media in wp admin
|
343 |
-
*
|
344 |
* @since 2.0.23
|
345 |
* @param string $link
|
346 |
* @param array $row
|
@@ -354,7 +354,7 @@ class SimpleMediaLogger extends SimpleLogger
|
|
354 |
if ( isset( $row->context["attachment_id"] ) ) {
|
355 |
|
356 |
$permalink = add_query_arg(array("action" => "edit", "post" => $row->context["attachment_id"]), admin_url( "post.php" ) );
|
357 |
-
|
358 |
if ( $permalink ) {
|
359 |
$link = $permalink;
|
360 |
}
|
199 |
|
200 |
$context["full_image_width"] = $full_image_width;
|
201 |
$context["full_image_height"] = $full_image_height;
|
202 |
+
$context["attachment_thumb"] = sprintf('<div class="SimpleHistoryLogitemThumbnail"><img src="%1$s" alt=""></div>', $thumb_src[0] );
|
203 |
|
204 |
}
|
205 |
|
340 |
|
341 |
/**
|
342 |
* Modify RSS links so they go directly to the correct media in wp admin
|
343 |
+
*
|
344 |
* @since 2.0.23
|
345 |
* @param string $link
|
346 |
* @param array $row
|
354 |
if ( isset( $row->context["attachment_id"] ) ) {
|
355 |
|
356 |
$permalink = add_query_arg(array("action" => "edit", "post" => $row->context["attachment_id"]), admin_url( "post.php" ) );
|
357 |
+
|
358 |
if ( $permalink ) {
|
359 |
$link = $permalink;
|
360 |
}
|
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, cms, dashboard, admin, syslog, feed, activity, stream
|
5 |
Requires at least: 3.6.0
|
6 |
-
Tested up to: 4.2.
|
7 |
-
Stable tag: 2.
|
8 |
|
9 |
View changes made by users within WordPress. See who created a page, uploaded an attachment or approved an comment, and more.
|
10 |
|
@@ -116,11 +116,22 @@ initiated by a specific user.
|
|
116 |
|
117 |
## Changelog
|
118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
= 2.0.30 (May 2015) =
|
120 |
|
121 |
- Added: Username of logged events now link to that user's profile.
|
122 |
- Fixed: When expanding ocassions the first loaded occasion was the same event as the one you expanded from, and the last ocassion was missing. Looked extra stupid when only 1 occasion existed, and you clicked "show ocassions" only to just find the same event again. So stupid. But fixed now!
|
123 |
-
- Fixed: If an event had many similar events the list of similar events could freeze the browser. ([17948 failed login attempts overnight](https://twitter.com/eskapism/status/595478847598002176) is not that uncommon it turns out!
|
124 |
- Fixed: Some loggers were missing the "All"-message in the search.
|
125 |
- Changed: Hide some more keys and values by default in the context data popup.
|
126 |
- Changed: Use `truncate` instead of `delete` when clearing the database. Works much faster on large logs.
|
3 |
Donate link: http://eskapism.se/sida/donate/
|
4 |
Tags: history, log, changes, changelog, audit, trail, pages, attachments, users, cms, dashboard, admin, syslog, feed, activity, stream
|
5 |
Requires at least: 3.6.0
|
6 |
+
Tested up to: 4.2.2
|
7 |
+
Stable tag: 2.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 |
|
116 |
|
117 |
## Changelog
|
118 |
|
119 |
+
= 2.1 (May 2015) =
|
120 |
+
|
121 |
+
- Added: Export! Now it's possible to export the events log to a JSON or CSV formatted file. It's your data so you should be able to export it any time you want or need. And now you can do that. You will find the export function in the Simple History settings page (Settings -> Simple History).
|
122 |
+
- Added: Filter `simple_history/add_custom_logger` and function `register_logger` that together are used to load external custom loggers. See [example-logger.php](https://github.com/bonny/WordPress-Simple-History/blob/master/examples/example-logger.php) for usage example.
|
123 |
+
- Added: Filter `simple_history/header_initiator_use_you`.
|
124 |
+
- Fixed: Fixed an undefined variable in get_avatar(). Fixes https://github.com/bonny/WordPress-Simple-History/issues/74.
|
125 |
+
- Fixed: When using [HyperDB](https://wordpress.org/support/plugin/hyperdb) only one event was returned. Fixed by using [adding `NO_SELECT_FOUND_ROWS` to the query](https://plugins.trac.wordpress.org/browser/hyperdb/trunk/db.php?#L49). Should fix problems for users using HyperDB and also users using for example [wpengine.com](http://wpengine.com) (that probably also is using HyperDB or a similar approach).
|
126 |
+
- Changed: Loggers now get default capability "manage_options" if they have no capability set.
|
127 |
+
- Changed: Misc internal cleanup.
|
128 |
+
- Removed: filter `simple_history/loggers_dir` removed, because loggers are loaded from array instead of file listing generated from `glob()`. Should be (however to the eye non-noticable) faster.
|
129 |
+
|
130 |
= 2.0.30 (May 2015) =
|
131 |
|
132 |
- Added: Username of logged events now link to that user's profile.
|
133 |
- Fixed: When expanding ocassions the first loaded occasion was the same event as the one you expanded from, and the last ocassion was missing. Looked extra stupid when only 1 occasion existed, and you clicked "show ocassions" only to just find the same event again. So stupid. But fixed now!
|
134 |
+
- Fixed: If an event had many similar events the list of similar events could freeze the browser. ([17948 failed login attempts overnight](https://twitter.com/eskapism/status/595478847598002176) is not that uncommon it turns out!)
|
135 |
- Fixed: Some loggers were missing the "All"-message in the search.
|
136 |
- Changed: Hide some more keys and values by default in the context data popup.
|
137 |
- Changed: Use `truncate` instead of `delete` when clearing the database. Works much faster on large logs.
|
templates/settings-statsForGeeks.php
CHANGED
@@ -174,7 +174,7 @@ echo "<p class='hide-if-no-js'><button class='button js-SimpleHistoryShowsStatsF
|
|
174 |
$one_logger_slug,
|
175 |
esc_html( $logger_info["name"]),
|
176 |
esc_html( $logger_info["description"]), // 4
|
177 |
-
esc_html( $
|
178 |
$loopnum % 2 ? " alt " : "", // 6
|
179 |
$html_logger_messages // 7
|
180 |
);
|
174 |
$one_logger_slug,
|
175 |
esc_html( $logger_info["name"]),
|
176 |
esc_html( $logger_info["description"]), // 4
|
177 |
+
esc_html( $logger->getCapability() ),
|
178 |
$loopnum % 2 ? " alt " : "", // 6
|
179 |
$html_logger_messages // 7
|
180 |
);
|