Version Description
(August 2019) =
- Fix error in Beaver Builder logger. Fixes https://wordpress.org/support/topic/conflict-with-beaver-builder-plugin-4/.
- Add filter
simple_history/admin_location
that makes is possible to move the main page from the dashboard menu to any other menu page, for example the Tools menu. Fixes https://github.com/bonny/WordPress-Simple-History/issues/140. Example usage of filter:
// Move Simple History log sub page from the "Dashboard" menu to the "Tools" menu.
add_filter('simple_history/admin_location', function ($location) {
$location
Download this release
Release Info
Developer | eskapism |
Plugin | Simple History |
Version | 2.32 |
Comparing to | |
See all releases |
Code changes from version 2.31.1 to 2.32
- README.md +0 -1
- code.md +9 -7
- composer.json +1 -1
- css/styles.css +5 -5
- dropins/SimpleHistoryDebugDropin.php +61 -0
- dropins/SimpleHistoryDonateDropin.php +69 -70
- dropins/SimpleHistoryExportDropin.php +209 -231
- dropins/SimpleHistoryFilterDropin.php +564 -574
- dropins/SimpleHistoryIpInfoDropin.php +166 -165
- dropins/SimpleHistoryNewRowsNotifier.php +64 -66
- dropins/SimpleHistoryPluginPatchesDropin.php +160 -160
- dropins/SimpleHistoryRSSDropin.php +398 -384
- dropins/SimpleHistorySettingsDebugDropin.php +26 -25
- dropins/SimpleHistorySettingsLogtestDropin.php +267 -263
- dropins/SimpleHistorySettingsStatsDropin.php +75 -77
- dropins/SimpleHistorySidebarDropin.php +161 -160
- dropins/SimpleHistorySidebarSettings.php +81 -81
- dropins/SimpleHistorySidebarStats.php +191 -194
- dropins/SimpleHistoryWPCLIDropin.php +156 -155
- examples/example-dropin.php +31 -32
- examples/example-logger.php +76 -77
- examples/examples.php +174 -189
- inc/SimpleHistory.php +3239 -4169
- inc/SimpleHistoryLogQuery.php +654 -707
- inc/helpers.php +219 -0
- index.php +36 -33
- loggers/AvailableUpdatesLogger.php +294 -303
- loggers/FileEditsLogger.php +248 -250
- loggers/PluginEnableMediaReplaceLogger.php +94 -95
- loggers/PluginUserSwitchingLogger.php +130 -134
- loggers/Plugin_ACF.php +1041 -1026
- loggers/Plugin_BeaverBuilder.php +94 -75
- loggers/Plugin_DuplicatePost.php +121 -116
- loggers/Plugin_LimitLoginAttempts.php +224 -234
- loggers/Plugin_Redirection.php +387 -376
- loggers/Plugin_UltimateMembers_Logger.php +47 -46
- loggers/SimpleCategoriesLogger.php +316 -291
- loggers/SimpleCommentsLogger.php +744 -763
- loggers/SimpleCoreUpdatesLogger.php +109 -108
- loggers/SimpleExportLogger.php +68 -68
- loggers/SimpleLegacyLogger.php +77 -79
- loggers/SimpleLogger.php +18 -26
- loggers/SimpleMediaLogger.php +344 -367
- loggers/SimpleMenuLogger.php +370 -371
- loggers/SimpleOptionsLogger.php +441 -475
- loggers/SimplePluginLogger.php +1117 -1153
- loggers/SimplePostLogger.php +190 -1243
README.md
CHANGED
@@ -65,7 +65,6 @@ SimpleLogger()->info("This is a message sent to the log");
|
|
65 |
SimpleLogger()->info("User admin edited page 'About our company'");
|
66 |
SimpleLogger()->warning("User 'Jessie' deleted user 'Kim'");
|
67 |
SimpleLogger()->debug("Ok, cron job is running!");
|
68 |
-
|
69 |
```
|
70 |
|
71 |
You will find more examples in the [examples.php](https://github.com/bonny/WordPress-Simple-History/blob/master/examples/examples.php) file.
|
65 |
SimpleLogger()->info("User admin edited page 'About our company'");
|
66 |
SimpleLogger()->warning("User 'Jessie' deleted user 'Kim'");
|
67 |
SimpleLogger()->debug("Ok, cron job is running!");
|
|
|
68 |
```
|
69 |
|
70 |
You will find more examples in the [examples.php](https://github.com/bonny/WordPress-Simple-History/blob/master/examples/examples.php) file.
|
code.md
CHANGED
@@ -1,10 +1,14 @@
|
|
|
|
1 |
|
2 |
-
|
|
|
3 |
|
4 |
-
- Formatting:
|
5 |
-
|
6 |
-
|
7 |
-
|
|
|
|
|
8 |
|
9 |
## How to use php codesniffer
|
10 |
|
@@ -15,5 +19,3 @@ List errors and warnings:
|
|
15 |
Fix things:
|
16 |
|
17 |
$ phpcbf /path/to/code
|
18 |
-
|
19 |
-
|
1 |
+
Since I always forget what standards I use in different projects this file is here to remind me about the standards I use in this project:
|
2 |
|
3 |
+
- PHP coding standard: PSR2 because that's the standard that I use in other projects.
|
4 |
+
`phpcs.xml.dist` is the config used.
|
5 |
|
6 |
+
- Formatting:
|
7 |
+
phpcbf to fix errors and warning.
|
8 |
+
Then sometimes Prettier, but befare it's not 100 % stable yet for PHP files.
|
9 |
+
|
10 |
+
- phpcs to lint while editing. Lots of code is old but working but was written
|
11 |
+
before my editor had nice linting, so much of the code does not lint. This will be fixed.
|
12 |
|
13 |
## How to use php codesniffer
|
14 |
|
19 |
Fix things:
|
20 |
|
21 |
$ phpcbf /path/to/code
|
|
|
|
composer.json
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
"require": {
|
15 |
"php": ">=5.3.0"
|
16 |
},
|
17 |
-
"version": "2.
|
18 |
"authors": [
|
19 |
{
|
20 |
"name": "Pär Thernström",
|
14 |
"require": {
|
15 |
"php": ">=5.3.0"
|
16 |
},
|
17 |
+
"version": "2.32",
|
18 |
"authors": [
|
19 |
{
|
20 |
"name": "Pär Thernström",
|
css/styles.css
CHANGED
@@ -39,7 +39,7 @@ The spinner that wp uses:;
|
|
39 |
|
40 |
/* on its own page */
|
41 |
/*.dashboard_page_simple_history_page .SimpleHistoryLogitemsWrap {*/
|
42 |
-
.
|
43 |
/*float: left;*/
|
44 |
position: relative;
|
45 |
margin-right: 340px;
|
@@ -47,21 +47,21 @@ The spinner that wp uses:;
|
|
47 |
background-color: rgba(255,255,255,.75);
|
48 |
}
|
49 |
|
50 |
-
.SimpleHistory--isLoaded
|
51 |
background-color: transparent;
|
52 |
}
|
53 |
|
54 |
-
.
|
55 |
width: 100%;
|
56 |
float: left;
|
57 |
}
|
58 |
|
59 |
@media only screen and (max-width: 850px) {
|
60 |
-
.
|
61 |
float: none;
|
62 |
margin-right: auto;
|
63 |
}
|
64 |
-
.
|
65 |
float: none;
|
66 |
}
|
67 |
}
|
39 |
|
40 |
/* on its own page */
|
41 |
/*.dashboard_page_simple_history_page .SimpleHistoryLogitemsWrap {*/
|
42 |
+
.SimpleHistoryGuiWrap {
|
43 |
/*float: left;*/
|
44 |
position: relative;
|
45 |
margin-right: 340px;
|
47 |
background-color: rgba(255,255,255,.75);
|
48 |
}
|
49 |
|
50 |
+
.SimpleHistory--isLoaded .SimpleHistoryGuiWrap {
|
51 |
background-color: transparent;
|
52 |
}
|
53 |
|
54 |
+
.SimpleHistoryGui {
|
55 |
width: 100%;
|
56 |
float: left;
|
57 |
}
|
58 |
|
59 |
@media only screen and (max-width: 850px) {
|
60 |
+
.SimpleHistoryGuiWrap {
|
61 |
float: none;
|
62 |
margin-right: auto;
|
63 |
}
|
64 |
+
.SimpleHistoryGui {
|
65 |
float: none;
|
66 |
}
|
67 |
}
|
dropins/SimpleHistoryDebugDropin.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
defined('ABSPATH') or die();
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Dropin Name: Debug
|
7 |
+
* Dropin Description: Add some extra info to each logged context when SIMPLE_HISTORY_LOG_DEBUG is set and true
|
8 |
+
* Dropin URI: http://simple-history.com/
|
9 |
+
* Author: Pär Thernström
|
10 |
+
*/
|
11 |
+
class SimpleHistoryDebugDropin
|
12 |
+
{
|
13 |
+
public function __construct($sh)
|
14 |
+
{
|
15 |
+
// Bail if Simple History debug mode is not active.
|
16 |
+
if (!defined('SIMPLE_HISTORY_LOG_DEBUG') || !SIMPLE_HISTORY_LOG_DEBUG) {
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
|
20 |
+
add_action('simple_history/log_argument/context', [$this, 'onLogArgumentContext'], 10, 4);
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Modify the context to add debug information.
|
25 |
+
*
|
26 |
+
* @param array $context
|
27 |
+
* @param string $level
|
28 |
+
* @param string $message
|
29 |
+
* @param SimpleLogger $logger
|
30 |
+
*/
|
31 |
+
public function onLogArgumentContext(array $context, string $level, string $message, SimpleLogger $logger)
|
32 |
+
{
|
33 |
+
$sh = SimpleHistory::get_instance();
|
34 |
+
$context['_debug_get'] = $sh->json_encode($_GET);
|
35 |
+
$context['_debug_post'] = $sh->json_encode($_POST);
|
36 |
+
$context['_debug_server'] = $sh->json_encode($_SERVER);
|
37 |
+
$context['_debug_files'] = $sh->json_encode($_FILES);
|
38 |
+
$context['_debug_php_sapi_name'] = php_sapi_name();
|
39 |
+
|
40 |
+
global $argv;
|
41 |
+
$context['_debug_argv'] = $sh->json_encode($argv);
|
42 |
+
|
43 |
+
$consts = get_defined_constants(true);
|
44 |
+
$consts = $consts['user'];
|
45 |
+
$context['_debug_user_constants'] = $sh->json_encode($consts);
|
46 |
+
|
47 |
+
$postdata = file_get_contents('php://input');
|
48 |
+
$context['_debug_http_raw_post_data'] = $sh->json_encode($postdata);
|
49 |
+
|
50 |
+
$context['_debug_wp_debug_backtrace_summary'] = wp_debug_backtrace_summary();
|
51 |
+
$context['_debug_is_admin'] = json_encode(is_admin());
|
52 |
+
$context['_debug_is_ajax'] = json_encode(defined('DOING_AJAX') && DOING_AJAX);
|
53 |
+
$context['_debug_is_doing_cron'] = json_encode(defined('DOING_CRON') && DOING_CRON);
|
54 |
+
|
55 |
+
global $wp_current_filter;
|
56 |
+
$context['_debug_current_filter_array'] = $wp_current_filter;
|
57 |
+
$context['_debug_current_filter'] = current_filter();
|
58 |
+
|
59 |
+
return $context;
|
60 |
+
}
|
61 |
+
}
|
dropins/SimpleHistoryDonateDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Donate things
|
@@ -12,73 +12,72 @@ Author: Pär Thernström
|
|
12 |
* Simple History Donate dropin
|
13 |
* Put some donate messages here and there
|
14 |
*/
|
15 |
-
class SimpleHistoryDonateDropin
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Donate things
|
12 |
* Simple History Donate dropin
|
13 |
* Put some donate messages here and there
|
14 |
*/
|
15 |
+
class SimpleHistoryDonateDropin
|
16 |
+
{
|
17 |
+
|
18 |
+
// Simple History instance
|
19 |
+
private $sh;
|
20 |
+
|
21 |
+
function __construct($sh)
|
22 |
+
{
|
23 |
+
|
24 |
+
$this->sh = $sh;
|
25 |
+
add_action('admin_menu', array( $this, 'add_settings' ), 50);
|
26 |
+
add_action('plugin_row_meta', array( $this, 'action_plugin_row_meta' ), 10, 2);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Add link to the donate page in the Plugins » Installed plugins screen
|
31 |
+
* Called from filter 'plugin_row_meta'
|
32 |
+
*/
|
33 |
+
function action_plugin_row_meta($links, $file)
|
34 |
+
{
|
35 |
+
|
36 |
+
if ($file == $this->sh->plugin_basename) {
|
37 |
+
$links = array_merge(
|
38 |
+
$links,
|
39 |
+
array( sprintf('<a href="https://www.paypal.me/eskapism">%1$s</a>', __('Donate', "simple-history")) )
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
return $links;
|
44 |
+
}
|
45 |
+
|
46 |
+
public function add_settings()
|
47 |
+
{
|
48 |
+
|
49 |
+
$settings_section_id = 'simple_history_settings_section_donate';
|
50 |
+
|
51 |
+
add_settings_section(
|
52 |
+
$settings_section_id,
|
53 |
+
_x('Donate', 'donate settings headline', 'simple-history'), // No title __("General", "simple-history"),
|
54 |
+
array( $this, 'settings_section_output' ),
|
55 |
+
SimpleHistory::SETTINGS_MENU_SLUG // same slug as for options menu page
|
56 |
+
);
|
57 |
+
|
58 |
+
// Empty section to make more room below
|
59 |
+
/*
|
60 |
+
add_settings_field(
|
61 |
+
"simple_history_settings_donate",
|
62 |
+
"", // __("Donate", "simple-history"),
|
63 |
+
array($this, "settings_field_donate"),
|
64 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
65 |
+
$settings_section_id
|
66 |
+
);
|
67 |
+
*/
|
68 |
+
}
|
69 |
+
|
70 |
+
function settings_section_output()
|
71 |
+
{
|
72 |
+
|
73 |
+
printf(
|
74 |
+
__('If you find Simple History useful please <a href="%1$s">donate</a>.', "simple-history"),
|
75 |
+
'https://www.paypal.me/eskapism'
|
76 |
+
);
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
function settings_field_donate()
|
81 |
+
{
|
82 |
+
}
|
|
|
83 |
}
|
dropins/SimpleHistoryExportDropin.php
CHANGED
@@ -6,269 +6,247 @@
|
|
6 |
* Dropin URI: http://simple-history.com/
|
7 |
* Author: Pär Thernström
|
8 |
*/
|
9 |
-
class SimpleHistoryExportDropin
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
$json_row = '[';
|
99 |
-
fwrite( $fp, $json_row );
|
100 |
-
|
101 |
-
} elseif ( 'html' == $export_format ) {
|
102 |
-
|
103 |
-
$html = sprintf(
|
104 |
-
'
|
105 |
<!doctype html>
|
106 |
<meta charset="utf-8">
|
107 |
<title>Simple History export</title>
|
108 |
<ul>
|
109 |
-
'
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
$json_row = $comma . $this->sh->json_encode( $one_row );
|
157 |
-
fwrite( $fp, $json_row );
|
158 |
-
|
159 |
-
} elseif ( 'html' == $export_format ) {
|
160 |
-
|
161 |
-
$html = sprintf(
|
162 |
-
'
|
163 |
<li>
|
164 |
<div>%1$s</div>
|
165 |
<div>%2$s</div>
|
166 |
<div>%3$s</div>
|
167 |
</li>
|
168 |
',
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
fwrite( $fp, $html );
|
175 |
-
|
176 |
-
}// End if().
|
177 |
-
|
178 |
-
$row_loop++;
|
179 |
-
|
180 |
-
}// End foreach().
|
181 |
-
|
182 |
-
// echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
183 |
-
// echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
184 |
-
// echo "<br>fetch next page";
|
185 |
-
flush();
|
186 |
-
|
187 |
-
// Fetch next page
|
188 |
-
// @TODO: must take into consideration that new items can be added while we do the fetch
|
189 |
-
$page_current++;
|
190 |
-
$query_args['paged'] = $page_current;
|
191 |
-
$events = $query->query( $query_args );
|
192 |
-
|
193 |
-
// echo "<br>did fetch next page";
|
194 |
-
// echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
195 |
-
// echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
196 |
-
}// End while().
|
197 |
-
|
198 |
-
if ( 'json' == $export_format ) {
|
199 |
-
|
200 |
-
$json_row = ']';
|
201 |
-
fwrite( $fp, $json_row );
|
202 |
|
203 |
-
|
|
|
204 |
|
205 |
-
|
206 |
-
|
207 |
|
208 |
-
|
|
|
|
|
|
|
209 |
|
210 |
-
|
211 |
-
|
|
|
|
|
|
|
212 |
|
213 |
-
|
|
|
|
|
|
|
214 |
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
217 |
|
218 |
-
|
|
|
219 |
|
|
|
220 |
|
221 |
-
|
|
|
|
|
222 |
|
223 |
-
?>
|
224 |
-
<!-- <h2>Export</h2> -->
|
225 |
|
226 |
-
|
|
|
227 |
|
228 |
-
|
|
|
229 |
|
230 |
-
|
231 |
|
232 |
-
|
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 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
247 |
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
|
|
253 |
|
254 |
-
|
255 |
-
<input type="radio" name="format" value="xml">
|
256 |
-
XML
|
257 |
-
</label> -->
|
258 |
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
|
|
263 |
|
264 |
-
|
265 |
-
|
266 |
-
|
|
|
267 |
|
268 |
-
|
|
|
|
|
|
|
269 |
|
270 |
-
|
|
|
|
|
271 |
|
272 |
-
|
273 |
|
|
|
|
|
274 |
}
|
6 |
* Dropin URI: http://simple-history.com/
|
7 |
* Author: Pär Thernström
|
8 |
*/
|
9 |
+
class SimpleHistoryExportDropin
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Simple History instance.
|
14 |
+
*
|
15 |
+
* @var $sh
|
16 |
+
*/
|
17 |
+
private $sh;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Constructor.
|
21 |
+
*
|
22 |
+
* @param instance $sh Simple History instance.
|
23 |
+
*/
|
24 |
+
public function __construct($sh)
|
25 |
+
{
|
26 |
+
|
27 |
+
$this->sh = $sh;
|
28 |
+
|
29 |
+
// Add tab to settings page.
|
30 |
+
$sh->registerSettingsTab(array(
|
31 |
+
'slug' => 'export',
|
32 |
+
'name' => _x('Export', 'Export dropin: Tab name on settings page', 'simple-history'),
|
33 |
+
'function' => array( $this, 'output' ),
|
34 |
+
));
|
35 |
+
|
36 |
+
add_action('init', array( $this, 'downloadExport' ));
|
37 |
+
}
|
38 |
+
|
39 |
+
public function downloadExport()
|
40 |
+
{
|
41 |
+
|
42 |
+
global $wpdb;
|
43 |
+
|
44 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
45 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
46 |
+
|
47 |
+
if (isset($_POST['simple-history-action']) && $_POST['simple-history-action'] === 'export-history') {
|
48 |
+
// Will die if nonce not valid
|
49 |
+
check_admin_referer(__CLASS__ . '-action-export');
|
50 |
+
|
51 |
+
$export_format = isset($_POST['format']) ? $_POST['format'] : 'json';
|
52 |
+
|
53 |
+
// Disable relative time output in header
|
54 |
+
add_filter('simple_history/header_time_ago_max_time', '__return_zero');
|
55 |
+
add_filter('simple_history/header_just_now_max_time', '__return_zero');
|
56 |
+
|
57 |
+
// Don't use "You" if event is initiated by the same user that does the export
|
58 |
+
add_filter('simple_history/header_initiator_use_you', '__return_false');
|
59 |
+
|
60 |
+
$query = new SimpleHistoryLogQuery();
|
61 |
+
|
62 |
+
$query_args = array(
|
63 |
+
'paged' => 1,
|
64 |
+
'posts_per_page' => 3000,
|
65 |
+
);
|
66 |
+
|
67 |
+
$events = $query->query($query_args);
|
68 |
+
|
69 |
+
// $events->total_row_count;
|
70 |
+
$pages_count = $events['pages_count'];
|
71 |
+
$page_current = $events['page_current'];
|
72 |
+
|
73 |
+
$fp = fopen('php://output', 'w');
|
74 |
+
|
75 |
+
$attachment_header_template = 'Content-Disposition: attachment; filename="%1$s"';
|
76 |
+
|
77 |
+
if ('csv' == $export_format) {
|
78 |
+
$filename = 'simple-history-export-' . time() . '.csv';
|
79 |
+
header('Content-Type: text/plain');
|
80 |
+
header(sprintf($attachment_header_template, $filename));
|
81 |
+
} elseif ('json' == $export_format) {
|
82 |
+
$filename = 'simple-history-export-' . time() . '.json';
|
83 |
+
header('Content-Type: application/json');
|
84 |
+
header(sprintf($attachment_header_template, $filename));
|
85 |
+
} elseif ('html' == $export_format) {
|
86 |
+
$filename = 'simple-history-export-' . time() . '.html';
|
87 |
+
header('Content-Type: text/html');
|
88 |
+
// header("Content-Disposition: attachment; filename='{$filename}'");
|
89 |
+
}
|
90 |
+
|
91 |
+
// Some formats need to output some stuff before the actual loops
|
92 |
+
if ('json' == $export_format) {
|
93 |
+
$json_row = '[';
|
94 |
+
fwrite($fp, $json_row);
|
95 |
+
} elseif ('html' == $export_format) {
|
96 |
+
$html = sprintf(
|
97 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
<!doctype html>
|
99 |
<meta charset="utf-8">
|
100 |
<title>Simple History export</title>
|
101 |
<ul>
|
102 |
+
'
|
103 |
+
);
|
104 |
+
fwrite($fp, $html);
|
105 |
+
}
|
106 |
+
|
107 |
+
// Paginate through all pages and all their rows.
|
108 |
+
$row_loop = 0;
|
109 |
+
while ($page_current <= $pages_count + 1) {
|
110 |
+
// if ($page_current > 1) { break; } # To debug/test
|
111 |
+
foreach ($events['log_rows'] as $one_row) {
|
112 |
+
// if ( $row_loop > 10) { break; } # To debug/test
|
113 |
+
set_time_limit(30);
|
114 |
+
|
115 |
+
if ('csv' == $export_format) {
|
116 |
+
$header_output = strip_tags(html_entity_decode($this->sh->getLogRowHeaderOutput($one_row), ENT_QUOTES, 'UTF-8'));
|
117 |
+
$header_output = trim(preg_replace('/\s\s+/', ' ', $header_output));
|
118 |
+
|
119 |
+
$message_output = strip_tags(html_entity_decode($this->sh->getLogRowPlainTextOutput($one_row), ENT_QUOTES, 'UTF-8'));
|
120 |
+
|
121 |
+
$user_email = empty($one_row->context['_user_email']) ? null : $one_row->context['_user_email'];
|
122 |
+
$user_login = empty($one_row->context['_user_login']) ? null : $one_row->context['_user_login'];
|
123 |
+
|
124 |
+
fputcsv($fp, array(
|
125 |
+
$one_row->date,
|
126 |
+
$one_row->logger,
|
127 |
+
$one_row->level,
|
128 |
+
$one_row->initiator,
|
129 |
+
$one_row->context_message_key,
|
130 |
+
$user_email,
|
131 |
+
$user_login,
|
132 |
+
$header_output,
|
133 |
+
$message_output,
|
134 |
+
$one_row->subsequentOccasions,
|
135 |
+
));
|
136 |
+
} elseif ('json' == $export_format) {
|
137 |
+
// If not first loop then add a comma between all json objects.
|
138 |
+
if ($row_loop == 0) {
|
139 |
+
$comma = "\n";
|
140 |
+
} else {
|
141 |
+
$comma = ",\n";
|
142 |
+
}
|
143 |
+
|
144 |
+
$json_row = $comma . $this->sh->json_encode($one_row);
|
145 |
+
fwrite($fp, $json_row);
|
146 |
+
} elseif ('html' == $export_format) {
|
147 |
+
$html = sprintf(
|
148 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
<li>
|
150 |
<div>%1$s</div>
|
151 |
<div>%2$s</div>
|
152 |
<div>%3$s</div>
|
153 |
</li>
|
154 |
',
|
155 |
+
$this->sh->getLogRowHeaderOutput($one_row),
|
156 |
+
$this->sh->getLogRowPlainTextOutput($one_row),
|
157 |
+
$this->sh->getLogRowDetailsOutput($one_row)
|
158 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
|
160 |
+
fwrite($fp, $html);
|
161 |
+
}// End if().
|
162 |
|
163 |
+
$row_loop++;
|
164 |
+
}// End foreach().
|
165 |
|
166 |
+
// echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
167 |
+
// echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
168 |
+
// echo "<br>fetch next page";
|
169 |
+
flush();
|
170 |
|
171 |
+
// Fetch next page
|
172 |
+
// @TODO: must take into consideration that new items can be added while we do the fetch
|
173 |
+
$page_current++;
|
174 |
+
$query_args['paged'] = $page_current;
|
175 |
+
$events = $query->query($query_args);
|
176 |
|
177 |
+
// echo "<br>did fetch next page";
|
178 |
+
// echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
179 |
+
// echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
180 |
+
}// End while().
|
181 |
|
182 |
+
if ('json' == $export_format) {
|
183 |
+
$json_row = ']';
|
184 |
+
fwrite($fp, $json_row);
|
185 |
+
} elseif ('html' == $export_format) {
|
186 |
+
$html = sprintf('</ul>');
|
187 |
+
fwrite($fp, $html);
|
188 |
+
}
|
189 |
|
190 |
+
fclose($fp);
|
191 |
+
flush();
|
192 |
|
193 |
+
exit;
|
194 |
|
195 |
+
// echo "<br>done";
|
196 |
+
}// End if().
|
197 |
+
}
|
198 |
|
|
|
|
|
199 |
|
200 |
+
public function output()
|
201 |
+
{
|
202 |
|
203 |
+
?>
|
204 |
+
<!-- <h2>Export</h2> -->
|
205 |
|
206 |
+
<p><?php _ex('The export function will export the full history.', 'Export dropin: introtext', 'simple-history') ?></p>
|
207 |
|
208 |
+
<form method="post">
|
|
|
|
|
|
|
|
|
|
|
209 |
|
210 |
+
<h3><?php _ex('Choose format to export to', 'Export dropin: format', 'simple-history') ?></h3>
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
+
<p>
|
213 |
+
<label>
|
214 |
+
<input type="radio" name="format" value="json" checked>
|
215 |
+
<?php _ex('JSON', 'Export dropin: export format', 'simple-history') ?>
|
216 |
+
</label>
|
217 |
+
</p>
|
218 |
|
219 |
+
<p>
|
220 |
+
<label>
|
221 |
+
<input type="radio" name="format" value="csv">
|
222 |
+
<?php _ex('CSV', 'Export dropin: export format', 'simple-history') ?>
|
223 |
+
</label>
|
224 |
+
</p>
|
225 |
|
226 |
+
<!-- <br> -->
|
|
|
|
|
|
|
227 |
|
228 |
+
<!--<label>
|
229 |
+
<input type="radio" name="format" value="html">
|
230 |
+
HTML
|
231 |
+
</label>
|
232 |
+
<br> -->
|
233 |
|
234 |
+
<!-- <label>
|
235 |
+
<input type="radio" name="format" value="xml">
|
236 |
+
XML
|
237 |
+
</label> -->
|
238 |
|
239 |
+
<p>
|
240 |
+
<button type="submit" class="button button-primary"><?php _ex('Download Export File', 'Export dropin: submit button', 'simple-history') ?></button>
|
241 |
+
<input type="hidden" name="simple-history-action" value="export-history">
|
242 |
+
</p>
|
243 |
|
244 |
+
<?php
|
245 |
+
wp_nonce_field(__CLASS__ . '-action-export');
|
246 |
+
?>
|
247 |
|
248 |
+
</form>
|
249 |
|
250 |
+
<?php
|
251 |
+
}
|
252 |
}
|
dropins/SimpleHistoryFilterDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Filter GUI
|
@@ -8,600 +8,590 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistoryFilterDropin
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
|
16 |
-
|
|
|
17 |
|
18 |
-
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
24 |
|
25 |
-
|
|
|
26 |
|
27 |
-
|
28 |
|
29 |
-
|
30 |
|
31 |
-
|
|
|
32 |
|
33 |
-
wp_enqueue_style( 'simple_history_FilterDropin', $file_url . 'SimpleHistoryFilterDropin.css', null, SIMPLE_HISTORY_VERSION );
|
34 |
|
35 |
-
|
|
|
36 |
|
|
|
37 |
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
|
|
|
41 |
|
42 |
-
|
43 |
-
* Filter that determines if search filters should be visible directly on page load
|
44 |
-
*
|
45 |
-
* Set to true to show the filters when page is loaded
|
46 |
-
* If false then user must click "Show options"
|
47 |
-
*
|
48 |
-
* @since 2.1.2
|
49 |
-
*
|
50 |
-
* @param bool $show_more_filters_on_load Default false
|
51 |
-
*/
|
52 |
-
$show_more_filters_on_load = false;
|
53 |
-
$show_more_filters_on_load = apply_filters( 'SimpleHistoryFilterDropin/show_more_filters_on_load' , $show_more_filters_on_load );
|
54 |
|
55 |
-
|
56 |
-
<div class="SimpleHistory__filters <?php echo $show_more_filters_on_load ? 'is-showingMoreFilters' : '' ?>">
|
57 |
|
58 |
-
|
59 |
|
60 |
-
|
|
|
|
|
|
|
61 |
|
62 |
-
|
|
|
|
|
63 |
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
$loggers_user_can_read_sql_in = $this->sh->getLoggersThatUserCanRead( null, 'sql' );
|
68 |
-
|
69 |
-
// Get unique months
|
70 |
-
$cache_key = 'sh_filter_unique_months';
|
71 |
-
$result_months = get_transient( $cache_key );
|
72 |
-
|
73 |
-
if ( false === $result_months ) {
|
74 |
-
|
75 |
-
$sql_dates = sprintf('
|
76 |
SELECT DISTINCT ( date_format(DATE, "%%Y-%%m") ) AS yearMonth
|
77 |
FROM %s
|
78 |
WHERE logger IN %s
|
79 |
ORDER BY yearMonth DESC
|
80 |
-
',
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
echo $prefix . '<br>';
|
596 |
-
|
597 |
-
/* translators: 1: month, 2: day, 3: year */
|
598 |
-
printf( __( '%1$s %2$s, %3$s' ), $month, $day, $year );
|
599 |
-
|
600 |
-
echo '</span>';
|
601 |
-
|
602 |
-
?>
|
603 |
-
|
604 |
-
<?php
|
605 |
-
} // func
|
606 |
-
|
607 |
} // end class
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Filter GUI
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistoryFilterDropin
|
12 |
+
{
|
13 |
|
14 |
+
// Simple History instance
|
15 |
+
private $sh;
|
16 |
|
17 |
+
function __construct($sh)
|
18 |
+
{
|
19 |
|
20 |
+
$this->sh = $sh;
|
21 |
|
22 |
+
add_action('simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ));
|
23 |
+
add_action('simple_history/history_page/before_gui', array( $this, 'gui_page_filters' ));
|
24 |
+
add_action('simple_history/dashboard/before_gui', array( $this, 'gui_page_filters' ));
|
25 |
+
add_action('wp_ajax_simple_history_filters_search_user', array( $this, 'ajax_simple_history_filters_search_user' ));
|
26 |
+
}
|
27 |
|
28 |
+
public function enqueue_admin_scripts()
|
29 |
+
{
|
30 |
|
31 |
+
$file_url = plugin_dir_url(__FILE__);
|
32 |
|
33 |
+
wp_enqueue_script('simple_history_FilterDropin', $file_url . 'SimpleHistoryFilterDropin.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true);
|
34 |
|
35 |
+
wp_enqueue_style('simple_history_FilterDropin', $file_url . 'SimpleHistoryFilterDropin.css', null, SIMPLE_HISTORY_VERSION);
|
36 |
+
}
|
37 |
|
|
|
38 |
|
39 |
+
public function gui_page_filters()
|
40 |
+
{
|
41 |
|
42 |
+
$loggers_user_can_read = $this->sh->getLoggersThatUserCanRead();
|
43 |
|
44 |
+
/**
|
45 |
+
* Filter that determines if search filters should be visible directly on page load
|
46 |
+
*
|
47 |
+
* Set to true to show the filters when page is loaded
|
48 |
+
* If false then user must click "Show options"
|
49 |
+
*
|
50 |
+
* @since 2.1.2
|
51 |
+
*
|
52 |
+
* @param bool $show_more_filters_on_load Default false
|
53 |
+
*/
|
54 |
+
$show_more_filters_on_load = false;
|
55 |
+
$show_more_filters_on_load = apply_filters('SimpleHistoryFilterDropin/show_more_filters_on_load', $show_more_filters_on_load);
|
56 |
|
57 |
+
?>
|
58 |
+
<div class="SimpleHistory__filters <?php echo $show_more_filters_on_load ? 'is-showingMoreFilters' : '' ?>">
|
59 |
|
60 |
+
<form class="SimpleHistory__filters__form js-SimpleHistory__filters__form">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
+
<!-- <h3><?php _e('Filter history', 'simple-history') ?></h3> -->
|
|
|
63 |
|
64 |
+
<?php
|
65 |
|
66 |
+
// Start months filter
|
67 |
+
global $wpdb;
|
68 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
69 |
+
$loggers_user_can_read_sql_in = $this->sh->getLoggersThatUserCanRead(null, 'sql');
|
70 |
|
71 |
+
// Get unique months
|
72 |
+
$cache_key = 'sh_filter_unique_months';
|
73 |
+
$result_months = get_transient($cache_key);
|
74 |
|
75 |
+
if (false === $result_months) {
|
76 |
+
$sql_dates = sprintf(
|
77 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
SELECT DISTINCT ( date_format(DATE, "%%Y-%%m") ) AS yearMonth
|
79 |
FROM %s
|
80 |
WHERE logger IN %s
|
81 |
ORDER BY yearMonth DESC
|
82 |
+
',
|
83 |
+
$table_name, // 1
|
84 |
+
$loggers_user_can_read_sql_in // 2
|
85 |
+
);
|
86 |
+
|
87 |
+
$result_months = $wpdb->get_results($sql_dates);
|
88 |
+
|
89 |
+
set_transient($cache_key, $result_months, HOUR_IN_SECONDS);
|
90 |
+
}
|
91 |
+
|
92 |
+
$arr_days_and_pages = array();
|
93 |
+
|
94 |
+
// Default month = current month
|
95 |
+
// Mainly for performance reasons, since often
|
96 |
+
// it's not the users intention to view all events,
|
97 |
+
// but just the latest
|
98 |
+
$this_month = date('Y-m');
|
99 |
+
|
100 |
+
// Determine if we limit the date range by default
|
101 |
+
$daysToShow = 1;
|
102 |
+
|
103 |
+
// Start with the latest day
|
104 |
+
$numEvents = $this->sh->get_unique_events_for_days($daysToShow);
|
105 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
106 |
+
|
107 |
+
$arr_days_and_pages[] = array(
|
108 |
+
'daysToShow' => $daysToShow,
|
109 |
+
'numPages' => $numPages,
|
110 |
+
);
|
111 |
+
|
112 |
+
// Example on my server with lots of brute force attacks (causing log to not load)
|
113 |
+
// 166434 / 15 = 11 000 pages for last 7 days
|
114 |
+
// 1 day = 3051 / 15 = 203 pages = still much but better than 11000 pages!
|
115 |
+
if ($numPages < 20) {
|
116 |
+
// Not that many things the last day. Let's try to expand to 7 days instead.
|
117 |
+
$daysToShow = 7;
|
118 |
+
$numEvents = $this->sh->get_unique_events_for_days($daysToShow);
|
119 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
120 |
+
|
121 |
+
$arr_days_and_pages[] = array(
|
122 |
+
'daysToShow' => $daysToShow,
|
123 |
+
'numPages' => $numPages,
|
124 |
+
);
|
125 |
+
|
126 |
+
if ($numPages < 20) {
|
127 |
+
// Not that many things the last 7 days. Let's try to expand to 14 days instead.
|
128 |
+
$daysToShow = 14;
|
129 |
+
$numEvents = $this->sh->get_unique_events_for_days($daysToShow);
|
130 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
131 |
+
|
132 |
+
$arr_days_and_pages[] = array(
|
133 |
+
'daysToShow' => $daysToShow,
|
134 |
+
'numPages' => $numPages,
|
135 |
+
);
|
136 |
+
|
137 |
+
if ($numPages < 20) {
|
138 |
+
// Not many things the last 14 days either. Let try with 30 days.
|
139 |
+
$daysToShow = 30;
|
140 |
+
$numEvents = $this->sh->get_unique_events_for_days($daysToShow);
|
141 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
142 |
+
|
143 |
+
$arr_days_and_pages[] = array(
|
144 |
+
'daysToShow' => $daysToShow,
|
145 |
+
'numPages' => $numPages,
|
146 |
+
);
|
147 |
+
|
148 |
+
// If 30 days gives a big amount of pages, go back to 14 days
|
149 |
+
if ($numPages > 1000) {
|
150 |
+
$daysToShow = 14;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
}
|
154 |
+
}// End if().
|
155 |
+
|
156 |
+
?>
|
157 |
+
|
158 |
+
<p class="SimpleHistory__filters__filterRow SimpleHistory__filters__filterRow--date" data-debug-daysAndPages='<?php echo json_encode($arr_days_and_pages) ?>'>
|
159 |
+
|
160 |
+
<label class="SimpleHistory__filters__filterLabel"><?php _ex('Dates:', 'Filter label', 'simple-history') ?></label>
|
161 |
+
|
162 |
+
<select class="SimpleHistory__filters__filter SimpleHistory__filters__filter--date"
|
163 |
+
name="dates"
|
164 |
+
placeholder="<?php echo _e('All dates', 'simple-history') ?>"
|
165 |
+
NOTmultiple
|
166 |
+
>
|
167 |
+
<?php
|
168 |
+
|
169 |
+
// custom date range
|
170 |
+
// since 2.8.1
|
171 |
+
printf(
|
172 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
173 |
+
'customRange', // 1 - value
|
174 |
+
_x('Custom date range...', 'Filter dropin: filter custom range', 'simple-history'), // 2 text
|
175 |
+
selected($daysToShow, 'customRange', 0)
|
176 |
+
);
|
177 |
+
|
178 |
+
// One day+ Last week + two weeks back + 30 days back
|
179 |
+
printf(
|
180 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
181 |
+
'lastdays:1', // 1 - value
|
182 |
+
_x('Last day', 'Filter dropin: filter week', 'simple-history'), // 2 text
|
183 |
+
selected($daysToShow, 1, 0)
|
184 |
+
);
|
185 |
+
|
186 |
+
printf(
|
187 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
188 |
+
'lastdays:7', // 1 - value
|
189 |
+
_x('Last 7 days', 'Filter dropin: filter week', 'simple-history'), // 2 text
|
190 |
+
selected($daysToShow, 7, 0)
|
191 |
+
);
|
192 |
+
|
193 |
+
printf(
|
194 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
195 |
+
'lastdays:14', // 1 - value
|
196 |
+
_x('Last 14 days', 'Filter dropin: filter week', 'simple-history'), // 2 text
|
197 |
+
selected($daysToShow, 14, 0)
|
198 |
+
);
|
199 |
+
|
200 |
+
printf(
|
201 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
202 |
+
'lastdays:30', // 1 - value
|
203 |
+
_x('Last 30 days', 'Filter dropin: filter week', 'simple-history'), // 2 text
|
204 |
+
selected($daysToShow, 30, 0)
|
205 |
+
);
|
206 |
+
|
207 |
+
printf(
|
208 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
209 |
+
'lastdays:60', // 1 - value
|
210 |
+
_x('Last 60 days', 'Filter dropin: filter week', 'simple-history'), // 2 text
|
211 |
+
selected($daysToShow, 60, 0)
|
212 |
+
);
|
213 |
+
|
214 |
+
// Months
|
215 |
+
foreach ($result_months as $row) {
|
216 |
+
printf(
|
217 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
218 |
+
'month:' . $row->yearMonth,
|
219 |
+
date_i18n('F Y', strtotime($row->yearMonth)),
|
220 |
+
'' // selected( $this_month, $row->yearMonth, false )
|
221 |
+
);
|
222 |
+
}
|
223 |
+
|
224 |
+
?>
|
225 |
+
</select>
|
226 |
+
|
227 |
+
<!-- <p> -->
|
228 |
+
<!-- <label class="SimpleHistory__filters__filterLabel"><?php _ex('Between dates:', 'Filter label', 'simple-history') ?></label> -->
|
229 |
+
<span class="SimpleHistory__filters__filter--dayValuesWrap">
|
230 |
+
<?php
|
231 |
+
$this->touch_time('from');
|
232 |
+
$this->touch_time('to');
|
233 |
+
?>
|
234 |
+
</span>
|
235 |
+
<!-- </p> -->
|
236 |
+
|
237 |
+
</p><!-- end months -->
|
238 |
+
|
239 |
+
<?php
|
240 |
+
/**
|
241 |
+
* Filter to control what the default search string is. Default to empty string.
|
242 |
+
*
|
243 |
+
* @since 2.1.2
|
244 |
+
*
|
245 |
+
* @param string Default search string
|
246 |
+
*/
|
247 |
+
$default_search_string = apply_filters('SimpleHistoryFilterDropin/filter_default_search_string', '');
|
248 |
+
?>
|
249 |
+
|
250 |
+
<p>
|
251 |
+
|
252 |
+
<label class="SimpleHistory__filters__filterLabel"><?php _ex('Containing words:', 'Filter label', 'simple-history') ?></label>
|
253 |
+
|
254 |
+
<input
|
255 |
+
type="search"
|
256 |
+
class="SimpleHistoryFilterDropin-searchInput"
|
257 |
+
placeholder="<?php /* _e("Containing words", "simple-history"); */ ?>"
|
258 |
+
name="search"
|
259 |
+
value="<?php echo esc_attr($default_search_string); ?>"
|
260 |
+
>
|
261 |
+
|
262 |
+
</p>
|
263 |
+
|
264 |
+
<p class="SimpleHistory__filters__filterSubmitWrap">
|
265 |
+
<button class="button SimpleHistoryFilterDropin-doFilterButton SimpleHistoryFilterDropin-doFilterButton--first js-SimpleHistoryFilterDropin-doFilter"><?php _e('Search events', 'simple-history') ?></button>
|
266 |
+
<button type="button" class="SimpleHistoryFilterDropin-showMoreFilters SimpleHistoryFilterDropin-showMoreFilters--first js-SimpleHistoryFilterDropin-showMoreFilters"><?php _ex('Show search options', 'Filter dropin: button to show more search options', 'simple-history') ?></button>
|
267 |
+
</p>
|
268 |
+
|
269 |
+
<?php
|
270 |
+
/**
|
271 |
+
* Filter to control what the default loglevels are.
|
272 |
+
*
|
273 |
+
* @since 2.1.2
|
274 |
+
*
|
275 |
+
* @param array Array with loglevel sugs. Default empty = show all.
|
276 |
+
*/
|
277 |
+
$arr_default_loglevels = apply_filters('SimpleHistoryFilterDropin/filter_default_loglevel', array());
|
278 |
+
?>
|
279 |
+
<div class="SimpleHistory__filters__moreFilters js-SimpleHistory__filters__moreFilters">
|
280 |
+
|
281 |
+
<p>
|
282 |
+
|
283 |
+
<label class="SimpleHistory__filters__filterLabel"><?php _ex('Log levels:', 'Filter label', 'simple-history') ?></label>
|
284 |
+
|
285 |
+
<select
|
286 |
+
name="loglevels"
|
287 |
+
class="SimpleHistory__filters__filter SimpleHistory__filters__filter--loglevel"
|
288 |
+
placeholder="<?php _e('All log levels', 'simple-history') ?>"
|
289 |
+
multiple
|
290 |
+
>
|
291 |
+
<option <?php selected(in_array('debug', $arr_default_loglevels)) ?> value="debug" data-color="#CEF6D8"><?php echo $this->sh->getLogLevelTranslated('Debug') ?></option>
|
292 |
+
<option <?php selected(in_array('info', $arr_default_loglevels)) ?> value="info" data-color="white"><?php echo $this->sh->getLogLevelTranslated('Info') ?></option>
|
293 |
+
<option <?php selected(in_array('notice', $arr_default_loglevels)) ?> value="notice" data-color="rgb(219, 219, 183)"><?php echo $this->sh->getLogLevelTranslated('Notice') ?></option>
|
294 |
+
<option <?php selected(in_array('warning', $arr_default_loglevels)) ?> value="warning" data-color="#F7D358"><?php echo $this->sh->getLogLevelTranslated('Warning') ?></option>
|
295 |
+
<option <?php selected(in_array('error', $arr_default_loglevels)) ?> value="error" data-color="#F79F81"><?php echo $this->sh->getLogLevelTranslated('Error') ?></option>
|
296 |
+
<option <?php selected(in_array('critical', $arr_default_loglevels)) ?> value="critical" data-color="#FA5858"><?php echo $this->sh->getLogLevelTranslated('Critical') ?></option>
|
297 |
+
<option <?php selected(in_array('alert', $arr_default_loglevels)) ?> value="alert" data-color="rgb(199, 69, 69)"><?php echo $this->sh->getLogLevelTranslated('Alert') ?></option>
|
298 |
+
<option <?php selected(in_array('emergency', $arr_default_loglevels)) ?> value="emergency" data-color="#DF0101"><?php echo $this->sh->getLogLevelTranslated('Emergency') ?></option>
|
299 |
+
</select>
|
300 |
+
|
301 |
+
</p>
|
302 |
+
|
303 |
+
<?php
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Todo: Filter to control what the default messages to filter/search.
|
307 |
+
* Message in in format: LoggerSlug:MessageKey
|
308 |
+
* For example:
|
309 |
+
* - SimplePluginLogger:plugin_activated
|
310 |
+
* - SimpleCommentsLogger:user_comment_added
|
311 |
+
*
|
312 |
+
* @since 2.1.2
|
313 |
+
*
|
314 |
+
* @param array Array with loglevel sugs. Default empty = show all.
|
315 |
+
*/
|
316 |
+
// $arr_default_messages = apply_filters("SimpleHistoryFilterDropin/filter_default_messages", array());
|
317 |
+
?>
|
318 |
+
<p>
|
319 |
+
|
320 |
+
<label class="SimpleHistory__filters__filterLabel"><?php _ex('Message types:', 'Filter label', 'simple-history') ?></label>
|
321 |
+
|
322 |
+
<select
|
323 |
+
name="messages"
|
324 |
+
class="SimpleHistory__filters__filter SimpleHistory__filters__filter--logger"
|
325 |
+
placeholder="<?php _e('All messages', 'simple-history') ?>"
|
326 |
+
multiple
|
327 |
+
>
|
328 |
+
<?php
|
329 |
+
foreach ($loggers_user_can_read as $logger) {
|
330 |
+
$logger_info = $logger['instance']->getInfo();
|
331 |
+
$logger_slug = $logger['instance']->slug;
|
332 |
+
|
333 |
+
// Get labels for logger
|
334 |
+
if (isset($logger_info['labels']['search'])) {
|
335 |
+
printf('<optgroup label="%1$s">', esc_attr($logger_info['labels']['search']['label']));
|
336 |
+
|
337 |
+
// If all activity
|
338 |
+
if (! empty($logger_info['labels']['search']['label_all'])) {
|
339 |
+
$arr_all_search_messages = array();
|
340 |
+
foreach ($logger_info['labels']['search']['options'] as $option_key => $option_messages) {
|
341 |
+
$arr_all_search_messages = array_merge($arr_all_search_messages, $option_messages);
|
342 |
+
}
|
343 |
+
|
344 |
+
foreach ($arr_all_search_messages as $key => $val) {
|
345 |
+
$arr_all_search_messages[ $key ] = $logger_slug . ':' . $val;
|
346 |
+
}
|
347 |
+
|
348 |
+
printf('<option value="%2$s">%1$s</option>', esc_attr($logger_info['labels']['search']['label_all']), esc_attr(implode(',', $arr_all_search_messages)));
|
349 |
+
}
|
350 |
+
|
351 |
+
// For each specific search option
|
352 |
+
foreach ($logger_info['labels']['search']['options'] as $option_key => $option_messages) {
|
353 |
+
foreach ($option_messages as $key => $val) {
|
354 |
+
$option_messages[ $key ] = $logger_slug . ':' . $val;
|
355 |
+
}
|
356 |
+
|
357 |
+
$str_option_messages = implode(',', $option_messages);
|
358 |
+
printf(
|
359 |
+
'<option value="%2$s">%1$s</option>',
|
360 |
+
esc_attr($option_key), // 1
|
361 |
+
esc_attr($str_option_messages) // 2
|
362 |
+
);
|
363 |
+
}
|
364 |
+
|
365 |
+
printf('</optgroup>');
|
366 |
+
}// End if().
|
367 |
+
}// End foreach().
|
368 |
+
?>
|
369 |
+
</select>
|
370 |
+
</p>
|
371 |
+
|
372 |
+
<?php
|
373 |
+
|
374 |
+
/**
|
375 |
+
* Filter what users to search for by default
|
376 |
+
*
|
377 |
+
* Example:
|
378 |
+
*
|
379 |
+
* add_filter("SimpleHistoryFilterDropin/filter_default_user_ids", function() { return array(1,4); });
|
380 |
+
*
|
381 |
+
* @since 2.1.2
|
382 |
+
*
|
383 |
+
* @param array Array with user ids. Default is an empty array = show all users.
|
384 |
+
*/
|
385 |
+
|
386 |
+
/*
|
387 |
+
add_filter("SimpleHistoryFilterDropin/filter_default_user_ids", function($arr) {
|
388 |
+
$arr = array(
|
389 |
+
1,
|
390 |
+
4
|
391 |
+
);
|
392 |
+
return $arr;
|
393 |
+
});
|
394 |
+
//*/
|
395 |
+
|
396 |
+
$default_user_ids = apply_filters('SimpleHistoryFilterDropin/filter_default_user_ids', array());
|
397 |
+
$arr_default_user_data = array();
|
398 |
+
|
399 |
+
foreach ($default_user_ids as $user_id) {
|
400 |
+
$arr_default_user_data[] = $this->get_data_for_user($user_id);
|
401 |
+
}
|
402 |
+
|
403 |
+
if (current_user_can('list_users')) {
|
404 |
+
?>
|
405 |
+
<p>
|
406 |
+
<label class="SimpleHistory__filters__filterLabel"><?php _ex('Users:', 'Filter label', 'simple-history') ?></label>
|
407 |
+
<select
|
408 |
+
name="users"
|
409 |
+
class="SimpleHistory__filters__filter SimpleHistory__filters__filter--user"
|
410 |
+
placeholder="<?php _e('All users', 'simple-history') ?>"
|
411 |
+
value="<?php echo esc_attr(implode(',', $default_user_ids)) ?>"
|
412 |
+
data-default-user-data="<?php echo esc_attr(json_encode($arr_default_user_data)) ?>"
|
413 |
+
>
|
414 |
+
</select>
|
415 |
+
</p>
|
416 |
+
<?php
|
417 |
+
}
|
418 |
+
|
419 |
+
?>
|
420 |
+
|
421 |
+
<p class="SimpleHistory__filters__filterSubmitWrap">
|
422 |
+
<button class="button SimpleHistoryFilterDropin-doFilterButton SimpleHistoryFilterDropin-doFilterButton--second js-SimpleHistoryFilterDropin-doFilter"><?php _e('Search events', 'simple-history') ?></button>
|
423 |
+
<button type="button" class="SimpleHistoryFilterDropin-showMoreFilters SimpleHistoryFilterDropin-showMoreFilters--second js-SimpleHistoryFilterDropin-showMoreFilters"><?php _ex('Hide search options', 'Filter dropin: button to hide more search options', 'simple-history') ?></button>
|
424 |
+
</p>
|
425 |
+
|
426 |
+
</div><!-- // more filters -->
|
427 |
+
|
428 |
+
<!--
|
429 |
+
<p>
|
430 |
+
<button class="button js-SimpleHistoryFilterDropin-doFilter"><?php _e('Search', 'simple-history') ?></button>
|
431 |
+
</p>
|
432 |
+
-->
|
433 |
+
|
434 |
+
</form>
|
435 |
+
|
436 |
+
</div>
|
437 |
+
<?php
|
438 |
+
} // function
|
439 |
+
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Return format used for select2 for a single user id
|
443 |
+
*
|
444 |
+
* @param int $userID
|
445 |
+
* @return array Array with each user as an object
|
446 |
+
*/
|
447 |
+
public function get_data_for_user($userID)
|
448 |
+
{
|
449 |
+
if (! $userID || ! is_numeric($userID)) {
|
450 |
+
return false;
|
451 |
+
}
|
452 |
+
|
453 |
+
$user = get_user_by('id', $userID);
|
454 |
+
|
455 |
+
if (false == $user) {
|
456 |
+
return false;
|
457 |
+
}
|
458 |
+
|
459 |
+
$userdata = (object) array(
|
460 |
+
'id' => $user->ID,
|
461 |
+
'user_email' => $user->user_email,
|
462 |
+
'user_login' => $user->user_login,
|
463 |
+
'user_nicename' => $user->user_nicename,
|
464 |
+
);
|
465 |
+
|
466 |
+
$this->add_gravatar_to_user_array($userdata);
|
467 |
+
|
468 |
+
return $userdata;
|
469 |
+
}
|
470 |
+
|
471 |
+
/**
|
472 |
+
* Return users
|
473 |
+
*/
|
474 |
+
public function ajax_simple_history_filters_search_user()
|
475 |
+
{
|
476 |
+
|
477 |
+
$q = isset($_GET['q']) ? $_GET['q'] : '';
|
478 |
+
$page_limit = isset($_GET['page_limit']) ? (int) $_GET['page_limit'] : '';
|
479 |
+
|
480 |
+
// query and page limit must be set
|
481 |
+
if (! $q || ! $page_limit) {
|
482 |
+
wp_send_json_error();
|
483 |
+
}
|
484 |
+
|
485 |
+
// user must have list_users capability (default super admin + administrators have this)
|
486 |
+
if (! current_user_can('list_users')) {
|
487 |
+
wp_send_json_error();
|
488 |
+
}
|
489 |
+
|
490 |
+
// Search both current users and all logged rows,
|
491 |
+
// because a user can change email
|
492 |
+
// search in context: user_id, user_email, user_login
|
493 |
+
// search in wp_users: login, nicename, user_email
|
494 |
+
// search and get users. make sure to use "fields" and "number" or we can get timeout/use lots of memory if we have a large amount of users
|
495 |
+
$results_user = get_users(array(
|
496 |
+
'search' => "*{$q}*",
|
497 |
+
'fields' => array( 'ID', 'user_login', 'user_nicename', 'user_email', 'display_name' ),
|
498 |
+
'number' => 20,
|
499 |
+
));
|
500 |
+
|
501 |
+
// add lower case id to user array
|
502 |
+
array_walk($results_user, function ($val) {
|
503 |
+
$val->id = $val->ID;
|
504 |
+
});
|
505 |
+
|
506 |
+
// add gravatars to user array
|
507 |
+
array_walk($results_user, array( $this, 'add_gravatar_to_user_array' ));
|
508 |
+
|
509 |
+
$data = array(
|
510 |
+
'results' => array(),
|
511 |
+
'more' => false,
|
512 |
+
'context' => array(),
|
513 |
+
'count' => sizeof($results_user),
|
514 |
+
);
|
515 |
+
|
516 |
+
$data['results'] = array_merge($data['results'], $results_user);
|
517 |
+
|
518 |
+
wp_send_json_success($data);
|
519 |
+
} // function
|
520 |
+
|
521 |
+
function add_gravatar_to_user_array(& $val, $index = null)
|
522 |
+
{
|
523 |
+
$val->text = sprintf(
|
524 |
+
'%1$s - %2$s',
|
525 |
+
$val->user_login,
|
526 |
+
$val->user_email
|
527 |
+
);
|
528 |
+
|
529 |
+
$val->gravatar = $this->sh->get_avatar($val->user_email, '18', 'mm');
|
530 |
+
}
|
531 |
+
|
532 |
+
|
533 |
+
/**
|
534 |
+
* Print out HTML form date elements for editing post or comment publish date.
|
535 |
+
*
|
536 |
+
* Based on the wordpress function touch_time();
|
537 |
+
*
|
538 |
+
* @global WP_Locale $wp_locale
|
539 |
+
*
|
540 |
+
* @param int|bool $edit Accepts 1|true for editing the date, 0|false for adding the date.
|
541 |
+
* @param int|bool $for_post Accepts 1|true for applying the date to a post, 0|false for a comment.
|
542 |
+
* @param int $tab_index The tabindex attribute to add. Default 0.
|
543 |
+
* @param int|bool $multi Optional. Whether the additional fields and buttons should be added.
|
544 |
+
* Default 0|false.
|
545 |
+
*/
|
546 |
+
function touch_time($from_or_to, $edit = 1)
|
547 |
+
{
|
548 |
+
|
549 |
+
global $wp_locale;
|
550 |
+
|
551 |
+
// Prefix = text before the inputs
|
552 |
+
$prefix = '';
|
553 |
+
$input_prefix = '';
|
554 |
+
if ('from' == $from_or_to) {
|
555 |
+
$prefix = _x('From', 'Filter dropin, custom date range', 'simple-history');
|
556 |
+
$input_prefix = 'from_';
|
557 |
+
} elseif ('to' == $from_or_to) {
|
558 |
+
$prefix = _x('To', 'Filter dropin, custom date range', 'simple-history');
|
559 |
+
$input_prefix = 'to_';
|
560 |
+
}
|
561 |
+
|
562 |
+
// The default date to show in the inputs
|
563 |
+
$date = date('Y-m-d');
|
564 |
+
|
565 |
+
$jj = mysql2date('d', $date, false);
|
566 |
+
$mm = mysql2date('m', $date, false);
|
567 |
+
$aa = mysql2date('Y', $date, false);
|
568 |
+
|
569 |
+
$month = "<select name='{$input_prefix}mm'>";
|
570 |
+
|
571 |
+
for ($i = 1; $i < 13; $i = $i + 1) {
|
572 |
+
$monthnum = zeroise($i, 2);
|
573 |
+
$monthtext = $wp_locale->get_month_abbrev($wp_locale->get_month($i));
|
574 |
+
$month .= "\t\t\t" . '<option value="' . $monthnum . '" data-text="' . $monthtext . '" ' . selected($monthnum, $mm, false) . '>';
|
575 |
+
/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
|
576 |
+
$month .= sprintf(__('%1$s-%2$s'), $monthnum, $monthtext) . "</option>\n";
|
577 |
+
}
|
578 |
+
$month .= '</select>';
|
579 |
+
$month .= '</label>';
|
580 |
+
|
581 |
+
$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>';
|
582 |
+
$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>';
|
583 |
+
|
584 |
+
echo '<span class="SimpleHistory__filters__filter SimpleHistory__filters__filter--day">';
|
585 |
+
|
586 |
+
echo $prefix . '<br>';
|
587 |
+
|
588 |
+
/* translators: 1: month, 2: day, 3: year */
|
589 |
+
printf(__('%1$s %2$s, %3$s'), $month, $day, $year);
|
590 |
+
|
591 |
+
echo '</span>';
|
592 |
+
|
593 |
+
?>
|
594 |
+
|
595 |
+
<?php
|
596 |
+
} // func
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
} // end class
|
dropins/SimpleHistoryIpInfoDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: IP Info
|
@@ -8,169 +8,170 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistoryIpInfoDropin
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
|
|
175 |
} // end class
|
176 |
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: IP Info
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistoryIpInfoDropin
|
12 |
+
{
|
13 |
+
|
14 |
+
private $sh;
|
15 |
+
|
16 |
+
function __construct($sh)
|
17 |
+
{
|
18 |
+
|
19 |
+
$this->sh = $sh;
|
20 |
+
|
21 |
+
// Since it's not quite done yet, it's for da devs only for now
|
22 |
+
/*
|
23 |
+
if ( ! defined("SIMPLE_HISTORY_DEV") || ! SIMPLE_HISTORY_DEV ) {
|
24 |
+
return;
|
25 |
+
}*/
|
26 |
+
|
27 |
+
add_action('simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ));
|
28 |
+
add_action('simple_history/admin_footer', array( $this, 'add_js_template' ));
|
29 |
+
}
|
30 |
+
|
31 |
+
public function enqueue_admin_scripts()
|
32 |
+
{
|
33 |
+
|
34 |
+
$file_url = plugin_dir_url(__FILE__);
|
35 |
+
|
36 |
+
wp_enqueue_script('simple_history_IpInfoDropin', $file_url . 'SimpleHistoryIpInfoDropin.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true);
|
37 |
+
|
38 |
+
wp_enqueue_style('simple_history_IpInfoDropin', $file_url . 'SimpleHistoryIpInfoDropin.css', null, SIMPLE_HISTORY_VERSION);
|
39 |
+
}
|
40 |
+
|
41 |
+
public function add_js_template()
|
42 |
+
{
|
43 |
+
?>
|
44 |
+
|
45 |
+
<div class="SimpleHistoryIpInfoDropin__popup">
|
46 |
+
<div class="SimpleHistoryIpInfoDropin__popupArrow"></div>
|
47 |
+
<div class="SimpleHistoryIpInfoDropin__popupClose"><button class="SimpleHistoryIpInfoDropin__popupCloseButton">×</button></div>
|
48 |
+
<div class="SimpleHistoryIpInfoDropin__popupContent"></div>
|
49 |
+
</div>
|
50 |
+
|
51 |
+
<script type="text/html" id="tmpl-simple-history-ipinfodropin-popup-loading">
|
52 |
+
<!-- <p>Getting IP info ...</p> -->
|
53 |
+
</script>
|
54 |
+
|
55 |
+
<script type="text/html" id="tmpl-simple-history-ipinfodropin-popup-loaded">
|
56 |
+
<!--
|
57 |
+
{
|
58 |
+
"ip": "8.8.8.8",
|
59 |
+
"hostname": "google-public-dns-a.google.com",
|
60 |
+
"city": "Mountain View",
|
61 |
+
"region": "California",
|
62 |
+
"country": "US",
|
63 |
+
"loc": "37.3860,-122.0838",
|
64 |
+
"org": "AS15169 Google Inc.",
|
65 |
+
"postal": "94035"
|
66 |
+
}
|
67 |
+
-->
|
68 |
+
<# if ( typeof(data.bogon) != "undefined" ) { #>
|
69 |
+
|
70 |
+
<p><?php _ex('That IP address does not seem like a public one.', 'IP Info Dropin', 'simple-history'); ?></p>
|
71 |
+
|
72 |
+
<# } else { #>
|
73 |
+
|
74 |
+
<table class="SimpleHistoryIpInfoDropin__ipInfoTable">
|
75 |
+
|
76 |
+
<tr class="SimpleHistoryIpInfoDropin__ipInfoTable__mapRow">
|
77 |
+
<td colspan="2">
|
78 |
+
<!--
|
79 |
+
<# if ( typeof(data.loc) != "undefined" && data.loc ) { #>
|
80 |
+
<a href="https://www.google.com/maps/place/{{ data.loc }}/@{{ data.loc }},6z" target="_blank">
|
81 |
+
<img src="https://maps.googleapis.com/maps/api/staticmap?center={{ data.loc }}&zoom=7&size=350x100&sensor=false" width="350" height="100" alt="Google Map">
|
82 |
+
</a>
|
83 |
+
<# } #>
|
84 |
+
-->
|
85 |
+
</td>
|
86 |
+
</tr>
|
87 |
+
|
88 |
+
<# if ( typeof(data.ip) != "undefined" && data.ip ) { #>
|
89 |
+
<tr>
|
90 |
+
<td>
|
91 |
+
<?php _ex('IP address', 'IP Info Dropin', 'simple-history'); ?>
|
92 |
+
</td>
|
93 |
+
<td>
|
94 |
+
{{ data.ip }}
|
95 |
+
</td>
|
96 |
+
</tr>
|
97 |
+
<# } #>
|
98 |
+
|
99 |
+
<# if ( typeof(data.hostname) != "undefined" && data.hostname ) { #>
|
100 |
+
<tr>
|
101 |
+
<td>
|
102 |
+
<?php _ex('Hostname', 'IP Info Dropin', 'simple-history'); ?>
|
103 |
+
</td>
|
104 |
+
<td>
|
105 |
+
{{ data.hostname }}
|
106 |
+
</td>
|
107 |
+
</tr>
|
108 |
+
<# } #>
|
109 |
+
|
110 |
+
<# if ( typeof(data.org) != "undefined" && data.org ) { #>
|
111 |
+
<tr>
|
112 |
+
<td>
|
113 |
+
<?php _ex('Network', 'IP Info Dropin', 'simple-history'); ?>
|
114 |
+
</td>
|
115 |
+
<td>
|
116 |
+
{{ data.org }}
|
117 |
+
</td>
|
118 |
+
</tr>
|
119 |
+
<# } #>
|
120 |
+
|
121 |
+
<# if ( typeof(data.network) != "undefined" && data.network ) { #>
|
122 |
+
<tr>
|
123 |
+
<td>
|
124 |
+
<?php _ex('Network', 'IP Info Dropin', 'simple-history'); ?>
|
125 |
+
</td>
|
126 |
+
<td>
|
127 |
+
{{ data.network }}
|
128 |
+
</td>
|
129 |
+
</tr>
|
130 |
+
<# } #>
|
131 |
+
|
132 |
+
<# if ( typeof(data.city) != "undefined" && data.city ) { #>
|
133 |
+
<tr>
|
134 |
+
<td>
|
135 |
+
<?php _ex('City', 'IP Info Dropin', 'simple-history'); ?>
|
136 |
+
</td>
|
137 |
+
<td>
|
138 |
+
{{ data.city }}
|
139 |
+
</td>
|
140 |
+
</tr>
|
141 |
+
<# } #>
|
142 |
+
|
143 |
+
<# if ( typeof(data.region) != "undefined" && data.region ) { #>
|
144 |
+
<tr>
|
145 |
+
<td>
|
146 |
+
<?php _ex('Region', 'IP Info Dropin', 'simple-history'); ?>
|
147 |
+
</td>
|
148 |
+
<td>
|
149 |
+
{{ data.region }}
|
150 |
+
</td>
|
151 |
+
</tr>
|
152 |
+
<# } #>
|
153 |
+
|
154 |
+
<# if ( typeof(data.country) != "undefined" && data.country ) { #>
|
155 |
+
<tr>
|
156 |
+
<td>
|
157 |
+
<?php _ex('Country', 'IP Info Dropin', 'simple-history'); ?>
|
158 |
+
</td>
|
159 |
+
<td>
|
160 |
+
{{ data.country }}
|
161 |
+
</td>
|
162 |
+
</tr>
|
163 |
+
<# } #>
|
164 |
+
|
165 |
+
</table>
|
166 |
+
|
167 |
+
<p class="SimpleHistoryIpInfoDropin__provider">
|
168 |
+
<?php printf(_x('IP info provided by %1$s ipinfo.io %2$s', 'IP Info Dropin', 'simple-history'), "<a href='https://ipinfo.io/{{ data.ip }}' target='_blank'>", '</a>'); ?>
|
169 |
+
</p>
|
170 |
+
|
171 |
+
<# } #>
|
172 |
+
|
173 |
+
</script>
|
174 |
+
<?php
|
175 |
+
}
|
176 |
} // end class
|
177 |
|
dropins/SimpleHistoryNewRowsNotifier.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Dropin Name: New Items Notifier
|
@@ -9,92 +9,90 @@ defined( 'ABSPATH' ) or die();
|
|
9 |
* Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
-
class SimpleHistoryNewRowsNotifier
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
|
17 |
-
|
18 |
-
|
19 |
|
20 |
-
|
|
|
21 |
|
22 |
-
|
23 |
|
24 |
-
|
25 |
-
|
26 |
|
27 |
-
|
28 |
-
|
|
|
29 |
|
30 |
-
|
|
|
31 |
|
32 |
-
|
33 |
|
34 |
-
|
35 |
|
36 |
-
|
|
|
|
|
|
|
37 |
|
38 |
-
|
39 |
-
'interval' => $this->interval,
|
40 |
-
'errorCheck' => _x( 'An error occured while checking for new events', 'New rows notifier: error while checking for new rows', 'simple-history' ),
|
41 |
-
);
|
42 |
|
43 |
-
|
|
|
44 |
|
45 |
-
|
|
|
46 |
|
47 |
-
|
48 |
|
49 |
-
|
|
|
|
|
|
|
|
|
50 |
|
51 |
-
|
|
|
|
|
|
|
|
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
'error' => 'MISSING_SINCE_ID',
|
62 |
-
) );
|
63 |
-
}
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
wp_send_json_error( array(
|
68 |
-
'error' => 'CAPABILITY_ERROR',
|
69 |
-
) );
|
70 |
-
}
|
71 |
|
72 |
-
|
73 |
-
|
74 |
|
75 |
-
|
76 |
-
|
|
|
77 |
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
// We have new rows
|
88 |
-
// Append strings
|
89 |
-
$textRowsFound = sprintf( _n( '1 new event', '%d new events', $numNewRows, 'simple-history' ), $numNewRows );
|
90 |
-
$json_data['strings'] = array(
|
91 |
-
'newRowsFound' => $textRowsFound,
|
92 |
-
);
|
93 |
-
|
94 |
-
}
|
95 |
-
|
96 |
-
wp_send_json_success( $json_data );
|
97 |
-
|
98 |
-
}
|
99 |
|
|
|
|
|
100 |
} // class
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Dropin Name: New Items Notifier
|
9 |
* Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
+
class SimpleHistoryNewRowsNotifier
|
13 |
+
{
|
14 |
|
15 |
+
// Simple History instance
|
16 |
+
private $sh;
|
17 |
|
18 |
+
// How often we should check for new rows, in ms
|
19 |
+
private $interval = 10000;
|
20 |
|
21 |
+
function __construct($sh)
|
22 |
+
{
|
23 |
|
24 |
+
$this->sh = $sh;
|
25 |
|
26 |
+
// How often the script checks for new rows
|
27 |
+
$this->interval = (int) apply_filters('SimpleHistoryNewRowsNotifier/interval', $this->interval);
|
28 |
|
29 |
+
add_action('wp_ajax_SimpleHistoryNewRowsNotifier', array( $this, 'ajax' ));
|
30 |
+
add_action('simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ));
|
31 |
+
}
|
32 |
|
33 |
+
public function enqueue_admin_scripts()
|
34 |
+
{
|
35 |
|
36 |
+
$file_url = plugin_dir_url(__FILE__);
|
37 |
|
38 |
+
wp_enqueue_script('simple_history_NewRowsNotifierDropin', $file_url . 'SimpleHistoryNewRowsNotifierDropin.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true);
|
39 |
|
40 |
+
$arr_localize_data = array(
|
41 |
+
'interval' => $this->interval,
|
42 |
+
'errorCheck' => _x('An error occured while checking for new events', 'New rows notifier: error while checking for new rows', 'simple-history'),
|
43 |
+
);
|
44 |
|
45 |
+
wp_localize_script('simple_history_NewRowsNotifierDropin', 'simple_history_NewRowsNotifierDropin', $arr_localize_data);
|
|
|
|
|
|
|
46 |
|
47 |
+
wp_enqueue_style('simple_history_NewRowsNotifierDropin', $file_url . 'SimpleHistoryNewRowsNotifierDropin.css', null, SIMPLE_HISTORY_VERSION);
|
48 |
+
}
|
49 |
|
50 |
+
public function ajax()
|
51 |
+
{
|
52 |
|
53 |
+
$apiArgs = isset($_GET['apiArgs']) ? $_GET['apiArgs'] : array();
|
54 |
|
55 |
+
if (! $apiArgs) {
|
56 |
+
wp_send_json_error(array(
|
57 |
+
'error' => 'MISSING_APIARGS',
|
58 |
+
));
|
59 |
+
}
|
60 |
|
61 |
+
if (empty($apiArgs['since_id']) || ! is_numeric($apiArgs['since_id'])) {
|
62 |
+
wp_send_json_error(array(
|
63 |
+
'error' => 'MISSING_SINCE_ID',
|
64 |
+
));
|
65 |
+
}
|
66 |
|
67 |
+
// User must have capability to view the history page
|
68 |
+
if (! current_user_can($this->sh->get_view_history_capability())) {
|
69 |
+
wp_send_json_error(array(
|
70 |
+
'error' => 'CAPABILITY_ERROR',
|
71 |
+
));
|
72 |
+
}
|
73 |
|
74 |
+
// $since_id = isset( $_GET["since_id"] ) ? absint($_GET["since_id"]) : null;
|
75 |
+
$logQueryArgs = $apiArgs;
|
|
|
|
|
|
|
76 |
|
77 |
+
$logQuery = new SimpleHistoryLogQuery();
|
78 |
+
$answer = $logQuery->query($logQueryArgs);
|
|
|
|
|
|
|
|
|
79 |
|
80 |
+
// Use our own response array instead of $answer to keep size down
|
81 |
+
$json_data = array();
|
82 |
|
83 |
+
$numNewRows = isset($answer['total_row_count']) ? $answer['total_row_count'] : 0;
|
84 |
+
$json_data['num_new_rows'] = $numNewRows;
|
85 |
+
$json_data['num_mysql_queries'] = get_num_queries();
|
86 |
|
87 |
+
if ($numNewRows) {
|
88 |
+
// We have new rows
|
89 |
+
// Append strings
|
90 |
+
$textRowsFound = sprintf(_n('1 new event', '%d new events', $numNewRows, 'simple-history'), $numNewRows);
|
91 |
+
$json_data['strings'] = array(
|
92 |
+
'newRowsFound' => $textRowsFound,
|
93 |
+
);
|
94 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
+
wp_send_json_success($json_data);
|
97 |
+
}
|
98 |
} // class
|
dropins/SimpleHistoryPluginPatchesDropin.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
defined(
|
3 |
|
4 |
/*
|
5 |
Dropin Name: Plugin Patches
|
@@ -8,163 +8,163 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistoryPluginPatchesDropin
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
} // end class
|
1 |
<?php
|
2 |
+
defined('ABSPATH') or die();
|
3 |
|
4 |
/*
|
5 |
Dropin Name: Plugin Patches
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistoryPluginPatchesDropin
|
12 |
+
{
|
13 |
+
|
14 |
+
private $sh;
|
15 |
+
|
16 |
+
function __construct($sh)
|
17 |
+
{
|
18 |
+
|
19 |
+
$this->sh = $sh;
|
20 |
+
|
21 |
+
$this->patch_captcha_on_login();
|
22 |
+
|
23 |
+
add_filter(
|
24 |
+
'simple_history/post_logger/skip_posttypes',
|
25 |
+
array( $this, 'woocommerce_skip_scheduled_actions_posttype' )
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Skip logging of WooCommerce scheduled actions/cron related things,
|
31 |
+
* stored in the scheduled-action"post type. If not disabled the log can be filled with
|
32 |
+
* a large amount of actions for this postype.
|
33 |
+
*
|
34 |
+
* @since 2.3
|
35 |
+
*/
|
36 |
+
public function woocommerce_skip_scheduled_actions_posttype($skip_posttypes)
|
37 |
+
{
|
38 |
+
$skip_posttypes[] = 'scheduled-action';
|
39 |
+
return $skip_posttypes;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Captcha on Login
|
44 |
+
*
|
45 |
+
* Calls wp_logut() wrongly when
|
46 |
+
* - a user IP is blocked
|
47 |
+
* - when max num of tries is reached
|
48 |
+
* - or when the capcha is not correct
|
49 |
+
*
|
50 |
+
* So the event logged will be logged_out but should be user_login_failed or user_unknown_login_failed.
|
51 |
+
* Wrong events logged reported here:
|
52 |
+
* https://wordpress.org/support/topic/many-unknown-logged-out-entries
|
53 |
+
*
|
54 |
+
* Plugin also gives lots of errors, reported by me here:
|
55 |
+
* https://wordpress.org/support/topic/errors-has_cap-deprecated-strict-standards-warning
|
56 |
+
*/
|
57 |
+
function patch_captcha_on_login()
|
58 |
+
{
|
59 |
+
|
60 |
+
add_action('simple_history/log/do_log', array( $this, 'patch_captcha_on_login_on_log' ), 10, 5);
|
61 |
+
}
|
62 |
+
|
63 |
+
// Detect that this log message is being called from Captha on login
|
64 |
+
// and that the message is "user_logged_out"
|
65 |
+
function patch_captcha_on_login_on_log($doLog, $level = null, $message = null, $context = null, $loggerInstance = null)
|
66 |
+
{
|
67 |
+
|
68 |
+
if (empty($context) || ! isset($context['_message_key']) || 'user_logged_out' != $context['_message_key']) {
|
69 |
+
// Message key did not exist or was not "user_logged_out"
|
70 |
+
return $doLog;
|
71 |
+
}
|
72 |
+
|
73 |
+
// 22 nov 2015: disabled this check beacuse for example robots/scripts don't pass all args
|
74 |
+
// instead they only post "log" and "pwd"
|
75 |
+
// codiga is the input with the captcha
|
76 |
+
/*
|
77 |
+
if ( ! isset( $_POST["log"], $_POST["pwd"], $_POST["wp-submit"], $_POST["codigo"] ) ) {
|
78 |
+
// All needed post variables was not set
|
79 |
+
return $doLog;
|
80 |
+
}
|
81 |
+
*/
|
82 |
+
|
83 |
+
// The Captcha on login uses a class called 'Anderson_Makiyama_Captcha_On_Login'
|
84 |
+
// and also a global variable called $global $anderson_makiyama
|
85 |
+
global $anderson_makiyama;
|
86 |
+
if (! class_exists('Anderson_Makiyama_Captcha_On_Login') || ! isset($anderson_makiyama)) {
|
87 |
+
return $doLog;
|
88 |
+
}
|
89 |
+
|
90 |
+
// We must come from wp-login
|
91 |
+
// Disabled 22 nov 2015 because robots/scripts dont send referer
|
92 |
+
/*
|
93 |
+
$wp_referer = wp_get_referer();
|
94 |
+
if ( ! $wp_referer || ! "wp-login.php" == basename( $wp_referer ) ) {
|
95 |
+
return $doLog;
|
96 |
+
}
|
97 |
+
*/
|
98 |
+
|
99 |
+
if (! isset($_SERVER['REQUEST_URI'])) {
|
100 |
+
return $doLog;
|
101 |
+
}
|
102 |
+
|
103 |
+
// File must be wp-login.php (can it even be another?)
|
104 |
+
$request_uri = basename(wp_unslash($_SERVER['REQUEST_URI']));
|
105 |
+
if ('wp-login.php' !== $request_uri) {
|
106 |
+
return $doLog;
|
107 |
+
}
|
108 |
+
|
109 |
+
$anderson_makiyama_indice = Anderson_Makiyama_Captcha_On_Login::PLUGIN_ID;
|
110 |
+
$capcha_on_login_class_name = $anderson_makiyama[ $anderson_makiyama_indice ]::CLASS_NAME;
|
111 |
+
|
112 |
+
$capcha_on_login_options = (array) get_option($capcha_on_login_class_name . '_options', array());
|
113 |
+
$last_100_logins = isset($capcha_on_login_options['last_100_logins']) ? (array) $capcha_on_login_options['last_100_logins'] : array();
|
114 |
+
$last_100_logins = array_reverse($last_100_logins);
|
115 |
+
|
116 |
+
// Possible messages
|
117 |
+
// - Failed: IP already blocked
|
118 |
+
// - Failed: exceeded max number of tries
|
119 |
+
// - Failed: image code did not match
|
120 |
+
// - Failed: Login or Password did not match
|
121 |
+
// - Success
|
122 |
+
$last_login_status = isset($last_100_logins[0][2]) ? $last_100_logins[0][2] : '';
|
123 |
+
|
124 |
+
// If we get here we're pretty sure we come from Captcha on login
|
125 |
+
// and that we should cancel the wp_logout message and log an failed login instead
|
126 |
+
// Get the user logger
|
127 |
+
$userLogger = $this->sh->getInstantiatedLoggerBySlug('SimpleUserLogger');
|
128 |
+
|
129 |
+
if (! $userLogger) {
|
130 |
+
return $doLog;
|
131 |
+
}
|
132 |
+
|
133 |
+
// $userLogger->warningMessage("user_unknown_login_failed", $context);
|
134 |
+
// Same context as in SimpleUserLogger
|
135 |
+
$context = array(
|
136 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
137 |
+
'server_http_user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null,
|
138 |
+
'_occasionsID' => 'SimpleUserLogger' . '/failed_user_login',
|
139 |
+
'patch_using_patch' => true,
|
140 |
+
'patch_name' => 'captcha_on_login',
|
141 |
+
);
|
142 |
+
|
143 |
+
// Append capcha message
|
144 |
+
if ($last_login_status) {
|
145 |
+
$context['patch_last_login_status'] = $last_login_status;
|
146 |
+
}
|
147 |
+
|
148 |
+
// Get user id and email and login
|
149 |
+
// Not passed to filter, but we have it in $_POST
|
150 |
+
$login_username = isset($_POST['log']) ? $_POST['log'] : null;
|
151 |
+
|
152 |
+
if ($login_username) {
|
153 |
+
$context['login_user_login'] = $login_username;
|
154 |
+
|
155 |
+
$user = get_user_by('login', $login_username);
|
156 |
+
|
157 |
+
if (is_a($user, 'WP_User')) {
|
158 |
+
$context['login_user_id'] = $user->ID;
|
159 |
+
$context['login_user_email'] = $user->user_email;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
$userLogger->warningMessage('user_login_failed', $context);
|
164 |
+
|
165 |
+
// Cancel original log event
|
166 |
+
$doLog = false;
|
167 |
+
|
168 |
+
return $doLog;
|
169 |
+
}
|
170 |
} // end class
|
dropins/SimpleHistoryRSSDropin.php
CHANGED
@@ -10,388 +10,402 @@ Author: Pär Thernström
|
|
10 |
/**
|
11 |
* Simple History RSS Feed drop-in
|
12 |
*/
|
13 |
-
class SimpleHistoryRSSDropin
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
} // end rss class
|
10 |
/**
|
11 |
* Simple History RSS Feed drop-in
|
12 |
*/
|
13 |
+
class SimpleHistoryRSSDropin
|
14 |
+
{
|
15 |
+
|
16 |
+
|
17 |
+
public function __construct($sh)
|
18 |
+
{
|
19 |
+
|
20 |
+
$this->sh = $sh;
|
21 |
+
|
22 |
+
if (! function_exists('get_editable_roles')) {
|
23 |
+
require_once(ABSPATH . '/wp-admin/includes/user.php');
|
24 |
+
}
|
25 |
+
|
26 |
+
// Check the status of the RSS feed
|
27 |
+
$this->isRssEnabled();
|
28 |
+
|
29 |
+
// Generate a rss secret, if it does not exist
|
30 |
+
if (! get_option('simple_history_rss_secret')) {
|
31 |
+
$this->updateRssSecret();
|
32 |
+
}
|
33 |
+
|
34 |
+
add_action('init', array( $this, 'checkForRssFeedRequest' ));
|
35 |
+
|
36 |
+
// Add settings with prio 11 so it' added after the main Simple History settings
|
37 |
+
add_action('admin_menu', array( $this, 'addSettings' ), 11);
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Add settings for the RSS feed
|
42 |
+
* + also regenerates the secret if requested
|
43 |
+
*/
|
44 |
+
public function addSettings()
|
45 |
+
{
|
46 |
+
|
47 |
+
// we register a setting to keep track of the RSS feed status (enabled/disabled)
|
48 |
+
register_setting(
|
49 |
+
SimpleHistory::SETTINGS_GENERAL_OPTION_GROUP,
|
50 |
+
'simple_history_enable_rss_feed',
|
51 |
+
array(
|
52 |
+
$this,
|
53 |
+
'public updateRssStatus',
|
54 |
+
)
|
55 |
+
);
|
56 |
+
/**
|
57 |
+
* Start new section for RSS feed
|
58 |
+
*/
|
59 |
+
$settings_section_rss_id = 'simple_history_settings_section_rss';
|
60 |
+
|
61 |
+
add_settings_section(
|
62 |
+
$settings_section_rss_id,
|
63 |
+
_x('RSS feed', 'rss settings headline', 'simple-history'), // No title __("General", "simple-history"),
|
64 |
+
array( $this, 'settingsSectionOutput' ),
|
65 |
+
SimpleHistory::SETTINGS_MENU_SLUG // same slug as for options menu page
|
66 |
+
);
|
67 |
+
|
68 |
+
// Enable/Disabled RSS feed
|
69 |
+
add_settings_field(
|
70 |
+
'simple_history_enable_rss_feed',
|
71 |
+
__('Enable', 'simple-history'),
|
72 |
+
array( $this, 'settingsFieldRssEnable' ),
|
73 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
74 |
+
$settings_section_rss_id
|
75 |
+
);
|
76 |
+
|
77 |
+
// if RSS is activated we display other fields
|
78 |
+
if ($this->isRssEnabled()) {
|
79 |
+
// RSS address
|
80 |
+
add_settings_field(
|
81 |
+
'simple_history_rss_feed',
|
82 |
+
__('Address', 'simple-history'),
|
83 |
+
array( $this, 'settingsFieldRss' ),
|
84 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
85 |
+
$settings_section_rss_id
|
86 |
+
);
|
87 |
+
|
88 |
+
// Regnerate address
|
89 |
+
add_settings_field(
|
90 |
+
'simple_history_rss_feed_regenerate_secret',
|
91 |
+
__('Regenerate', 'simple-history'),
|
92 |
+
array( $this, 'settingsFieldRssRegenerate' ),
|
93 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
94 |
+
$settings_section_rss_id
|
95 |
+
);
|
96 |
+
}
|
97 |
+
|
98 |
+
// Create new RSS secret
|
99 |
+
$create_new_secret = false;
|
100 |
+
$create_secret_nonce_name = 'simple_history_rss_secret_regenerate_nonce';
|
101 |
+
$createNonceOk = isset($_GET[ $create_secret_nonce_name ]) && wp_verify_nonce($_GET[ $create_secret_nonce_name ], 'simple_history_rss_update_secret');
|
102 |
+
|
103 |
+
if ($createNonceOk) {
|
104 |
+
$create_new_secret = true;
|
105 |
+
$this->updateRssSecret();
|
106 |
+
|
107 |
+
// Add updated-message and store in transient and then redirect
|
108 |
+
// This is the way options.php does it.
|
109 |
+
$msg = __('Created new secret RSS address', 'simple-history');
|
110 |
+
add_settings_error('simple_history_rss_feed_regenerate_secret', 'simple_history_rss_feed_regenerate_secret', $msg, 'updated');
|
111 |
+
set_transient('settings_errors', get_settings_errors(), 30);
|
112 |
+
|
113 |
+
$goback = esc_url_raw(add_query_arg('settings-updated', 'true', wp_get_referer()));
|
114 |
+
wp_redirect($goback);
|
115 |
+
exit;
|
116 |
+
}
|
117 |
+
} // settings
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Check if RSS feed is enabled or disabled
|
121 |
+
*/
|
122 |
+
public function isRssEnabled()
|
123 |
+
{
|
124 |
+
|
125 |
+
// User has never used the plugin we disable RSS feed
|
126 |
+
if (get_option('simple_history_rss_secret') === false && get_option('simple_history_enable_rss_feed') === false) {
|
127 |
+
// We disable RSS by default, we use 0/1 to prevent fake disabled with bools from functions returning false for unset
|
128 |
+
update_option('simple_history_enable_rss_feed', '0');
|
129 |
+
} elseif (get_option('simple_history_enable_rss_feed') === false) {
|
130 |
+
// User was using the plugin before RSS feed became disabled by default
|
131 |
+
// We activate RSS to prevent a "breaking change"
|
132 |
+
update_option('simple_history_enable_rss_feed', '1');
|
133 |
+
return true;
|
134 |
+
} elseif (get_option('simple_history_enable_rss_feed') === '1') {
|
135 |
+
return true;
|
136 |
+
}
|
137 |
+
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Output for settings field that show current RSS address
|
143 |
+
*/
|
144 |
+
public function settingsFieldRssEnable()
|
145 |
+
{
|
146 |
+
?>
|
147 |
+
<input value="1" type="checkbox" id="simple_history_enable_rss_feed" name="simple_history_enable_rss_feed" <?php checked($this->isRssEnabled(), 1); ?> />
|
148 |
+
<label for="simple_history_enable_rss_feed"><?php _e('Enable RSS feed', 'simple-history') ?></label>
|
149 |
+
<?php
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Sanitize RSS enabled/disabled status on update settings
|
154 |
+
*/
|
155 |
+
public function updateRssStatus($field)
|
156 |
+
{
|
157 |
+
|
158 |
+
if ($field === '1') {
|
159 |
+
return '1';
|
160 |
+
}
|
161 |
+
|
162 |
+
return '0';
|
163 |
+
}
|
164 |
+
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Check if current request is a request for the RSS feed
|
168 |
+
*/
|
169 |
+
public function checkForRssFeedRequest()
|
170 |
+
{
|
171 |
+
// check for RSS
|
172 |
+
// don't know if this is the right way to do this, but it seems to work!
|
173 |
+
if (isset($_GET['simple_history_get_rss'])) {
|
174 |
+
$this->outputRss();
|
175 |
+
exit;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Modify capability check so all users reading rss feed (logged in or not) can read all loggers
|
181 |
+
*/
|
182 |
+
public function onCanReadSingleLogger($user_can_read_logger, $logger_instance, $user_id)
|
183 |
+
{
|
184 |
+
$user_can_read_logger = true;
|
185 |
+
|
186 |
+
return $user_can_read_logger;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Output RSS
|
191 |
+
*/
|
192 |
+
public function outputRss()
|
193 |
+
{
|
194 |
+
|
195 |
+
$rss_secret_option = get_option('simple_history_rss_secret');
|
196 |
+
$rss_secret_get = isset($_GET['rss_secret']) ? $_GET['rss_secret'] : '';
|
197 |
+
|
198 |
+
if (empty($rss_secret_option) || empty($rss_secret_get)) {
|
199 |
+
die();
|
200 |
+
}
|
201 |
+
|
202 |
+
$rss_show = true;
|
203 |
+
$rss_show = apply_filters('simple_history/rss_feed_show', $rss_show);
|
204 |
+
if (! $rss_show || ! $this->isRssEnabled()) {
|
205 |
+
wp_die('Nothing here.');
|
206 |
+
}
|
207 |
+
|
208 |
+
header('Content-Type: text/xml; charset=utf-8');
|
209 |
+
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
210 |
+
$self_link = $this->getRssAddress();
|
211 |
+
|
212 |
+
if ($rss_secret_option === $rss_secret_get) {
|
213 |
+
?>
|
214 |
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
215 |
+
<channel>
|
216 |
+
<title><![CDATA[<?php printf(__('History for %s', 'simple-history'), get_bloginfo('name')) ?>]]></title>
|
217 |
+
<description><![CDATA[<?php printf(__('WordPress History for %s', 'simple-history'), get_bloginfo('name')) ?>]]></description>
|
218 |
+
<link><?php echo get_bloginfo('url') ?></link>
|
219 |
+
<atom:link href="<?php echo $self_link; ?>" rel="self" type="application/atom+xml" />
|
220 |
+
<?php
|
221 |
+
|
222 |
+
// Override capability check: if you have a valid rss_secret_key you can read it all
|
223 |
+
$action_tag = 'simple_history/loggers_user_can_read/can_read_single_logger';
|
224 |
+
add_action($action_tag, array( $this, 'onCanReadSingleLogger' ), 10, 3);
|
225 |
+
|
226 |
+
// Modify header time output so it does not show relative date or time ago-format
|
227 |
+
// Because we don't know when a user reads the RSS feed, time ago format may be very inaccurate
|
228 |
+
add_action('simple_history/header_just_now_max_time', '__return_zero');
|
229 |
+
add_action('simple_history/header_time_ago_max_time', '__return_zero');
|
230 |
+
|
231 |
+
// Get log rows
|
232 |
+
$args = array(
|
233 |
+
'posts_per_page' => 10,
|
234 |
+
);
|
235 |
+
|
236 |
+
$args = apply_filters('simple_history/rss_feed_args', $args);
|
237 |
+
|
238 |
+
$logQuery = new SimpleHistoryLogQuery();
|
239 |
+
$queryResults = $logQuery->query($args);
|
240 |
+
|
241 |
+
// Remove capability override after query is done
|
242 |
+
// remove_action( $action_tag, array($this, "onCanReadSingleLogger") );
|
243 |
+
foreach ($queryResults['log_rows'] as $row) {
|
244 |
+
$header_output = $this->sh->getLogRowHeaderOutput($row);
|
245 |
+
$text_output = $this->sh->getLogRowPlainTextOutput($row);
|
246 |
+
$details_output = $this->sh->getLogRowDetailsOutput($row);
|
247 |
+
|
248 |
+
// http://cyber.law.harvard.edu/rss/rss.html#ltguidgtSubelementOfLtitemgt
|
249 |
+
// $item_guid = home_url() . "?SimpleHistoryGuid=" . $row->id;
|
250 |
+
$item_guid = esc_url(add_query_arg('SimpleHistoryGuid', $row->id, home_url()));
|
251 |
+
$item_link = esc_url(add_query_arg('SimpleHistoryGuid', $row->id, home_url()));
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Filter the guid/link URL used in RSS feed.
|
255 |
+
* Link will be esc_url'ed by simple history, so no need to do that in your filter
|
256 |
+
*
|
257 |
+
* @since 2.0.23
|
258 |
+
*
|
259 |
+
* @param string $item_guid link.
|
260 |
+
* @param array $row
|
261 |
+
*/
|
262 |
+
$item_link = apply_filters('simple_history/rss_item_link', $item_link, $row);
|
263 |
+
$item_link = esc_url($item_link);
|
264 |
+
|
265 |
+
$item_title = sprintf(
|
266 |
+
'%2$s',
|
267 |
+
$this->sh->getLogLevelTranslated($row->level),
|
268 |
+
wp_kses($text_output, array())
|
269 |
+
);
|
270 |
+
|
271 |
+
$level_output = sprintf(__('Severity level: %1$s'), $this->sh->getLogLevelTranslated($row->level));
|
272 |
+
|
273 |
+
?>
|
274 |
+
<item>
|
275 |
+
<title><![CDATA[<?php echo $item_title; ?>]]></title>
|
276 |
+
<description><![CDATA[
|
277 |
+
<p><?php echo $header_output ?></p>
|
278 |
+
<p><?php echo $text_output ?></p>
|
279 |
+
<div><?php echo $details_output ?></div>
|
280 |
+
<p><?php echo $level_output ?></p>
|
281 |
+
<?php
|
282 |
+
$occasions = $row->subsequentOccasions - 1;
|
283 |
+
if ($occasions) {
|
284 |
+
printf(
|
285 |
+
_n('+%1$s occasion', '+%1$s occasions', $occasions, 'simple-history'),
|
286 |
+
$occasions
|
287 |
+
);
|
288 |
+
}
|
289 |
+
?>
|
290 |
+
]]></description>
|
291 |
+
<?php
|
292 |
+
// author must be email to validate, but the field is optional, so we skip it
|
293 |
+
/* <author><?php echo $row->initiator ?></author> */
|
294 |
+
?>
|
295 |
+
<pubDate><?php echo date('D, d M Y H:i:s', strtotime($row->date)) ?> GMT</pubDate>
|
296 |
+
<guid isPermaLink="false"><![CDATA[<?php echo $item_guid ?>]]></guid>
|
297 |
+
<link><![CDATA[<?php echo $item_link ?>]]></link>
|
298 |
+
</item>
|
299 |
+
<?php
|
300 |
+
} // End foreach().
|
301 |
+
|
302 |
+
?>
|
303 |
+
</channel>
|
304 |
+
</rss>
|
305 |
+
<?php
|
306 |
+
} else {
|
307 |
+
// RSS secret was not ok
|
308 |
+
?>
|
309 |
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
310 |
+
<channel>
|
311 |
+
<title><?php printf(__('History for %s', 'simple-history'), get_bloginfo('name')) ?></title>
|
312 |
+
<description><?php printf(__('WordPress History for %s', 'simple-history'), get_bloginfo('name')) ?></description>
|
313 |
+
<link><?php echo home_url() ?></link>
|
314 |
+
<item>
|
315 |
+
<title><?php _e('Wrong RSS secret', 'simple-history')?></title>
|
316 |
+
<description><?php _e('Your RSS secret for Simple History RSS feed is wrong. Please see WordPress settings for current link to the RSS feed.', 'simple-history')?></description>
|
317 |
+
<pubDate><?php echo date('D, d M Y H:i:s', time()) ?> GMT</pubDate>
|
318 |
+
<guid><?php echo home_url() . '?SimpleHistoryGuid=wrong-secret' ?></guid>
|
319 |
+
</item>
|
320 |
+
</channel>
|
321 |
+
</rss>
|
322 |
+
<?php
|
323 |
+
}// End if().
|
324 |
+
} // rss
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Create a new RSS secret
|
328 |
+
*
|
329 |
+
* @return string new secret
|
330 |
+
*/
|
331 |
+
public function updateRssSecret()
|
332 |
+
{
|
333 |
+
|
334 |
+
$rss_secret = '';
|
335 |
+
|
336 |
+
for ($i = 0; $i < 20; $i++) {
|
337 |
+
$rss_secret .= chr(rand(97, 122));
|
338 |
+
}
|
339 |
+
|
340 |
+
update_option('simple_history_rss_secret', $rss_secret);
|
341 |
+
|
342 |
+
return $rss_secret;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Output for settings field that show current RSS address
|
347 |
+
*/
|
348 |
+
public function settingsFieldRss()
|
349 |
+
{
|
350 |
+
|
351 |
+
$rss_address = $this->getRssAddress();
|
352 |
+
|
353 |
+
echo "<p><code><a href='$rss_address'>$rss_address</a></code></p>";
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Output for settings field that regenerates the RSS adress/secret
|
358 |
+
*/
|
359 |
+
public function settingsFieldRssRegenerate()
|
360 |
+
{
|
361 |
+
|
362 |
+
$update_link = esc_url(add_query_arg('', ''));
|
363 |
+
$update_link = wp_nonce_url($update_link, 'simple_history_rss_update_secret', 'simple_history_rss_secret_regenerate_nonce');
|
364 |
+
|
365 |
+
echo '<p>';
|
366 |
+
_e('You can generate a new address for the RSS feed. This is useful if you think that the address has fallen into the wrong hands.', 'simple-history');
|
367 |
+
echo '</p>';
|
368 |
+
|
369 |
+
echo '<p>';
|
370 |
+
printf(
|
371 |
+
'<a class="button" href="%1$s">%2$s</a>',
|
372 |
+
$update_link, // 1
|
373 |
+
__('Generate new address', 'simple-history') // 2
|
374 |
+
);
|
375 |
+
|
376 |
+
echo '</p>';
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* Get the URL to the RSS feed
|
381 |
+
*
|
382 |
+
* @return string URL
|
383 |
+
*/
|
384 |
+
public function getRssAddress()
|
385 |
+
{
|
386 |
+
|
387 |
+
$rss_secret = get_option('simple_history_rss_secret');
|
388 |
+
$rss_address = add_query_arg(
|
389 |
+
array(
|
390 |
+
'simple_history_get_rss' => '1',
|
391 |
+
'rss_secret' => $rss_secret,
|
392 |
+
),
|
393 |
+
get_bloginfo('url') . '/'
|
394 |
+
);
|
395 |
+
$rss_address = esc_url($rss_address);
|
396 |
+
// $rss_address = htmlspecialchars($rss_address, ENT_COMPAT, "UTF-8");
|
397 |
+
return $rss_address;
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Content for section intro. Leave it be, even if empty.
|
402 |
+
* Called from add_sections_setting.
|
403 |
+
*/
|
404 |
+
public function settingsSectionOutput()
|
405 |
+
{
|
406 |
+
|
407 |
+
echo '<p>';
|
408 |
+
_e('Simple History has a RSS feed which you can subscribe to and receive log updates. Make sure you only share the feed with people you trust, since it can contain sensitive or confidential information.', 'simple-history');
|
409 |
+
echo '</p>';
|
410 |
+
}
|
411 |
} // end rss class
|
dropins/SimpleHistorySettingsDebugDropin.php
CHANGED
@@ -7,41 +7,42 @@ Dropin URI: http://simple-history.com/
|
|
7 |
Author: Pär Thernström
|
8 |
*/
|
9 |
|
10 |
-
defined(
|
11 |
|
12 |
-
class SimpleHistorySettingsDebugDropin
|
|
|
13 |
|
14 |
-
|
15 |
|
16 |
-
|
|
|
17 |
|
18 |
-
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
|
27 |
-
|
28 |
-
|
29 |
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
34 |
|
35 |
-
|
36 |
-
|
37 |
|
38 |
-
|
39 |
-
|
40 |
|
41 |
-
|
42 |
-
|
43 |
-
include SIMPLE_HISTORY_PATH . 'templates/template-settings-tab-debug.php';
|
44 |
-
|
45 |
-
}
|
46 |
|
|
|
|
|
47 |
}
|
7 |
Author: Pär Thernström
|
8 |
*/
|
9 |
|
10 |
+
defined('ABSPATH') or die();
|
11 |
|
12 |
+
class SimpleHistorySettingsDebugDropin
|
13 |
+
{
|
14 |
|
15 |
+
private $sh;
|
16 |
|
17 |
+
public function __construct($sh)
|
18 |
+
{
|
19 |
|
20 |
+
$this->sh = $sh;
|
21 |
|
22 |
+
// How do we register this to the settings array?
|
23 |
+
$sh->registerSettingsTab(array(
|
24 |
+
'slug' => 'debug',
|
25 |
+
'name' => __('Debug', 'simple-history'),
|
26 |
+
'function' => array( $this, 'output' ),
|
27 |
+
));
|
28 |
|
29 |
+
// add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'on_admin_enqueue_scripts' ) );
|
30 |
+
}
|
31 |
|
32 |
+
/*
|
33 |
+
public function on_admin_enqueue_scripts() {
|
34 |
|
35 |
+
$file_url = plugin_dir_url( __FILE__ );
|
36 |
|
37 |
+
wp_enqueue_script( "google-ajax-api", "https://www.google.com/jsapi" );
|
38 |
+
wp_enqueue_style( "simple_history_SettingsStatsDropin", $file_url . "SimpleHistorySettingsStatsDropin.css", null, SIMPLE_HISTORY_VERSION );
|
39 |
|
40 |
+
}
|
41 |
+
*/
|
42 |
|
43 |
+
public function output()
|
44 |
+
{
|
|
|
|
|
|
|
45 |
|
46 |
+
include SIMPLE_HISTORY_PATH . 'templates/template-settings-tab-debug.php';
|
47 |
+
}
|
48 |
}
|
dropins/SimpleHistorySettingsLogtestDropin.php
CHANGED
@@ -1,289 +1,293 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
-
class SimpleHistorySettingsLogtestDropin
|
|
|
6 |
|
7 |
-
|
8 |
-
|
9 |
|
10 |
-
|
|
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
|
17 |
-
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
29 |
|
30 |
-
|
|
|
31 |
|
32 |
-
|
33 |
|
34 |
-
|
|
|
|
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
);
|
39 |
|
40 |
-
|
|
|
41 |
|
42 |
-
|
|
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
?>
|
47 |
-
<script>
|
48 |
-
|
49 |
-
jQuery(function($) {
|
50 |
-
|
51 |
-
var button = $(".js-SimpleHistorySettingsLogtestDropin-addStuff");
|
52 |
-
var messageDone = $(".js-SimpleHistorySettingsLogtestDropin-addStuffDone");
|
53 |
-
var messageWorking = $(".js-SimpleHistorySettingsLogtestDropin-addStuffWorking");
|
54 |
-
|
55 |
-
button.on("click", function(e) {
|
56 |
-
|
57 |
-
messageWorking.show();
|
58 |
-
messageDone.hide();
|
59 |
-
|
60 |
-
$.post(ajaxurl, {
|
61 |
-
action: "SimpleHistoryAddLogTest"
|
62 |
-
}).done(function(r) {
|
63 |
-
|
64 |
-
messageWorking.hide();
|
65 |
-
messageDone.show();
|
66 |
-
|
67 |
-
});
|
68 |
-
|
69 |
-
});
|
70 |
-
|
71 |
-
});
|
72 |
-
|
73 |
-
|
74 |
-
</script>
|
75 |
-
<?php
|
76 |
-
|
77 |
-
}
|
78 |
-
|
79 |
-
public function output() {
|
80 |
-
|
81 |
-
?>
|
82 |
-
<h1>Test data</h1>
|
83 |
-
|
84 |
-
<p>Add lots of test data to the log database.</p>
|
85 |
-
|
86 |
-
<p>
|
87 |
-
<button class="button js-SimpleHistorySettingsLogtestDropin-addStuff">Ok, add lots of stuff to the log!</button>
|
88 |
-
</p>
|
89 |
-
|
90 |
-
<div class="updated hidden js-SimpleHistorySettingsLogtestDropin-addStuffDone">
|
91 |
-
<p>Done! Added lots of test rows</p>
|
92 |
-
</div>
|
93 |
-
|
94 |
-
<div class="updated hidden js-SimpleHistorySettingsLogtestDropin-addStuffWorking">
|
95 |
-
<p>Adding...</p>
|
96 |
-
</div>
|
97 |
-
|
98 |
-
<?php
|
99 |
-
|
100 |
-
}
|
101 |
-
|
102 |
-
public function doLogTestThings() {
|
103 |
-
|
104 |
-
// Add some data random back in time, to fill up the log to test much data
|
105 |
-
for ( $j = 0; $j < 50; $j++ ) {
|
106 |
-
// between yesteday and a month back in time
|
107 |
-
for ( $i = 0; $i < rand( 1,30 ); $i++ ) {
|
108 |
-
$str_date = date( 'Y-m-d H:i:s', strtotime( "now -{$i}days" ) );
|
109 |
-
SimpleLogger()->info(
|
110 |
-
'Entry with date in the past', array(
|
111 |
-
'_date' => $str_date,
|
112 |
-
'_occasionsID' => "past_date:{$str_date}",
|
113 |
-
));
|
114 |
-
}
|
115 |
-
}
|
116 |
-
|
117 |
-
SimpleLogger()->info( 'This is a message sent to the log' );
|
118 |
-
|
119 |
-
// Second log entry with same info will make these two become an occasionGroup,
|
120 |
-
// collapsing their entries into one expandable log item
|
121 |
-
SimpleLogger()->info( 'This is a message sent to the log' );
|
122 |
-
|
123 |
-
// Log entries can be of different severity
|
124 |
-
SimpleLogger()->info( "User admin edited page 'About our company'" );
|
125 |
-
SimpleLogger()->warning( "User 'Jessie' deleted user 'Kim'" );
|
126 |
-
SimpleLogger()->debug( 'Ok, cron job is running!' );
|
127 |
-
|
128 |
-
// Log entries can have placeholders and context
|
129 |
-
// This makes log entried translatable and filterable
|
130 |
-
for ( $i = 0; $i < rand( 1, 50 ); $i++ ) {
|
131 |
-
SimpleLogger()->notice(
|
132 |
-
'User {username} edited page {pagename}',
|
133 |
-
array(
|
134 |
-
'username' => 'bonnyerden',
|
135 |
-
'pagename' => 'My test page',
|
136 |
-
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
137 |
-
'_user_id' => rand( 1,20 ),
|
138 |
-
'_user_login' => 'loginname' . rand( 1,20 ),
|
139 |
-
'_user_email' => 'user' . rand( 1,20 ) . '@example.com',
|
140 |
-
)
|
141 |
-
);
|
142 |
-
}
|
143 |
-
// return;
|
144 |
-
// Log entried can have custom occasionsID
|
145 |
-
// This will group items together and a log entry will only be shown once
|
146 |
-
// in the log overview
|
147 |
-
for ( $i = 0; $i < rand( 1, 50 ); $i++ ) {
|
148 |
-
SimpleLogger()->notice('User {username} edited page {pagename}', array(
|
149 |
-
'username' => 'admin',
|
150 |
-
'pagename' => 'My test page',
|
151 |
-
'_occasionsID' => 'username:1,postID:24884,action:edited',
|
152 |
-
));
|
153 |
-
}
|
154 |
-
|
155 |
-
SimpleLogger()->info(
|
156 |
-
'WordPress updated itself from version {from_version} to {to_version}',
|
157 |
-
array(
|
158 |
-
'from_version' => '3.8',
|
159 |
-
'to_version' => '3.8.1',
|
160 |
-
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
161 |
-
)
|
162 |
-
);
|
163 |
-
|
164 |
-
SimpleLogger()->info(
|
165 |
-
'Plugin {plugin_name} was updated from version {plugin_from_version} to version {plugin_to_version}',
|
166 |
-
array(
|
167 |
-
'plugin_name' => 'CMS Tree Page View',
|
168 |
-
'plugin_from_version' => '4.0',
|
169 |
-
'plugin_to_version' => '4.2',
|
170 |
-
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
171 |
-
)
|
172 |
-
);
|
173 |
-
|
174 |
-
SimpleLogger()->info(
|
175 |
-
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
176 |
-
array(
|
177 |
-
'plugin_name' => 'Ninja Forms',
|
178 |
-
'plugin_from_version' => '1.1',
|
179 |
-
'plugin_to_version' => '1.1.2',
|
180 |
-
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
181 |
-
)
|
182 |
-
);
|
183 |
-
|
184 |
-
SimpleLogger()->warning("An attempt to login as user 'administrator' failed to login because the wrong password was entered", array(
|
185 |
-
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
186 |
-
));
|
187 |
-
|
188 |
-
SimpleLogger()->info(
|
189 |
-
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
190 |
-
array(
|
191 |
-
'plugin_name' => 'Simple Fields',
|
192 |
-
'plugin_from_version' => '1.3.7',
|
193 |
-
'plugin_to_version' => '1.3.8',
|
194 |
-
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
195 |
-
)
|
196 |
-
);
|
197 |
-
|
198 |
-
SimpleLogger()->error("A JavaScript error was detected on page 'About us'", array(
|
199 |
-
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
200 |
-
));
|
201 |
-
|
202 |
-
SimpleLogger()->debug("WP Cron 'my_test_cron_job' finished in 0.012 seconds", array(
|
203 |
-
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
204 |
-
));
|
205 |
-
|
206 |
-
for ( $i = 0; $i < rand( 50,1000 ); $i++ ) {
|
207 |
-
SimpleLogger()->warning(
|
208 |
-
'An attempt to login as user "{user_login}" failed to login because the wrong password was entered', array(
|
209 |
-
'user_login' => 'admin',
|
210 |
-
'_userID' => null,
|
211 |
-
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
212 |
-
));
|
213 |
-
}
|
214 |
-
|
215 |
-
// Add more data to context array. Data can be used later on to show detailed info about a log entry.
|
216 |
-
SimpleLogger()->info("Edited product '{pagename}'", array(
|
217 |
-
'pagename' => 'We are hiring!',
|
218 |
-
'_postType' => 'product',
|
219 |
-
'_userID' => 1,
|
220 |
-
'_userLogin' => 'jessie',
|
221 |
-
'_userEmail' => 'jessie@example.com',
|
222 |
-
'_occasionsID' => 'username:1,postID:24885,action:edited',
|
223 |
-
));
|
224 |
-
|
225 |
-
SimpleLogger()->debug( 'This is a message with no translation' );
|
226 |
-
SimpleLogger()->debug( __( 'Plugin' ), array(
|
227 |
-
'comment' => "This message is 'Plugin' and should contain text domain 'default' since it's a translation that comes with WordPress",
|
228 |
-
) );
|
229 |
-
SimpleLogger()->debug( __( 'Enter title of new page', 'cms-tree-page-view' ), array(
|
230 |
-
'comment' => 'A translation used in CMS Tree Page View',
|
231 |
-
) );
|
232 |
-
|
233 |
-
}
|
234 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
}
|
236 |
|
237 |
|
238 |
/*
|
239 |
add_action("init", function() {
|
240 |
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
|
288 |
});
|
289 |
*/
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
+
class SimpleHistorySettingsLogtestDropin
|
6 |
+
{
|
7 |
|
8 |
+
// Simple History instance
|
9 |
+
private $sh;
|
10 |
|
11 |
+
public function __construct($sh)
|
12 |
+
{
|
13 |
|
14 |
+
// Since it's not quite done yet, it's for da devs only for now
|
15 |
+
if (! defined('SIMPLE_HISTORY_DEV') || ! SIMPLE_HISTORY_DEV) {
|
16 |
+
return;
|
17 |
+
}
|
18 |
|
19 |
+
$this->sh = $sh;
|
20 |
|
21 |
+
// How do we register this to the settings array?
|
22 |
+
$sh->registerSettingsTab(array(
|
23 |
+
'slug' => 'testLog',
|
24 |
+
'name' => __('Test data (debug)', 'simple-history'),
|
25 |
+
'function' => array( $this, 'output' ),
|
26 |
+
));
|
27 |
|
28 |
+
// add_action( 'admin_enqueue_scripts', array( $this, 'on_admin_enqueue_scripts') );
|
29 |
+
add_action('admin_head', array( $this, 'on_admin_head' ));
|
30 |
+
add_action('wp_ajax_SimpleHistoryAddLogTest', array( $this, 'on_ajax_add_logtests' ));
|
31 |
+
}
|
32 |
|
33 |
+
public function on_ajax_add_logtests()
|
34 |
+
{
|
35 |
|
36 |
+
$this->doLogTestThings();
|
37 |
|
38 |
+
$arr = array(
|
39 |
+
'message' => 'did it!',
|
40 |
+
);
|
41 |
|
42 |
+
wp_send_json_success($arr);
|
43 |
+
}
|
|
|
44 |
|
45 |
+
public function on_admin_head()
|
46 |
+
{
|
47 |
|
48 |
+
?>
|
49 |
+
<script>
|
50 |
|
51 |
+
jQuery(function($) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
var button = $(".js-SimpleHistorySettingsLogtestDropin-addStuff");
|
54 |
+
var messageDone = $(".js-SimpleHistorySettingsLogtestDropin-addStuffDone");
|
55 |
+
var messageWorking = $(".js-SimpleHistorySettingsLogtestDropin-addStuffWorking");
|
56 |
+
|
57 |
+
button.on("click", function(e) {
|
58 |
+
|
59 |
+
messageWorking.show();
|
60 |
+
messageDone.hide();
|
61 |
+
|
62 |
+
$.post(ajaxurl, {
|
63 |
+
action: "SimpleHistoryAddLogTest"
|
64 |
+
}).done(function(r) {
|
65 |
+
|
66 |
+
messageWorking.hide();
|
67 |
+
messageDone.show();
|
68 |
+
|
69 |
+
});
|
70 |
+
|
71 |
+
});
|
72 |
+
|
73 |
+
});
|
74 |
+
|
75 |
+
|
76 |
+
</script>
|
77 |
+
<?php
|
78 |
+
}
|
79 |
+
|
80 |
+
public function output()
|
81 |
+
{
|
82 |
+
|
83 |
+
?>
|
84 |
+
<h1>Test data</h1>
|
85 |
+
|
86 |
+
<p>Add lots of test data to the log database.</p>
|
87 |
+
|
88 |
+
<p>
|
89 |
+
<button class="button js-SimpleHistorySettingsLogtestDropin-addStuff">Ok, add lots of stuff to the log!</button>
|
90 |
+
</p>
|
91 |
+
|
92 |
+
<div class="updated hidden js-SimpleHistorySettingsLogtestDropin-addStuffDone">
|
93 |
+
<p>Done! Added lots of test rows</p>
|
94 |
+
</div>
|
95 |
+
|
96 |
+
<div class="updated hidden js-SimpleHistorySettingsLogtestDropin-addStuffWorking">
|
97 |
+
<p>Adding...</p>
|
98 |
+
</div>
|
99 |
+
|
100 |
+
<?php
|
101 |
+
}
|
102 |
+
|
103 |
+
public function doLogTestThings()
|
104 |
+
{
|
105 |
+
|
106 |
+
// Add some data random back in time, to fill up the log to test much data
|
107 |
+
for ($j = 0; $j < 50; $j++) {
|
108 |
+
// between yesteday and a month back in time
|
109 |
+
for ($i = 0; $i < rand(1, 30); $i++) {
|
110 |
+
$str_date = date('Y-m-d H:i:s', strtotime("now -{$i}days"));
|
111 |
+
SimpleLogger()->info(
|
112 |
+
'Entry with date in the past',
|
113 |
+
array(
|
114 |
+
'_date' => $str_date,
|
115 |
+
'_occasionsID' => "past_date:{$str_date}",
|
116 |
+
)
|
117 |
+
);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
|
121 |
+
SimpleLogger()->info('This is a message sent to the log');
|
122 |
+
|
123 |
+
// Second log entry with same info will make these two become an occasionGroup,
|
124 |
+
// collapsing their entries into one expandable log item
|
125 |
+
SimpleLogger()->info('This is a message sent to the log');
|
126 |
+
|
127 |
+
// Log entries can be of different severity
|
128 |
+
SimpleLogger()->info("User admin edited page 'About our company'");
|
129 |
+
SimpleLogger()->warning("User 'Jessie' deleted user 'Kim'");
|
130 |
+
SimpleLogger()->debug('Ok, cron job is running!');
|
131 |
+
|
132 |
+
// Log entries can have placeholders and context
|
133 |
+
// This makes log entried translatable and filterable
|
134 |
+
for ($i = 0; $i < rand(1, 50); $i++) {
|
135 |
+
SimpleLogger()->notice(
|
136 |
+
'User {username} edited page {pagename}',
|
137 |
+
array(
|
138 |
+
'username' => 'bonnyerden',
|
139 |
+
'pagename' => 'My test page',
|
140 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
141 |
+
'_user_id' => rand(1, 20),
|
142 |
+
'_user_login' => 'loginname' . rand(1, 20),
|
143 |
+
'_user_email' => 'user' . rand(1, 20) . '@example.com',
|
144 |
+
)
|
145 |
+
);
|
146 |
+
}
|
147 |
+
// return;
|
148 |
+
// Log entried can have custom occasionsID
|
149 |
+
// This will group items together and a log entry will only be shown once
|
150 |
+
// in the log overview
|
151 |
+
for ($i = 0; $i < rand(1, 50); $i++) {
|
152 |
+
SimpleLogger()->notice('User {username} edited page {pagename}', array(
|
153 |
+
'username' => 'admin',
|
154 |
+
'pagename' => 'My test page',
|
155 |
+
'_occasionsID' => 'username:1,postID:24884,action:edited',
|
156 |
+
));
|
157 |
+
}
|
158 |
+
|
159 |
+
SimpleLogger()->info(
|
160 |
+
'WordPress updated itself from version {from_version} to {to_version}',
|
161 |
+
array(
|
162 |
+
'from_version' => '3.8',
|
163 |
+
'to_version' => '3.8.1',
|
164 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
165 |
+
)
|
166 |
+
);
|
167 |
+
|
168 |
+
SimpleLogger()->info(
|
169 |
+
'Plugin {plugin_name} was updated from version {plugin_from_version} to version {plugin_to_version}',
|
170 |
+
array(
|
171 |
+
'plugin_name' => 'CMS Tree Page View',
|
172 |
+
'plugin_from_version' => '4.0',
|
173 |
+
'plugin_to_version' => '4.2',
|
174 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
175 |
+
)
|
176 |
+
);
|
177 |
+
|
178 |
+
SimpleLogger()->info(
|
179 |
+
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
180 |
+
array(
|
181 |
+
'plugin_name' => 'Ninja Forms',
|
182 |
+
'plugin_from_version' => '1.1',
|
183 |
+
'plugin_to_version' => '1.1.2',
|
184 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
185 |
+
)
|
186 |
+
);
|
187 |
+
|
188 |
+
SimpleLogger()->warning("An attempt to login as user 'administrator' failed to login because the wrong password was entered", array(
|
189 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
190 |
+
));
|
191 |
+
|
192 |
+
SimpleLogger()->info(
|
193 |
+
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
194 |
+
array(
|
195 |
+
'plugin_name' => 'Simple Fields',
|
196 |
+
'plugin_from_version' => '1.3.7',
|
197 |
+
'plugin_to_version' => '1.3.8',
|
198 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
199 |
+
)
|
200 |
+
);
|
201 |
+
|
202 |
+
SimpleLogger()->error("A JavaScript error was detected on page 'About us'", array(
|
203 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
204 |
+
));
|
205 |
+
|
206 |
+
SimpleLogger()->debug("WP Cron 'my_test_cron_job' finished in 0.012 seconds", array(
|
207 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
208 |
+
));
|
209 |
+
|
210 |
+
for ($i = 0; $i < rand(50, 1000); $i++) {
|
211 |
+
SimpleLogger()->warning(
|
212 |
+
'An attempt to login as user "{user_login}" failed to login because the wrong password was entered',
|
213 |
+
array(
|
214 |
+
'user_login' => 'admin',
|
215 |
+
'_userID' => null,
|
216 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
217 |
+
)
|
218 |
+
);
|
219 |
+
}
|
220 |
+
|
221 |
+
// Add more data to context array. Data can be used later on to show detailed info about a log entry.
|
222 |
+
SimpleLogger()->info("Edited product '{pagename}'", array(
|
223 |
+
'pagename' => 'We are hiring!',
|
224 |
+
'_postType' => 'product',
|
225 |
+
'_userID' => 1,
|
226 |
+
'_userLogin' => 'jessie',
|
227 |
+
'_userEmail' => 'jessie@example.com',
|
228 |
+
'_occasionsID' => 'username:1,postID:24885,action:edited',
|
229 |
+
));
|
230 |
+
|
231 |
+
SimpleLogger()->debug('This is a message with no translation');
|
232 |
+
SimpleLogger()->debug(__('Plugin'), array(
|
233 |
+
'comment' => "This message is 'Plugin' and should contain text domain 'default' since it's a translation that comes with WordPress",
|
234 |
+
));
|
235 |
+
SimpleLogger()->debug(__('Enter title of new page', 'cms-tree-page-view'), array(
|
236 |
+
'comment' => 'A translation used in CMS Tree Page View',
|
237 |
+
));
|
238 |
+
}
|
239 |
}
|
240 |
|
241 |
|
242 |
/*
|
243 |
add_action("init", function() {
|
244 |
|
245 |
+
register_post_type("texts", array(
|
246 |
+
"show_ui" => true
|
247 |
+
));
|
248 |
+
|
249 |
+
register_post_type("products", array(
|
250 |
+
"labels" => array(
|
251 |
+
"name" => "Products",
|
252 |
+
"singular_name" => "Product"
|
253 |
+
),
|
254 |
+
"public" => true
|
255 |
+
));
|
256 |
+
|
257 |
+
// Example from the codex
|
258 |
+
$labels = array(
|
259 |
+
'name' => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
|
260 |
+
'singular_name' => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
|
261 |
+
'menu_name' => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
|
262 |
+
'name_admin_bar' => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
|
263 |
+
'add_new' => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
|
264 |
+
'add_new_item' => __( 'Add New Book', 'your-plugin-textdomain' ),
|
265 |
+
'new_item' => __( 'New Book', 'your-plugin-textdomain' ),
|
266 |
+
'edit_item' => __( 'Edit Book', 'your-plugin-textdomain' ),
|
267 |
+
'view_item' => __( 'View Book', 'your-plugin-textdomain' ),
|
268 |
+
'all_items' => __( 'All Books', 'your-plugin-textdomain' ),
|
269 |
+
'search_items' => __( 'Search Books', 'your-plugin-textdomain' ),
|
270 |
+
'parent_item_colon' => __( 'Parent Books:', 'your-plugin-textdomain' ),
|
271 |
+
'not_found' => __( 'No books found.', 'your-plugin-textdomain' ),
|
272 |
+
'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' ),
|
273 |
+
);
|
274 |
+
|
275 |
+
$args = array(
|
276 |
+
'labels' => $labels,
|
277 |
+
'public' => true,
|
278 |
+
'publicly_queryable' => true,
|
279 |
+
'show_ui' => true,
|
280 |
+
'show_in_menu' => true,
|
281 |
+
'query_var' => true,
|
282 |
+
'rewrite' => array( 'slug' => 'book' ),
|
283 |
+
'capability_type' => 'post',
|
284 |
+
'has_archive' => true,
|
285 |
+
'hierarchical' => false,
|
286 |
+
'menu_position' => null,
|
287 |
+
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
|
288 |
+
);
|
289 |
+
|
290 |
+
register_post_type( 'book', $args );
|
291 |
|
292 |
});
|
293 |
*/
|
dropins/SimpleHistorySettingsStatsDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Settings stats
|
@@ -9,107 +9,105 @@ Dropin URI: http://simple-history.com/
|
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
-
class SimpleHistorySettingsStatsDropin
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
|
17 |
-
|
|
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
|
24 |
-
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
|
|
34 |
|
35 |
-
|
|
|
36 |
|
37 |
-
|
38 |
|
39 |
-
|
|
|
|
|
40 |
|
41 |
-
|
42 |
-
|
43 |
|
44 |
-
|
|
|
|
|
45 |
|
46 |
-
|
|
|
|
|
|
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
<script>
|
64 |
-
google.load('visualization', '1', {'packages':['corechart']});
|
65 |
-
</script>
|
66 |
-
<?php
|
67 |
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
include( SIMPLE_HISTORY_PATH . 'templates/settings-statsIntro.php' );
|
73 |
-
?>
|
74 |
-
</div>
|
75 |
|
76 |
-
|
77 |
-
|
|
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
</div><!-- // end bar chart rows per day -->
|
83 |
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
91 |
|
92 |
-
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--users'>
|
93 |
-
<?php include( SIMPLE_HISTORY_PATH . 'templates/settings-statsUsers.php' ) ?>
|
94 |
-
</div>
|
95 |
-
|
96 |
-
<!--
|
97 |
-
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--initiators'>
|
98 |
-
<?php include( SIMPLE_HISTORY_PATH . 'templates/settings-statsInitiators.php' ) ?>
|
99 |
-
</div>
|
100 |
-
-->
|
101 |
-
|
102 |
-
|
103 |
-
</div><!-- // end charts wrapper -->
|
104 |
-
|
105 |
-
<?php
|
106 |
-
|
107 |
-
include( SIMPLE_HISTORY_PATH . 'templates/settings-statsForGeeks.php' );
|
108 |
-
|
109 |
-
}
|
110 |
|
|
|
111 |
|
|
|
112 |
|
|
|
|
|
113 |
}
|
114 |
|
115 |
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Settings stats
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
+
class SimpleHistorySettingsStatsDropin
|
13 |
+
{
|
14 |
|
15 |
+
// Simple History instance
|
16 |
+
private $sh;
|
17 |
|
18 |
+
public function __construct($sh)
|
19 |
+
{
|
20 |
|
21 |
+
// Since it's not quite done yet, it's for da devs only for now
|
22 |
+
if (! defined('SIMPLE_HISTORY_DEV') || ! SIMPLE_HISTORY_DEV) {
|
23 |
+
return;
|
24 |
+
}
|
25 |
|
26 |
+
$this->sh = $sh;
|
27 |
|
28 |
+
// How do we register this to the settings array?
|
29 |
+
$sh->registerSettingsTab(array(
|
30 |
+
'slug' => 'stats',
|
31 |
+
'name' => __('Stats', 'simple-history'),
|
32 |
+
'function' => array( $this, 'output' ),
|
33 |
+
));
|
34 |
|
35 |
+
add_action('simple_history/enqueue_admin_scripts', array( $this, 'on_admin_enqueue_scripts' ));
|
36 |
+
}
|
37 |
|
38 |
+
public function on_admin_enqueue_scripts()
|
39 |
+
{
|
40 |
|
41 |
+
$file_url = plugin_dir_url(__FILE__);
|
42 |
|
43 |
+
wp_enqueue_script('google-ajax-api', 'https://www.google.com/jsapi');
|
44 |
+
wp_enqueue_style('simple_history_SettingsStatsDropin', $file_url . 'SimpleHistorySettingsStatsDropin.css', null, SIMPLE_HISTORY_VERSION);
|
45 |
+
}
|
46 |
|
47 |
+
public function output()
|
48 |
+
{
|
49 |
|
50 |
+
global $wpdb;
|
51 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
52 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
53 |
|
54 |
+
// $period_days = (int) 28;
|
55 |
+
$period_days = (int) 14;
|
56 |
+
$period_start_date = DateTime::createFromFormat('U', strtotime("-$period_days days"));
|
57 |
+
$period_end_date = DateTime::createFromFormat('U', time());
|
58 |
|
59 |
+
// Colors taken from the gogole chart example that was found in this Stack Overflow thread:
|
60 |
+
// http://stackoverflow.com/questions/236936/how-pick-colors-for-a-pie-chart
|
61 |
+
$arr_colors = explode(',', '8a56e2,cf56e2,e256ae,e25668,e28956,e2cf56,aee256,68e256,56e289,56e2cf,56aee2,5668e2');
|
62 |
|
63 |
+
// Load google charts libraries
|
64 |
+
?>
|
65 |
+
<script>
|
66 |
+
google.load('visualization', '1', {'packages':['corechart']});
|
67 |
+
</script>
|
68 |
+
<?php
|
69 |
|
70 |
+
?>
|
71 |
+
<!-- Overview, larger text -->
|
72 |
+
<div class='SimpleHistoryStats__intro'>
|
73 |
+
<?php
|
74 |
+
include(SIMPLE_HISTORY_PATH . 'templates/settings-statsIntro.php');
|
75 |
+
?>
|
76 |
+
</div>
|
77 |
|
78 |
+
<!-- Start charts wrap -->
|
79 |
+
<div class='SimpleHistoryStats__graphs SimpleHistory__cf'>
|
|
|
|
|
|
|
|
|
80 |
|
81 |
+
<!-- bar chart with rows per day -->
|
82 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--rowsPerDay'>
|
83 |
+
<?php include(SIMPLE_HISTORY_PATH . 'templates/settings-statsRowsPerDay.php') ?>
|
84 |
+
</div><!-- // end bar chart rows per day -->
|
|
|
|
|
|
|
85 |
|
86 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--loggersPie'>
|
87 |
+
<?php include(SIMPLE_HISTORY_PATH . 'templates/settings-statsLoggers.php') ?>
|
88 |
+
</div>
|
89 |
|
90 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--logLevels'>
|
91 |
+
<?php include(SIMPLE_HISTORY_PATH . 'templates/settings-statsLogLevels.php') ?>
|
92 |
+
</div>
|
|
|
93 |
|
94 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--users'>
|
95 |
+
<?php include(SIMPLE_HISTORY_PATH . 'templates/settings-statsUsers.php') ?>
|
96 |
+
</div>
|
97 |
|
98 |
+
<!--
|
99 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--initiators'>
|
100 |
+
<?php include(SIMPLE_HISTORY_PATH . 'templates/settings-statsInitiators.php') ?>
|
101 |
+
</div>
|
102 |
+
-->
|
103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
+
</div><!-- // end charts wrapper -->
|
106 |
|
107 |
+
<?php
|
108 |
|
109 |
+
include(SIMPLE_HISTORY_PATH . 'templates/settings-statsForGeeks.php');
|
110 |
+
}
|
111 |
}
|
112 |
|
113 |
|
dropins/SimpleHistorySidebarDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar
|
@@ -9,34 +9,36 @@ Dropin URI: http://simple-history.com/
|
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
-
class SimpleHistorySidebarDropin
|
|
|
13 |
|
14 |
-
|
15 |
|
16 |
-
|
|
|
17 |
|
18 |
-
|
19 |
|
20 |
-
|
21 |
-
|
22 |
|
23 |
-
|
24 |
-
|
|
|
25 |
|
26 |
-
|
|
|
27 |
|
28 |
-
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
33 |
|
34 |
-
|
35 |
-
_x( 'You can star, fork, or report issues with this plugin over at the <a href="%1$s">GitHub page</a>.', 'Sidebar box', 'simple-history' ),
|
36 |
-
'https://github.com/bonny/WordPress-Simple-History'
|
37 |
-
);
|
38 |
-
|
39 |
-
$boxGithub = '
|
40 |
<div class="postbox">
|
41 |
<h3 class="hndle">' . $headline . '</h3>
|
42 |
<div class="inside">
|
@@ -45,15 +47,15 @@ class SimpleHistorySidebarDropin {
|
|
45 |
</div>
|
46 |
';
|
47 |
|
48 |
-
|
49 |
-
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
|
56 |
-
|
57 |
<div class="postbox">
|
58 |
<h3 class="hndle">' . $headline . '</h3>
|
59 |
<div class="inside">
|
@@ -62,17 +64,17 @@ class SimpleHistorySidebarDropin {
|
|
62 |
</div>
|
63 |
';
|
64 |
|
65 |
-
|
66 |
-
|
67 |
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
|
73 |
-
|
74 |
|
75 |
-
|
76 |
<div class="postbox">
|
77 |
<h3 class="hndle">' . $headline . '</h3>
|
78 |
<div class="inside">
|
@@ -82,20 +84,21 @@ class SimpleHistorySidebarDropin {
|
|
82 |
</div>
|
83 |
';
|
84 |
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
99 |
<div class="postbox">
|
100 |
<h3 class="hndle">%1$s</h3>
|
101 |
<div class="inside">
|
@@ -104,12 +107,13 @@ class SimpleHistorySidebarDropin {
|
|
104 |
</div>
|
105 |
</div>
|
106 |
',
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
|
111 |
-
|
112 |
-
|
|
|
113 |
<div class="postbox">
|
114 |
<h3 class="hndle">%1$s</h3>
|
115 |
<div class="inside">
|
@@ -117,45 +121,44 @@ class SimpleHistorySidebarDropin {
|
|
117 |
</div>
|
118 |
</div>
|
119 |
',
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
$boxTranslationTmpl = '
|
159 |
<div class="postbox">
|
160 |
<h3 class="hndle">Translate Simple History to %1$s</h3>
|
161 |
<div class="inside">
|
@@ -176,71 +179,69 @@ class SimpleHistorySidebarDropin {
|
|
176 |
</div>
|
177 |
';
|
178 |
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
}
|
245 |
-
|
246 |
}//end class
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
+
class SimpleHistorySidebarDropin
|
13 |
+
{
|
14 |
|
15 |
+
private $sh;
|
16 |
|
17 |
+
function __construct($sh)
|
18 |
+
{
|
19 |
|
20 |
+
$this->sh = $sh;
|
21 |
|
22 |
+
add_action('simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ));
|
23 |
+
add_action('simple_history/history_page/after_gui', array( $this, 'output_sidebar_html' ));
|
24 |
|
25 |
+
// add_action("simple_history/dropin/sidebar/sidebar_html", array($this, "example_output"));
|
26 |
+
add_action('simple_history/dropin/sidebar/sidebar_html', array( $this, 'default_sidebar_contents' ));
|
27 |
+
}
|
28 |
|
29 |
+
public function default_sidebar_contents()
|
30 |
+
{
|
31 |
|
32 |
+
// Boxes that will appear randomly
|
33 |
+
// Box about GitHub
|
34 |
+
$headline = _x('Simple History is on GitHub', 'Sidebar box', 'simple-history');
|
35 |
|
36 |
+
$body = sprintf(
|
37 |
+
_x('You can star, fork, or report issues with this plugin over at the <a href="%1$s">GitHub page</a>.', 'Sidebar box', 'simple-history'),
|
38 |
+
'https://github.com/bonny/WordPress-Simple-History'
|
39 |
+
);
|
40 |
|
41 |
+
$boxGithub = '
|
|
|
|
|
|
|
|
|
|
|
42 |
<div class="postbox">
|
43 |
<h3 class="hndle">' . $headline . '</h3>
|
44 |
<div class="inside">
|
47 |
</div>
|
48 |
';
|
49 |
|
50 |
+
// Box about donation
|
51 |
+
$headline = _x('Donate to support development', 'Sidebar box', 'simple-history');
|
52 |
|
53 |
+
$body = sprintf(
|
54 |
+
_x('If you like and use Simple History you should <a href="%1$s">donate to keep this plugin free</a>.', 'Sidebar box', 'simple-history'),
|
55 |
+
'http://eskapism.se/sida/donate/'
|
56 |
+
);
|
57 |
|
58 |
+
$boxDonate = '
|
59 |
<div class="postbox">
|
60 |
<h3 class="hndle">' . $headline . '</h3>
|
61 |
<div class="inside">
|
64 |
</div>
|
65 |
';
|
66 |
|
67 |
+
// Box about review
|
68 |
+
$headline = _x('Review this plugin if you like it', 'Sidebar box', 'simple-history');
|
69 |
|
70 |
+
$body1 = sprintf(
|
71 |
+
_x('If you like Simple History then please <a href="%1$s">give it a nice review over at wordpress.org</a>.', 'Sidebar box', 'simple-history'),
|
72 |
+
'https://wordpress.org/support/view/plugin-reviews/simple-history'
|
73 |
+
);
|
74 |
|
75 |
+
$body2 = _x('A good review will help new users find this plugin. And it will make the plugin author very happy :)', 'Sidebar box', 'simple-history');
|
76 |
|
77 |
+
$boxReview = '
|
78 |
<div class="postbox">
|
79 |
<h3 class="hndle">' . $headline . '</h3>
|
80 |
<div class="inside">
|
84 |
</div>
|
85 |
';
|
86 |
|
87 |
+
// Box about tweeting and blogging
|
88 |
+
/*
|
89 |
+
$boxSocial = '
|
90 |
+
<div class="postbox">
|
91 |
+
<h3 class="hndle">Blog or tweet</h3>
|
92 |
+
<div class="inside">
|
93 |
+
<p>Yeah, how about that yo.</p>
|
94 |
+
</div>
|
95 |
+
</div>
|
96 |
+
';
|
97 |
+
*/
|
98 |
+
|
99 |
+
// Box about possible events missing
|
100 |
+
$boxMissingEvents = sprintf(
|
101 |
+
'
|
102 |
<div class="postbox">
|
103 |
<h3 class="hndle">%1$s</h3>
|
104 |
<div class="inside">
|
107 |
</div>
|
108 |
</div>
|
109 |
',
|
110 |
+
_x('Add more to the log', 'Sidebar box', 'simple-history'), // 1
|
111 |
+
_x('Are there things you miss in the history log?', 'Sidebar box', 'simple-history') // 2
|
112 |
+
);
|
113 |
|
114 |
+
// Box about support
|
115 |
+
$boxSupport = sprintf(
|
116 |
+
'
|
117 |
<div class="postbox">
|
118 |
<h3 class="hndle">%1$s</h3>
|
119 |
<div class="inside">
|
121 |
</div>
|
122 |
</div>
|
123 |
',
|
124 |
+
_x('Support', 'Sidebar box', 'simple-history'), // 1
|
125 |
+
sprintf(_x('<a href="%1$s">Visit the support forum</a> if you need help or have questions.', 'Sidebar box', 'simple-history'), 'https://wordpress.org/support/plugin/simple-history') // 2
|
126 |
+
);
|
127 |
+
|
128 |
+
$arrBoxes = array(
|
129 |
+
'boxReview' => $boxReview,
|
130 |
+
'boxSupport' => $boxSupport,
|
131 |
+
// "boxMissingEvents" => $boxMissingEvents,
|
132 |
+
'boxDonate' => $boxDonate,
|
133 |
+
// "boxGithub" => $boxGithub,
|
134 |
+
);
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Filter the default boxes to output in the sidebar
|
138 |
+
*
|
139 |
+
* @since 2.0.17
|
140 |
+
*
|
141 |
+
* @param array $arrBoxes array with boxes to output. Check the key to determine which box is which.
|
142 |
+
*/
|
143 |
+
$arrBoxes = apply_filters('simple_history/SidebarDropin/default_sidebar_boxes', $arrBoxes);
|
144 |
+
|
145 |
+
// echo $arrBoxes[array_rand($arrBoxes)];
|
146 |
+
echo implode('', $arrBoxes); // show all
|
147 |
+
|
148 |
+
// Box to encourage people translate plugin
|
149 |
+
$current_locale = get_locale();
|
150 |
+
|
151 |
+
/** WordPress Translation Install API. This file exists only since 4.0. */
|
152 |
+
$translation_install_file = ABSPATH . 'wp-admin/includes/translation-install.php';
|
153 |
+
|
154 |
+
// Show only the translation box if current language is not an english language
|
155 |
+
if (in_array($current_locale, array( 'en_US', 'en_GB', 'en_CA', 'en_NZ', 'en_AU' )) != $current_locale && file_exists($translation_install_file)) {
|
156 |
+
require_once $translation_install_file;
|
157 |
+
|
158 |
+
$translations = wp_get_available_translations();
|
159 |
+
|
160 |
+
// This text does not need translation since is's only shown in English
|
161 |
+
$boxTranslationTmpl = '
|
|
|
162 |
<div class="postbox">
|
163 |
<h3 class="hndle">Translate Simple History to %1$s</h3>
|
164 |
<div class="inside">
|
179 |
</div>
|
180 |
';
|
181 |
|
182 |
+
if (isset($translations[ $current_locale ])) {
|
183 |
+
// Check if an existing text string returns something else, and that current lang is not en
|
184 |
+
$teststring_translated = __('Just now', 'simple-history');
|
185 |
+
$teststring_untranslated = 'Just now';
|
186 |
+
if ($teststring_untranslated == $teststring_translated) {
|
187 |
+
// strings are the same, so plugin probably not translated
|
188 |
+
printf($boxTranslationTmpl, $translations[ $current_locale ]['english_name']);
|
189 |
+
}
|
190 |
+
}
|
191 |
+
} // End if().
|
192 |
+
}
|
193 |
+
|
194 |
+
public function example_output()
|
195 |
+
{
|
196 |
+
?>
|
197 |
+
<div class="postbox">
|
198 |
+
<h3 class="hndle">Example title</h3>
|
199 |
+
<div class="inside">
|
200 |
+
<p>Example content. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Inquit, dasne adolescenti veniam? Non laboro, inquit, de nomine. In quibus doctissimi illi veteres inesse quiddam caeleste et divinum putaverunt. Duo Reges: constructio interrete. Indicant pueri, in quibus ut in speculis natura cernitur. Quod ea non occurrentia fingunt, vincunt Aristonem; Quod quidem iam fit etiam in Academia. Aliter enim nosmet ipsos nosse non possumus.</p>
|
201 |
+
</div>
|
202 |
+
</div>
|
203 |
+
<?php
|
204 |
+
}
|
205 |
+
|
206 |
+
public function enqueue_admin_scripts()
|
207 |
+
{
|
208 |
+
|
209 |
+
$file_url = plugin_dir_url(__FILE__);
|
210 |
+
|
211 |
+
wp_enqueue_style('simple_history_SidebarDropin', $file_url . 'SimpleHistorySidebarDropin.css', null, SIMPLE_HISTORY_VERSION);
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Output the outline for the sidebar
|
216 |
+
* Plugins and dropins simple use the filters to output contents to the sidebar
|
217 |
+
* Example HTML code to generate meta box:
|
218 |
+
*
|
219 |
+
* <div class="postbox">
|
220 |
+
* <h3 class="hndle">Title</h3>
|
221 |
+
* <div class="inside">
|
222 |
+
* <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Inquit, dasne adolescenti veniam? Non laboro, inquit, de nomine. In quibus doctissimi illi veteres inesse quiddam caeleste et divinum putaverunt. Duo Reges: constructio interrete. Indicant pueri, in quibus ut in speculis natura cernitur. Quod ea non occurrentia fingunt, vincunt Aristonem; Quod quidem iam fit etiam in Academia. Aliter enim nosmet ipsos nosse non possumus.</p>
|
223 |
+
* </div>
|
224 |
+
* </div>
|
225 |
+
*/
|
226 |
+
public function output_sidebar_html()
|
227 |
+
{
|
228 |
+
|
229 |
+
?>
|
230 |
+
<div class="SimpleHistory__pageSidebar">
|
231 |
+
|
232 |
+
<div class="metabox-holder">
|
233 |
+
|
234 |
+
<?php
|
235 |
+
/**
|
236 |
+
* Allows to output HTML in sidebar
|
237 |
+
*
|
238 |
+
* @since 2.0.16
|
239 |
+
*/
|
240 |
+
do_action('simple_history/dropin/sidebar/sidebar_html');
|
241 |
+
?>
|
242 |
+
</div>
|
243 |
+
|
244 |
+
</div>
|
245 |
+
<?php
|
246 |
+
}
|
|
|
|
|
247 |
}//end class
|
dropins/SimpleHistorySidebarSettings.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with link to settings
|
@@ -8,84 +8,84 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistorySidebarSettings
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with link to settings
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistorySidebarSettings
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Simple History isntance
|
16 |
+
*
|
17 |
+
* @var object $sh Simple History instance.
|
18 |
+
*/
|
19 |
+
private $sh;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Constructor.
|
23 |
+
*
|
24 |
+
* @param object $sh Simple History instance.
|
25 |
+
*/
|
26 |
+
function __construct($sh)
|
27 |
+
{
|
28 |
+
|
29 |
+
$this->init($sh);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Init
|
34 |
+
*
|
35 |
+
* @param object $sh Simple History instance.
|
36 |
+
*/
|
37 |
+
function init($sh)
|
38 |
+
{
|
39 |
+
|
40 |
+
$this->sh = $sh;
|
41 |
+
|
42 |
+
add_action('simple_history/dropin/sidebar/sidebar_html', array( $this, 'on_sidebar_html' ), 5);
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Output HTML
|
47 |
+
*/
|
48 |
+
function on_sidebar_html()
|
49 |
+
{
|
50 |
+
|
51 |
+
?>
|
52 |
+
|
53 |
+
<div class="postbox">
|
54 |
+
|
55 |
+
<h3 class="hndle"><?php esc_html_e('Settings', 'simple-history') ?></h3>
|
56 |
+
|
57 |
+
<div class="inside">
|
58 |
+
|
59 |
+
<p>
|
60 |
+
<?php
|
61 |
+
|
62 |
+
/*
|
63 |
+
Visit the settings page to change the number of items to show and
|
64 |
+
where to show
|
65 |
+
rss feed
|
66 |
+
clear log
|
67 |
+
|
68 |
+
- Visit the settings page to change the number of events to show, to get
|
69 |
+
- Visit the settings page
|
70 |
+
*/
|
71 |
+
printf(
|
72 |
+
wp_kses(
|
73 |
+
/* translators: 1: URL to settings page */
|
74 |
+
__('<a href="%1$s">Visit the settings page</a> to change things like the number of events to show and to get access to the RSS feed with all events, and more.', 'simple-history'),
|
75 |
+
array(
|
76 |
+
'a' => array(
|
77 |
+
'href' => array(),
|
78 |
+
),
|
79 |
+
)
|
80 |
+
),
|
81 |
+
esc_url(menu_page_url(SimpleHistory::SETTINGS_MENU_SLUG, false))
|
82 |
+
);
|
83 |
+
?>
|
84 |
+
</p>
|
85 |
+
|
86 |
+
</div>
|
87 |
+
</div>
|
88 |
+
|
89 |
+
<?php
|
90 |
+
}
|
91 |
}
|
dropins/SimpleHistorySidebarStats.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with short stats
|
@@ -8,240 +8,237 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistorySidebarStats
|
|
|
|
|
|
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
|
16 |
|
17 |
-
|
18 |
|
19 |
-
|
20 |
|
21 |
-
|
|
|
22 |
|
23 |
-
|
|
|
24 |
|
25 |
-
|
|
|
26 |
|
27 |
-
|
|
|
28 |
|
29 |
-
|
|
|
30 |
|
31 |
-
|
|
|
|
|
|
|
32 |
|
33 |
-
|
34 |
|
35 |
-
|
36 |
|
37 |
-
|
|
|
|
|
38 |
|
39 |
-
|
|
|
|
|
40 |
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
-
/**
|
45 |
-
* JavaScript for SimpleHistory_SidebarChart
|
46 |
-
*/
|
47 |
-
(function($) {
|
48 |
|
49 |
-
|
|
|
50 |
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
var chartDatasetData = JSON.parse( $(".SimpleHistory_SidebarChart_ChartDatasetData").val() );
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
options: {
|
72 |
-
legend: {
|
73 |
-
display: false
|
74 |
-
},
|
75 |
-
scales: {
|
76 |
-
yAxes: [{
|
77 |
-
ticks: {
|
78 |
-
beginAtZero:true
|
79 |
-
},
|
80 |
-
}],
|
81 |
-
xAxes: [{
|
82 |
-
display: false
|
83 |
-
}]
|
84 |
-
},
|
85 |
-
onClick: clickChart
|
86 |
-
},
|
87 |
-
});
|
88 |
|
|
|
|
|
|
|
89 |
|
90 |
-
|
91 |
-
|
92 |
|
93 |
-
|
|
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
|
100 |
-
|
101 |
-
// var value = this.data.datasets[chartElmClicked._datasetIndex].data[chartElmClicked._index];
|
102 |
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
|
114 |
-
|
115 |
-
|
116 |
-
}
|
117 |
|
118 |
-
|
119 |
-
|
|
|
|
|
120 |
|
121 |
-
|
122 |
-
|
|
|
123 |
|
124 |
-
|
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 |
-
|
|
|
|
|
130 |
|
131 |
-
|
|
|
|
|
|
|
132 |
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
-
|
136 |
|
137 |
-
|
|
|
|
|
|
|
138 |
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
-
|
142 |
|
143 |
-
|
|
|
|
|
|
|
|
|
144 |
|
145 |
-
|
|
|
|
|
|
|
|
|
146 |
|
147 |
-
|
|
|
|
|
|
|
|
|
148 |
|
149 |
-
|
150 |
-
|
151 |
-
$period_end_date = DateTime::createFromFormat( 'U', time() );
|
152 |
-
$interval = DateInterval::createFromDateString( '1 day' );
|
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' ),
|
168 |
-
$this->sh->get_num_events_last_n_days( $num_days ),
|
169 |
-
number_format_i18n( $num_days )
|
170 |
-
);
|
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>
|
178 |
-
</div>
|
179 |
-
|
180 |
-
<p class="SimpleHistory_SidebarChart_ChartDescription" style="font-style: italic; color: #777; text-align: center;">
|
181 |
-
<?php _e( 'Number of events per day.', 'simple-history' ) ?>
|
182 |
-
</p>
|
183 |
-
|
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'
|
198 |
-
$yearDate = $dt->format( 'Y-m-d' );
|
199 |
-
$day_data = wp_filter_object_list( $num_events_per_day_for_period, array(
|
200 |
-
'yearDate' => $yearDate,
|
201 |
-
) );
|
202 |
-
|
203 |
-
$arr_labels[] = $str_date;
|
204 |
-
|
205 |
-
$arr_labels_to_datetime[] = array(
|
206 |
-
'label' => $str_date,
|
207 |
-
'date' => $str_date_ymd,
|
208 |
-
);
|
209 |
-
|
210 |
-
if ( $day_data ) {
|
211 |
-
|
212 |
-
$day_data = reset( $day_data );
|
213 |
-
$arr_dataset_data[] = $day_data->count;
|
214 |
-
|
215 |
-
} else {
|
216 |
-
$arr_dataset_data[] = 0;
|
217 |
-
}
|
218 |
-
}
|
219 |
-
|
220 |
-
?>
|
221 |
-
|
222 |
-
<input
|
223 |
-
type="hidden"
|
224 |
-
class="SimpleHistory_SidebarChart_ChartLabels"
|
225 |
-
value="<?php esc_attr_e( json_encode( $arr_labels ) ) ?>"
|
226 |
-
/>
|
227 |
-
|
228 |
-
<input
|
229 |
-
type="hidden"
|
230 |
-
class="SimpleHistory_SidebarChart_ChartLabelsToDates"
|
231 |
-
value="<?php esc_attr_e( json_encode( $arr_labels_to_datetime ) ) ?>"
|
232 |
-
/>
|
233 |
-
|
234 |
-
<input
|
235 |
-
type="hidden"
|
236 |
-
class="SimpleHistory_SidebarChart_ChartDatasetData"
|
237 |
-
value="<?php esc_attr_e( json_encode( $arr_dataset_data ) ) ?>"
|
238 |
-
/>
|
239 |
-
|
240 |
-
</div>
|
241 |
-
</div>
|
242 |
-
|
243 |
-
<?php
|
244 |
-
|
245 |
-
}
|
246 |
|
|
|
|
|
247 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with short stats
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistorySidebarStats
|
12 |
+
{
|
13 |
+
|
14 |
+
private $sh;
|
15 |
|
16 |
+
function __construct($sh)
|
17 |
+
{
|
18 |
+
|
19 |
+
$this->init($sh);
|
20 |
+
}
|
21 |
+
|
22 |
+
function init($sh)
|
23 |
+
{
|
24 |
|
25 |
+
$this->sh = $sh;
|
26 |
|
27 |
+
add_action('simple_history/dropin/sidebar/sidebar_html', array( $this, 'on_sidebar_html' ), 5);
|
28 |
|
29 |
+
add_action('simple_history/enqueue_admin_scripts', array( $this, 'on_admin_enqueue_scripts' ));
|
30 |
|
31 |
+
add_action('simple_history/admin_footer', array( $this, 'on_admin_footer' ));
|
32 |
+
}
|
33 |
|
34 |
+
public function on_admin_enqueue_scripts()
|
35 |
+
{
|
36 |
|
37 |
+
wp_enqueue_script('simple_history_chart.js', SIMPLE_HISTORY_DIR_URL . 'js/Chart.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true);
|
38 |
+
}
|
39 |
|
40 |
+
function on_admin_footer()
|
41 |
+
{
|
42 |
|
43 |
+
?>
|
44 |
+
<script>
|
45 |
|
46 |
+
/**
|
47 |
+
* JavaScript for SimpleHistory_SidebarChart
|
48 |
+
*/
|
49 |
+
(function($) {
|
50 |
|
51 |
+
$(function() {
|
52 |
|
53 |
+
var ctx = $(".SimpleHistory_SidebarChart_ChartCanvas");
|
54 |
|
55 |
+
if ( ! ctx.length ) {
|
56 |
+
return;
|
57 |
+
}
|
58 |
|
59 |
+
var chartLabels = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabels").val() );
|
60 |
+
var chartLabelsToDates = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabelsToDates").val() );
|
61 |
+
var chartDatasetData = JSON.parse( $(".SimpleHistory_SidebarChart_ChartDatasetData").val() );
|
62 |
|
63 |
+
var myChart = new Simple_History_Chart(ctx, {
|
64 |
+
type: 'bar',
|
65 |
+
data: {
|
66 |
+
labels: chartLabels,
|
67 |
+
datasets: [{
|
68 |
+
data: chartDatasetData,
|
69 |
+
backgroundColor: "rgb(210,210,210)",
|
70 |
+
hoverBackgroundColor: "rgb(175,175,175)",
|
71 |
+
}]
|
72 |
+
},
|
73 |
+
options: {
|
74 |
+
legend: {
|
75 |
+
display: false
|
76 |
+
},
|
77 |
+
scales: {
|
78 |
+
yAxes: [{
|
79 |
+
ticks: {
|
80 |
+
beginAtZero:true
|
81 |
+
},
|
82 |
+
}],
|
83 |
+
xAxes: [{
|
84 |
+
display: false
|
85 |
+
}]
|
86 |
+
},
|
87 |
+
onClick: clickChart
|
88 |
+
},
|
89 |
+
});
|
90 |
|
|
|
|
|
|
|
|
|
91 |
|
92 |
+
// when chart is clicked determine what value/day was clicked
|
93 |
+
function clickChart(e) {
|
94 |
|
95 |
+
var chartElmClicked = this.getElementAtEvent(e)[0];
|
96 |
|
97 |
+
if (!chartElmClicked || !chartElmClicked._index) {
|
98 |
+
console.log("No value found for click");
|
99 |
+
return;
|
100 |
+
}
|
101 |
|
102 |
+
var label = this.data.labels[chartElmClicked._index];
|
103 |
+
// var value = this.data.datasets[chartElmClicked._datasetIndex].data[chartElmClicked._index];
|
|
|
104 |
|
105 |
+
// now we have the label which is like "July 23" or "23 juli" depending on language
|
106 |
+
// look for that label value in chartLabelsToDates and there we get the date in format Y-m-d
|
107 |
+
//console.log("chartLabelsToDates", chartLabelsToDates);
|
108 |
+
var labelDate;
|
109 |
+
for (idx in chartLabelsToDates) {
|
110 |
+
if (label == chartLabelsToDates[idx].label) {
|
111 |
+
//console.log(chartLabelsToDates[idx]);
|
112 |
+
labelDate = chartLabelsToDates[idx];
|
113 |
+
}
|
114 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
+
if (!labelDate) {
|
117 |
+
return;
|
118 |
+
}
|
119 |
|
120 |
+
// got a date, now reload the history/post search filter form again
|
121 |
+
var labelDateParts = labelDate.date.split("-"); ["2016", "07", "18"]
|
122 |
|
123 |
+
// show custom date range
|
124 |
+
$(".SimpleHistory__filters__filter--date").val("customRange").trigger("change");
|
125 |
|
126 |
+
// set values, same for both from and to because we only want to show one day
|
127 |
+
SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_aa'], [name='to_aa']").val(labelDateParts[0]);
|
128 |
+
SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_jj'], [name='to_jj']").val(labelDateParts[2]);
|
129 |
+
SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_mm'], [name='to_mm']").val(labelDateParts[1]);
|
130 |
|
131 |
+
SimpleHistoryFilterDropin.$elms.filter_form.trigger("submit");
|
|
|
132 |
|
133 |
+
}
|
134 |
+
|
135 |
+
});
|
136 |
+
|
137 |
+
})(jQuery);
|
138 |
+
|
139 |
+
</script>
|
140 |
+
|
141 |
+
<?php
|
142 |
+
}
|
143 |
+
|
144 |
+
function on_sidebar_html()
|
145 |
+
{
|
146 |
+
|
147 |
+
$num_days = 28;
|
148 |
+
|
149 |
+
$num_events_per_day_for_period = $this->sh->get_num_events_per_day_last_n_days($num_days);
|
150 |
+
|
151 |
+
// Period = all dates, so empty ones don't get lost
|
152 |
+
$period_start_date = DateTime::createFromFormat('U', strtotime("-$num_days days"));
|
153 |
+
$period_end_date = DateTime::createFromFormat('U', time());
|
154 |
+
$interval = DateInterval::createFromDateString('1 day');
|
155 |
+
$period = new DatePeriod($period_start_date, $interval, $period_end_date->add(date_interval_create_from_date_string('1 days')));
|
156 |
+
|
157 |
+
?>
|
158 |
+
|
159 |
+
<div class="postbox">
|
160 |
+
|
161 |
+
<h3 class="hndle"><?php _e('Stats', 'simple-history') ?></h3>
|
162 |
+
|
163 |
+
<div class="inside">
|
164 |
+
|
165 |
+
<p>
|
166 |
+
<?php
|
167 |
+
|
168 |
+
printf(
|
169 |
+
__('<b>%1$s events</b> have been logged the last <b>%2$s days</b>.', 'simple-history'),
|
170 |
+
$this->sh->get_num_events_last_n_days($num_days),
|
171 |
+
number_format_i18n($num_days)
|
172 |
+
);
|
173 |
|
174 |
+
?>
|
175 |
+
</p>
|
|
|
176 |
|
177 |
+
<!-- wrapper div so sidebar does not "jump" when loading. so annoying. -->
|
178 |
+
<div style="position: relative; height: 0; overflow: hidden; padding-bottom: 40%;">
|
179 |
+
<canvas style="position: absolute; left: 0; right: 0;" class="SimpleHistory_SidebarChart_ChartCanvas" width="100" height="40"></canvas>
|
180 |
+
</div>
|
181 |
|
182 |
+
<p class="SimpleHistory_SidebarChart_ChartDescription" style="font-style: italic; color: #777; text-align: center;">
|
183 |
+
<?php _e('Number of events per day.', 'simple-history') ?>
|
184 |
+
</p>
|
185 |
|
186 |
+
<?php
|
|
|
|
|
|
|
187 |
|
188 |
+
$arr_labels = array();
|
189 |
+
$arr_labels_to_datetime = array();
|
190 |
+
$arr_dataset_data = array();
|
191 |
|
192 |
+
foreach ($period as $dt) {
|
193 |
+
$datef = _x('M j', 'stats: date in rows per day chart', 'simple-history');
|
194 |
+
$str_date = date_i18n($datef, $dt->getTimestamp());
|
195 |
+
$str_date_ymd = date('Y-m-d', $dt->getTimestamp());
|
196 |
|
197 |
+
// Get data for this day, if exist
|
198 |
+
// Day in object is in format '2014-09-07'
|
199 |
+
$yearDate = $dt->format('Y-m-d');
|
200 |
+
$day_data = wp_filter_object_list($num_events_per_day_for_period, array(
|
201 |
+
'yearDate' => $yearDate,
|
202 |
+
));
|
203 |
|
204 |
+
$arr_labels[] = $str_date;
|
205 |
|
206 |
+
$arr_labels_to_datetime[] = array(
|
207 |
+
'label' => $str_date,
|
208 |
+
'date' => $str_date_ymd,
|
209 |
+
);
|
210 |
|
211 |
+
if ($day_data) {
|
212 |
+
$day_data = reset($day_data);
|
213 |
+
$arr_dataset_data[] = $day_data->count;
|
214 |
+
} else {
|
215 |
+
$arr_dataset_data[] = 0;
|
216 |
+
}
|
217 |
+
}
|
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 |
}
|
dropins/SimpleHistoryWPCLIDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/*
|
6 |
Dropin Name: WP CLI
|
@@ -8,158 +8,159 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistoryWPCLIDropin
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
165 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: WP CLI
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistoryWPCLIDropin
|
12 |
+
{
|
13 |
+
|
14 |
+
// Simple History instance
|
15 |
+
private $sh;
|
16 |
+
|
17 |
+
function __construct($sh)
|
18 |
+
{
|
19 |
+
|
20 |
+
$this->sh = $sh;
|
21 |
+
// add_action( 'admin_menu', array($this, 'add_settings'), 50 );
|
22 |
+
// add_action( 'plugin_row_meta', array($this, 'action_plugin_row_meta'), 10, 2);
|
23 |
+
if (defined('WP_CLI') && WP_CLI) {
|
24 |
+
$this->register_commands();
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
private function register_commands()
|
29 |
+
{
|
30 |
+
$commandConfigurationOptions = array(
|
31 |
+
'shortdesc' => 'Lists the history log',
|
32 |
+
'synopsis' => array(
|
33 |
+
array(
|
34 |
+
'type' => 'assoc',
|
35 |
+
'name' => 'format',
|
36 |
+
'optional' => true,
|
37 |
+
'default' => 'table',
|
38 |
+
'options' => array( 'table', 'json', 'csv', 'yaml' ),
|
39 |
+
),
|
40 |
+
array(
|
41 |
+
'type' => 'assoc',
|
42 |
+
'name' => 'count',
|
43 |
+
'optional' => true,
|
44 |
+
'default' => '10',
|
45 |
+
),
|
46 |
+
),
|
47 |
+
'when' => 'after_wp_load',
|
48 |
+
);
|
49 |
+
|
50 |
+
WP_CLI::add_command('simple-history list', array( $this, 'commandList' ), $commandConfigurationOptions);
|
51 |
+
}
|
52 |
+
|
53 |
+
private function getInitiatorTextFromRow($row)
|
54 |
+
{
|
55 |
+
if (! isset($row->initiator)) {
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
|
59 |
+
$initiator = $row->initiator;
|
60 |
+
$initiatorText = '';
|
61 |
+
|
62 |
+
switch ($initiator) {
|
63 |
+
case 'wp':
|
64 |
+
$initiatorText = 'WordPress';
|
65 |
+
break;
|
66 |
+
case 'wp_cli':
|
67 |
+
$initiatorText = 'WP-CLI';
|
68 |
+
break;
|
69 |
+
case 'wp_user':
|
70 |
+
$user_id = isset($row->context['_user_id']) ? $row->context['_user_id'] : null;
|
71 |
+
|
72 |
+
if ($user_id > 0 && $user = get_user_by('id', $user_id)) {
|
73 |
+
// User still exists
|
74 |
+
// Get user role, as done in user-edit.php
|
75 |
+
$wp_roles = $GLOBALS['wp_roles'];
|
76 |
+
$all_roles = (array) $wp_roles->roles;
|
77 |
+
$user_roles = array_intersect(array_values((array) $user->roles), array_keys((array) $wp_roles->roles));
|
78 |
+
$user_role = array_shift($user_roles);
|
79 |
+
|
80 |
+
$initiatorText = sprintf(
|
81 |
+
'%1$s (%2$s)',
|
82 |
+
$user->user_login, // 1
|
83 |
+
$user->user_email // 2
|
84 |
+
);
|
85 |
+
} elseif ($user_id > 0) {
|
86 |
+
// Sender was a user, but user is deleted now
|
87 |
+
$initiatorText = sprintf(
|
88 |
+
__('Deleted user (had id %1$s, email %2$s, login %3$s)', 'simple-history'),
|
89 |
+
$context['_user_id'], // 1
|
90 |
+
$context['_user_email'], // 2
|
91 |
+
$context['_user_login'] // 3
|
92 |
+
);
|
93 |
+
} // End if().
|
94 |
+
break;
|
95 |
+
case 'web_user':
|
96 |
+
$initiatorText = __('Anonymous web user', 'simple-history');
|
97 |
+
break;
|
98 |
+
case 'other':
|
99 |
+
$initiatorText = _x('Other', 'Event header output, when initiator is unknown', 'simple-history');
|
100 |
+
break;
|
101 |
+
default:
|
102 |
+
$initiatorText = $initiator;
|
103 |
+
}// End switch().
|
104 |
+
|
105 |
+
return $initiatorText;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* The function for the command "list"
|
110 |
+
*/
|
111 |
+
public function commandList($args, $assoc_args)
|
112 |
+
{
|
113 |
+
|
114 |
+
if (! is_numeric($assoc_args['count'])) {
|
115 |
+
WP_CLI::error(__('Error: parameter "count" must be a number', 'simple-history'));
|
116 |
+
}
|
117 |
+
|
118 |
+
// Override capability check: if you can run wp cli commands you can read all loggers
|
119 |
+
add_action('simple_history/loggers_user_can_read/can_read_single_logger', '__return_true', 10, 3);
|
120 |
+
|
121 |
+
// WP_CLI::log( sprintf( 'Showing %1$d events from Simple History', $assoc_args["count"] ) );
|
122 |
+
$query = new SimpleHistoryLogQuery();
|
123 |
+
|
124 |
+
$query_args = array(
|
125 |
+
'paged' => 1,
|
126 |
+
'posts_per_page' => $assoc_args['count'],
|
127 |
+
);
|
128 |
+
|
129 |
+
$events = $query->query($query_args);
|
130 |
+
|
131 |
+
// A cleaned version of the events, formatted for wp cli table output
|
132 |
+
$eventsCleaned = array();
|
133 |
+
|
134 |
+
foreach ($events['log_rows'] as $row) {
|
135 |
+
$header_output = $this->sh->getLogRowHeaderOutput($row);
|
136 |
+
$text_output = $this->sh->getLogRowPlainTextOutput($row);
|
137 |
+
// $details_output = $this->sh->getLogRowDetailsOutput($row);
|
138 |
+
$header_output = strip_tags(html_entity_decode($header_output, ENT_QUOTES, 'UTF-8'));
|
139 |
+
$header_output = trim(preg_replace('/\s\s+/', ' ', $header_output));
|
140 |
+
|
141 |
+
$text_output = strip_tags(html_entity_decode($text_output, ENT_QUOTES, 'UTF-8'));
|
142 |
+
|
143 |
+
$eventsCleaned[] = array(
|
144 |
+
'date' => get_date_from_gmt($row->date),
|
145 |
+
// "initiator" => $row->initiator,
|
146 |
+
'initiator' => $this->getInitiatorTextFromRow($row),
|
147 |
+
'logger' => $row->logger,
|
148 |
+
'level' => $row->level,
|
149 |
+
'who_when' => $header_output,
|
150 |
+
'description' => $text_output,
|
151 |
+
'count' => $row->subsequentOccasions,
|
152 |
+
// "details" => $details_output
|
153 |
+
);
|
154 |
+
}
|
155 |
+
|
156 |
+
$fields = array(
|
157 |
+
'date',
|
158 |
+
'initiator',
|
159 |
+
'description',
|
160 |
+
'level',
|
161 |
+
'count',
|
162 |
+
);
|
163 |
+
|
164 |
+
WP_CLI\Utils\format_items($assoc_args['format'], $eventsCleaned, $fields);
|
165 |
+
}
|
166 |
}
|
examples/example-dropin.php
CHANGED
@@ -11,58 +11,57 @@ exit;
|
|
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_dropin', function(
|
15 |
-
|
16 |
-
$simpleHistory->register_dropin( 'AddSettingsPageTab' );
|
17 |
|
|
|
18 |
});
|
19 |
|
20 |
|
21 |
/**
|
22 |
* This is the class that does the main work!
|
23 |
*/
|
24 |
-
class AddSettingsPageTab
|
25 |
-
|
26 |
-
// This will hold a reference to the simple history instance
|
27 |
-
private $sh;
|
28 |
-
|
29 |
-
// simple history will pass itself to the constructor
|
30 |
-
function __construct( $sh ) {
|
31 |
-
|
32 |
-
$this->sh = $sh;
|
33 |
-
|
34 |
-
$this->init();
|
35 |
-
|
36 |
-
}
|
37 |
|
38 |
-
|
|
|
39 |
|
40 |
-
|
|
|
|
|
41 |
|
42 |
-
|
43 |
|
44 |
-
|
|
|
45 |
|
46 |
-
|
47 |
-
|
48 |
-
'name' => __( 'Example tab', 'simple-history' ),
|
49 |
-
'function' => array( $this, 'settings_tab_output' ),
|
50 |
-
) );
|
51 |
|
52 |
-
|
|
|
53 |
|
54 |
-
|
|
|
55 |
|
56 |
-
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
-
|
|
|
59 |
|
60 |
-
|
61 |
|
62 |
-
|
63 |
|
64 |
-
|
65 |
|
|
|
|
|
66 |
} // end class
|
67 |
|
68 |
|
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_dropin', function ($simpleHistory) {
|
|
|
|
|
15 |
|
16 |
+
$simpleHistory->register_dropin('AddSettingsPageTab');
|
17 |
});
|
18 |
|
19 |
|
20 |
/**
|
21 |
* This is the class that does the main work!
|
22 |
*/
|
23 |
+
class AddSettingsPageTab
|
24 |
+
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
|
26 |
+
// This will hold a reference to the simple history instance
|
27 |
+
private $sh;
|
28 |
|
29 |
+
// simple history will pass itself to the constructor
|
30 |
+
function __construct($sh)
|
31 |
+
{
|
32 |
|
33 |
+
$this->sh = $sh;
|
34 |
|
35 |
+
$this->init();
|
36 |
+
}
|
37 |
|
38 |
+
function init()
|
39 |
+
{
|
|
|
|
|
|
|
40 |
|
41 |
+
add_action('init', array( $this, 'add_settings_tab' ));
|
42 |
+
}
|
43 |
|
44 |
+
function add_settings_tab()
|
45 |
+
{
|
46 |
|
47 |
+
$this->sh->registerSettingsTab(array(
|
48 |
+
'slug' => 'my_unique_settings_tab_slug',
|
49 |
+
'name' => __('Example tab', 'simple-history'),
|
50 |
+
'function' => array( $this, 'settings_tab_output' ),
|
51 |
+
));
|
52 |
+
}
|
53 |
|
54 |
+
function settings_tab_output()
|
55 |
+
{
|
56 |
|
57 |
+
?>
|
58 |
|
59 |
+
<h3>Hi there!</h3>
|
60 |
|
61 |
+
<p>I'm the output from on settings tab.</p>
|
62 |
|
63 |
+
<?php
|
64 |
+
}
|
65 |
} // end class
|
66 |
|
67 |
|
examples/example-logger.php
CHANGED
@@ -11,86 +11,85 @@ exit;
|
|
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(
|
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 (
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
}// End if().
|
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 |
// We make sure that the SimpleLogger class exists before trying to extend it.
|
20 |
// This prevents error if the Simple History plugin gets inactivated.
|
21 |
+
if (class_exists('SimpleLogger')) {
|
22 |
+
|
23 |
+
/**
|
24 |
+
* This is the class that does the main work!
|
25 |
+
*/
|
26 |
+
class FourOhFourLogger extends SimpleLogger
|
27 |
+
{
|
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 |
+
|
42 |
+
$arr_info = array(
|
43 |
+
'name' => '404 Logger',
|
44 |
+
'description' => 'Logs access to pages that result in page not found errors (error code 404)',
|
45 |
+
'capability' => 'edit_pages',
|
46 |
+
'messages' => array(
|
47 |
+
'page_not_found' => __('Got a 404-page when trying to visit "{request_uri}"', 'simple-history'),
|
48 |
+
),
|
49 |
+
'labels' => array(
|
50 |
+
'search' => array(
|
51 |
+
'label' => _x('Pages not found (404 errors)', 'User logger: 404', 'simple-history'),
|
52 |
+
'options' => array(
|
53 |
+
_x('Pages not found', 'User logger: 404', 'simple-history') => array(
|
54 |
+
'page_not_found',
|
55 |
+
),
|
56 |
+
),
|
57 |
+
), // end search
|
58 |
+
), // end labels
|
59 |
+
);
|
60 |
+
|
61 |
+
return $arr_info;
|
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 |
+
|
72 |
+
// Call a function when WordPress finds a 404 page
|
73 |
+
add_action('404_template', array( $this, 'on_404_template' ), 10, 1);
|
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 |
+
|
84 |
+
$context = array(
|
85 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
86 |
+
'request_uri' => isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '',
|
87 |
+
'http_referer' => isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '',
|
88 |
+
);
|
89 |
+
|
90 |
+
$this->warningMessage('page_not_found', $context);
|
91 |
+
|
92 |
+
return $template;
|
93 |
+
}
|
94 |
+
}
|
95 |
}// End if().
|
examples/examples.php
CHANGED
@@ -13,7 +13,7 @@ exit;
|
|
13 |
*/
|
14 |
|
15 |
// Add $_GET, $_POST, and more info to each logged even.
|
16 |
-
define(
|
17 |
|
18 |
|
19 |
/**
|
@@ -24,65 +24,60 @@ define( 'SIMPLE_HISTORY_LOG_DEBUG', true );
|
|
24 |
* Remove the "Clear log"-button, so a user with admin access can not clear the log
|
25 |
* and wipe their mischievous behavior from the log.
|
26 |
*/
|
27 |
-
add_filter(
|
28 |
-
|
29 |
-
|
30 |
});
|
31 |
|
32 |
// Modify who can read a logger.
|
33 |
// Modify the if part to give users access or no access to a logger.
|
34 |
-
add_filter(
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
}, 10, 3 );
|
47 |
|
48 |
|
49 |
// Do not log some post types, for example pages and attachments in this case
|
50 |
-
add_filter(
|
51 |
-
|
52 |
-
$post_types_to_not_log = array(
|
53 |
-
'page',
|
54 |
-
'attachment',
|
55 |
-
);
|
56 |
-
|
57 |
-
if ( ( isset( $logger->slug ) && ($logger->slug === 'SimplePostLogger' || $logger->slug === 'SimpleMediaLogger') ) && ( isset( $context['post_type'] ) && in_array( $context['post_type'], $post_types_to_not_log ) ) ) {
|
58 |
-
|
59 |
-
$do_log = false;
|
60 |
|
61 |
-
|
|
|
|
|
|
|
62 |
|
63 |
-
|
|
|
|
|
64 |
|
|
|
65 |
}, 10, 5);
|
66 |
|
67 |
// Disable all logging
|
68 |
-
add_filter(
|
69 |
|
70 |
/**
|
71 |
* Example that modifies the parameters sent to the message template
|
72 |
* This example will change the post type from "post" or "page" or similar to "my own page type"
|
73 |
*/
|
74 |
-
add_filter(
|
75 |
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
return $context;
|
85 |
|
|
|
86 |
}, 10, 3);
|
87 |
|
88 |
|
@@ -91,11 +86,10 @@ add_filter( 'simple_history/logger/interpolate/context', function( $context, $me
|
|
91 |
* Change capability required to manage the options page of simple history.
|
92 |
* Default capability is "manage_options"
|
93 |
*/
|
94 |
-
add_filter('simple_history/view_settings_capability', function(
|
95 |
-
|
96 |
-
$capability = 'manage_options';
|
97 |
-
return $capability;
|
98 |
|
|
|
|
|
99 |
});
|
100 |
|
101 |
|
@@ -104,244 +98,235 @@ add_filter('simple_history/view_settings_capability', function( $capability ) {
|
|
104 |
* Default capability is "edit_pages". Change to for example "manage options"
|
105 |
* to only allow admins to view the history log.
|
106 |
*/
|
107 |
-
add_filter('simple_history/view_history_capability', function(
|
108 |
-
|
109 |
-
$capability = 'manage_options';
|
110 |
-
return $capability;
|
111 |
|
|
|
|
|
112 |
});
|
113 |
|
114 |
|
115 |
// Skip adding things to the context table during logging.
|
116 |
// Useful if you don't want to add cool and possible super useful info to your logged events.
|
117 |
// Also nice to have if you want to make sure your database does not grow.
|
118 |
-
add_filter('simple_history/log_insert_context', function(
|
119 |
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
return $context;
|
126 |
|
|
|
127 |
}, 10, 2);
|
128 |
|
129 |
// Hide some columns from the detailed context view popup window
|
130 |
-
add_filter('simple_history/log_html_output_details_table/row_keys_to_show', function(
|
131 |
-
|
132 |
-
$logRowKeysToShow['id'] = false;
|
133 |
-
$logRowKeysToShow['logger'] = false;
|
134 |
-
$logRowKeysToShow['level'] = false;
|
135 |
-
$logRowKeysToShow['message'] = false;
|
136 |
|
137 |
-
|
|
|
|
|
|
|
138 |
|
|
|
139 |
}, 10, 2);
|
140 |
|
141 |
|
142 |
// Hide some more columns from the detailed context view popup window
|
143 |
-
add_filter('simple_history/log_html_output_details_table/context_keys_to_show', function(
|
144 |
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
return $logRowContextKeysToShow;
|
151 |
|
|
|
152 |
}, 10, 2);
|
153 |
|
154 |
|
155 |
|
156 |
// Allow only the users specified in $allowed_users to show the history page, the history widget on the dashboard, or the history settings page
|
157 |
-
add_filter(
|
158 |
-
add_filter(
|
159 |
-
add_filter(
|
160 |
-
function function_show_history_dashboard_or_page(
|
161 |
-
|
162 |
-
$allowed_users = array(
|
163 |
-
'user1@example.com',
|
164 |
-
'anotheruser@example.com',
|
165 |
-
);
|
166 |
|
167 |
-
|
|
|
|
|
|
|
168 |
|
169 |
-
|
170 |
-
$show = false;
|
171 |
-
}
|
172 |
|
173 |
-
|
|
|
|
|
174 |
|
|
|
175 |
}
|
176 |
|
177 |
|
178 |
// Skip loading of loggers
|
179 |
-
add_filter('simple_history/logger/load_logger', function(
|
180 |
-
|
181 |
-
// Don't load loggers for comments or menus, i.e. don't log changes to comments or to menus
|
182 |
-
if ( in_array( $oneLoggerFile, array( 'SimpleCommentsLogger', 'SimpleMenuLogger' ) ) ) {
|
183 |
-
$load_logger = false;
|
184 |
-
}
|
185 |
|
186 |
-
|
|
|
|
|
|
|
187 |
|
|
|
188 |
}, 10, 2);
|
189 |
|
190 |
/**
|
191 |
* Load only the loggers that are specified in the $do_log_us array
|
192 |
*/
|
193 |
-
add_filter('simple_history/logger/load_logger', function(
|
194 |
|
195 |
-
|
196 |
-
|
197 |
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
|
202 |
-
|
203 |
-
|
204 |
-
}, 10, 2 );
|
205 |
|
206 |
|
207 |
// Skip the loading of dropins
|
208 |
-
add_filter('simple_history/dropin/load_dropin', function(
|
209 |
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
return $load_dropin;
|
221 |
|
|
|
222 |
}, 10, 2);
|
223 |
|
224 |
|
225 |
// Don't log failed logins
|
226 |
-
add_filter('simple_history/simple_logger/log_message_key', function(
|
227 |
-
|
228 |
-
// Don't log login attempts to non existing users
|
229 |
-
if ( 'SimpleUserLogger' == $loggerSlug && 'user_unknown_login_failed' == $messageKey ) {
|
230 |
-
$doLog = false;
|
231 |
-
}
|
232 |
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
|
238 |
-
|
|
|
|
|
|
|
239 |
|
|
|
240 |
}, 10, 5);
|
241 |
|
242 |
// Never clear the log (default is 60 days)
|
243 |
-
add_filter(
|
244 |
|
245 |
// Clear items that are older than a 7 days (i.e. keep only the most recent 7 days in the log)
|
246 |
-
add_filter(
|
247 |
-
|
248 |
-
$days = 7;
|
249 |
|
250 |
-
|
251 |
|
252 |
-
|
|
|
253 |
|
254 |
// Don't let anyone - even with the correct secret - view the RSS feed
|
255 |
-
add_filter(
|
256 |
|
257 |
// Skip loading of a dropin completely (in this case the RSS dropin)
|
258 |
-
add_filter(
|
259 |
|
260 |
/**
|
261 |
* Example of logging
|
262 |
*/
|
263 |
|
264 |
// This is the easiest and safest way to add messages to the log:
|
265 |
-
apply_filters(
|
266 |
-
apply_filters(
|
267 |
-
|
268 |
-
|
269 |
-
)
|
270 |
-
apply_filters(
|
271 |
|
272 |
// Below is the function way of adding things to the log
|
273 |
// Remember to check that the SimpleLogger function exists before trying to log anything,
|
274 |
// or else your site will break if you disable the Simple History plugin
|
275 |
// (Use the apply_filters method above if you want to stay safer!)
|
276 |
-
if (
|
277 |
-
|
278 |
}
|
279 |
|
280 |
// Add a message to the history log
|
281 |
-
SimpleLogger()->info(
|
282 |
|
283 |
// Add log entries with different severities
|
284 |
-
SimpleLogger()->warning(
|
285 |
-
SimpleLogger()->debug(
|
286 |
|
287 |
// Add a message to the history log
|
288 |
// and then add a second log entry with same info and Simple History
|
289 |
// will make these two become an "occasionGroup",
|
290 |
// i.e. collapsing their entries into one expandable log item
|
291 |
-
SimpleLogger()->info(
|
292 |
-
SimpleLogger()->info(
|
293 |
|
294 |
// Log entries can have placeholders and context
|
295 |
// This makes log entried translatable and filterable
|
296 |
SimpleLogger()->notice(
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
);
|
307 |
|
308 |
// Log entried can have custom occasionsID
|
309 |
// This will group items together and a log entry will only be shown once
|
310 |
// in the log overview, even if the logged messages are different
|
311 |
-
for (
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
}
|
318 |
|
319 |
// Events can have different "initiators",
|
320 |
// i.e. who was responsible for the logged event
|
321 |
// Initiator "WORDPRESS" means that WordPress did something on it's own
|
322 |
SimpleLogger()->info(
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
);
|
330 |
|
331 |
// Initiator "WP_USER" means that a logged in user did someting
|
332 |
SimpleLogger()->info(
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
);
|
341 |
|
342 |
// // Initiator "WEB_USER" means that an unknown internet user did something
|
343 |
SimpleLogger()->warning("An attempt to login as user 'administrator' failed to login because the wrong password was entered", array(
|
344 |
-
|
345 |
));
|
346 |
|
347 |
|
@@ -349,12 +334,12 @@ SimpleLogger()->warning("An attempt to login as user 'administrator' failed to l
|
|
349 |
// Data can be used later on to show detailed info about a log entry
|
350 |
// and does not need to be shown on the overview screen
|
351 |
SimpleLogger()->info("Edited product '{pagename}'", array(
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
));
|
359 |
|
360 |
|
@@ -366,31 +351,31 @@ wp_schedule_event( time(), "hourly", "simple_history_cron_testhook");
|
|
366 |
wp_clear_scheduled_hook("simple_history_cron_testhook");
|
367 |
add_action( 'simple_history_cron_testhook', 'simple_history_cron_testhook_function' );
|
368 |
function simple_history_cron_testhook_function() {
|
369 |
-
|
370 |
}
|
371 |
*/
|
372 |
|
373 |
/*
|
374 |
add_action("init", function() {
|
375 |
|
376 |
-
|
377 |
|
378 |
-
|
379 |
-
|
380 |
|
381 |
-
|
382 |
|
383 |
-
|
384 |
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
|
393 |
-
|
394 |
|
395 |
}, 100);
|
396 |
*/
|
@@ -399,7 +384,7 @@ add_action("init", function() {
|
|
399 |
/*
|
400 |
add_action("init", function() {
|
401 |
|
402 |
-
|
403 |
|
404 |
}, 100);
|
405 |
// */
|
13 |
*/
|
14 |
|
15 |
// Add $_GET, $_POST, and more info to each logged even.
|
16 |
+
define('SIMPLE_HISTORY_LOG_DEBUG', true);
|
17 |
|
18 |
|
19 |
/**
|
24 |
* Remove the "Clear log"-button, so a user with admin access can not clear the log
|
25 |
* and wipe their mischievous behavior from the log.
|
26 |
*/
|
27 |
+
add_filter('simple_history/user_can_clear_log', function ($user_can_clear_log) {
|
28 |
+
$user_can_clear_log = false;
|
29 |
+
return $user_can_clear_log;
|
30 |
});
|
31 |
|
32 |
// Modify who can read a logger.
|
33 |
// Modify the if part to give users access or no access to a logger.
|
34 |
+
add_filter('simple_history/loggers_user_can_read/can_read_single_logger', function ($user_can_read_logger, $logger_instance, $user_id) {
|
35 |
|
36 |
+
// in this example user with id 3 gets access to the post logger
|
37 |
+
// while user with id 8 does not get any access to it
|
38 |
+
if ($logger_instance->slug == 'SimplePostLogger' && $user_id === 3) {
|
39 |
+
$user_can_read_logger = true;
|
40 |
+
} elseif ($logger_instance->slug == 'SimplePostLogger' && $user_id === 9) {
|
41 |
+
$user_can_read_logger = false;
|
42 |
+
}
|
43 |
|
44 |
+
return $user_can_read_logger;
|
45 |
+
}, 10, 3);
|
|
|
46 |
|
47 |
|
48 |
// Do not log some post types, for example pages and attachments in this case
|
49 |
+
add_filter('simple_history/log/do_log', function ($do_log = null, $level = null, $message = null, $context = null, $logger = null) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
|
51 |
+
$post_types_to_not_log = array(
|
52 |
+
'page',
|
53 |
+
'attachment',
|
54 |
+
);
|
55 |
|
56 |
+
if (( isset($logger->slug) && ($logger->slug === 'SimplePostLogger' || $logger->slug === 'SimpleMediaLogger') ) && ( isset($context['post_type']) && in_array($context['post_type'], $post_types_to_not_log) )) {
|
57 |
+
$do_log = false;
|
58 |
+
}
|
59 |
|
60 |
+
return $do_log;
|
61 |
}, 10, 5);
|
62 |
|
63 |
// Disable all logging
|
64 |
+
add_filter('simple_history/log/do_log', '__return_false');
|
65 |
|
66 |
/**
|
67 |
* Example that modifies the parameters sent to the message template
|
68 |
* This example will change the post type from "post" or "page" or similar to "my own page type"
|
69 |
*/
|
70 |
+
add_filter('simple_history/logger/interpolate/context', function ($context, $message, $row) {
|
71 |
|
72 |
+
if (empty($row)) {
|
73 |
+
return $context;
|
74 |
+
}
|
75 |
|
76 |
+
if ($row->logger == 'SimplePostLogger' && $row->context_message_key == 'post_updated') {
|
77 |
+
$context['post_type'] = 'my own page type';
|
78 |
+
}
|
|
|
|
|
79 |
|
80 |
+
return $context;
|
81 |
}, 10, 3);
|
82 |
|
83 |
|
86 |
* Change capability required to manage the options page of simple history.
|
87 |
* Default capability is "manage_options"
|
88 |
*/
|
89 |
+
add_filter('simple_history/view_settings_capability', function ($capability) {
|
|
|
|
|
|
|
90 |
|
91 |
+
$capability = 'manage_options';
|
92 |
+
return $capability;
|
93 |
});
|
94 |
|
95 |
|
98 |
* Default capability is "edit_pages". Change to for example "manage options"
|
99 |
* to only allow admins to view the history log.
|
100 |
*/
|
101 |
+
add_filter('simple_history/view_history_capability', function ($capability) {
|
|
|
|
|
|
|
102 |
|
103 |
+
$capability = 'manage_options';
|
104 |
+
return $capability;
|
105 |
});
|
106 |
|
107 |
|
108 |
// Skip adding things to the context table during logging.
|
109 |
// Useful if you don't want to add cool and possible super useful info to your logged events.
|
110 |
// Also nice to have if you want to make sure your database does not grow.
|
111 |
+
add_filter('simple_history/log_insert_context', function ($context, $data) {
|
112 |
|
113 |
+
unset($context['_user_id']);
|
114 |
+
unset($context['_user_login']);
|
115 |
+
unset($context['_user_email']);
|
116 |
+
unset($context['server_http_user_agent']);
|
|
|
|
|
117 |
|
118 |
+
return $context;
|
119 |
}, 10, 2);
|
120 |
|
121 |
// Hide some columns from the detailed context view popup window
|
122 |
+
add_filter('simple_history/log_html_output_details_table/row_keys_to_show', function ($logRowKeysToShow, $oneLogRow) {
|
|
|
|
|
|
|
|
|
|
|
123 |
|
124 |
+
$logRowKeysToShow['id'] = false;
|
125 |
+
$logRowKeysToShow['logger'] = false;
|
126 |
+
$logRowKeysToShow['level'] = false;
|
127 |
+
$logRowKeysToShow['message'] = false;
|
128 |
|
129 |
+
return $logRowKeysToShow;
|
130 |
}, 10, 2);
|
131 |
|
132 |
|
133 |
// Hide some more columns from the detailed context view popup window
|
134 |
+
add_filter('simple_history/log_html_output_details_table/context_keys_to_show', function ($logRowContextKeysToShow, $oneLogRow) {
|
135 |
|
136 |
+
$logRowContextKeysToShow['plugin_slug'] = false;
|
137 |
+
$logRowContextKeysToShow['plugin_name'] = false;
|
138 |
+
$logRowContextKeysToShow['plugin_title'] = false;
|
139 |
+
$logRowContextKeysToShow['plugin_description'] = false;
|
|
|
|
|
140 |
|
141 |
+
return $logRowContextKeysToShow;
|
142 |
}, 10, 2);
|
143 |
|
144 |
|
145 |
|
146 |
// Allow only the users specified in $allowed_users to show the history page, the history widget on the dashboard, or the history settings page
|
147 |
+
add_filter('simple_history/show_dashboard_page', 'function_show_history_dashboard_or_page');
|
148 |
+
add_filter('simple_history/show_dashboard_widget', 'function_show_history_dashboard_or_page');
|
149 |
+
add_filter('simple_history/show_settings_page', 'function_show_history_dashboard_or_page');
|
150 |
+
function function_show_history_dashboard_or_page($show)
|
151 |
+
{
|
|
|
|
|
|
|
|
|
152 |
|
153 |
+
$allowed_users = array(
|
154 |
+
'user1@example.com',
|
155 |
+
'anotheruser@example.com',
|
156 |
+
);
|
157 |
|
158 |
+
$user = wp_get_current_user();
|
|
|
|
|
159 |
|
160 |
+
if (! in_array($user->user_email, $allowed_users)) {
|
161 |
+
$show = false;
|
162 |
+
}
|
163 |
|
164 |
+
return $show;
|
165 |
}
|
166 |
|
167 |
|
168 |
// Skip loading of loggers
|
169 |
+
add_filter('simple_history/logger/load_logger', function ($load_logger, $oneLoggerFile) {
|
|
|
|
|
|
|
|
|
|
|
170 |
|
171 |
+
// Don't load loggers for comments or menus, i.e. don't log changes to comments or to menus
|
172 |
+
if (in_array($oneLoggerFile, array( 'SimpleCommentsLogger', 'SimpleMenuLogger' ))) {
|
173 |
+
$load_logger = false;
|
174 |
+
}
|
175 |
|
176 |
+
return $load_logger;
|
177 |
}, 10, 2);
|
178 |
|
179 |
/**
|
180 |
* Load only the loggers that are specified in the $do_log_us array
|
181 |
*/
|
182 |
+
add_filter('simple_history/logger/load_logger', function ($load_logger, $logger_basename) {
|
183 |
|
184 |
+
$load_logger = false;
|
185 |
+
$do_log_us = array( 'SimplePostLogger', 'SimplePluginLogger', 'SimpleLogger' );
|
186 |
|
187 |
+
if (in_array($logger_basename, $do_log_us)) {
|
188 |
+
$load_logger = true;
|
189 |
+
}
|
190 |
|
191 |
+
return $load_logger;
|
192 |
+
}, 10, 2);
|
|
|
193 |
|
194 |
|
195 |
// Skip the loading of dropins
|
196 |
+
add_filter('simple_history/dropin/load_dropin', function ($load_dropin, $dropinFileBasename) {
|
197 |
|
198 |
+
// Don't load the RSS feed dropin
|
199 |
+
if ($dropinFileBasename == 'SimpleHistoryRSSDropin') {
|
200 |
+
$load_dropin = false;
|
201 |
+
}
|
202 |
|
203 |
+
// Don't load the dropin that polls for changes
|
204 |
+
if ($dropinFileBasename == 'SimpleHistoryNewRowsNotifier') {
|
205 |
+
$load_dropin = false;
|
206 |
+
}
|
|
|
|
|
207 |
|
208 |
+
return $load_dropin;
|
209 |
}, 10, 2);
|
210 |
|
211 |
|
212 |
// Don't log failed logins
|
213 |
+
add_filter('simple_history/simple_logger/log_message_key', function ($doLog, $loggerSlug, $messageKey, $SimpleLoggerLogLevelsLevel, $context) {
|
|
|
|
|
|
|
|
|
|
|
214 |
|
215 |
+
// Don't log login attempts to non existing users
|
216 |
+
if ('SimpleUserLogger' == $loggerSlug && 'user_unknown_login_failed' == $messageKey) {
|
217 |
+
$doLog = false;
|
218 |
+
}
|
219 |
|
220 |
+
// Don't log failed logins to existing users
|
221 |
+
if ('SimpleUserLogger' == $loggerSlug && 'user_login_failed' == $messageKey) {
|
222 |
+
$doLog = false;
|
223 |
+
}
|
224 |
|
225 |
+
return $doLog;
|
226 |
}, 10, 5);
|
227 |
|
228 |
// Never clear the log (default is 60 days)
|
229 |
+
add_filter('simple_history/db_purge_days_interval', '__return_zero');
|
230 |
|
231 |
// Clear items that are older than a 7 days (i.e. keep only the most recent 7 days in the log)
|
232 |
+
add_filter('simple_history/db_purge_days_interval', function ($days) {
|
|
|
|
|
233 |
|
234 |
+
$days = 7;
|
235 |
|
236 |
+
return $days;
|
237 |
+
});
|
238 |
|
239 |
// Don't let anyone - even with the correct secret - view the RSS feed
|
240 |
+
add_filter('simple_history/rss_feed_show', '__return_false');
|
241 |
|
242 |
// Skip loading of a dropin completely (in this case the RSS dropin)
|
243 |
+
add_filter('simple_history/dropin/load_dropin_SimpleHistoryRSSDropin', '__return_false');
|
244 |
|
245 |
/**
|
246 |
* Example of logging
|
247 |
*/
|
248 |
|
249 |
// This is the easiest and safest way to add messages to the log:
|
250 |
+
apply_filters('simple_history_log', 'This is a logged message');
|
251 |
+
apply_filters('simple_history_log', 'This is a message with some context added', array(
|
252 |
+
'isATestMessage' => 'yup',
|
253 |
+
'debugRequestData' => $_REQUEST,
|
254 |
+
));
|
255 |
+
apply_filters('simple_history_log', 'This is another logged message, with another severity level', null, 'debug');
|
256 |
|
257 |
// Below is the function way of adding things to the log
|
258 |
// Remember to check that the SimpleLogger function exists before trying to log anything,
|
259 |
// or else your site will break if you disable the Simple History plugin
|
260 |
// (Use the apply_filters method above if you want to stay safer!)
|
261 |
+
if (function_exists('SimpleLogger')) {
|
262 |
+
SimpleLogger()->info('This is a message added to the log');
|
263 |
}
|
264 |
|
265 |
// Add a message to the history log
|
266 |
+
SimpleLogger()->info('This is a message sent to the log');
|
267 |
|
268 |
// Add log entries with different severities
|
269 |
+
SimpleLogger()->warning("User 'Jessie' deleted user 'Kim'");
|
270 |
+
SimpleLogger()->debug('Ok, cron job is running!');
|
271 |
|
272 |
// Add a message to the history log
|
273 |
// and then add a second log entry with same info and Simple History
|
274 |
// will make these two become an "occasionGroup",
|
275 |
// i.e. collapsing their entries into one expandable log item
|
276 |
+
SimpleLogger()->info('This is a message sent to the log');
|
277 |
+
SimpleLogger()->info('This is a message sent to the log');
|
278 |
|
279 |
// Log entries can have placeholders and context
|
280 |
// This makes log entried translatable and filterable
|
281 |
SimpleLogger()->notice(
|
282 |
+
'User {username} edited page {pagename}',
|
283 |
+
array(
|
284 |
+
'username' => 'jessie',
|
285 |
+
'pagename' => 'My test page',
|
286 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
287 |
+
'_user_id' => 5,
|
288 |
+
'_user_login' => 'jess',
|
289 |
+
'_user_email' => 'jessie@example.com',
|
290 |
+
)
|
291 |
);
|
292 |
|
293 |
// Log entried can have custom occasionsID
|
294 |
// This will group items together and a log entry will only be shown once
|
295 |
// in the log overview, even if the logged messages are different
|
296 |
+
for ($i = 0; $i < rand(1, 50); $i++) {
|
297 |
+
SimpleLogger()->notice('User {username} edited page {pagename}', array(
|
298 |
+
'username' => "example_user_{$i}",
|
299 |
+
'pagename' => 'My test page',
|
300 |
+
'_occasionsID' => 'postID:24884,action:edited',
|
301 |
+
));
|
302 |
}
|
303 |
|
304 |
// Events can have different "initiators",
|
305 |
// i.e. who was responsible for the logged event
|
306 |
// Initiator "WORDPRESS" means that WordPress did something on it's own
|
307 |
SimpleLogger()->info(
|
308 |
+
'WordPress updated itself from version {from_version} to {to_version}',
|
309 |
+
array(
|
310 |
+
'from_version' => '3.8',
|
311 |
+
'to_version' => '3.8.1',
|
312 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
313 |
+
)
|
314 |
);
|
315 |
|
316 |
// Initiator "WP_USER" means that a logged in user did someting
|
317 |
SimpleLogger()->info(
|
318 |
+
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
319 |
+
array(
|
320 |
+
'plugin_name' => 'Ninja Forms',
|
321 |
+
'plugin_from_version' => '1.1',
|
322 |
+
'plugin_to_version' => '1.1.2',
|
323 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
324 |
+
)
|
325 |
);
|
326 |
|
327 |
// // Initiator "WEB_USER" means that an unknown internet user did something
|
328 |
SimpleLogger()->warning("An attempt to login as user 'administrator' failed to login because the wrong password was entered", array(
|
329 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
330 |
));
|
331 |
|
332 |
|
334 |
// Data can be used later on to show detailed info about a log entry
|
335 |
// and does not need to be shown on the overview screen
|
336 |
SimpleLogger()->info("Edited product '{pagename}'", array(
|
337 |
+
'pagename' => 'We are hiring!',
|
338 |
+
'_postType' => 'product',
|
339 |
+
'_userID' => 1,
|
340 |
+
'_userLogin' => 'jessie',
|
341 |
+
'_userEmail' => 'jessie@example.com',
|
342 |
+
'_occasionsID' => 'username:1,postID:24885,action:edited',
|
343 |
));
|
344 |
|
345 |
|
351 |
wp_clear_scheduled_hook("simple_history_cron_testhook");
|
352 |
add_action( 'simple_history_cron_testhook', 'simple_history_cron_testhook_function' );
|
353 |
function simple_history_cron_testhook_function() {
|
354 |
+
SimpleLogger()->info("This is a message inside a cron function");
|
355 |
}
|
356 |
*/
|
357 |
|
358 |
/*
|
359 |
add_action("init", function() {
|
360 |
|
361 |
+
global $wp_current_filter;
|
362 |
|
363 |
+
$doing_cron = get_transient( 'doing_cron' );
|
364 |
+
$const_doing_cron = defined('DOING_CRON') && DOING_CRON;
|
365 |
|
366 |
+
if ($const_doing_cron) {
|
367 |
|
368 |
+
$current_filter = current_filter();
|
369 |
|
370 |
+
SimpleLogger()->info("This is a message inside init, trying to log crons", array(
|
371 |
+
"doing_cron" => simpleHistory::json_encode($doing_cron),
|
372 |
+
"current_filter" => $current_filter,
|
373 |
+
"wp_current_filter" => $wp_current_filter,
|
374 |
+
"wp_current_filter" => simpleHistory::json_encode( $wp_current_filter ),
|
375 |
+
"const_doing_cron" => simpleHistory::json_encode($const_doing_cron)
|
376 |
+
));
|
377 |
|
378 |
+
}
|
379 |
|
380 |
}, 100);
|
381 |
*/
|
384 |
/*
|
385 |
add_action("init", function() {
|
386 |
|
387 |
+
#SimpleLogger()->info("This is a regular info message" . time());
|
388 |
|
389 |
}, 100);
|
390 |
// */
|
inc/SimpleHistory.php
CHANGED
@@ -7,4191 +7,3261 @@ defined('ABSPATH') or die();
|
|
7 |
*/
|
8 |
class SimpleHistory
|
9 |
{
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
|
1609 |
-
|
1610 |
-
|
1611 |
-
|
1612 |
-
|
1613 |
-
|
1614 |
-
|
1615 |
-
|
1616 |
-
|
1617 |
-
|
1618 |
-
|
1619 |
-
|
1620 |
-
|
1621 |
-
|
1622 |
-
|
1623 |
-
|
1624 |
-
|
1625 |
-
|
1626 |
-
|
1627 |
-
|
1628 |
-
|
1629 |
-
|
1630 |
-
|
1631 |
-
|
1632 |
-
|
1633 |
-
|
1634 |
-
|
1635 |
-
|
1636 |
-
|
1637 |
-
|
1638 |
-
|
1639 |
-
|
1640 |
-
|
1641 |
-
|
1642 |
-
|
1643 |
-
|
1644 |
-
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
1656 |
-
|
1657 |
-
|
1658 |
-
|
1659 |
-
);
|
1660 |
-
|
1661 |
-
wp_enqueue_script(
|
1662 |
-
'select2',
|
1663 |
-
SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.full.min.js',
|
1664 |
-
array('jquery')
|
1665 |
-
);
|
1666 |
-
wp_enqueue_style(
|
1667 |
-
'select2',
|
1668 |
-
SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.min.css'
|
1669 |
-
);
|
1670 |
-
|
1671 |
-
// Translations that we use in JavaScript
|
1672 |
-
wp_localize_script(
|
1673 |
-
'simple_history_script',
|
1674 |
-
'simple_history_script_vars',
|
1675 |
-
array(
|
1676 |
-
'settingsConfirmClearLog' => __(
|
1677 |
-
'Remove all log items?',
|
1678 |
-
'simple-history'
|
1679 |
-
),
|
1680 |
-
'pagination' => array(
|
1681 |
-
'goToTheFirstPage' => __(
|
1682 |
-
'Go to the first page',
|
1683 |
-
'simple-history'
|
1684 |
-
),
|
1685 |
-
'goToThePrevPage' => __(
|
1686 |
-
'Go to the previous page',
|
1687 |
-
'simple-history'
|
1688 |
-
),
|
1689 |
-
'goToTheNextPage' => __(
|
1690 |
-
'Go to the next page',
|
1691 |
-
'simple-history'
|
1692 |
-
),
|
1693 |
-
'goToTheLastPage' => __(
|
1694 |
-
'Go to the last page',
|
1695 |
-
'simple-history'
|
1696 |
-
),
|
1697 |
-
'currentPage' => __('Current page', 'simple-history')
|
1698 |
-
),
|
1699 |
-
'loadLogAPIError' => __(
|
1700 |
-
'Oups, the log could not be loaded right now.',
|
1701 |
-
'simple-history'
|
1702 |
-
),
|
1703 |
-
'ajaxLoadError' => __(
|
1704 |
-
'Hm, the log could not be loaded right now. Perhaps another plugin is giving some errors. Anyway, below is the output I got from the server.',
|
1705 |
-
'simple-history'
|
1706 |
-
),
|
1707 |
-
'logNoHits' => __(
|
1708 |
-
'Your search did not match any history events.',
|
1709 |
-
'simple-history'
|
1710 |
-
)
|
1711 |
-
)
|
1712 |
-
);
|
1713 |
-
|
1714 |
-
// Call plugins adminCSS-method, so they can add their CSS
|
1715 |
-
foreach ($this->instantiatedLoggers as $one_logger) {
|
1716 |
-
if (method_exists($one_logger['instance'], 'adminCSS')) {
|
1717 |
-
$one_logger['instance']->adminCSS();
|
1718 |
-
}
|
1719 |
-
}
|
1720 |
-
|
1721 |
-
// Add timeago.js
|
1722 |
-
wp_enqueue_script(
|
1723 |
-
'timeago',
|
1724 |
-
SIMPLE_HISTORY_DIR_URL . 'js/timeago/jquery.timeago.js',
|
1725 |
-
array('jquery'),
|
1726 |
-
'1.5.2',
|
1727 |
-
true
|
1728 |
-
);
|
1729 |
-
|
1730 |
-
// Determine current locale to load timeago locale
|
1731 |
-
$locale = strtolower(substr(get_locale(), 0, 2));
|
1732 |
-
$locale_url_path =
|
1733 |
-
SIMPLE_HISTORY_DIR_URL .
|
1734 |
-
'js/timeago/locales/jquery.timeago.%s.js';
|
1735 |
-
$locale_dir_path =
|
1736 |
-
SIMPLE_HISTORY_PATH . 'js/timeago/locales/jquery.timeago.%s.js';
|
1737 |
-
|
1738 |
-
// Only enqueue if locale-file exists on file system
|
1739 |
-
if (file_exists(sprintf($locale_dir_path, $locale))) {
|
1740 |
-
wp_enqueue_script(
|
1741 |
-
'timeago-locale',
|
1742 |
-
sprintf($locale_url_path, $locale),
|
1743 |
-
array('jquery'),
|
1744 |
-
'1.5.2',
|
1745 |
-
true
|
1746 |
-
);
|
1747 |
-
} else {
|
1748 |
-
wp_enqueue_script(
|
1749 |
-
'timeago-locale',
|
1750 |
-
sprintf($locale_url_path, 'en'),
|
1751 |
-
array('jquery'),
|
1752 |
-
'1.5.2',
|
1753 |
-
true
|
1754 |
-
);
|
1755 |
-
}
|
1756 |
-
// end add timeago
|
1757 |
-
// Load Select2 locale
|
1758 |
-
$locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/select2/i18n/%s.js';
|
1759 |
-
$locale_dir_path = SIMPLE_HISTORY_PATH . 'js/select2/i18n/%s.js';
|
1760 |
-
|
1761 |
-
if (file_exists(sprintf($locale_dir_path, $locale))) {
|
1762 |
-
wp_enqueue_script(
|
1763 |
-
'select2-locale',
|
1764 |
-
sprintf($locale_url_path, $locale),
|
1765 |
-
array('jquery'),
|
1766 |
-
'3.5.1',
|
1767 |
-
true
|
1768 |
-
);
|
1769 |
-
}
|
1770 |
-
|
1771 |
-
/**
|
1772 |
-
* Fires when the admin scripts have been enqueued.
|
1773 |
-
* Only fires on any of the pages where Simple History is used
|
1774 |
-
*
|
1775 |
-
* @since 2.0
|
1776 |
-
*
|
1777 |
-
* @param SimpleHistory $SimpleHistory This class.
|
1778 |
-
*/
|
1779 |
-
do_action('simple_history/enqueue_admin_scripts', $this);
|
1780 |
-
} // End if().
|
1781 |
-
}
|
1782 |
-
|
1783 |
-
function filter_option_page_capability($capability)
|
1784 |
-
{
|
1785 |
-
return $capability;
|
1786 |
-
}
|
1787 |
-
|
1788 |
-
/**
|
1789 |
-
* Check if plugin version have changed, i.e. has been upgraded
|
1790 |
-
* If upgrade is detected then maybe modify database and so on for that version
|
1791 |
-
*/
|
1792 |
-
function check_for_upgrade()
|
1793 |
-
{
|
1794 |
-
global $wpdb;
|
1795 |
-
|
1796 |
-
$db_version = get_option('simple_history_db_version');
|
1797 |
-
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
1798 |
-
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
1799 |
-
$first_install = false;
|
1800 |
-
|
1801 |
-
// If no db_version is set then this
|
1802 |
-
// is a version of Simple History < 0.4
|
1803 |
-
// or it's a first install
|
1804 |
-
// Fix database not using UTF-8
|
1805 |
-
if (false === $db_version || intval($db_version) == 0) {
|
1806 |
-
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1807 |
-
|
1808 |
-
// Table creation, used to be in register_activation_hook
|
1809 |
-
// We change the varchar size to add one num just to force update of encoding. dbdelta didn't see it otherwise.
|
1810 |
-
$sql =
|
1811 |
-
'CREATE TABLE ' .
|
1812 |
-
$table_name .
|
1813 |
-
' (
|
1814 |
-
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1815 |
-
date datetime NOT NULL,
|
1816 |
-
PRIMARY KEY (id)
|
1817 |
-
) CHARACTER SET=utf8;';
|
1818 |
-
|
1819 |
-
// Upgrade db / fix utf for varchars
|
1820 |
-
dbDelta($sql);
|
1821 |
-
|
1822 |
-
// Fix UTF-8 for table
|
1823 |
-
$sql = sprintf('alter table %1$s charset=utf8;', $table_name);
|
1824 |
-
$wpdb->query($sql);
|
1825 |
-
|
1826 |
-
$db_version_prev = $db_version;
|
1827 |
-
$db_version = 1;
|
1828 |
-
|
1829 |
-
update_option('simple_history_db_version', $db_version);
|
1830 |
-
|
1831 |
-
// We are not 100% sure that this is a first install,
|
1832 |
-
// but it is at least a very old version that is being updated
|
1833 |
-
$first_install = true;
|
1834 |
-
} // End if().
|
1835 |
-
|
1836 |
-
// If db version is 1 then upgrade to 2
|
1837 |
-
// Version 2 added the action_description column
|
1838 |
-
if (1 == intval($db_version)) {
|
1839 |
-
// V2 used to add column "action_description"
|
1840 |
-
// but it's not used any more so don't do i
|
1841 |
-
$db_version_prev = $db_version;
|
1842 |
-
$db_version = 2;
|
1843 |
-
|
1844 |
-
update_option('simple_history_db_version', $db_version);
|
1845 |
-
}
|
1846 |
-
|
1847 |
-
// Check that all options we use are set to their defaults, if they miss value
|
1848 |
-
// Each option that is missing a value will make a sql call otherwise = unnecessary
|
1849 |
-
$arr_options = array(
|
1850 |
-
array(
|
1851 |
-
'name' => 'simple_history_show_as_page',
|
1852 |
-
'default_value' => 1
|
1853 |
-
),
|
1854 |
-
array(
|
1855 |
-
'name' => 'simple_history_show_on_dashboard',
|
1856 |
-
'default_value' => 1
|
1857 |
-
)
|
1858 |
-
);
|
1859 |
-
|
1860 |
-
foreach ($arr_options as $one_option) {
|
1861 |
-
if (false === ($option_value = get_option($one_option['name']))) {
|
1862 |
-
// Value is not set in db, so set it to a default
|
1863 |
-
update_option(
|
1864 |
-
$one_option['name'],
|
1865 |
-
$one_option['default_value']
|
1866 |
-
);
|
1867 |
-
}
|
1868 |
-
}
|
1869 |
-
|
1870 |
-
/**
|
1871 |
-
* If db_version is 2 then upgrade to 3:
|
1872 |
-
* - Add some fields to existing table wp_simple_history_contexts
|
1873 |
-
* - Add all new table wp_simple_history_contexts
|
1874 |
-
*
|
1875 |
-
* @since 2.0
|
1876 |
-
*/
|
1877 |
-
if (2 == intval($db_version)) {
|
1878 |
-
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1879 |
-
|
1880 |
-
// Update old table
|
1881 |
-
$sql = "
|
1882 |
-
CREATE TABLE {$table_name} (
|
1883 |
-
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1884 |
-
date datetime NOT NULL,
|
1885 |
-
logger varchar(30) DEFAULT NULL,
|
1886 |
-
level varchar(20) DEFAULT NULL,
|
1887 |
-
message varchar(255) DEFAULT NULL,
|
1888 |
-
occasionsID varchar(32) DEFAULT NULL,
|
1889 |
-
initiator varchar(16) DEFAULT NULL,
|
1890 |
-
PRIMARY KEY (id),
|
1891 |
-
KEY date (date),
|
1892 |
-
KEY loggerdate (logger,date)
|
1893 |
-
) CHARSET=utf8;";
|
1894 |
-
|
1895 |
-
dbDelta($sql);
|
1896 |
-
|
1897 |
-
// Add context table
|
1898 |
-
$sql = "
|
1899 |
-
CREATE TABLE IF NOT EXISTS {$table_name_contexts} (
|
1900 |
-
context_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
1901 |
-
history_id bigint(20) unsigned NOT NULL,
|
1902 |
-
`key` varchar(255) DEFAULT NULL,
|
1903 |
-
value longtext,
|
1904 |
-
PRIMARY KEY (context_id),
|
1905 |
-
KEY history_id (history_id),
|
1906 |
-
KEY `key` (`key`)
|
1907 |
-
) CHARSET=utf8;
|
1908 |
-
";
|
1909 |
-
|
1910 |
-
$wpdb->query($sql);
|
1911 |
-
|
1912 |
-
$db_version_prev = $db_version;
|
1913 |
-
$db_version = 3;
|
1914 |
-
update_option('simple_history_db_version', $db_version);
|
1915 |
-
|
1916 |
-
// Update possible old items to use SimpleLegacyLogger
|
1917 |
-
$sql = sprintf(
|
1918 |
-
'
|
1919 |
-
UPDATE %1$s
|
1920 |
-
SET
|
1921 |
-
logger = "SimpleLegacyLogger",
|
1922 |
-
level = "info"
|
1923 |
-
WHERE logger IS NULL
|
1924 |
-
',
|
1925 |
-
$table_name
|
1926 |
-
);
|
1927 |
-
|
1928 |
-
$wpdb->query($sql);
|
1929 |
-
|
1930 |
-
// Say welcome, however loggers are not added this early so we need to
|
1931 |
-
// use a filter to load it later
|
1932 |
-
add_action('simple_history/loggers_loaded', array(
|
1933 |
-
$this,
|
1934 |
-
'addWelcomeLogMessage'
|
1935 |
-
));
|
1936 |
-
} // End if().
|
1937 |
-
|
1938 |
-
/**
|
1939 |
-
* If db version = 3
|
1940 |
-
* then we need to update database to allow null values for some old columns
|
1941 |
-
* that used to work in pre wp 4.1 beta, but since 4.1 wp uses STRICT_ALL_TABLES
|
1942 |
-
* WordPress Commit: https://github.com/WordPress/WordPress/commit/f17d168a0f72211a9bfd9d3fa680713069871bb6
|
1943 |
-
*
|
1944 |
-
* @since 2.0
|
1945 |
-
*/
|
1946 |
-
if (3 == intval($db_version)) {
|
1947 |
-
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1948 |
-
|
1949 |
-
// If old columns exist = this is an old install, then modify the columns so we still can keep them
|
1950 |
-
// we want to keep them because user may have logged items that they want to keep
|
1951 |
-
$db_cools = $wpdb->get_col("DESCRIBE $table_name");
|
1952 |
-
|
1953 |
-
if (in_array('action', $db_cools)) {
|
1954 |
-
$sql = sprintf(
|
1955 |
-
'
|
1956 |
-
ALTER TABLE %1$s
|
1957 |
-
MODIFY `action` varchar(255) NULL,
|
1958 |
-
MODIFY `object_type` varchar(255) NULL,
|
1959 |
-
MODIFY `object_subtype` varchar(255) NULL,
|
1960 |
-
MODIFY `user_id` int(10) NULL,
|
1961 |
-
MODIFY `object_id` int(10) NULL,
|
1962 |
-
MODIFY `object_name` varchar(255) NULL
|
1963 |
-
',
|
1964 |
-
$table_name
|
1965 |
-
);
|
1966 |
-
$wpdb->query($sql);
|
1967 |
-
}
|
1968 |
-
|
1969 |
-
$db_version_prev = $db_version;
|
1970 |
-
$db_version = 4;
|
1971 |
-
|
1972 |
-
update_option('simple_history_db_version', $db_version);
|
1973 |
-
} // End if().
|
1974 |
-
|
1975 |
-
// Some installs on 2.2.2 got failed installs
|
1976 |
-
// We detect these by checking for db_version and then running the install stuff again
|
1977 |
-
if (4 == intval($db_version)) {
|
1978 |
-
if (!$this->does_database_have_data()) {
|
1979 |
-
// not ok, decrease db number so installs will run again and hopefully fix things
|
1980 |
-
$db_version = 0;
|
1981 |
-
} else {
|
1982 |
-
// all looks ok, upgrade to db version 5, so this part is not done again
|
1983 |
-
$db_version = 5;
|
1984 |
-
}
|
1985 |
-
|
1986 |
-
update_option('simple_history_db_version', $db_version);
|
1987 |
-
}
|
1988 |
-
} // end check_for_upgrade
|
1989 |
-
|
1990 |
-
/**
|
1991 |
-
* Check if the database has data/rows
|
1992 |
-
*
|
1993 |
-
* @since 2.1.6
|
1994 |
-
* @return bool True if database is not empty, false if database is empty = contains no data
|
1995 |
-
*/
|
1996 |
-
function does_database_have_data()
|
1997 |
-
{
|
1998 |
-
global $wpdb;
|
1999 |
-
|
2000 |
-
$tableprefix = $wpdb->prefix;
|
2001 |
-
|
2002 |
-
$simple_history_table = SimpleHistory::DBTABLE;
|
2003 |
-
$simple_history_context_table = SimpleHistory::DBTABLE_CONTEXTS;
|
2004 |
-
|
2005 |
-
$sql_data_exists = "SELECT id AS id_exists FROM {$tableprefix}{$simple_history_table} LIMIT 1";
|
2006 |
-
$data_exists = (bool) $wpdb->get_var($sql_data_exists, 0);
|
2007 |
-
|
2008 |
-
return $data_exists;
|
2009 |
-
}
|
2010 |
-
|
2011 |
-
/**
|
2012 |
-
* Greet users to version 2!
|
2013 |
-
* Is only called after database has been upgraded, so only on first install (or upgrade).
|
2014 |
-
* Not called after only plugin activation.
|
2015 |
-
*/
|
2016 |
-
public function addWelcomeLogMessage()
|
2017 |
-
{
|
2018 |
-
$db_data_exists = $this->does_database_have_data();
|
2019 |
-
// $db_data_exists = false;
|
2020 |
-
$pluginLogger = $this->getInstantiatedLoggerBySlug(
|
2021 |
-
'SimplePluginLogger'
|
2022 |
-
);
|
2023 |
-
if ($pluginLogger) {
|
2024 |
-
// Add plugin installed message
|
2025 |
-
$context = array(
|
2026 |
-
'plugin_name' => 'Simple History',
|
2027 |
-
'plugin_description' =>
|
2028 |
-
'Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.',
|
2029 |
-
'plugin_url' => 'http://simple-history.com',
|
2030 |
-
'plugin_version' => SIMPLE_HISTORY_VERSION,
|
2031 |
-
'plugin_author' => 'Pär Thernström'
|
2032 |
-
);
|
2033 |
-
|
2034 |
-
$pluginLogger->infoMessage('plugin_installed', $context);
|
2035 |
-
|
2036 |
-
// Add plugin activated message
|
2037 |
-
$context['plugin_slug'] = 'simple-history';
|
2038 |
-
$context['plugin_title'] =
|
2039 |
-
'<a href="http://simple-history.com/">Simple History</a>';
|
2040 |
-
|
2041 |
-
$pluginLogger->infoMessage('plugin_activated', $context);
|
2042 |
-
}
|
2043 |
-
|
2044 |
-
if (!$db_data_exists) {
|
2045 |
-
$welcome_message_1 = __(
|
2046 |
-
'
|
2047 |
Welcome to Simple History!
|
2048 |
|
2049 |
This is the main history feed. It will contain events that this plugin has logged.
|
2050 |
',
|
2051 |
-
|
2052 |
-
|
2053 |
|
2054 |
-
|
2055 |
-
|
2056 |
Because Simple History was just recently installed, this feed does not contain much events yet. But keep the plugin activated and soon you will see detailed information about page edits, plugin updates, user logins, and much more.
|
2057 |
',
|
2058 |
-
|
2059 |
-
|
2060 |
-
|
2061 |
-
|
2062 |
-
|
2063 |
-
|
2064 |
-
|
2065 |
-
|
2066 |
-
|
2067 |
-
|
2068 |
-
|
2069 |
-
|
2070 |
-
|
2071 |
-
|
2072 |
-
|
2073 |
-
|
2074 |
-
|
2075 |
-
|
2076 |
-
|
2077 |
-
|
2078 |
-
|
2079 |
-
|
2080 |
-
|
2081 |
-
|
2082 |
-
|
2083 |
-
|
2084 |
-
|
2085 |
-
|
2086 |
-
|
2087 |
-
|
2088 |
-
|
2089 |
-
|
2090 |
-
|
2091 |
-
|
2092 |
-
|
2093 |
-
|
2094 |
-
|
2095 |
-
|
2096 |
-
|
2097 |
-
|
2098 |
-
|
2099 |
-
|
2100 |
-
|
2101 |
-
|
2102 |
-
|
2103 |
-
|
2104 |
-
|
2105 |
-
|
2106 |
-
|
2107 |
-
|
2108 |
-
|
2109 |
-
|
2110 |
-
|
2111 |
-
|
2112 |
-
|
2113 |
-
|
2114 |
-
|
2115 |
-
|
2116 |
-
|
2117 |
-
|
2118 |
-
|
2119 |
-
|
2120 |
-
|
2121 |
-
|
2122 |
-
|
2123 |
-
|
2124 |
-
|
2125 |
-
|
2126 |
-
|
2127 |
-
|
2128 |
-
|
2129 |
-
|
2130 |
-
|
2131 |
-
|
2132 |
-
|
2133 |
-
|
2134 |
-
|
2135 |
-
|
2136 |
-
|
2137 |
-
|
2138 |
-
|
2139 |
-
|
2140 |
-
|
2141 |
-
|
2142 |
-
|
2143 |
-
|
2144 |
-
|
2145 |
-
|
2146 |
-
|
2147 |
-
|
2148 |
-
|
2149 |
-
|
2150 |
-
|
2151 |
-
|
2152 |
-
|
2153 |
-
|
2154 |
-
|
2155 |
-
|
2156 |
-
|
2157 |
-
|
2158 |
-
|
2159 |
-
|
2160 |
-
|
2161 |
-
|
2162 |
-
|
2163 |
-
|
2164 |
-
|
2165 |
-
|
2166 |
-
|
2167 |
-
|
2168 |
-
|
2169 |
-
|
2170 |
-
|
2171 |
-
|
2172 |
-
|
2173 |
-
|
2174 |
-
|
2175 |
-
|
2176 |
-
|
2177 |
-
|
2178 |
-
|
2179 |
-
|
2180 |
-
|
2181 |
-
|
2182 |
-
|
2183 |
-
|
2184 |
-
|
2185 |
-
|
2186 |
-
|
2187 |
-
|
2188 |
-
|
2189 |
-
|
2190 |
-
|
2191 |
-
|
2192 |
-
|
2193 |
-
|
2194 |
-
|
2195 |
-
|
2196 |
-
|
2197 |
-
|
2198 |
-
|
2199 |
-
|
2200 |
-
|
2201 |
-
|
2202 |
-
|
2203 |
-
|
2204 |
-
|
2205 |
-
|
2206 |
-
|
2207 |
-
|
2208 |
-
|
2209 |
-
|
2210 |
-
|
2211 |
-
|
2212 |
-
|
2213 |
-
|
2214 |
-
|
2215 |
-
|
2216 |
-
|
2217 |
-
|
2218 |
-
|
2219 |
-
|
2220 |
-
|
2221 |
-
|
2222 |
-
|
2223 |
-
|
2224 |
-
|
2225 |
-
|
2226 |
-
|
2227 |
-
|
2228 |
-
|
2229 |
-
|
2230 |
-
|
2231 |
-
|
2232 |
-
|
2233 |
-
|
2234 |
-
|
2235 |
-
|
2236 |
-
|
2237 |
-
|
2238 |
-
|
2239 |
-
|
2240 |
-
|
2241 |
-
|
2242 |
-
|
2243 |
-
|
2244 |
-
|
2245 |
-
|
2246 |
-
|
2247 |
-
|
2248 |
-
|
2249 |
-
|
2250 |
-
|
2251 |
-
|
2252 |
-
|
2253 |
-
|
2254 |
-
|
2255 |
-
|
2256 |
-
|
2257 |
-
|
2258 |
-
|
2259 |
-
|
2260 |
-
|
2261 |
-
|
2262 |
-
|
2263 |
-
|
2264 |
-
|
2265 |
-
|
2266 |
-
|
2267 |
-
|
2268 |
-
|
2269 |
-
|
2270 |
-
|
2271 |
-
|
2272 |
-
|
2273 |
-
|
2274 |
-
|
2275 |
-
|
2276 |
-
|
2277 |
-
|
2278 |
-
|
2279 |
-
|
2280 |
-
|
2281 |
-
|
2282 |
-
|
2283 |
-
|
2284 |
-
|
2285 |
-
|
2286 |
-
|
2287 |
-
|
2288 |
-
|
2289 |
-
|
2290 |
-
|
2291 |
-
|
2292 |
-
|
2293 |
-
|
2294 |
-
|
2295 |
-
|
2296 |
-
|
2297 |
-
|
2298 |
-
|
2299 |
-
|
2300 |
-
|
2301 |
-
|
2302 |
-
|
2303 |
-
|
2304 |
-
|
2305 |
-
|
2306 |
-
|
2307 |
-
|
2308 |
-
|
2309 |
-
|
2310 |
-
|
2311 |
-
|
2312 |
-
|
2313 |
-
|
2314 |
-
|
2315 |
-
|
2316 |
-
|
2317 |
-
|
2318 |
-
|
2319 |
-
|
2320 |
-
|
2321 |
-
|
2322 |
-
|
2323 |
-
|
2324 |
-
|
2325 |
-
|
2326 |
-
|
2327 |
-
|
2328 |
-
|
2329 |
-
|
2330 |
-
|
2331 |
-
|
2332 |
-
|
2333 |
-
|
2334 |
-
|
2335 |
-
|
2336 |
-
|
2337 |
-
|
2338 |
-
|
2339 |
-
|
2340 |
-
|
2341 |
-
|
2342 |
-
|
2343 |
-
|
2344 |
-
|
2345 |
-
|
2346 |
-
|
2347 |
-
|
2348 |
-
|
2349 |
-
|
2350 |
-
|
2351 |
-
|
2352 |
-
|
2353 |
-
|
2354 |
-
|
2355 |
-
|
2356 |
-
|
2357 |
-
$pager_size
|
2358 |
-
);
|
2359 |
-
?>
|
2360 |
-
|
2361 |
-
<div class="wrap SimpleHistoryWrap">
|
2362 |
-
|
2363 |
-
<h1 class="SimpleHistoryPageHeadline">
|
2364 |
-
<div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
|
2365 |
-
<?php echo _x('Simple History', 'history page headline', 'simple-history'); ?>
|
2366 |
-
</h1>
|
2367 |
-
|
2368 |
-
<?php /**
|
2369 |
-
* Fires before the gui div
|
2370 |
-
*
|
2371 |
-
* @since 2.0
|
2372 |
-
*
|
2373 |
-
* @param SimpleHistory $SimpleHistory This class.
|
2374 |
-
*/
|
2375 |
-
do_action('simple_history/history_page/before_gui', $this); ?>
|
2376 |
-
|
2377 |
-
<div class="SimpleHistoryGuiWrap">
|
2378 |
-
|
2379 |
-
<div class="SimpleHistoryGui"
|
2380 |
-
data-pager-size='<?php echo $pager_size; ?>'
|
2381 |
-
></div>
|
2382 |
-
|
2383 |
-
<?php /**
|
2384 |
-
* Fires after the gui div
|
2385 |
*
|
2386 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2387 |
*
|
2388 |
-
* @
|
2389 |
*/
|
2390 |
-
|
2391 |
-
|
2392 |
-
|
2393 |
-
|
2394 |
-
</div>
|
2395 |
-
|
2396 |
-
<?php
|
2397 |
-
}
|
2398 |
-
|
2399 |
-
/**
|
2400 |
-
* Get setting if plugin should be visible on dasboard.
|
2401 |
-
* Defaults to true
|
2402 |
-
*
|
2403 |
-
* @return bool
|
2404 |
-
*/
|
2405 |
-
function setting_show_on_dashboard()
|
2406 |
-
{
|
2407 |
-
$show_on_dashboard = get_option('simple_history_show_on_dashboard', 1);
|
2408 |
-
$show_on_dashboard = apply_filters(
|
2409 |
-
'simple_history_show_on_dashboard',
|
2410 |
-
$show_on_dashboard
|
2411 |
-
);
|
2412 |
-
return (bool) $show_on_dashboard;
|
2413 |
-
}
|
2414 |
-
|
2415 |
-
/**
|
2416 |
-
* Should simple history be shown as a page
|
2417 |
-
* Defaults to true
|
2418 |
-
*
|
2419 |
-
* @return bool
|
2420 |
-
*/
|
2421 |
-
function setting_show_as_page()
|
2422 |
-
{
|
2423 |
-
$setting = get_option('simple_history_show_as_page', 1);
|
2424 |
-
$setting = apply_filters('simple_history_show_as_page', $setting);
|
2425 |
-
|
2426 |
-
return (bool) $setting;
|
2427 |
-
}
|
2428 |
-
|
2429 |
-
/**
|
2430 |
-
* Settings field for how many rows/items to show in log on the log page
|
2431 |
-
*/
|
2432 |
-
function settings_field_number_of_items()
|
2433 |
-
{
|
2434 |
-
$current_pager_size = $this->get_pager_size(); ?>
|
2435 |
-
<select name="simple_history_pager_size">
|
2436 |
-
<option <?php echo $current_pager_size == 5
|
2437 |
-
? 'selected'
|
2438 |
-
: ''; ?> value="5">5</option>
|
2439 |
-
<option <?php echo $current_pager_size == 10
|
2440 |
-
? 'selected'
|
2441 |
-
: ''; ?> value="10">10</option>
|
2442 |
-
<option <?php echo $current_pager_size == 15
|
2443 |
-
? 'selected'
|
2444 |
-
: ''; ?> value="15">15</option>
|
2445 |
-
<option <?php echo $current_pager_size == 20
|
2446 |
-
? 'selected'
|
2447 |
-
: ''; ?> value="20">20</option>
|
2448 |
-
<option <?php echo $current_pager_size == 25
|
2449 |
-
? 'selected'
|
2450 |
-
: ''; ?> value="25">25</option>
|
2451 |
-
<option <?php echo $current_pager_size == 30
|
2452 |
-
? 'selected'
|
2453 |
-
: ''; ?> value="30">30</option>
|
2454 |
-
<option <?php echo $current_pager_size == 40
|
2455 |
-
? 'selected'
|
2456 |
-
: ''; ?> value="40">40</option>
|
2457 |
-
<option <?php echo $current_pager_size == 50
|
2458 |
-
? 'selected'
|
2459 |
-
: ''; ?> value="50">50</option>
|
2460 |
-
<option <?php echo $current_pager_size == 75
|
2461 |
-
? 'selected'
|
2462 |
-
: ''; ?> value="75">75</option>
|
2463 |
-
<option <?php echo $current_pager_size == 100
|
2464 |
-
? 'selected'
|
2465 |
-
: ''; ?> value="100">100</option>
|
2466 |
-
</select>
|
2467 |
-
<?php
|
2468 |
-
}
|
2469 |
-
|
2470 |
-
/**
|
2471 |
-
* Settings field for how many rows/items to show in log on the dashboard
|
2472 |
-
*/
|
2473 |
-
function settings_field_number_of_items_dashboard()
|
2474 |
-
{
|
2475 |
-
$current_pager_size = $this->get_pager_size_dashboard(); ?>
|
2476 |
-
<select name="simple_history_pager_size_dashboard">
|
2477 |
-
<option <?php echo $current_pager_size == 5
|
2478 |
-
? 'selected'
|
2479 |
-
: ''; ?> value="5">5</option>
|
2480 |
-
<option <?php echo $current_pager_size == 10
|
2481 |
-
? 'selected'
|
2482 |
-
: ''; ?> value="10">10</option>
|
2483 |
-
<option <?php echo $current_pager_size == 15
|
2484 |
-
? 'selected'
|
2485 |
-
: ''; ?> value="15">15</option>
|
2486 |
-
<option <?php echo $current_pager_size == 20
|
2487 |
-
? 'selected'
|
2488 |
-
: ''; ?> value="20">20</option>
|
2489 |
-
<option <?php echo $current_pager_size == 25
|
2490 |
-
? 'selected'
|
2491 |
-
: ''; ?> value="25">25</option>
|
2492 |
-
<option <?php echo $current_pager_size == 30
|
2493 |
-
? 'selected'
|
2494 |
-
: ''; ?> value="30">30</option>
|
2495 |
-
<option <?php echo $current_pager_size == 40
|
2496 |
-
? 'selected'
|
2497 |
-
: ''; ?> value="40">40</option>
|
2498 |
-
<option <?php echo $current_pager_size == 50
|
2499 |
-
? 'selected'
|
2500 |
-
: ''; ?> value="50">50</option>
|
2501 |
-
<option <?php echo $current_pager_size == 75
|
2502 |
-
? 'selected'
|
2503 |
-
: ''; ?> value="75">75</option>
|
2504 |
-
<option <?php echo $current_pager_size == 100
|
2505 |
-
? 'selected'
|
2506 |
-
: ''; ?> value="100">100</option>
|
2507 |
-
</select>
|
2508 |
-
<?php
|
2509 |
-
}
|
2510 |
-
|
2511 |
-
/**
|
2512 |
-
* Settings field for where to show the log, page or dashboard
|
2513 |
-
*/
|
2514 |
-
function settings_field_where_to_show()
|
2515 |
-
{
|
2516 |
-
$show_on_dashboard = $this->setting_show_on_dashboard();
|
2517 |
-
$show_as_page = $this->setting_show_as_page();
|
2518 |
-
?>
|
2519 |
-
|
2520 |
-
<input <?php echo $show_on_dashboard
|
2521 |
-
? "checked='checked'"
|
2522 |
-
: ''; ?> type="checkbox" value="1" name="simple_history_show_on_dashboard" id="simple_history_show_on_dashboard" class="simple_history_show_on_dashboard" />
|
2523 |
-
<label for="simple_history_show_on_dashboard"><?php _e(
|
2524 |
-
'on the dashboard',
|
2525 |
-
'simple-history'
|
2526 |
-
); ?></label>
|
2527 |
-
|
2528 |
-
<br />
|
2529 |
-
|
2530 |
-
<input <?php echo $show_as_page
|
2531 |
-
? "checked='checked'"
|
2532 |
-
: ''; ?> type="checkbox" value="1" name="simple_history_show_as_page" id="simple_history_show_as_page" class="simple_history_show_as_page" />
|
2533 |
-
<label for="simple_history_show_as_page"><?php _e(
|
2534 |
-
'as a page under the dashboard menu',
|
2535 |
-
'simple-history'
|
2536 |
-
); ?></label>
|
2537 |
-
|
2538 |
-
<?php
|
2539 |
-
}
|
2540 |
-
|
2541 |
-
/**
|
2542 |
-
* Settings section to clear database
|
2543 |
-
*/
|
2544 |
-
function settings_field_clear_log()
|
2545 |
-
{
|
2546 |
-
$clear_link = esc_url(add_query_arg('', ''));
|
2547 |
-
$clear_link = wp_nonce_url(
|
2548 |
-
$clear_link,
|
2549 |
-
'simple_history_clear_log',
|
2550 |
-
'simple_history_clear_log_nonce'
|
2551 |
-
);
|
2552 |
-
$clear_days = $this->get_clear_history_interval();
|
2553 |
-
|
2554 |
-
echo '<p>';
|
2555 |
-
|
2556 |
-
if ($clear_days > 0) {
|
2557 |
-
echo sprintf(
|
2558 |
-
__(
|
2559 |
-
'Items in the database are automatically removed after %1$s days.',
|
2560 |
-
'simple-history'
|
2561 |
-
),
|
2562 |
-
$clear_days
|
2563 |
-
);
|
2564 |
-
} else {
|
2565 |
-
_e('Items in the database are kept forever.', 'simple-history');
|
2566 |
-
}
|
2567 |
-
|
2568 |
-
echo '</p>';
|
2569 |
-
|
2570 |
-
printf(
|
2571 |
-
'<p><a class="button js-SimpleHistory-Settings-ClearLog" href="%2$s">%1$s</a></p>',
|
2572 |
-
__('Clear log now', 'simple-history'),
|
2573 |
-
$clear_link
|
2574 |
-
);
|
2575 |
-
}
|
2576 |
-
|
2577 |
-
/**
|
2578 |
-
* How old log entried are allowed to be.
|
2579 |
-
* 0 = don't delete old entries.
|
2580 |
-
*
|
2581 |
-
* @return int Number of days.
|
2582 |
-
*/
|
2583 |
-
function get_clear_history_interval()
|
2584 |
-
{
|
2585 |
-
$days = 60;
|
2586 |
-
|
2587 |
-
/**
|
2588 |
-
* Filter to modify number of days of history to keep.
|
2589 |
-
* Default is 60 days.
|
2590 |
-
*
|
2591 |
-
* @param $days Number of days of history to keep
|
2592 |
-
*/
|
2593 |
-
$days = (int) apply_filters(
|
2594 |
-
'simple_history_db_purge_days_interval',
|
2595 |
-
$days
|
2596 |
-
);
|
2597 |
-
$days = (int) apply_filters(
|
2598 |
-
'simple_history/db_purge_days_interval',
|
2599 |
-
$days
|
2600 |
-
);
|
2601 |
-
|
2602 |
-
return $days;
|
2603 |
-
}
|
2604 |
-
|
2605 |
-
/**
|
2606 |
-
* Removes all items from the log
|
2607 |
-
*/
|
2608 |
-
function clear_log()
|
2609 |
-
{
|
2610 |
-
global $wpdb;
|
2611 |
-
|
2612 |
-
$tableprefix = $wpdb->prefix;
|
2613 |
-
|
2614 |
-
$simple_history_table = SimpleHistory::DBTABLE;
|
2615 |
-
$simple_history_context_table = SimpleHistory::DBTABLE_CONTEXTS;
|
2616 |
-
|
2617 |
-
// Get number of rows before delete.
|
2618 |
-
$sql_num_rows = "SELECT count(id) AS num_rows FROM {$tableprefix}{$simple_history_table}";
|
2619 |
-
$num_rows = $wpdb->get_var($sql_num_rows, 0);
|
2620 |
-
|
2621 |
-
// Use truncate instead of delete because it's much faster (I think, writing this much later).
|
2622 |
-
$sql = "TRUNCATE {$tableprefix}{$simple_history_table}";
|
2623 |
-
$wpdb->query($sql);
|
2624 |
-
|
2625 |
-
$sql = "TRUNCATE {$tableprefix}{$simple_history_context_table}";
|
2626 |
-
$wpdb->query($sql);
|
2627 |
-
|
2628 |
-
// Zero state sucks
|
2629 |
-
SimpleLogger()->info(
|
2630 |
-
__(
|
2631 |
-
'The log for Simple History was cleared ({num_rows} rows were removed).',
|
2632 |
-
'simple-history'
|
2633 |
-
),
|
2634 |
-
array(
|
2635 |
-
'num_rows' => $num_rows
|
2636 |
-
)
|
2637 |
-
);
|
2638 |
-
|
2639 |
-
$this->get_cache_incrementor(true);
|
2640 |
-
}
|
2641 |
-
|
2642 |
-
/**
|
2643 |
-
* Runs the purge_db() method sometimes
|
2644 |
-
* We don't want to call it each time because it performs SQL queries
|
2645 |
-
*
|
2646 |
-
* @since 2.0.17
|
2647 |
-
*/
|
2648 |
-
function maybe_purge_db()
|
2649 |
-
{
|
2650 |
-
// How often should we try to do this?
|
2651 |
-
// Once a day = a bit tiresome.
|
2652 |
-
// Let's go with sundays; purge the log on sundays.
|
2653 |
-
// Day of week, 1 = mon, 7 = sun.
|
2654 |
-
$day_of_week = date('N');
|
2655 |
-
if (7 === (int) $day_of_week) {
|
2656 |
-
$this->purge_db();
|
2657 |
-
}
|
2658 |
-
}
|
2659 |
-
|
2660 |
-
/**
|
2661 |
-
* Removes old entries from the db
|
2662 |
-
*/
|
2663 |
-
function purge_db()
|
2664 |
-
{
|
2665 |
-
$do_purge_history = true;
|
2666 |
-
|
2667 |
-
$do_purge_history = apply_filters(
|
2668 |
-
'simple_history_allow_db_purge',
|
2669 |
-
$do_purge_history
|
2670 |
-
);
|
2671 |
-
$do_purge_history = apply_filters(
|
2672 |
-
'simple_history/allow_db_purge',
|
2673 |
-
$do_purge_history
|
2674 |
-
);
|
2675 |
-
|
2676 |
-
if (!$do_purge_history) {
|
2677 |
-
return;
|
2678 |
-
}
|
2679 |
-
|
2680 |
-
$days = $this->get_clear_history_interval();
|
2681 |
-
|
2682 |
-
// Never clear log if days = 0.
|
2683 |
-
if (0 == $days) {
|
2684 |
-
return;
|
2685 |
-
}
|
2686 |
-
|
2687 |
-
global $wpdb;
|
2688 |
-
|
2689 |
-
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
2690 |
-
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
2691 |
-
|
2692 |
-
while (1 > 0) {
|
2693 |
-
// Get id of rows to delete.
|
2694 |
-
$sql = $wpdb->prepare(
|
2695 |
-
"SELECT id FROM $table_name WHERE DATE_ADD(date, INTERVAL %d DAY) < now() LIMIT 100000",
|
2696 |
-
$days
|
2697 |
-
);
|
2698 |
-
|
2699 |
-
$ids_to_delete = $wpdb->get_col($sql);
|
2700 |
-
|
2701 |
-
if (empty($ids_to_delete)) {
|
2702 |
-
// Nothing to delete.
|
2703 |
-
return;
|
2704 |
-
}
|
2705 |
-
|
2706 |
-
$sql_ids_in = implode(',', $ids_to_delete);
|
2707 |
-
|
2708 |
-
// Add number of deleted rows to total_rows option.
|
2709 |
-
$prev_total_rows = (int) get_option('simple_history_total_rows', 0);
|
2710 |
-
$total_rows = $prev_total_rows + sizeof($ids_to_delete);
|
2711 |
-
update_option('simple_history_total_rows', $total_rows);
|
2712 |
-
|
2713 |
-
// Remove rows + contexts.
|
2714 |
-
$sql_delete_history = "DELETE FROM {$table_name} WHERE id IN ($sql_ids_in)";
|
2715 |
-
$sql_delete_history_context = "DELETE FROM {$table_name_contexts} WHERE history_id IN ($sql_ids_in)";
|
2716 |
-
|
2717 |
-
$wpdb->query($sql_delete_history);
|
2718 |
-
$wpdb->query($sql_delete_history_context);
|
2719 |
-
|
2720 |
-
$message = _nx(
|
2721 |
-
'Simple History removed one event that were older than {days} days',
|
2722 |
-
'Simple History removed {num_rows} events that were older than {days} days',
|
2723 |
-
count($ids_to_delete),
|
2724 |
-
'Database is being cleared automagically',
|
2725 |
-
'simple-history'
|
2726 |
-
);
|
2727 |
-
|
2728 |
-
SimpleLogger()->info($message, array(
|
2729 |
-
'days' => $days,
|
2730 |
-
'num_rows' => count($ids_to_delete)
|
2731 |
-
));
|
2732 |
-
|
2733 |
-
$this->get_cache_incrementor(true);
|
2734 |
-
}
|
2735 |
-
}
|
2736 |
-
|
2737 |
-
/**
|
2738 |
-
* Return plain text output for a log row
|
2739 |
-
* Uses the getLogRowPlainTextOutput of the logger that logged the row
|
2740 |
-
* with fallback to SimpleLogger if logger is not available.
|
2741 |
-
*
|
2742 |
-
* @param array $row
|
2743 |
-
* @return string
|
2744 |
-
*/
|
2745 |
-
public function getLogRowPlainTextOutput($row)
|
2746 |
-
{
|
2747 |
-
$row_logger = $row->logger;
|
2748 |
-
$logger = null;
|
2749 |
-
$row->context =
|
2750 |
-
isset($row->context) && is_array($row->context)
|
2751 |
-
? $row->context
|
2752 |
-
: array();
|
2753 |
-
|
2754 |
-
if (!isset($row->context['_message_key'])) {
|
2755 |
-
$row->context['_message_key'] = null;
|
2756 |
-
}
|
2757 |
-
|
2758 |
-
// Fallback to SimpleLogger if no logger exists for row
|
2759 |
-
if (!isset($this->instantiatedLoggers[$row_logger])) {
|
2760 |
-
$row_logger = 'SimpleLogger';
|
2761 |
-
}
|
2762 |
-
|
2763 |
-
$logger = $this->instantiatedLoggers[$row_logger]['instance'];
|
2764 |
-
|
2765 |
-
return $logger->getLogRowPlainTextOutput($row);
|
2766 |
-
}
|
2767 |
-
|
2768 |
-
/**
|
2769 |
-
* Return header output for a log row
|
2770 |
-
* Uses the getLogRowHeaderOutput of the logger that logged the row
|
2771 |
-
* with fallback to SimpleLogger if logger is not available
|
2772 |
-
*
|
2773 |
-
* Loggers are discouraged to override this in the loggers,
|
2774 |
-
* because the output should be the same for all items in the gui
|
2775 |
-
*
|
2776 |
-
* @param array $row
|
2777 |
-
* @return string
|
2778 |
-
*/
|
2779 |
-
public function getLogRowHeaderOutput($row)
|
2780 |
-
{
|
2781 |
-
$row_logger = $row->logger;
|
2782 |
-
$logger = null;
|
2783 |
-
$row->context =
|
2784 |
-
isset($row->context) && is_array($row->context)
|
2785 |
-
? $row->context
|
2786 |
-
: array();
|
2787 |
-
|
2788 |
-
// Fallback to SimpleLogger if no logger exists for row
|
2789 |
-
if (!isset($this->instantiatedLoggers[$row_logger])) {
|
2790 |
-
$row_logger = 'SimpleLogger';
|
2791 |
-
}
|
2792 |
-
|
2793 |
-
$logger = $this->instantiatedLoggers[$row_logger]['instance'];
|
2794 |
-
|
2795 |
-
return $logger->getLogRowHeaderOutput($row);
|
2796 |
-
}
|
2797 |
-
|
2798 |
-
/**
|
2799 |
-
*
|
2800 |
-
*
|
2801 |
-
* @param array $row
|
2802 |
-
* @return string
|
2803 |
-
*/
|
2804 |
-
private function getLogRowSenderImageOutput($row)
|
2805 |
-
{
|
2806 |
-
$row_logger = $row->logger;
|
2807 |
-
$logger = null;
|
2808 |
-
$row->context =
|
2809 |
-
isset($row->context) && is_array($row->context)
|
2810 |
-
? $row->context
|
2811 |
-
: array();
|
2812 |
-
|
2813 |
-
// Fallback to SimpleLogger if no logger exists for row
|
2814 |
-
if (!isset($this->instantiatedLoggers[$row_logger])) {
|
2815 |
-
$row_logger = 'SimpleLogger';
|
2816 |
-
}
|
2817 |
-
|
2818 |
-
$logger = $this->instantiatedLoggers[$row_logger]['instance'];
|
2819 |
-
|
2820 |
-
return $logger->getLogRowSenderImageOutput($row);
|
2821 |
-
}
|
2822 |
-
|
2823 |
-
public function getLogRowDetailsOutput($row)
|
2824 |
-
{
|
2825 |
-
$row_logger = $row->logger;
|
2826 |
-
$logger = null;
|
2827 |
-
$row->context =
|
2828 |
-
isset($row->context) && is_array($row->context)
|
2829 |
-
? $row->context
|
2830 |
-
: array();
|
2831 |
-
|
2832 |
-
// Fallback to SimpleLogger if no logger exists for row
|
2833 |
-
if (!isset($this->instantiatedLoggers[$row_logger])) {
|
2834 |
-
$row_logger = 'SimpleLogger';
|
2835 |
-
}
|
2836 |
-
|
2837 |
-
$logger = $this->instantiatedLoggers[$row_logger]['instance'];
|
2838 |
-
|
2839 |
-
return $logger->getLogRowDetailsOutput($row);
|
2840 |
-
}
|
2841 |
-
|
2842 |
-
/**
|
2843 |
-
* Works like json_encode, but adds JSON_PRETTY_PRINT if the current php version supports it
|
2844 |
-
* i.e. PHP is 5.4.0 or greated
|
2845 |
-
*
|
2846 |
-
* @param mixed $value array|object|string|whatever that is json_encode'able.
|
2847 |
-
*/
|
2848 |
-
public static function json_encode($value)
|
2849 |
-
{
|
2850 |
-
return version_compare(PHP_VERSION, '5.4.0') >= 0
|
2851 |
-
? json_encode($value, JSON_PRETTY_PRINT)
|
2852 |
-
: json_encode($value);
|
2853 |
-
}
|
2854 |
-
|
2855 |
-
/**
|
2856 |
-
* Returns true if $haystack ends with $needle
|
2857 |
-
*
|
2858 |
-
* @param string $haystack
|
2859 |
-
* @param string $needle
|
2860 |
-
*/
|
2861 |
-
public static function ends_with($haystack, $needle)
|
2862 |
-
{
|
2863 |
-
return $needle === substr($haystack, -strlen($needle));
|
2864 |
-
}
|
2865 |
-
|
2866 |
-
/**
|
2867 |
-
* Returns the HTML output for a log row, to be used in the GUI/Activity Feed
|
2868 |
-
*
|
2869 |
-
* @param array $oneLogRow SimpleHistoryLogQuery array with data from SimpleHistoryLogQuery
|
2870 |
-
* @return string
|
2871 |
-
*/
|
2872 |
-
public function getLogRowHTMLOutput($oneLogRow, $args)
|
2873 |
-
{
|
2874 |
-
$defaults = array(
|
2875 |
-
'type' => 'overview' // or "single" to include more stuff
|
2876 |
-
);
|
2877 |
-
|
2878 |
-
$args = wp_parse_args($args, $defaults);
|
2879 |
-
|
2880 |
-
$header_html = $this->getLogRowHeaderOutput($oneLogRow);
|
2881 |
-
$plain_text_html = $this->getLogRowPlainTextOutput($oneLogRow);
|
2882 |
-
$sender_image_html = $this->getLogRowSenderImageOutput($oneLogRow);
|
2883 |
-
|
2884 |
-
// Details = for example thumbnail of media
|
2885 |
-
$details_html = trim($this->getLogRowDetailsOutput($oneLogRow));
|
2886 |
-
if ($details_html) {
|
2887 |
-
$details_html = sprintf(
|
2888 |
-
'<div class="SimpleHistoryLogitem__details">%1$s</div>',
|
2889 |
-
$details_html
|
2890 |
-
);
|
2891 |
-
}
|
2892 |
-
|
2893 |
-
// subsequentOccasions = including the current one
|
2894 |
-
$occasions_count = $oneLogRow->subsequentOccasions - 1;
|
2895 |
-
$occasions_html = '';
|
2896 |
-
|
2897 |
-
if ($occasions_count > 0) {
|
2898 |
-
$occasions_html = '<div class="SimpleHistoryLogitem__occasions">';
|
2899 |
-
|
2900 |
-
$occasions_html .=
|
2901 |
-
'<a href="#" class="SimpleHistoryLogitem__occasionsLink">';
|
2902 |
-
$occasions_html .= sprintf(
|
2903 |
-
_n(
|
2904 |
-
'+%1$s similar event',
|
2905 |
-
'+%1$s similar events',
|
2906 |
-
$occasions_count,
|
2907 |
-
'simple-history'
|
2908 |
-
),
|
2909 |
-
$occasions_count
|
2910 |
-
);
|
2911 |
-
$occasions_html .= '</a>';
|
2912 |
-
|
2913 |
-
$occasions_html .=
|
2914 |
-
'<span class="SimpleHistoryLogitem__occasionsLoading">';
|
2915 |
-
$occasions_html .= sprintf(
|
2916 |
-
__('Loading…', 'simple-history'),
|
2917 |
-
$occasions_count
|
2918 |
-
);
|
2919 |
-
$occasions_html .= '</span>';
|
2920 |
-
|
2921 |
-
$occasions_html .=
|
2922 |
-
'<span class="SimpleHistoryLogitem__occasionsLoaded">';
|
2923 |
-
$occasions_html .= sprintf(
|
2924 |
-
__('Showing %1$s more', 'simple-history'),
|
2925 |
-
$occasions_count
|
2926 |
-
);
|
2927 |
-
$occasions_html .= '</span>';
|
2928 |
-
|
2929 |
-
$occasions_html .= '</div>';
|
2930 |
-
}
|
2931 |
-
|
2932 |
-
// Add data atributes to log row, so plugins can do stuff
|
2933 |
-
$data_attrs = '';
|
2934 |
-
$data_attrs .= sprintf(' data-row-id="%1$d" ', $oneLogRow->id);
|
2935 |
-
$data_attrs .= sprintf(
|
2936 |
-
' data-occasions-count="%1$d" ',
|
2937 |
-
$occasions_count
|
2938 |
-
);
|
2939 |
-
$data_attrs .= sprintf(
|
2940 |
-
' data-occasions-id="%1$s" ',
|
2941 |
-
esc_attr($oneLogRow->occasionsID)
|
2942 |
-
);
|
2943 |
-
|
2944 |
-
if (isset($oneLogRow->context['_server_remote_addr'])) {
|
2945 |
-
$data_attrs .= sprintf(
|
2946 |
-
' data-ip-address="%1$s" ',
|
2947 |
-
esc_attr($oneLogRow->context['_server_remote_addr'])
|
2948 |
-
);
|
2949 |
-
}
|
2950 |
-
|
2951 |
-
$arr_found_additional_ip_headers = $this->instantiatedLoggers[
|
2952 |
-
'SimpleLogger'
|
2953 |
-
]['instance']->get_event_ip_number_headers($oneLogRow);
|
2954 |
-
if ($arr_found_additional_ip_headers) {
|
2955 |
-
$data_attrs .= sprintf(' data-ip-address-multiple="1" ');
|
2956 |
-
}
|
2957 |
-
|
2958 |
-
$data_attrs .= sprintf(
|
2959 |
-
' data-logger="%1$s" ',
|
2960 |
-
esc_attr($oneLogRow->logger)
|
2961 |
-
);
|
2962 |
-
$data_attrs .= sprintf(
|
2963 |
-
' data-level="%1$s" ',
|
2964 |
-
esc_attr($oneLogRow->level)
|
2965 |
-
);
|
2966 |
-
$data_attrs .= sprintf(
|
2967 |
-
' data-date="%1$s" ',
|
2968 |
-
esc_attr($oneLogRow->date)
|
2969 |
-
);
|
2970 |
-
$data_attrs .= sprintf(
|
2971 |
-
' data-initiator="%1$s" ',
|
2972 |
-
esc_attr($oneLogRow->initiator)
|
2973 |
-
);
|
2974 |
-
|
2975 |
-
if (isset($oneLogRow->context['_user_id'])) {
|
2976 |
-
$data_attrs .= sprintf(
|
2977 |
-
' data-initiator-user-id="%1$d" ',
|
2978 |
-
$oneLogRow->context['_user_id']
|
2979 |
-
);
|
2980 |
-
}
|
2981 |
-
|
2982 |
-
// If type is single then include more details
|
2983 |
-
$more_details_html = '';
|
2984 |
-
if ($args['type'] == 'single') {
|
2985 |
-
$more_details_html = apply_filters(
|
2986 |
-
'simple_history/log_html_output_details_single/html_before_context_table',
|
2987 |
-
$more_details_html,
|
2988 |
-
$oneLogRow
|
2989 |
-
);
|
2990 |
-
|
2991 |
-
$more_details_html .= sprintf(
|
2992 |
-
'<h2 class="SimpleHistoryLogitem__moreDetailsHeadline">%1$s</h2>',
|
2993 |
-
__('Context data', 'simple-history')
|
2994 |
-
);
|
2995 |
-
$more_details_html .=
|
2996 |
-
'<p>' .
|
2997 |
-
__(
|
2998 |
-
'This is potentially useful meta data that a logger has saved.',
|
2999 |
-
'simple-history'
|
3000 |
-
) .
|
3001 |
-
'</p>';
|
3002 |
-
$more_details_html .=
|
3003 |
-
"<table class='SimpleHistoryLogitem__moreDetailsContext'>";
|
3004 |
-
$more_details_html .= sprintf(
|
3005 |
-
'<tr>
|
3006 |
-
<th>%1$s</th>
|
3007 |
-
<th>%2$s</th>
|
3008 |
-
</tr>',
|
3009 |
-
'Key',
|
3010 |
-
'Value'
|
3011 |
-
);
|
3012 |
-
|
3013 |
-
$logRowKeysToShow = array_fill_keys(
|
3014 |
-
array_keys((array) $oneLogRow),
|
3015 |
-
true
|
3016 |
-
);
|
3017 |
-
|
3018 |
-
/**
|
3019 |
-
* Filter what keys to show from oneLogRow
|
3020 |
-
*
|
3021 |
-
* Array is in format
|
3022 |
-
*
|
3023 |
-
* Array
|
3024 |
-
* (
|
3025 |
-
* [id] => 1
|
3026 |
-
* [logger] => 1
|
3027 |
-
* [level] => 1
|
3028 |
-
* ...
|
3029 |
-
* )
|
3030 |
-
*
|
3031 |
-
* @since 2.0.29
|
3032 |
-
*
|
3033 |
-
* @param array with keys to show. key to show = key. value = boolean to show or not.
|
3034 |
-
* @param object log row to show details from
|
3035 |
-
*/
|
3036 |
-
$logRowKeysToShow = apply_filters(
|
3037 |
-
'simple_history/log_html_output_details_table/row_keys_to_show',
|
3038 |
-
$logRowKeysToShow,
|
3039 |
-
$oneLogRow
|
3040 |
-
);
|
3041 |
-
|
3042 |
-
// Hide some keys by default
|
3043 |
-
unset(
|
3044 |
-
$logRowKeysToShow['occasionsID'],
|
3045 |
-
$logRowKeysToShow['subsequentOccasions'],
|
3046 |
-
$logRowKeysToShow['rep'],
|
3047 |
-
$logRowKeysToShow['repeated'],
|
3048 |
-
$logRowKeysToShow['occasionsIDType'],
|
3049 |
-
$logRowKeysToShow['context'],
|
3050 |
-
$logRowKeysToShow['type']
|
3051 |
-
);
|
3052 |
-
|
3053 |
-
foreach ($oneLogRow as $rowKey => $rowVal) {
|
3054 |
-
// Only columns from oneLogRow that exist in logRowKeysToShow will be outputed
|
3055 |
-
if (
|
3056 |
-
!array_key_exists($rowKey, $logRowKeysToShow) ||
|
3057 |
-
!$logRowKeysToShow[$rowKey]
|
3058 |
-
) {
|
3059 |
-
continue;
|
3060 |
-
}
|
3061 |
-
|
3062 |
-
// skip arrays and objects and such
|
3063 |
-
if (is_array($rowVal) || is_object($rowVal)) {
|
3064 |
-
continue;
|
3065 |
-
}
|
3066 |
-
|
3067 |
-
$more_details_html .= sprintf(
|
3068 |
-
'<tr>
|
3069 |
-
<td>%1$s</td>
|
3070 |
-
<td>%2$s</td>
|
3071 |
-
</tr>',
|
3072 |
-
esc_html($rowKey),
|
3073 |
-
esc_html($rowVal)
|
3074 |
-
);
|
3075 |
-
}
|
3076 |
-
|
3077 |
-
$logRowContextKeysToShow = array_fill_keys(
|
3078 |
-
array_keys((array) $oneLogRow->context),
|
3079 |
-
true
|
3080 |
-
);
|
3081 |
-
|
3082 |
-
/**
|
3083 |
-
* Filter what keys to show from the row context
|
3084 |
-
*
|
3085 |
-
* Array is in format
|
3086 |
-
*
|
3087 |
-
* Array
|
3088 |
-
* (
|
3089 |
-
* [plugin_slug] => 1
|
3090 |
-
* [plugin_name] => 1
|
3091 |
-
* [plugin_title] => 1
|
3092 |
-
* [plugin_description] => 1
|
3093 |
-
* [plugin_author] => 1
|
3094 |
-
* [plugin_version] => 1
|
3095 |
-
* ...
|
3096 |
-
* )
|
3097 |
-
*
|
3098 |
-
* @since 2.0.29
|
3099 |
-
*
|
3100 |
-
* @param array with keys to show. key to show = key. value = boolean to show or not.
|
3101 |
-
* @param object log row to show details from
|
3102 |
-
*/
|
3103 |
-
$logRowContextKeysToShow = apply_filters(
|
3104 |
-
'simple_history/log_html_output_details_table/context_keys_to_show',
|
3105 |
-
$logRowContextKeysToShow,
|
3106 |
-
$oneLogRow
|
3107 |
-
);
|
3108 |
-
|
3109 |
-
foreach ($oneLogRow->context as $contextKey => $contextVal) {
|
3110 |
-
// Only columns from context that exist in logRowContextKeysToShow will be outputed
|
3111 |
-
if (
|
3112 |
-
!array_key_exists($contextKey, $logRowContextKeysToShow) ||
|
3113 |
-
!$logRowContextKeysToShow[$contextKey]
|
3114 |
-
) {
|
3115 |
-
continue;
|
3116 |
-
}
|
3117 |
-
|
3118 |
-
$more_details_html .= sprintf(
|
3119 |
-
'<tr>
|
3120 |
-
<td>%1$s</td>
|
3121 |
-
<td>%2$s</td>
|
3122 |
-
</tr>',
|
3123 |
-
esc_html($contextKey),
|
3124 |
-
esc_html($contextVal)
|
3125 |
-
);
|
3126 |
-
}
|
3127 |
-
|
3128 |
-
$more_details_html .= '</table>';
|
3129 |
-
|
3130 |
-
$more_details_html = apply_filters(
|
3131 |
-
'simple_history/log_html_output_details_single/html_after_context_table',
|
3132 |
-
$more_details_html,
|
3133 |
-
$oneLogRow
|
3134 |
-
);
|
3135 |
-
|
3136 |
-
$more_details_html = sprintf(
|
3137 |
-
'<div class="SimpleHistoryLogitem__moreDetails">%1$s</div>',
|
3138 |
-
$more_details_html
|
3139 |
-
);
|
3140 |
-
} // End if().
|
3141 |
-
|
3142 |
-
// Classes to add to log item li element
|
3143 |
-
$classes = array(
|
3144 |
-
'SimpleHistoryLogitem',
|
3145 |
-
"SimpleHistoryLogitem--loglevel-{$oneLogRow->level}",
|
3146 |
-
"SimpleHistoryLogitem--logger-{$oneLogRow->logger}"
|
3147 |
-
);
|
3148 |
-
|
3149 |
-
if (isset($oneLogRow->initiator) && !empty($oneLogRow->initiator)) {
|
3150 |
-
$classes[] =
|
3151 |
-
'SimpleHistoryLogitem--initiator-' . $oneLogRow->initiator;
|
3152 |
-
}
|
3153 |
-
|
3154 |
-
if ($arr_found_additional_ip_headers) {
|
3155 |
-
$classes[] = 'SimpleHistoryLogitem--IPAddress-multiple';
|
3156 |
-
}
|
3157 |
-
|
3158 |
-
// Always append the log level tag
|
3159 |
-
$log_level_tag_html = sprintf(
|
3160 |
-
' <span class="SimpleHistoryLogitem--logleveltag SimpleHistoryLogitem--logleveltag-%1$s">%2$s</span>',
|
3161 |
-
$oneLogRow->level,
|
3162 |
-
$this->getLogLevelTranslated($oneLogRow->level)
|
3163 |
-
);
|
3164 |
-
|
3165 |
-
$plain_text_html .= $log_level_tag_html;
|
3166 |
-
|
3167 |
-
/**
|
3168 |
-
* Filter to modify classes added to item li element
|
3169 |
-
*
|
3170 |
-
* @since 2.0.7
|
3171 |
-
*
|
3172 |
-
* @param $classes Array with classes
|
3173 |
-
*/
|
3174 |
-
$classes = apply_filters(
|
3175 |
-
'simple_history/logrowhtmloutput/classes',
|
3176 |
-
$classes
|
3177 |
-
);
|
3178 |
-
|
3179 |
-
// Generate the HTML output for a row
|
3180 |
-
$output = sprintf(
|
3181 |
-
'
|
3182 |
-
<li %8$s class="%10$s">
|
3183 |
-
<div class="SimpleHistoryLogitem__firstcol">
|
3184 |
-
<div class="SimpleHistoryLogitem__senderImage">%3$s</div>
|
3185 |
-
</div>
|
3186 |
-
<div class="SimpleHistoryLogitem__secondcol">
|
3187 |
-
<div class="SimpleHistoryLogitem__header">%1$s</div>
|
3188 |
-
<div class="SimpleHistoryLogitem__text">%2$s</div>
|
3189 |
-
%6$s <!-- details_html -->
|
3190 |
-
%9$s <!-- more details html -->
|
3191 |
-
%4$s <!-- occasions -->
|
3192 |
-
</div>
|
3193 |
-
</li>
|
3194 |
-
',
|
3195 |
-
$header_html, // 1
|
3196 |
-
$plain_text_html, // 2
|
3197 |
-
$sender_image_html, // 3
|
3198 |
-
$occasions_html, // 4
|
3199 |
-
$oneLogRow->level, // 5
|
3200 |
-
$details_html, // 6
|
3201 |
-
$oneLogRow->logger, // 7
|
3202 |
-
$data_attrs, // 8 data attributes
|
3203 |
-
$more_details_html, // 9
|
3204 |
-
esc_attr(join(' ', $classes)) // 10
|
3205 |
-
);
|
3206 |
-
|
3207 |
-
// Get the main message row.
|
3208 |
-
// Should be as plain as possible, like plain text
|
3209 |
-
// but with links to for example users and posts
|
3210 |
-
// SimpleLoggerFormatter::getRowTextOutput($oneLogRow);
|
3211 |
-
// Get detailed HTML-based output
|
3212 |
-
// May include images, lists, any cool stuff needed to view
|
3213 |
-
// SimpleLoggerFormatter::getRowHTMLOutput($oneLogRow);
|
3214 |
-
return trim($output);
|
3215 |
-
}
|
3216 |
-
|
3217 |
-
/**
|
3218 |
-
* Return translated loglevel
|
3219 |
-
*
|
3220 |
-
* @since 2.0.14
|
3221 |
-
* @param string $loglevel
|
3222 |
-
* @return string translated loglevel
|
3223 |
-
*/
|
3224 |
-
function getLogLevelTranslated($loglevel)
|
3225 |
-
{
|
3226 |
-
$str_translated = '';
|
3227 |
-
|
3228 |
-
switch ($loglevel) {
|
3229 |
-
// Lowercase
|
3230 |
-
case 'emergency':
|
3231 |
-
$str_translated = _x(
|
3232 |
-
'emergency',
|
3233 |
-
'Log level in gui',
|
3234 |
-
'simple-history'
|
3235 |
-
);
|
3236 |
-
break;
|
3237 |
-
|
3238 |
-
case 'alert':
|
3239 |
-
$str_translated = _x(
|
3240 |
-
'alert',
|
3241 |
-
'Log level in gui',
|
3242 |
-
'simple-history'
|
3243 |
-
);
|
3244 |
-
break;
|
3245 |
-
|
3246 |
-
case 'critical':
|
3247 |
-
$str_translated = _x(
|
3248 |
-
'critical',
|
3249 |
-
'Log level in gui',
|
3250 |
-
'simple-history'
|
3251 |
-
);
|
3252 |
-
break;
|
3253 |
-
|
3254 |
-
case 'error':
|
3255 |
-
$str_translated = _x(
|
3256 |
-
'error',
|
3257 |
-
'Log level in gui',
|
3258 |
-
'simple-history'
|
3259 |
-
);
|
3260 |
-
break;
|
3261 |
-
|
3262 |
-
case 'warning':
|
3263 |
-
$str_translated = _x(
|
3264 |
-
'warning',
|
3265 |
-
'Log level in gui',
|
3266 |
-
'simple-history'
|
3267 |
-
);
|
3268 |
-
break;
|
3269 |
-
|
3270 |
-
case 'notice':
|
3271 |
-
$str_translated = _x(
|
3272 |
-
'notice',
|
3273 |
-
'Log level in gui',
|
3274 |
-
'simple-history'
|
3275 |
-
);
|
3276 |
-
break;
|
3277 |
-
|
3278 |
-
case 'info':
|
3279 |
-
$str_translated = _x(
|
3280 |
-
'info',
|
3281 |
-
'Log level in gui',
|
3282 |
-
'simple-history'
|
3283 |
-
);
|
3284 |
-
break;
|
3285 |
-
|
3286 |
-
case 'debug':
|
3287 |
-
$str_translated = _x(
|
3288 |
-
'debug',
|
3289 |
-
'Log level in gui',
|
3290 |
-
'simple-history'
|
3291 |
-
);
|
3292 |
-
break;
|
3293 |
-
|
3294 |
-
// Uppercase
|
3295 |
-
case 'Emergency':
|
3296 |
-
$str_translated = _x(
|
3297 |
-
'Emergency',
|
3298 |
-
'Log level in gui',
|
3299 |
-
'simple-history'
|
3300 |
-
);
|
3301 |
-
break;
|
3302 |
-
|
3303 |
-
case 'Alert':
|
3304 |
-
$str_translated = _x(
|
3305 |
-
'Alert',
|
3306 |
-
'Log level in gui',
|
3307 |
-
'simple-history'
|
3308 |
-
);
|
3309 |
-
break;
|
3310 |
-
|
3311 |
-
case 'Critical':
|
3312 |
-
$str_translated = _x(
|
3313 |
-
'Critical',
|
3314 |
-
'Log level in gui',
|
3315 |
-
'simple-history'
|
3316 |
-
);
|
3317 |
-
break;
|
3318 |
-
|
3319 |
-
case 'Error':
|
3320 |
-
$str_translated = _x(
|
3321 |
-
'Error',
|
3322 |
-
'Log level in gui',
|
3323 |
-
'simple-history'
|
3324 |
-
);
|
3325 |
-
break;
|
3326 |
-
|
3327 |
-
case 'Warning':
|
3328 |
-
$str_translated = _x(
|
3329 |
-
'Warning',
|
3330 |
-
'Log level in gui',
|
3331 |
-
'simple-history'
|
3332 |
-
);
|
3333 |
-
break;
|
3334 |
-
|
3335 |
-
case 'Notice':
|
3336 |
-
$str_translated = _x(
|
3337 |
-
'Notice',
|
3338 |
-
'Log level in gui',
|
3339 |
-
'simple-history'
|
3340 |
-
);
|
3341 |
-
break;
|
3342 |
-
|
3343 |
-
case 'Info':
|
3344 |
-
$str_translated = _x(
|
3345 |
-
'Info',
|
3346 |
-
'Log level in gui',
|
3347 |
-
'simple-history'
|
3348 |
-
);
|
3349 |
-
break;
|
3350 |
-
|
3351 |
-
case 'Debug':
|
3352 |
-
$str_translated = _x(
|
3353 |
-
'Debug',
|
3354 |
-
'Log level in gui',
|
3355 |
-
'simple-history'
|
3356 |
-
);
|
3357 |
-
break;
|
3358 |
-
|
3359 |
-
default:
|
3360 |
-
$str_translated = $loglevel;
|
3361 |
-
} // End switch().
|
3362 |
-
|
3363 |
-
return $str_translated;
|
3364 |
-
}
|
3365 |
-
|
3366 |
-
public function getInstantiatedLoggers()
|
3367 |
-
{
|
3368 |
-
return $this->instantiatedLoggers;
|
3369 |
-
}
|
3370 |
-
|
3371 |
-
public function getInstantiatedDropins()
|
3372 |
-
{
|
3373 |
-
return $this->instantiatedDropins;
|
3374 |
-
}
|
3375 |
-
|
3376 |
-
/**
|
3377 |
-
* @param string $slug
|
3378 |
-
* @return mixed logger instance if found, bool false if logger not found
|
3379 |
-
*/
|
3380 |
-
public function getInstantiatedLoggerBySlug($slug = '')
|
3381 |
-
{
|
3382 |
-
if (empty($slug)) {
|
3383 |
-
return false;
|
3384 |
-
}
|
3385 |
-
|
3386 |
-
foreach ($this->getInstantiatedLoggers() as $one_logger) {
|
3387 |
-
if ($slug == $one_logger['instance']->slug) {
|
3388 |
-
return $one_logger['instance'];
|
3389 |
-
}
|
3390 |
-
}
|
3391 |
-
|
3392 |
-
return false;
|
3393 |
-
}
|
3394 |
-
|
3395 |
-
/**
|
3396 |
-
* Check which loggers a user has the right to read and return an array
|
3397 |
-
* with all loggers they are allowed to read
|
3398 |
-
*
|
3399 |
-
* @param int $user_id Id of user to get loggers for. Defaults to current user id.
|
3400 |
-
* @param string $format format to return loggers in. Default is array. Can also be "sql"
|
3401 |
-
* @return array
|
3402 |
-
*/
|
3403 |
-
public function getLoggersThatUserCanRead($user_id = '', $format = 'array')
|
3404 |
-
{
|
3405 |
-
$arr_loggers_user_can_view = array();
|
3406 |
-
|
3407 |
-
if (!is_numeric($user_id)) {
|
3408 |
-
$user_id = get_current_user_id();
|
3409 |
-
}
|
3410 |
-
|
3411 |
-
$loggers = $this->getInstantiatedLoggers();
|
3412 |
-
foreach ($loggers as $one_logger) {
|
3413 |
-
$logger_capability = $one_logger['instance']->getCapability();
|
3414 |
-
|
3415 |
-
// $arr_loggers_user_can_view = apply_filters("simple_history/loggers_user_can_read", $user_id, $arr_loggers_user_can_view);
|
3416 |
-
$user_can_read_logger = user_can($user_id, $logger_capability);
|
3417 |
-
$user_can_read_logger = apply_filters(
|
3418 |
-
'simple_history/loggers_user_can_read/can_read_single_logger',
|
3419 |
-
$user_can_read_logger,
|
3420 |
-
$one_logger['instance'],
|
3421 |
-
$user_id
|
3422 |
-
);
|
3423 |
-
|
3424 |
-
if ($user_can_read_logger) {
|
3425 |
-
$arr_loggers_user_can_view[] = $one_logger;
|
3426 |
-
}
|
3427 |
-
}
|
3428 |
-
|
3429 |
-
/**
|
3430 |
-
* Fires before Simple History does it's init stuff
|
3431 |
-
*
|
3432 |
-
* @since 2.0
|
3433 |
-
*
|
3434 |
-
* @param array $arr_loggers_user_can_view Array with loggers that user $user_id can read
|
3435 |
-
* @param int user_id ID of user to check read capability for
|
3436 |
-
*/
|
3437 |
-
$arr_loggers_user_can_view = apply_filters(
|
3438 |
-
'simple_history/loggers_user_can_read',
|
3439 |
-
$arr_loggers_user_can_view,
|
3440 |
-
$user_id
|
3441 |
-
);
|
3442 |
-
|
3443 |
-
// just return array with slugs in parenthesis suitable for sql-where
|
3444 |
-
if ('sql' == $format) {
|
3445 |
-
$str_return = '(';
|
3446 |
-
|
3447 |
-
if (sizeof($arr_loggers_user_can_view)) {
|
3448 |
-
foreach ($arr_loggers_user_can_view as $one_logger) {
|
3449 |
-
$str_return .= sprintf(
|
3450 |
-
'"%1$s", ',
|
3451 |
-
esc_sql($one_logger['instance']->slug)
|
3452 |
-
);
|
3453 |
-
}
|
3454 |
-
|
3455 |
-
$str_return = rtrim($str_return, ' ,');
|
3456 |
-
} else {
|
3457 |
-
// user was not allowed to read any loggers, return in (NULL) to return nothing
|
3458 |
-
$str_return .= 'NULL';
|
3459 |
-
}
|
3460 |
-
|
3461 |
-
$str_return .= ')';
|
3462 |
-
|
3463 |
-
return $str_return;
|
3464 |
-
}
|
3465 |
-
|
3466 |
-
return $arr_loggers_user_can_view;
|
3467 |
-
}
|
3468 |
-
|
3469 |
-
/**
|
3470 |
-
* Retrieve the avatar for a user who provided a user ID or email address.
|
3471 |
-
* A modified version of the function that comes with WordPress, but we
|
3472 |
-
* want to allow/show gravatars even if they are disabled in discussion settings
|
3473 |
-
*
|
3474 |
-
* @since 2.0
|
3475 |
-
*
|
3476 |
-
* @param string $email email address
|
3477 |
-
* @param int $size Size of the avatar image
|
3478 |
-
* @param string $default URL to a default image to use if no avatar is available
|
3479 |
-
* @param string $alt Alternative text to use in image tag. Defaults to blank
|
3480 |
-
* @return string <img> tag for the user's avatar
|
3481 |
-
*/
|
3482 |
-
function get_avatar($email, $size = '96', $default = '', $alt = false)
|
3483 |
-
{
|
3484 |
-
// WP setting for avatars is to show, so just use the built in function
|
3485 |
-
if (get_option('show_avatars')) {
|
3486 |
-
$avatar = get_avatar($email, $size, $default, $alt);
|
3487 |
-
|
3488 |
-
return $avatar;
|
3489 |
-
} else {
|
3490 |
-
// WP setting for avatar was to not show, but we do it anyway, using the same code as get_avatar() would have used
|
3491 |
-
if (false === $alt) {
|
3492 |
-
$safe_alt = '';
|
3493 |
-
} else {
|
3494 |
-
$safe_alt = esc_attr($alt);
|
3495 |
-
}
|
3496 |
-
|
3497 |
-
if (!is_numeric($size)) {
|
3498 |
-
$size = '96';
|
3499 |
-
}
|
3500 |
-
|
3501 |
-
if (empty($default)) {
|
3502 |
-
$avatar_default = get_option('avatar_default');
|
3503 |
-
if (empty($avatar_default)) {
|
3504 |
-
$default = 'mystery';
|
3505 |
-
} else {
|
3506 |
-
$default = $avatar_default;
|
3507 |
-
}
|
3508 |
-
}
|
3509 |
-
|
3510 |
-
if (!empty($email)) {
|
3511 |
-
$email_hash = md5(strtolower(trim($email)));
|
3512 |
-
}
|
3513 |
-
|
3514 |
-
if (is_ssl()) {
|
3515 |
-
$host = 'https://secure.gravatar.com';
|
3516 |
-
} else {
|
3517 |
-
if (!empty($email)) {
|
3518 |
-
$host = sprintf(
|
3519 |
-
'http://%d.gravatar.com',
|
3520 |
-
hexdec($email_hash[0]) % 2
|
3521 |
-
);
|
3522 |
-
} else {
|
3523 |
-
$host = 'http://0.gravatar.com';
|
3524 |
-
}
|
3525 |
-
}
|
3526 |
-
|
3527 |
-
if ('mystery' == $default) {
|
3528 |
-
$default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
|
3529 |
-
}
|
3530 |
-
// End if().
|
3531 |
-
elseif ('blank' == $default) {
|
3532 |
-
$default = $email ? 'blank' : includes_url('images/blank.gif');
|
3533 |
-
} elseif (!empty($email) && 'gravatar_default' == $default) {
|
3534 |
-
$default = '';
|
3535 |
-
} elseif ('gravatar_default' == $default) {
|
3536 |
-
$default = "$host/avatar/?s={$size}";
|
3537 |
-
} elseif (empty($email)) {
|
3538 |
-
$default = "$host/avatar/?d=$default&s={$size}";
|
3539 |
-
} elseif (strpos($default, 'http://') === 0) {
|
3540 |
-
$default = add_query_arg('s', $size, $default);
|
3541 |
-
}
|
3542 |
-
|
3543 |
-
if (!empty($email)) {
|
3544 |
-
$out = "$host/avatar/";
|
3545 |
-
$out .= $email_hash;
|
3546 |
-
$out .= '?s=' . $size;
|
3547 |
-
$out .= '&d=' . urlencode($default);
|
3548 |
-
|
3549 |
-
$rating = get_option('avatar_rating');
|
3550 |
-
if (!empty($rating)) {
|
3551 |
-
$out .= "&r={$rating}";
|
3552 |
-
}
|
3553 |
-
|
3554 |
-
$out = str_replace('&', '&', esc_url($out));
|
3555 |
-
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
|
3556 |
-
} else {
|
3557 |
-
$out = esc_url($default);
|
3558 |
-
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
|
3559 |
-
}
|
3560 |
-
|
3561 |
-
/**
|
3562 |
-
* Filter the avatar to retrieve.
|
3563 |
-
* Same filter WordPress uses
|
3564 |
-
*
|
3565 |
-
* @since 2.0.19
|
3566 |
-
*
|
3567 |
-
* @param string $avatar Image tag for the user's avatar.
|
3568 |
-
* @param int|object|string $id_or_email A user ID, email address, or comment object.
|
3569 |
-
* @param int $size Square avatar width and height in pixels to retrieve.
|
3570 |
-
* @param string $alt Alternative text to use in the avatar image tag.
|
3571 |
-
* Default empty.
|
3572 |
-
*/
|
3573 |
-
$avatar = apply_filters(
|
3574 |
-
'get_avatar',
|
3575 |
-
$avatar,
|
3576 |
-
$email,
|
3577 |
-
$size,
|
3578 |
-
$default,
|
3579 |
-
$alt
|
3580 |
-
);
|
3581 |
-
|
3582 |
-
return $avatar;
|
3583 |
-
} // End if().
|
3584 |
-
}
|
3585 |
-
|
3586 |
-
/**
|
3587 |
-
* Quick stats above the log
|
3588 |
-
* Uses filter "simple_history/history_page/before_gui" to output its contents
|
3589 |
-
*/
|
3590 |
-
public function output_quick_stats()
|
3591 |
-
{
|
3592 |
-
global $wpdb;
|
3593 |
-
|
3594 |
-
// Get number of events today
|
3595 |
-
$logQuery = new SimpleHistoryLogQuery();
|
3596 |
-
$logResults = $logQuery->query(array(
|
3597 |
-
'posts_per_page' => 1,
|
3598 |
-
'date_from' => strtotime('today')
|
3599 |
-
));
|
3600 |
-
|
3601 |
-
$total_row_count = (int) $logResults['total_row_count'];
|
3602 |
-
|
3603 |
-
// Get sql query for where to read only loggers current user is allowed to read/view
|
3604 |
-
$sql_loggers_in = $this->getLoggersThatUserCanRead(
|
3605 |
-
get_current_user_id(),
|
3606 |
-
'sql'
|
3607 |
-
);
|
3608 |
-
|
3609 |
-
// Get number of users today, i.e. events with wp_user as initiator
|
3610 |
-
$sql_users_today = sprintf(
|
3611 |
-
'
|
3612 |
-
SELECT
|
3613 |
-
DISTINCT(c.value) AS user_id
|
3614 |
-
#h.id, h.logger, h.level, h.initiator, h.date
|
3615 |
-
FROM %3$s AS h
|
3616 |
-
INNER JOIN %4$s AS c
|
3617 |
-
ON c.history_id = h.id AND c.key = "_user_id"
|
3618 |
-
WHERE
|
3619 |
-
initiator = "wp_user"
|
3620 |
-
AND logger IN %1$s
|
3621 |
-
AND date > "%2$s"
|
3622 |
-
',
|
3623 |
-
$sql_loggers_in,
|
3624 |
-
date('Y-m-d H:i', strtotime('today')),
|
3625 |
-
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3626 |
-
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS
|
3627 |
-
);
|
3628 |
-
|
3629 |
-
$cache_key =
|
3630 |
-
'quick_stats_users_today_' . md5(serialize($sql_loggers_in));
|
3631 |
-
$cache_group = 'simple-history-' . $this->get_cache_incrementor();
|
3632 |
-
$results_users_today = wp_cache_get($cache_key, $cache_group);
|
3633 |
-
|
3634 |
-
if (false === $results_users_today) {
|
3635 |
-
$results_users_today = $wpdb->get_results($sql_users_today);
|
3636 |
-
wp_cache_set($cache_key, $results_users_today, $cache_group);
|
3637 |
-
}
|
3638 |
-
|
3639 |
-
$count_users_today = sizeof($results_users_today);
|
3640 |
-
|
3641 |
-
// Get number of other sources (not wp_user)
|
3642 |
-
$sql_other_sources_where = sprintf(
|
3643 |
-
'
|
3644 |
-
initiator <> "wp_user"
|
3645 |
-
AND logger IN %1$s
|
3646 |
-
AND date > "%2$s"
|
3647 |
-
',
|
3648 |
-
$sql_loggers_in,
|
3649 |
-
date('Y-m-d H:i', strtotime('today')),
|
3650 |
-
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3651 |
-
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS
|
3652 |
-
);
|
3653 |
-
|
3654 |
-
$sql_other_sources_where = apply_filters(
|
3655 |
-
'simple_history/quick_stats_where',
|
3656 |
-
$sql_other_sources_where
|
3657 |
-
);
|
3658 |
-
|
3659 |
-
$sql_other_sources = sprintf(
|
3660 |
-
'
|
3661 |
-
SELECT
|
3662 |
-
DISTINCT(h.initiator) AS initiator
|
3663 |
-
FROM %3$s AS h
|
3664 |
-
WHERE
|
3665 |
-
%5$s
|
3666 |
-
',
|
3667 |
-
$sql_loggers_in,
|
3668 |
-
date('Y-m-d H:i', strtotime('today')),
|
3669 |
-
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3670 |
-
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS,
|
3671 |
-
$sql_other_sources_where // 5
|
3672 |
-
);
|
3673 |
-
// sf_d($sql_other_sources, '$sql_other_sources');
|
3674 |
-
$cache_key =
|
3675 |
-
'quick_stats_results_other_sources_today_' .
|
3676 |
-
md5(serialize($sql_other_sources));
|
3677 |
-
$results_other_sources_today = wp_cache_get($cache_key, $cache_group);
|
3678 |
-
|
3679 |
-
if (false === $results_other_sources_today) {
|
3680 |
-
$results_other_sources_today = $wpdb->get_results(
|
3681 |
-
$sql_other_sources
|
3682 |
-
);
|
3683 |
-
wp_cache_set(
|
3684 |
-
$cache_key,
|
3685 |
-
$results_other_sources_today,
|
3686 |
-
$cache_group
|
3687 |
-
);
|
3688 |
-
}
|
3689 |
-
|
3690 |
-
$count_other_sources = sizeof($results_other_sources_today);
|
3691 |
-
|
3692 |
-
// sf_d($logResults, '$logResults');
|
3693 |
-
// sf_d($results_users_today, '$sql_users_today');
|
3694 |
-
// sf_d($results_other_sources_today, '$results_other_sources_today');
|
3695 |
-
?>
|
3696 |
-
<div class="SimpleHistoryQuickStats">
|
3697 |
-
<p>
|
3698 |
-
<?php
|
3699 |
-
$msg_tmpl = '';
|
3700 |
-
|
3701 |
-
// No results today at all
|
3702 |
-
if ($total_row_count == 0) {
|
3703 |
-
$msg_tmpl = __('No events today so far.', 'simple-history');
|
3704 |
-
} else {
|
3705 |
-
/*
|
3706 |
-
Type of results
|
3707 |
-
x1 event today from 1 user.
|
3708 |
-
x1 event today from 1 source.
|
3709 |
-
3 events today from 1 user.
|
3710 |
-
x2 events today from 2 users.
|
3711 |
-
x2 events today from 1 user and 1 other source.
|
3712 |
-
x3 events today from 2 users and 1 other source.
|
3713 |
-
x3 events today from 1 user and 2 other sources.
|
3714 |
-
x4 events today from 2 users and 2 other sources.
|
3715 |
-
*/
|
3716 |
-
|
3717 |
-
// A single event existed and was from a user
|
3718 |
-
// 1 event today from 1 user.
|
3719 |
-
if ($total_row_count == 1 && $count_users_today == 1) {
|
3720 |
-
$msg_tmpl .= __('One event today from one user.', 'simple-history');
|
3721 |
-
}
|
3722 |
-
|
3723 |
-
// A single event existed and was from another source
|
3724 |
-
// 1 event today from 1 source.
|
3725 |
-
if ($total_row_count == 1 && !$count_users_today) {
|
3726 |
-
$msg_tmpl .= __(
|
3727 |
-
'One event today from one source.',
|
3728 |
-
'simple-history'
|
3729 |
-
);
|
3730 |
-
}
|
3731 |
-
|
3732 |
-
// Multiple events from a single user
|
3733 |
-
// 3 events today from one user.
|
3734 |
-
if (
|
3735 |
-
$total_row_count > 1 &&
|
3736 |
-
$count_users_today == 1 &&
|
3737 |
-
!$count_other_sources
|
3738 |
-
) {
|
3739 |
-
$msg_tmpl .= __(
|
3740 |
-
'%1$d events today from one user.',
|
3741 |
-
'simple-history'
|
3742 |
-
);
|
3743 |
-
}
|
3744 |
-
|
3745 |
-
// Multiple events from only users
|
3746 |
-
// 2 events today from 2 users.
|
3747 |
-
if ($total_row_count > 1 && $count_users_today == $total_row_count) {
|
3748 |
-
$msg_tmpl .= __(
|
3749 |
-
'%1$d events today from %2$d users.',
|
3750 |
-
'simple-history'
|
3751 |
-
);
|
3752 |
-
}
|
3753 |
-
|
3754 |
-
// Multiple events from 1 single user and 1 single other source
|
3755 |
-
// 2 events today from 1 user and 1 other source.
|
3756 |
-
if (
|
3757 |
-
$total_row_count &&
|
3758 |
-
1 == $count_users_today &&
|
3759 |
-
1 == $count_other_sources
|
3760 |
-
) {
|
3761 |
-
$msg_tmpl .= __(
|
3762 |
-
'%1$d events today from one user and one other source.',
|
3763 |
-
'simple-history'
|
3764 |
-
);
|
3765 |
-
}
|
3766 |
-
|
3767 |
-
// Multiple events from multple users but from only 1 single other source
|
3768 |
-
// 3 events today from 2 users and 1 other source.
|
3769 |
-
if (
|
3770 |
-
$total_row_count > 1 &&
|
3771 |
-
$count_users_today > 1 &&
|
3772 |
-
$count_other_sources == 1
|
3773 |
-
) {
|
3774 |
-
$msg_tmpl .= __(
|
3775 |
-
'%1$d events today from one user and one other source.',
|
3776 |
-
'simple-history'
|
3777 |
-
);
|
3778 |
-
}
|
3779 |
-
|
3780 |
-
// Multiple events from 1 user but from multiple other source
|
3781 |
-
// 3 events today from 1 user and 2 other sources.
|
3782 |
-
if (
|
3783 |
-
$total_row_count > 1 &&
|
3784 |
-
1 == $count_users_today &&
|
3785 |
-
$count_other_sources > 1
|
3786 |
-
) {
|
3787 |
-
$msg_tmpl .= __(
|
3788 |
-
'%1$d events today from one user and %3$d other sources.',
|
3789 |
-
'simple-history'
|
3790 |
-
);
|
3791 |
-
}
|
3792 |
-
|
3793 |
-
// Multiple events from multiple user and from multiple other sources
|
3794 |
-
// 4 events today from 2 users and 2 other sources.
|
3795 |
-
if (
|
3796 |
-
$total_row_count > 1 &&
|
3797 |
-
$count_users_today > 1 &&
|
3798 |
-
$count_other_sources > 1
|
3799 |
-
) {
|
3800 |
-
$msg_tmpl .= __(
|
3801 |
-
'%1$s events today from %2$d users and %3$d other sources.',
|
3802 |
-
'simple-history'
|
3803 |
-
);
|
3804 |
-
}
|
3805 |
-
} // End if().
|
3806 |
-
|
3807 |
-
// only show stats if we have something to output
|
3808 |
-
if ($msg_tmpl) {
|
3809 |
-
printf(
|
3810 |
-
$msg_tmpl,
|
3811 |
-
$logResults['total_row_count'], // 1
|
3812 |
-
$count_users_today, // 2
|
3813 |
-
$count_other_sources // 3
|
3814 |
-
);
|
3815 |
-
|
3816 |
-
// Space between texts
|
3817 |
-
/*
|
3818 |
-
echo " ";
|
3819 |
-
|
3820 |
-
// http://playground-root.ep/wp-admin/options-general.php?page=simple_history_settings_menu_slug&selected-tab=stats
|
3821 |
-
printf(
|
3822 |
-
'<a href="%1$s">View more stats</a>.',
|
3823 |
-
add_query_arg("selected-tab", "stats", menu_page_url(SimpleHistory::SETTINGS_MENU_SLUG, 0))
|
3824 |
-
);
|
3825 |
-
*/
|
3826 |
-
}?>
|
3827 |
-
</p>
|
3828 |
-
</div>
|
3829 |
-
<?php
|
3830 |
-
} // output_quick_stats
|
3831 |
-
|
3832 |
-
/**
|
3833 |
-
* https://www.tollmanz.com/invalidation-schemes/
|
3834 |
-
*
|
3835 |
-
* @param $refresh bool
|
3836 |
-
* @return string
|
3837 |
-
*/
|
3838 |
-
public static function get_cache_incrementor($refresh = false)
|
3839 |
-
{
|
3840 |
-
$incrementor_key = 'simple_history_incrementor';
|
3841 |
-
$incrementor_value = wp_cache_get($incrementor_key);
|
3842 |
-
|
3843 |
-
if (false === $incrementor_value || true === $refresh) {
|
3844 |
-
$incrementor_value = time();
|
3845 |
-
wp_cache_set($incrementor_key, $incrementor_value);
|
3846 |
-
}
|
3847 |
-
|
3848 |
-
// echo "<br>incrementor_value: $incrementor_value";
|
3849 |
-
return $incrementor_value;
|
3850 |
-
}
|
3851 |
-
|
3852 |
-
// Number of rows the last n days
|
3853 |
-
function get_num_events_last_n_days($period_days = 28)
|
3854 |
-
{
|
3855 |
-
$transient_key = 'sh_' . md5(__METHOD__ . $period_days . '_2');
|
3856 |
-
|
3857 |
-
$count = get_transient($transient_key);
|
3858 |
-
|
3859 |
-
if (false === $count) {
|
3860 |
-
global $wpdb;
|
3861 |
-
|
3862 |
-
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead(
|
3863 |
-
null,
|
3864 |
-
'sql'
|
3865 |
-
);
|
3866 |
-
|
3867 |
-
$sql = sprintf(
|
3868 |
-
'
|
3869 |
-
SELECT count(*)
|
3870 |
-
FROM %1$s
|
3871 |
-
WHERE UNIX_TIMESTAMP(date) >= %2$d
|
3872 |
-
AND logger IN %3$s
|
3873 |
-
',
|
3874 |
-
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3875 |
-
strtotime("-$period_days days"),
|
3876 |
-
$sqlStringLoggersUserCanRead
|
3877 |
-
);
|
3878 |
-
|
3879 |
-
$count = $wpdb->get_var($sql);
|
3880 |
-
|
3881 |
-
set_transient($transient_key, $count, HOUR_IN_SECONDS);
|
3882 |
-
}
|
3883 |
-
|
3884 |
-
return $count;
|
3885 |
-
} // get_num_events_last_n_days
|
3886 |
-
|
3887 |
-
function get_num_events_per_day_last_n_days($period_days = 28)
|
3888 |
-
{
|
3889 |
-
$transient_key = 'sh_' . md5(__METHOD__ . $period_days . '_2');
|
3890 |
-
|
3891 |
-
$dates = get_transient($transient_key);
|
3892 |
-
|
3893 |
-
if (false === $dates) {
|
3894 |
-
global $wpdb;
|
3895 |
-
|
3896 |
-
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead(
|
3897 |
-
null,
|
3898 |
-
'sql'
|
3899 |
-
);
|
3900 |
-
|
3901 |
-
$sql = sprintf(
|
3902 |
-
'
|
3903 |
-
SELECT
|
3904 |
-
date_format(date, "%%Y-%%m-%%d") AS yearDate,
|
3905 |
-
count(date) AS count
|
3906 |
-
FROM
|
3907 |
-
%1$s
|
3908 |
-
WHERE
|
3909 |
-
UNIX_TIMESTAMP(date) >= %2$d
|
3910 |
-
AND logger IN (%3$d)
|
3911 |
-
GROUP BY yearDate
|
3912 |
-
ORDER BY yearDate ASC
|
3913 |
-
',
|
3914 |
-
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3915 |
-
strtotime("-$period_days days"),
|
3916 |
-
$sqlStringLoggersUserCanRead
|
3917 |
-
);
|
3918 |
-
|
3919 |
-
$dates = $wpdb->get_results($sql);
|
3920 |
-
|
3921 |
-
set_transient($transient_key, $dates, HOUR_IN_SECONDS);
|
3922 |
-
// echo "set";exit;
|
3923 |
-
} else {
|
3924 |
-
// echo "get";exit;
|
3925 |
-
}
|
3926 |
-
|
3927 |
-
return $dates;
|
3928 |
-
} // get_num_events_per_day_for_period
|
3929 |
-
|
3930 |
-
// Number of unique events the last n days
|
3931 |
-
public function get_unique_events_for_days($days = 7)
|
3932 |
-
{
|
3933 |
-
global $wpdb;
|
3934 |
-
|
3935 |
-
$days = (int) $days;
|
3936 |
-
|
3937 |
-
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
3938 |
-
|
3939 |
-
$cache_key = 'sh_' . md5(__METHOD__ . $days);
|
3940 |
-
|
3941 |
-
$numEvents = get_transient($cache_key);
|
3942 |
-
|
3943 |
-
if (false == $numEvents) {
|
3944 |
-
$sql = $wpdb->prepare(
|
3945 |
-
"
|
3946 |
-
SELECT count( DISTINCT occasionsID )
|
3947 |
-
FROM $table_name
|
3948 |
-
WHERE date >= DATE_ADD(CURDATE(), INTERVAL -%d DAY)
|
3949 |
-
",
|
3950 |
-
$days
|
3951 |
-
);
|
3952 |
-
|
3953 |
-
$numEvents = $wpdb->get_var($sql);
|
3954 |
-
|
3955 |
-
set_transient($cache_key, $numEvents, HOUR_IN_SECONDS);
|
3956 |
-
}
|
3957 |
-
|
3958 |
-
return $numEvents;
|
3959 |
-
} // get_unique_events_for_days
|
3960 |
-
|
3961 |
-
/**
|
3962 |
-
* Output an admin notice about logger slug being to long
|
3963 |
-
*/
|
3964 |
-
public function admin_notice_logger_slug_to_long()
|
3965 |
-
{
|
3966 |
-
?>
|
3967 |
-
<div class="error notice">
|
3968 |
-
<p><?php echo esc_html__(
|
3969 |
-
'The slug for a logger in Simple History can be max 30 chars long.',
|
3970 |
-
'simple-history'
|
3971 |
-
); ?></p>
|
3972 |
-
</div>
|
3973 |
-
<?php
|
3974 |
-
}
|
3975 |
-
} // class
|
3976 |
|
3977 |
-
|
3978 |
-
|
3979 |
-
*
|
3980 |
-
* Makes call like this possible:
|
3981 |
-
* SimpleLogger()->info("This is a message sent to the log");
|
3982 |
-
*/
|
3983 |
-
function SimpleLogger()
|
3984 |
-
{
|
3985 |
-
return new SimpleLogger(SimpleHistory::get_instance());
|
3986 |
-
}
|
3987 |
|
3988 |
-
/**
|
3989 |
-
|
3990 |
-
|
3991 |
-
|
3992 |
-
|
3993 |
-
|
3994 |
-
|
3995 |
-
|
3996 |
-
|
3997 |
-
|
3998 |
-
|
3999 |
-
|
4000 |
-
|
4001 |
-
|
4002 |
-
|
4003 |
-
|
4004 |
-
|
4005 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4006 |
|
4007 |
-
|
4008 |
|
4009 |
-
|
|
|
4010 |
|
4011 |
-
|
4012 |
-
|
|
|
4013 |
|
4014 |
-
|
4015 |
-
|
4016 |
-
|
4017 |
-
* @since 2.0.29
|
4018 |
-
*
|
4019 |
-
*
|
4020 |
-
* Original description from wp_text_diff():
|
4021 |
-
*
|
4022 |
-
* Displays a human readable HTML representation of the difference between two strings.
|
4023 |
-
*
|
4024 |
-
* The Diff is available for getting the changes between versions. The output is
|
4025 |
-
* HTML, so the primary use is for displaying the changes. If the two strings
|
4026 |
-
* are equivalent, then an empty string will be returned.
|
4027 |
-
*
|
4028 |
-
* The arguments supported and can be changed are listed below.
|
4029 |
-
*
|
4030 |
-
* 'title' : Default is an empty string. Titles the diff in a manner compatible
|
4031 |
-
* with the output.
|
4032 |
-
* 'title_left' : Default is an empty string. Change the HTML to the left of the
|
4033 |
-
* title.
|
4034 |
-
* 'title_right' : Default is an empty string. Change the HTML to the right of
|
4035 |
-
* the title.
|
4036 |
-
*
|
4037 |
-
* @see wp_parse_args() Used to change defaults to user defined settings.
|
4038 |
-
* @uses Text_Diff
|
4039 |
-
* @uses WP_Text_Diff_Renderer_Table
|
4040 |
-
*
|
4041 |
-
* @param string $left_string "old" (left) version of string
|
4042 |
-
* @param string $right_string "new" (right) version of string
|
4043 |
-
* @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. And leading_context_lines and trailing_context_lines.
|
4044 |
-
* @return string Empty string if strings are equivalent or HTML with differences.
|
4045 |
-
*/
|
4046 |
-
function simple_history_text_diff($left_string, $right_string, $args = null)
|
4047 |
-
{
|
4048 |
-
$defaults = array(
|
4049 |
-
'title' => '',
|
4050 |
-
'title_left' => '',
|
4051 |
-
'title_right' => '',
|
4052 |
-
'leading_context_lines' => 1,
|
4053 |
-
'trailing_context_lines' => 1
|
4054 |
-
);
|
4055 |
-
|
4056 |
-
$args = wp_parse_args($args, $defaults);
|
4057 |
-
|
4058 |
-
if (!class_exists('WP_Text_Diff_Renderer_Table')) {
|
4059 |
-
require ABSPATH . WPINC . '/wp-diff.php';
|
4060 |
-
}
|
4061 |
-
|
4062 |
-
$left_string = normalize_whitespace($left_string);
|
4063 |
-
$right_string = normalize_whitespace($right_string);
|
4064 |
-
|
4065 |
-
$left_lines = explode("\n", $left_string);
|
4066 |
-
$right_lines = explode("\n", $right_string);
|
4067 |
-
$text_diff = new Text_Diff($left_lines, $right_lines);
|
4068 |
-
|
4069 |
-
$renderer = new WP_Text_Diff_Renderer_Table($args);
|
4070 |
-
$renderer->_leading_context_lines = $args['leading_context_lines'];
|
4071 |
-
$renderer->_trailing_context_lines = $args['trailing_context_lines'];
|
4072 |
-
|
4073 |
-
$diff = $renderer->render($text_diff);
|
4074 |
-
|
4075 |
-
if (!$diff) {
|
4076 |
-
return '';
|
4077 |
-
}
|
4078 |
-
|
4079 |
-
$r = '';
|
4080 |
-
|
4081 |
-
$r .= "<div class='SimpleHistory__diff__contents' tabindex='0'>";
|
4082 |
-
$r .= "<div class='SimpleHistory__diff__contentsInner'>";
|
4083 |
-
|
4084 |
-
$r .= "<table class='diff SimpleHistory__diff'>\n";
|
4085 |
-
|
4086 |
-
if (!empty($args['show_split_view'])) {
|
4087 |
-
$r .=
|
4088 |
-
"<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />";
|
4089 |
-
} else {
|
4090 |
-
$r .= "<col class='content' />";
|
4091 |
-
}
|
4092 |
-
|
4093 |
-
if ($args['title'] || $args['title_left'] || $args['title_right']) {
|
4094 |
-
$r .= '<thead>';
|
4095 |
-
}
|
4096 |
-
if ($args['title']) {
|
4097 |
-
$r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
|
4098 |
-
}
|
4099 |
-
if ($args['title_left'] || $args['title_right']) {
|
4100 |
-
$r .= "<tr class='diff-sub-title'>\n";
|
4101 |
-
$r .= "\t<td></td><th>$args[title_left]</th>\n";
|
4102 |
-
$r .= "\t<td></td><th>$args[title_right]</th>\n";
|
4103 |
-
$r .= "</tr>\n";
|
4104 |
-
}
|
4105 |
-
if ($args['title'] || $args['title_left'] || $args['title_right']) {
|
4106 |
-
$r .= "</thead>\n";
|
4107 |
-
}
|
4108 |
-
|
4109 |
-
$r .= "<tbody>\n$diff</div>\n</tbody>\n";
|
4110 |
-
$r .= '</table>';
|
4111 |
-
|
4112 |
-
$r .= '</div>';
|
4113 |
-
$r .= '</div>';
|
4114 |
-
|
4115 |
-
return $r;
|
4116 |
-
}
|
4117 |
|
4118 |
-
|
4119 |
-
|
4120 |
-
* Any number of variables can be passed and each variable is print_r'ed to the error log.
|
4121 |
-
*
|
4122 |
-
* Example usage:
|
4123 |
-
* sh_error_log(
|
4124 |
-
* 'rest_request_after_callbacks:',
|
4125 |
-
* $handler,
|
4126 |
-
* $handler['callback'][0],
|
4127 |
-
* $handler['callback'][1]
|
4128 |
-
* );
|
4129 |
-
*/
|
4130 |
-
function sh_error_log()
|
4131 |
-
{
|
4132 |
-
foreach (func_get_args() as $var) {
|
4133 |
-
if (is_bool($var)) {
|
4134 |
-
$bool_string = true === $var ? 'true' : 'false';
|
4135 |
-
error_log("$bool_string (boolean value)");
|
4136 |
-
} elseif (is_null($var)) {
|
4137 |
-
error_log('null (null value)');
|
4138 |
-
} else {
|
4139 |
-
error_log(print_r($var, true));
|
4140 |
-
}
|
4141 |
-
}
|
4142 |
-
}
|
4143 |
|
4144 |
-
|
4145 |
-
|
4146 |
-
|
4147 |
-
|
4148 |
-
|
4149 |
-
|
4150 |
-
|
4151 |
-
* - Redirection_Api_Redirect::route_bulk
|
4152 |
-
* - wpcf7_rest_create_feedback
|
4153 |
-
* - closure
|
4154 |
-
*
|
4155 |
-
* Function based on code found on stack overflow:
|
4156 |
-
* https://stackoverflow.com/questions/34324576/print-name-or-definition-of-callable-in-php
|
4157 |
-
*
|
4158 |
-
* @param callable $callable The callable thing to check.
|
4159 |
-
* @return string Name of callable.
|
4160 |
-
*/
|
4161 |
-
function sh_get_callable_name($callable)
|
4162 |
-
{
|
4163 |
-
if (is_string($callable)) {
|
4164 |
-
return trim($callable);
|
4165 |
-
} elseif (is_array($callable)) {
|
4166 |
-
if (is_object($callable[0])) {
|
4167 |
-
return sprintf(
|
4168 |
-
'%s::%s',
|
4169 |
-
get_class($callable[0]),
|
4170 |
-
trim($callable[1])
|
4171 |
-
);
|
4172 |
-
} else {
|
4173 |
-
return sprintf('%s::%s', trim($callable[0]), trim($callable[1]));
|
4174 |
-
}
|
4175 |
-
} elseif ($callable instanceof Closure) {
|
4176 |
-
return 'closure';
|
4177 |
-
} else {
|
4178 |
-
return 'unknown';
|
4179 |
-
}
|
4180 |
-
}
|
4181 |
|
4182 |
-
|
4183 |
-
|
4184 |
-
|
4185 |
-
|
4186 |
-
|
4187 |
-
|
4188 |
-
|
4189 |
-
|
4190 |
-
|
4191 |
-
function
|
4192 |
-
{
|
4193 |
-
|
4194 |
-
|
4195 |
-
|
4196 |
-
|
4197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
*/
|
8 |
class SimpleHistory
|
9 |
{
|
10 |
+
const NAME = 'Simple History';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* For singleton
|
14 |
+
*/
|
15 |
+
private static $instance;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Array with external loggers to load
|
19 |
+
*/
|
20 |
+
private $externalLoggers;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Array with external dropins to load
|
24 |
+
*/
|
25 |
+
private $externalDropins;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Array with all instantiated loggers
|
29 |
+
*/
|
30 |
+
private $instantiatedLoggers;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Array with all instantiated dropins
|
34 |
+
*/
|
35 |
+
private $instantiatedDropins;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Bool if gettext filter function should be active
|
39 |
+
* Should only be active during the load of a logger
|
40 |
+
*/
|
41 |
+
private $doFilterGettext = false;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Used by gettext filter to temporarily store current logger
|
45 |
+
*/
|
46 |
+
private $doFilterGettext_currentLogger = null;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Used to store latest translations used by __()
|
50 |
+
* Required to automagically determine orginal text and text domain
|
51 |
+
* for calls like this `SimpleLogger()->log( __("My translated message") );`
|
52 |
+
*/
|
53 |
+
public $gettextLatestTranslations = array();
|
54 |
+
|
55 |
+
/**
|
56 |
+
* All registered settings tabs
|
57 |
+
*/
|
58 |
+
private $arr_settings_tabs = array();
|
59 |
+
|
60 |
+
const DBTABLE = 'simple_history';
|
61 |
+
const DBTABLE_CONTEXTS = 'simple_history_contexts';
|
62 |
+
|
63 |
+
/** Slug for the settings menu */
|
64 |
+
const SETTINGS_MENU_SLUG = 'simple_history_settings_menu_slug';
|
65 |
+
|
66 |
+
/** Slug for the settings menu */
|
67 |
+
const SETTINGS_GENERAL_OPTION_GROUP = 'simple_history_settings_group';
|
68 |
+
|
69 |
+
/** ID for the general settings section */
|
70 |
+
const SETTINGS_SECTION_GENERAL_ID = 'simple_history_settings_section_general';
|
71 |
+
|
72 |
+
public function __construct()
|
73 |
+
{
|
74 |
+
$this->init();
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @since 2.5.2
|
79 |
+
*/
|
80 |
+
public function init()
|
81 |
+
{
|
82 |
+
/**
|
83 |
+
* Fires before Simple History does it's init stuff
|
84 |
+
*
|
85 |
+
* @since 2.0
|
86 |
+
*
|
87 |
+
* @param SimpleHistory $SimpleHistory This class.
|
88 |
+
*/
|
89 |
+
do_action('simple_history/before_init', $this);
|
90 |
+
|
91 |
+
$this->setup_variables();
|
92 |
+
|
93 |
+
// Actions and filters, ordered by order specified in codex: http://codex.wordpress.org/Plugin_API/Action_Reference
|
94 |
+
add_action('after_setup_theme', array( $this, 'load_plugin_textdomain' ));
|
95 |
+
add_action('after_setup_theme', array( $this, 'add_default_settings_tabs' ));
|
96 |
+
|
97 |
+
// Plugins and dropins are loaded using the "after_setup_theme" filter so
|
98 |
+
// themes can use filters to modify the loading of them.
|
99 |
+
// The drawback with this is that for example logouts done when plugins like
|
100 |
+
// iThemes Security is installed is not logged, because those plugins fire wp_logout()
|
101 |
+
// using filter "plugins_loaded", i.e. before simple history has loaded its filters.
|
102 |
+
add_action('after_setup_theme', array( $this, 'load_loggers' ));
|
103 |
+
add_action('after_setup_theme', array( $this, 'load_dropins' ));
|
104 |
+
|
105 |
+
// Run before loading of loggers and before menu items are added.
|
106 |
+
add_action('after_setup_theme', array( $this, 'check_for_upgrade' ), 5);
|
107 |
+
|
108 |
+
add_action('after_setup_theme', array( $this, 'setup_cron' ));
|
109 |
+
|
110 |
+
// Filters and actions not called during regular boot.
|
111 |
+
add_filter('gettext', array( $this, 'filter_gettext' ), 20, 3);
|
112 |
+
add_filter('gettext_with_context', array( $this, 'filter_gettext_with_context' ), 20, 4);
|
113 |
+
|
114 |
+
add_filter('gettext', array( $this, 'filter_gettext_storeLatestTranslations' ), 10, 3);
|
115 |
+
|
116 |
+
add_action('admin_bar_menu', array( $this, 'add_admin_bar_network_menu_item' ), 40);
|
117 |
+
add_action('admin_bar_menu', array( $this, 'add_admin_bar_menu_item' ), 40);
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Filter that is used to log things, without the need to check that simple history is available
|
121 |
+
* i.e. you can have simple history acivated and log things and then you can disable the plugin
|
122 |
+
* and no errors will occur
|
123 |
+
*
|
124 |
+
* Usage:
|
125 |
+
* apply_filters("simple_history_log", "This is the log message");
|
126 |
+
* apply_filters("simple_history_log", "This is the log message with some extra data/info", ["extraThing1" => $variableWIihThing]);
|
127 |
+
* apply_filters("simple_history_log", "This is the log message with severity debug", null, "debug");
|
128 |
+
* apply_filters("simple_history_log", "This is the log message with severity debug and with some extra info/data logged", ["userData" => $userData, "shoppingCartDebugData" => $shopDebugData], "debug",);
|
129 |
+
*
|
130 |
+
* @since 2.13
|
131 |
+
*/
|
132 |
+
add_filter('simple_history_log', array( $this, 'on_filter_simple_history_log' ), 10, 3);
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Filter to log with specific log level, for example:
|
136 |
+
* apply_filters('simple_history_log_debug', 'My debug message');
|
137 |
+
* apply_filters('simple_history_log_warning', 'My warning message');
|
138 |
+
*
|
139 |
+
* @since 2.17
|
140 |
+
*/
|
141 |
+
add_filter('simple_history_log_emergency', array( $this, 'on_filter_simple_history_log_emergency' ), 10, 3);
|
142 |
+
add_filter('simple_history_log_alert', array( $this, 'on_filter_simple_history_log_alert' ), 10, 2);
|
143 |
+
add_filter('simple_history_log_critical', array( $this, 'on_filter_simple_history_log_critical' ), 10, 2);
|
144 |
+
add_filter('simple_history_log_error', array( $this, 'on_filter_simple_history_log_error' ), 10, 2);
|
145 |
+
add_filter('simple_history_log_warning', array( $this, 'on_filter_simple_history_log_warning' ), 10, 2);
|
146 |
+
add_filter('simple_history_log_notice', array( $this, 'on_filter_simple_history_log_notice' ), 10, 2);
|
147 |
+
add_filter('simple_history_log_info', array( $this, 'on_filter_simple_history_log_info' ), 10, 2);
|
148 |
+
add_filter('simple_history_log_debug', array( $this, 'on_filter_simple_history_log_debug' ), 10, 2);
|
149 |
+
|
150 |
+
if (is_admin()) {
|
151 |
+
$this->add_admin_actions();
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Fires after Simple History has done it's init stuff
|
156 |
+
*
|
157 |
+
* @since 2.0
|
158 |
+
*
|
159 |
+
* @param SimpleHistory $SimpleHistory This class.
|
160 |
+
*/
|
161 |
+
do_action('simple_history/after_init', $this);
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Log a message
|
166 |
+
*
|
167 |
+
* Function called when running filter "simple_history_log"
|
168 |
+
*
|
169 |
+
* @since 2.13
|
170 |
+
* @param string $message The message to log.
|
171 |
+
* @param array $context Optional context to add to the logged data.
|
172 |
+
* @param string $level The loglevel. Must be one of the existing ones. Defaults to "info".
|
173 |
+
*/
|
174 |
+
public function on_filter_simple_history_log($message = null, $context = null, $level = 'info')
|
175 |
+
{
|
176 |
+
SimpleLogger()->log($level, $message, $context);
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_emergency'.
|
181 |
+
*
|
182 |
+
* @param string $message The message to log.
|
183 |
+
* @param array $context The context (optional).
|
184 |
+
*/
|
185 |
+
public function on_filter_simple_history_log_emergency($message = null, $context = null)
|
186 |
+
{
|
187 |
+
SimpleLogger()->log('emergency', $message, $context);
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_alert'.
|
192 |
+
*
|
193 |
+
* @param string $message The message to log.
|
194 |
+
* @param array $context The context (optional).
|
195 |
+
*/
|
196 |
+
public function on_filter_simple_history_log_alert($message = null, $context = null)
|
197 |
+
{
|
198 |
+
SimpleLogger()->log('alert', $message, $context);
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_critical'.
|
203 |
+
*
|
204 |
+
* @param string $message The message to log.
|
205 |
+
* @param array $context The context (optional).
|
206 |
+
*/
|
207 |
+
public function on_filter_simple_history_log_critical($message = null, $context = null)
|
208 |
+
{
|
209 |
+
SimpleLogger()->log('critical', $message, $context);
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_error'.
|
214 |
+
*
|
215 |
+
* @param string $message The message to log.
|
216 |
+
* @param array $context The context (optional).
|
217 |
+
*/
|
218 |
+
public function on_filter_simple_history_log_error($message = null, $context = null)
|
219 |
+
{
|
220 |
+
SimpleLogger()->log('error', $message, $context);
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_warning'.
|
225 |
+
*
|
226 |
+
* @param string $message The message to log.
|
227 |
+
* @param array $context The context (optional).
|
228 |
+
*/
|
229 |
+
public function on_filter_simple_history_log_warning($message = null, $context = null)
|
230 |
+
{
|
231 |
+
SimpleLogger()->log('warning', $message, $context);
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_notice'.
|
236 |
+
*
|
237 |
+
* @param string $message The message to log.
|
238 |
+
* @param array $context The context (optional).
|
239 |
+
*/
|
240 |
+
public function on_filter_simple_history_log_notice($message = null, $context = null)
|
241 |
+
{
|
242 |
+
SimpleLogger()->log('notice', $message, $context);
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_info'.
|
247 |
+
*
|
248 |
+
* @param string $message The message to log.
|
249 |
+
* @param array $context The context (optional).
|
250 |
+
*/
|
251 |
+
public function on_filter_simple_history_log_info($message = null, $context = null)
|
252 |
+
{
|
253 |
+
SimpleLogger()->log('info', $message, $context);
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_debug'.
|
258 |
+
*
|
259 |
+
* @param string $message The message to log.
|
260 |
+
* @param array $context The context (optional).
|
261 |
+
*/
|
262 |
+
public function on_filter_simple_history_log_debug($message = null, $context = null)
|
263 |
+
{
|
264 |
+
SimpleLogger()->log('debug', $message, $context);
|
265 |
+
}
|
266 |
+
|
267 |
+
/**
|
268 |
+
* @since 2.5.2
|
269 |
+
*/
|
270 |
+
private function add_admin_actions()
|
271 |
+
{
|
272 |
+
add_action('admin_menu', array( $this, 'add_admin_pages' ));
|
273 |
+
add_action('admin_menu', array( $this, 'add_settings' ));
|
274 |
+
|
275 |
+
add_action('admin_footer', array( $this, 'add_js_templates' ));
|
276 |
+
|
277 |
+
add_action('wp_dashboard_setup', array( $this, 'add_dashboard_widget' ));
|
278 |
+
|
279 |
+
add_action('admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ));
|
280 |
+
|
281 |
+
add_action('admin_head', array( $this, 'onAdminHead' ));
|
282 |
+
add_action('admin_footer', array( $this, 'onAdminFooter' ));
|
283 |
+
|
284 |
+
add_action('simple_history/history_page/before_gui', array( $this, 'output_quick_stats' ));
|
285 |
+
add_action('simple_history/dashboard/before_gui', array( $this, 'output_quick_stats' ));
|
286 |
+
|
287 |
+
add_action('wp_ajax_simple_history_api', array( $this, 'api' ));
|
288 |
+
|
289 |
+
add_filter('plugin_action_links_simple-history/index.php', array( $this, 'plugin_action_links' ), 10, 4);
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Adds a "View history" item/shortcut to the network admin, on blogs where Simple History is installed
|
294 |
+
*
|
295 |
+
* Useful because Simple History is something at least the author of this plugin often use on a site :)
|
296 |
+
*
|
297 |
+
* @since 2.7.1
|
298 |
+
*/
|
299 |
+
public function add_admin_bar_network_menu_item($wp_admin_bar)
|
300 |
+
{
|
301 |
+
/**
|
302 |
+
* Filter to control if admin bar shortcut should be added
|
303 |
+
*
|
304 |
+
* @since 2.7.1
|
305 |
+
*
|
306 |
+
* @param bool Add item
|
307 |
+
*/
|
308 |
+
$add_items = apply_filters('simple_history/add_admin_bar_network_menu_item', true);
|
309 |
+
|
310 |
+
if (! $add_items) {
|
311 |
+
return;
|
312 |
+
}
|
313 |
+
|
314 |
+
// Don't show for logged out users or single site mode.
|
315 |
+
if (! is_user_logged_in() || ! is_multisite()) {
|
316 |
+
return;
|
317 |
+
}
|
318 |
+
|
319 |
+
// Show only when the user has at least one site, or they're a super admin.
|
320 |
+
if (count($wp_admin_bar->user->blogs) < 1 && ! is_super_admin()) {
|
321 |
+
return;
|
322 |
+
}
|
323 |
+
|
324 |
+
// Setting to show as page must be true
|
325 |
+
if (! $this->setting_show_as_page()) {
|
326 |
+
return;
|
327 |
+
}
|
328 |
+
|
329 |
+
// User must have capability to view the history page
|
330 |
+
if (! current_user_can($this->get_view_history_capability())) {
|
331 |
+
return;
|
332 |
+
}
|
333 |
+
|
334 |
+
/*
|
335 |
+
menu_page_url() is defined in the WordPress Plugin Administration API, which is not loaded here by default */
|
336 |
+
/* dito for is_plugin_active() */
|
337 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
338 |
+
|
339 |
+
foreach ((array) $wp_admin_bar->user->blogs as $blog) {
|
340 |
+
switch_to_blog($blog->userblog_id);
|
341 |
+
|
342 |
+
if (is_plugin_active(SIMPLE_HISTORY_BASENAME)) {
|
343 |
+
$menu_id = 'simple-history-blog-' . $blog->userblog_id;
|
344 |
+
$parent_menu_id = 'blog-' . $blog->userblog_id;
|
345 |
+
$url = admin_url(apply_filters('simple_history/admin_location', 'index') . '.php?page=simple_history_page');
|
346 |
+
|
347 |
+
// Each network site is added by WP core with id "blog-1", "blog-2" ... "blog-n"
|
348 |
+
// https://codex.wordpress.org/Function_Reference/add_node
|
349 |
+
$args = array(
|
350 |
+
'id' => $menu_id,
|
351 |
+
'parent' => $parent_menu_id,
|
352 |
+
'title' => _x('View History', 'Admin bar network name', 'simple-history'),
|
353 |
+
'href' => $url,
|
354 |
+
'meta' => array(
|
355 |
+
'class' => 'ab-item--simplehistory'
|
356 |
+
)
|
357 |
+
);
|
358 |
+
|
359 |
+
$wp_admin_bar->add_node($args);
|
360 |
+
} // End if().
|
361 |
+
|
362 |
+
restore_current_blog();
|
363 |
+
} // End foreach().
|
364 |
+
} // func
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Adds a "View history" item/shortcut to the admin bar
|
368 |
+
*
|
369 |
+
* Useful because Simple History is something at least the author of this plugin often use on a site :)
|
370 |
+
*
|
371 |
+
* @since 2.7.1
|
372 |
+
*/
|
373 |
+
public function add_admin_bar_menu_item($wp_admin_bar)
|
374 |
+
{
|
375 |
+
/**
|
376 |
+
* Filter to control if admin bar shortcut should be added
|
377 |
+
*
|
378 |
+
* @since 2.7.1
|
379 |
+
*
|
380 |
+
* @param bool Add item
|
381 |
+
*/
|
382 |
+
$add_item = apply_filters('simple_history/add_admin_bar_menu_item', true);
|
383 |
+
|
384 |
+
if (! $add_item) {
|
385 |
+
return;
|
386 |
+
}
|
387 |
+
|
388 |
+
// Don't show for logged out users
|
389 |
+
if (! is_user_logged_in()) {
|
390 |
+
return;
|
391 |
+
}
|
392 |
+
|
393 |
+
// Setting to show as page must be true
|
394 |
+
if (! $this->setting_show_as_page()) {
|
395 |
+
return;
|
396 |
+
}
|
397 |
+
|
398 |
+
// User must have capability to view the history page
|
399 |
+
if (! current_user_can($this->get_view_history_capability())) {
|
400 |
+
return;
|
401 |
+
}
|
402 |
+
|
403 |
+
/* menu_page_url() and is_plugin_active()is defined in the WordPress Plugin Administration API, which is not loaded here by default */
|
404 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
405 |
+
|
406 |
+
$menu_id = 'simple-history-view-history';
|
407 |
+
$parent_menu_id = 'site-name';
|
408 |
+
$url = admin_url(apply_filters('simple_history/admin_location', 'index') . '.php?page=simple_history_page');
|
409 |
+
|
410 |
+
$args = array(
|
411 |
+
'id' => $menu_id,
|
412 |
+
'parent' => $parent_menu_id,
|
413 |
+
'title' => _x('Simple History', 'Admin bar name', 'simple-history'),
|
414 |
+
'href' => $url,
|
415 |
+
'meta' => array(
|
416 |
+
'class' => 'ab-item--simplehistory'
|
417 |
+
)
|
418 |
+
);
|
419 |
+
|
420 |
+
$wp_admin_bar->add_node($args);
|
421 |
+
} // func
|
422 |
+
|
423 |
+
/**
|
424 |
+
* Get singleton intance
|
425 |
+
*
|
426 |
+
* @return SimpleHistory instance
|
427 |
+
*/
|
428 |
+
public static function get_instance()
|
429 |
+
{
|
430 |
+
if (! isset(self::$instance)) {
|
431 |
+
self::$instance = new SimpleHistory();
|
432 |
+
}
|
433 |
+
|
434 |
+
return self::$instance;
|
435 |
+
}
|
436 |
+
|
437 |
+
public function filter_gettext_storeLatestTranslations($translation, $text, $domain)
|
438 |
+
{
|
439 |
+
// Check that translation is a string or integer, i.ex. the valid values for an array key
|
440 |
+
if (! is_string($translation) || ! is_integer($translation)) {
|
441 |
+
return $translation;
|
442 |
+
}
|
443 |
+
|
444 |
+
$array_max_size = 5;
|
445 |
+
|
446 |
+
// Keep a listing of the n latest translation
|
447 |
+
// when SimpleLogger->log() is called from anywhere we can then search for the
|
448 |
+
// translated string among our n latest things and find it there, if it's translated
|
449 |
+
// global $sh_latest_translations;
|
450 |
+
$sh_latest_translations = $this->gettextLatestTranslations;
|
451 |
+
|
452 |
+
$sh_latest_translations[ $translation ] = array(
|
453 |
+
'translation' => $translation,
|
454 |
+
'text' => $text,
|
455 |
+
'domain' => $domain
|
456 |
+
);
|
457 |
+
|
458 |
+
$arr_length = sizeof($sh_latest_translations);
|
459 |
+
if ($arr_length > $array_max_size) {
|
460 |
+
$sh_latest_translations = array_slice($sh_latest_translations, $arr_length - $array_max_size);
|
461 |
+
}
|
462 |
+
|
463 |
+
$this->gettextLatestTranslations = $sh_latest_translations;
|
464 |
+
|
465 |
+
return $translation;
|
466 |
+
}
|
467 |
+
|
468 |
+
public function setup_cron()
|
469 |
+
{
|
470 |
+
add_filter('simple_history/maybe_purge_db', array( $this, 'maybe_purge_db' ));
|
471 |
+
|
472 |
+
if (! wp_next_scheduled('simple_history/maybe_purge_db')) {
|
473 |
+
wp_schedule_event(time(), 'daily', 'simple_history/maybe_purge_db');
|
474 |
+
} else {
|
475 |
+
}
|
476 |
+
|
477 |
+
// Remove old schedule (only author dev sites should have it)
|
478 |
+
$old_next_scheduled = wp_next_scheduled('simple_history/purge_db');
|
479 |
+
if ($old_next_scheduled) {
|
480 |
+
wp_unschedule_event($old_next_scheduled, 'simple_history/purge_db');
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
public function onAdminHead()
|
485 |
+
{
|
486 |
+
if ($this->is_on_our_own_pages()) {
|
487 |
+
do_action('simple_history/admin_head', $this);
|
488 |
+
}
|
489 |
+
}
|
490 |
+
|
491 |
+
public function onAdminFooter()
|
492 |
+
{
|
493 |
+
if ($this->is_on_our_own_pages()) {
|
494 |
+
do_action('simple_history/admin_footer', $this);
|
495 |
+
}
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* Output JS templated into footer
|
500 |
+
*/
|
501 |
+
public function add_js_templates($hook)
|
502 |
+
{
|
503 |
+
if ($this->is_on_our_own_pages()) { ?>
|
504 |
+
<script type="text/html" id="tmpl-simple-history-base">
|
505 |
+
|
506 |
+
<div class="SimpleHistory__waitingForFirstLoad">
|
507 |
+
<img src="<?php echo admin_url('/images/spinner.gif'); ?>" alt="" width="20" height="20">
|
508 |
+
<?php echo _x(
|
509 |
+
'Loading history...',
|
510 |
+
'Message visible while waiting for log to load from server the first time',
|
511 |
+
'simple-history'
|
512 |
+
); ?>
|
513 |
+
</div>
|
514 |
+
|
515 |
+
<div class="SimpleHistoryLogitemsWrap">
|
516 |
+
<div class="SimpleHistoryLogitems__beforeTopPagination"></div>
|
517 |
+
<div class="SimpleHistoryLogitems__above"></div>
|
518 |
+
<ul class="SimpleHistoryLogitems"></ul>
|
519 |
+
<div class="SimpleHistoryLogitems__below"></div>
|
520 |
+
<div class="SimpleHistoryLogitems__pagination"></div>
|
521 |
+
<div class="SimpleHistoryLogitems__afterBottomPagination"></div>
|
522 |
+
</div>
|
523 |
+
|
524 |
+
<div class="SimpleHistoryLogitems__debug"></div>
|
525 |
+
|
526 |
+
</script>
|
527 |
+
|
528 |
+
<script type="text/html" id="tmpl-simple-history-logitems-pagination">
|
529 |
+
|
530 |
+
<!-- this uses the (almost) the same html as WP does -->
|
531 |
+
<div class="SimpleHistoryPaginationPages">
|
532 |
+
<!--
|
533 |
+
{{ data.page_rows_from }}–{{ data.page_rows_to }}
|
534 |
+
<span class="SimpleHistoryPaginationDisplayNum"> of {{ data.total_row_count }} </span>
|
535 |
+
-->
|
536 |
+
<span class="SimpleHistoryPaginationLinks">
|
537 |
+
<a
|
538 |
+
data-direction="first"
|
539 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--firstPage <# if ( data.api_args.paged <= 1 ) { #> disabled <# } #>"
|
540 |
+
title="{{ data.strings.goToTheFirstPage }}"
|
541 |
+
href="#">«</a>
|
542 |
+
<a
|
543 |
+
data-direction="prev"
|
544 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--prevPage <# if ( data.api_args.paged <= 1 ) { #> disabled <# } #>"
|
545 |
+
title="{{ data.strings.goToThePrevPage }}"
|
546 |
+
href="#">‹</a>
|
547 |
+
<span class="SimpleHistoryPaginationInput">
|
548 |
+
<input class="SimpleHistoryPaginationCurrentPage" title="{{ data.strings.currentPage }}" type="text" name="paged" value="{{ data.api_args.paged }}" size="4">
|
549 |
+
<?php _x('of', 'page n of n', 'simple-history'); ?>
|
550 |
+
<span class="total-pages">{{ data.pages_count }}</span>
|
551 |
+
</span>
|
552 |
+
<a
|
553 |
+
data-direction="next"
|
554 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--nextPage <# if ( data.api_args.paged >= data.pages_count ) { #> disabled <# } #>"
|
555 |
+
title="{{ data.strings.goToTheNextPage }}"
|
556 |
+
href="#">›</a>
|
557 |
+
<a
|
558 |
+
data-direction="last"
|
559 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--lastPage <# if ( data.api_args.paged >= data.pages_count ) { #> disabled <# } #>"
|
560 |
+
title="{{ data.strings.goToTheLastPage }}"
|
561 |
+
href="#">»</a>
|
562 |
+
</span>
|
563 |
+
</div>
|
564 |
+
|
565 |
+
</script>
|
566 |
+
|
567 |
+
<script type="text/html" id="tmpl-simple-history-logitems-modal">
|
568 |
+
|
569 |
+
<div class="SimpleHistory-modal">
|
570 |
+
<div class="SimpleHistory-modal__background"></div>
|
571 |
+
<div class="SimpleHistory-modal__content">
|
572 |
+
<div class="SimpleHistory-modal__contentInner">
|
573 |
+
<img class="SimpleHistory-modal__contentSpinner" src="<?php echo esc_url(admin_url('/images/spinner.gif')); ?>" alt="">
|
574 |
+
</div>
|
575 |
+
<div class="SimpleHistory-modal__contentClose">
|
576 |
+
<button class="button">✕</button>
|
577 |
+
</div>
|
578 |
+
</div>
|
579 |
+
</div>
|
580 |
+
|
581 |
+
</script>
|
582 |
+
|
583 |
+
<script type="text/html" id="tmpl-simple-history-occasions-too-many">
|
584 |
+
<li
|
585 |
+
class="SimpleHistoryLogitem
|
586 |
+
SimpleHistoryLogitem--occasion
|
587 |
+
SimpleHistoryLogitem--occasion-tooMany
|
588 |
+
">
|
589 |
+
<div class="SimpleHistoryLogitem__firstcol"></div>
|
590 |
+
<div class="SimpleHistoryLogitem__secondcol">
|
591 |
+
<div class="SimpleHistoryLogitem__text">
|
592 |
+
<?php _e('Sorry, but there are too many similar events to show.', 'simple-history'); ?>
|
593 |
+
<!-- <br>occasionsCount: {{ data.occasionsCount }}
|
594 |
+
<br>occasionsCountMaxReturn: {{ data.occasionsCountMaxReturn }}
|
595 |
+
<br>diff: {{ data.occasionsCount - data.occasionsCountMaxReturn }}
|
596 |
+
Suggestions:
|
597 |
+
<ul>
|
598 |
+
<li>- dig into database directly
|
599 |
+
<li>- Export
|
600 |
+
</ul>
|
601 |
+
-->
|
602 |
+
</div>
|
603 |
+
</div>
|
604 |
+
</li>
|
605 |
+
</script>
|
606 |
+
|
607 |
+
<?php // Call plugins so they can add their js
|
608 |
+
foreach ($this->instantiatedLoggers as $one_logger) {
|
609 |
+
if (method_exists($one_logger['instance'], 'adminJS')) {
|
610 |
+
$one_logger['instance']->adminJS();
|
611 |
+
}
|
612 |
+
}
|
613 |
+
}// End if().
|
614 |
+
}
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Base url is:
|
618 |
+
* /wp-admin/admin-ajax.php?action=simple_history_api
|
619 |
+
*
|
620 |
+
* Examples:
|
621 |
+
* http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&posts_per_page=5&paged=1&format=html
|
622 |
+
*/
|
623 |
+
public function api()
|
624 |
+
{
|
625 |
+
global $wpdb;
|
626 |
+
|
627 |
+
// Fake slow answers
|
628 |
+
// sleep(2);
|
629 |
+
// sleep(rand(0,3));
|
630 |
+
$args = $_GET;
|
631 |
+
unset($args['action']);
|
632 |
+
|
633 |
+
// Type = overview | ...
|
634 |
+
$type = isset($_GET['type']) ? $_GET['type'] : null;
|
635 |
+
|
636 |
+
if (empty($args) || ! $type) {
|
637 |
+
wp_send_json_error(array(
|
638 |
+
_x('Not enough args specified', 'API: not enought arguments passed', 'simple-history')
|
639 |
+
));
|
640 |
+
}
|
641 |
+
|
642 |
+
// User must have capability to view the history page
|
643 |
+
if (! current_user_can($this->get_view_history_capability())) {
|
644 |
+
wp_send_json_error(array(
|
645 |
+
'error' => 'CAPABILITY_ERROR'
|
646 |
+
));
|
647 |
+
}
|
648 |
+
|
649 |
+
if (isset($args['id'])) {
|
650 |
+
$args['post__in'] = array($args['id']);
|
651 |
+
}
|
652 |
+
|
653 |
+
$data = array();
|
654 |
+
|
655 |
+
switch ($type) {
|
656 |
+
case 'overview':
|
657 |
+
case 'occasions':
|
658 |
+
case 'single':
|
659 |
+
// API use SimpleHistoryLogQuery, so simply pass args on to that
|
660 |
+
$logQuery = new SimpleHistoryLogQuery();
|
661 |
+
$data = $logQuery->query($args);
|
662 |
+
|
663 |
+
$data['api_args'] = $args;
|
664 |
+
|
665 |
+
// Output can be array or HMTL
|
666 |
+
if (isset($args['format']) && 'html' === $args['format']) {
|
667 |
+
$data['log_rows_raw'] = array();
|
668 |
+
|
669 |
+
foreach ($data['log_rows'] as $key => $oneLogRow) {
|
670 |
+
$args = array();
|
671 |
+
if ($type == 'single') {
|
672 |
+
$args['type'] = 'single';
|
673 |
+
}
|
674 |
+
|
675 |
+
$data['log_rows'][ $key ] = $this->getLogRowHTMLOutput($oneLogRow, $args);
|
676 |
+
$data['num_queries'] = get_num_queries();
|
677 |
+
}
|
678 |
+
} else {
|
679 |
+
// $data["logRows"] = $logRows;
|
680 |
+
}
|
681 |
+
|
682 |
+
break;
|
683 |
+
|
684 |
+
default:
|
685 |
+
$data[] = 'Nah.';
|
686 |
+
}// End switch().
|
687 |
+
|
688 |
+
wp_send_json_success($data);
|
689 |
+
}
|
690 |
+
|
691 |
+
/**
|
692 |
+
* During the load of info for a logger we want to get a reference
|
693 |
+
* to the untranslated text too, because that's the version we want to store
|
694 |
+
* in the database.
|
695 |
+
*/
|
696 |
+
public function filter_gettext($translated_text, $untranslated_text, $domain)
|
697 |
+
{
|
698 |
+
if (isset($this->doFilterGettext) && $this->doFilterGettext) {
|
699 |
+
$this->doFilterGettext_currentLogger->messages[] = array(
|
700 |
+
'untranslated_text' => $untranslated_text,
|
701 |
+
'translated_text' => $translated_text,
|
702 |
+
'domain' => $domain,
|
703 |
+
'context' => null
|
704 |
+
);
|
705 |
+
}
|
706 |
+
|
707 |
+
return $translated_text;
|
708 |
+
}
|
709 |
+
|
710 |
+
/**
|
711 |
+
* Store messages with context
|
712 |
+
*/
|
713 |
+
public function filter_gettext_with_context($translated_text, $untranslated_text, $context, $domain)
|
714 |
+
{
|
715 |
+
if (isset($this->doFilterGettext) && $this->doFilterGettext) {
|
716 |
+
$this->doFilterGettext_currentLogger->messages[] = array(
|
717 |
+
'untranslated_text' => $untranslated_text,
|
718 |
+
'translated_text' => $translated_text,
|
719 |
+
'domain' => $domain,
|
720 |
+
'context' => $context
|
721 |
+
);
|
722 |
+
}
|
723 |
+
|
724 |
+
return $translated_text;
|
725 |
+
}
|
726 |
+
|
727 |
+
/**
|
728 |
+
* Load language files.
|
729 |
+
* Uses the method described here:
|
730 |
+
* http://geertdedeckere.be/article/loading-wordpress-language-files-the-right-way
|
731 |
+
*
|
732 |
+
* @since 2.0
|
733 |
+
*/
|
734 |
+
public function load_plugin_textdomain()
|
735 |
+
{
|
736 |
+
$domain = 'simple-history';
|
737 |
+
|
738 |
+
// The "plugin_locale" filter is also used in load_plugin_textdomain()
|
739 |
+
$locale = apply_filters('plugin_locale', get_locale(), $domain);
|
740 |
+
load_textdomain($domain, WP_LANG_DIR . '/simple-history/' . $domain . '-' . $locale . '.mo');
|
741 |
+
load_plugin_textdomain($domain, false, dirname($this->plugin_basename) . '/languages/');
|
742 |
+
}
|
743 |
+
|
744 |
+
/**
|
745 |
+
* Setup variables and things
|
746 |
+
*/
|
747 |
+
public function setup_variables()
|
748 |
+
{
|
749 |
+
$this->externalLoggers = array();
|
750 |
+
$this->externalDropins = array();
|
751 |
+
$this->instantiatedLoggers = array();
|
752 |
+
$this->instantiatedDropins = array();
|
753 |
+
|
754 |
+
$this->plugin_basename = SIMPLE_HISTORY_BASENAME;
|
755 |
+
}
|
756 |
+
|
757 |
+
/**
|
758 |
+
* Return capability required to view history = for who will the History page be added
|
759 |
+
*
|
760 |
+
* @since 2.1.5
|
761 |
+
* @return string capability
|
762 |
+
*/
|
763 |
+
public function get_view_history_capability()
|
764 |
+
{
|
765 |
+
$view_history_capability = 'edit_pages';
|
766 |
+
$view_history_capability = apply_filters('simple_history_view_history_capability', $view_history_capability);
|
767 |
+
$view_history_capability = apply_filters('simple_history/view_history_capability', $view_history_capability);
|
768 |
+
|
769 |
+
return $view_history_capability;
|
770 |
+
}
|
771 |
+
|
772 |
+
/**
|
773 |
+
* Return capability required to view settings
|
774 |
+
*
|
775 |
+
* @since 2.1.5
|
776 |
+
* @return string capability
|
777 |
+
*/
|
778 |
+
public function get_view_settings_capability()
|
779 |
+
{
|
780 |
+
$view_settings_capability = 'manage_options';
|
781 |
+
$view_settings_capability = apply_filters('simple_history_view_settings_capability', $view_settings_capability);
|
782 |
+
$view_settings_capability = apply_filters('simple_history/view_settings_capability', $view_settings_capability);
|
783 |
+
|
784 |
+
return $view_settings_capability;
|
785 |
+
}
|
786 |
+
|
787 |
+
/**
|
788 |
+
* Check if the current user can clear the log
|
789 |
+
*
|
790 |
+
* @since 2.19
|
791 |
+
* @return bool
|
792 |
+
*/
|
793 |
+
public function user_can_clear_log()
|
794 |
+
{
|
795 |
+
$user_can_clear_log = apply_filters('simple_history/user_can_clear_log', true);
|
796 |
+
|
797 |
+
return $user_can_clear_log;
|
798 |
+
}
|
799 |
+
|
800 |
+
/**
|
801 |
+
* Adds default tabs to settings
|
802 |
+
*/
|
803 |
+
public function add_default_settings_tabs()
|
804 |
+
{
|
805 |
+
// Add default settings tabs
|
806 |
+
$this->arr_settings_tabs = array(
|
807 |
+
array(
|
808 |
+
'slug' => 'settings',
|
809 |
+
'name' => __('Settings', 'simple-history'),
|
810 |
+
'function' => array($this, 'settings_output_general')
|
811 |
+
)
|
812 |
+
);
|
813 |
+
|
814 |
+
if (defined('SIMPLE_HISTORY_DEV') && SIMPLE_HISTORY_DEV) {
|
815 |
+
$arr_dev_tabs = array(
|
816 |
+
array(
|
817 |
+
'slug' => 'log',
|
818 |
+
'name' => __('Log (debug)', 'simple-history'),
|
819 |
+
'function' => array($this, 'settings_output_log')
|
820 |
+
),
|
821 |
+
array(
|
822 |
+
'slug' => 'styles-example',
|
823 |
+
'name' => __('Styles example (debug)', 'simple-history'),
|
824 |
+
'function' => array($this, 'settings_output_styles_example')
|
825 |
+
)
|
826 |
+
);
|
827 |
+
|
828 |
+
$this->arr_settings_tabs = array_merge($this->arr_settings_tabs, $arr_dev_tabs);
|
829 |
+
}
|
830 |
+
}
|
831 |
+
|
832 |
+
/**
|
833 |
+
* Register an external logger so Simple History knows about it.
|
834 |
+
* Does not load the logger, so file with logger class must be loaded already.
|
835 |
+
*
|
836 |
+
* See example-logger.php for an example on how to use this.
|
837 |
+
*
|
838 |
+
* @since 2.1
|
839 |
+
*/
|
840 |
+
public function register_logger($loggerClassName)
|
841 |
+
{
|
842 |
+
$this->externalLoggers[] = $loggerClassName;
|
843 |
+
}
|
844 |
+
|
845 |
+
/**
|
846 |
+
* Register an external dropin so Simple History knows about it.
|
847 |
+
* Does not load the dropin, so file with dropin class must be loaded already.
|
848 |
+
*
|
849 |
+
* See example-dropin.php for an example on how to use this.
|
850 |
+
*
|
851 |
+
* @since 2.1
|
852 |
+
*/
|
853 |
+
public function register_dropin($dropinClassName)
|
854 |
+
{
|
855 |
+
$this->externalDropins[] = $dropinClassName;
|
856 |
+
}
|
857 |
+
|
858 |
+
/**
|
859 |
+
* Load built in loggers from all files in /loggers
|
860 |
+
* and instantiates them
|
861 |
+
*/
|
862 |
+
public function load_loggers()
|
863 |
+
{
|
864 |
+
$loggersDir = SIMPLE_HISTORY_PATH . 'loggers/';
|
865 |
+
|
866 |
+
$loggersFiles = array(
|
867 |
+
// Main loggers.
|
868 |
+
$loggersDir . 'SimpleCommentsLogger.php',
|
869 |
+
$loggersDir . 'SimpleCoreUpdatesLogger.php',
|
870 |
+
$loggersDir . 'SimpleExportLogger.php',
|
871 |
+
$loggersDir . 'SimpleLegacyLogger.php',
|
872 |
+
$loggersDir . 'SimpleLogger.php',
|
873 |
+
$loggersDir . 'SimpleMediaLogger.php',
|
874 |
+
$loggersDir . 'SimpleMenuLogger.php',
|
875 |
+
$loggersDir . 'SimpleOptionsLogger.php',
|
876 |
+
$loggersDir . 'SimplePluginLogger.php',
|
877 |
+
$loggersDir . 'SimplePostLogger.php',
|
878 |
+
$loggersDir . 'SimpleThemeLogger.php',
|
879 |
+
$loggersDir . 'SimpleUserLogger.php',
|
880 |
+
$loggersDir . 'SimpleCategoriesLogger.php',
|
881 |
+
$loggersDir . 'AvailableUpdatesLogger.php',
|
882 |
+
$loggersDir . 'FileEditsLogger.php',
|
883 |
+
$loggersDir . 'class-sh-privacy-logger.php',
|
884 |
+
$loggersDir . 'class-sh-translations-logger.php',
|
885 |
+
$loggersDir . 'class-sh-jetpack-logger.php',
|
886 |
+
|
887 |
+
// Loggers for third party plugins.
|
888 |
+
$loggersDir . 'PluginUserSwitchingLogger.php',
|
889 |
+
$loggersDir . 'PluginEnableMediaReplaceLogger.php',
|
890 |
+
$loggersDir . 'Plugin_UltimateMembers_Logger.php',
|
891 |
+
$loggersDir . 'Plugin_LimitLoginAttempts.php',
|
892 |
+
$loggersDir . 'Plugin_Redirection.php',
|
893 |
+
$loggersDir . 'Plugin_DuplicatePost.php',
|
894 |
+
$loggersDir . 'Plugin_ACF.php',
|
895 |
+
$loggersDir . 'Plugin_BeaverBuilder.php'
|
896 |
+
);
|
897 |
+
|
898 |
+
// SimpleLogger.php must be loaded first and always since the other loggers extend it.
|
899 |
+
// Include it manually so no risk of anyone using filters or similar disables it.
|
900 |
+
include_once $loggersDir . 'SimpleLogger.php';
|
901 |
+
|
902 |
+
/**
|
903 |
+
* Filter the array with absolute paths to logger files to be loaded.
|
904 |
+
*
|
905 |
+
* Each file will be loaded and will be assumed to be a logger with a classname
|
906 |
+
* the same as the filename.
|
907 |
+
*
|
908 |
+
* @since 2.0
|
909 |
+
*
|
910 |
+
* @param array $loggersFiles Array with filenames
|
911 |
+
*/
|
912 |
+
$loggersFiles = apply_filters('simple_history/loggers_files', $loggersFiles);
|
913 |
+
|
914 |
+
// Array with slug of loggers to instantiate.
|
915 |
+
// Slug of logger must also be the name of the logger class.
|
916 |
+
$arr_loggers_to_instantiate = array();
|
917 |
+
|
918 |
+
// $one_logger_file = "SimpleCommentsLogger.php", "class-privacy-logger.php", and so on.
|
919 |
+
foreach ($loggersFiles as $one_logger_file) {
|
920 |
+
$load_logger = true;
|
921 |
+
|
922 |
+
// SimpleCommentsLogger.php -> SimpleCommentsLogger.
|
923 |
+
// class-privacy-logger.php -> class-privacy-logger.
|
924 |
+
$basename_no_suffix = basename($one_logger_file, '.php');
|
925 |
+
|
926 |
+
/**
|
927 |
+
* Filter to completely skip loading of a logger
|
928 |
+
*
|
929 |
+
* @since 2.0.22
|
930 |
+
*
|
931 |
+
* @param bool if to load the logger. return false to not load it.
|
932 |
+
* @param string basename of logger, i.e. "SimpleCommentsLogger" or "class-privacy-logger"
|
933 |
+
*/
|
934 |
+
$load_logger = apply_filters('simple_history/logger/load_logger', $load_logger, $basename_no_suffix);
|
935 |
+
|
936 |
+
// If logger was SimpleLogger then force it to be loaded because for example
|
937 |
+
// custom extended plugins added later probably depends on it.
|
938 |
+
if ('SimpleLogger' === $basename_no_suffix) {
|
939 |
+
$load_logger = true;
|
940 |
+
}
|
941 |
+
|
942 |
+
if (! $load_logger) {
|
943 |
+
continue;
|
944 |
+
}
|
945 |
+
|
946 |
+
include_once $one_logger_file;
|
947 |
+
|
948 |
+
$arr_loggers_to_instantiate[] = $basename_no_suffix;
|
949 |
+
}
|
950 |
+
|
951 |
+
/**
|
952 |
+
* Action that plugins can use to add their custom loggers.
|
953 |
+
* See register_logger() for more info.
|
954 |
+
*
|
955 |
+
* @since 2.1
|
956 |
+
*
|
957 |
+
* @param SimpleHistory instance
|
958 |
+
*/
|
959 |
+
do_action('simple_history/add_custom_logger', $this);
|
960 |
+
|
961 |
+
$arr_loggers_to_instantiate = array_merge($arr_loggers_to_instantiate, $this->externalLoggers);
|
962 |
+
|
963 |
+
/**
|
964 |
+
* Filter the array with names of loggers to instantiate.
|
965 |
+
*
|
966 |
+
* Array
|
967 |
+
* (
|
968 |
+
* [0] => SimpleCommentsLogger
|
969 |
+
* [1] => SimpleCoreUpdatesLogger
|
970 |
+
* ...
|
971 |
+
* )
|
972 |
+
*
|
973 |
+
* @since 2.0
|
974 |
+
*
|
975 |
+
* @param array $arr_loggers_to_instantiate Array with class names
|
976 |
+
*/
|
977 |
+
$arr_loggers_to_instantiate = apply_filters(
|
978 |
+
'simple_history/loggers_to_instantiate',
|
979 |
+
$arr_loggers_to_instantiate
|
980 |
+
);
|
981 |
+
|
982 |
+
// Instantiate each logger.
|
983 |
+
foreach ($arr_loggers_to_instantiate as $one_logger_name) {
|
984 |
+
// Detect logger class name.
|
985 |
+
$logger_class_name = null;
|
986 |
+
|
987 |
+
if (class_exists($one_logger_name)) {
|
988 |
+
// Logger name is "SimpleCommentsLogger".
|
989 |
+
$logger_class_name = $one_logger_name;
|
990 |
+
} else {
|
991 |
+
// Check if class is "class-privacy-logger".
|
992 |
+
$logger_snaked_name = substr($one_logger_name, 6);
|
993 |
+
// "privacy-logger" -> "privacy_logger" -> Privacy_Logger
|
994 |
+
$logger_snaked_name = str_replace('-', '_', $logger_snaked_name);
|
995 |
+
$logger_snaked_name = sh_ucwords($logger_snaked_name, '_');
|
996 |
+
|
997 |
+
if (class_exists($logger_snaked_name)) {
|
998 |
+
$logger_class_name = $logger_snaked_name;
|
999 |
+
}
|
1000 |
+
}
|
1001 |
+
|
1002 |
+
// Continue to load next logger if no valid logger class found.
|
1003 |
+
if (! $logger_class_name) {
|
1004 |
+
continue;
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
// Init found logger class.
|
1008 |
+
$logger_instance = new $logger_class_name($this);
|
1009 |
+
|
1010 |
+
if (! is_subclass_of($logger_instance, 'SimpleLogger') && ! is_a($logger_instance, 'SimpleLogger')) {
|
1011 |
+
continue;
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
$logger_instance->loaded();
|
1015 |
+
|
1016 |
+
// Tell gettext-filter to add untranslated messages.
|
1017 |
+
$this->doFilterGettext = true;
|
1018 |
+
$this->doFilterGettext_currentLogger = $logger_instance;
|
1019 |
+
|
1020 |
+
$logger_info = $logger_instance->getInfo();
|
1021 |
+
|
1022 |
+
// Check so no logger has a logger slug with more than 30 chars,
|
1023 |
+
// because db column is only 30 chars.
|
1024 |
+
if (strlen($logger_instance->slug) > 30) {
|
1025 |
+
add_action('admin_notices', array( $this, 'admin_notice_logger_slug_to_long' ));
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
// Un-tell gettext filter.
|
1029 |
+
$this->doFilterGettext = false;
|
1030 |
+
$this->doFilterGettext_currentLogger = null;
|
1031 |
+
|
1032 |
+
// LoggerInfo contains all messages, both translated an not, by key.
|
1033 |
+
// Add messages to the loggerInstance.
|
1034 |
+
$loopNum = 0;
|
1035 |
+
|
1036 |
+
$arr_messages_by_message_key = array();
|
1037 |
+
|
1038 |
+
if (isset($logger_info['messages']) && is_array($logger_info['messages'])) {
|
1039 |
+
foreach ((array) $logger_info['messages'] as $message_key => $message_translated) {
|
1040 |
+
// Find message in array with both translated and non translated strings.
|
1041 |
+
foreach ($logger_instance->messages as $one_message_with_translation_info) {
|
1042 |
+
if ($message_translated == $one_message_with_translation_info['translated_text']) {
|
1043 |
+
$arr_messages_by_message_key[ $message_key ] = $one_message_with_translation_info;
|
1044 |
+
continue;
|
1045 |
+
}
|
1046 |
+
}
|
1047 |
+
}
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
$logger_instance->messages = $arr_messages_by_message_key;
|
1051 |
+
|
1052 |
+
// Add logger to array of loggers.
|
1053 |
+
$this->instantiatedLoggers[ $logger_instance->slug ] = array(
|
1054 |
+
'name' => $logger_info['name'],
|
1055 |
+
'instance' => $logger_instance
|
1056 |
+
);
|
1057 |
+
}// End foreach().
|
1058 |
+
|
1059 |
+
do_action('simple_history/loggers_loaded');
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
/**
|
1063 |
+
* Load built in dropins from all files in /dropins
|
1064 |
+
* and instantiates them
|
1065 |
+
*/
|
1066 |
+
public function load_dropins()
|
1067 |
+
{
|
1068 |
+
$dropinsDir = SIMPLE_HISTORY_PATH . 'dropins/';
|
1069 |
+
|
1070 |
+
$dropinsFiles = array(
|
1071 |
+
$dropinsDir . 'SimpleHistoryPluginPatchesDropin.php',
|
1072 |
+
$dropinsDir . 'SimpleHistoryDonateDropin.php',
|
1073 |
+
$dropinsDir . 'SimpleHistoryExportDropin.php',
|
1074 |
+
$dropinsDir . 'SimpleHistoryFilterDropin.php',
|
1075 |
+
$dropinsDir . 'SimpleHistoryIpInfoDropin.php',
|
1076 |
+
$dropinsDir . 'SimpleHistoryNewRowsNotifier.php',
|
1077 |
+
$dropinsDir . 'SimpleHistoryRSSDropin.php',
|
1078 |
+
$dropinsDir . 'SimpleHistorySettingsLogtestDropin.php',
|
1079 |
+
$dropinsDir . 'SimpleHistorySettingsStatsDropin.php',
|
1080 |
+
$dropinsDir . 'SimpleHistorySettingsDebugDropin.php',
|
1081 |
+
$dropinsDir . 'SimpleHistorySidebarDropin.php',
|
1082 |
+
$dropinsDir . 'SimpleHistorySidebarStats.php',
|
1083 |
+
$dropinsDir . 'SimpleHistorySidebarSettings.php',
|
1084 |
+
$dropinsDir . 'SimpleHistoryWPCLIDropin.php',
|
1085 |
+
$dropinsDir . 'SimpleHistoryDebugDropin.php',
|
1086 |
+
);
|
1087 |
+
|
1088 |
+
/**
|
1089 |
+
* Filter the array with absolute paths to files as returned by glob function.
|
1090 |
+
* Each file will be loaded and will be assumed to be a dropin with a classname
|
1091 |
+
* the same as the filename.
|
1092 |
+
*
|
1093 |
+
* @since 2.0
|
1094 |
+
*
|
1095 |
+
* @param array $dropinsFiles Array with filenames
|
1096 |
+
*/
|
1097 |
+
$dropinsFiles = apply_filters('simple_history/dropins_files', $dropinsFiles);
|
1098 |
+
|
1099 |
+
$arrDropinsToInstantiate = array();
|
1100 |
+
|
1101 |
+
foreach ($dropinsFiles as $oneDropinFile) {
|
1102 |
+
// path/path/simplehistory/dropins/SimpleHistoryDonateDropin.php => SimpleHistoryDonateDropin
|
1103 |
+
$oneDropinFileBasename = basename($oneDropinFile, '.php');
|
1104 |
+
|
1105 |
+
$load_dropin = true;
|
1106 |
+
|
1107 |
+
/**
|
1108 |
+
* Filter to completely skip loading of dropin
|
1109 |
+
* complete filer name will be like:
|
1110 |
+
* simple_history/dropin/load_dropin_SimpleHistoryRSSDropin
|
1111 |
+
*
|
1112 |
+
* @since 2.0.6
|
1113 |
+
*
|
1114 |
+
* @param bool if to load the dropin. return false to not load it.
|
1115 |
+
*/
|
1116 |
+
$load_dropin = apply_filters("simple_history/dropin/load_dropin_{$oneDropinFileBasename}", $load_dropin);
|
1117 |
+
|
1118 |
+
/**
|
1119 |
+
* Filter to completely skip loading of a dropin
|
1120 |
+
*
|
1121 |
+
* @since 2.0.22
|
1122 |
+
*
|
1123 |
+
* @param bool if to load the dropin. return false to not load it.
|
1124 |
+
* @param string slug of dropin
|
1125 |
+
*/
|
1126 |
+
$load_dropin = apply_filters('simple_history/dropin/load_dropin', $load_dropin, $oneDropinFileBasename);
|
1127 |
+
|
1128 |
+
if (! $load_dropin) {
|
1129 |
+
continue;
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
include_once $oneDropinFile;
|
1133 |
+
|
1134 |
+
$arrDropinsToInstantiate[] = $oneDropinFileBasename;
|
1135 |
+
}// End foreach().
|
1136 |
+
|
1137 |
+
/**
|
1138 |
+
* Action that dropins can use to add their custom loggers.
|
1139 |
+
* See register_dropin() for more info.
|
1140 |
+
*
|
1141 |
+
* @since 2.3.2
|
1142 |
+
*
|
1143 |
+
* @param array $arrDropinsToInstantiate Array with class names
|
1144 |
+
*/
|
1145 |
+
do_action('simple_history/add_custom_dropin', $this);
|
1146 |
+
|
1147 |
+
/**
|
1148 |
+
* Filter the array with names of dropin to instantiate.
|
1149 |
+
*
|
1150 |
+
* @since 2.0
|
1151 |
+
*
|
1152 |
+
* @param array $arrDropinsToInstantiate Array with class names
|
1153 |
+
*/
|
1154 |
+
$arrDropinsToInstantiate = apply_filters('simple_history/dropins_to_instantiate', $arrDropinsToInstantiate);
|
1155 |
+
|
1156 |
+
$arrDropinsToInstantiate = array_merge($arrDropinsToInstantiate, $this->externalDropins);
|
1157 |
+
|
1158 |
+
// Instantiate each dropin
|
1159 |
+
foreach ($arrDropinsToInstantiate as $oneDropinName) {
|
1160 |
+
if (! class_exists($oneDropinName)) {
|
1161 |
+
continue;
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
$this->instantiatedDropins[ $oneDropinName ] = array(
|
1165 |
+
'name' => $oneDropinName,
|
1166 |
+
'instance' => new $oneDropinName($this)
|
1167 |
+
);
|
1168 |
+
}
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
/**
|
1172 |
+
* Gets the pager size,
|
1173 |
+
* i.e. the number of items to show on each page in the history
|
1174 |
+
*
|
1175 |
+
* @return int
|
1176 |
+
*/
|
1177 |
+
public function get_pager_size()
|
1178 |
+
{
|
1179 |
+
$pager_size = get_option('simple_history_pager_size', 20);
|
1180 |
+
|
1181 |
+
/**
|
1182 |
+
* Filter the pager size setting
|
1183 |
+
*
|
1184 |
+
* @since 2.0
|
1185 |
+
*
|
1186 |
+
* @param int $pager_size
|
1187 |
+
*/
|
1188 |
+
$pager_size = apply_filters('simple_history/pager_size', $pager_size);
|
1189 |
+
|
1190 |
+
return $pager_size;
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
/**
|
1194 |
+
* Gets the pager size,
|
1195 |
+
* i.e. the number of items to show on each page in the history
|
1196 |
+
*
|
1197 |
+
* @since 2.12
|
1198 |
+
* @return int
|
1199 |
+
*/
|
1200 |
+
public function get_pager_size_dashboard()
|
1201 |
+
{
|
1202 |
+
$pager_size = get_option('simple_history_pager_size_dashboard', 5);
|
1203 |
+
|
1204 |
+
/**
|
1205 |
+
* Filter the pager size setting
|
1206 |
+
*
|
1207 |
+
* @since 2.12
|
1208 |
+
*
|
1209 |
+
* @param int $pager_size
|
1210 |
+
*/
|
1211 |
+
$pager_size = apply_filters('simple_history/pager_size_dashboard', $pager_size);
|
1212 |
+
|
1213 |
+
return $pager_size;
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
/**
|
1217 |
+
* Show a link to our settings page on the Plugins -> Installed Plugins screen
|
1218 |
+
*/
|
1219 |
+
public function plugin_action_links($actions, $b, $c, $d)
|
1220 |
+
{
|
1221 |
+
// Only add link if user has the right to view the settings page
|
1222 |
+
if (! current_user_can($this->get_view_settings_capability())) {
|
1223 |
+
return $actions;
|
1224 |
+
}
|
1225 |
+
|
1226 |
+
$settings_page_url = menu_page_url(SimpleHistory::SETTINGS_MENU_SLUG, 0);
|
1227 |
+
|
1228 |
+
if (empty($actions)) {
|
1229 |
+
// Create array if actions is empty (and therefore is assumed to be a string by PHP & results in PHP 7.1+ fatal error due to trying to make array modifications on what's assumed to be a string)
|
1230 |
+
$actions = array();
|
1231 |
+
} elseif (is_string($actions)) {
|
1232 |
+
// Convert the string (which it might've been retrieved as) to an array for future use as an array
|
1233 |
+
$actions = array( $actions );
|
1234 |
+
}
|
1235 |
+
$actions[] = "<a href='$settings_page_url'>" . __('Settings', 'simple-history') . '</a>';
|
1236 |
+
|
1237 |
+
return $actions;
|
1238 |
+
}
|
1239 |
+
|
1240 |
+
/**
|
1241 |
+
* Maybe add a dashboard widget,
|
1242 |
+
* requires current user to have view history capability
|
1243 |
+
* and a setting to show dashboard to be set
|
1244 |
+
*/
|
1245 |
+
public function add_dashboard_widget()
|
1246 |
+
{
|
1247 |
+
if ($this->setting_show_on_dashboard() && current_user_can($this->get_view_history_capability())) {
|
1248 |
+
/**
|
1249 |
+
* Filter to determine if history page should be added to page below dashboard or not
|
1250 |
+
*
|
1251 |
+
* @since 2.0.23
|
1252 |
+
*
|
1253 |
+
* @param bool Show the page or not
|
1254 |
+
*/
|
1255 |
+
$show_dashboard_widget = apply_filters('simple_history/show_dashboard_widget', true);
|
1256 |
+
|
1257 |
+
if ($show_dashboard_widget) {
|
1258 |
+
wp_add_dashboard_widget(
|
1259 |
+
'simple_history_dashboard_widget',
|
1260 |
+
__('Simple History', 'simple-history'),
|
1261 |
+
array($this, 'dashboard_widget_output')
|
1262 |
+
);
|
1263 |
+
}
|
1264 |
+
}
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
/**
|
1268 |
+
* Output html for the dashboard widget
|
1269 |
+
*/
|
1270 |
+
public function dashboard_widget_output()
|
1271 |
+
{
|
1272 |
+
$pager_size = $this->get_pager_size_dashboard();
|
1273 |
+
|
1274 |
+
/**
|
1275 |
+
* Filter the pager size setting for the dashboard
|
1276 |
+
*
|
1277 |
+
* @since 2.0
|
1278 |
+
*
|
1279 |
+
* @param int $pager_size
|
1280 |
+
*/
|
1281 |
+
$pager_size = apply_filters('simple_history/dashboard_pager_size', $pager_size);
|
1282 |
+
|
1283 |
+
do_action('simple_history/dashboard/before_gui', $this);
|
1284 |
+
?>
|
1285 |
+
<div class="SimpleHistoryGui"
|
1286 |
+
data-pager-size='<?php echo $pager_size; ?>'
|
1287 |
+
></div>
|
1288 |
+
<?php
|
1289 |
+
}
|
1290 |
+
|
1291 |
+
public function is_on_our_own_pages($hook = '')
|
1292 |
+
{
|
1293 |
+
$current_screen = get_current_screen();
|
1294 |
+
|
1295 |
+
$basePrefix = apply_filters('simple_history/admin_location', 'index');
|
1296 |
+
$basePrefix = ( $basePrefix === 'index' ) ? 'dashboard' : $basePrefix;
|
1297 |
+
|
1298 |
+
if ($current_screen && $current_screen->base == 'settings_page_' . SimpleHistory::SETTINGS_MENU_SLUG) {
|
1299 |
+
return true;
|
1300 |
+
} elseif ($current_screen && $current_screen->base == $basePrefix. '_page_simple_history_page') {
|
1301 |
+
return true;
|
1302 |
+
} elseif (( $hook == 'settings_page_' . SimpleHistory::SETTINGS_MENU_SLUG ) || ( $this->setting_show_on_dashboard() && $hook == 'index.php' ) || ( $this->setting_show_as_page() && $hook == $basePrefix . '_page_simple_history_page' )) {
|
1303 |
+
return true;
|
1304 |
+
} elseif ($current_screen && $current_screen->base == 'dashboard' && $this->setting_show_on_dashboard()) {
|
1305 |
+
return true;
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
return false;
|
1309 |
+
}
|
1310 |
+
|
1311 |
+
/**
|
1312 |
+
* Enqueue styles and scripts for Simple History but only to our own pages.
|
1313 |
+
*
|
1314 |
+
* Only adds scripts to pages where the log is shown or the settings page.
|
1315 |
+
*/
|
1316 |
+
public function enqueue_admin_scripts($hook)
|
1317 |
+
{
|
1318 |
+
if ($this->is_on_our_own_pages()) {
|
1319 |
+
add_thickbox();
|
1320 |
+
|
1321 |
+
wp_enqueue_style(
|
1322 |
+
'simple_history_styles',
|
1323 |
+
SIMPLE_HISTORY_DIR_URL . 'css/styles.css',
|
1324 |
+
false,
|
1325 |
+
SIMPLE_HISTORY_VERSION
|
1326 |
+
);
|
1327 |
+
wp_enqueue_script(
|
1328 |
+
'simple_history_script',
|
1329 |
+
SIMPLE_HISTORY_DIR_URL . 'js/scripts.js',
|
1330 |
+
array('jquery', 'backbone', 'wp-util'),
|
1331 |
+
SIMPLE_HISTORY_VERSION,
|
1332 |
+
true
|
1333 |
+
);
|
1334 |
+
|
1335 |
+
wp_enqueue_script('select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.full.min.js', array( 'jquery' ));
|
1336 |
+
wp_enqueue_style('select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.min.css');
|
1337 |
+
|
1338 |
+
// Translations that we use in JavaScript
|
1339 |
+
wp_localize_script('simple_history_script', 'simple_history_script_vars', array(
|
1340 |
+
'settingsConfirmClearLog' => __('Remove all log items?', 'simple-history'),
|
1341 |
+
'pagination' => array(
|
1342 |
+
'goToTheFirstPage' => __('Go to the first page', 'simple-history'),
|
1343 |
+
'goToThePrevPage' => __('Go to the previous page', 'simple-history'),
|
1344 |
+
'goToTheNextPage' => __('Go to the next page', 'simple-history'),
|
1345 |
+
'goToTheLastPage' => __('Go to the last page', 'simple-history'),
|
1346 |
+
'currentPage' => __('Current page', 'simple-history')
|
1347 |
+
),
|
1348 |
+
'loadLogAPIError' => __('Oups, the log could not be loaded right now.', 'simple-history'),
|
1349 |
+
'ajaxLoadError' => __(
|
1350 |
+
'Hm, the log could not be loaded right now. Perhaps another plugin is giving some errors. Anyway, below is the output I got from the server.',
|
1351 |
+
'simple-history'
|
1352 |
+
),
|
1353 |
+
'logNoHits' => __('Your search did not match any history events.', 'simple-history')
|
1354 |
+
));
|
1355 |
+
|
1356 |
+
// Call plugins adminCSS-method, so they can add their CSS
|
1357 |
+
foreach ($this->instantiatedLoggers as $one_logger) {
|
1358 |
+
if (method_exists($one_logger['instance'], 'adminCSS')) {
|
1359 |
+
$one_logger['instance']->adminCSS();
|
1360 |
+
}
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
// Add timeago.js
|
1364 |
+
wp_enqueue_script(
|
1365 |
+
'timeago',
|
1366 |
+
SIMPLE_HISTORY_DIR_URL . 'js/timeago/jquery.timeago.js',
|
1367 |
+
array('jquery'),
|
1368 |
+
'1.5.2',
|
1369 |
+
true
|
1370 |
+
);
|
1371 |
+
|
1372 |
+
// Determine current locale to load timeago locale
|
1373 |
+
$locale = strtolower(substr(get_locale(), 0, 2));
|
1374 |
+
$locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/timeago/locales/jquery.timeago.%s.js';
|
1375 |
+
$locale_dir_path = SIMPLE_HISTORY_PATH . 'js/timeago/locales/jquery.timeago.%s.js';
|
1376 |
+
|
1377 |
+
// Only enqueue if locale-file exists on file system
|
1378 |
+
if (file_exists(sprintf($locale_dir_path, $locale))) {
|
1379 |
+
wp_enqueue_script('timeago-locale', sprintf($locale_url_path, $locale), array( 'jquery' ), '1.5.2', true);
|
1380 |
+
} else {
|
1381 |
+
wp_enqueue_script('timeago-locale', sprintf($locale_url_path, 'en'), array( 'jquery' ), '1.5.2', true);
|
1382 |
+
}
|
1383 |
+
// end add timeago
|
1384 |
+
// Load Select2 locale
|
1385 |
+
$locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/select2/i18n/%s.js';
|
1386 |
+
$locale_dir_path = SIMPLE_HISTORY_PATH . 'js/select2/i18n/%s.js';
|
1387 |
+
|
1388 |
+
if (file_exists(sprintf($locale_dir_path, $locale))) {
|
1389 |
+
wp_enqueue_script('select2-locale', sprintf($locale_url_path, $locale), array( 'jquery' ), '3.5.1', true);
|
1390 |
+
}
|
1391 |
+
|
1392 |
+
/**
|
1393 |
+
* Fires when the admin scripts have been enqueued.
|
1394 |
+
* Only fires on any of the pages where Simple History is used
|
1395 |
+
*
|
1396 |
+
* @since 2.0
|
1397 |
+
*
|
1398 |
+
* @param SimpleHistory $SimpleHistory This class.
|
1399 |
+
*/
|
1400 |
+
do_action('simple_history/enqueue_admin_scripts', $this);
|
1401 |
+
}// End if().
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
public function filter_option_page_capability($capability)
|
1405 |
+
{
|
1406 |
+
return $capability;
|
1407 |
+
}
|
1408 |
+
|
1409 |
+
/**
|
1410 |
+
* Check if plugin version have changed, i.e. has been upgraded
|
1411 |
+
* If upgrade is detected then maybe modify database and so on for that version
|
1412 |
+
*/
|
1413 |
+
public function check_for_upgrade()
|
1414 |
+
{
|
1415 |
+
global $wpdb;
|
1416 |
+
|
1417 |
+
$db_version = get_option('simple_history_db_version');
|
1418 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
1419 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
1420 |
+
$first_install = false;
|
1421 |
+
|
1422 |
+
// If no db_version is set then this
|
1423 |
+
// is a version of Simple History < 0.4
|
1424 |
+
// or it's a first install
|
1425 |
+
// Fix database not using UTF-8
|
1426 |
+
if (false === $db_version || intval($db_version) == 0) {
|
1427 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1428 |
+
|
1429 |
+
// Table creation, used to be in register_activation_hook
|
1430 |
+
// We change the varchar size to add one num just to force update of encoding. dbdelta didn't see it otherwise.
|
1431 |
+
$sql =
|
1432 |
+
'CREATE TABLE ' .
|
1433 |
+
$table_name .
|
1434 |
+
' (
|
1435 |
+
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1436 |
+
date datetime NOT NULL,
|
1437 |
+
PRIMARY KEY (id)
|
1438 |
+
) CHARACTER SET=utf8;';
|
1439 |
+
|
1440 |
+
// Upgrade db / fix utf for varchars
|
1441 |
+
dbDelta($sql);
|
1442 |
+
|
1443 |
+
// Fix UTF-8 for table
|
1444 |
+
$sql = sprintf('alter table %1$s charset=utf8;', $table_name);
|
1445 |
+
$wpdb->query($sql);
|
1446 |
+
|
1447 |
+
$db_version_prev = $db_version;
|
1448 |
+
$db_version = 1;
|
1449 |
+
|
1450 |
+
update_option('simple_history_db_version', $db_version);
|
1451 |
+
|
1452 |
+
// We are not 100% sure that this is a first install,
|
1453 |
+
// but it is at least a very old version that is being updated
|
1454 |
+
$first_install = true;
|
1455 |
+
} // End if().
|
1456 |
+
|
1457 |
+
// If db version is 1 then upgrade to 2
|
1458 |
+
// Version 2 added the action_description column
|
1459 |
+
if (1 == intval($db_version)) {
|
1460 |
+
// V2 used to add column "action_description"
|
1461 |
+
// but it's not used any more so don't do i
|
1462 |
+
$db_version_prev = $db_version;
|
1463 |
+
$db_version = 2;
|
1464 |
+
|
1465 |
+
update_option('simple_history_db_version', $db_version);
|
1466 |
+
}
|
1467 |
+
|
1468 |
+
// Check that all options we use are set to their defaults, if they miss value
|
1469 |
+
// Each option that is missing a value will make a sql call otherwise = unnecessary
|
1470 |
+
$arr_options = array(
|
1471 |
+
array(
|
1472 |
+
'name' => 'simple_history_show_as_page',
|
1473 |
+
'default_value' => 1
|
1474 |
+
),
|
1475 |
+
array(
|
1476 |
+
'name' => 'simple_history_show_on_dashboard',
|
1477 |
+
'default_value' => 1
|
1478 |
+
)
|
1479 |
+
);
|
1480 |
+
|
1481 |
+
foreach ($arr_options as $one_option) {
|
1482 |
+
if (false === ( $option_value = get_option($one_option['name']) )) {
|
1483 |
+
// Value is not set in db, so set it to a default
|
1484 |
+
update_option($one_option['name'], $one_option['default_value']);
|
1485 |
+
}
|
1486 |
+
}
|
1487 |
+
|
1488 |
+
/**
|
1489 |
+
* If db_version is 2 then upgrade to 3:
|
1490 |
+
* - Add some fields to existing table wp_simple_history_contexts
|
1491 |
+
* - Add all new table wp_simple_history_contexts
|
1492 |
+
*
|
1493 |
+
* @since 2.0
|
1494 |
+
*/
|
1495 |
+
if (2 == intval($db_version)) {
|
1496 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1497 |
+
|
1498 |
+
// Update old table
|
1499 |
+
$sql = "
|
1500 |
+
CREATE TABLE {$table_name} (
|
1501 |
+
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1502 |
+
date datetime NOT NULL,
|
1503 |
+
logger varchar(30) DEFAULT NULL,
|
1504 |
+
level varchar(20) DEFAULT NULL,
|
1505 |
+
message varchar(255) DEFAULT NULL,
|
1506 |
+
occasionsID varchar(32) DEFAULT NULL,
|
1507 |
+
initiator varchar(16) DEFAULT NULL,
|
1508 |
+
PRIMARY KEY (id),
|
1509 |
+
KEY date (date),
|
1510 |
+
KEY loggerdate (logger,date)
|
1511 |
+
) CHARSET=utf8;";
|
1512 |
+
|
1513 |
+
dbDelta($sql);
|
1514 |
+
|
1515 |
+
// Add context table
|
1516 |
+
$sql = "
|
1517 |
+
CREATE TABLE IF NOT EXISTS {$table_name_contexts} (
|
1518 |
+
context_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
1519 |
+
history_id bigint(20) unsigned NOT NULL,
|
1520 |
+
`key` varchar(255) DEFAULT NULL,
|
1521 |
+
value longtext,
|
1522 |
+
PRIMARY KEY (context_id),
|
1523 |
+
KEY history_id (history_id),
|
1524 |
+
KEY `key` (`key`)
|
1525 |
+
) CHARSET=utf8;
|
1526 |
+
";
|
1527 |
+
|
1528 |
+
$wpdb->query($sql);
|
1529 |
+
|
1530 |
+
$db_version_prev = $db_version;
|
1531 |
+
$db_version = 3;
|
1532 |
+
update_option('simple_history_db_version', $db_version);
|
1533 |
+
|
1534 |
+
// Update possible old items to use SimpleLegacyLogger
|
1535 |
+
$sql = sprintf(
|
1536 |
+
'
|
1537 |
+
UPDATE %1$s
|
1538 |
+
SET
|
1539 |
+
logger = "SimpleLegacyLogger",
|
1540 |
+
level = "info"
|
1541 |
+
WHERE logger IS NULL
|
1542 |
+
',
|
1543 |
+
$table_name
|
1544 |
+
);
|
1545 |
+
|
1546 |
+
$wpdb->query($sql);
|
1547 |
+
|
1548 |
+
// Say welcome, however loggers are not added this early so we need to
|
1549 |
+
// use a filter to load it later
|
1550 |
+
add_action('simple_history/loggers_loaded', array( $this, 'addWelcomeLogMessage' ));
|
1551 |
+
} // End if().
|
1552 |
+
|
1553 |
+
/**
|
1554 |
+
* If db version = 3
|
1555 |
+
* then we need to update database to allow null values for some old columns
|
1556 |
+
* that used to work in pre wp 4.1 beta, but since 4.1 wp uses STRICT_ALL_TABLES
|
1557 |
+
* WordPress Commit: https://github.com/WordPress/WordPress/commit/f17d168a0f72211a9bfd9d3fa680713069871bb6
|
1558 |
+
*
|
1559 |
+
* @since 2.0
|
1560 |
+
*/
|
1561 |
+
if (3 == intval($db_version)) {
|
1562 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1563 |
+
|
1564 |
+
// If old columns exist = this is an old install, then modify the columns so we still can keep them
|
1565 |
+
// we want to keep them because user may have logged items that they want to keep
|
1566 |
+
$db_cools = $wpdb->get_col("DESCRIBE $table_name");
|
1567 |
+
|
1568 |
+
if (in_array('action', $db_cools)) {
|
1569 |
+
$sql = sprintf(
|
1570 |
+
'
|
1571 |
+
ALTER TABLE %1$s
|
1572 |
+
MODIFY `action` varchar(255) NULL,
|
1573 |
+
MODIFY `object_type` varchar(255) NULL,
|
1574 |
+
MODIFY `object_subtype` varchar(255) NULL,
|
1575 |
+
MODIFY `user_id` int(10) NULL,
|
1576 |
+
MODIFY `object_id` int(10) NULL,
|
1577 |
+
MODIFY `object_name` varchar(255) NULL
|
1578 |
+
',
|
1579 |
+
$table_name
|
1580 |
+
);
|
1581 |
+
$wpdb->query($sql);
|
1582 |
+
}
|
1583 |
+
|
1584 |
+
$db_version_prev = $db_version;
|
1585 |
+
$db_version = 4;
|
1586 |
+
|
1587 |
+
update_option('simple_history_db_version', $db_version);
|
1588 |
+
} // End if().
|
1589 |
+
|
1590 |
+
// Some installs on 2.2.2 got failed installs
|
1591 |
+
// We detect these by checking for db_version and then running the install stuff again
|
1592 |
+
if (4 == intval($db_version)) {
|
1593 |
+
if (! $this->does_database_have_data()) {
|
1594 |
+
// not ok, decrease db number so installs will run again and hopefully fix things
|
1595 |
+
$db_version = 0;
|
1596 |
+
} else {
|
1597 |
+
// all looks ok, upgrade to db version 5, so this part is not done again
|
1598 |
+
$db_version = 5;
|
1599 |
+
}
|
1600 |
+
|
1601 |
+
update_option('simple_history_db_version', $db_version);
|
1602 |
+
}
|
1603 |
+
} // end check_for_upgrade
|
1604 |
+
|
1605 |
+
/**
|
1606 |
+
* Check if the database has data/rows
|
1607 |
+
*
|
1608 |
+
* @since 2.1.6
|
1609 |
+
* @return bool True if database is not empty, false if database is empty = contains no data
|
1610 |
+
*/
|
1611 |
+
public function does_database_have_data()
|
1612 |
+
{
|
1613 |
+
global $wpdb;
|
1614 |
+
|
1615 |
+
$tableprefix = $wpdb->prefix;
|
1616 |
+
|
1617 |
+
$simple_history_table = SimpleHistory::DBTABLE;
|
1618 |
+
$simple_history_context_table = SimpleHistory::DBTABLE_CONTEXTS;
|
1619 |
+
|
1620 |
+
$sql_data_exists = "SELECT id AS id_exists FROM {$tableprefix}{$simple_history_table} LIMIT 1";
|
1621 |
+
$data_exists = (bool) $wpdb->get_var($sql_data_exists, 0);
|
1622 |
+
|
1623 |
+
return $data_exists;
|
1624 |
+
}
|
1625 |
+
|
1626 |
+
/**
|
1627 |
+
* Greet users to version 2!
|
1628 |
+
* Is only called after database has been upgraded, so only on first install (or upgrade).
|
1629 |
+
* Not called after only plugin activation.
|
1630 |
+
*/
|
1631 |
+
public function addWelcomeLogMessage()
|
1632 |
+
{
|
1633 |
+
$db_data_exists = $this->does_database_have_data();
|
1634 |
+
// $db_data_exists = false;
|
1635 |
+
$pluginLogger = $this->getInstantiatedLoggerBySlug('SimplePluginLogger');
|
1636 |
+
if ($pluginLogger) {
|
1637 |
+
// Add plugin installed message
|
1638 |
+
$context = array(
|
1639 |
+
'plugin_name' => 'Simple History',
|
1640 |
+
'plugin_description' =>
|
1641 |
+
'Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.',
|
1642 |
+
'plugin_url' => 'http://simple-history.com',
|
1643 |
+
'plugin_version' => SIMPLE_HISTORY_VERSION,
|
1644 |
+
'plugin_author' => 'Pär Thernström'
|
1645 |
+
);
|
1646 |
+
|
1647 |
+
$pluginLogger->infoMessage('plugin_installed', $context);
|
1648 |
+
|
1649 |
+
// Add plugin activated message
|
1650 |
+
$context['plugin_slug'] = 'simple-history';
|
1651 |
+
$context['plugin_title'] = '<a href="http://simple-history.com/">Simple History</a>';
|
1652 |
+
|
1653 |
+
$pluginLogger->infoMessage('plugin_activated', $context);
|
1654 |
+
}
|
1655 |
+
|
1656 |
+
if (! $db_data_exists) {
|
1657 |
+
$welcome_message_1 = __(
|
1658 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1659 |
Welcome to Simple History!
|
1660 |
|
1661 |
This is the main history feed. It will contain events that this plugin has logged.
|
1662 |
',
|
1663 |
+
'simple-history'
|
1664 |
+
);
|
1665 |
|
1666 |
+
$welcome_message_2 = __(
|
1667 |
+
'
|
1668 |
Because Simple History was just recently installed, this feed does not contain much events yet. But keep the plugin activated and soon you will see detailed information about page edits, plugin updates, user logins, and much more.
|
1669 |
',
|
1670 |
+
'simple-history'
|
1671 |
+
);
|
1672 |
+
|
1673 |
+
SimpleLogger()->info($welcome_message_2, array(
|
1674 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS
|
1675 |
+
));
|
1676 |
+
|
1677 |
+
SimpleLogger()->info($welcome_message_1, array(
|
1678 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS
|
1679 |
+
));
|
1680 |
+
}
|
1681 |
+
}
|
1682 |
+
|
1683 |
+
public function registerSettingsTab($arr_tab_settings)
|
1684 |
+
{
|
1685 |
+
$this->arr_settings_tabs[] = $arr_tab_settings;
|
1686 |
+
}
|
1687 |
+
|
1688 |
+
public function getSettingsTabs()
|
1689 |
+
{
|
1690 |
+
return $this->arr_settings_tabs;
|
1691 |
+
}
|
1692 |
+
|
1693 |
+
/**
|
1694 |
+
* Output HTML for the settings page
|
1695 |
+
* Called from add_options_page
|
1696 |
+
*/
|
1697 |
+
public function settings_page_output()
|
1698 |
+
{
|
1699 |
+
$arr_settings_tabs = $this->getSettingsTabs(); ?>
|
1700 |
+
<div class="wrap">
|
1701 |
+
|
1702 |
+
<h1 class="SimpleHistoryPageHeadline">
|
1703 |
+
<div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
|
1704 |
+
<?php _e('Simple History Settings', 'simple-history'); ?>
|
1705 |
+
</h1>
|
1706 |
+
|
1707 |
+
<?php
|
1708 |
+
$active_tab = isset($_GET['selected-tab']) ? $_GET['selected-tab'] : 'settings';
|
1709 |
+
$settings_base_url = menu_page_url(SimpleHistory::SETTINGS_MENU_SLUG, 0);
|
1710 |
+
?>
|
1711 |
+
|
1712 |
+
<h2 class="nav-tab-wrapper">
|
1713 |
+
<?php foreach ($arr_settings_tabs as $one_tab) {
|
1714 |
+
$tab_slug = $one_tab['slug'];
|
1715 |
+
|
1716 |
+
printf(
|
1717 |
+
'<a href="%3$s" class="nav-tab %4$s">%1$s</a>',
|
1718 |
+
$one_tab['name'], // 1
|
1719 |
+
$tab_slug, // 2
|
1720 |
+
esc_url(add_query_arg('selected-tab', $tab_slug, $settings_base_url)), // 3
|
1721 |
+
$active_tab == $tab_slug ? 'nav-tab-active' : ''// 4
|
1722 |
+
);
|
1723 |
+
} ?>
|
1724 |
+
</h2>
|
1725 |
+
|
1726 |
+
<?php
|
1727 |
+
// Output contents for selected tab
|
1728 |
+
$arr_active_tab = wp_filter_object_list($arr_settings_tabs, array(
|
1729 |
+
'slug' => $active_tab
|
1730 |
+
));
|
1731 |
+
$arr_active_tab = current($arr_active_tab);
|
1732 |
+
|
1733 |
+
// We must have found an active tab and it must have a callable function
|
1734 |
+
if (! $arr_active_tab || ! is_callable($arr_active_tab['function'])) {
|
1735 |
+
wp_die(__('No valid callback found', 'simple-history'));
|
1736 |
+
}
|
1737 |
+
|
1738 |
+
$args = array(
|
1739 |
+
'arr_active_tab' => $arr_active_tab
|
1740 |
+
);
|
1741 |
+
|
1742 |
+
call_user_func_array($arr_active_tab['function'], $args);?>
|
1743 |
+
|
1744 |
+
</div>
|
1745 |
+
<?php
|
1746 |
+
}
|
1747 |
+
|
1748 |
+
public function settings_output_log()
|
1749 |
+
{
|
1750 |
+
include SIMPLE_HISTORY_PATH . 'templates/settings-log.php';
|
1751 |
+
}
|
1752 |
+
|
1753 |
+
public function settings_output_general()
|
1754 |
+
{
|
1755 |
+
include SIMPLE_HISTORY_PATH . 'templates/settings-general.php';
|
1756 |
+
}
|
1757 |
+
|
1758 |
+
public function settings_output_styles_example()
|
1759 |
+
{
|
1760 |
+
include SIMPLE_HISTORY_PATH . 'templates/settings-style-example.php';
|
1761 |
+
}
|
1762 |
+
|
1763 |
+
/**
|
1764 |
+
* Content for section intro. Leave it be, even if empty.
|
1765 |
+
* Called from add_sections_setting.
|
1766 |
+
*/
|
1767 |
+
public function settings_section_output()
|
1768 |
+
{
|
1769 |
+
}
|
1770 |
+
|
1771 |
+
/**
|
1772 |
+
* Add pages (history page and settings page)
|
1773 |
+
*/
|
1774 |
+
public function add_admin_pages()
|
1775 |
+
{
|
1776 |
+
// Add a history page as a sub-page below the Dashboard menu item
|
1777 |
+
if ($this->setting_show_as_page()) {
|
1778 |
+
/**
|
1779 |
+
* Filter to determine if history page should be added to page below dashboard or not
|
1780 |
+
*
|
1781 |
+
* @since 2.0.23
|
1782 |
+
*
|
1783 |
+
* @param bool Show the page or not
|
1784 |
+
*/
|
1785 |
+
$show_dashboard_page = apply_filters('simple_history/show_dashboard_page', true);
|
1786 |
+
|
1787 |
+
if ($show_dashboard_page) {
|
1788 |
+
add_submenu_page(
|
1789 |
+
apply_filters('simple_history/admin_location', 'index') . '.php',
|
1790 |
+
_x('Simple History', 'dashboard title name', 'simple-history'),
|
1791 |
+
_x('Simple History', 'dashboard menu name', 'simple-history'),
|
1792 |
+
$this->get_view_history_capability(),
|
1793 |
+
'simple_history_page',
|
1794 |
+
array( $this, 'history_page_output' )
|
1795 |
+
);
|
1796 |
+
}
|
1797 |
+
}
|
1798 |
+
|
1799 |
+
// Add a settings page
|
1800 |
+
$show_settings_page = true;
|
1801 |
+
$show_settings_page = apply_filters('simple_history_show_settings_page', $show_settings_page);
|
1802 |
+
$show_settings_page = apply_filters('simple_history/show_settings_page', $show_settings_page);
|
1803 |
+
|
1804 |
+
if ($show_settings_page) {
|
1805 |
+
add_options_page(
|
1806 |
+
__('Simple History Settings', 'simple-history'),
|
1807 |
+
_x('Simple History', 'Options page menu title', 'simple-history'),
|
1808 |
+
$this->get_view_settings_capability(),
|
1809 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
1810 |
+
array( $this, 'settings_page_output' )
|
1811 |
+
);
|
1812 |
+
}
|
1813 |
+
}
|
1814 |
+
|
1815 |
+
/**
|
1816 |
+
* Add setting sections and settings for the settings page
|
1817 |
+
* Also maybe save some settings before outputing them
|
1818 |
+
*/
|
1819 |
+
public function add_settings()
|
1820 |
+
{
|
1821 |
+
// Clear the log if clear button was clicked in settings.
|
1822 |
+
if (isset($_GET['simple_history_clear_log_nonce']) &&
|
1823 |
+
wp_verify_nonce($_GET['simple_history_clear_log_nonce'], 'simple_history_clear_log')
|
1824 |
+
) {
|
1825 |
+
if ($this->user_can_clear_log()) {
|
1826 |
+
$this->clear_log();
|
1827 |
+
}
|
1828 |
+
|
1829 |
+
$msg = __('Cleared database', 'simple-history');
|
1830 |
+
|
1831 |
+
add_settings_error(
|
1832 |
+
'simple_history_rss_feed_regenerate_secret',
|
1833 |
+
'simple_history_rss_feed_regenerate_secret',
|
1834 |
+
$msg,
|
1835 |
+
'updated'
|
1836 |
+
);
|
1837 |
+
|
1838 |
+
set_transient('settings_errors', get_settings_errors(), 30);
|
1839 |
+
|
1840 |
+
$goback = esc_url_raw(add_query_arg('settings-updated', 'true', wp_get_referer()));
|
1841 |
+
wp_redirect($goback);
|
1842 |
+
exit();
|
1843 |
+
}
|
1844 |
+
|
1845 |
+
// Section for general options.
|
1846 |
+
// Will contain settings like where to show simple history and number of items.
|
1847 |
+
$settings_section_general_id = self::SETTINGS_SECTION_GENERAL_ID;
|
1848 |
+
add_settings_section(
|
1849 |
+
$settings_section_general_id,
|
1850 |
+
'',
|
1851 |
+
array( $this, 'settings_section_output' ),
|
1852 |
+
SimpleHistory::SETTINGS_MENU_SLUG // Same slug as for options menu page.
|
1853 |
+
);
|
1854 |
+
|
1855 |
+
// Settings for the general settings section
|
1856 |
+
// Each setting = one row in the settings section
|
1857 |
+
// add_settings_field( $id, $title, $callback, $page, $section, $args );
|
1858 |
+
// Checkboxes for where to show simple history
|
1859 |
+
add_settings_field(
|
1860 |
+
'simple_history_show_where',
|
1861 |
+
__('Show history', 'simple-history'),
|
1862 |
+
array( $this, 'settings_field_where_to_show' ),
|
1863 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
1864 |
+
$settings_section_general_id
|
1865 |
+
);
|
1866 |
+
|
1867 |
+
// Nonces for show where inputs.
|
1868 |
+
register_setting(SimpleHistory::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_show_on_dashboard');
|
1869 |
+
register_setting(SimpleHistory::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_show_as_page');
|
1870 |
+
|
1871 |
+
// Number if items to show on the history page.
|
1872 |
+
add_settings_field(
|
1873 |
+
'simple_history_number_of_items',
|
1874 |
+
__('Number of items per page on the log page', 'simple-history'),
|
1875 |
+
array( $this, 'settings_field_number_of_items' ),
|
1876 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
1877 |
+
$settings_section_general_id
|
1878 |
+
);
|
1879 |
+
|
1880 |
+
// Nonces for number of items inputs.
|
1881 |
+
register_setting(SimpleHistory::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_pager_size');
|
1882 |
+
|
1883 |
+
// Number if items to show on dashboard.
|
1884 |
+
add_settings_field(
|
1885 |
+
'simple_history_number_of_items_dashboard',
|
1886 |
+
__('Number of items per page on the dashboard', 'simple-history'),
|
1887 |
+
array( $this, 'settings_field_number_of_items_dashboard' ),
|
1888 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
1889 |
+
$settings_section_general_id
|
1890 |
+
);
|
1891 |
+
|
1892 |
+
// Nonces for number of items inputs.
|
1893 |
+
register_setting(SimpleHistory::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_pager_size_dashboard');
|
1894 |
+
|
1895 |
+
// Link/button to clear log.
|
1896 |
+
if ($this->user_can_clear_log()) {
|
1897 |
+
add_settings_field(
|
1898 |
+
'simple_history_clear_log',
|
1899 |
+
__('Clear log', 'simple-history'),
|
1900 |
+
array( $this, 'settings_field_clear_log' ),
|
1901 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
1902 |
+
$settings_section_general_id
|
1903 |
+
);
|
1904 |
+
}
|
1905 |
+
}
|
1906 |
+
|
1907 |
+
/**
|
1908 |
+
* Output for page with the history
|
1909 |
+
*/
|
1910 |
+
public function history_page_output()
|
1911 |
+
{
|
1912 |
+
// global $simple_history;
|
1913 |
+
// $this->purge_db();
|
1914 |
+
global $wpdb;
|
1915 |
+
|
1916 |
+
$pager_size = $this->get_pager_size();
|
1917 |
+
|
1918 |
+
/**
|
1919 |
+
* Filter the pager size setting for the history page
|
1920 |
+
*
|
1921 |
+
* @since 2.0
|
1922 |
+
*
|
1923 |
+
* @param int $pager_size
|
1924 |
+
*/
|
1925 |
+
$pager_size = apply_filters('simple_history/page_pager_size', $pager_size);
|
1926 |
+
?>
|
1927 |
+
|
1928 |
+
<div class="wrap SimpleHistoryWrap">
|
1929 |
+
|
1930 |
+
<h1 class="SimpleHistoryPageHeadline">
|
1931 |
+
<div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
|
1932 |
+
<?php echo _x('Simple History', 'history page headline', 'simple-history'); ?>
|
1933 |
+
</h1>
|
1934 |
+
|
1935 |
+
<?php /**
|
1936 |
+
* Fires before the gui div
|
1937 |
+
*
|
1938 |
+
* @since 2.0
|
1939 |
+
*
|
1940 |
+
* @param SimpleHistory $SimpleHistory This class.
|
1941 |
+
*/
|
1942 |
+
do_action('simple_history/history_page/before_gui', $this); ?>
|
1943 |
+
|
1944 |
+
<div class="SimpleHistoryGuiWrap">
|
1945 |
+
|
1946 |
+
<div class="SimpleHistoryGui"
|
1947 |
+
data-pager-size='<?php echo $pager_size; ?>'
|
1948 |
+
></div>
|
1949 |
+
|
1950 |
+
<?php /**
|
1951 |
+
* Fires after the gui div
|
1952 |
+
*
|
1953 |
+
* @since 2.0
|
1954 |
+
*
|
1955 |
+
* @param SimpleHistory $SimpleHistory This class.
|
1956 |
+
*/
|
1957 |
+
do_action('simple_history/history_page/after_gui', $this); ?>
|
1958 |
+
|
1959 |
+
</div>
|
1960 |
+
|
1961 |
+
</div>
|
1962 |
+
|
1963 |
+
<?php
|
1964 |
+
}
|
1965 |
+
|
1966 |
+
/**
|
1967 |
+
* Get setting if plugin should be visible on dasboard.
|
1968 |
+
* Defaults to true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1969 |
*
|
1970 |
+
* @return bool
|
1971 |
+
*/
|
1972 |
+
public function setting_show_on_dashboard()
|
1973 |
+
{
|
1974 |
+
$show_on_dashboard = get_option('simple_history_show_on_dashboard', 1);
|
1975 |
+
$show_on_dashboard = apply_filters('simple_history_show_on_dashboard', $show_on_dashboard);
|
1976 |
+
return (bool) $show_on_dashboard;
|
1977 |
+
}
|
1978 |
+
|
1979 |
+
/**
|
1980 |
+
* Should simple history be shown as a page
|
1981 |
+
* Defaults to true
|
1982 |
*
|
1983 |
+
* @return bool
|
1984 |
*/
|
1985 |
+
public function setting_show_as_page()
|
1986 |
+
{
|
1987 |
+
$setting = get_option('simple_history_show_as_page', 1);
|
1988 |
+
$setting = apply_filters('simple_history_show_as_page', $setting);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1989 |
|
1990 |
+
return (bool) $setting;
|
1991 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1992 |
|
1993 |
+
/**
|
1994 |
+
* Settings field for how many rows/items to show in log on the log page
|
1995 |
+
*/
|
1996 |
+
public function settings_field_number_of_items()
|
1997 |
+
{
|
1998 |
+
$current_pager_size = $this->get_pager_size(); ?>
|
1999 |
+
<select name="simple_history_pager_size">
|
2000 |
+
<option <?php echo $current_pager_size == 5 ? 'selected' : ''; ?> value="5">5</option>
|
2001 |
+
<option <?php echo $current_pager_size == 10 ? 'selected' : ''; ?> value="10">10</option>
|
2002 |
+
<option <?php echo $current_pager_size == 15 ? 'selected' : ''; ?> value="15">15</option>
|
2003 |
+
<option <?php echo $current_pager_size == 20 ? 'selected' : ''; ?> value="20">20</option>
|
2004 |
+
<option <?php echo $current_pager_size == 25 ? 'selected' : ''; ?> value="25">25</option>
|
2005 |
+
<option <?php echo $current_pager_size == 30 ? 'selected' : ''; ?> value="30">30</option>
|
2006 |
+
<option <?php echo $current_pager_size == 40 ? 'selected' : ''; ?> value="40">40</option>
|
2007 |
+
<option <?php echo $current_pager_size == 50 ? 'selected' : ''; ?> value="50">50</option>
|
2008 |
+
<option <?php echo $current_pager_size == 75 ? 'selected' : ''; ?> value="75">75</option>
|
2009 |
+
<option <?php echo $current_pager_size == 100 ? 'selected' : ''; ?> value="100">100</option>
|
2010 |
+
</select>
|
2011 |
+
<?php
|
2012 |
+
}
|
2013 |
+
|
2014 |
+
/**
|
2015 |
+
* Settings field for how many rows/items to show in log on the dashboard
|
2016 |
+
*/
|
2017 |
+
public function settings_field_number_of_items_dashboard()
|
2018 |
+
{
|
2019 |
+
$current_pager_size = $this->get_pager_size_dashboard(); ?>
|
2020 |
+
<select name="simple_history_pager_size_dashboard">
|
2021 |
+
<option <?php echo $current_pager_size == 5 ? 'selected' : ''; ?> value="5">5</option>
|
2022 |
+
<option <?php echo $current_pager_size == 10 ? 'selected' : ''; ?> value="10">10</option>
|
2023 |
+
<option <?php echo $current_pager_size == 15 ? 'selected' : ''; ?> value="15">15</option>
|
2024 |
+
<option <?php echo $current_pager_size == 20 ? 'selected' : ''; ?> value="20">20</option>
|
2025 |
+
<option <?php echo $current_pager_size == 25 ? 'selected' : ''; ?> value="25">25</option>
|
2026 |
+
<option <?php echo $current_pager_size == 30 ? 'selected' : ''; ?> value="30">30</option>
|
2027 |
+
<option <?php echo $current_pager_size == 40 ? 'selected' : ''; ?> value="40">40</option>
|
2028 |
+
<option <?php echo $current_pager_size == 50 ? 'selected' : ''; ?> value="50">50</option>
|
2029 |
+
<option <?php echo $current_pager_size == 75 ? 'selected' : ''; ?> value="75">75</option>
|
2030 |
+
<option <?php echo $current_pager_size == 100 ? 'selected' : ''; ?> value="100">100</option>
|
2031 |
+
</select>
|
2032 |
+
<?php
|
2033 |
+
}
|
2034 |
+
|
2035 |
+
/**
|
2036 |
+
* Settings field for where to show the log, page or dashboard
|
2037 |
+
*/
|
2038 |
+
public function settings_field_where_to_show()
|
2039 |
+
{
|
2040 |
+
$show_on_dashboard = $this->setting_show_on_dashboard();
|
2041 |
+
$show_as_page = $this->setting_show_as_page();
|
2042 |
+
?>
|
2043 |
+
|
2044 |
+
<input <?php echo $show_on_dashboard
|
2045 |
+
? "checked='checked'"
|
2046 |
+
: ''; ?> type="checkbox" value="1" name="simple_history_show_on_dashboard" id="simple_history_show_on_dashboard" class="simple_history_show_on_dashboard" />
|
2047 |
+
<label for="simple_history_show_on_dashboard"><?php _e('on the dashboard', 'simple-history'); ?></label>
|
2048 |
+
|
2049 |
+
<br />
|
2050 |
+
|
2051 |
+
<input <?php echo $show_as_page
|
2052 |
+
? "checked='checked'"
|
2053 |
+
: ''; ?> type="checkbox" value="1" name="simple_history_show_as_page" id="simple_history_show_as_page" class="simple_history_show_as_page" />
|
2054 |
+
<label for="simple_history_show_as_page">
|
2055 |
+
<?php
|
2056 |
+
_e(
|
2057 |
+
'as a page under the dashboard menu',
|
2058 |
+
'simple-history'
|
2059 |
+
);
|
2060 |
+
?>
|
2061 |
+
</label>
|
2062 |
+
|
2063 |
+
<?php
|
2064 |
+
}
|
2065 |
+
|
2066 |
+
/**
|
2067 |
+
* Settings section to clear database
|
2068 |
+
*/
|
2069 |
+
public function settings_field_clear_log()
|
2070 |
+
{
|
2071 |
+
$clear_link = esc_url(add_query_arg('', ''));
|
2072 |
+
$clear_link = wp_nonce_url($clear_link, 'simple_history_clear_log', 'simple_history_clear_log_nonce');
|
2073 |
+
$clear_days = $this->get_clear_history_interval();
|
2074 |
+
|
2075 |
+
echo '<p>';
|
2076 |
+
|
2077 |
+
if ($clear_days > 0) {
|
2078 |
+
echo sprintf(
|
2079 |
+
__('Items in the database are automatically removed after %1$s days.', 'simple-history'),
|
2080 |
+
$clear_days
|
2081 |
+
);
|
2082 |
+
} else {
|
2083 |
+
_e('Items in the database are kept forever.', 'simple-history');
|
2084 |
+
}
|
2085 |
+
|
2086 |
+
echo '</p>';
|
2087 |
+
|
2088 |
+
printf(
|
2089 |
+
'<p><a class="button js-SimpleHistory-Settings-ClearLog" href="%2$s">%1$s</a></p>',
|
2090 |
+
__('Clear log now', 'simple-history'),
|
2091 |
+
$clear_link
|
2092 |
+
);
|
2093 |
+
}
|
2094 |
+
|
2095 |
+
/**
|
2096 |
+
* How old log entried are allowed to be.
|
2097 |
+
* 0 = don't delete old entries.
|
2098 |
+
*
|
2099 |
+
* @return int Number of days.
|
2100 |
+
*/
|
2101 |
+
public function get_clear_history_interval()
|
2102 |
+
{
|
2103 |
+
$days = 60;
|
2104 |
+
|
2105 |
+
/**
|
2106 |
+
* Filter to modify number of days of history to keep.
|
2107 |
+
* Default is 60 days.
|
2108 |
+
*
|
2109 |
+
* @param $days Number of days of history to keep
|
2110 |
+
*/
|
2111 |
+
$days = (int) apply_filters('simple_history_db_purge_days_interval', $days);
|
2112 |
+
$days = (int) apply_filters('simple_history/db_purge_days_interval', $days);
|
2113 |
+
|
2114 |
+
return $days;
|
2115 |
+
}
|
2116 |
+
|
2117 |
+
/**
|
2118 |
+
* Removes all items from the log
|
2119 |
+
*/
|
2120 |
+
public function clear_log()
|
2121 |
+
{
|
2122 |
+
global $wpdb;
|
2123 |
|
2124 |
+
$tableprefix = $wpdb->prefix;
|
2125 |
|
2126 |
+
$simple_history_table = SimpleHistory::DBTABLE;
|
2127 |
+
$simple_history_context_table = SimpleHistory::DBTABLE_CONTEXTS;
|
2128 |
|
2129 |
+
// Get number of rows before delete.
|
2130 |
+
$sql_num_rows = "SELECT count(id) AS num_rows FROM {$tableprefix}{$simple_history_table}";
|
2131 |
+
$num_rows = $wpdb->get_var($sql_num_rows, 0);
|
2132 |
|
2133 |
+
// Use truncate instead of delete because it's much faster (I think, writing this much later).
|
2134 |
+
$sql = "TRUNCATE {$tableprefix}{$simple_history_table}";
|
2135 |
+
$wpdb->query($sql);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2136 |
|
2137 |
+
$sql = "TRUNCATE {$tableprefix}{$simple_history_context_table}";
|
2138 |
+
$wpdb->query($sql);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2139 |
|
2140 |
+
// Zero state sucks
|
2141 |
+
SimpleLogger()->info(
|
2142 |
+
__('The log for Simple History was cleared ({num_rows} rows were removed).', 'simple-history'),
|
2143 |
+
array(
|
2144 |
+
'num_rows' => $num_rows
|
2145 |
+
)
|
2146 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2147 |
|
2148 |
+
$this->get_cache_incrementor(true);
|
2149 |
+
}
|
2150 |
+
|
2151 |
+
/**
|
2152 |
+
* Runs the purge_db() method sometimes
|
2153 |
+
* We don't want to call it each time because it performs SQL queries
|
2154 |
+
*
|
2155 |
+
* @since 2.0.17
|
2156 |
+
*/
|
2157 |
+
public function maybe_purge_db()
|
2158 |
+
{
|
2159 |
+
// How often should we try to do this?
|
2160 |
+
// Once a day = a bit tiresome.
|
2161 |
+
// Let's go with sundays; purge the log on sundays.
|
2162 |
+
// Day of week, 1 = mon, 7 = sun.
|
2163 |
+
$day_of_week = date('N');
|
2164 |
+
if (7 === (int) $day_of_week) {
|
2165 |
+
$this->purge_db();
|
2166 |
+
}
|
2167 |
+
}
|
2168 |
+
|
2169 |
+
/**
|
2170 |
+
* Removes old entries from the db
|
2171 |
+
*/
|
2172 |
+
public function purge_db()
|
2173 |
+
{
|
2174 |
+
$do_purge_history = true;
|
2175 |
+
|
2176 |
+
$do_purge_history = apply_filters('simple_history_allow_db_purge', $do_purge_history);
|
2177 |
+
$do_purge_history = apply_filters('simple_history/allow_db_purge', $do_purge_history);
|
2178 |
+
|
2179 |
+
if (! $do_purge_history) {
|
2180 |
+
return;
|
2181 |
+
}
|
2182 |
+
|
2183 |
+
$days = $this->get_clear_history_interval();
|
2184 |
+
|
2185 |
+
// Never clear log if days = 0.
|
2186 |
+
if (0 == $days) {
|
2187 |
+
return;
|
2188 |
+
}
|
2189 |
+
|
2190 |
+
global $wpdb;
|
2191 |
+
|
2192 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
2193 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
2194 |
+
|
2195 |
+
while (1 > 0) {
|
2196 |
+
// Get id of rows to delete.
|
2197 |
+
$sql = $wpdb->prepare(
|
2198 |
+
"SELECT id FROM $table_name WHERE DATE_ADD(date, INTERVAL %d DAY) < now() LIMIT 100000",
|
2199 |
+
$days
|
2200 |
+
);
|
2201 |
+
|
2202 |
+
$ids_to_delete = $wpdb->get_col($sql);
|
2203 |
+
|
2204 |
+
if (empty($ids_to_delete)) {
|
2205 |
+
// Nothing to delete.
|
2206 |
+
return;
|
2207 |
+
}
|
2208 |
+
|
2209 |
+
$sql_ids_in = implode(',', $ids_to_delete);
|
2210 |
+
|
2211 |
+
// Add number of deleted rows to total_rows option.
|
2212 |
+
$prev_total_rows = (int) get_option('simple_history_total_rows', 0);
|
2213 |
+
$total_rows = $prev_total_rows + sizeof($ids_to_delete);
|
2214 |
+
update_option('simple_history_total_rows', $total_rows);
|
2215 |
+
|
2216 |
+
// Remove rows + contexts.
|
2217 |
+
$sql_delete_history = "DELETE FROM {$table_name} WHERE id IN ($sql_ids_in)";
|
2218 |
+
$sql_delete_history_context = "DELETE FROM {$table_name_contexts} WHERE history_id IN ($sql_ids_in)";
|
2219 |
+
|
2220 |
+
$wpdb->query($sql_delete_history);
|
2221 |
+
$wpdb->query($sql_delete_history_context);
|
2222 |
+
|
2223 |
+
$message = _nx(
|
2224 |
+
'Simple History removed one event that were older than {days} days',
|
2225 |
+
'Simple History removed {num_rows} events that were older than {days} days',
|
2226 |
+
count($ids_to_delete),
|
2227 |
+
'Database is being cleared automagically',
|
2228 |
+
'simple-history'
|
2229 |
+
);
|
2230 |
+
|
2231 |
+
SimpleLogger()->info($message, array(
|
2232 |
+
'days' => $days,
|
2233 |
+
'num_rows' => count($ids_to_delete)
|
2234 |
+
));
|
2235 |
+
|
2236 |
+
$this->get_cache_incrementor(true);
|
2237 |
+
}
|
2238 |
+
}
|
2239 |
+
|
2240 |
+
/**
|
2241 |
+
* Return plain text output for a log row
|
2242 |
+
* Uses the getLogRowPlainTextOutput of the logger that logged the row
|
2243 |
+
* with fallback to SimpleLogger if logger is not available.
|
2244 |
+
*
|
2245 |
+
* @param array $row
|
2246 |
+
* @return string
|
2247 |
+
*/
|
2248 |
+
public function getLogRowPlainTextOutput($row)
|
2249 |
+
{
|
2250 |
+
$row_logger = $row->logger;
|
2251 |
+
$logger = null;
|
2252 |
+
$row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
|
2253 |
+
|
2254 |
+
if (! isset($row->context['_message_key'])) {
|
2255 |
+
$row->context['_message_key'] = null;
|
2256 |
+
}
|
2257 |
+
|
2258 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2259 |
+
if (! isset($this->instantiatedLoggers[ $row_logger ])) {
|
2260 |
+
$row_logger = 'SimpleLogger';
|
2261 |
+
}
|
2262 |
+
|
2263 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2264 |
+
|
2265 |
+
return $logger->getLogRowPlainTextOutput($row);
|
2266 |
+
}
|
2267 |
+
|
2268 |
+
/**
|
2269 |
+
* Return header output for a log row
|
2270 |
+
* Uses the getLogRowHeaderOutput of the logger that logged the row
|
2271 |
+
* with fallback to SimpleLogger if logger is not available
|
2272 |
+
*
|
2273 |
+
* Loggers are discouraged to override this in the loggers,
|
2274 |
+
* because the output should be the same for all items in the gui
|
2275 |
+
*
|
2276 |
+
* @param array $row
|
2277 |
+
* @return string
|
2278 |
+
*/
|
2279 |
+
public function getLogRowHeaderOutput($row)
|
2280 |
+
{
|
2281 |
+
$row_logger = $row->logger;
|
2282 |
+
$logger = null;
|
2283 |
+
$row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
|
2284 |
+
|
2285 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2286 |
+
if (! isset($this->instantiatedLoggers[ $row_logger ])) {
|
2287 |
+
$row_logger = 'SimpleLogger';
|
2288 |
+
}
|
2289 |
+
|
2290 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2291 |
+
|
2292 |
+
return $logger->getLogRowHeaderOutput($row);
|
2293 |
+
}
|
2294 |
+
|
2295 |
+
/**
|
2296 |
+
*
|
2297 |
+
*
|
2298 |
+
* @param array $row
|
2299 |
+
* @return string
|
2300 |
+
*/
|
2301 |
+
private function getLogRowSenderImageOutput($row)
|
2302 |
+
{
|
2303 |
+
$row_logger = $row->logger;
|
2304 |
+
$logger = null;
|
2305 |
+
$row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
|
2306 |
+
|
2307 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2308 |
+
if (! isset($this->instantiatedLoggers[ $row_logger ])) {
|
2309 |
+
$row_logger = 'SimpleLogger';
|
2310 |
+
}
|
2311 |
+
|
2312 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2313 |
+
|
2314 |
+
return $logger->getLogRowSenderImageOutput($row);
|
2315 |
+
}
|
2316 |
+
|
2317 |
+
public function getLogRowDetailsOutput($row)
|
2318 |
+
{
|
2319 |
+
$row_logger = $row->logger;
|
2320 |
+
$logger = null;
|
2321 |
+
$row->context = isset($row->context) && is_array($row->context) ? $row->context : array();
|
2322 |
+
|
2323 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2324 |
+
if (! isset($this->instantiatedLoggers[ $row_logger ])) {
|
2325 |
+
$row_logger = 'SimpleLogger';
|
2326 |
+
}
|
2327 |
+
|
2328 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2329 |
+
|
2330 |
+
return $logger->getLogRowDetailsOutput($row);
|
2331 |
+
}
|
2332 |
+
|
2333 |
+
/**
|
2334 |
+
* Works like json_encode, but adds JSON_PRETTY_PRINT if the current php version supports it
|
2335 |
+
* i.e. PHP is 5.4.0 or greated
|
2336 |
+
*
|
2337 |
+
* @param mixed $value array|object|string|whatever that is json_encode'able.
|
2338 |
+
*/
|
2339 |
+
public static function json_encode($value)
|
2340 |
+
{
|
2341 |
+
return version_compare(PHP_VERSION, '5.4.0') >= 0
|
2342 |
+
? json_encode($value, JSON_PRETTY_PRINT)
|
2343 |
+
: json_encode($value);
|
2344 |
+
}
|
2345 |
+
|
2346 |
+
/**
|
2347 |
+
* Returns true if $haystack ends with $needle
|
2348 |
+
*
|
2349 |
+
* @param string $haystack
|
2350 |
+
* @param string $needle
|
2351 |
+
*/
|
2352 |
+
public static function ends_with($haystack, $needle)
|
2353 |
+
{
|
2354 |
+
return $needle === substr($haystack, -strlen($needle));
|
2355 |
+
}
|
2356 |
+
|
2357 |
+
/**
|
2358 |
+
* Returns the HTML output for a log row, to be used in the GUI/Activity Feed
|
2359 |
+
*
|
2360 |
+
* @param array $oneLogRow SimpleHistoryLogQuery array with data from SimpleHistoryLogQuery
|
2361 |
+
* @return string
|
2362 |
+
*/
|
2363 |
+
public function getLogRowHTMLOutput($oneLogRow, $args)
|
2364 |
+
{
|
2365 |
+
$defaults = array(
|
2366 |
+
'type' => 'overview' // or "single" to include more stuff
|
2367 |
+
);
|
2368 |
+
|
2369 |
+
$args = wp_parse_args($args, $defaults);
|
2370 |
+
|
2371 |
+
$header_html = $this->getLogRowHeaderOutput($oneLogRow);
|
2372 |
+
$plain_text_html = $this->getLogRowPlainTextOutput($oneLogRow);
|
2373 |
+
$sender_image_html = $this->getLogRowSenderImageOutput($oneLogRow);
|
2374 |
+
|
2375 |
+
// Details = for example thumbnail of media
|
2376 |
+
$details_html = trim($this->getLogRowDetailsOutput($oneLogRow));
|
2377 |
+
if ($details_html) {
|
2378 |
+
$details_html = sprintf('<div class="SimpleHistoryLogitem__details">%1$s</div>', $details_html);
|
2379 |
+
}
|
2380 |
+
|
2381 |
+
// subsequentOccasions = including the current one
|
2382 |
+
$occasions_count = $oneLogRow->subsequentOccasions - 1;
|
2383 |
+
$occasions_html = '';
|
2384 |
+
|
2385 |
+
if ($occasions_count > 0) {
|
2386 |
+
$occasions_html = '<div class="SimpleHistoryLogitem__occasions">';
|
2387 |
+
|
2388 |
+
$occasions_html .= '<a href="#" class="SimpleHistoryLogitem__occasionsLink">';
|
2389 |
+
$occasions_html .= sprintf(
|
2390 |
+
_n('+%1$s similar event', '+%1$s similar events', $occasions_count, 'simple-history'),
|
2391 |
+
$occasions_count
|
2392 |
+
);
|
2393 |
+
$occasions_html .= '</a>';
|
2394 |
+
|
2395 |
+
$occasions_html .= '<span class="SimpleHistoryLogitem__occasionsLoading">';
|
2396 |
+
$occasions_html .= sprintf(__('Loading…', 'simple-history'), $occasions_count);
|
2397 |
+
$occasions_html .= '</span>';
|
2398 |
+
|
2399 |
+
$occasions_html .= '<span class="SimpleHistoryLogitem__occasionsLoaded">';
|
2400 |
+
$occasions_html .= sprintf(__('Showing %1$s more', 'simple-history'), $occasions_count);
|
2401 |
+
$occasions_html .= '</span>';
|
2402 |
+
|
2403 |
+
$occasions_html .= '</div>';
|
2404 |
+
}
|
2405 |
+
|
2406 |
+
// Add data atributes to log row, so plugins can do stuff
|
2407 |
+
$data_attrs = '';
|
2408 |
+
$data_attrs .= sprintf(' data-row-id="%1$d" ', $oneLogRow->id);
|
2409 |
+
$data_attrs .= sprintf(' data-occasions-count="%1$d" ', $occasions_count);
|
2410 |
+
$data_attrs .= sprintf(' data-occasions-id="%1$s" ', esc_attr($oneLogRow->occasionsID));
|
2411 |
+
|
2412 |
+
if (isset($oneLogRow->context['_server_remote_addr'])) {
|
2413 |
+
$data_attrs .= sprintf(' data-ip-address="%1$s" ', esc_attr($oneLogRow->context['_server_remote_addr']));
|
2414 |
+
}
|
2415 |
+
|
2416 |
+
$arr_found_additional_ip_headers = $this->instantiatedLoggers['SimpleLogger'][
|
2417 |
+
'instance'
|
2418 |
+
]->get_event_ip_number_headers($oneLogRow);
|
2419 |
+
if ($arr_found_additional_ip_headers) {
|
2420 |
+
$data_attrs .= sprintf(' data-ip-address-multiple="1" ');
|
2421 |
+
}
|
2422 |
+
|
2423 |
+
$data_attrs .= sprintf(' data-logger="%1$s" ', esc_attr($oneLogRow->logger));
|
2424 |
+
$data_attrs .= sprintf(' data-level="%1$s" ', esc_attr($oneLogRow->level));
|
2425 |
+
$data_attrs .= sprintf(' data-date="%1$s" ', esc_attr($oneLogRow->date));
|
2426 |
+
$data_attrs .= sprintf(' data-initiator="%1$s" ', esc_attr($oneLogRow->initiator));
|
2427 |
+
|
2428 |
+
if (isset($oneLogRow->context['_user_id'])) {
|
2429 |
+
$data_attrs .= sprintf(' data-initiator-user-id="%1$d" ', $oneLogRow->context['_user_id']);
|
2430 |
+
}
|
2431 |
+
|
2432 |
+
// If type is single then include more details
|
2433 |
+
$more_details_html = '';
|
2434 |
+
if ($args['type'] == 'single') {
|
2435 |
+
$more_details_html = apply_filters(
|
2436 |
+
'simple_history/log_html_output_details_single/html_before_context_table',
|
2437 |
+
$more_details_html,
|
2438 |
+
$oneLogRow
|
2439 |
+
);
|
2440 |
+
|
2441 |
+
$more_details_html .= sprintf(
|
2442 |
+
'<h2 class="SimpleHistoryLogitem__moreDetailsHeadline">%1$s</h2>',
|
2443 |
+
__('Context data', 'simple-history')
|
2444 |
+
);
|
2445 |
+
$more_details_html .=
|
2446 |
+
'<p>' . __('This is potentially useful meta data that a logger has saved.', 'simple-history') . '</p>';
|
2447 |
+
$more_details_html .= "<table class='SimpleHistoryLogitem__moreDetailsContext'>";
|
2448 |
+
$more_details_html .= sprintf(
|
2449 |
+
'<tr>
|
2450 |
+
<th>%1$s</th>
|
2451 |
+
<th>%2$s</th>
|
2452 |
+
</tr>',
|
2453 |
+
'Key',
|
2454 |
+
'Value'
|
2455 |
+
);
|
2456 |
+
|
2457 |
+
$logRowKeysToShow = array_fill_keys(array_keys((array) $oneLogRow), true);
|
2458 |
+
|
2459 |
+
/**
|
2460 |
+
* Filter what keys to show from oneLogRow
|
2461 |
+
*
|
2462 |
+
* Array is in format
|
2463 |
+
*
|
2464 |
+
* Array
|
2465 |
+
* (
|
2466 |
+
* [id] => 1
|
2467 |
+
* [logger] => 1
|
2468 |
+
* [level] => 1
|
2469 |
+
* ...
|
2470 |
+
* )
|
2471 |
+
*
|
2472 |
+
* @since 2.0.29
|
2473 |
+
*
|
2474 |
+
* @param array with keys to show. key to show = key. value = boolean to show or not.
|
2475 |
+
* @param object log row to show details from
|
2476 |
+
*/
|
2477 |
+
$logRowKeysToShow = apply_filters(
|
2478 |
+
'simple_history/log_html_output_details_table/row_keys_to_show',
|
2479 |
+
$logRowKeysToShow,
|
2480 |
+
$oneLogRow
|
2481 |
+
);
|
2482 |
+
|
2483 |
+
// Hide some keys by default
|
2484 |
+
unset(
|
2485 |
+
$logRowKeysToShow['occasionsID'],
|
2486 |
+
$logRowKeysToShow['subsequentOccasions'],
|
2487 |
+
$logRowKeysToShow['rep'],
|
2488 |
+
$logRowKeysToShow['repeated'],
|
2489 |
+
$logRowKeysToShow['occasionsIDType'],
|
2490 |
+
$logRowKeysToShow['context'],
|
2491 |
+
$logRowKeysToShow['type']
|
2492 |
+
);
|
2493 |
+
|
2494 |
+
foreach ($oneLogRow as $rowKey => $rowVal) {
|
2495 |
+
// Only columns from oneLogRow that exist in logRowKeysToShow will be outputed
|
2496 |
+
if (! array_key_exists($rowKey, $logRowKeysToShow) || ! $logRowKeysToShow[ $rowKey ]) {
|
2497 |
+
continue;
|
2498 |
+
}
|
2499 |
+
|
2500 |
+
// skip arrays and objects and such
|
2501 |
+
if (is_array($rowVal) || is_object($rowVal)) {
|
2502 |
+
continue;
|
2503 |
+
}
|
2504 |
+
|
2505 |
+
$more_details_html .= sprintf(
|
2506 |
+
'<tr>
|
2507 |
+
<td>%1$s</td>
|
2508 |
+
<td>%2$s</td>
|
2509 |
+
</tr>',
|
2510 |
+
esc_html($rowKey),
|
2511 |
+
esc_html($rowVal)
|
2512 |
+
);
|
2513 |
+
}
|
2514 |
+
|
2515 |
+
$logRowContextKeysToShow = array_fill_keys(array_keys((array) $oneLogRow->context), true);
|
2516 |
+
|
2517 |
+
/**
|
2518 |
+
* Filter what keys to show from the row context
|
2519 |
+
*
|
2520 |
+
* Array is in format
|
2521 |
+
*
|
2522 |
+
* Array
|
2523 |
+
* (
|
2524 |
+
* [plugin_slug] => 1
|
2525 |
+
* [plugin_name] => 1
|
2526 |
+
* [plugin_title] => 1
|
2527 |
+
* [plugin_description] => 1
|
2528 |
+
* [plugin_author] => 1
|
2529 |
+
* [plugin_version] => 1
|
2530 |
+
* ...
|
2531 |
+
* )
|
2532 |
+
*
|
2533 |
+
* @since 2.0.29
|
2534 |
+
*
|
2535 |
+
* @param array with keys to show. key to show = key. value = boolean to show or not.
|
2536 |
+
* @param object log row to show details from
|
2537 |
+
*/
|
2538 |
+
$logRowContextKeysToShow = apply_filters(
|
2539 |
+
'simple_history/log_html_output_details_table/context_keys_to_show',
|
2540 |
+
$logRowContextKeysToShow,
|
2541 |
+
$oneLogRow
|
2542 |
+
);
|
2543 |
+
|
2544 |
+
foreach ($oneLogRow->context as $contextKey => $contextVal) {
|
2545 |
+
// Only columns from context that exist in logRowContextKeysToShow will be outputed
|
2546 |
+
if (!array_key_exists($contextKey, $logRowContextKeysToShow) ||
|
2547 |
+
!$logRowContextKeysToShow[$contextKey]
|
2548 |
+
) {
|
2549 |
+
continue;
|
2550 |
+
}
|
2551 |
+
|
2552 |
+
$more_details_html .= sprintf(
|
2553 |
+
'<tr>
|
2554 |
+
<td>%1$s</td>
|
2555 |
+
<td>%2$s</td>
|
2556 |
+
</tr>',
|
2557 |
+
esc_html($contextKey),
|
2558 |
+
esc_html($contextVal)
|
2559 |
+
);
|
2560 |
+
}
|
2561 |
+
|
2562 |
+
$more_details_html .= '</table>';
|
2563 |
+
|
2564 |
+
$more_details_html = apply_filters(
|
2565 |
+
'simple_history/log_html_output_details_single/html_after_context_table',
|
2566 |
+
$more_details_html,
|
2567 |
+
$oneLogRow
|
2568 |
+
);
|
2569 |
+
|
2570 |
+
$more_details_html = sprintf(
|
2571 |
+
'<div class="SimpleHistoryLogitem__moreDetails">%1$s</div>',
|
2572 |
+
$more_details_html
|
2573 |
+
);
|
2574 |
+
}// End if().
|
2575 |
+
|
2576 |
+
// Classes to add to log item li element
|
2577 |
+
$classes = array(
|
2578 |
+
'SimpleHistoryLogitem',
|
2579 |
+
"SimpleHistoryLogitem--loglevel-{$oneLogRow->level}",
|
2580 |
+
"SimpleHistoryLogitem--logger-{$oneLogRow->logger}"
|
2581 |
+
);
|
2582 |
+
|
2583 |
+
if (isset($oneLogRow->initiator) && ! empty($oneLogRow->initiator)) {
|
2584 |
+
$classes[] = 'SimpleHistoryLogitem--initiator-' . $oneLogRow->initiator;
|
2585 |
+
}
|
2586 |
+
|
2587 |
+
if ($arr_found_additional_ip_headers) {
|
2588 |
+
$classes[] = 'SimpleHistoryLogitem--IPAddress-multiple';
|
2589 |
+
}
|
2590 |
+
|
2591 |
+
// Always append the log level tag
|
2592 |
+
$log_level_tag_html = sprintf(
|
2593 |
+
' <span class="SimpleHistoryLogitem--logleveltag SimpleHistoryLogitem--logleveltag-%1$s">%2$s</span>',
|
2594 |
+
$oneLogRow->level,
|
2595 |
+
$this->getLogLevelTranslated($oneLogRow->level)
|
2596 |
+
);
|
2597 |
+
|
2598 |
+
$plain_text_html .= $log_level_tag_html;
|
2599 |
+
|
2600 |
+
/**
|
2601 |
+
* Filter to modify classes added to item li element
|
2602 |
+
*
|
2603 |
+
* @since 2.0.7
|
2604 |
+
*
|
2605 |
+
* @param $classes Array with classes
|
2606 |
+
*/
|
2607 |
+
$classes = apply_filters('simple_history/logrowhtmloutput/classes', $classes);
|
2608 |
+
|
2609 |
+
// Generate the HTML output for a row
|
2610 |
+
$output = sprintf(
|
2611 |
+
'
|
2612 |
+
<li %8$s class="%10$s">
|
2613 |
+
<div class="SimpleHistoryLogitem__firstcol">
|
2614 |
+
<div class="SimpleHistoryLogitem__senderImage">%3$s</div>
|
2615 |
+
</div>
|
2616 |
+
<div class="SimpleHistoryLogitem__secondcol">
|
2617 |
+
<div class="SimpleHistoryLogitem__header">%1$s</div>
|
2618 |
+
<div class="SimpleHistoryLogitem__text">%2$s</div>
|
2619 |
+
%6$s <!-- details_html -->
|
2620 |
+
%9$s <!-- more details html -->
|
2621 |
+
%4$s <!-- occasions -->
|
2622 |
+
</div>
|
2623 |
+
</li>
|
2624 |
+
',
|
2625 |
+
$header_html, // 1
|
2626 |
+
$plain_text_html, // 2
|
2627 |
+
$sender_image_html, // 3
|
2628 |
+
$occasions_html, // 4
|
2629 |
+
$oneLogRow->level, // 5
|
2630 |
+
$details_html, // 6
|
2631 |
+
$oneLogRow->logger, // 7
|
2632 |
+
$data_attrs, // 8 data attributes
|
2633 |
+
$more_details_html, // 9
|
2634 |
+
esc_attr(join(' ', $classes)) // 10
|
2635 |
+
);
|
2636 |
+
|
2637 |
+
// Get the main message row.
|
2638 |
+
// Should be as plain as possible, like plain text
|
2639 |
+
// but with links to for example users and posts
|
2640 |
+
// SimpleLoggerFormatter::getRowTextOutput($oneLogRow);
|
2641 |
+
// Get detailed HTML-based output
|
2642 |
+
// May include images, lists, any cool stuff needed to view
|
2643 |
+
// SimpleLoggerFormatter::getRowHTMLOutput($oneLogRow);
|
2644 |
+
return trim($output);
|
2645 |
+
}
|
2646 |
+
|
2647 |
+
/**
|
2648 |
+
* Return translated loglevel
|
2649 |
+
*
|
2650 |
+
* @since 2.0.14
|
2651 |
+
* @param string $loglevel
|
2652 |
+
* @return string translated loglevel
|
2653 |
+
*/
|
2654 |
+
public function getLogLevelTranslated($loglevel)
|
2655 |
+
{
|
2656 |
+
$str_translated = '';
|
2657 |
+
|
2658 |
+
switch ($loglevel) {
|
2659 |
+
// Lowercase
|
2660 |
+
case 'emergency':
|
2661 |
+
$str_translated = _x('emergency', 'Log level in gui', 'simple-history');
|
2662 |
+
break;
|
2663 |
+
|
2664 |
+
case 'alert':
|
2665 |
+
$str_translated = _x('alert', 'Log level in gui', 'simple-history');
|
2666 |
+
break;
|
2667 |
+
|
2668 |
+
case 'critical':
|
2669 |
+
$str_translated = _x('critical', 'Log level in gui', 'simple-history');
|
2670 |
+
break;
|
2671 |
+
|
2672 |
+
case 'error':
|
2673 |
+
$str_translated = _x('error', 'Log level in gui', 'simple-history');
|
2674 |
+
break;
|
2675 |
+
|
2676 |
+
case 'warning':
|
2677 |
+
$str_translated = _x('warning', 'Log level in gui', 'simple-history');
|
2678 |
+
break;
|
2679 |
+
|
2680 |
+
case 'notice':
|
2681 |
+
$str_translated = _x('notice', 'Log level in gui', 'simple-history');
|
2682 |
+
break;
|
2683 |
+
|
2684 |
+
case 'info':
|
2685 |
+
$str_translated = _x('info', 'Log level in gui', 'simple-history');
|
2686 |
+
break;
|
2687 |
+
|
2688 |
+
case 'debug':
|
2689 |
+
$str_translated = _x('debug', 'Log level in gui', 'simple-history');
|
2690 |
+
break;
|
2691 |
+
|
2692 |
+
// Uppercase
|
2693 |
+
case 'Emergency':
|
2694 |
+
$str_translated = _x('Emergency', 'Log level in gui', 'simple-history');
|
2695 |
+
break;
|
2696 |
+
|
2697 |
+
case 'Alert':
|
2698 |
+
$str_translated = _x('Alert', 'Log level in gui', 'simple-history');
|
2699 |
+
break;
|
2700 |
+
|
2701 |
+
case 'Critical':
|
2702 |
+
$str_translated = _x('Critical', 'Log level in gui', 'simple-history');
|
2703 |
+
break;
|
2704 |
+
|
2705 |
+
case 'Error':
|
2706 |
+
$str_translated = _x('Error', 'Log level in gui', 'simple-history');
|
2707 |
+
break;
|
2708 |
+
|
2709 |
+
case 'Warning':
|
2710 |
+
$str_translated = _x('Warning', 'Log level in gui', 'simple-history');
|
2711 |
+
break;
|
2712 |
+
|
2713 |
+
case 'Notice':
|
2714 |
+
$str_translated = _x('Notice', 'Log level in gui', 'simple-history');
|
2715 |
+
break;
|
2716 |
+
|
2717 |
+
case 'Info':
|
2718 |
+
$str_translated = _x('Info', 'Log level in gui', 'simple-history');
|
2719 |
+
break;
|
2720 |
+
|
2721 |
+
case 'Debug':
|
2722 |
+
$str_translated = _x('Debug', 'Log level in gui', 'simple-history');
|
2723 |
+
break;
|
2724 |
+
|
2725 |
+
default:
|
2726 |
+
$str_translated = $loglevel;
|
2727 |
+
}// End switch().
|
2728 |
+
|
2729 |
+
return $str_translated;
|
2730 |
+
}
|
2731 |
+
|
2732 |
+
public function getInstantiatedLoggers()
|
2733 |
+
{
|
2734 |
+
return $this->instantiatedLoggers;
|
2735 |
+
}
|
2736 |
+
|
2737 |
+
public function getInstantiatedDropins()
|
2738 |
+
{
|
2739 |
+
return $this->instantiatedDropins;
|
2740 |
+
}
|
2741 |
+
|
2742 |
+
/**
|
2743 |
+
* @param string $slug
|
2744 |
+
* @return mixed logger instance if found, bool false if logger not found
|
2745 |
+
*/
|
2746 |
+
public function getInstantiatedLoggerBySlug($slug = '')
|
2747 |
+
{
|
2748 |
+
if (empty($slug)) {
|
2749 |
+
return false;
|
2750 |
+
}
|
2751 |
+
|
2752 |
+
foreach ($this->getInstantiatedLoggers() as $one_logger) {
|
2753 |
+
if ($slug == $one_logger['instance']->slug) {
|
2754 |
+
return $one_logger['instance'];
|
2755 |
+
}
|
2756 |
+
}
|
2757 |
+
|
2758 |
+
return false;
|
2759 |
+
}
|
2760 |
+
|
2761 |
+
/**
|
2762 |
+
* Check which loggers a user has the right to read and return an array
|
2763 |
+
* with all loggers they are allowed to read
|
2764 |
+
*
|
2765 |
+
* @param int $user_id Id of user to get loggers for. Defaults to current user id.
|
2766 |
+
* @param string $format format to return loggers in. Default is array. Can also be "sql"
|
2767 |
+
* @return array
|
2768 |
+
*/
|
2769 |
+
public function getLoggersThatUserCanRead($user_id = '', $format = 'array')
|
2770 |
+
{
|
2771 |
+
$arr_loggers_user_can_view = array();
|
2772 |
+
|
2773 |
+
if (! is_numeric($user_id)) {
|
2774 |
+
$user_id = get_current_user_id();
|
2775 |
+
}
|
2776 |
+
|
2777 |
+
$loggers = $this->getInstantiatedLoggers();
|
2778 |
+
foreach ($loggers as $one_logger) {
|
2779 |
+
$logger_capability = $one_logger['instance']->getCapability();
|
2780 |
+
|
2781 |
+
// $arr_loggers_user_can_view = apply_filters("simple_history/loggers_user_can_read", $user_id, $arr_loggers_user_can_view);
|
2782 |
+
$user_can_read_logger = user_can($user_id, $logger_capability);
|
2783 |
+
$user_can_read_logger = apply_filters(
|
2784 |
+
'simple_history/loggers_user_can_read/can_read_single_logger',
|
2785 |
+
$user_can_read_logger,
|
2786 |
+
$one_logger['instance'],
|
2787 |
+
$user_id
|
2788 |
+
);
|
2789 |
+
|
2790 |
+
if ($user_can_read_logger) {
|
2791 |
+
$arr_loggers_user_can_view[] = $one_logger;
|
2792 |
+
}
|
2793 |
+
}
|
2794 |
+
|
2795 |
+
/**
|
2796 |
+
* Fires before Simple History does it's init stuff
|
2797 |
+
*
|
2798 |
+
* @since 2.0
|
2799 |
+
*
|
2800 |
+
* @param array $arr_loggers_user_can_view Array with loggers that user $user_id can read
|
2801 |
+
* @param int user_id ID of user to check read capability for
|
2802 |
+
*/
|
2803 |
+
$arr_loggers_user_can_view = apply_filters(
|
2804 |
+
'simple_history/loggers_user_can_read',
|
2805 |
+
$arr_loggers_user_can_view,
|
2806 |
+
$user_id
|
2807 |
+
);
|
2808 |
+
|
2809 |
+
// just return array with slugs in parenthesis suitable for sql-where
|
2810 |
+
if ('sql' == $format) {
|
2811 |
+
$str_return = '(';
|
2812 |
+
|
2813 |
+
if (sizeof($arr_loggers_user_can_view)) {
|
2814 |
+
foreach ($arr_loggers_user_can_view as $one_logger) {
|
2815 |
+
$str_return .= sprintf('"%1$s", ', esc_sql($one_logger['instance']->slug));
|
2816 |
+
}
|
2817 |
+
|
2818 |
+
$str_return = rtrim($str_return, ' ,');
|
2819 |
+
} else {
|
2820 |
+
// user was not allowed to read any loggers, return in (NULL) to return nothing
|
2821 |
+
$str_return .= 'NULL';
|
2822 |
+
}
|
2823 |
+
|
2824 |
+
$str_return .= ')';
|
2825 |
+
|
2826 |
+
return $str_return;
|
2827 |
+
}
|
2828 |
+
|
2829 |
+
return $arr_loggers_user_can_view;
|
2830 |
+
}
|
2831 |
+
|
2832 |
+
/**
|
2833 |
+
* Retrieve the avatar for a user who provided a user ID or email address.
|
2834 |
+
* A modified version of the function that comes with WordPress, but we
|
2835 |
+
* want to allow/show gravatars even if they are disabled in discussion settings
|
2836 |
+
*
|
2837 |
+
* @since 2.0
|
2838 |
+
*
|
2839 |
+
* @param string $email email address
|
2840 |
+
* @param int $size Size of the avatar image
|
2841 |
+
* @param string $default URL to a default image to use if no avatar is available
|
2842 |
+
* @param string $alt Alternative text to use in image tag. Defaults to blank
|
2843 |
+
* @return string <img> tag for the user's avatar
|
2844 |
+
*/
|
2845 |
+
public function get_avatar($email, $size = '96', $default = '', $alt = false)
|
2846 |
+
{
|
2847 |
+
// WP setting for avatars is to show, so just use the built in function
|
2848 |
+
if (get_option('show_avatars')) {
|
2849 |
+
$avatar = get_avatar($email, $size, $default, $alt);
|
2850 |
+
|
2851 |
+
return $avatar;
|
2852 |
+
} else {
|
2853 |
+
// WP setting for avatar was to not show, but we do it anyway, using the same code as get_avatar() would have used
|
2854 |
+
if (false === $alt) {
|
2855 |
+
$safe_alt = '';
|
2856 |
+
} else {
|
2857 |
+
$safe_alt = esc_attr($alt);
|
2858 |
+
}
|
2859 |
+
|
2860 |
+
if (! is_numeric($size)) {
|
2861 |
+
$size = '96';
|
2862 |
+
}
|
2863 |
+
|
2864 |
+
if (empty($default)) {
|
2865 |
+
$avatar_default = get_option('avatar_default');
|
2866 |
+
if (empty($avatar_default)) {
|
2867 |
+
$default = 'mystery';
|
2868 |
+
} else {
|
2869 |
+
$default = $avatar_default;
|
2870 |
+
}
|
2871 |
+
}
|
2872 |
+
|
2873 |
+
if (! empty($email)) {
|
2874 |
+
$email_hash = md5(strtolower(trim($email)));
|
2875 |
+
}
|
2876 |
+
|
2877 |
+
if (is_ssl()) {
|
2878 |
+
$host = 'https://secure.gravatar.com';
|
2879 |
+
} else {
|
2880 |
+
if (! empty($email)) {
|
2881 |
+
$host = sprintf('http://%d.gravatar.com', hexdec($email_hash[0]) % 2);
|
2882 |
+
} else {
|
2883 |
+
$host = 'http://0.gravatar.com';
|
2884 |
+
}
|
2885 |
+
}
|
2886 |
+
|
2887 |
+
if ('mystery' == $default) {
|
2888 |
+
$default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
|
2889 |
+
} elseif ('blank' == $default) {
|
2890 |
+
$default = $email ? 'blank' : includes_url('images/blank.gif');
|
2891 |
+
} elseif (! empty($email) && 'gravatar_default' == $default) {
|
2892 |
+
$default = '';
|
2893 |
+
} elseif ('gravatar_default' == $default) {
|
2894 |
+
$default = "$host/avatar/?s={$size}";
|
2895 |
+
} elseif (empty($email)) {
|
2896 |
+
$default = "$host/avatar/?d=$default&s={$size}";
|
2897 |
+
} elseif (strpos($default, 'http://') === 0) {
|
2898 |
+
$default = add_query_arg('s', $size, $default);
|
2899 |
+
}
|
2900 |
+
|
2901 |
+
if (! empty($email)) {
|
2902 |
+
$out = "$host/avatar/";
|
2903 |
+
$out .= $email_hash;
|
2904 |
+
$out .= '?s=' . $size;
|
2905 |
+
$out .= '&d=' . urlencode($default);
|
2906 |
+
|
2907 |
+
$rating = get_option('avatar_rating');
|
2908 |
+
if (! empty($rating)) {
|
2909 |
+
$out .= "&r={$rating}";
|
2910 |
+
}
|
2911 |
+
|
2912 |
+
$out = str_replace('&', '&', esc_url($out));
|
2913 |
+
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
|
2914 |
+
} else {
|
2915 |
+
$out = esc_url($default);
|
2916 |
+
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
|
2917 |
+
}
|
2918 |
+
|
2919 |
+
/**
|
2920 |
+
* Filter the avatar to retrieve.
|
2921 |
+
* Same filter WordPress uses
|
2922 |
+
*
|
2923 |
+
* @since 2.0.19
|
2924 |
+
*
|
2925 |
+
* @param string $avatar Image tag for the user's avatar.
|
2926 |
+
* @param int|object|string $id_or_email A user ID, email address, or comment object.
|
2927 |
+
* @param int $size Square avatar width and height in pixels to retrieve.
|
2928 |
+
* @param string $alt Alternative text to use in the avatar image tag.
|
2929 |
+
* Default empty.
|
2930 |
+
*/
|
2931 |
+
$avatar = apply_filters('get_avatar', $avatar, $email, $size, $default, $alt);
|
2932 |
+
|
2933 |
+
return $avatar;
|
2934 |
+
} // End if().
|
2935 |
+
}
|
2936 |
+
|
2937 |
+
/**
|
2938 |
+
* Quick stats above the log
|
2939 |
+
* Uses filter "simple_history/history_page/before_gui" to output its contents
|
2940 |
+
*/
|
2941 |
+
public function output_quick_stats()
|
2942 |
+
{
|
2943 |
+
global $wpdb;
|
2944 |
+
|
2945 |
+
// Get number of events today
|
2946 |
+
$logQuery = new SimpleHistoryLogQuery();
|
2947 |
+
$logResults = $logQuery->query(array(
|
2948 |
+
'posts_per_page' => 1,
|
2949 |
+
'date_from' => strtotime('today')
|
2950 |
+
));
|
2951 |
+
|
2952 |
+
$total_row_count = (int) $logResults['total_row_count'];
|
2953 |
+
|
2954 |
+
// Get sql query for where to read only loggers current user is allowed to read/view
|
2955 |
+
$sql_loggers_in = $this->getLoggersThatUserCanRead(get_current_user_id(), 'sql');
|
2956 |
+
|
2957 |
+
// Get number of users today, i.e. events with wp_user as initiator
|
2958 |
+
$sql_users_today = sprintf(
|
2959 |
+
'
|
2960 |
+
SELECT
|
2961 |
+
DISTINCT(c.value) AS user_id
|
2962 |
+
#h.id, h.logger, h.level, h.initiator, h.date
|
2963 |
+
FROM %3$s AS h
|
2964 |
+
INNER JOIN %4$s AS c
|
2965 |
+
ON c.history_id = h.id AND c.key = "_user_id"
|
2966 |
+
WHERE
|
2967 |
+
initiator = "wp_user"
|
2968 |
+
AND logger IN %1$s
|
2969 |
+
AND date > "%2$s"
|
2970 |
+
',
|
2971 |
+
$sql_loggers_in,
|
2972 |
+
date('Y-m-d H:i', strtotime('today')),
|
2973 |
+
$wpdb->prefix . SimpleHistory::DBTABLE,
|
2974 |
+
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS
|
2975 |
+
);
|
2976 |
+
|
2977 |
+
$cache_key = 'quick_stats_users_today_' . md5(serialize($sql_loggers_in));
|
2978 |
+
$cache_group = 'simple-history-' . $this->get_cache_incrementor();
|
2979 |
+
$results_users_today = wp_cache_get($cache_key, $cache_group);
|
2980 |
+
|
2981 |
+
if (false === $results_users_today) {
|
2982 |
+
$results_users_today = $wpdb->get_results($sql_users_today);
|
2983 |
+
wp_cache_set($cache_key, $results_users_today, $cache_group);
|
2984 |
+
}
|
2985 |
+
|
2986 |
+
$count_users_today = sizeof($results_users_today);
|
2987 |
+
|
2988 |
+
// Get number of other sources (not wp_user)
|
2989 |
+
$sql_other_sources_where = sprintf(
|
2990 |
+
'
|
2991 |
+
initiator <> "wp_user"
|
2992 |
+
AND logger IN %1$s
|
2993 |
+
AND date > "%2$s"
|
2994 |
+
',
|
2995 |
+
$sql_loggers_in,
|
2996 |
+
date('Y-m-d H:i', strtotime('today')),
|
2997 |
+
$wpdb->prefix . SimpleHistory::DBTABLE,
|
2998 |
+
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS
|
2999 |
+
);
|
3000 |
+
|
3001 |
+
$sql_other_sources_where = apply_filters('simple_history/quick_stats_where', $sql_other_sources_where);
|
3002 |
+
|
3003 |
+
$sql_other_sources = sprintf(
|
3004 |
+
'
|
3005 |
+
SELECT
|
3006 |
+
DISTINCT(h.initiator) AS initiator
|
3007 |
+
FROM %3$s AS h
|
3008 |
+
WHERE
|
3009 |
+
%5$s
|
3010 |
+
',
|
3011 |
+
$sql_loggers_in,
|
3012 |
+
date('Y-m-d H:i', strtotime('today')),
|
3013 |
+
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3014 |
+
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS,
|
3015 |
+
$sql_other_sources_where // 5
|
3016 |
+
);
|
3017 |
+
// sf_d($sql_other_sources, '$sql_other_sources');
|
3018 |
+
$cache_key = 'quick_stats_results_other_sources_today_' . md5(serialize($sql_other_sources));
|
3019 |
+
$results_other_sources_today = wp_cache_get($cache_key, $cache_group);
|
3020 |
+
|
3021 |
+
if (false === $results_other_sources_today) {
|
3022 |
+
$results_other_sources_today = $wpdb->get_results($sql_other_sources);
|
3023 |
+
wp_cache_set($cache_key, $results_other_sources_today, $cache_group);
|
3024 |
+
}
|
3025 |
+
|
3026 |
+
$count_other_sources = sizeof($results_other_sources_today);
|
3027 |
+
|
3028 |
+
// sf_d($logResults, '$logResults');
|
3029 |
+
// sf_d($results_users_today, '$sql_users_today');
|
3030 |
+
// sf_d($results_other_sources_today, '$results_other_sources_today');
|
3031 |
+
?>
|
3032 |
+
<div class="SimpleHistoryQuickStats">
|
3033 |
+
<p>
|
3034 |
+
<?php
|
3035 |
+
$msg_tmpl = '';
|
3036 |
+
|
3037 |
+
// No results today at all
|
3038 |
+
if ($total_row_count == 0) {
|
3039 |
+
$msg_tmpl = __('No events today so far.', 'simple-history');
|
3040 |
+
} else {
|
3041 |
+
/*
|
3042 |
+
Type of results
|
3043 |
+
x1 event today from 1 user.
|
3044 |
+
x1 event today from 1 source.
|
3045 |
+
3 events today from 1 user.
|
3046 |
+
x2 events today from 2 users.
|
3047 |
+
x2 events today from 1 user and 1 other source.
|
3048 |
+
x3 events today from 2 users and 1 other source.
|
3049 |
+
x3 events today from 1 user and 2 other sources.
|
3050 |
+
x4 events today from 2 users and 2 other sources.
|
3051 |
+
*/
|
3052 |
+
|
3053 |
+
// A single event existed and was from a user
|
3054 |
+
// 1 event today from 1 user.
|
3055 |
+
if ($total_row_count == 1 && $count_users_today == 1) {
|
3056 |
+
$msg_tmpl .= __('One event today from one user.', 'simple-history');
|
3057 |
+
}
|
3058 |
+
|
3059 |
+
// A single event existed and was from another source
|
3060 |
+
// 1 event today from 1 source.
|
3061 |
+
if ($total_row_count == 1 && ! $count_users_today) {
|
3062 |
+
$msg_tmpl .= __('One event today from one source.', 'simple-history');
|
3063 |
+
}
|
3064 |
+
|
3065 |
+
// Multiple events from a single user
|
3066 |
+
// 3 events today from one user.
|
3067 |
+
if ($total_row_count > 1 && $count_users_today == 1 && ! $count_other_sources) {
|
3068 |
+
$msg_tmpl .= __('%1$d events today from one user.', 'simple-history');
|
3069 |
+
}
|
3070 |
+
|
3071 |
+
// Multiple events from only users
|
3072 |
+
// 2 events today from 2 users.
|
3073 |
+
if ($total_row_count > 1 && $count_users_today == $total_row_count) {
|
3074 |
+
$msg_tmpl .= __('%1$d events today from %2$d users.', 'simple-history');
|
3075 |
+
}
|
3076 |
+
|
3077 |
+
// Multiple events from 1 single user and 1 single other source
|
3078 |
+
// 2 events today from 1 user and 1 other source.
|
3079 |
+
if ($total_row_count && 1 == $count_users_today && 1 == $count_other_sources) {
|
3080 |
+
$msg_tmpl .= __('%1$d events today from one user and one other source.', 'simple-history');
|
3081 |
+
}
|
3082 |
+
|
3083 |
+
// Multiple events from multple users but from only 1 single other source
|
3084 |
+
// 3 events today from 2 users and 1 other source.
|
3085 |
+
if ($total_row_count > 1 && $count_users_today > 1 && $count_other_sources == 1) {
|
3086 |
+
$msg_tmpl .= __('%1$d events today from one user and one other source.', 'simple-history');
|
3087 |
+
}
|
3088 |
+
|
3089 |
+
// Multiple events from 1 user but from multiple other source
|
3090 |
+
// 3 events today from 1 user and 2 other sources.
|
3091 |
+
if ($total_row_count > 1 && 1 == $count_users_today && $count_other_sources > 1) {
|
3092 |
+
$msg_tmpl .= __('%1$d events today from one user and %3$d other sources.', 'simple-history');
|
3093 |
+
}
|
3094 |
+
|
3095 |
+
// Multiple events from multiple user and from multiple other sources
|
3096 |
+
// 4 events today from 2 users and 2 other sources.
|
3097 |
+
if ($total_row_count > 1 && $count_users_today > 1 && $count_other_sources > 1) {
|
3098 |
+
$msg_tmpl .= __('%1$s events today from %2$d users and %3$d other sources.', 'simple-history');
|
3099 |
+
}
|
3100 |
+
}// End if().
|
3101 |
+
|
3102 |
+
// only show stats if we have something to output
|
3103 |
+
if ($msg_tmpl) {
|
3104 |
+
printf(
|
3105 |
+
$msg_tmpl,
|
3106 |
+
$logResults['total_row_count'], // 1
|
3107 |
+
$count_users_today, // 2
|
3108 |
+
$count_other_sources // 3
|
3109 |
+
);
|
3110 |
+
|
3111 |
+
// Space between texts
|
3112 |
+
/*
|
3113 |
+
echo " ";
|
3114 |
+
|
3115 |
+
// http://playground-root.ep/wp-admin/options-general.php?page=simple_history_settings_menu_slug&selected-tab=stats
|
3116 |
+
printf(
|
3117 |
+
'<a href="%1$s">View more stats</a>.',
|
3118 |
+
add_query_arg("selected-tab", "stats", menu_page_url(SimpleHistory::SETTINGS_MENU_SLUG, 0))
|
3119 |
+
);
|
3120 |
+
*/
|
3121 |
+
}?>
|
3122 |
+
</p>
|
3123 |
+
</div>
|
3124 |
+
<?php
|
3125 |
+
} // output_quick_stats
|
3126 |
+
|
3127 |
+
/**
|
3128 |
+
* https://www.tollmanz.com/invalidation-schemes/
|
3129 |
+
*
|
3130 |
+
* @param $refresh bool
|
3131 |
+
* @return string
|
3132 |
+
*/
|
3133 |
+
public static function get_cache_incrementor($refresh = false)
|
3134 |
+
{
|
3135 |
+
$incrementor_key = 'simple_history_incrementor';
|
3136 |
+
$incrementor_value = wp_cache_get($incrementor_key);
|
3137 |
+
|
3138 |
+
if (false === $incrementor_value || true === $refresh) {
|
3139 |
+
$incrementor_value = time();
|
3140 |
+
wp_cache_set($incrementor_key, $incrementor_value);
|
3141 |
+
}
|
3142 |
+
|
3143 |
+
// echo "<br>incrementor_value: $incrementor_value";
|
3144 |
+
return $incrementor_value;
|
3145 |
+
}
|
3146 |
+
|
3147 |
+
// Number of rows the last n days
|
3148 |
+
public function get_num_events_last_n_days($period_days = 28)
|
3149 |
+
{
|
3150 |
+
$transient_key = 'sh_' . md5(__METHOD__ . $period_days . '_2');
|
3151 |
+
|
3152 |
+
$count = get_transient($transient_key);
|
3153 |
+
|
3154 |
+
if (false === $count) {
|
3155 |
+
global $wpdb;
|
3156 |
+
|
3157 |
+
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead(null, 'sql');
|
3158 |
+
|
3159 |
+
$sql = sprintf(
|
3160 |
+
'
|
3161 |
+
SELECT count(*)
|
3162 |
+
FROM %1$s
|
3163 |
+
WHERE UNIX_TIMESTAMP(date) >= %2$d
|
3164 |
+
AND logger IN %3$s
|
3165 |
+
',
|
3166 |
+
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3167 |
+
strtotime("-$period_days days"),
|
3168 |
+
$sqlStringLoggersUserCanRead
|
3169 |
+
);
|
3170 |
+
|
3171 |
+
$count = $wpdb->get_var($sql);
|
3172 |
+
|
3173 |
+
set_transient($transient_key, $count, HOUR_IN_SECONDS);
|
3174 |
+
}
|
3175 |
+
|
3176 |
+
return $count;
|
3177 |
+
} // get_num_events_last_n_days
|
3178 |
+
|
3179 |
+
public function get_num_events_per_day_last_n_days($period_days = 28)
|
3180 |
+
{
|
3181 |
+
$transient_key = 'sh_' . md5(__METHOD__ . $period_days . '_2');
|
3182 |
+
|
3183 |
+
$dates = get_transient($transient_key);
|
3184 |
+
|
3185 |
+
if (false === $dates) {
|
3186 |
+
global $wpdb;
|
3187 |
+
|
3188 |
+
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead(null, 'sql');
|
3189 |
+
|
3190 |
+
$sql = sprintf(
|
3191 |
+
'
|
3192 |
+
SELECT
|
3193 |
+
date_format(date, "%%Y-%%m-%%d") AS yearDate,
|
3194 |
+
count(date) AS count
|
3195 |
+
FROM
|
3196 |
+
%1$s
|
3197 |
+
WHERE
|
3198 |
+
UNIX_TIMESTAMP(date) >= %2$d
|
3199 |
+
AND logger IN (%3$d)
|
3200 |
+
GROUP BY yearDate
|
3201 |
+
ORDER BY yearDate ASC
|
3202 |
+
',
|
3203 |
+
$wpdb->prefix . SimpleHistory::DBTABLE,
|
3204 |
+
strtotime("-$period_days days"),
|
3205 |
+
$sqlStringLoggersUserCanRead
|
3206 |
+
);
|
3207 |
+
|
3208 |
+
$dates = $wpdb->get_results($sql);
|
3209 |
+
|
3210 |
+
set_transient($transient_key, $dates, HOUR_IN_SECONDS);
|
3211 |
+
// echo "set";exit;
|
3212 |
+
} else {
|
3213 |
+
// echo "get";exit;
|
3214 |
+
}
|
3215 |
+
|
3216 |
+
return $dates;
|
3217 |
+
} // get_num_events_per_day_for_period
|
3218 |
+
|
3219 |
+
// Number of unique events the last n days
|
3220 |
+
public function get_unique_events_for_days($days = 7)
|
3221 |
+
{
|
3222 |
+
global $wpdb;
|
3223 |
+
|
3224 |
+
$days = (int) $days;
|
3225 |
+
|
3226 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
3227 |
+
|
3228 |
+
$cache_key = 'sh_' . md5(__METHOD__ . $days);
|
3229 |
+
|
3230 |
+
$numEvents = get_transient($cache_key);
|
3231 |
+
|
3232 |
+
if (false == $numEvents) {
|
3233 |
+
$sql = $wpdb->prepare(
|
3234 |
+
"
|
3235 |
+
SELECT count( DISTINCT occasionsID )
|
3236 |
+
FROM $table_name
|
3237 |
+
WHERE date >= DATE_ADD(CURDATE(), INTERVAL -%d DAY)
|
3238 |
+
",
|
3239 |
+
$days
|
3240 |
+
);
|
3241 |
+
|
3242 |
+
$numEvents = $wpdb->get_var($sql);
|
3243 |
+
|
3244 |
+
set_transient($cache_key, $numEvents, HOUR_IN_SECONDS);
|
3245 |
+
}
|
3246 |
+
|
3247 |
+
return $numEvents;
|
3248 |
+
} // get_unique_events_for_days
|
3249 |
+
|
3250 |
+
/**
|
3251 |
+
* Output an admin notice about logger slug being to long
|
3252 |
+
*/
|
3253 |
+
public function admin_notice_logger_slug_to_long()
|
3254 |
+
{
|
3255 |
+
?>
|
3256 |
+
<div class="error notice">
|
3257 |
+
<p>
|
3258 |
+
<?php
|
3259 |
+
echo esc_html__(
|
3260 |
+
'The slug for a logger in Simple History can be max 30 chars long.',
|
3261 |
+
'simple-history'
|
3262 |
+
);
|
3263 |
+
?></p>
|
3264 |
+
</div>
|
3265 |
+
<?php
|
3266 |
+
}
|
3267 |
+
} // class
|
inc/SimpleHistoryLogQuery.php
CHANGED
@@ -1,133 +1,134 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Queries the Simple History Log
|
7 |
*/
|
8 |
-
class SimpleHistoryLogQuery
|
|
|
9 |
|
10 |
-
|
|
|
11 |
|
12 |
-
|
13 |
-
|
14 |
|
15 |
-
|
16 |
|
17 |
-
|
18 |
-
|
|
|
19 |
|
20 |
-
|
|
|
|
|
21 |
|
22 |
-
|
23 |
-
|
24 |
|
25 |
-
|
26 |
-
|
27 |
|
28 |
-
|
29 |
-
|
30 |
|
31 |
-
|
32 |
-
|
33 |
|
34 |
-
|
35 |
-
|
36 |
|
37 |
-
|
38 |
-
|
|
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
'max_id_first_page' => null,
|
43 |
|
44 |
-
|
45 |
-
|
|
|
|
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
'date_to' => null,
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
|
|
|
55 |
|
56 |
-
|
57 |
-
|
58 |
-
// "lastdays:7" for the last 7 days
|
59 |
-
'dates' => null,
|
60 |
|
61 |
-
|
62 |
-
|
63 |
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
'loggers' => null,
|
69 |
|
70 |
-
|
|
|
71 |
|
72 |
-
|
73 |
-
|
74 |
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
77 |
|
78 |
-
|
79 |
-
// occasionsCount
|
80 |
-
// occasionsCountMaxReturn
|
81 |
-
// occasionsID
|
82 |
-
// If rows should be returned, or the actualy sql query used
|
83 |
-
'returnQuery' => false,
|
84 |
|
85 |
-
|
|
|
|
|
|
|
|
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
$cache_group = 'simple-history-' . SimpleHistory::get_cache_incrementor();
|
91 |
-
$arr_return = wp_cache_get( $cache_key, $cache_group );
|
92 |
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
-
|
98 |
-
Subequent occasions query thanks to this Stack Overflow thread:
|
99 |
-
http://stackoverflow.com/questions/13566303/how-to-group-subsequent-rows-based-on-a-criteria-and-then-count-them-mysql/13567320#13567320
|
100 |
-
Similar questions that I didn't manage to understand, work, or did try:
|
101 |
-
- http://stackoverflow.com/questions/23651176/mysql-query-if-dates-are-subsequent
|
102 |
-
- http://stackoverflow.com/questions/17651868/mysql-group-by-subsequent
|
103 |
-
- http://stackoverflow.com/questions/4495242/mysql-number-of-subsequent-occurrences
|
104 |
-
- http://stackoverflow.com/questions/20446242/postgresql-group-subsequent-rows
|
105 |
-
- http://stackoverflow.com/questions/17061156/mysql-group-by-range
|
106 |
-
- http://stackoverflow.com/questions/6602006/complicated-query-with-group-by-and-range-of-prices-in-mysql
|
107 |
-
*/
|
108 |
|
109 |
-
|
|
|
110 |
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
// 3 = db name
|
128 |
-
// 4 = where for inner calc sql query thingie
|
129 |
-
// 5 = db name contexts
|
130 |
-
$sql_tmpl = '
|
131 |
/*NO_SELECT_FOUND_ROWS*/
|
132 |
SELECT
|
133 |
SQL_CALC_FOUND_ROWS
|
@@ -173,20 +174,18 @@ class SimpleHistoryLogQuery {
|
|
173 |
%2$s
|
174 |
';
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
// 3 = db name
|
189 |
-
$sql_tmpl = '
|
190 |
SELECT h.*,
|
191 |
# fake columns that exist in overview query
|
192 |
1 as subsequentOccasions
|
@@ -196,167 +195,147 @@ class SimpleHistoryLogQuery {
|
|
196 |
%2$s
|
197 |
';
|
198 |
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
foreach ( $arr_dates as $one_date ) {
|
310 |
-
|
311 |
-
// If begins with "month:" then strip string and keep only month numbers
|
312 |
-
if ( strpos( $one_date, 'month:' ) === 0 ) {
|
313 |
-
$args['months'][] = substr( $one_date, strlen( 'month:' ) );
|
314 |
-
} elseif ( strpos( $one_date, 'lastdays:' ) === 0 ) {
|
315 |
-
// Only keep largest lastdays value
|
316 |
-
$args['lastdays'] = max( $args['lastdays'], substr( $one_date, strlen( 'lastdays:' ) ) );
|
317 |
-
// $args["lastdays"][] = substr($one_date, strlen("lastdays:"));
|
318 |
-
}
|
319 |
-
}
|
320 |
-
}
|
321 |
-
|
322 |
-
// lastdays, as int
|
323 |
-
if ( ! empty( $args['lastdays'] ) ) {
|
324 |
-
|
325 |
-
$inner_where .= sprintf('
|
326 |
# lastdays
|
327 |
AND date >= DATE(NOW()) - INTERVAL %d DAY
|
328 |
', $args['lastdays']);
|
|
|
329 |
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
|
|
|
|
|
|
334 |
|
335 |
-
|
336 |
-
$arr_months = $args['months'];
|
337 |
-
} else {
|
338 |
-
$arr_months = explode( ',', $args['months'] );
|
339 |
-
}
|
340 |
-
|
341 |
-
$sql_months = '
|
342 |
# sql_months
|
343 |
AND (
|
344 |
';
|
345 |
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
$date_month_beginning = strtotime( $one_month );
|
352 |
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
|
358 |
-
|
359 |
-
|
360 |
(
|
361 |
date >= "%1$s"
|
362 |
AND date <= "%2$s"
|
@@ -364,478 +343,446 @@ class SimpleHistoryLogQuery {
|
|
364 |
|
365 |
OR
|
366 |
',
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
}
|
372 |
|
373 |
-
|
374 |
-
|
375 |
|
376 |
-
|
377 |
# end sql_months and wrap
|
378 |
)
|
379 |
';
|
380 |
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
}
|
513 |
-
|
514 |
-
$arr_loggers_and_messages[ $arr_one_logger_and_message[0] ][] = $arr_one_logger_and_message[1];
|
515 |
-
|
516 |
-
}
|
517 |
-
}
|
518 |
-
|
519 |
-
// Now create sql where based on loggers and messages
|
520 |
-
$sql_messages_where = ' AND (';
|
521 |
-
// print_r($arr_loggers_and_messages);exit;
|
522 |
-
foreach ( $arr_loggers_and_messages as $logger_slug => $logger_messages ) {
|
523 |
-
$sql_messages_where .= sprintf(
|
524 |
-
'
|
525 |
(
|
526 |
h.logger = "%1$s"
|
527 |
AND c1.value IN (%2$s)
|
528 |
)
|
529 |
OR ',
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
$userID = (int) $args['user'];
|
628 |
-
$sql_user = sprintf(
|
629 |
-
'
|
630 |
AND id IN ( SELECT history_id FROM %1$s AS c WHERE c.key = "_user_id" AND c.value = %2$s )
|
631 |
',
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
|
636 |
-
|
|
|
637 |
|
638 |
-
|
|
|
|
|
|
|
639 |
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
|
645 |
-
|
646 |
-
|
647 |
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
if ( $users ) {
|
652 |
-
|
653 |
-
$users_in = implode( ',', $users );
|
654 |
-
|
655 |
-
$sql_user = sprintf(
|
656 |
-
'
|
657 |
AND id IN ( SELECT history_id FROM %1$s AS c WHERE c.key = "_user_id" AND c.value IN (%2$s) )
|
658 |
',
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
$min_id = $last_row->id;
|
784 |
-
|
785 |
-
} else {
|
786 |
-
|
787 |
-
// Last row did have occaions, so fetch all occasions, and find id of last one
|
788 |
-
$db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
789 |
-
$sql = sprintf(
|
790 |
-
'
|
791 |
SELECT id, date, occasionsID
|
792 |
FROM %1$s
|
793 |
WHERE id <= %2$s
|
794 |
ORDER BY id DESC
|
795 |
LIMIT %3$s
|
796 |
',
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
} // query
|
840 |
-
|
841 |
} // class
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Queries the Simple History Log
|
7 |
*/
|
8 |
+
class SimpleHistoryLogQuery
|
9 |
+
{
|
10 |
|
11 |
+
public function __construct()
|
12 |
+
{
|
13 |
|
14 |
+
/*
|
15 |
+
if ( is_array($args) && ! empty($args) ) {
|
16 |
|
17 |
+
return $this->query($args);
|
18 |
|
19 |
+
}
|
20 |
+
*/
|
21 |
+
}
|
22 |
|
23 |
+
public function query($args)
|
24 |
+
{
|
25 |
+
$defaults = array(
|
26 |
|
27 |
+
// overview | occasions
|
28 |
+
'type' => 'overview',
|
29 |
|
30 |
+
// Number of posts to show per page. 0 to show all.
|
31 |
+
'posts_per_page' => 0,
|
32 |
|
33 |
+
// Page to show. 1 = first page
|
34 |
+
'paged' => 1,
|
35 |
|
36 |
+
// Array. Only get posts that are in array.
|
37 |
+
'post__in' => null,
|
38 |
|
39 |
+
// array or html
|
40 |
+
'format' => 'array',
|
41 |
|
42 |
+
// If max_id_first_page is set then only get rows
|
43 |
+
// that have id equal or lower than this, to make
|
44 |
+
'max_id_first_page' => null,
|
45 |
|
46 |
+
// if since_id is set the rows returned will only be rows with an ID greater than (i.e. more recent than) since_id
|
47 |
+
'since_id' => null,
|
|
|
48 |
|
49 |
+
// date range
|
50 |
+
// in unix datetime or Y-m-d H:i (or format compatible with strtotime())
|
51 |
+
'date_from' => null,
|
52 |
+
'date_to' => null,
|
53 |
|
54 |
+
// months in format "Y-m"
|
55 |
+
// array or comma separated
|
56 |
+
'months' => null,
|
|
|
57 |
|
58 |
+
// dates in format
|
59 |
+
// "month:2015-06" for june 2015
|
60 |
+
// "lastdays:7" for the last 7 days
|
61 |
+
'dates' => null,
|
62 |
|
63 |
+
// search
|
64 |
+
'search' => null,
|
|
|
|
|
65 |
|
66 |
+
// log levels to include. comma separated or as array. defaults to all.
|
67 |
+
'loglevels' => null,
|
68 |
|
69 |
+
// loggers to include. comma separated. defaults to all the user can read
|
70 |
+
'loggers' => null,
|
71 |
|
72 |
+
'messages' => null,
|
|
|
73 |
|
74 |
+
// userID as number
|
75 |
+
'user' => null,
|
76 |
|
77 |
+
// user ids, comma separated
|
78 |
+
'users' => null,
|
79 |
|
80 |
+
// Can also contain:
|
81 |
+
// occasionsCount
|
82 |
+
// occasionsCountMaxReturn
|
83 |
+
// occasionsID
|
84 |
+
// If rows should be returned, or the actualy sql query used
|
85 |
+
'returnQuery' => false,
|
86 |
|
87 |
+
);
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
+
$args = wp_parse_args($args, $defaults);
|
90 |
+
// sf_d($args, "Run log query with args");
|
91 |
+
$cache_key = 'SimpleHistoryLogQuery_' . md5(serialize($args)) . '_get_' . md5(serialize($_GET)) . '_userid_' . get_current_user_id();
|
92 |
+
$cache_group = 'simple-history-' . SimpleHistory::get_cache_incrementor();
|
93 |
+
$arr_return = wp_cache_get($cache_key, $cache_group);
|
94 |
|
95 |
+
if (false !== $arr_return) {
|
96 |
+
return $arr_return;
|
97 |
+
}
|
|
|
|
|
98 |
|
99 |
+
/*
|
100 |
+
Subequent occasions query thanks to this Stack Overflow thread:
|
101 |
+
http://stackoverflow.com/questions/13566303/how-to-group-subsequent-rows-based-on-a-criteria-and-then-count-them-mysql/13567320#13567320
|
102 |
+
Similar questions that I didn't manage to understand, work, or did try:
|
103 |
+
- http://stackoverflow.com/questions/23651176/mysql-query-if-dates-are-subsequent
|
104 |
+
- http://stackoverflow.com/questions/17651868/mysql-group-by-subsequent
|
105 |
+
- http://stackoverflow.com/questions/4495242/mysql-number-of-subsequent-occurrences
|
106 |
+
- http://stackoverflow.com/questions/20446242/postgresql-group-subsequent-rows
|
107 |
+
- http://stackoverflow.com/questions/17061156/mysql-group-by-range
|
108 |
+
- http://stackoverflow.com/questions/6602006/complicated-query-with-group-by-and-range-of-prices-in-mysql
|
109 |
+
*/
|
110 |
|
111 |
+
global $wpdb;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
|
113 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
114 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
115 |
|
116 |
+
$where = '1 = 1';
|
117 |
+
$limit = '';
|
118 |
+
$inner_where = '1 = 1';
|
119 |
+
|
120 |
+
if ('overview' === $args['type'] || 'single' === $args['type']) {
|
121 |
+
// Set variables used by query
|
122 |
+
$sql_set_var = "SET @a:='', @counter:=1, @groupby:=0";
|
123 |
+
$wpdb->query($sql_set_var);
|
124 |
+
|
125 |
+
// New and slightly faster query
|
126 |
+
// 1 = where
|
127 |
+
// 2 = limit
|
128 |
+
// 3 = db name
|
129 |
+
// 4 = where for inner calc sql query thingie
|
130 |
+
// 5 = db name contexts
|
131 |
+
$sql_tmpl = '
|
|
|
|
|
|
|
|
|
132 |
/*NO_SELECT_FOUND_ROWS*/
|
133 |
SELECT
|
134 |
SQL_CALC_FOUND_ROWS
|
174 |
%2$s
|
175 |
';
|
176 |
|
177 |
+
$sh = SimpleHistory::get_instance();
|
178 |
+
|
179 |
+
// Only include loggers that the current user can view
|
180 |
+
// @TODO: this causes error if user has no access to any logger at all
|
181 |
+
$sql_loggers_user_can_view = $sh->getLoggersThatUserCanRead(get_current_user_id(), 'sql');
|
182 |
+
$inner_where .= " AND logger IN {$sql_loggers_user_can_view}";
|
183 |
+
} elseif ('occasions' === $args['type']) {
|
184 |
+
// Query template
|
185 |
+
// 1 = where
|
186 |
+
// 2 = limit
|
187 |
+
// 3 = db name
|
188 |
+
$sql_tmpl = '
|
|
|
|
|
189 |
SELECT h.*,
|
190 |
# fake columns that exist in overview query
|
191 |
1 as subsequentOccasions
|
195 |
%2$s
|
196 |
';
|
197 |
|
198 |
+
$where .= ' AND h.id < ' . (int) $args['logRowID'];
|
199 |
+
$where .= " AND h.occasionsID = '" . esc_sql($args['occasionsID']) . "'";
|
200 |
+
|
201 |
+
if (isset($args['occasionsCountMaxReturn']) && (int) $args['occasionsCountMaxReturn'] < (int) $args['occasionsCount']) {
|
202 |
+
// Limit to max nn events if occasionsCountMaxReturn is set.
|
203 |
+
// Used in gui to prevent top many events returned, that can stall the browser.
|
204 |
+
$limit = 'LIMIT ' . (int) $args['occasionsCountMaxReturn'];
|
205 |
+
} else {
|
206 |
+
// Regular limit that gets all occasions
|
207 |
+
$limit = 'LIMIT ' . (int) $args['occasionsCount'];
|
208 |
+
}
|
209 |
+
}// End if().
|
210 |
+
|
211 |
+
// Determine limit
|
212 |
+
// Both posts_per_page and paged must be set
|
213 |
+
$is_limit_query = ( is_numeric($args['posts_per_page']) && $args['posts_per_page'] > 0 );
|
214 |
+
$is_limit_query = $is_limit_query && ( is_numeric($args['paged']) && $args['paged'] > 0 );
|
215 |
+
if ($is_limit_query) {
|
216 |
+
$limit_offset = ($args['paged'] - 1) * $args['posts_per_page'];
|
217 |
+
$limit .= sprintf('LIMIT %1$d, %2$d', $limit_offset, $args['posts_per_page']);
|
218 |
+
}
|
219 |
+
|
220 |
+
// Determine where
|
221 |
+
if ($args['post__in'] && is_array($args['post__in'])) {
|
222 |
+
// make sure all vals are integers
|
223 |
+
$args['post__in'] = array_map('intval', $args['post__in']);
|
224 |
+
|
225 |
+
$inner_where .= sprintf(' AND id IN (%1$s)', implode(',', $args['post__in']));
|
226 |
+
}
|
227 |
+
|
228 |
+
// If max_id_first_page is then then only include rows
|
229 |
+
// with id equal to or earlier
|
230 |
+
if (isset($args['max_id_first_page']) && is_numeric($args['max_id_first_page'])) {
|
231 |
+
$max_id_first_page = (int) $args['max_id_first_page'];
|
232 |
+
$inner_where .= sprintf(
|
233 |
+
' AND id <= %1$d',
|
234 |
+
$max_id_first_page
|
235 |
+
);
|
236 |
+
}
|
237 |
+
|
238 |
+
if (isset($args['since_id']) && is_numeric($args['since_id'])) {
|
239 |
+
$since_id = (int) $args['since_id'];
|
240 |
+
/*
|
241 |
+
$where .= sprintf(
|
242 |
+
' AND t.id > %1$d',
|
243 |
+
$since_id
|
244 |
+
);
|
245 |
+
*/
|
246 |
+
// Add where to inner because that's faster
|
247 |
+
$inner_where .= sprintf(
|
248 |
+
' AND id > %1$d',
|
249 |
+
$since_id
|
250 |
+
);
|
251 |
+
}
|
252 |
+
|
253 |
+
// Append date where
|
254 |
+
if (! empty($args['date_from'])) {
|
255 |
+
// date_from=2014-08-01
|
256 |
+
// if date is not numeric assume Y-m-d H:i-format
|
257 |
+
$date_from = $args['date_from'];
|
258 |
+
if (! is_numeric($date_from)) {
|
259 |
+
$date_from = strtotime($date_from);
|
260 |
+
}
|
261 |
+
|
262 |
+
$inner_where .= "\n" . sprintf(' AND date >= "%1$s"', esc_sql(date('Y-m-d H:i:s', $date_from)));
|
263 |
+
}
|
264 |
+
|
265 |
+
if (! empty($args['date_to'])) {
|
266 |
+
// date_to=2014-08-01
|
267 |
+
// if date is not numeric assume Y-m-d H:i-format
|
268 |
+
$date_to = $args['date_to'];
|
269 |
+
if (! is_numeric($date_to)) {
|
270 |
+
$date_to = strtotime($date_to);
|
271 |
+
}
|
272 |
+
|
273 |
+
$inner_where .= "\n" . sprintf(' AND date <= "%1$s"', date('Y-m-d H:i:s', $date_to));
|
274 |
+
}
|
275 |
+
|
276 |
+
/*
|
277 |
+
AND date >= "2015-01-01 00:00:00" AND date <= "2015-01-31 00:00:00"
|
278 |
+
*/
|
279 |
+
// echo $inner_where;exit;
|
280 |
+
// dats
|
281 |
+
// if months they translate to $args["months"] because we already have support for that
|
282 |
+
// can't use months and dates and the same time
|
283 |
+
if (! empty($args['dates'])) {
|
284 |
+
if (is_array($args['dates'])) {
|
285 |
+
$arr_dates = $args['dates'];
|
286 |
+
} else {
|
287 |
+
$arr_dates = explode(',', $args['dates']);
|
288 |
+
}
|
289 |
+
|
290 |
+
$args['months'] = array();
|
291 |
+
$args['lastdays'] = 0;
|
292 |
+
|
293 |
+
foreach ($arr_dates as $one_date) {
|
294 |
+
// If begins with "month:" then strip string and keep only month numbers
|
295 |
+
if (strpos($one_date, 'month:') === 0) {
|
296 |
+
$args['months'][] = substr($one_date, strlen('month:'));
|
297 |
+
} elseif (strpos($one_date, 'lastdays:') === 0) {
|
298 |
+
// Only keep largest lastdays value
|
299 |
+
$args['lastdays'] = max($args['lastdays'], substr($one_date, strlen('lastdays:')));
|
300 |
+
// $args["lastdays"][] = substr($one_date, strlen("lastdays:"));
|
301 |
+
}
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
// lastdays, as int
|
306 |
+
if (! empty($args['lastdays'])) {
|
307 |
+
$inner_where .= sprintf('
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
# lastdays
|
309 |
AND date >= DATE(NOW()) - INTERVAL %d DAY
|
310 |
', $args['lastdays']);
|
311 |
+
}
|
312 |
|
313 |
+
// months, in format "Y-m"
|
314 |
+
if (! empty($args['months'])) {
|
315 |
+
if (is_array($args['months'])) {
|
316 |
+
$arr_months = $args['months'];
|
317 |
+
} else {
|
318 |
+
$arr_months = explode(',', $args['months']);
|
319 |
+
}
|
320 |
|
321 |
+
$sql_months = '
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
# sql_months
|
323 |
AND (
|
324 |
';
|
325 |
|
326 |
+
foreach ($arr_months as $one_month) {
|
327 |
+
// beginning of month
|
328 |
+
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08") ) . "\n";
|
329 |
+
// >> 2014-08-01 00:00
|
330 |
+
$date_month_beginning = strtotime($one_month);
|
|
|
331 |
|
332 |
+
// end of month
|
333 |
+
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08 + 1 month") ) . "\n";'
|
334 |
+
// >> 2014-09-01 00:00
|
335 |
+
$date_month_end = strtotime("{$one_month} + 1 month");
|
336 |
|
337 |
+
$sql_months .= sprintf(
|
338 |
+
'
|
339 |
(
|
340 |
date >= "%1$s"
|
341 |
AND date <= "%2$s"
|
343 |
|
344 |
OR
|
345 |
',
|
346 |
+
date('Y-m-d H:i:s', $date_month_beginning), // 1
|
347 |
+
date('Y-m-d H:i:s', $date_month_end) // 2
|
348 |
+
);
|
349 |
+
}
|
|
|
350 |
|
351 |
+
$sql_months = trim($sql_months);
|
352 |
+
$sql_months = rtrim($sql_months, ' OR ');
|
353 |
|
354 |
+
$sql_months .= '
|
355 |
# end sql_months and wrap
|
356 |
)
|
357 |
';
|
358 |
|
359 |
+
$inner_where .= $sql_months;
|
360 |
+
// echo $inner_where;exit;
|
361 |
+
}// End if().
|
362 |
+
|
363 |
+
// search
|
364 |
+
if (! empty($args['search'])) {
|
365 |
+
$search_words = $args['search'];
|
366 |
+
$str_search_conditions = '';
|
367 |
+
$arr_search_words = preg_split('/[\s,]+/', $search_words);
|
368 |
+
|
369 |
+
// create array of all searched words
|
370 |
+
// split both spaces and commas and such
|
371 |
+
$arr_sql_like_cols = array( 'message', 'logger', 'level' );
|
372 |
+
|
373 |
+
foreach ($arr_sql_like_cols as $one_col) {
|
374 |
+
$str_sql_search_words = '';
|
375 |
+
|
376 |
+
foreach ($arr_search_words as $one_search_word) {
|
377 |
+
if (method_exists($wpdb, 'esc_like')) {
|
378 |
+
$str_like = esc_sql($wpdb->esc_like($one_search_word));
|
379 |
+
} else {
|
380 |
+
$str_like = esc_sql(like_escape($one_search_word));
|
381 |
+
}
|
382 |
+
|
383 |
+
$str_sql_search_words .= sprintf(
|
384 |
+
' AND %1$s LIKE "%2$s" ',
|
385 |
+
$one_col,
|
386 |
+
"%{$str_like}%"
|
387 |
+
);
|
388 |
+
}
|
389 |
+
|
390 |
+
$str_sql_search_words = ltrim($str_sql_search_words, ' AND ');
|
391 |
+
|
392 |
+
$str_search_conditions .= "\n" . sprintf(
|
393 |
+
' OR ( %1$s ) ',
|
394 |
+
$str_sql_search_words
|
395 |
+
);
|
396 |
+
}
|
397 |
+
|
398 |
+
$str_search_conditions = preg_replace('/^OR /', ' ', trim($str_search_conditions));
|
399 |
+
|
400 |
+
// also search contexts
|
401 |
+
$str_search_conditions .= "\n OR ( ";
|
402 |
+
foreach ($arr_search_words as $one_search_word) {
|
403 |
+
if (method_exists($wpdb, 'esc_like')) {
|
404 |
+
$str_like = esc_sql($wpdb->esc_like($one_search_word));
|
405 |
+
} else {
|
406 |
+
$str_like = esc_sql(like_escape($one_search_word));
|
407 |
+
}
|
408 |
+
|
409 |
+
$str_search_conditions .= "\n" . sprintf(
|
410 |
+
' id IN ( SELECT history_id FROM %1$s AS c WHERE c.value LIKE "%2$s" ) AND ',
|
411 |
+
$table_name_contexts, // 1
|
412 |
+
'%' . $str_like . '%' // 2
|
413 |
+
);
|
414 |
+
}
|
415 |
+
$str_search_conditions = preg_replace('/ AND $/', '', $str_search_conditions);
|
416 |
+
|
417 |
+
$str_search_conditions .= "\n ) "; // end or for contexts
|
418 |
+
|
419 |
+
$inner_where .= "\n AND \n(\n {$str_search_conditions} \n ) ";
|
420 |
+
|
421 |
+
// echo $inner_where;exit;
|
422 |
+
}// End if().
|
423 |
+
|
424 |
+
// log levels
|
425 |
+
// comma separated
|
426 |
+
// 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
|
427 |
+
if (! empty($args['loglevels'])) {
|
428 |
+
$sql_loglevels = '';
|
429 |
+
|
430 |
+
if (is_array($args['loglevels'])) {
|
431 |
+
$arr_loglevels = $args['loglevels'];
|
432 |
+
} else {
|
433 |
+
$arr_loglevels = explode(',', $args['loglevels']);
|
434 |
+
}
|
435 |
+
|
436 |
+
foreach ($arr_loglevels as $one_loglevel) {
|
437 |
+
$sql_loglevels .= sprintf(' "%s", ', esc_sql($one_loglevel));
|
438 |
+
}
|
439 |
+
|
440 |
+
if ($sql_loglevels) {
|
441 |
+
$sql_loglevels = rtrim($sql_loglevels, ' ,');
|
442 |
+
$sql_loglevels = "\n AND level IN ({$sql_loglevels}) ";
|
443 |
+
}
|
444 |
+
|
445 |
+
$inner_where .= $sql_loglevels;
|
446 |
+
}
|
447 |
+
|
448 |
+
// messages
|
449 |
+
if (! empty($args['messages'])) {
|
450 |
+
// print_r($args["messages"]);exit;
|
451 |
+
/*
|
452 |
+
Array
|
453 |
+
(
|
454 |
+
[0] => SimpleCommentsLogger:anon_comment_added,SimpleCommentsLogger:user_comment_added,SimpleCommentsLogger:anon_trackback_added,SimpleCommentsLogger:user_trackback_added,SimpleCommentsLogger:anon_pingback_added,SimpleCommentsLogger:user_pingback_added,SimpleCommentsLogger:comment_edited,SimpleCommentsLogger:trackback_edited,SimpleCommentsLogger:pingback_edited,SimpleCommentsLogger:comment_status_approve,SimpleCommentsLogger:trackback_status_approve,SimpleCommentsLogger:pingback_status_approve,SimpleCommentsLogger:comment_status_hold,SimpleCommentsLogger:trackback_status_hold,SimpleCommentsLogger:pingback_status_hold,SimpleCommentsLogger:comment_status_spam,SimpleCommentsLogger:trackback_status_spam,SimpleCommentsLogger:pingback_status_spam,SimpleCommentsLogger:comment_status_trash,SimpleCommentsLogger:trackback_status_trash,SimpleCommentsLogger:pingback_status_trash,SimpleCommentsLogger:comment_untrashed,SimpleCommentsLogger:trackback_untrashed,SimpleCommentsLogger:pingback_untrashed,SimpleCommentsLogger:comment_deleted,SimpleCommentsLogger:trackback_deleted,SimpleCommentsLogger:pingback_deleted
|
455 |
+
[1] => SimpleCommentsLogger:SimpleCommentsLogger:comment_status_spam,SimpleCommentsLogger:trackback_status_spam,SimpleCommentsLogger:pingback_status_spam
|
456 |
+
)
|
457 |
+
*/
|
458 |
+
|
459 |
+
// Array with loggers and messages
|
460 |
+
$arr_loggers_and_messages = array();
|
461 |
+
|
462 |
+
// Tranform from get'et format to our own internal format
|
463 |
+
foreach ((array) $args['messages'] as $one_arr_messages_row) {
|
464 |
+
$arr_row_messages = explode(',', $one_arr_messages_row);
|
465 |
+
// print_r($arr_row_messages);#exit;
|
466 |
+
/*
|
467 |
+
Array
|
468 |
+
(
|
469 |
+
[0] => SimpleCommentsLogger:anon_comment_added
|
470 |
+
[1] => SimpleCommentsLogger:user_comment_added
|
471 |
+
[2] => SimpleCommentsLogger:anon_trackback_added
|
472 |
+
*/
|
473 |
+
foreach ($arr_row_messages as $one_row_logger_and_message) {
|
474 |
+
$arr_one_logger_and_message = explode(':', $one_row_logger_and_message);
|
475 |
+
|
476 |
+
if (! isset($arr_loggers_and_messages[ $arr_one_logger_and_message[0] ])) {
|
477 |
+
$arr_loggers_and_messages[ $arr_one_logger_and_message[0] ] = array();
|
478 |
+
}
|
479 |
+
|
480 |
+
$arr_loggers_and_messages[ $arr_one_logger_and_message[0] ][] = $arr_one_logger_and_message[1];
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
// Now create sql where based on loggers and messages
|
485 |
+
$sql_messages_where = ' AND (';
|
486 |
+
// print_r($arr_loggers_and_messages);exit;
|
487 |
+
foreach ($arr_loggers_and_messages as $logger_slug => $logger_messages) {
|
488 |
+
$sql_messages_where .= sprintf(
|
489 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
490 |
(
|
491 |
h.logger = "%1$s"
|
492 |
AND c1.value IN (%2$s)
|
493 |
)
|
494 |
OR ',
|
495 |
+
esc_sql($logger_slug),
|
496 |
+
"'" . implode("','", $logger_messages) . "'"
|
497 |
+
);
|
498 |
+
}
|
499 |
+
// remove last or
|
500 |
+
$sql_messages_where = preg_replace('/OR $/', '', $sql_messages_where);
|
501 |
+
|
502 |
+
$sql_messages_where .= "\n )";
|
503 |
+
// echo $sql_messages_where;exit;
|
504 |
+
$where .= $sql_messages_where;
|
505 |
+
|
506 |
+
/*
|
507 |
+
print_r($arr_loggers_and_messages);exit;
|
508 |
+
Array
|
509 |
+
(
|
510 |
+
[SimpleCommentsLogger] => Array
|
511 |
+
(
|
512 |
+
[0] => anon_comment_added
|
513 |
+
[1] => user_comment_added
|
514 |
+
[2] => anon_trackback_added
|
515 |
+
[3] => user_trackback_added
|
516 |
+
[4] => anon_pingback_added
|
517 |
+
[5] => user_pingback_added
|
518 |
+
[6] => comment_edited
|
519 |
+
[7] => trackback_edited
|
520 |
+
[8] => pingback_edited
|
521 |
+
[9] => comment_status_approve
|
522 |
+
[10] => trackback_status_approve
|
523 |
+
[11] => pingback_status_approve
|
524 |
+
[12] => comment_status_hold
|
525 |
+
[13] => trackback_status_hold
|
526 |
+
[14] => pingback_status_hold
|
527 |
+
[15] => comment_status_spam
|
528 |
+
[16] => trackback_status_spam
|
529 |
+
[17] => pingback_status_spam
|
530 |
+
[18] => comment_status_trash
|
531 |
+
[19] => trackback_status_trash
|
532 |
+
[20] => pingback_status_trash
|
533 |
+
[21] => comment_untrashed
|
534 |
+
[22] => trackback_untrashed
|
535 |
+
[23] => pingback_untrashed
|
536 |
+
[24] => comment_deleted
|
537 |
+
[25] => trackback_deleted
|
538 |
+
[26] => pingback_deleted
|
539 |
+
)
|
540 |
+
|
541 |
+
[SimpleUserLogger] => Array
|
542 |
+
(
|
543 |
+
[0] => SimpleUserLogger
|
544 |
+
[1] => SimpleUserLogger
|
545 |
+
)
|
546 |
+
|
547 |
+
)
|
548 |
+
|
549 |
+
*/
|
550 |
+
}// End if().
|
551 |
+
|
552 |
+
// loggers
|
553 |
+
// comma separated
|
554 |
+
// 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
|
555 |
+
if (! empty($args['loggers'])) {
|
556 |
+
$sql_loggers = '';
|
557 |
+
if (is_array($args['loggers'])) {
|
558 |
+
$arr_loggers = $args['loggers'];
|
559 |
+
} else {
|
560 |
+
$arr_loggers = explode(',', $args['loggers']);
|
561 |
+
}
|
562 |
+
|
563 |
+
// print_r($args["loggers"]);exit;
|
564 |
+
// print_r($arr_loggers);exit;
|
565 |
+
/*
|
566 |
+
Example of version with logger + message keys
|
567 |
+
Array
|
568 |
+
(
|
569 |
+
[0] => SimpleUserLogger:user_created
|
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 |
+
}
|
577 |
+
|
578 |
+
if ($sql_loggers) {
|
579 |
+
$sql_loggers = rtrim($sql_loggers, ' ,');
|
580 |
+
$sql_loggers = "\n AND logger IN ({$sql_loggers}) ";
|
581 |
+
}
|
582 |
+
|
583 |
+
$inner_where .= $sql_loggers;
|
584 |
+
}
|
585 |
+
|
586 |
+
// user, a single userID
|
587 |
+
if (! empty($args['user']) && is_numeric($args['user'])) {
|
588 |
+
$userID = (int) $args['user'];
|
589 |
+
$sql_user = sprintf(
|
590 |
+
'
|
|
|
|
|
|
|
|
|
591 |
AND id IN ( SELECT history_id FROM %1$s AS c WHERE c.key = "_user_id" AND c.value = %2$s )
|
592 |
',
|
593 |
+
$table_name_contexts, // 1
|
594 |
+
$userID // 2
|
595 |
+
);
|
596 |
|
597 |
+
$inner_where .= $sql_user;
|
598 |
+
}
|
599 |
|
600 |
+
// If users is array, make it comma separated.
|
601 |
+
if (isset($args['users']) && is_array($args['users'])) {
|
602 |
+
$args['users'] = implode(',', $args['users']);
|
603 |
+
}
|
604 |
|
605 |
+
// Users, comma separated.
|
606 |
+
if (! empty($args['users']) && is_string($args['users'])) {
|
607 |
+
$users = explode(',', $args['users']);
|
608 |
+
$users = array_map('intval', $users);
|
609 |
|
610 |
+
if ($users) {
|
611 |
+
$users_in = implode(',', $users);
|
612 |
|
613 |
+
$sql_user = sprintf(
|
614 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
615 |
AND id IN ( SELECT history_id FROM %1$s AS c WHERE c.key = "_user_id" AND c.value IN (%2$s) )
|
616 |
',
|
617 |
+
$table_name_contexts, // 1
|
618 |
+
$users_in // 2
|
619 |
+
);
|
620 |
+
|
621 |
+
$inner_where .= $sql_user;
|
622 |
+
|
623 |
+
// echo $inner_where;exit;
|
624 |
+
}
|
625 |
+
}
|
626 |
+
|
627 |
+
/**
|
628 |
+
* Filter the sql template
|
629 |
+
*
|
630 |
+
* @since 2.0
|
631 |
+
*
|
632 |
+
* @param string $sql_tmpl
|
633 |
+
*/
|
634 |
+
$sql_tmpl = apply_filters('simple_history/log_query_sql_template', $sql_tmpl);
|
635 |
+
|
636 |
+
/**
|
637 |
+
* Filter the sql template where clause
|
638 |
+
*
|
639 |
+
* @since 2.0
|
640 |
+
*
|
641 |
+
* @param string $where
|
642 |
+
*/
|
643 |
+
$where = apply_filters('simple_history/log_query_sql_where', $where);
|
644 |
+
|
645 |
+
/**
|
646 |
+
* Filter the sql template limit
|
647 |
+
*
|
648 |
+
* @since 2.0
|
649 |
+
*
|
650 |
+
* @param string $limit
|
651 |
+
*/
|
652 |
+
$limit = apply_filters('simple_history/log_query_limit', $limit);
|
653 |
+
|
654 |
+
/**
|
655 |
+
* Filter the sql template limit
|
656 |
+
*
|
657 |
+
* @since 2.0
|
658 |
+
*
|
659 |
+
* @param string $limit
|
660 |
+
*/
|
661 |
+
$inner_where = apply_filters('simple_history/log_query_inner_where', $inner_where);
|
662 |
+
|
663 |
+
$sql = sprintf(
|
664 |
+
$sql_tmpl, // sprintf template
|
665 |
+
$where, // 1
|
666 |
+
$limit, // 2
|
667 |
+
$table_name, // 3
|
668 |
+
$inner_where, // 4
|
669 |
+
$table_name_contexts // 5
|
670 |
+
);
|
671 |
+
|
672 |
+
/**
|
673 |
+
* Filter the final sql query
|
674 |
+
*
|
675 |
+
* @since 2.0
|
676 |
+
*
|
677 |
+
* @param string $sql
|
678 |
+
*/
|
679 |
+
$sql = apply_filters('simple_history/log_query_sql', $sql);
|
680 |
+
|
681 |
+
// Remove comments below to debug query (includes query in json result)
|
682 |
+
// $include_query_in_result = true;
|
683 |
+
if (isset($_GET['SimpleHistoryLogQuery-showDebug']) && $_GET['SimpleHistoryLogQuery-showDebug']) {
|
684 |
+
echo '<pre>';
|
685 |
+
echo $sql_set_var;
|
686 |
+
echo $sql;
|
687 |
+
exit;
|
688 |
+
}
|
689 |
+
|
690 |
+
// Only return sql query
|
691 |
+
if ($args['returnQuery']) {
|
692 |
+
return $sql;
|
693 |
+
}
|
694 |
+
|
695 |
+
$log_rows = $wpdb->get_results($sql, OBJECT_K);
|
696 |
+
$num_rows = sizeof($log_rows);
|
697 |
+
|
698 |
+
// Find total number of rows that we would have gotten without pagination
|
699 |
+
// This is the number of rows with occasions taken into consideration
|
700 |
+
$sql_found_rows = 'SELECT FOUND_ROWS()';
|
701 |
+
$total_found_rows = (int) $wpdb->get_var($sql_found_rows);
|
702 |
+
|
703 |
+
// Add context
|
704 |
+
$post_ids = wp_list_pluck($log_rows, 'id');
|
705 |
+
|
706 |
+
if (empty($post_ids)) {
|
707 |
+
$context_results = array();
|
708 |
+
} else {
|
709 |
+
$sql_context = sprintf('SELECT * FROM %2$s WHERE history_id IN (%1$s)', join(',', $post_ids), $table_name_contexts);
|
710 |
+
$context_results = $wpdb->get_results($sql_context);
|
711 |
+
}
|
712 |
+
|
713 |
+
foreach ($context_results as $context_row) {
|
714 |
+
if (! isset($log_rows[ $context_row->history_id ]->context)) {
|
715 |
+
$log_rows[ $context_row->history_id ]->context = array();
|
716 |
+
}
|
717 |
+
|
718 |
+
$log_rows[ $context_row->history_id ]->context[ $context_row->key ] = $context_row->value;
|
719 |
+
}
|
720 |
+
|
721 |
+
// Remove id from keys, because they are cumbersome when working with JSON
|
722 |
+
$log_rows = array_values($log_rows);
|
723 |
+
$min_id = null;
|
724 |
+
$max_id = null;
|
725 |
+
|
726 |
+
if (sizeof($log_rows)) {
|
727 |
+
// Max id is simply the id of the first row
|
728 |
+
$max_id = reset($log_rows)->id;
|
729 |
+
|
730 |
+
// Min id = to find the lowest id we must take occasions into consideration
|
731 |
+
$last_row = end($log_rows);
|
732 |
+
$last_row_occasions_count = (int) $last_row->subsequentOccasions - 1;
|
733 |
+
if ($last_row_occasions_count === 0) {
|
734 |
+
// Last row did not have any more occasions, so get min_id directly from the row
|
735 |
+
$min_id = $last_row->id;
|
736 |
+
} else {
|
737 |
+
// Last row did have occaions, so fetch all occasions, and find id of last one
|
738 |
+
$db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
739 |
+
$sql = sprintf(
|
740 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
741 |
SELECT id, date, occasionsID
|
742 |
FROM %1$s
|
743 |
WHERE id <= %2$s
|
744 |
ORDER BY id DESC
|
745 |
LIMIT %3$s
|
746 |
',
|
747 |
+
$db_table,
|
748 |
+
$last_row->id,
|
749 |
+
$last_row_occasions_count + 1
|
750 |
+
);
|
751 |
+
|
752 |
+
$results = $wpdb->get_results($sql);
|
753 |
+
|
754 |
+
// the last occasion has the id we consider last in this paged result
|
755 |
+
$min_id = end($results)->id;
|
756 |
+
}
|
757 |
+
}// End if().
|
758 |
+
|
759 |
+
// Calc pages
|
760 |
+
if ($args['posts_per_page']) {
|
761 |
+
$pages_count = Ceil($total_found_rows / (int) $args['posts_per_page']);
|
762 |
+
} else {
|
763 |
+
$pages_count = 1;
|
764 |
+
}
|
765 |
+
|
766 |
+
// Create array to return
|
767 |
+
// Make all rows a sub key because we want to add some meta info too
|
768 |
+
$log_rows_count = sizeof($log_rows);
|
769 |
+
$page_rows_from = ( (int) $args['paged'] * (int) $args['posts_per_page'] ) - (int) $args['posts_per_page'] + 1;
|
770 |
+
$page_rows_to = $page_rows_from + $log_rows_count - 1;
|
771 |
+
$arr_return = array(
|
772 |
+
'total_row_count' => $total_found_rows,
|
773 |
+
'pages_count' => $pages_count,
|
774 |
+
'page_current' => (int) $args['paged'],
|
775 |
+
'page_rows_from' => $page_rows_from,
|
776 |
+
'page_rows_to' => $page_rows_to,
|
777 |
+
'max_id' => (int) $max_id,
|
778 |
+
'min_id' => (int) $min_id,
|
779 |
+
'log_rows_count' => $log_rows_count,
|
780 |
+
'log_rows' => $log_rows,
|
781 |
+
);
|
782 |
+
|
783 |
+
// sf_d($arr_return, '$arr_return');exit;
|
784 |
+
wp_cache_set($cache_key, $arr_return, $cache_group);
|
785 |
+
|
786 |
+
return $arr_return;
|
787 |
+
} // query
|
|
|
|
|
|
|
788 |
} // class
|
inc/helpers.php
ADDED
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Helper function with same name as the SimpleLogger-class
|
5 |
+
*
|
6 |
+
* Makes call like this possible:
|
7 |
+
* SimpleLogger()->info("This is a message sent to the log");
|
8 |
+
*/
|
9 |
+
function SimpleLogger()
|
10 |
+
{
|
11 |
+
return new SimpleLogger(SimpleHistory::get_instance());
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Add event to history table
|
16 |
+
* This is here for backwards compatibility
|
17 |
+
* If you use this please consider using
|
18 |
+
* SimpleHistory()->info();
|
19 |
+
* instead
|
20 |
+
*/
|
21 |
+
function simple_history_add($args)
|
22 |
+
{
|
23 |
+
$defaults = array(
|
24 |
+
'action' => null,
|
25 |
+
'object_type' => null,
|
26 |
+
'object_subtype' => null,
|
27 |
+
'object_id' => null,
|
28 |
+
'object_name' => null,
|
29 |
+
'user_id' => null,
|
30 |
+
'description' => null
|
31 |
+
);
|
32 |
+
|
33 |
+
$context = wp_parse_args($args, $defaults);
|
34 |
+
|
35 |
+
$message = "{$context["object_type"]} {$context["object_name"]} {$context["action"]}";
|
36 |
+
|
37 |
+
SimpleLogger()->info($message, $context);
|
38 |
+
} // simple_history_add
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Pretty much same as wp_text_diff() but with this you can set leading and trailing context lines
|
42 |
+
*
|
43 |
+
* @since 2.0.29
|
44 |
+
*
|
45 |
+
*
|
46 |
+
* Original description from wp_text_diff():
|
47 |
+
*
|
48 |
+
* Displays a human readable HTML representation of the difference between two strings.
|
49 |
+
*
|
50 |
+
* The Diff is available for getting the changes between versions. The output is
|
51 |
+
* HTML, so the primary use is for displaying the changes. If the two strings
|
52 |
+
* are equivalent, then an empty string will be returned.
|
53 |
+
*
|
54 |
+
* The arguments supported and can be changed are listed below.
|
55 |
+
*
|
56 |
+
* 'title' : Default is an empty string. Titles the diff in a manner compatible
|
57 |
+
* with the output.
|
58 |
+
* 'title_left' : Default is an empty string. Change the HTML to the left of the
|
59 |
+
* title.
|
60 |
+
* 'title_right' : Default is an empty string. Change the HTML to the right of
|
61 |
+
* the title.
|
62 |
+
*
|
63 |
+
* @see wp_parse_args() Used to change defaults to user defined settings.
|
64 |
+
* @uses Text_Diff
|
65 |
+
* @uses WP_Text_Diff_Renderer_Table
|
66 |
+
*
|
67 |
+
* @param string $left_string "old" (left) version of string
|
68 |
+
* @param string $right_string "new" (right) version of string
|
69 |
+
* @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. And leading_context_lines and trailing_context_lines.
|
70 |
+
* @return string Empty string if strings are equivalent or HTML with differences.
|
71 |
+
*/
|
72 |
+
function simple_history_text_diff($left_string, $right_string, $args = null)
|
73 |
+
{
|
74 |
+
$defaults = array(
|
75 |
+
'title' => '',
|
76 |
+
'title_left' => '',
|
77 |
+
'title_right' => '',
|
78 |
+
'leading_context_lines' => 1,
|
79 |
+
'trailing_context_lines' => 1
|
80 |
+
);
|
81 |
+
|
82 |
+
$args = wp_parse_args($args, $defaults);
|
83 |
+
|
84 |
+
if (!class_exists('WP_Text_Diff_Renderer_Table')) {
|
85 |
+
require ABSPATH . WPINC . '/wp-diff.php';
|
86 |
+
}
|
87 |
+
|
88 |
+
$left_string = normalize_whitespace($left_string);
|
89 |
+
$right_string = normalize_whitespace($right_string);
|
90 |
+
|
91 |
+
$left_lines = explode("\n", $left_string);
|
92 |
+
$right_lines = explode("\n", $right_string);
|
93 |
+
$text_diff = new Text_Diff($left_lines, $right_lines);
|
94 |
+
|
95 |
+
$renderer = new WP_Text_Diff_Renderer_Table($args);
|
96 |
+
$renderer->_leading_context_lines = $args['leading_context_lines'];
|
97 |
+
$renderer->_trailing_context_lines = $args['trailing_context_lines'];
|
98 |
+
|
99 |
+
$diff = $renderer->render($text_diff);
|
100 |
+
|
101 |
+
if (!$diff) {
|
102 |
+
return '';
|
103 |
+
}
|
104 |
+
|
105 |
+
$r = '';
|
106 |
+
|
107 |
+
$r .= "<div class='SimpleHistory__diff__contents' tabindex='0'>";
|
108 |
+
$r .= "<div class='SimpleHistory__diff__contentsInner'>";
|
109 |
+
|
110 |
+
$r .= "<table class='diff SimpleHistory__diff'>\n";
|
111 |
+
|
112 |
+
if (!empty($args['show_split_view'])) {
|
113 |
+
$r .=
|
114 |
+
"<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />";
|
115 |
+
} else {
|
116 |
+
$r .= "<col class='content' />";
|
117 |
+
}
|
118 |
+
|
119 |
+
if ($args['title'] || $args['title_left'] || $args['title_right']) {
|
120 |
+
$r .= '<thead>';
|
121 |
+
}
|
122 |
+
if ($args['title']) {
|
123 |
+
$r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
|
124 |
+
}
|
125 |
+
if ($args['title_left'] || $args['title_right']) {
|
126 |
+
$r .= "<tr class='diff-sub-title'>\n";
|
127 |
+
$r .= "\t<td></td><th>$args[title_left]</th>\n";
|
128 |
+
$r .= "\t<td></td><th>$args[title_right]</th>\n";
|
129 |
+
$r .= "</tr>\n";
|
130 |
+
}
|
131 |
+
if ($args['title'] || $args['title_left'] || $args['title_right']) {
|
132 |
+
$r .= "</thead>\n";
|
133 |
+
}
|
134 |
+
|
135 |
+
$r .= "<tbody>\n$diff</div>\n</tbody>\n";
|
136 |
+
$r .= '</table>';
|
137 |
+
|
138 |
+
$r .= '</div>';
|
139 |
+
$r .= '</div>';
|
140 |
+
|
141 |
+
return $r;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Log variable(s) to error log.
|
146 |
+
* Any number of variables can be passed and each variable is print_r'ed to the error log.
|
147 |
+
*
|
148 |
+
* Example usage:
|
149 |
+
* sh_error_log(
|
150 |
+
* 'rest_request_after_callbacks:',
|
151 |
+
* $handler,
|
152 |
+
* $handler['callback'][0],
|
153 |
+
* $handler['callback'][1]
|
154 |
+
* );
|
155 |
+
*/
|
156 |
+
function sh_error_log()
|
157 |
+
{
|
158 |
+
foreach (func_get_args() as $var) {
|
159 |
+
if (is_bool($var)) {
|
160 |
+
$bool_string = true === $var ? 'true' : 'false';
|
161 |
+
error_log("$bool_string (boolean value)");
|
162 |
+
} elseif (is_null($var)) {
|
163 |
+
error_log('null (null value)');
|
164 |
+
} else {
|
165 |
+
error_log(print_r($var, true));
|
166 |
+
}
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Return a name for a callable.
|
172 |
+
*
|
173 |
+
* Examples of return values:
|
174 |
+
* - WP_REST_Posts_Controller::get_items
|
175 |
+
* - WP_REST_Users_Controller::get_items"
|
176 |
+
* - WP_REST_Server::get_index
|
177 |
+
* - Redirection_Api_Redirect::route_bulk
|
178 |
+
* - wpcf7_rest_create_feedback
|
179 |
+
* - closure
|
180 |
+
*
|
181 |
+
* Function based on code found on stack overflow:
|
182 |
+
* https://stackoverflow.com/questions/34324576/print-name-or-definition-of-callable-in-php
|
183 |
+
*
|
184 |
+
* @param callable $callable The callable thing to check.
|
185 |
+
* @return string Name of callable.
|
186 |
+
*/
|
187 |
+
function sh_get_callable_name($callable)
|
188 |
+
{
|
189 |
+
if (is_string($callable)) {
|
190 |
+
return trim($callable);
|
191 |
+
} elseif (is_array($callable)) {
|
192 |
+
if (is_object($callable[0])) {
|
193 |
+
return sprintf('%s::%s', get_class($callable[0]), trim($callable[1]));
|
194 |
+
} else {
|
195 |
+
return sprintf('%s::%s', trim($callable[0]), trim($callable[1]));
|
196 |
+
}
|
197 |
+
} elseif ($callable instanceof Closure) {
|
198 |
+
return 'closure';
|
199 |
+
} else {
|
200 |
+
return 'unknown';
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* PHP 5.3 compatible version of ucwords with second argument.
|
206 |
+
* Taken from http://php.net/manual/en/function.ucwords.php#105249.
|
207 |
+
*
|
208 |
+
* @param string $str String.
|
209 |
+
* @param string $separator String.
|
210 |
+
*
|
211 |
+
* @return string with words uppercased.
|
212 |
+
*/
|
213 |
+
function sh_ucwords($str, $separator = ' ')
|
214 |
+
{
|
215 |
+
$str = str_replace($separator, ' ', $str);
|
216 |
+
$str = ucwords(strtolower($str));
|
217 |
+
$str = str_replace(' ', $separator, $str);
|
218 |
+
return $str;
|
219 |
+
}
|
index.php
CHANGED
@@ -4,9 +4,8 @@
|
|
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
|
8 |
-
*
|
9 |
-
* Version: 2.31.1
|
10 |
* Author: Pär Thernström
|
11 |
* Author URI: http://simple-history.com/
|
12 |
* License: GPL2
|
@@ -47,7 +46,7 @@ if ($ok_php_version && $ok_wp_version) {
|
|
47 |
*/
|
48 |
|
49 |
if (!defined('SIMPLE_HISTORY_VERSION')) {
|
50 |
-
define('SIMPLE_HISTORY_VERSION', '2.
|
51 |
}
|
52 |
|
53 |
if (!defined('SIMPLE_HISTORY_PATH')) {
|
@@ -69,6 +68,7 @@ if ($ok_php_version && $ok_wp_version) {
|
|
69 |
/** Load required files */
|
70 |
require_once __DIR__ . '/inc/SimpleHistory.php';
|
71 |
require_once __DIR__ . '/inc/SimpleHistoryLogQuery.php';
|
|
|
72 |
|
73 |
/** Boot up */
|
74 |
SimpleHistory::get_instance();
|
@@ -84,35 +84,38 @@ if ($ok_php_version && $ok_wp_version) {
|
|
84 |
$ok_wp_version = version_compare($GLOBALS['wp_version'], '4.5.1', '>=');
|
85 |
$ok_php_version = version_compare(phpversion(), '5.3', '>=');
|
86 |
?>
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
|
|
|
|
117 |
}
|
118 |
} // End if().
|
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.32
|
|
|
9 |
* Author: Pär Thernström
|
10 |
* Author URI: http://simple-history.com/
|
11 |
* License: GPL2
|
46 |
*/
|
47 |
|
48 |
if (!defined('SIMPLE_HISTORY_VERSION')) {
|
49 |
+
define('SIMPLE_HISTORY_VERSION', '2.32');
|
50 |
}
|
51 |
|
52 |
if (!defined('SIMPLE_HISTORY_PATH')) {
|
68 |
/** Load required files */
|
69 |
require_once __DIR__ . '/inc/SimpleHistory.php';
|
70 |
require_once __DIR__ . '/inc/SimpleHistoryLogQuery.php';
|
71 |
+
require_once __DIR__ . '/inc/helpers.php';
|
72 |
|
73 |
/** Boot up */
|
74 |
SimpleHistory::get_instance();
|
84 |
$ok_wp_version = version_compare($GLOBALS['wp_version'], '4.5.1', '>=');
|
85 |
$ok_php_version = version_compare(phpversion(), '5.3', '>=');
|
86 |
?>
|
87 |
+
<div class="updated error">
|
88 |
+
<?php
|
89 |
+
if (!$ok_php_version) {
|
90 |
+
echo '<p>';
|
91 |
+
printf(
|
92 |
+
/* translators: 1: PHP version */
|
93 |
+
esc_html(
|
94 |
+
__(
|
95 |
+
'Simple History is a great plugin, but to use it your server must have at least PHP 5.3 installed (you have version %s).',
|
96 |
+
'simple-history'
|
97 |
+
)
|
98 |
+
),
|
99 |
+
phpversion() // 1
|
100 |
+
);
|
101 |
+
echo '</p>';
|
102 |
+
}
|
103 |
|
104 |
+
if (!$ok_wp_version) {
|
105 |
+
echo '<p>';
|
106 |
+
printf(
|
107 |
+
/* translators: 1: WordPress version */
|
108 |
+
esc_html(
|
109 |
+
__(
|
110 |
+
'Simple History requires WordPress version 4.5.1 or higher (you have version %s).',
|
111 |
+
'simple-history'
|
112 |
+
)
|
113 |
+
),
|
114 |
+
$GLOBALS['wp_version'] // 1
|
115 |
+
);
|
116 |
+
echo '</p>';
|
117 |
+
}?>
|
118 |
+
</div>
|
119 |
+
<?php
|
120 |
}
|
121 |
} // End if().
|
loggers/AvailableUpdatesLogger.php
CHANGED
@@ -6,313 +6,304 @@
|
|
6 |
* @package SimpleHistory
|
7 |
*/
|
8 |
|
9 |
-
if (
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
$active_plugins = get_option( 'active_plugins' );
|
130 |
$active_plugins = array_flip( $active_plugins ); // find which plugins are active
|
131 |
$plugins_need_update = array_intersect_key( $plugins_need_update, $active_plugins ); // only keep plugins that are active
|
132 |
*/
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
$output .= '</a></p>';
|
309 |
-
}
|
310 |
-
}
|
311 |
-
|
312 |
-
return $output;
|
313 |
-
|
314 |
-
}
|
315 |
-
|
316 |
-
} // class
|
317 |
|
318 |
} // End if().
|
6 |
* @package SimpleHistory
|
7 |
*/
|
8 |
|
9 |
+
if (! class_exists('AvailableUpdatesLogger')) {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class.
|
13 |
+
*/
|
14 |
+
class AvailableUpdatesLogger extends SimpleLogger
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Slug for logger.
|
19 |
+
*
|
20 |
+
* @var $slug string
|
21 |
+
*/
|
22 |
+
public $slug = __CLASS__;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Return logger info
|
26 |
+
*
|
27 |
+
* @return array
|
28 |
+
*/
|
29 |
+
function getInfo()
|
30 |
+
{
|
31 |
+
|
32 |
+
$arr_info = array(
|
33 |
+
'name' => 'AvailableUpdatesLogger',
|
34 |
+
'description' => 'Logs found updates to WordPress, plugins, and themes',
|
35 |
+
'capability' => 'manage_options',
|
36 |
+
'messages' => array(
|
37 |
+
'core_update_available' => __('Found an update to WordPress.', 'simple-history'),
|
38 |
+
'plugin_update_available' => __('Found an update to plugin "{plugin_name}"', 'simple-history'),
|
39 |
+
'theme_update_available' => __('Found an update to theme "{theme_name}"', 'simple-history'),
|
40 |
+
),
|
41 |
+
'labels' => array(
|
42 |
+
'search' => array(
|
43 |
+
'label' => _x('WordPress and plugins updates found', 'Plugin logger: updates found', 'simple-history'),
|
44 |
+
'label_all' => _x('All found updates', 'Plugin logger: updates found', 'simple-history'),
|
45 |
+
'options' => array(
|
46 |
+
_x('WordPress updates found', 'Plugin logger: updates found', 'simple-history') => array(
|
47 |
+
'core_update_available'
|
48 |
+
),
|
49 |
+
_x('Plugin updates found', 'Plugin logger: updates found', 'simple-history') => array(
|
50 |
+
'plugin_update_available',
|
51 |
+
),
|
52 |
+
_x('Theme updates found', 'Plugin logger: updates found', 'simple-history') => array(
|
53 |
+
'theme_update_available'
|
54 |
+
),
|
55 |
+
),
|
56 |
+
), // search array.
|
57 |
+
), // labels.
|
58 |
+
);
|
59 |
+
|
60 |
+
return $arr_info;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Called when logger is loaded.
|
65 |
+
*/
|
66 |
+
function loaded()
|
67 |
+
{
|
68 |
+
|
69 |
+
// When WP is done checking for core updates it sets a site transient called "update_core"
|
70 |
+
// set_site_transient( 'update_core', null ); // Uncomment to test
|
71 |
+
add_action('set_site_transient_update_core', array( $this, 'on_setted_update_core_transient' ), 10, 1);
|
72 |
+
|
73 |
+
// Dito for plugins
|
74 |
+
// set_site_transient( 'update_plugins', null ); // Uncomment to test
|
75 |
+
add_action('set_site_transient_update_plugins', array( $this, 'on_setted_update_plugins_transient' ), 10, 1);
|
76 |
+
|
77 |
+
add_action('set_site_transient_update_themes', array( $this, 'on_setted_update_update_themes' ), 10, 1);
|
78 |
+
}
|
79 |
+
|
80 |
+
function on_setted_update_core_transient($updates)
|
81 |
+
{
|
82 |
+
|
83 |
+
global $wp_version;
|
84 |
+
|
85 |
+
$last_version_checked = get_option("simplehistory_{$this->slug}_wp_core_version_available");
|
86 |
+
|
87 |
+
// During update of network sites this was not set, so make sure to check
|
88 |
+
if (empty($updates->updates[0]->current)) {
|
89 |
+
return;
|
90 |
+
}
|
91 |
+
|
92 |
+
$new_wp_core_version = $updates->updates[0]->current; // The new WP core version
|
93 |
+
|
94 |
+
// Some plugins can mess with version, so get fresh from the version file.
|
95 |
+
require_once ABSPATH . WPINC . '/version.php';
|
96 |
+
|
97 |
+
// If found version is same version as we have logged about before then don't continue
|
98 |
+
if ($last_version_checked == $new_wp_core_version) {
|
99 |
+
return;
|
100 |
+
}
|
101 |
+
|
102 |
+
// is WP core update available?
|
103 |
+
if ('upgrade' == $updates->updates[0]->response) {
|
104 |
+
$this->noticeMessage('core_update_available', array(
|
105 |
+
'wp_core_current_version' => $wp_version,
|
106 |
+
'wp_core_new_version' => $new_wp_core_version,
|
107 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
108 |
+
));
|
109 |
+
|
110 |
+
// Store updated version available, so we don't log that version again
|
111 |
+
update_option("simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version);
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Called when WordPress is done checking for plugin updates.
|
117 |
+
* WP sets site transient 'update_plugins' when done.
|
118 |
+
* Log found plugin updates.
|
119 |
+
*/
|
120 |
+
function on_setted_update_plugins_transient($updates)
|
121 |
+
{
|
122 |
+
|
123 |
+
if (empty($updates->response) || ! is_array($updates->response)) {
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
// If we only want to notify about active plugins
|
128 |
+
/*
|
129 |
$active_plugins = get_option( 'active_plugins' );
|
130 |
$active_plugins = array_flip( $active_plugins ); // find which plugins are active
|
131 |
$plugins_need_update = array_intersect_key( $plugins_need_update, $active_plugins ); // only keep plugins that are active
|
132 |
*/
|
133 |
|
134 |
+
// update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
|
135 |
+
$option_key = "simplehistory_{$this->slug}_plugin_updates_available";
|
136 |
+
$checked_updates = get_option($option_key);
|
137 |
+
|
138 |
+
if (! is_array($checked_updates)) {
|
139 |
+
$checked_updates = array();
|
140 |
+
}
|
141 |
+
|
142 |
+
// File needed plugin API
|
143 |
+
if (! function_exists('get_plugin_data')) {
|
144 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
145 |
+
}
|
146 |
+
|
147 |
+
// For each available update.
|
148 |
+
foreach ($updates->response as $key => $data) {
|
149 |
+
// Make sure plugin directory exists or get_plugin_data will
|
150 |
+
// give warning like
|
151 |
+
// "PHP Warning: fread() expects parameter 1 to be resource, boolean given in /wp/wp-includes/functions.php on line 4837"
|
152 |
+
$file = WP_PLUGIN_DIR . '/' . $key;
|
153 |
+
|
154 |
+
// Continue with next plugin if plugin file did not exist.
|
155 |
+
if (! file_exists($file)) {
|
156 |
+
continue;
|
157 |
+
}
|
158 |
+
|
159 |
+
$fp = fopen($file, 'r');
|
160 |
+
|
161 |
+
// Continue with next plugin if plugin file could not be read.
|
162 |
+
if (false === $fp) {
|
163 |
+
continue;
|
164 |
+
}
|
165 |
+
|
166 |
+
$plugin_info = get_plugin_data($file, true, false);
|
167 |
+
|
168 |
+
$plugin_new_version = isset($data->new_version) ? $data->new_version : '';
|
169 |
+
|
170 |
+
// Check if this plugin and this version has been checked/logged already.
|
171 |
+
if (! array_key_exists($key, $checked_updates)) {
|
172 |
+
$checked_updates[ $key ] = array(
|
173 |
+
'checked_version' => null,
|
174 |
+
);
|
175 |
+
}
|
176 |
+
|
177 |
+
if ($checked_updates[ $key ]['checked_version'] == $plugin_new_version) {
|
178 |
+
// This version has been checked/logged already
|
179 |
+
continue;
|
180 |
+
}
|
181 |
+
|
182 |
+
$checked_updates[ $key ]['checked_version'] = $plugin_new_version;
|
183 |
+
|
184 |
+
$this->noticeMessage('plugin_update_available', array(
|
185 |
+
'plugin_name' => isset($plugin_info['Name']) ? $plugin_info['Name'] : '',
|
186 |
+
'plugin_current_version' => isset($plugin_info['Version']) ? $plugin_info['Version'] : '',
|
187 |
+
'plugin_new_version' => $plugin_new_version,
|
188 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
189 |
+
// "plugin_info" => $plugin_info,
|
190 |
+
// "remote_plugin_info" => $remote_plugin_info,
|
191 |
+
// "active_plugins" => $active_plugins,
|
192 |
+
// "updates" => $updates
|
193 |
+
));
|
194 |
+
} // End foreach().
|
195 |
+
|
196 |
+
update_option($option_key, $checked_updates);
|
197 |
+
} // function
|
198 |
+
|
199 |
+
function on_setted_update_update_themes($updates)
|
200 |
+
{
|
201 |
+
|
202 |
+
if (empty($updates->response) || ! is_array($updates->response)) {
|
203 |
+
return;
|
204 |
+
}
|
205 |
+
|
206 |
+
// update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
|
207 |
+
$option_key = "simplehistory_{$this->slug}_theme_updates_available";
|
208 |
+
$checked_updates = get_option($option_key);
|
209 |
+
|
210 |
+
if (! is_array($checked_updates)) {
|
211 |
+
$checked_updates = array();
|
212 |
+
}
|
213 |
+
|
214 |
+
// For each available update
|
215 |
+
foreach ($updates->response as $key => $data) {
|
216 |
+
$theme_info = wp_get_theme($key);
|
217 |
+
|
218 |
+
// $message .= "\n" . sprintf( __( "Theme: %s is out of date. Please update from version %s to %s", "wp-updates-notifier" ), $theme_info['Name'], $theme_info['Version'], $data['new_version'] ) . "\n";
|
219 |
+
$settings['notified']['theme'][ $key ] = $data['new_version']; // set theme version we are notifying about
|
220 |
+
|
221 |
+
$theme_new_version = isset($data['new_version']) ? $data['new_version'] : '';
|
222 |
+
|
223 |
+
// check if this plugin and this version has been checked/logged already
|
224 |
+
if (! array_key_exists($key, $checked_updates)) {
|
225 |
+
$checked_updates[ $key ] = array(
|
226 |
+
'checked_version' => null,
|
227 |
+
);
|
228 |
+
}
|
229 |
+
|
230 |
+
if ($checked_updates[ $key ]['checked_version'] == $theme_new_version) {
|
231 |
+
// This version has been checked/logged already
|
232 |
+
continue;
|
233 |
+
}
|
234 |
+
|
235 |
+
$checked_updates[ $key ]['checked_version'] = $theme_new_version;
|
236 |
+
|
237 |
+
$this->noticeMessage('theme_update_available', array(
|
238 |
+
'theme_name' => isset($theme_info['Name']) ? $theme_info['Name'] : '',
|
239 |
+
'theme_current_version' => isset($theme_info['Version']) ? $theme_info['Version'] : '',
|
240 |
+
'theme_new_version' => $theme_new_version,
|
241 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
242 |
+
// "plugin_info" => $plugin_info,
|
243 |
+
// "remote_plugin_info" => $remote_plugin_info,
|
244 |
+
// "active_plugins" => $active_plugins,
|
245 |
+
// "updates" => $updates,
|
246 |
+
));
|
247 |
+
} // End foreach().
|
248 |
+
|
249 |
+
update_option($option_key, $checked_updates);
|
250 |
+
} // function
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Append prev and current version of update object as details in the output
|
254 |
+
*/
|
255 |
+
function getLogRowDetailsOutput($row)
|
256 |
+
{
|
257 |
+
|
258 |
+
$output = '';
|
259 |
+
|
260 |
+
$current_version = null;
|
261 |
+
$new_version = null;
|
262 |
+
$context_message_key = isset($row->context_message_key) ? $row->context_message_key : null;
|
263 |
+
|
264 |
+
$context = isset($row->context) ? $row->context : array();
|
265 |
+
|
266 |
+
switch ($context_message_key) {
|
267 |
+
case 'core_update_available':
|
268 |
+
$current_version = isset($context['wp_core_current_version']) ? $context['wp_core_current_version'] : null;
|
269 |
+
$new_version = isset($context['wp_core_new_version']) ? $context['wp_core_new_version'] : null;
|
270 |
+
break;
|
271 |
+
|
272 |
+
case 'plugin_update_available':
|
273 |
+
$current_version = isset($context['plugin_current_version']) ? $context['plugin_current_version'] : null;
|
274 |
+
$new_version = isset($context['plugin_new_version']) ? $context['plugin_new_version'] : null;
|
275 |
+
break;
|
276 |
+
|
277 |
+
case 'theme_update_available':
|
278 |
+
$current_version = isset($context['theme_current_version']) ? $context['theme_current_version'] : null;
|
279 |
+
$new_version = isset($context['theme_new_version']) ? $context['theme_new_version'] : null;
|
280 |
+
break;
|
281 |
+
}
|
282 |
+
|
283 |
+
if ($current_version && $new_version) {
|
284 |
+
$output .= '<p>';
|
285 |
+
$output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
|
286 |
+
$output .= '<em>' . __('Available version', 'simple-history') . '</em> ' . esc_html($new_version);
|
287 |
+
$output .= '</span> ';
|
288 |
+
|
289 |
+
$output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
|
290 |
+
$output .= '<em>' . __('Installed version', 'simple-history') . '</em> ' . esc_html($current_version);
|
291 |
+
$output .= '</span>';
|
292 |
+
|
293 |
+
$output .= '</p>';
|
294 |
+
|
295 |
+
// Add link to update-page, if user is allowed to that page.
|
296 |
+
$is_allowed_to_update_page = current_user_can('update_core') || current_user_can('update_themes') || current_user_can('update_plugins');
|
297 |
+
|
298 |
+
if ($is_allowed_to_update_page) {
|
299 |
+
$output .= sprintf('<p><a href="%1$s">', admin_url('update-core.php'));
|
300 |
+
$output .= __('View all updates', 'simple-history');
|
301 |
+
$output .= '</a></p>';
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
return $output;
|
306 |
+
}
|
307 |
+
} // class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
|
309 |
} // End if().
|
loggers/FileEditsLogger.php
CHANGED
@@ -3,254 +3,252 @@
|
|
3 |
/**
|
4 |
* Logs edits to theme or plugin files done from Appearance -> Editor or Plugins -> Editor
|
5 |
*/
|
6 |
-
class FileEditsLogger extends SimpleLogger
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
}
|
255 |
-
|
256 |
} // class
|
3 |
/**
|
4 |
* Logs edits to theme or plugin files done from Appearance -> Editor or Plugins -> Editor
|
5 |
*/
|
6 |
+
class FileEditsLogger extends SimpleLogger
|
7 |
+
{
|
8 |
+
|
9 |
+
public $slug = __CLASS__;
|
10 |
+
|
11 |
+
function getInfo()
|
12 |
+
{
|
13 |
+
|
14 |
+
$arr_info = array(
|
15 |
+
'name' => 'FileEditsLogger',
|
16 |
+
'description' => 'Logs edits to theme and plugin files',
|
17 |
+
'capability' => 'manage_options',
|
18 |
+
'messages' => array(
|
19 |
+
'theme_file_edited' => __('Edited file "{file_name}" in theme "{theme_name}"', 'simple-history'),
|
20 |
+
'plugin_file_edited' => __('Edited file "{file_name}" in plugin "{plugin_name}"', 'simple-history'),
|
21 |
+
),
|
22 |
+
'labels' => array(
|
23 |
+
'search' => array(
|
24 |
+
'label' => _x('Edited theme and plugin files', 'Plugin logger: file edits', 'simple-history'),
|
25 |
+
'label_all' => _x('All file edits', 'Plugin logger: file edits', 'simple-history'),
|
26 |
+
'options' => array(
|
27 |
+
_x('Edited theme files', 'Plugin logger: file edits', 'simple-history') => array(
|
28 |
+
'theme_file_edited'
|
29 |
+
),
|
30 |
+
_x('Edited plugin files', 'Plugin logger: file edits', 'simple-history') => array(
|
31 |
+
'plugin_file_edited',
|
32 |
+
),
|
33 |
+
),
|
34 |
+
),// search array
|
35 |
+
),// labels
|
36 |
+
);
|
37 |
+
|
38 |
+
return $arr_info;
|
39 |
+
}
|
40 |
+
|
41 |
+
function loaded()
|
42 |
+
{
|
43 |
+
add_action('load-theme-editor.php', array( $this, 'on_load_theme_editor' ), 10, 1);
|
44 |
+
add_action('load-plugin-editor.php', array( $this, 'on_load_plugin_editor' ), 10, 1);
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Called when /wp/wp-admin/plugin-editor.php is loaded
|
49 |
+
* Both using regular GET and during POST with updated file data
|
50 |
+
*
|
51 |
+
* todo:
|
52 |
+
* - log edits
|
53 |
+
* - log failed edits that result in error and plugin deactivation
|
54 |
+
*/
|
55 |
+
public function on_load_plugin_editor()
|
56 |
+
{
|
57 |
+
if (isset($_POST) && isset($_POST['action'])) {
|
58 |
+
$action = isset($_POST['action']) ? $_POST['action'] : null;
|
59 |
+
$file = isset($_POST['file']) ? $_POST['file'] : null;
|
60 |
+
$plugin_file = isset($_POST['plugin']) ? $_POST['plugin'] : null;
|
61 |
+
$fileNewContents = isset($_POST['newcontent']) ? wp_unslash($_POST['newcontent']) : null;
|
62 |
+
$scrollto = isset($_POST['scrollto']) ? (int) $_POST['scrollto'] : 0;
|
63 |
+
|
64 |
+
// if 'phperror' is set then there was an error and an edit is done and wp tries to activate the plugin again
|
65 |
+
// $phperror = isset($_POST["phperror"]) ? $_POST["phperror"] : null;
|
66 |
+
// Get info about the edited plugin
|
67 |
+
$pluginInfo = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_file);
|
68 |
+
$pluginName = isset($pluginInfo['Name']) ? $pluginInfo['Name'] : null;
|
69 |
+
$pluginVersion = isset($pluginInfo['Version']) ? $pluginInfo['Version'] : null;
|
70 |
+
|
71 |
+
// Get contents before save
|
72 |
+
$fileContentsBeforeEdit = file_get_contents(WP_PLUGIN_DIR . '/' . $file);
|
73 |
+
|
74 |
+
$context = array(
|
75 |
+
'file_name' => $plugin_file,
|
76 |
+
'plugin_name' => $pluginName,
|
77 |
+
'plugin_version' => $pluginVersion,
|
78 |
+
'old_file_contents' => $fileContentsBeforeEdit,
|
79 |
+
'new_file_contents' => $fileNewContents,
|
80 |
+
'_occasionsID' => __CLASS__ . '/' . __FUNCTION__ . "/file-edit/$plugin_file/$file",
|
81 |
+
);
|
82 |
+
|
83 |
+
$loggerInstance = $this;
|
84 |
+
add_filter('wp_redirect', function ($location, $status) use ($context, $loggerInstance) {
|
85 |
+
$locationParsed = parse_url($location);
|
86 |
+
|
87 |
+
if ($locationParsed === false || empty($locationParsed['query'])) {
|
88 |
+
return $location;
|
89 |
+
}
|
90 |
+
|
91 |
+
parse_str($locationParsed['query'], $queryStringParsed);
|
92 |
+
// ddd($_POST, $context, $queryStringParsed, $location);
|
93 |
+
if (empty($queryStringParsed)) {
|
94 |
+
return $location;
|
95 |
+
}
|
96 |
+
|
97 |
+
// If query string "a=te" exists or "liveupdate=1" then plugin file was updated
|
98 |
+
$teIsSet = isset($queryStringParsed['a']) && $queryStringParsed['a'] === 'te';
|
99 |
+
$liveUpdateIsSet = isset($queryStringParsed['liveupdate']) && $queryStringParsed['liveupdate'] === '1';
|
100 |
+
if ($teIsSet || $liveUpdateIsSet) {
|
101 |
+
// File was updated
|
102 |
+
$loggerInstance->infoMessage('plugin_file_edited', $context);
|
103 |
+
}
|
104 |
+
|
105 |
+
return $location;
|
106 |
+
|
107 |
+
// location when successful edit to non-active plugin
|
108 |
+
// http://wp-playground.dev/wp/wp-admin/plugin-editor.php?file=akismet/akismet.php&plugin=akismet/akismet.php&a=te&scrollto=0
|
109 |
+
// locations when activated plugin edited successfully
|
110 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&plugin=akismet%2Fakismet.php&liveupdate=1&scrollto=0&networkwide&_wpnonce=b3f399fe94
|
111 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&phperror=1&_error_nonce=63511c266d
|
112 |
+
// http://wp-playground.dev/wp/wp-admin/plugin-editor.php?file=akismet/akismet.php&plugin=akismet/akismet.php&a=te&scrollto=0
|
113 |
+
// locations when editing active plugin and error occurs
|
114 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&plugin=akismet%2Fakismet.php&liveupdate=1&scrollto=0&networkwide&_wpnonce=b3f399fe94
|
115 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&phperror=1&_error_nonce=63511c266d
|
116 |
+
// locations when error edit is fixed and saved and plugin is activated again
|
117 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&plugin=akismet%2Fakismet.php&liveupdate=1&scrollto=0&networkwide&_wpnonce=b3f399fe94
|
118 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&phperror=1&_error_nonce=63511c266d
|
119 |
+
// http://wp-playground.dev/wp/wp-admin/plugin-editor.php?file=akismet/akismet.php&plugin=akismet/akismet.php&a=te&scrollto=0
|
120 |
+
}, 10, 2);
|
121 |
+
}// End if().
|
122 |
+
/*
|
123 |
+
<?php if (isset($_GET['a'])) : ?>
|
124 |
+
<div id="message" class="updated notice is-dismissible"><p><?php _e('File edited successfully.') ?></p></div>
|
125 |
+
<?php elseif (isset($_GET['phperror'])) : ?>
|
126 |
+
<div id="message" class="updated"><p><?php _e('This plugin has been deactivated because your changes resulted in a <strong>fatal error</strong>.') ?></p>
|
127 |
+
*/
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Called when /wp/wp-admin/theme-editor.php is loaded
|
132 |
+
* Both using regular GET and during POST with updated file data
|
133 |
+
*
|
134 |
+
* When this action is fired we don't know if a file will be successfully saved or not.
|
135 |
+
* There are no filters/actions fired when the edit is saved. On the end wp_redirect() is
|
136 |
+
* called however and we know the location for the redirect and wp_redirect() has filters
|
137 |
+
* so we hook onto that to save the edit.
|
138 |
+
*/
|
139 |
+
public function on_load_theme_editor()
|
140 |
+
{
|
141 |
+
// Only continue if method is post and action is update
|
142 |
+
if (isset($_POST) && isset($_POST['action']) && $_POST['action'] === 'update') {
|
143 |
+
/*
|
144 |
+
POST data is like
|
145 |
+
array(8)
|
146 |
+
'_wpnonce' => string(10) "9b5e46634f"
|
147 |
+
'_wp_http_referer' => string(88) "/wp/wp-admin/theme-editor.php?file=style.css&theme=twentyfifteen&scrollto=0&upda…"
|
148 |
+
'newcontent' => string(104366) "/* Theme Name: Twenty Fifteen Theme URI: https://wordpress.org/themes/twentyfift…"
|
149 |
+
'action' => string(6) "update"
|
150 |
+
'file' => string(9) "style.css"
|
151 |
+
'theme' => string(13) "twentyfifteen"
|
152 |
+
'scrollto' => string(3) "638"
|
153 |
+
'submit' => string(11) "Update File"
|
154 |
+
*/
|
155 |
+
|
156 |
+
$action = isset($_POST['action']) ? $_POST['action'] : null;
|
157 |
+
$file = isset($_POST['file']) ? $_POST['file'] : null;
|
158 |
+
$theme = isset($_POST['theme']) ? $_POST['theme'] : null;
|
159 |
+
$fileNewContents = isset($_POST['newcontent']) ? wp_unslash($_POST['newcontent']) : null;
|
160 |
+
$scrollto = isset($_POST['scrollto']) ? (int) $_POST['scrollto'] : 0;
|
161 |
+
|
162 |
+
// Same code as in theme-editor.php
|
163 |
+
if ($theme) {
|
164 |
+
$stylesheet = $theme;
|
165 |
+
} else {
|
166 |
+
$stylesheet = get_stylesheet();
|
167 |
+
}
|
168 |
+
|
169 |
+
$theme = wp_get_theme($stylesheet);
|
170 |
+
|
171 |
+
if (! is_a($theme, 'WP_Theme')) {
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
|
175 |
+
// Same code as in theme-editor.php
|
176 |
+
$relative_file = $file;
|
177 |
+
$file = $theme->get_stylesheet_directory() . '/' . $relative_file;
|
178 |
+
|
179 |
+
// Get file contents, so we have something to compare with later
|
180 |
+
$fileContentsBeforeEdit = file_get_contents($file);
|
181 |
+
|
182 |
+
$context = array(
|
183 |
+
'theme_name' => $theme->name,
|
184 |
+
'theme_stylesheet_path' => $theme->get_stylesheet(),
|
185 |
+
'theme_stylesheet_dir' => $theme->get_stylesheet_directory(),
|
186 |
+
'file_name' => $relative_file,
|
187 |
+
'file_dir' => $file,
|
188 |
+
'old_file_contents' => $fileContentsBeforeEdit,
|
189 |
+
'new_file_contents' => $fileNewContents,
|
190 |
+
'_occasionsID' => __CLASS__ . '/' . __FUNCTION__ . "/file-edit/$file",
|
191 |
+
);
|
192 |
+
|
193 |
+
// Hook into wp_redirect
|
194 |
+
// This hook is only added when we know a POST is done from theme-editor.php
|
195 |
+
$loggerInstance = $this;
|
196 |
+
add_filter('wp_redirect', function ($location, $status) use ($context, $loggerInstance) {
|
197 |
+
$locationParsed = parse_url($location);
|
198 |
+
|
199 |
+
if ($locationParsed === false || empty($locationParsed['query'])) {
|
200 |
+
return $location;
|
201 |
+
}
|
202 |
+
|
203 |
+
parse_str($locationParsed['query'], $queryStringParsed);
|
204 |
+
|
205 |
+
if (empty($queryStringParsed)) {
|
206 |
+
return $location;
|
207 |
+
}
|
208 |
+
|
209 |
+
if (isset($queryStringParsed['updated']) && $queryStringParsed['updated']) {
|
210 |
+
// File was updated
|
211 |
+
$loggerInstance->infoMessage('theme_file_edited', $context);
|
212 |
+
} else {
|
213 |
+
// File was not updated. Unknown reason, but probably because could not be written.
|
214 |
+
}
|
215 |
+
|
216 |
+
return $location;
|
217 |
+
}, 10, 2); // add_filter
|
218 |
+
} // End if().
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
public function getLogRowDetailsOutput($row)
|
223 |
+
{
|
224 |
+
|
225 |
+
$context = $row->context;
|
226 |
+
$message_key = isset($context['_message_key']) ? $context['_message_key'] : null;
|
227 |
+
|
228 |
+
if (! $message_key) {
|
229 |
+
return;
|
230 |
+
}
|
231 |
+
|
232 |
+
$out = '';
|
233 |
+
|
234 |
+
$diff_table_output = '';
|
235 |
+
|
236 |
+
if (! empty($context['new_file_contents']) && ! empty($context['old_file_contents'])) {
|
237 |
+
if ($context['new_file_contents'] !== $context['old_file_contents']) {
|
238 |
+
$diff_table_output .= sprintf(
|
239 |
+
'<tr><td>%1$s</td><td>%2$s</td></tr>',
|
240 |
+
__('File contents', 'simple-history'),
|
241 |
+
simple_history_text_diff($context['old_file_contents'], $context['new_file_contents'])
|
242 |
+
);
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
if ($diff_table_output) {
|
247 |
+
$diff_table_output = '<table class="SimpleHistoryLogitem__keyValueTable">' . $diff_table_output . '</table>';
|
248 |
+
}
|
249 |
+
|
250 |
+
$out .= $diff_table_output;
|
251 |
+
|
252 |
+
return $out;
|
253 |
+
}
|
|
|
|
|
254 |
} // class
|
loggers/PluginEnableMediaReplaceLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs attachments updated with the great Enable Media Replace plugin
|
@@ -8,98 +8,97 @@ defined( 'ABSPATH' ) or die();
|
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
-
class PluginEnableMediaReplaceLogger extends SimpleLogger
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs attachments updated with the great Enable Media Replace plugin
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
+
class PluginEnableMediaReplaceLogger extends SimpleLogger
|
12 |
+
{
|
13 |
+
|
14 |
+
public $slug = __CLASS__;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Get array with information about this logger
|
18 |
+
*
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
function getInfo()
|
22 |
+
{
|
23 |
+
|
24 |
+
$arr_info = array(
|
25 |
+
'name' => _x('Enable Media Replace Logger', 'PluginEnableMediaReplaceLogger', 'simple-history'),
|
26 |
+
'description' => _x('Logs media updates made with the Enable Media Replace Plugin', 'PluginEnableMediaReplaceLogger', 'simple-history'),
|
27 |
+
'name_via' => _x('Using plugin Enable Media Replace', 'PluginUserSwitchingLogger', 'simple-history'),
|
28 |
+
'capability' => 'upload_files',
|
29 |
+
'messages' => array(
|
30 |
+
'replaced_file' => _x('Replaced attachment "{prev_attachment_title}" with new attachment "{new_attachment_title}"', 'PluginEnableMediaReplaceLogger', 'simple-history'),
|
31 |
+
),
|
32 |
+
);
|
33 |
+
|
34 |
+
return $arr_info;
|
35 |
+
}
|
36 |
+
|
37 |
+
function loaded()
|
38 |
+
{
|
39 |
+
|
40 |
+
// Action that is called when Enable Media Replace loads it's admin options page (both when viewing and when posting new file to it)
|
41 |
+
add_action('load-media_page_enable-media-replace/enable-media-replace', array( $this, 'on_load_plugin_admin_page' ), 10, 1);
|
42 |
+
}
|
43 |
+
|
44 |
+
function on_load_plugin_admin_page()
|
45 |
+
{
|
46 |
+
|
47 |
+
if (empty($_POST)) {
|
48 |
+
return;
|
49 |
+
}
|
50 |
+
|
51 |
+
if (isset($_GET['action']) && $_GET['action'] == 'media_replace_upload') {
|
52 |
+
$attachment_id = empty($_POST['ID']) ? null : (int) $_POST['ID'];
|
53 |
+
$replace_type = empty($_POST['replace_type']) ? null : sanitize_text_field($_POST['replace_type']);
|
54 |
+
$new_file = empty($_FILES['userfile']) ? null : (array) $_FILES['userfile'];
|
55 |
+
|
56 |
+
$prev_attachment_post = get_post($attachment_id);
|
57 |
+
|
58 |
+
if (empty($attachment_id) || empty($new_file) || empty($prev_attachment_post)) {
|
59 |
+
return;
|
60 |
+
}
|
61 |
+
|
62 |
+
/*
|
63 |
+
get {
|
64 |
+
"page": "enable-media-replace\/enable-media-replace.php",
|
65 |
+
"noheader": "true",
|
66 |
+
"action": "media_replace_upload",
|
67 |
+
"attachment_id": "64085",
|
68 |
+
"_wpnonce": "1089573e0c"
|
69 |
+
}
|
70 |
+
|
71 |
+
post {
|
72 |
+
"ID": "64085",
|
73 |
+
"replace_type": "replace"
|
74 |
+
}
|
75 |
+
|
76 |
+
files {
|
77 |
+
"userfile": {
|
78 |
+
"name": "earth-transparent.png",
|
79 |
+
"type": "image\/png",
|
80 |
+
"tmp_name": "\/Applications\/MAMP\/tmp\/php\/phpKA2XOo",
|
81 |
+
"error": 0,
|
82 |
+
"size": 4325729
|
83 |
+
}
|
84 |
+
}
|
85 |
+
*/
|
86 |
+
|
87 |
+
$this->infoMessage('replaced_file', array(
|
88 |
+
'attachment_id' => $attachment_id,
|
89 |
+
'prev_attachment_title' => get_the_title($prev_attachment_post),
|
90 |
+
'new_attachment_title' => $new_file['name'],
|
91 |
+
'new_attachment_type' => $new_file['type'],
|
92 |
+
'new_attachment_size' => $new_file['size'],
|
93 |
+
'replace_type' => $replace_type,
|
94 |
+
/*
|
95 |
+
"get" => $_GET,
|
96 |
+
"post" => $_POST,
|
97 |
+
"files" => $_FILES,
|
98 |
+
"old_attachment_post" => $prev_attachment_post,
|
99 |
+
"old_attachment_meta" => $prev_attachment_meta
|
100 |
+
*/
|
101 |
+
));
|
102 |
+
}// End if().
|
103 |
+
}
|
|
|
104 |
}
|
loggers/PluginUserSwitchingLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs user switching from the great User Switching plugin
|
@@ -8,137 +8,133 @@ defined( 'ABSPATH' ) or die();
|
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
-
class PluginUserSwitchingLogger extends SimpleLogger
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
);
|
141 |
-
|
142 |
-
}
|
143 |
-
|
144 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs user switching from the great User Switching plugin
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
+
class PluginUserSwitchingLogger extends SimpleLogger
|
12 |
+
{
|
13 |
+
|
14 |
+
public $slug = __CLASS__;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Get array with information about this logger
|
18 |
+
*
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
function getInfo()
|
22 |
+
{
|
23 |
+
|
24 |
+
$arr_info = array(
|
25 |
+
'name' => _x('User Switching Logger', 'PluginUserSwitchingLogger', 'simple-history'),
|
26 |
+
'description' => _x('Logs user switches', 'PluginUserSwitchingLogger', 'simple-history'),
|
27 |
+
// Definition of via: by way of, through the medium or agency of; also : by means of
|
28 |
+
'name_via' => _x('Using plugin User Switching', 'PluginUserSwitchingLogger', 'simple-history'),
|
29 |
+
'capability' => 'edit_users',
|
30 |
+
'messages' => array(
|
31 |
+
'switched_to_user' => _x('Switched to user "{user_login_to}" from user "{user_login_from}"', 'PluginUserSwitchingLogger', 'simple-history'),
|
32 |
+
'switched_back_user' => _x('Switched back to user "{user_login_to}" from user "{user_login_from}"', 'PluginUserSwitchingLogger', 'simple-history'),
|
33 |
+
'switched_back_themself' => _x('Switched back to user "{user_login_to}"', 'PluginUserSwitchingLogger', 'simple-history'),
|
34 |
+
'switched_off_user' => _x('Switched off user "{user_login}"', 'PluginUserSwitchingLogger', 'simple-history'),
|
35 |
+
),
|
36 |
+
);
|
37 |
+
|
38 |
+
return $arr_info;
|
39 |
+
}
|
40 |
+
|
41 |
+
function loaded()
|
42 |
+
{
|
43 |
+
|
44 |
+
add_action('switch_to_user', array( $this, 'on_switch_to_user' ), 10, 2);
|
45 |
+
add_action('switch_back_user', array( $this, 'on_switch_back_user' ), 10, 2);
|
46 |
+
add_action('switch_off_user', array( $this, 'on_switch_off_user' ), 10, 1);
|
47 |
+
}
|
48 |
+
|
49 |
+
function on_switch_to_user($user_id, $old_user_id)
|
50 |
+
{
|
51 |
+
|
52 |
+
$user_to = get_user_by('id', $user_id);
|
53 |
+
$user_from = get_user_by('id', $old_user_id);
|
54 |
+
|
55 |
+
if (! is_a($user_to, 'WP_User') || ! is_a($user_from, 'WP_User')) {
|
56 |
+
return;
|
57 |
+
}
|
58 |
+
|
59 |
+
$this->infoMessage(
|
60 |
+
'switched_to_user',
|
61 |
+
array(
|
62 |
+
// It is the old user who initiates the switching
|
63 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
64 |
+
'_user_id' => $old_user_id,
|
65 |
+
'user_id' => $user_id,
|
66 |
+
'old_user_id' => $old_user_id,
|
67 |
+
'user_login_to' => $user_to->user_login,
|
68 |
+
'user_login_from' => $user_from->user_login,
|
69 |
+
)
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Function is called when a user switches back to their originating account.
|
75 |
+
* When you switch back after being logged off the
|
76 |
+
*
|
77 |
+
* Note: $old_user_id parameter is boolean false because there is no old user.
|
78 |
+
*
|
79 |
+
* @param int $user_id The ID of the user being switched back to.
|
80 |
+
* @param int|false $old_user_id The ID of the user being switched from, or false if the user is switching back
|
81 |
+
* after having been switched off.
|
82 |
+
*/
|
83 |
+
function on_switch_back_user($user_id, $old_user_id)
|
84 |
+
{
|
85 |
+
|
86 |
+
$user_to = get_user_by('id', $user_id);
|
87 |
+
|
88 |
+
$user_from = $old_user_id == false ? null : get_user_by('id', $old_user_id);
|
89 |
+
|
90 |
+
if (! is_a($user_to, 'WP_User')) {
|
91 |
+
return;
|
92 |
+
}
|
93 |
+
|
94 |
+
if ($user_from) {
|
95 |
+
// User switched back from another user
|
96 |
+
$this->infoMessage(
|
97 |
+
'switched_back_user',
|
98 |
+
array(
|
99 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
100 |
+
'_user_id' => $old_user_id,
|
101 |
+
'user_id' => $user_id,
|
102 |
+
'old_user_id' => $old_user_id,
|
103 |
+
'user_login_to' => $user_to->user_login,
|
104 |
+
'user_login_from' => $user_from->user_login,
|
105 |
+
)
|
106 |
+
);
|
107 |
+
} else {
|
108 |
+
// User switched back to themself (no prev user)
|
109 |
+
$this->infoMessage(
|
110 |
+
'switched_back_themself',
|
111 |
+
array(
|
112 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
113 |
+
'_user_id' => $user_id,
|
114 |
+
'user_login_to' => $user_to->user_login,
|
115 |
+
)
|
116 |
+
);
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
function on_switch_off_user($user_id)
|
121 |
+
{
|
122 |
+
|
123 |
+
$user = get_user_by('id', $user_id);
|
124 |
+
|
125 |
+
if (! is_a($user, 'WP_User')) {
|
126 |
+
return;
|
127 |
+
}
|
128 |
+
|
129 |
+
$this->infoMessage(
|
130 |
+
'switched_off_user',
|
131 |
+
array(
|
132 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
133 |
+
'_user_id' => $user_id,
|
134 |
+
|
135 |
+
'user_id' => $user_id,
|
136 |
+
'user_login' => $user->user_login,
|
137 |
+
)
|
138 |
+
);
|
139 |
+
}
|
|
|
|
|
|
|
|
|
140 |
}
|
loggers/Plugin_ACF.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logger for the Advanced Custom Fields (ACF) plugin
|
@@ -9,1055 +9,1070 @@ defined( 'ABSPATH' ) || die();
|
|
9 |
* @package SimpleHistory
|
10 |
* @since 2.21
|
11 |
*/
|
12 |
-
if (
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
570 |
<td>%1$s</td>
|
571 |
<td>
|
572 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
573 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
574 |
</td>
|
575 |
</tr>',
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
<td>%1$s</td>
|
610 |
<td>
|
611 |
%2$s
|
612 |
%3$s
|
613 |
</td>
|
614 |
</tr>',
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
<td>%1$s</td>
|
643 |
<td>%2$s</td>
|
644 |
</tr>',
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
<td>%1$s</td>
|
672 |
<td>%2$s</td>
|
673 |
</tr>',
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
%4$s
|
733 |
%3$s
|
734 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%1$s</ins>
|
735 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%2$s</del>
|
736 |
',
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
<td>%1$s</td>
|
751 |
<td>%2$s</td>
|
752 |
</tr>',
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
|
|
|
|
|
|
|
|
|
|
1063 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') || die();
|
4 |
|
5 |
/**
|
6 |
* Logger for the Advanced Custom Fields (ACF) plugin
|
9 |
* @package SimpleHistory
|
10 |
* @since 2.21
|
11 |
*/
|
12 |
+
if (! class_exists('Plugin_ACF')) {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class for ACF logging.
|
16 |
+
*/
|
17 |
+
class Plugin_ACF extends SimpleLogger
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The slug for this logger.
|
22 |
+
*
|
23 |
+
* @var string $slug
|
24 |
+
*/
|
25 |
+
public $slug = __CLASS__;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Will contain field groups and fields, before and after post save.
|
29 |
+
*
|
30 |
+
* @var string $oldAndNewFieldGroupsAndFields
|
31 |
+
*/
|
32 |
+
private $oldAndNewFieldGroupsAndFields = array(
|
33 |
+
'fieldGroup' => array(
|
34 |
+
'old' => null,
|
35 |
+
'new' => null,
|
36 |
+
),
|
37 |
+
'modifiedFields' => array(
|
38 |
+
'old' => null,
|
39 |
+
'new' => null,
|
40 |
+
),
|
41 |
+
'addedFields' => array(),
|
42 |
+
'deletedFields' => array(),
|
43 |
+
);
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Will contain the post data before save, i.e. the previous version of the post.
|
47 |
+
*
|
48 |
+
* @var string $oldPostData
|
49 |
+
*/
|
50 |
+
private $oldPostData = array();
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get info for this logger.
|
54 |
+
*
|
55 |
+
* @return array Array with info about the logger.
|
56 |
+
*/
|
57 |
+
public function getInfo()
|
58 |
+
{
|
59 |
+
$arr_info = array(
|
60 |
+
'name' => 'Plugin ACF',
|
61 |
+
'description' => _x('Logs ACF stuff', 'Logger: Plugin ACF', 'simple-history'),
|
62 |
+
'name_via' => _x('Using plugin ACF', 'Logger: Plugin ACF', 'simple-history'),
|
63 |
+
'capability' => 'manage_options',
|
64 |
+
);
|
65 |
+
|
66 |
+
return $arr_info;
|
67 |
+
}
|
68 |
+
|
69 |
+
private function isACFInstalled()
|
70 |
+
{
|
71 |
+
return defined('ACF') && ACF;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Method called when logger is loaded.
|
76 |
+
*/
|
77 |
+
public function loaded()
|
78 |
+
{
|
79 |
+
|
80 |
+
// Bail if no ACF found.
|
81 |
+
if (! $this->isACFInstalled()) {
|
82 |
+
return;
|
83 |
+
}
|
84 |
+
|
85 |
+
// Remove ACF Fields from the post types that postlogger logs.
|
86 |
+
add_filter('simple_history/post_logger/skip_posttypes', array( $this, 'remove_acf_from_postlogger' ));
|
87 |
+
|
88 |
+
// Get prev version of acf field group.
|
89 |
+
// This is called before transition_post_status.
|
90 |
+
add_filter('wp_insert_post_data', array( $this, 'on_wp_insert_post_data' ), 10, 2);
|
91 |
+
|
92 |
+
// Store old and new field data when a post is saved.
|
93 |
+
add_action('transition_post_status', array( $this, 'on_transition_post_status' ), 5, 3);
|
94 |
+
|
95 |
+
// Append ACF data to post context
|
96 |
+
add_filter('simple_history/post_logger/post_updated/context', array( $this, 'on_post_updated_context' ), 10, 2);
|
97 |
+
|
98 |
+
// Add ACF diff data to activity feed detailed output.
|
99 |
+
add_filter('simple_history/post_logger/post_updated/diff_table_output', array( $this, 'on_diff_table_output_field_group' ), 10, 2);
|
100 |
+
|
101 |
+
// Store prev ACF field values before new values are added.
|
102 |
+
// Called from filter admin_action_editpost that is fired at top of admin.php
|
103 |
+
add_action('admin_action_editpost', array( $this, 'on_admin_action_editpost' ));
|
104 |
+
|
105 |
+
// Fired when ACF saves a post. Adds ACF context to logged row.
|
106 |
+
add_filter('acf/save_post', array( $this, 'on_acf_save_post' ), 50);
|
107 |
+
|
108 |
+
// Fired after a log row is inserted. Add filter so field group save is is not logged again.
|
109 |
+
add_action('simple_history/log/inserted', array( $this, 'on_log_inserted' ), 10, 3);
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Fired after a log row is inserted.
|
114 |
+
*/
|
115 |
+
public function on_log_inserted($context, $data_parent_row, $simple_history_instance)
|
116 |
+
{
|
117 |
+
$message_key = ! empty($context['_message_key']) ? $context['_message_key'] : false;
|
118 |
+
$logger = ! empty($data_parent_row['logger']) ? $data_parent_row['logger'] : false;
|
119 |
+
$post_id = ! empty($context['post_id']) ? $context['post_id'] : false;
|
120 |
+
$post_type = ! empty($context['post_type']) ? $context['post_type'] : false;
|
121 |
+
|
122 |
+
// Bail if not all required vars are set.
|
123 |
+
if (! $message_key || ! $logger || ! $post_id || ! $post_type) {
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
// Only act when logger was SimplePostLogger.
|
128 |
+
if ($logger !== 'SimplePostLogger') {
|
129 |
+
return;
|
130 |
+
}
|
131 |
+
|
132 |
+
// Only act when the saved type was a ACF Field Group.
|
133 |
+
if ($post_type !== 'acf-field-group') {
|
134 |
+
return;
|
135 |
+
}
|
136 |
+
|
137 |
+
// Ok, a row was inserted using the log function on SimplePostLogger,
|
138 |
+
// now ACF will call save_post again and trigger
|
139 |
+
// another log of the same row. To prevent this we
|
140 |
+
// now add a filter to prevent the next log.
|
141 |
+
add_filter('simple_history/post_logger/post_updated/ok_to_log', array( $this, 'prevent_second_acf_field_group_post_save_log' ), 10, 4);
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Fired from SimpleLogger action 'simple_history/post_logger/post_updated/ok_to_log' and added only after
|
146 |
+
* a row already has been logged.
|
147 |
+
*
|
148 |
+
* This function checks if post type logged by SimplePostLogger is a ACF Field Group, and if it is
|
149 |
+
* then don't log that log. This way we prevent the post logger from logging the field group changes twice.
|
150 |
+
*/
|
151 |
+
public function prevent_second_acf_field_group_post_save_log($ok_to_log, $new_status, $old_status, $post)
|
152 |
+
{
|
153 |
+
if (isset($post->post_type) && $post->post_type === 'acf-field-group') {
|
154 |
+
$ok_to_log = false;
|
155 |
+
}
|
156 |
+
|
157 |
+
return $ok_to_log;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Append info about changes in ACF fields input,
|
162 |
+
* i.e. store all info we later use to show changes that a user has done.
|
163 |
+
*
|
164 |
+
* Called when ACF saves a post.
|
165 |
+
*
|
166 |
+
* @param mixed int $post_id ID of post that is being saved. string "option" or "options" when saving an options page.
|
167 |
+
*/
|
168 |
+
public function on_acf_save_post($post_id)
|
169 |
+
{
|
170 |
+
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
171 |
+
return;
|
172 |
+
}
|
173 |
+
|
174 |
+
// Only act when $post_id is numeric, can be "options" too when
|
175 |
+
// ACF saves an options page.
|
176 |
+
if (! is_numeric($post_id)) {
|
177 |
+
return;
|
178 |
+
}
|
179 |
+
|
180 |
+
// Don't act on post revision.
|
181 |
+
if (wp_is_post_revision($post_id)) {
|
182 |
+
return;
|
183 |
+
}
|
184 |
+
|
185 |
+
/*
|
186 |
+
Meta values look like
|
187 |
+
[product_images_0_image] => 625
|
188 |
+
[_product_images_0_image] => field_59a091044812e
|
189 |
+
[product_images_0_image_caption] => Image row yes
|
190 |
+
[_product_images_0_image_caption] => field_59a0910f4812f
|
191 |
+
[product_images_0_image_related_0_related_name] => Related one
|
192 |
+
[_product_images_0_image_related_0_related_name] => field_59aaedd43ae11
|
193 |
+
[product_images_0_image_related_0_related_item_post] =>
|
194 |
+
[_product_images_0_image_related_0_related_item_post] => field_59aaede43ae12
|
195 |
+
[product_images_0_image_related_1_related_name] => Another related
|
196 |
+
[_product_images_0_image_related_1_related_name] => field_59aaedd43ae11
|
197 |
+
[product_images_0_image_related_1_related_item_post] =>
|
198 |
+
[_product_images_0_image_related_1_related_item_post] => field_59aaede43ae12
|
199 |
+
[product_images_0_image_related] => 2
|
200 |
+
[_product_images_0_image_related] => field_59aaedbc3ae10
|
201 |
+
[product_images_1_image] => 574
|
202 |
+
*/
|
203 |
+
$prev_post_meta = isset($this->oldPostData['prev_post_meta']) ? $this->oldPostData['prev_post_meta'] : array();
|
204 |
+
|
205 |
+
$new_post_meta = get_post_custom($post_id);
|
206 |
+
$new_post_meta = array_map('reset', $new_post_meta);
|
207 |
+
|
208 |
+
// New and old post meta can contain different amount of keys,
|
209 |
+
// join them so we have the name of all post meta thaf have been added, removed, or modified.
|
210 |
+
$new_and_old_post_meta = array_merge($prev_post_meta, $new_post_meta);
|
211 |
+
ksort($new_and_old_post_meta, SORT_REGULAR);
|
212 |
+
|
213 |
+
// array1 - The array to compare from
|
214 |
+
// array2 - An array to compare against
|
215 |
+
// Returns an array containing all the values from array1 that are not present in any of the other arrays.
|
216 |
+
// Keep only ACF fields in prev and new post meta.
|
217 |
+
$prev_post_meta = $this->keep_only_acf_stuff_in_array($prev_post_meta, $new_and_old_post_meta);
|
218 |
+
$new_post_meta = $this->keep_only_acf_stuff_in_array($new_post_meta, $new_and_old_post_meta);
|
219 |
+
$new_and_old_post_meta_acf_fields = array_merge($prev_post_meta, $new_post_meta);
|
220 |
+
|
221 |
+
// Map field name with fieldkey so we can get field objects when needed.
|
222 |
+
// Final array have values like:
|
223 |
+
// [product_images_0_image] => field_59a091044812e
|
224 |
+
// [product_images_0_image_caption] => field_59a0910f4812f
|
225 |
+
// [product_images_0_image_related_0_related_name] => field_59aaedd43ae11.
|
226 |
+
$fieldnames_to_field_keys = array();
|
227 |
+
foreach ($new_and_old_post_meta_acf_fields as $meta_key => $meta_value) {
|
228 |
+
// $key is like [product_images_0_image_related_1_related_name].
|
229 |
+
// Get ACF fieldkey for that value. Will be in $new_and_old_post_meta
|
230 |
+
// as the same as key but with underscore first
|
231 |
+
$meta_key_to_look_for = "_{$meta_key}";
|
232 |
+
if (isset($new_and_old_post_meta[ $meta_key_to_look_for ])) {
|
233 |
+
$fieldnames_to_field_keys[ $meta_key ] = $new_and_old_post_meta[ $meta_key_to_look_for ];
|
234 |
+
}
|
235 |
+
}
|
236 |
+
|
237 |
+
// Compare old with new = get only changed, not added, deleted are here.
|
238 |
+
$post_meta_diff1 = array_diff_assoc($prev_post_meta, $new_post_meta);
|
239 |
+
|
240 |
+
// Compare new with old = get an diff with added and changed stuff.
|
241 |
+
$post_meta_diff2 = array_diff_assoc($new_post_meta, $prev_post_meta);
|
242 |
+
|
243 |
+
// Compare keys, gets added fields.
|
244 |
+
$post_meta_added_fields = array_diff(array_keys($post_meta_diff2), array_keys($post_meta_diff1));
|
245 |
+
$post_meta_added_fields = array_values($post_meta_added_fields);
|
246 |
+
|
247 |
+
// Keys that exist in diff1 but not in diff2 = deleted.
|
248 |
+
$post_meta_removed_fields = array_diff_assoc(array_keys($post_meta_diff1), array_keys($post_meta_diff2));
|
249 |
+
$post_meta_removed_fields = array_values($post_meta_removed_fields);
|
250 |
+
|
251 |
+
$post_meta_changed_fields = array_keys($post_meta_diff1);
|
252 |
+
|
253 |
+
/*
|
254 |
+
* value is changed: added to both diff and diff2
|
255 |
+
* value is added, like in repeater: added to diff2 (not to diff)
|
256 |
+
* $diff3: contains only added things.
|
257 |
+
* Compare old and new values
|
258 |
+
* Loop all keys in $new_and_old_post_meta
|
259 |
+
* But act only on those whose keys begins with "_" and where the value begins with "field_" and ends with alphanum.
|
260 |
+
*/
|
261 |
+
|
262 |
+
/*
|
263 |
+
* We have the diff, now add it to the context
|
264 |
+
* This is called after Simple History already has added its row
|
265 |
+
* So... we must add to the context late somehow
|
266 |
+
* Get the latest inserted row from the SimplePostLogger, check if that postID is
|
267 |
+
* same as the
|
268 |
+
*/
|
269 |
+
$post_logger = $this->simpleHistory->getInstantiatedLoggerBySlug('SimplePostLogger');
|
270 |
+
|
271 |
+
// Save ACF diff if detected post here is same as the last one used in Postlogger.
|
272 |
+
if ($post_id === $post_logger->lastInsertContext['post_id']) {
|
273 |
+
$last_insert_id = $post_logger->lastInsertID;
|
274 |
+
|
275 |
+
// Append new info to the context of history item with id $post_logger->lastInsertID.
|
276 |
+
$acf_context = array();
|
277 |
+
$acf_context = $this->add_acf_context($acf_context, 'added', $post_meta_added_fields, $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys);
|
278 |
+
$acf_context = $this->add_acf_context($acf_context, 'changed', $post_meta_changed_fields, $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys);
|
279 |
+
$acf_context = $this->add_acf_context($acf_context, 'removed', $post_meta_removed_fields, $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys);
|
280 |
+
|
281 |
+
$post_logger->append_context($last_insert_id, $acf_context);
|
282 |
+
|
283 |
+
// Prev and new post meta for testing.
|
284 |
+
/*
|
285 |
+
$post_logger->append_context(
|
286 |
+
$last_insert_id,
|
287 |
+
array(
|
288 |
+
'prev_post_meta' => $prev_post_meta,
|
289 |
+
)
|
290 |
+
);
|
291 |
+
$post_logger->append_context(
|
292 |
+
$last_insert_id,
|
293 |
+
array(
|
294 |
+
'new_post_meta' => $new_post_meta,
|
295 |
+
)
|
296 |
+
);
|
297 |
+
*/
|
298 |
+
} // End if().
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Add ACF context for added, removed, or changed fields.
|
303 |
+
*
|
304 |
+
* @param array $context Context.
|
305 |
+
* @param string $modify_type Type. added | removed | changed.
|
306 |
+
* @param array $relevant_acf_fields Fields.
|
307 |
+
* @param array $prev_post_meta Prev meta.
|
308 |
+
* @param array $new_post_meta New meta.
|
309 |
+
* @param array $fieldnames_to_field_keys Fieldnames to field keys mapping.
|
310 |
+
* @return array Modified context.
|
311 |
+
*/
|
312 |
+
public function add_acf_context($context = array(), $modify_type = '', $relevant_acf_fields = array(), $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys)
|
313 |
+
{
|
314 |
+
|
315 |
+
if (! is_array($context) || empty($modify_type) || empty($relevant_acf_fields)) {
|
316 |
+
return $context;
|
317 |
+
}
|
318 |
+
|
319 |
+
$loopnum = 0;
|
320 |
+
foreach ($relevant_acf_fields as $field_slug) {
|
321 |
+
/*
|
322 |
+
Store just the names to begin with
|
323 |
+
acf_field_added_0 = url.
|
324 |
+
acf_field_added_1 = first_name.
|
325 |
+
|
326 |
+
If field slug contains a number, like in "product_images_2_image"
|
327 |
+
that probably means that that field is a repeater with name "product_images"
|
328 |
+
with a sub field called "image" and that the image is the 2:nd among it's selected sub fields.
|
329 |
+
|
330 |
+
Example of how fields can look:
|
331 |
+
acf_field_added_0 product_images_2_image
|
332 |
+
acf_field_added_1 product_images_2_image_caption
|
333 |
+
acf_field_added_2 product_images_2_image_related
|
334 |
+
acf_field_changed_0 my_field_in_acf
|
335 |
+
acf_field_changed_1 product_images
|
336 |
+
acf_field_changed_2 price
|
337 |
+
acf_field_changed_3 description
|
338 |
+
*/
|
339 |
+
$context_key = "acf_field_{$modify_type}_{$loopnum}";
|
340 |
+
$context[ "{$context_key}/slug" ] = $field_slug;
|
341 |
+
|
342 |
+
/*
|
343 |
+
* Try to get som extra info, like display name and type for this field.
|
344 |
+
* For a nice context in the feed we want: parent field group name and type?
|
345 |
+
*/
|
346 |
+
if (isset($fieldnames_to_field_keys[ $field_slug ])) {
|
347 |
+
$field_key = $fieldnames_to_field_keys[ $field_slug ];
|
348 |
+
$context[ "{$context_key}/key" ] = $field_key;
|
349 |
+
|
350 |
+
// Interesting stuff in field object:
|
351 |
+
// - Label = the human readable name of the field
|
352 |
+
// - Type = the type of the field
|
353 |
+
// - Parent = id of parent field post id.
|
354 |
+
$field_object = get_field_object($field_key);
|
355 |
+
|
356 |
+
if (is_array($field_object)) {
|
357 |
+
$context[ "{$context_key}/label" ] = $field_object['label'];
|
358 |
+
if (! empty($field_object['type'])) {
|
359 |
+
$context[ "{$context_key}/type" ] = $field_object['type'];
|
360 |
+
}
|
361 |
+
|
362 |
+
// If no parent just continue to next field.
|
363 |
+
if (empty($field_object['parent'])) {
|
364 |
+
continue;
|
365 |
+
}
|
366 |
+
|
367 |
+
// We have at least one parent, get them all, including the field group
|
368 |
+
// $context[ "{$context_key}/field_parent_object" ] = $parent_field;
|
369 |
+
$field_parents = array();
|
370 |
+
$field_field_group = null;
|
371 |
+
|
372 |
+
// Begin with the direct parent.
|
373 |
+
$parent_field = $field_object;
|
374 |
+
|
375 |
+
while (! empty($parent_field['parent'])) {
|
376 |
+
$parentFieldParent = $parent_field['parent'];
|
377 |
+
|
378 |
+
// acf-field | acf-field-group.
|
379 |
+
$parent_field_post_type = get_post_type($parentFieldParent);
|
380 |
+
|
381 |
+
if (false === $parent_field_post_type) {
|
382 |
+
break;
|
383 |
+
}
|
384 |
+
|
385 |
+
if ('acf-field' === $parent_field_post_type) {
|
386 |
+
// Field is when field is for example a sub field of a repeater.
|
387 |
+
if (function_exists('acf_get_field')) {
|
388 |
+
// Since ACF 5.7.10 the acf_get_field() function is available.
|
389 |
+
$parent_field = acf_get_field($parentFieldParent);
|
390 |
+
} elseif (function_exists('_acf_get_field_by_id')) {
|
391 |
+
// ACF function _acf_get_field_by_id() is available before ACF 5.7.10.
|
392 |
+
$parent_field = _acf_get_field_by_id($parentFieldParent);
|
393 |
+
}
|
394 |
+
} elseif ('acf-field-group' === $parent_field_post_type) {
|
395 |
+
$parent_field = acf_get_field_group($parentFieldParent);
|
396 |
+
} else {
|
397 |
+
// Unknown post type.
|
398 |
+
break;
|
399 |
+
}
|
400 |
+
|
401 |
+
if (false === $parent_field) {
|
402 |
+
break;
|
403 |
+
}
|
404 |
+
|
405 |
+
if ('acf-field' === $parent_field_post_type) {
|
406 |
+
$field_parents[] = $parent_field;
|
407 |
+
} elseif ('acf-field-group' === $parent_field_post_type) {
|
408 |
+
$field_field_group = $parent_field;
|
409 |
+
} // End if().
|
410 |
+
} // End while().
|
411 |
+
|
412 |
+
$field_parents = array_reverse($field_parents);
|
413 |
+
|
414 |
+
// Array with info about each parent.
|
415 |
+
$arr_field_path = array();
|
416 |
+
|
417 |
+
if (! empty($field_field_group['title'])) {
|
418 |
+
$arr_field_path[] = array(
|
419 |
+
'name' => $field_field_group['title'],
|
420 |
+
'type' => 'field_group',
|
421 |
+
);
|
422 |
+
}
|
423 |
+
|
424 |
+
foreach ($field_parents as $one_field_parent) {
|
425 |
+
$arr_field_path[] = array(
|
426 |
+
'name' => $one_field_parent['label'],
|
427 |
+
'type' => 'field',
|
428 |
+
'field_type' => $one_field_parent['type'],
|
429 |
+
);
|
430 |
+
}
|
431 |
+
|
432 |
+
if (! empty($arr_field_path)) {
|
433 |
+
$path_loop_num = 0;
|
434 |
+
foreach ($arr_field_path as $one_field_path) {
|
435 |
+
$context[ "{$context_key}/path_{$path_loop_num}/name" ] = $one_field_path['name'];
|
436 |
+
$context[ "{$context_key}/path_{$path_loop_num}/type" ] = $one_field_path['type'];
|
437 |
+
if (! empty($one_field_path['field_type'])) {
|
438 |
+
$context[ "{$context_key}/path_{$path_loop_num}/field_type" ] = $one_field_path['field_type'];
|
439 |
+
}
|
440 |
+
$path_loop_num++;
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
// Add value of fields if they are not part of
|
445 |
+
// repeatable or flexible fields or similar.
|
446 |
+
// error_log( "Final parents" . print_r( $field_parents, 1 ) );
|
447 |
+
// error_log( "Final field group" . print_r( $field_field_group['title'], 1 ) );
|
448 |
+
// error_log( "context" . print_r( $context, 1 ) );
|
449 |
+
} // End if().
|
450 |
+
} // End if().
|
451 |
+
|
452 |
+
$loopnum++;
|
453 |
+
} // End foreach().
|
454 |
+
|
455 |
+
// error_log( "---------------------------" );
|
456 |
+
// error_log( "field_path_string: $field_path_string");
|
457 |
+
// error_log( "context" . print_r( $context, 1 ) );
|
458 |
+
return $context;
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Clean array and keep only ACF related things.
|
463 |
+
*
|
464 |
+
* Remove
|
465 |
+
* - underscore fields
|
466 |
+
* - fields with value field_*
|
467 |
+
*
|
468 |
+
* Keep
|
469 |
+
* - vals that are acf
|
470 |
+
*
|
471 |
+
* @param array $arr Array.
|
472 |
+
* @param array $all_fields Array fields.
|
473 |
+
*/
|
474 |
+
public function keep_only_acf_stuff_in_array($arr, $all_fields)
|
475 |
+
{
|
476 |
+
$new_arr = array();
|
477 |
+
|
478 |
+
foreach ($arr as $key => $val) {
|
479 |
+
// Don't keep keys that begin with underscore "_".
|
480 |
+
if (strpos($key, '_') === 0) {
|
481 |
+
continue;
|
482 |
+
}
|
483 |
+
|
484 |
+
// Don't keep keys that begin with "field_".
|
485 |
+
if (strpos($val, 'field_') === 0) {
|
486 |
+
continue;
|
487 |
+
}
|
488 |
+
|
489 |
+
// Don't keep fields that does not have a corresponding _field value.
|
490 |
+
// Each key has both the name, for example 'color' and another
|
491 |
+
// key called '_color'. We check that the underscore version exists
|
492 |
+
// and contains 'field_'. After this check only ACF fields should exist
|
493 |
+
// in the array..
|
494 |
+
if (! isset($all_fields[ "_{$key}" ])) {
|
495 |
+
continue;
|
496 |
+
}
|
497 |
+
|
498 |
+
if (strpos($all_fields[ "_{$key}" ], 'field_') !== 0) {
|
499 |
+
continue;
|
500 |
+
}
|
501 |
+
|
502 |
+
$new_arr[ $key ] = $val;
|
503 |
+
}
|
504 |
+
|
505 |
+
return $new_arr;
|
506 |
+
}
|
507 |
+
|
508 |
+
/**
|
509 |
+
* Store prev post meta when post is saved.
|
510 |
+
* Stores data in $this->oldPostData.
|
511 |
+
*/
|
512 |
+
public function on_admin_action_editpost()
|
513 |
+
{
|
514 |
+
$post_ID = isset($_POST['post_ID']) ? (int) $_POST['post_ID'] : 0;
|
515 |
+
|
516 |
+
if (! $post_ID) {
|
517 |
+
return;
|
518 |
+
}
|
519 |
+
|
520 |
+
$prev_post = get_post($post_ID);
|
521 |
+
|
522 |
+
if (is_wp_error($prev_post)) {
|
523 |
+
return;
|
524 |
+
}
|
525 |
+
|
526 |
+
$post_meta = get_post_custom($post_ID);
|
527 |
+
|
528 |
+
// Meta is array of arrays, get first value of each array value.
|
529 |
+
$post_meta = array_map('reset', $post_meta);
|
530 |
+
|
531 |
+
$this->oldPostData['prev_post_meta'] = $post_meta;
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Called from PostLogger and its diff table output using filter 'simple_history/post_logger/post_updated/diff_table_output'.
|
536 |
+
* Diff table is generated only for post type 'acf-field-group'.
|
537 |
+
*
|
538 |
+
* @param string $diff_table_output
|
539 |
+
* @param array $context
|
540 |
+
* @return string
|
541 |
+
*/
|
542 |
+
public function on_diff_table_output_field_group($diff_table_output, $context)
|
543 |
+
{
|
544 |
+
$post_type = ! empty($context['post_type']) ? $context['post_type'] : false;
|
545 |
+
|
546 |
+
// Bail if not ACF Field Group.
|
547 |
+
if ($post_type !== 'acf-field-group') {
|
548 |
+
return $diff_table_output;
|
549 |
+
}
|
550 |
+
|
551 |
+
// Field group fields to check for and output if found
|
552 |
+
$arrKeys = array(
|
553 |
+
'instruction_placement' => array(
|
554 |
+
'name' => _x('Instruction placement', 'Logger: Plugin ACF', 'simple-history'),
|
555 |
+
),
|
556 |
+
'label_placement' => array(
|
557 |
+
'name' => _x('Label placement', 'Logger: Plugin ACF', 'simple-history'),
|
558 |
+
),
|
559 |
+
'description' => array(
|
560 |
+
'name' => _x('Description', 'Logger: Plugin ACF', 'simple-history'),
|
561 |
+
),
|
562 |
+
'menu_order' => array(
|
563 |
+
'name' => _x('Menu order', 'Logger: Plugin ACF', 'simple-history'),
|
564 |
+
),
|
565 |
+
'position' => array(
|
566 |
+
'name' => _x('Position', 'Logger: Plugin ACF', 'simple-history'),
|
567 |
+
),
|
568 |
+
'active' => array(
|
569 |
+
'name' => _x('Active', 'Logger: Plugin ACF', 'simple-history'),
|
570 |
+
),
|
571 |
+
'style' => array(
|
572 |
+
'name' => _x('Style', 'Logger: Plugin ACF', 'simple-history'),
|
573 |
+
),
|
574 |
+
);
|
575 |
+
|
576 |
+
foreach ($arrKeys as $acfKey => $acfVals) {
|
577 |
+
if (isset($context[ "acf_new_$acfKey" ]) && isset($context[ "acf_prev_$acfKey" ])) {
|
578 |
+
$diff_table_output .= sprintf(
|
579 |
+
'<tr>
|
580 |
<td>%1$s</td>
|
581 |
<td>
|
582 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
583 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
584 |
</td>
|
585 |
</tr>',
|
586 |
+
$acfVals['name'],
|
587 |
+
esc_html($context[ "acf_new_$acfKey" ]),
|
588 |
+
esc_html($context[ "acf_prev_$acfKey" ])
|
589 |
+
);
|
590 |
+
}
|
591 |
+
}
|
592 |
+
|
593 |
+
// If only acf_hide_on_screen_removed exists nothing is outputed.
|
594 |
+
$acf_hide_on_screen_added = empty($context['acf_hide_on_screen_added']) ? null : $context['acf_hide_on_screen_added'];
|
595 |
+
$acf_hide_on_screen_removed = empty($context['acf_hide_on_screen_removed']) ? null : $context['acf_hide_on_screen_removed'];
|
596 |
+
|
597 |
+
if ($acf_hide_on_screen_added || $acf_hide_on_screen_removed) {
|
598 |
+
$strCheckedHideOnScreen = '';
|
599 |
+
$strUncheckedHideOnScreen = '';
|
600 |
+
|
601 |
+
if ($acf_hide_on_screen_added) {
|
602 |
+
$strCheckedHideOnScreen = sprintf(
|
603 |
+
'%1$s %2$s',
|
604 |
+
_x('Checked', 'Logger: Plugin ACF', 'simple-history'), // 1
|
605 |
+
esc_html($acf_hide_on_screen_added) // 2
|
606 |
+
);
|
607 |
+
}
|
608 |
+
|
609 |
+
if ($acf_hide_on_screen_removed) {
|
610 |
+
$strUncheckedHideOnScreen = sprintf(
|
611 |
+
'%1$s %2$s',
|
612 |
+
_x('Unchecked', 'Logger: Plugin ACF', 'simple-history'), // 1
|
613 |
+
esc_html($acf_hide_on_screen_removed) // 2
|
614 |
+
);
|
615 |
+
}
|
616 |
+
|
617 |
+
$diff_table_output .= sprintf(
|
618 |
+
'<tr>
|
619 |
<td>%1$s</td>
|
620 |
<td>
|
621 |
%2$s
|
622 |
%3$s
|
623 |
</td>
|
624 |
</tr>',
|
625 |
+
_x('Hide on screen', 'Logger: Plugin ACF', 'simple-history'), // 1
|
626 |
+
$strCheckedHideOnScreen, // 2
|
627 |
+
$strUncheckedHideOnScreen // 3
|
628 |
+
);
|
629 |
+
}
|
630 |
+
|
631 |
+
// Check for deleted fields.
|
632 |
+
if (isset($context['acf_deleted_fields_0_key'])) {
|
633 |
+
// 1 or more deleted fields exist in context.
|
634 |
+
$loopnum = 0;
|
635 |
+
$strDeletedFields = '';
|
636 |
+
|
637 |
+
while (isset($context[ "acf_deleted_fields_{$loopnum}_key" ])) {
|
638 |
+
$strDeletedFields .= sprintf(
|
639 |
+
'%1$s (%3$s), ',
|
640 |
+
esc_html($context[ "acf_deleted_fields_{$loopnum}_label" ]),
|
641 |
+
esc_html($context[ "acf_deleted_fields_{$loopnum}_name" ]),
|
642 |
+
esc_html($context[ "acf_deleted_fields_{$loopnum}_type" ])
|
643 |
+
);
|
644 |
+
|
645 |
+
$loopnum++;
|
646 |
+
}
|
647 |
+
|
648 |
+
$strDeletedFields = trim($strDeletedFields, ', ');
|
649 |
+
|
650 |
+
$diff_table_output .= sprintf(
|
651 |
+
'<tr>
|
652 |
<td>%1$s</td>
|
653 |
<td>%2$s</td>
|
654 |
</tr>',
|
655 |
+
_nx('Deleted field', 'Deleted fields', $loopnum, 'Logger: Plugin ACF', 'simple-history'), // 1
|
656 |
+
$strDeletedFields
|
657 |
+
);
|
658 |
+
} // if deleted fields
|
659 |
+
|
660 |
+
// Check for added fields
|
661 |
+
if (isset($context['acf_added_fields_0_key'])) {
|
662 |
+
// 1 or more deleted fields exist in context
|
663 |
+
$loopnum = 0;
|
664 |
+
$strAddedFields = '';
|
665 |
+
|
666 |
+
while (isset($context[ "acf_added_fields_{$loopnum}_key" ])) {
|
667 |
+
$strAddedFields .= sprintf(
|
668 |
+
'%1$s (%3$s), ',
|
669 |
+
esc_html($context[ "acf_added_fields_{$loopnum}_label" ]), // 1
|
670 |
+
esc_html($context[ "acf_added_fields_{$loopnum}_name" ]), // 2
|
671 |
+
esc_html($context[ "acf_added_fields_{$loopnum}_type" ]) // 3
|
672 |
+
);
|
673 |
+
|
674 |
+
$loopnum++;
|
675 |
+
}
|
676 |
+
|
677 |
+
$strAddedFields = trim($strAddedFields, ', ');
|
678 |
+
|
679 |
+
$diff_table_output .= sprintf(
|
680 |
+
'<tr>
|
681 |
<td>%1$s</td>
|
682 |
<td>%2$s</td>
|
683 |
</tr>',
|
684 |
+
_nx('Added field', 'Added fields', $loopnum, 'Logger: Plugin ACF', 'simple-history'), // 1
|
685 |
+
$strAddedFields
|
686 |
+
);
|
687 |
+
} // if deleted fields
|
688 |
+
|
689 |
+
// Check for modified fields
|
690 |
+
if (isset($context['acf_modified_fields_0_ID_prev'])) {
|
691 |
+
// 1 or more modifiedfields exist in context
|
692 |
+
$loopnum = 0;
|
693 |
+
$strModifiedFields = '';
|
694 |
+
$arrAddedFieldsKeysToCheck = array(
|
695 |
+
'name' => array(
|
696 |
+
'name' => _x('Name: ', 'Logger: Plugin ACF', 'simple-history'),
|
697 |
+
),
|
698 |
+
'parent' => array(
|
699 |
+
'name' => _x('Parent: ', 'Logger: Plugin ACF', 'simple-history'),
|
700 |
+
),
|
701 |
+
'key' => array(
|
702 |
+
'name' => _x('Key: ', 'Logger: Plugin ACF', 'simple-history'),
|
703 |
+
),
|
704 |
+
'label' => array(
|
705 |
+
'name' => _x('Label: ', 'Logger: Plugin ACF', 'simple-history'),
|
706 |
+
),
|
707 |
+
'type' => array(
|
708 |
+
'name' => _x('Type: ', 'Logger: Plugin ACF', 'simple-history'),
|
709 |
+
),
|
710 |
+
);
|
711 |
+
|
712 |
+
while (isset($context[ "acf_modified_fields_{$loopnum}_name_prev" ])) {
|
713 |
+
// One modified field, with one or more changed things
|
714 |
+
$strOneModifiedField = '';
|
715 |
+
|
716 |
+
// Add the field name manually, if it is not among the changed field,
|
717 |
+
// or we don't know what field the other changed values belongs to.
|
718 |
+
/*
|
719 |
+
if (empty($context["acf_modified_fields_{$loopnum}_name_new"])) {
|
720 |
+
$strOneModifiedField .= sprintf(
|
721 |
+
_x('Name: %1$s', 'Logger: Plugin ACF', 'simple-history'), // 1
|
722 |
+
esc_html($context["acf_modified_fields_{$loopnum}_name_prev"]) // 2
|
723 |
+
);
|
724 |
+
}
|
725 |
+
*/
|
726 |
+
|
727 |
+
// Add the label name manually, if it is not among the changed field,
|
728 |
+
// or we don't know what field the other changed values belongs to.
|
729 |
+
if (empty($context[ "acf_modified_fields_{$loopnum}_label_new" ])) {
|
730 |
+
$strOneModifiedField .= sprintf(
|
731 |
+
_x('Label: %1$s', 'Logger: Plugin ACF', 'simple-history'), // 1
|
732 |
+
esc_html($context[ "acf_modified_fields_{$loopnum}_label_prev" ]) // 2
|
733 |
+
);
|
734 |
+
}
|
735 |
+
|
736 |
+
// Check for other keys changed for this field
|
737 |
+
foreach ($arrAddedFieldsKeysToCheck as $oneAddedFieldKeyToCheck => $oneAddedFieldKeyToCheckVals) {
|
738 |
+
$newAndOldValsExists = isset($context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_new" ]) && isset($context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_new" ]);
|
739 |
+
if ($newAndOldValsExists) {
|
740 |
+
$strOneModifiedField .= sprintf(
|
741 |
+
'
|
742 |
%4$s
|
743 |
%3$s
|
744 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%1$s</ins>
|
745 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%2$s</del>
|
746 |
',
|
747 |
+
esc_html($context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_new" ]), // 1
|
748 |
+
esc_html($context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_prev" ]), // 2
|
749 |
+
esc_html($oneAddedFieldKeyToCheckVals['name']), // 3
|
750 |
+
empty($strOneModifiedField) ? '' : '<br>' // 4 new line
|
751 |
+
);
|
752 |
+
}
|
753 |
+
}
|
754 |
+
|
755 |
+
$strOneModifiedField = trim($strOneModifiedField, ", \n\r\t");
|
756 |
+
|
757 |
+
if ($strOneModifiedField) {
|
758 |
+
$strModifiedFields .= sprintf(
|
759 |
+
'<tr>
|
760 |
<td>%1$s</td>
|
761 |
<td>%2$s</td>
|
762 |
</tr>',
|
763 |
+
_x('Modified field', 'Logger: Plugin ACF', 'simple-history'), // 1
|
764 |
+
$strOneModifiedField
|
765 |
+
);
|
766 |
+
}
|
767 |
+
|
768 |
+
$loopnum++;
|
769 |
+
}
|
770 |
+
|
771 |
+
/*
|
772 |
+
if ($strModifiedFields) {
|
773 |
+
$strModifiedFields = sprintf(
|
774 |
+
'<tr>
|
775 |
+
<td>%1$s</td>
|
776 |
+
<td>%2$s</td>
|
777 |
+
</tr>',
|
778 |
+
_nx('Modified field', 'Modified fields', $loopnum, 'Logger: Plugin ACF', 'simple-history'), // 1
|
779 |
+
$strModifiedFields
|
780 |
+
) . $strModifiedFields;
|
781 |
+
}*/
|
782 |
+
|
783 |
+
$diff_table_output .= $strModifiedFields;
|
784 |
+
} // if deleted fields
|
785 |
+
|
786 |
+
return $diff_table_output;
|
787 |
+
}
|
788 |
+
|
789 |
+
/**
|
790 |
+
* Append ACF data to post context.
|
791 |
+
*
|
792 |
+
* Called via filter `simple_history/post_logger/post_updated/context`.
|
793 |
+
*
|
794 |
+
* @param array $context
|
795 |
+
* @param WP_Post $post
|
796 |
+
*/
|
797 |
+
public function on_post_updated_context($context, $post)
|
798 |
+
{
|
799 |
+
|
800 |
+
// Only act if this is a ACF field group that is saved
|
801 |
+
if ($post->post_type !== 'acf-field-group') {
|
802 |
+
return $context;
|
803 |
+
}
|
804 |
+
|
805 |
+
// Remove some keys that we don't want,
|
806 |
+
// for example the content because that's just a json string
|
807 |
+
// in acf-field-group posts.
|
808 |
+
unset(
|
809 |
+
$context['post_prev_post_content'],
|
810 |
+
$context['post_new_post_content'],
|
811 |
+
$context['post_prev_post_name'],
|
812 |
+
$context['post_new_post_name'],
|
813 |
+
$context['post_prev_post_date'],
|
814 |
+
$context['post_new_post_date'],
|
815 |
+
$context['post_prev_post_date_gmt'],
|
816 |
+
$context['post_new_post_date_gmt']
|
817 |
+
);
|
818 |
+
|
819 |
+
$acf_data_diff = array();
|
820 |
+
|
821 |
+
// 'fieldGroup' fields to check.
|
822 |
+
$arr_field_group_keys_to_diff = array(
|
823 |
+
'menu_order',
|
824 |
+
'position',
|
825 |
+
'style',
|
826 |
+
'label_placement',
|
827 |
+
'instruction_placement',
|
828 |
+
'active',
|
829 |
+
'description',
|
830 |
+
);
|
831 |
+
|
832 |
+
$fieldGroup = $this->oldAndNewFieldGroupsAndFields['fieldGroup'];
|
833 |
+
|
834 |
+
foreach ($arr_field_group_keys_to_diff as $key) {
|
835 |
+
if (isset($fieldGroup['old'][ $key ]) && isset($fieldGroup['new'][ $key ])) {
|
836 |
+
$acf_data_diff = $this->add_diff($acf_data_diff, $key, (string) $fieldGroup['old'][ $key ], (string) $fieldGroup['new'][ $key ]);
|
837 |
+
}
|
838 |
+
}
|
839 |
+
|
840 |
+
foreach ($acf_data_diff as $diff_key => $diff_values) {
|
841 |
+
$context[ "acf_prev_{$diff_key}" ] = $diff_values['old'];
|
842 |
+
$context[ "acf_new_{$diff_key}" ] = $diff_values['new'];
|
843 |
+
}
|
844 |
+
|
845 |
+
// Add checked or uncheckd hide on screen-items to context
|
846 |
+
$arrhHideOnScreenAdded = array();
|
847 |
+
$arrHideOnScreenRemoved = array();
|
848 |
+
|
849 |
+
$fieldGroup['new']['hide_on_screen'] = isset($fieldGroup['new']['hide_on_screen']) && is_array($fieldGroup['new']['hide_on_screen']) ? $fieldGroup['new']['hide_on_screen'] : array();
|
850 |
+
$fieldGroup['old']['hide_on_screen'] = isset($fieldGroup['old']['hide_on_screen']) && is_array($fieldGroup['old']['hide_on_screen']) ? $fieldGroup['old']['hide_on_screen'] : array();
|
851 |
+
|
852 |
+
// dd($fieldGroup['old']['hide_on_screen'], $fieldGroup['new']['hide_on_screen']);
|
853 |
+
// Act when new or old hide_on_screen is set
|
854 |
+
if (! empty($fieldGroup['new']['hide_on_screen']) || ! empty($fieldGroup['old']['hide_on_screen'])) {
|
855 |
+
$arrhHideOnScreenAdded = array_diff($fieldGroup['new']['hide_on_screen'], $fieldGroup['old']['hide_on_screen']);
|
856 |
+
$arrHideOnScreenRemoved = array_diff($fieldGroup['old']['hide_on_screen'], $fieldGroup['new']['hide_on_screen']);
|
857 |
+
|
858 |
+
// ddd($arrhHideOnScreenAdded, $arrHideOnScreenRemoved);
|
859 |
+
if ($arrhHideOnScreenAdded) {
|
860 |
+
$context['acf_hide_on_screen_added'] = implode(',', $arrhHideOnScreenAdded);
|
861 |
+
}
|
862 |
+
|
863 |
+
if ($arrHideOnScreenRemoved) {
|
864 |
+
$context['acf_hide_on_screen_removed'] = implode(',', $arrHideOnScreenRemoved);
|
865 |
+
}
|
866 |
+
}
|
867 |
+
|
868 |
+
// ddd($context, $arrhHideOnScreenAdded, $arrHideOnScreenRemoved);
|
869 |
+
// Add removed fields to context
|
870 |
+
if (! empty($this->oldAndNewFieldGroupsAndFields['deletedFields']) && is_array($this->oldAndNewFieldGroupsAndFields['deletedFields'])) {
|
871 |
+
$loopnum = 0;
|
872 |
+
foreach ($this->oldAndNewFieldGroupsAndFields['deletedFields'] as $oneDeletedField) {
|
873 |
+
$context[ "acf_deleted_fields_{$loopnum}_key" ] = $oneDeletedField['key'];
|
874 |
+
$context[ "acf_deleted_fields_{$loopnum}_name" ] = $oneDeletedField['name'];
|
875 |
+
$context[ "acf_deleted_fields_{$loopnum}_label" ] = $oneDeletedField['label'];
|
876 |
+
$context[ "acf_deleted_fields_{$loopnum}_type" ] = $oneDeletedField['type'];
|
877 |
+
$loopnum++;
|
878 |
+
}
|
879 |
+
}
|
880 |
+
|
881 |
+
// Add added fields to context
|
882 |
+
if (! empty($this->oldAndNewFieldGroupsAndFields['addedFields']) && is_array($this->oldAndNewFieldGroupsAndFields['addedFields'])) {
|
883 |
+
$loopnum = 0;
|
884 |
+
|
885 |
+
foreach ($this->oldAndNewFieldGroupsAndFields['addedFields'] as $oneAddedField) {
|
886 |
+
// Id not available here, wold be nice to have
|
887 |
+
// $context["acf_added_fields_{$loopnum}_ID"] = $oneAddedField['ID'];
|
888 |
+
$context[ "acf_added_fields_{$loopnum}_key" ] = $oneAddedField['key'];
|
889 |
+
$context[ "acf_added_fields_{$loopnum}_name" ] = $oneAddedField['name'];
|
890 |
+
$context[ "acf_added_fields_{$loopnum}_label" ] = $oneAddedField['label'];
|
891 |
+
$context[ "acf_added_fields_{$loopnum}_type" ] = $oneAddedField['type'];
|
892 |
+
$loopnum++;
|
893 |
+
}
|
894 |
+
}
|
895 |
+
|
896 |
+
// Add modified fields to context
|
897 |
+
// dd('on_post_updated_context', $context, $this->oldAndNewFieldGroupsAndFields);
|
898 |
+
if (! empty($this->oldAndNewFieldGroupsAndFields['modifiedFields']['old']) && ! empty($this->oldAndNewFieldGroupsAndFields['modifiedFields']['new'])) {
|
899 |
+
$modifiedFields = $this->oldAndNewFieldGroupsAndFields['modifiedFields'];
|
900 |
+
|
901 |
+
$arr_added_fields_keys_to_add = array(
|
902 |
+
'parent',
|
903 |
+
'key',
|
904 |
+
'label',
|
905 |
+
'name',
|
906 |
+
'type',
|
907 |
+
);
|
908 |
+
|
909 |
+
$loopnum = 0;
|
910 |
+
|
911 |
+
foreach ($modifiedFields['old'] as $modifiedFieldId => $modifiedFieldValues) {
|
912 |
+
// Both old and new values mest exist
|
913 |
+
if (empty($modifiedFields['new'][ $modifiedFieldId ])) {
|
914 |
+
continue;
|
915 |
+
}
|
916 |
+
|
917 |
+
// Always add ID, name, and lavel
|
918 |
+
$context[ "acf_modified_fields_{$loopnum}_ID_prev" ] = $modifiedFields['old'][ $modifiedFieldId ]['ID'];
|
919 |
+
$context[ "acf_modified_fields_{$loopnum}_name_prev" ] = $modifiedFields['old'][ $modifiedFieldId ]['name'];
|
920 |
+
$context[ "acf_modified_fields_{$loopnum}_label_prev" ] = $modifiedFields['old'][ $modifiedFieldId ]['label'];
|
921 |
+
|
922 |
+
foreach ($arr_added_fields_keys_to_add as $one_key_to_add) {
|
923 |
+
// Check that new and old exist.
|
924 |
+
$new_exists = isset($modifiedFields['new'][ $modifiedFieldId ][ $one_key_to_add ]);
|
925 |
+
$old_exists = isset($modifiedFields['old'][ $modifiedFieldId ][ $one_key_to_add ]);
|
926 |
+
|
927 |
+
if (! $new_exists || ! $old_exists) {
|
928 |
+
continue;
|
929 |
+
}
|
930 |
+
|
931 |
+
// Only add to context if modified.
|
932 |
+
if ($modifiedFields['new'][ $modifiedFieldId ][ $one_key_to_add ] != $modifiedFields['old'][ $modifiedFieldId ][ $one_key_to_add ]) {
|
933 |
+
$context[ "acf_modified_fields_{$loopnum}_{$one_key_to_add}_prev" ] = $modifiedFields['old'][ $modifiedFieldId ][ $one_key_to_add ];
|
934 |
+
$context[ "acf_modified_fields_{$loopnum}_{$one_key_to_add}_new" ] = $modifiedFields['new'][ $modifiedFieldId ][ $one_key_to_add ];
|
935 |
+
}
|
936 |
+
}
|
937 |
+
|
938 |
+
$loopnum++;
|
939 |
+
}
|
940 |
+
}
|
941 |
+
|
942 |
+
return $context;
|
943 |
+
}
|
944 |
+
|
945 |
+
public function add_diff($post_data_diff, $key, $old_value, $new_value)
|
946 |
+
{
|
947 |
+
if ($old_value != $new_value) {
|
948 |
+
$post_data_diff[ $key ] = array(
|
949 |
+
'old' => $old_value,
|
950 |
+
'new' => $new_value,
|
951 |
+
);
|
952 |
+
}
|
953 |
+
|
954 |
+
return $post_data_diff;
|
955 |
+
}
|
956 |
+
|
957 |
+
/**
|
958 |
+
* Store a version of the field group as it was before the save
|
959 |
+
* Called before field group post/values is added to db
|
960 |
+
*
|
961 |
+
* @param array $data Post data.
|
962 |
+
* @param array $postarr Post data.
|
963 |
+
*/
|
964 |
+
public function on_wp_insert_post_data($data, $postarr)
|
965 |
+
{
|
966 |
+
|
967 |
+
// Only do this if ACF field group is being saved.
|
968 |
+
if ($postarr['post_type'] !== 'acf-field-group') {
|
969 |
+
return $data;
|
970 |
+
}
|
971 |
+
|
972 |
+
if (empty($postarr['ID'])) {
|
973 |
+
return $data;
|
974 |
+
}
|
975 |
+
|
976 |
+
if (empty($_POST['acf_field_group'])) {
|
977 |
+
return $data;
|
978 |
+
}
|
979 |
+
|
980 |
+
$this->oldAndNewFieldGroupsAndFields['fieldGroup']['old'] = acf_get_field_group($postarr['ID']);
|
981 |
+
|
982 |
+
$this->oldAndNewFieldGroupsAndFields['fieldGroup']['new'] = acf_get_valid_field_group($_POST['acf_field_group']);
|
983 |
+
|
984 |
+
return $data;
|
985 |
+
}
|
986 |
+
|
987 |
+
/**
|
988 |
+
* ACF field group is saved
|
989 |
+
* Called before ACF calls its save_post filter
|
990 |
+
* Here we save the new fields values and also get the old values so we can compare
|
991 |
+
*/
|
992 |
+
public function on_transition_post_status($new_status, $old_status, $post)
|
993 |
+
{
|
994 |
+
static $isCalled = false;
|
995 |
+
|
996 |
+
if ($isCalled) {
|
997 |
+
return;
|
998 |
+
}
|
999 |
+
|
1000 |
+
$isCalled = true;
|
1001 |
+
|
1002 |
+
$post_id = $post->ID;
|
1003 |
+
|
1004 |
+
// do not act if this is an auto save routine
|
1005 |
+
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
1006 |
+
return;
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
// bail early if not acf-field-group
|
1010 |
+
if ($post->post_type !== 'acf-field-group') {
|
1011 |
+
return;
|
1012 |
+
}
|
1013 |
+
|
1014 |
+
// only save once! WordPress save's a revision as well.
|
1015 |
+
if (wp_is_post_revision($post_id)) {
|
1016 |
+
return;
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
// Store info about fields that are going to be deleted
|
1020 |
+
if (! empty($_POST['_acf_delete_fields'])) {
|
1021 |
+
$deletedFieldsIDs = explode('|', $_POST['_acf_delete_fields']);
|
1022 |
+
$deletedFieldsIDs = array_map('intval', $deletedFieldsIDs);
|
1023 |
+
|
1024 |
+
foreach ($deletedFieldsIDs as $id) {
|
1025 |
+
if (! $id) {
|
1026 |
+
continue;
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
$field_info = acf_get_field($id);
|
1030 |
+
|
1031 |
+
if (! $field_info) {
|
1032 |
+
continue;
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
$this->oldAndNewFieldGroupsAndFields['deletedFields'][ $id ] = $field_info;
|
1036 |
+
}
|
1037 |
+
}
|
1038 |
+
|
1039 |
+
// Store info about added or modified fields
|
1040 |
+
if (! empty($_POST['acf_fields']) && is_array($_POST['acf_fields'])) {
|
1041 |
+
foreach ($_POST['acf_fields'] as $oneFieldAddedOrUpdated) {
|
1042 |
+
if (empty($oneFieldAddedOrUpdated['ID'])) {
|
1043 |
+
// New fields have no id
|
1044 |
+
// 'ID' => string(0) ""
|
1045 |
+
$this->oldAndNewFieldGroupsAndFields['addedFields'][] = $oneFieldAddedOrUpdated;
|
1046 |
+
} else {
|
1047 |
+
// Existing fields have an id
|
1048 |
+
// 'ID' => string(3) "383"
|
1049 |
+
$this->oldAndNewFieldGroupsAndFields['modifiedFields']['old'][ $oneFieldAddedOrUpdated['ID'] ] = acf_get_field($oneFieldAddedOrUpdated['ID']);
|
1050 |
+
|
1051 |
+
$this->oldAndNewFieldGroupsAndFields['modifiedFields']['new'][ $oneFieldAddedOrUpdated['ID'] ] = $oneFieldAddedOrUpdated;
|
1052 |
+
}
|
1053 |
+
}
|
1054 |
+
}
|
1055 |
+
|
1056 |
+
// We don't do anything else here, but we make the actual logging
|
1057 |
+
// in filter 'acf/update_field_group' beacuse it's safer because
|
1058 |
+
// ACF has done it's validation and it's after ACF has saved the fields,
|
1059 |
+
// so less likely that we make some critical error
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
|
1063 |
+
/**
|
1064 |
+
* Add the post types that ACF uses for fields to the array of post types
|
1065 |
+
* that the default post logger should not log. If not each field will cause one
|
1066 |
+
* post update log message.
|
1067 |
+
*/
|
1068 |
+
public function remove_acf_from_postlogger($skip_posttypes)
|
1069 |
+
{
|
1070 |
+
array_push(
|
1071 |
+
$skip_posttypes,
|
1072 |
+
'acf-field'
|
1073 |
+
);
|
1074 |
+
|
1075 |
+
return $skip_posttypes;
|
1076 |
+
}
|
1077 |
+
} // Class.
|
1078 |
} // End if().
|
loggers/Plugin_BeaverBuilder.php
CHANGED
@@ -6,90 +6,109 @@ defined('ABSPATH') or die();
|
|
6 |
* Logger for Beaver Builder
|
7 |
*/
|
8 |
if (!class_exists('Plugin_BeaverBuilder')) {
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
|
48 |
-
|
49 |
-
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
add_action(
|
58 |
-
'fl_builder_after_save_layout',
|
59 |
-
array($this, 'save_layout'),
|
60 |
-
10,
|
61 |
-
4
|
62 |
-
);
|
63 |
-
add_action(
|
64 |
-
'fl_builder_after_save_user_template',
|
65 |
-
array($this, 'save_layout'),
|
66 |
-
10,
|
67 |
-
4
|
68 |
-
);
|
69 |
-
add_action(
|
70 |
-
'fl_builder_after_save_draft',
|
71 |
-
array($this, 'save_layout'),
|
72 |
-
10,
|
73 |
-
4
|
74 |
-
);
|
75 |
-
add_action('fl_builder_admin_settings_save', array(
|
76 |
-
$this,
|
77 |
-
'save_admin'
|
78 |
-
));
|
79 |
-
}
|
80 |
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
{
|
83 |
-
|
84 |
$context = array(
|
85 |
'layout_name' => $post->post_name
|
86 |
);
|
87 |
-
$this->noticeMessage('
|
88 |
}
|
89 |
-
|
90 |
-
|
91 |
{
|
92 |
-
$
|
|
|
|
|
|
|
93 |
}
|
94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
} // End if().
|
6 |
* Logger for Beaver Builder
|
7 |
*/
|
8 |
if (!class_exists('Plugin_BeaverBuilder')) {
|
9 |
+
class Plugin_BeaverBuilder extends SimpleLogger
|
10 |
+
{
|
11 |
+
public $slug = __CLASS__;
|
12 |
|
13 |
+
function getInfo()
|
14 |
+
{
|
15 |
+
$arr_info = array(
|
16 |
+
'name' => 'Plugin Beaver Builder',
|
17 |
+
'description' => _x(
|
18 |
+
'Logs various things in Beaver Builder',
|
19 |
+
'Logger: Plugin Beaver Builder',
|
20 |
+
'simple-history'
|
21 |
+
),
|
22 |
+
'name_via' => _x(
|
23 |
+
'Using plugin Beaver Builder',
|
24 |
+
'Logger: Plugin Beaver Builder',
|
25 |
+
'simple-history'
|
26 |
+
),
|
27 |
+
'capability' => 'manage_options',
|
28 |
+
'messages' => array(
|
29 |
+
'layout_saved' => __(
|
30 |
+
'Layout "{layout_name}" updated',
|
31 |
+
'simple-history'
|
32 |
+
),
|
33 |
+
'template_saved' => __(
|
34 |
+
'Template "{layout_name}" updated',
|
35 |
+
'simple-history'
|
36 |
+
),
|
37 |
+
'draft_saved' => __(
|
38 |
+
'Draft "{layout_name}" updated',
|
39 |
+
'simple-history'
|
40 |
+
),
|
41 |
+
'admin_saved' => __(
|
42 |
+
'Beaver Builder settings saved',
|
43 |
+
'simple-history'
|
44 |
+
)
|
45 |
+
)
|
46 |
+
);
|
47 |
|
48 |
+
return $arr_info;
|
49 |
+
}
|
50 |
|
51 |
+
function loaded()
|
52 |
+
{
|
53 |
+
if (!class_exists('FLBuilder')) {
|
54 |
+
return;
|
55 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
+
add_action(
|
58 |
+
'fl_builder_after_save_layout',
|
59 |
+
array($this, 'save_layout'),
|
60 |
+
10,
|
61 |
+
4
|
62 |
+
);
|
63 |
+
add_action(
|
64 |
+
'fl_builder_after_save_user_template',
|
65 |
+
array($this, 'save_template'),
|
66 |
+
10,
|
67 |
+
1
|
68 |
+
);
|
69 |
+
add_action(
|
70 |
+
'fl_builder_after_save_draft',
|
71 |
+
array($this, 'save_draft'),
|
72 |
+
10,
|
73 |
+
2
|
74 |
+
);
|
75 |
+
add_action('fl_builder_admin_settings_save', array(
|
76 |
+
$this,
|
77 |
+
'save_admin'
|
78 |
+
));
|
79 |
+
}
|
80 |
+
|
81 |
+
function save_template($post_id)
|
82 |
{
|
83 |
+
$post = get_post($post_id);
|
84 |
$context = array(
|
85 |
'layout_name' => $post->post_name
|
86 |
);
|
87 |
+
$this->noticeMessage('template_saved', $context);
|
88 |
}
|
89 |
+
|
90 |
+
function save_draft($post_id, $publish)
|
91 |
{
|
92 |
+
$context = array(
|
93 |
+
'layout_name' => $post_id
|
94 |
+
);
|
95 |
+
$this->noticeMessage('draft_saved', $context);
|
96 |
}
|
97 |
+
|
98 |
+
function save_layout($post_id, $publish, $data, $settings)
|
99 |
+
{
|
100 |
+
$post = get_post($post_id);
|
101 |
+
$context = array(
|
102 |
+
'layout_name' => $post->post_name
|
103 |
+
);
|
104 |
+
if ( $publish ) {
|
105 |
+
$this->noticeMessage('layout_saved', $context);
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
function save_admin()
|
110 |
+
{
|
111 |
+
$this->noticeMessage('admin_saved');
|
112 |
+
}
|
113 |
+
} // class
|
114 |
} // End if().
|
loggers/Plugin_DuplicatePost.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logger for the Duplicate Post plugin
|
@@ -9,119 +9,124 @@ defined( 'ABSPATH' ) or die();
|
|
9 |
* @package SimpleHistory
|
10 |
* @since 2.13
|
11 |
*/
|
12 |
-
if (
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
127 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logger for the Duplicate Post plugin
|
9 |
* @package SimpleHistory
|
10 |
* @since 2.13
|
11 |
*/
|
12 |
+
if (! class_exists('Plugin_DuplicatePost')) {
|
13 |
+
|
14 |
+
class Plugin_DuplicatePost extends SimpleLogger
|
15 |
+
{
|
16 |
+
|
17 |
+
public $slug = __CLASS__;
|
18 |
+
|
19 |
+
public function getInfo()
|
20 |
+
{
|
21 |
+
$arr_info = array(
|
22 |
+
'name' => 'Plugin Duplicate Posts',
|
23 |
+
'description' => _x('Logs posts and pages cloned using plugin Duplicate Post', 'Logger: Plugin Duplicate Post', 'simple-history'),
|
24 |
+
'name_via' => _x('Using plugin Duplicate Posts', 'Logger: Plugin Duplicate Post', 'simple-history'),
|
25 |
+
'capability' => 'manage_options',
|
26 |
+
'messages' => array(
|
27 |
+
'post_duplicated' => _x('Cloned "{duplicated_post_title}" to a new post', 'Logger: Plugin Duplicate Post', 'simple-history'),
|
28 |
+
),
|
29 |
+
);
|
30 |
+
|
31 |
+
return $arr_info;
|
32 |
+
}
|
33 |
+
|
34 |
+
public function loaded()
|
35 |
+
{
|
36 |
+
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
37 |
+
|
38 |
+
$pluginFilePath = 'duplicate-post/duplicate-post.php';
|
39 |
+
$isPluginActive = is_plugin_active('duplicate-post/duplicate-post.php');
|
40 |
+
|
41 |
+
if (! $isPluginActive) {
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
|
45 |
+
// When a copy have been made of a post or page
|
46 |
+
// the action 'dp_duplicate_page' or 'dp_duplicate_post'
|
47 |
+
// is fired with args $new_post_id, $post, $status.
|
48 |
+
// We add actions with prio 20 so we probably run after
|
49 |
+
// the plugins own
|
50 |
+
add_action('dp_duplicate_post', array( $this, 'onDpDuplicatePost' ), 100, 3);
|
51 |
+
add_action('dp_duplicate_page', array( $this, 'onDpDuplicatePost' ), 100, 3);
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* A post or page was duplicated
|
56 |
+
*
|
57 |
+
* @param $new_post_id
|
58 |
+
* @param $post old post that a copy was made of
|
59 |
+
* @param $status
|
60 |
+
*/
|
61 |
+
public function onDpDuplicatePost($newPostID, $post, $status)
|
62 |
+
{
|
63 |
+
$new_post = get_post($newPostID);
|
64 |
+
|
65 |
+
$context = array(
|
66 |
+
'new_post_title' => $new_post->post_title,
|
67 |
+
'new_post_id' => $new_post->ID,
|
68 |
+
'duplicated_post_title' => $post->post_title,
|
69 |
+
'duplicated_post_id' => $post->ID,
|
70 |
+
// "duplicate_new_post_id" => $newPostID,
|
71 |
+
// "status" => $status
|
72 |
+
);
|
73 |
+
|
74 |
+
$this->infoMessage(
|
75 |
+
'post_duplicated',
|
76 |
+
$context
|
77 |
+
);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Modify plain output to include link to post
|
82 |
+
*/
|
83 |
+
public function getLogRowPlainTextOutput($row)
|
84 |
+
{
|
85 |
+
|
86 |
+
$context = $row->context;
|
87 |
+
$new_post_id = isset($context['new_post_id']) ? $context['new_post_id'] : null;
|
88 |
+
$duplicated_post_id = isset($context['duplicated_post_id']) ? $context['duplicated_post_id'] : null;
|
89 |
+
$duplicated_post_title = isset($context['duplicated_post_title']) ? $context['duplicated_post_title'] : null;
|
90 |
+
$message_key = isset($context['_message_key']) ? $context['_message_key'] : null;
|
91 |
+
|
92 |
+
$message = $row->message;
|
93 |
+
|
94 |
+
// Check if post still is available
|
95 |
+
// It will return a WP_Post Object if post still is in system
|
96 |
+
// If post is deleted from trash (not just moved there), then null is returned
|
97 |
+
$postDuplicated = get_post($duplicated_post_id);
|
98 |
+
$post_is_available = is_a($postDuplicated, 'WP_Post');
|
99 |
+
|
100 |
+
// Try to get singular name
|
101 |
+
$post_type = isset($postDuplicated->post_type) ? $postDuplicated->post_type : '';
|
102 |
+
$post_type_obj = get_post_type_object($post_type);
|
103 |
+
|
104 |
+
if (! is_null($post_type_obj)) {
|
105 |
+
if (! empty($post_type_obj->labels->singular_name)) {
|
106 |
+
$context['duplicated_post_post_type_singular_name'] = strtolower($post_type_obj->labels->singular_name);
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
$context['duplicated_post_edit_link'] = get_edit_post_link($duplicated_post_id);
|
111 |
+
$context['new_post_edit_link'] = get_edit_post_link($new_post_id);
|
112 |
+
|
113 |
+
// If post is not available any longer then we can't link to it, so keep plain message then
|
114 |
+
// Also keep plain format if user is not allowed to edit post (edit link is empty)
|
115 |
+
if ($post_is_available && $context['duplicated_post_edit_link']) {
|
116 |
+
$message = _x('Cloned {duplicated_post_post_type_singular_name} <a href="{duplicated_post_edit_link}">"{duplicated_post_title}"</a> to <a href="{new_post_edit_link}">a new {duplicated_post_post_type_singular_name}</a>', 'Logger: Plugin Duplicate Post', 'simple-history');
|
117 |
+
} // End if().
|
118 |
+
|
119 |
+
$context['new_post_edit_link'] = isset($context['new_post_edit_link']) ? esc_html($context['new_post_edit_link']) : '';
|
120 |
+
|
121 |
+
$context['duplicated_post_edit_link'] = isset($context['duplicated_post_edit_link']) ? esc_html($context['duplicated_post_edit_link']) : '';
|
122 |
+
|
123 |
+
$context['duplicated_post_title'] = isset($context['duplicated_post_title']) ? esc_html($context['duplicated_post_title']) : '';
|
124 |
+
|
125 |
+
$context['duplicated_post_title'] = isset($context['duplicated_post_title']) ? esc_html($context['duplicated_post_title']) : '';
|
126 |
+
|
127 |
+
$context['duplicated_post_post_type_singular_name'] = isset($context['duplicated_post_post_type_singular_name']) ? esc_html($context['duplicated_post_post_type_singular_name']) : '';
|
128 |
+
|
129 |
+
return $this->interpolate($message, $context, $row);
|
130 |
+
}
|
131 |
+
} // class
|
132 |
} // End if().
|
loggers/Plugin_LimitLoginAttempts.php
CHANGED
@@ -1,243 +1,233 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logger for the (old but still) very popular plugin Limit Login Attempts
|
7 |
* https://sv.wordpress.org/plugins/limit-login-attempts/
|
8 |
*/
|
9 |
-
if (
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
$when // 1
|
233 |
-
) . '</p>';
|
234 |
-
|
235 |
-
}
|
236 |
-
|
237 |
-
return $output;
|
238 |
-
|
239 |
-
}
|
240 |
-
|
241 |
-
} // class
|
242 |
|
243 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logger for the (old but still) very popular plugin Limit Login Attempts
|
7 |
* https://sv.wordpress.org/plugins/limit-login-attempts/
|
8 |
*/
|
9 |
+
if (! class_exists('Plugin_LimitLoginAttempts')) {
|
10 |
+
|
11 |
+
class Plugin_LimitLoginAttempts extends SimpleLogger
|
12 |
+
{
|
13 |
+
|
14 |
+
public $slug = __CLASS__;
|
15 |
+
|
16 |
+
function getInfo()
|
17 |
+
{
|
18 |
+
|
19 |
+
$arr_info = array(
|
20 |
+
'name' => 'Plugin Limit Login Attempts',
|
21 |
+
'description' => _x('Logs failed login attempts, lockouts, and configuration changes made in the plugin Limit Login Attempts', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
22 |
+
'name_via' => _x('Using plugin Limit Login Attempts', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
23 |
+
'capability' => 'manage_options',
|
24 |
+
'messages' => array(
|
25 |
+
// 'user_locked_out' => _x( 'User locked out', "Logger: Plugin Limit Login Attempts", "simple-history" ),
|
26 |
+
'failed_login_whitelisted' => _x('Failed login attempt from whitelisted IP', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
27 |
+
'failed_login' => _x('Was locked out because too many failed login attempts', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
28 |
+
'cleared_ip_log' => _x('Cleared IP log', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
29 |
+
'reseted_lockout_count' => _x('Reseted lockout count', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
30 |
+
'cleared_current_lockouts' => _x('Cleared current lockouts', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
31 |
+
'updated_options' => _x('Updated options', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
32 |
+
),
|
33 |
+
/*
|
34 |
+
"labels" => array(
|
35 |
+
"search" => array(
|
36 |
+
"label" => _x( "Limit Login Attempts", "Logger: Plugin Limit Login Attempts", "simple-history" ),
|
37 |
+
"options" => array(
|
38 |
+
_x( "xxxPages not found", "User logger: 404", "simple-history" ) => array(
|
39 |
+
"page_not_found",
|
40 |
+
),
|
41 |
+
),
|
42 |
+
), // end search
|
43 |
+
),*/ // end labels
|
44 |
+
);
|
45 |
+
|
46 |
+
return $arr_info;
|
47 |
+
}
|
48 |
+
|
49 |
+
function loaded()
|
50 |
+
{
|
51 |
+
|
52 |
+
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
53 |
+
|
54 |
+
$pluginFilePath = 'limit-login-attempts/limit-login-attempts.php';
|
55 |
+
$isPluginActive = is_plugin_active($pluginFilePath);
|
56 |
+
|
57 |
+
// Only continue to add filters if plugin is active.
|
58 |
+
// This minimise the risk of plugin errors, because plugin
|
59 |
+
// has been forked to new versions.
|
60 |
+
if (! $isPluginActive) {
|
61 |
+
return;
|
62 |
+
}
|
63 |
+
|
64 |
+
add_filter('pre_option_limit_login_lockouts_total', array( $this, 'on_option_limit_login_lockouts_total' ), 10, 1);
|
65 |
+
|
66 |
+
add_action('load-settings_page_limit-login-attempts', array( $this, 'on_load_settings_page' ), 10, 1);
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Fired when plugin options screen is loaded
|
71 |
+
*/
|
72 |
+
function on_load_settings_page($a)
|
73 |
+
{
|
74 |
+
|
75 |
+
if ($_POST && wp_verify_nonce($_POST['_wpnonce'], 'limit-login-attempts-options')) {
|
76 |
+
// Settings saved
|
77 |
+
if (isset($_POST['clear_log'])) {
|
78 |
+
$this->noticeMessage('cleared_ip_log');
|
79 |
+
}
|
80 |
+
|
81 |
+
if (isset($_POST['reset_total'])) {
|
82 |
+
$this->noticeMessage('reseted_lockout_count');
|
83 |
+
}
|
84 |
+
|
85 |
+
if (isset($_POST['reset_current'])) {
|
86 |
+
$this->noticeMessage('cleared_current_lockouts');
|
87 |
+
}
|
88 |
+
|
89 |
+
if (isset($_POST['update_options'])) {
|
90 |
+
$options = array(
|
91 |
+
'client_type' => sanitize_text_field($_POST['client_type']),
|
92 |
+
'allowed_retries' => sanitize_text_field($_POST['allowed_retries']),
|
93 |
+
'lockout_duration' => sanitize_text_field($_POST['lockout_duration']) * 60,
|
94 |
+
'valid_duration' => sanitize_text_field($_POST['valid_duration']) * 3600,
|
95 |
+
'allowed_lockouts' => sanitize_text_field($_POST['allowed_lockouts']),
|
96 |
+
'long_duration' => sanitize_text_field($_POST['long_duration']) * 3600,
|
97 |
+
'email_after' => sanitize_text_field($_POST['email_after']),
|
98 |
+
'cookies' => (isset($_POST['cookies']) && $_POST['cookies'] == '1') ? 'yes' : 'no',
|
99 |
+
);
|
100 |
+
|
101 |
+
$v = array();
|
102 |
+
if (isset($_POST['lockout_notify_log'])) {
|
103 |
+
$v[] = 'log';
|
104 |
+
}
|
105 |
+
if (isset($_POST['lockout_notify_email'])) {
|
106 |
+
$v[] = 'email';
|
107 |
+
}
|
108 |
+
$lockout_notify = implode(',', $v);
|
109 |
+
$options['lockout_notify'] = $lockout_notify;
|
110 |
+
|
111 |
+
$this->noticeMessage('updated_options', array(
|
112 |
+
'options' => $options,
|
113 |
+
));
|
114 |
+
}
|
115 |
+
}// End if().
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* When option value is updated
|
120 |
+
* do same checks as plugin itself does
|
121 |
+
* and log if we match something
|
122 |
+
*/
|
123 |
+
function on_option_limit_login_lockouts_total($value)
|
124 |
+
{
|
125 |
+
|
126 |
+
global $limit_login_just_lockedout;
|
127 |
+
|
128 |
+
if (! $limit_login_just_lockedout) {
|
129 |
+
return $value;
|
130 |
+
}
|
131 |
+
|
132 |
+
$ip = limit_login_get_address();
|
133 |
+
$whitelisted = is_limit_login_ip_whitelisted($ip);
|
134 |
+
|
135 |
+
$retries = get_option('limit_login_retries');
|
136 |
+
if (! is_array($retries)) {
|
137 |
+
$retries = array();
|
138 |
+
}
|
139 |
+
|
140 |
+
if (isset($retries[ $ip ]) && ( ( $retries[ $ip ] / limit_login_option('allowed_retries') ) % limit_login_option('notify_email_after') ) != 0) {
|
141 |
+
// $this->notice( "user locked out but don't log" );
|
142 |
+
// return;
|
143 |
+
}
|
144 |
+
|
145 |
+
/* Format message. First current lockout duration */
|
146 |
+
$lockout_type = '';
|
147 |
+
if (! isset($retries[ $ip ])) {
|
148 |
+
/* longer lockout */
|
149 |
+
$lockout_type = 'longer';
|
150 |
+
$count = limit_login_option('allowed_retries') * limit_login_option('allowed_lockouts');
|
151 |
+
$lockouts = limit_login_option('allowed_lockouts');
|
152 |
+
$time = round(limit_login_option('long_duration') / 3600);
|
153 |
+
// $when = sprintf( _n( '%d hour', '%d hours', $time, "Logger: Plugin Limit Login Attempts", 'limit-login-attempts' ), $time );
|
154 |
+
} else {
|
155 |
+
/* normal lockout */
|
156 |
+
$lockout_type = 'normal';
|
157 |
+
$count = $retries[ $ip ];
|
158 |
+
$lockouts = floor($count / limit_login_option('allowed_retries'));
|
159 |
+
$time = round(limit_login_option('lockout_duration') / 60);
|
160 |
+
// $when = sprintf( _n( '%d minute', '%d minutes', $time, 'limit-login-attempts' ), $time );
|
161 |
+
}
|
162 |
+
|
163 |
+
if ($whitelisted) {
|
164 |
+
// $subject = __( "Failed login attempts from whitelisted IP", 'limit-login-attempts' );
|
165 |
+
$message_key = 'failed_login_whitelisted';
|
166 |
+
} else {
|
167 |
+
// $subject = __( "Too many failed login attempts", 'limit-login-attempts' );
|
168 |
+
$message_key = 'failed_login';
|
169 |
+
}
|
170 |
+
|
171 |
+
$this->noticeMessage($message_key, array(
|
172 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
173 |
+
'value' => $value,
|
174 |
+
'limit_login_just_lockedout' => $limit_login_just_lockedout,
|
175 |
+
// "retries" => $retries,
|
176 |
+
// "whitelisted" => $whitelisted, // bool, true | false
|
177 |
+
// "subject" => $subject,
|
178 |
+
// "message" => $message,
|
179 |
+
'count' => $count, // num of failed login attempts before block
|
180 |
+
'time' => $time, // duration in minutes for block
|
181 |
+
'lockouts' => $lockouts,
|
182 |
+
'ip' => $ip,
|
183 |
+
'lockout_type' => $lockout_type,
|
184 |
+
));
|
185 |
+
|
186 |
+
return $value;
|
187 |
+
}
|
188 |
+
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Add some extra info
|
192 |
+
*/
|
193 |
+
function getLogRowDetailsOutput($row)
|
194 |
+
{
|
195 |
+
|
196 |
+
$output = '';
|
197 |
+
|
198 |
+
$context = isset($row->context) ? $row->context : array();
|
199 |
+
|
200 |
+
$message_key = $row->context_message_key;
|
201 |
+
|
202 |
+
if ('failed_login' == $message_key) {
|
203 |
+
$count = $context['count'];
|
204 |
+
$lockouts = $context['lockouts'];
|
205 |
+
$ip = $context['ip'];
|
206 |
+
// $whitelisted = $context["whitelisted"];
|
207 |
+
$lockout_type = $context['lockout_type'];
|
208 |
+
$time = $context['time'];
|
209 |
+
|
210 |
+
$output .= sprintf(
|
211 |
+
'<p>' . _x('%1$d failed login attempts (%2$d lockout(s)) from IP: %3$s', 'Logger: Plugin Limit Login Attempts', 'simple-history') . '</p>',
|
212 |
+
$count, // 1
|
213 |
+
$lockouts, // 2
|
214 |
+
$ip // 3
|
215 |
+
);
|
216 |
+
|
217 |
+
if ('longer' == $lockout_type) {
|
218 |
+
$when = sprintf(_nx('%d hour', '%d hours', $time, 'Logger: Plugin Limit Login Attempts', 'limit-login-attempts'), $time);
|
219 |
+
} elseif ('normal' == $lockout_type) {
|
220 |
+
$when = sprintf(_nx('%d minute', '%d minutes', $time, 'Logger: Plugin Limit Login Attempts', 'limit-login-attempts'), $time);
|
221 |
+
}
|
222 |
+
|
223 |
+
$output .= '<p>' . sprintf(
|
224 |
+
_x('IP was blocked for %1$s', 'Logger: Plugin Limit Login Attempts', 'simple-history'),
|
225 |
+
$when // 1
|
226 |
+
) . '</p>';
|
227 |
+
}
|
228 |
+
|
229 |
+
return $output;
|
230 |
+
}
|
231 |
+
} // class
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
|
233 |
} // End if().
|
loggers/Plugin_Redirection.php
CHANGED
@@ -1,399 +1,410 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logger for the Redirection plugin
|
7 |
* https://wordpress.org/plugins/redirection/
|
8 |
*/
|
9 |
-
if (
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
362 |
<td>%1$s</td>
|
363 |
<td>
|
364 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
365 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
366 |
</td>
|
367 |
</tr>',
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
|
373 |
-
|
374 |
-
|
375 |
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
<td>%1$s</td>
|
380 |
<td>
|
381 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
382 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
383 |
</td>
|
384 |
</tr>',
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
} // class
|
398 |
|
399 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') || die();
|
4 |
|
5 |
/**
|
6 |
* Logger for the Redirection plugin
|
7 |
* https://wordpress.org/plugins/redirection/
|
8 |
*/
|
9 |
+
if (! class_exists('Plugin_Redirection')) {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class to log things from the Redirection plugin.
|
13 |
+
*/
|
14 |
+
class Plugin_Redirection extends SimpleLogger
|
15 |
+
{
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Logger slug.
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
public $slug = __CLASS__;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Return info about logger.
|
26 |
+
*
|
27 |
+
* @return array Array with plugin info.
|
28 |
+
*/
|
29 |
+
public function getInfo()
|
30 |
+
{
|
31 |
+
|
32 |
+
$arr_info = array(
|
33 |
+
'name' => 'Redirection',
|
34 |
+
'description' => _x('Text', 'Logger: Redirection', 'simple-history'),
|
35 |
+
'name_via' => _x('In plugin Redirection', 'Logger: Redirection', 'simple-history'),
|
36 |
+
'capability' => 'manage_options',
|
37 |
+
'messages' => array(
|
38 |
+
'redirection_redirection_added' => _x('Added a redirection for URL "{source_url}"', 'Logger: Redirection', 'simple-history'),
|
39 |
+
'redirection_redirection_edited' => _x('Edited redirection for URL "{prev_source_url}"', 'Logger: Redirection', 'simple-history'),
|
40 |
+
'redirection_redirection_enabled' => _x('Enabled redirection for {items_count} URL(s)', 'Logger: Redirection', 'simple-history'),
|
41 |
+
'redirection_redirection_disabled' => _x('Disabled redirection for {items_count} URL(s)', 'Logger: Redirection', 'simple-history'),
|
42 |
+
'redirection_redirection_deleted' => _x('Deleted redirection for {items_count} URL(s)', 'Logger: Redirection', 'simple-history'),
|
43 |
+
'redirection_options_saved' => _x('Updated redirection options', 'Logger: Redirection', 'simple-history'),
|
44 |
+
'redirection_options_removed_all' => _x('Removed all redirection options and deactivated plugin', 'Logger: Redirection', 'simple-history'),
|
45 |
+
'redirection_group_added' => _x('Added redirection group "{group_name}"', 'Logger: Redirection', 'simple-history'),
|
46 |
+
'redirection_group_enabled' => _x('Enabled {items_count} redirection group(s)', 'Logger: Redirection', 'simple-history'),
|
47 |
+
'redirection_group_disabled' => _x('Disabled {items_count} redirection group(s)', 'Logger: Redirection', 'simple-history'),
|
48 |
+
'redirection_group_deleted' => _x('Deleted {items_count} redirection group(s)', 'Logger: Redirection', 'simple-history'),
|
49 |
+
),
|
50 |
+
|
51 |
+
/*
|
52 |
+
"labels" => array(
|
53 |
+
"search" => array(
|
54 |
+
"label" => _x("Plugin Redirection", "Logger: Redirection", "simple-history"),
|
55 |
+
"label_all" => _x("All posts & pages activity", "Logger: Redirection", "simple-history"),
|
56 |
+
"options" => array(
|
57 |
+
_x("Posts created", "Logger: Redirection", "simple-history") => array(
|
58 |
+
"post_created"
|
59 |
+
),
|
60 |
+
_x("Posts updated", "Logger: Redirection", "simple-history") => array(
|
61 |
+
"post_updated"
|
62 |
+
),
|
63 |
+
_x("Posts trashed", "Logger: Redirection", "simple-history") => array(
|
64 |
+
"post_trashed"
|
65 |
+
),
|
66 |
+
_x("Posts deleted", "Logger: Redirection", "simple-history") => array(
|
67 |
+
"post_deleted"
|
68 |
+
),
|
69 |
+
_x("Posts restored", "Logger: Redirection", "simple-history") => array(
|
70 |
+
"post_restored"
|
71 |
+
),
|
72 |
+
)
|
73 |
+
) // end search array
|
74 |
+
) // end labels
|
75 |
+
*/
|
76 |
+
);
|
77 |
+
|
78 |
+
return $arr_info;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Called when logger is loaded.
|
83 |
+
*/
|
84 |
+
public function loaded()
|
85 |
+
{
|
86 |
+
// Redirection plugin uses the WP REST API, so catch when requests do the API is done.
|
87 |
+
// We use filter *_before_callbacks so we can access the old title
|
88 |
+
// of the Redirection object, i.e. before new values are saved.
|
89 |
+
add_filter('rest_request_before_callbacks', array( $this, 'on_rest_request_before_callbacks' ), 10, 3);
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Fired when WP REST API call is done.
|
94 |
+
*
|
95 |
+
* @param WP_HTTP_Response $response Result to send to the client. Usually a WP_REST_Response.
|
96 |
+
* @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server).
|
97 |
+
* @param WP_REST_Request $request Request used to generate the response.
|
98 |
+
*
|
99 |
+
* @return WP_HTTP_Response $response
|
100 |
+
*/
|
101 |
+
public function on_rest_request_before_callbacks($response, $handler, $request)
|
102 |
+
{
|
103 |
+
// Callback must be set.
|
104 |
+
if (! isset($handler['callback'])) {
|
105 |
+
return $response;
|
106 |
+
}
|
107 |
+
|
108 |
+
$callback = $handler['callback'];
|
109 |
+
|
110 |
+
$callable_name = sh_get_callable_name($callback);
|
111 |
+
|
112 |
+
$ok_redirection_api_callable_names = array(
|
113 |
+
'Redirection_Api_Redirect::route_bulk',
|
114 |
+
'Redirection_Api_Redirect::route_create',
|
115 |
+
'Redirection_Api_Redirect::route_update',
|
116 |
+
'Redirection_Api_Group::route_create',
|
117 |
+
'Redirection_Api_Group::route_bulk',
|
118 |
+
'Redirection_Api_Settings::route_save_settings',
|
119 |
+
);
|
120 |
+
|
121 |
+
// Bail directly if this is not a Redirection API call.
|
122 |
+
if (! in_array($callable_name, $ok_redirection_api_callable_names)) {
|
123 |
+
return $response;
|
124 |
+
}
|
125 |
+
|
126 |
+
if ('Redirection_Api_Redirect::route_create' === $callable_name) {
|
127 |
+
$this->log_redirection_add($request);
|
128 |
+
} elseif ('Redirection_Api_Redirect::route_update' === $callable_name) {
|
129 |
+
$this->log_redirection_edit($request);
|
130 |
+
} elseif ('Redirection_Api_Redirect::route_bulk' === $callable_name) {
|
131 |
+
$bulk_action = $request->get_param('bulk');
|
132 |
+
|
133 |
+
$bulk_items = $request->get_param('items');
|
134 |
+
$bulk_items = explode(',', $bulk_items);
|
135 |
+
|
136 |
+
if (is_array($bulk_items)) {
|
137 |
+
$bulk_items = array_map('intval', $bulk_items);
|
138 |
+
}
|
139 |
+
|
140 |
+
if (empty($bulk_items)) {
|
141 |
+
return $response;
|
142 |
+
}
|
143 |
+
|
144 |
+
if ('enable' === $bulk_action) {
|
145 |
+
$this->log_redirection_enable_or_disable($request, $bulk_items);
|
146 |
+
} elseif ('disable' === $bulk_action) {
|
147 |
+
$this->log_redirection_enable_or_disable($request, $bulk_items);
|
148 |
+
} elseif ('delete' === $bulk_action) {
|
149 |
+
$this->log_redirection_delete($request, $bulk_items);
|
150 |
+
}
|
151 |
+
} elseif ('Redirection_Api_Group::route_create' === $callable_name) {
|
152 |
+
$this->log_group_add($request);
|
153 |
+
} elseif ('Redirection_Api_Group::route_bulk' === $callable_name) {
|
154 |
+
$bulk_action = $request->get_param('bulk');
|
155 |
+
|
156 |
+
$bulk_items = $request->get_param('items');
|
157 |
+
$bulk_items = explode(',', $bulk_items);
|
158 |
+
|
159 |
+
if (is_array($bulk_items)) {
|
160 |
+
$bulk_items = array_map('intval', $bulk_items);
|
161 |
+
}
|
162 |
+
|
163 |
+
if (empty($bulk_items)) {
|
164 |
+
return $response;
|
165 |
+
}
|
166 |
+
|
167 |
+
if ('enable' === $bulk_action) {
|
168 |
+
$this->log_group_enable_or_disable($request, $bulk_items);
|
169 |
+
} elseif ('disable' === $bulk_action) {
|
170 |
+
$this->log_group_enable_or_disable($request, $bulk_items);
|
171 |
+
} elseif ('delete' === $bulk_action) {
|
172 |
+
$this->log_group_delete($request, $bulk_items);
|
173 |
+
}
|
174 |
+
} elseif ('Redirection_Api_Settings::route_save_settings' == $callable_name) {
|
175 |
+
$this->log_options_save($request);
|
176 |
+
}
|
177 |
+
|
178 |
+
return $response;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Log when a Redirection group is deleted.
|
183 |
+
*
|
184 |
+
* @param object $req Request.
|
185 |
+
* @param array $bulk_items Array with item ids.
|
186 |
+
*/
|
187 |
+
public function log_group_delete($req, $bulk_items)
|
188 |
+
{
|
189 |
+
$context = array(
|
190 |
+
'items' => $bulk_items,
|
191 |
+
'items_count' => count($bulk_items),
|
192 |
+
);
|
193 |
+
|
194 |
+
$this->infoMessage(
|
195 |
+
'redirection_group_deleted',
|
196 |
+
$context
|
197 |
+
);
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* Log when a Redirection grouop is added
|
202 |
+
*
|
203 |
+
* @param WP_REST_Request $req Request.
|
204 |
+
*/
|
205 |
+
public function log_group_add($req)
|
206 |
+
{
|
207 |
+
$group_name = $req->get_param('name');
|
208 |
+
|
209 |
+
if (! $group_name) {
|
210 |
+
return;
|
211 |
+
}
|
212 |
+
|
213 |
+
$context = array(
|
214 |
+
'group_name' => $group_name,
|
215 |
+
);
|
216 |
+
|
217 |
+
$this->infoMessage(
|
218 |
+
'redirection_group_added',
|
219 |
+
$context
|
220 |
+
);
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Log enabling and disabling of redirection groups.
|
225 |
+
*
|
226 |
+
* @param object $req Request.
|
227 |
+
* @param array $bulk_items Array with item ids.
|
228 |
+
*/
|
229 |
+
public function log_group_enable_or_disable($req, $bulk_items)
|
230 |
+
{
|
231 |
+
$bulk_action = $req->get_param('bulk');
|
232 |
+
|
233 |
+
$message_key = 'enable' === $bulk_action ? 'redirection_group_enabled' : 'redirection_group_disabled';
|
234 |
+
|
235 |
+
$context = array(
|
236 |
+
'items' => $bulk_items,
|
237 |
+
'items_count' => count($bulk_items),
|
238 |
+
);
|
239 |
+
|
240 |
+
$this->infoMessage(
|
241 |
+
$message_key,
|
242 |
+
$context
|
243 |
+
);
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Log when options are saved.
|
248 |
+
*
|
249 |
+
* @param object $req Request.
|
250 |
+
*/
|
251 |
+
protected function log_options_save($req)
|
252 |
+
{
|
253 |
+
$this->infoMessage('redirection_options_saved');
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Log the deletion of a redirection.
|
258 |
+
*
|
259 |
+
* @param object $req Request.
|
260 |
+
* @param array $bulk_items Array with item ids.
|
261 |
+
*/
|
262 |
+
protected function log_redirection_delete($req, $bulk_items)
|
263 |
+
{
|
264 |
+
$context = array(
|
265 |
+
'items' => $bulk_items,
|
266 |
+
'items_count' => count($bulk_items),
|
267 |
+
);
|
268 |
+
|
269 |
+
$message_key = 'redirection_redirection_deleted';
|
270 |
+
|
271 |
+
$this->infoMessage(
|
272 |
+
$message_key,
|
273 |
+
$context
|
274 |
+
);
|
275 |
+
}
|
276 |
+
|
277 |
+
/**
|
278 |
+
* Log enable or disable of items.
|
279 |
+
*
|
280 |
+
* @param Object $req Req.
|
281 |
+
* @param Array $bulk_items Array.
|
282 |
+
*/
|
283 |
+
protected function log_redirection_enable_or_disable($req, $bulk_items)
|
284 |
+
{
|
285 |
+
$bulk_action = $req->get_param('bulk');
|
286 |
+
|
287 |
+
$message_key = 'enable' === $bulk_action ? 'redirection_redirection_enabled' : 'redirection_redirection_disabled';
|
288 |
+
|
289 |
+
$context = array(
|
290 |
+
'items' => $bulk_items,
|
291 |
+
'items_count' => count($bulk_items),
|
292 |
+
);
|
293 |
+
|
294 |
+
$this->infoMessage(
|
295 |
+
$message_key,
|
296 |
+
$context
|
297 |
+
);
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Log when a Redirection is added.
|
302 |
+
*
|
303 |
+
* @param WP_REST_Request $req Request.
|
304 |
+
*/
|
305 |
+
protected function log_redirection_add($req)
|
306 |
+
{
|
307 |
+
$action_data = $req->get_param('action_data');
|
308 |
+
|
309 |
+
if (! $action_data || ! is_array($action_data)) {
|
310 |
+
return false;
|
311 |
+
}
|
312 |
+
|
313 |
+
$context = array(
|
314 |
+
'source_url' => $req->get_param('url'),
|
315 |
+
'target_url' => $action_data['url'],
|
316 |
+
);
|
317 |
+
|
318 |
+
$this->infoMessage('redirection_redirection_added', $context);
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Log when a Redirection is changed.
|
323 |
+
*
|
324 |
+
* @param WP_REST_Request $req Request.
|
325 |
+
*/
|
326 |
+
protected function log_redirection_edit($req)
|
327 |
+
{
|
328 |
+
$action_data = $req->get_param('action_data');
|
329 |
+
|
330 |
+
if (! $action_data || ! is_array($action_data)) {
|
331 |
+
return false;
|
332 |
+
}
|
333 |
+
|
334 |
+
$message_key = 'redirection_redirection_edited';
|
335 |
+
|
336 |
+
$redirection_id = $req->get_param('id');
|
337 |
+
|
338 |
+
$context = array(
|
339 |
+
'new_source_url' => $req->get_param('url'),
|
340 |
+
'new_target' => $action_data,
|
341 |
+
'redirection_id' => $redirection_id,
|
342 |
+
);
|
343 |
+
|
344 |
+
// Get old values.
|
345 |
+
$redirection_item = Red_Item::get_by_id($redirection_id);
|
346 |
+
|
347 |
+
if (false !== $redirection_item) {
|
348 |
+
$context['prev_source_url'] = $redirection_item->get_url();
|
349 |
+
$context['prev_target'] = maybe_unserialize($redirection_item->get_action_data());
|
350 |
+
}
|
351 |
+
|
352 |
+
$this->infoMessage(
|
353 |
+
$message_key,
|
354 |
+
$context
|
355 |
+
);
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Return more info about an logged redirection event.
|
360 |
+
*
|
361 |
+
* @param array $row Row with info.
|
362 |
+
*/
|
363 |
+
public function getLogRowDetailsOutput($row)
|
364 |
+
{
|
365 |
+
$context = $row->context;
|
366 |
+
$message_key = $context['_message_key'];
|
367 |
+
|
368 |
+
$out = '';
|
369 |
+
|
370 |
+
if ('redirection_redirection_edited' === $message_key) {
|
371 |
+
if ($context['new_source_url'] !== $context['prev_source_url']) {
|
372 |
+
$diff_table_output = sprintf(
|
373 |
+
'<tr>
|
374 |
<td>%1$s</td>
|
375 |
<td>
|
376 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
377 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
378 |
</td>
|
379 |
</tr>',
|
380 |
+
esc_html_x('Source URL', 'Logger: Redirection', 'simple-history'), // 1
|
381 |
+
esc_html($context['new_source_url']), // 2
|
382 |
+
esc_html($context['prev_source_url']) // 3
|
383 |
+
);
|
384 |
|
385 |
+
$out .= '<table class="SimpleHistoryLogitem__keyValueTable">' . $diff_table_output . '</table>';
|
386 |
+
}
|
387 |
|
388 |
+
if ($context['new_target'] !== $context['prev_target']) {
|
389 |
+
$diff_table_output = sprintf(
|
390 |
+
'<tr>
|
391 |
<td>%1$s</td>
|
392 |
<td>
|
393 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
394 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
395 |
</td>
|
396 |
</tr>',
|
397 |
+
esc_html_x('Target', 'Logger: Redirection', 'simple-history'), // 1
|
398 |
+
esc_html($context['new_target']), // 2
|
399 |
+
esc_html($context['prev_target']) // 3
|
400 |
+
);
|
401 |
+
|
402 |
+
$out .= '<table class="SimpleHistoryLogitem__keyValueTable">' . $diff_table_output . '</table>';
|
403 |
+
}
|
404 |
+
}
|
405 |
+
|
406 |
+
return $out;
|
407 |
+
}
|
408 |
+
} // class
|
|
|
409 |
|
410 |
} // End if().
|
loggers/Plugin_UltimateMembers_Logger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
*
|
@@ -8,49 +8,50 @@ defined( 'ABSPATH' ) or die();
|
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
-
class Plugin_UltimateMembers_Logger extends SimpleLogger
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
56 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
*
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
+
class Plugin_UltimateMembers_Logger extends SimpleLogger
|
12 |
+
{
|
13 |
+
|
14 |
+
public $slug = __CLASS__;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Get array with information about this logger
|
18 |
+
*
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
function getInfo()
|
22 |
+
{
|
23 |
+
|
24 |
+
$arr_info = array(
|
25 |
+
'name' => _x('Ultimate Members Logger', 'PluginUltimateMembersLogger', 'simple-history'),
|
26 |
+
'description' => _x('Logs actions from the Ultimate Members plugin', 'PluginUltimateMembersLogger', 'simple-history'),
|
27 |
+
'capability' => 'edit_users',
|
28 |
+
'messages' => array(
|
29 |
+
'logged_in' => _x('Logged in', 'PluginUltimateMembersLogger', 'simple-history'),
|
30 |
+
),
|
31 |
+
);
|
32 |
+
|
33 |
+
return $arr_info;
|
34 |
+
}
|
35 |
+
|
36 |
+
function loaded()
|
37 |
+
{
|
38 |
+
|
39 |
+
// Action that is called when Enable Media Replace loads it's admin options page (both when viewing and when posting new file to it)
|
40 |
+
add_action('um_on_login_before_redirect', array( $this, 'on_um_on_login_before_redirect' ), 10, 1);
|
41 |
+
}
|
42 |
+
|
43 |
+
function on_um_on_login_before_redirect($user_id)
|
44 |
+
{
|
45 |
+
|
46 |
+
$this->infoMessage('logged_in', array(
|
47 |
+
// "user_id" => $user_id,
|
48 |
+
/*
|
49 |
+
"get" => $_GET,
|
50 |
+
"post" => $_POST,
|
51 |
+
"files" => $_FILES,
|
52 |
+
"old_attachment_post" => $prev_attachment_post,
|
53 |
+
"old_attachment_meta" => $prev_attachment_meta
|
54 |
+
*/
|
55 |
+
));
|
56 |
+
}
|
57 |
}
|
loggers/SimpleCategoriesLogger.php
CHANGED
@@ -1,298 +1,323 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs changes to categories and tags and taxonomies
|
7 |
*/
|
8 |
-
class SimpleCategoriesLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
298 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs changes to categories and tags and taxonomies
|
7 |
*/
|
8 |
+
class SimpleCategoriesLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
public $slug = __CLASS__;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Get array with information about this logger
|
15 |
+
*
|
16 |
+
* @return array
|
17 |
+
*/
|
18 |
+
public function getInfo()
|
19 |
+
{
|
20 |
+
|
21 |
+
$arr_info = array(
|
22 |
+
'name' => __('Categories Logger', 'simple-history'),
|
23 |
+
'description' => 'Logs changes to categories, tags, and taxonomies',
|
24 |
+
'messages' => array(
|
25 |
+
'created_term' => __('Added term "{term_name}" in taxonomy "{term_taxonomy}"', 'simple-history'),
|
26 |
+
'deleted_term' => __('Deleted term "{term_name}" from taxonomy "{term_taxonomy}"', 'simple-history'),
|
27 |
+
'edited_term' => __('Edited term "{to_term_name}" in taxonomy "{to_term_taxonomy}"', 'simple-history'),
|
28 |
+
),
|
29 |
+
'labels' => array(
|
30 |
+
'search' => array(
|
31 |
+
'label' => _x('Categories', 'Categories logger: search', 'simple-history'),
|
32 |
+
'label_all' => _x('All category activity', 'Category logger: search', 'simple-history'),
|
33 |
+
'options' => array(
|
34 |
+
_x('Term created', 'Category logger: search', 'simple-history') => array(
|
35 |
+
'created_term'
|
36 |
+
),
|
37 |
+
_x('Term deleted', 'Category logger: search', 'simple-history') => array(
|
38 |
+
'deleted_term'
|
39 |
+
),
|
40 |
+
_x('Term edited', 'Category logger: search', 'simple-history') => array(
|
41 |
+
'edited_term'
|
42 |
+
),
|
43 |
+
)
|
44 |
+
) // end search array
|
45 |
+
) // end labels
|
46 |
+
);
|
47 |
+
|
48 |
+
return $arr_info;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Called when the logger is loaded.
|
53 |
+
*/
|
54 |
+
public function loaded()
|
55 |
+
{
|
56 |
+
// Fires after a new term is created, and after the term cache has been cleaned..
|
57 |
+
add_action('created_term', array( $this, 'on_created_term' ), 10, 3);
|
58 |
+
|
59 |
+
// Hook to this filter to see if it will cause a hierarchy loop.
|
60 |
+
add_action('delete_term', array( $this, 'on_delete_term' ), 10, 4);
|
61 |
+
|
62 |
+
// Filter the term parent.
|
63 |
+
add_action('wp_update_term_parent', array( $this, 'on_wp_update_term_parent' ), 10, 5);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Filter the term parent.
|
68 |
+
* Only way for Simple History to get both old and new term name.
|
69 |
+
* For example 'edited_term' does not contain enough info to know what the term was called before the update.
|
70 |
+
*
|
71 |
+
* @param int $parent ID of the parent term.
|
72 |
+
* @param int $term_id Term ID.
|
73 |
+
* @param string $taxonomy Taxonomy slug.
|
74 |
+
* @param array $parsed_args An array of potentially altered update arguments for the given term.
|
75 |
+
* @param array $term_update_args An array of update arguments for the given term.
|
76 |
+
*/
|
77 |
+
public function on_wp_update_term_parent($parent = null, $term_id = null, $taxonomy = null, $parsed_args = null, $term_update_args = null)
|
78 |
+
{
|
79 |
+
|
80 |
+
$term_before_edited = get_term_by('id', $term_id, $taxonomy);
|
81 |
+
|
82 |
+
if (! $term_before_edited || empty($term_update_args)) {
|
83 |
+
return $parent;
|
84 |
+
}
|
85 |
+
|
86 |
+
$term_id = $term_before_edited->term_id;
|
87 |
+
|
88 |
+
$from_term_name = $term_before_edited->name;
|
89 |
+
$from_term_taxonomy = $term_before_edited->taxonomy;
|
90 |
+
$from_term_slug = $term_before_edited->slug;
|
91 |
+
$from_term_description = $term_before_edited->description;
|
92 |
+
|
93 |
+
$to_term_name = $term_update_args['name'];
|
94 |
+
$to_term_taxonomy = $term_update_args['taxonomy'];
|
95 |
+
$to_term_slug = $term_update_args['slug'];
|
96 |
+
$to_term_description = $term_update_args['description'];
|
97 |
+
|
98 |
+
$do_log_term = $this->ok_to_log_taxonomy($from_term_taxonomy);
|
99 |
+
|
100 |
+
if (! $do_log_term) {
|
101 |
+
return $parent;
|
102 |
+
}
|
103 |
+
|
104 |
+
$this->infoMessage(
|
105 |
+
'edited_term',
|
106 |
+
array(
|
107 |
+
'term_id' => $term_id,
|
108 |
+
'from_term_name' => $from_term_name,
|
109 |
+
'from_term_taxonomy' => $from_term_taxonomy,
|
110 |
+
'from_term_slug' => $from_term_slug,
|
111 |
+
'from_term_description' => $from_term_description,
|
112 |
+
'to_term_name' => $to_term_name,
|
113 |
+
'to_term_taxonomy' => $to_term_taxonomy,
|
114 |
+
'to_term_slug' => $to_term_slug,
|
115 |
+
'to_term_description' => $to_term_description,
|
116 |
+
)
|
117 |
+
);
|
118 |
+
|
119 |
+
return $parent;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Check if it's ok to log a taxonomy.
|
124 |
+
* We skip some taxonomies, for example Polylang translation terms that fill the log with
|
125 |
+
* messages like 'Edited term "pll_5a3643a142c80" in taxonomy "post_translations"' otherwise.
|
126 |
+
*
|
127 |
+
* @since 2.21
|
128 |
+
* @param string $from_term_taxonomy Slug of taxonomy.
|
129 |
+
* @return bool True or false.
|
130 |
+
*/
|
131 |
+
public function ok_to_log_taxonomy($from_term_taxonomy = '')
|
132 |
+
{
|
133 |
+
if (empty($from_term_taxonomy)) {
|
134 |
+
return false;
|
135 |
+
}
|
136 |
+
|
137 |
+
$skip_taxonomies = $this->get_skip_taxonomies();
|
138 |
+
|
139 |
+
$do_log = ! in_array($from_term_taxonomy, $skip_taxonomies, true);
|
140 |
+
|
141 |
+
return $do_log;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Get taxonomies to skip.
|
146 |
+
*
|
147 |
+
* @since 2.21
|
148 |
+
* @return array Array with taxonomies.
|
149 |
+
*/
|
150 |
+
public function get_skip_taxonomies()
|
151 |
+
{
|
152 |
+
|
153 |
+
$taxonomies_to_skip = array(
|
154 |
+
// Polylang taxonomies used to store translation mappings.
|
155 |
+
'post_translations',
|
156 |
+
'term_translations',
|
157 |
+
);
|
158 |
+
|
159 |
+
$taxonomies_to_skip = apply_filters('simple_history/categories_logger/skip_taxonomies', $taxonomies_to_skip);
|
160 |
+
|
161 |
+
return $taxonomies_to_skip;
|
162 |
+
}
|
163 |
+
|
164 |
+
/*
|
165 |
+
* Fires after a new term is created, and after the term cache has been cleaned.
|
166 |
+
*
|
167 |
+
* @since 2.3.0
|
168 |
+
*
|
169 |
+
* @param int $term_id Term ID.
|
170 |
+
* @param int $tt_id Term taxonomy ID.
|
171 |
+
* @param string $taxonomy Taxonomy slug.
|
172 |
+
*/
|
173 |
+
public function on_created_term($term_id = null, $tt_id = null, $taxonomy = null)
|
174 |
+
{
|
175 |
+
|
176 |
+
$term = get_term_by('id', $term_id, $taxonomy);
|
177 |
+
|
178 |
+
if (! $term) {
|
179 |
+
return;
|
180 |
+
}
|
181 |
+
|
182 |
+
$term_name = $term->name;
|
183 |
+
$term_taxonomy = $term->taxonomy;
|
184 |
+
$term_id = $term->term_id;
|
185 |
+
|
186 |
+
$do_log_term = $this->ok_to_log_taxonomy($term_taxonomy);
|
187 |
+
|
188 |
+
if (! $do_log_term) {
|
189 |
+
return;
|
190 |
+
}
|
191 |
+
|
192 |
+
$this->infoMessage(
|
193 |
+
'created_term',
|
194 |
+
array(
|
195 |
+
'term_id' => $term_id,
|
196 |
+
'term_name' => $term_name,
|
197 |
+
'term_taxonomy' => $term_taxonomy,
|
198 |
+
)
|
199 |
+
);
|
200 |
+
}
|
201 |
+
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Fires after a term is deleted from the database and the cache is cleaned.
|
205 |
+
*
|
206 |
+
* @param int $term Term ID.
|
207 |
+
* @param int $tt_id Term taxonomy ID.
|
208 |
+
* @param string $taxonomy Taxonomy slug.
|
209 |
+
* @param mixed $deleted_term Copy of the already-deleted term, in the form specified
|
210 |
+
* by the parent function. WP_Error otherwise.
|
211 |
+
*/
|
212 |
+
public function on_delete_term($term = null, $tt_id = null, $taxonomy = null, $deleted_term = null)
|
213 |
+
{
|
214 |
+
|
215 |
+
if (is_wp_error($deleted_term)) {
|
216 |
+
return;
|
217 |
+
}
|
218 |
+
|
219 |
+
$term_name = $deleted_term->name;
|
220 |
+
$term_taxonomy = $deleted_term->taxonomy;
|
221 |
+
$term_id = $deleted_term->term_id;
|
222 |
+
|
223 |
+
$do_log_term = $this->ok_to_log_taxonomy($term_taxonomy);
|
224 |
+
|
225 |
+
if (! $do_log_term) {
|
226 |
+
return;
|
227 |
+
}
|
228 |
+
|
229 |
+
$this->infoMessage(
|
230 |
+
'deleted_term',
|
231 |
+
array(
|
232 |
+
'term_id' => $term_id,
|
233 |
+
'term_name' => $term_name,
|
234 |
+
'term_taxonomy' => $term_taxonomy,
|
235 |
+
)
|
236 |
+
);
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Modify plain output to include link to term and taxonomy.
|
241 |
+
*
|
242 |
+
* @param array $row Row data.
|
243 |
+
*/
|
244 |
+
public function getLogRowPlainTextOutput($row)
|
245 |
+
{
|
246 |
+
$context = $row->context;
|
247 |
+
$message_key = isset($context['_message_key']) ? $context['_message_key'] : null;
|
248 |
+
|
249 |
+
// Default to original log message.
|
250 |
+
$message = $row->message;
|
251 |
+
|
252 |
+
// Get term that was created, edited, or removed.
|
253 |
+
$term_id = isset($context['term_id']) ? (int) $context['term_id'] : null;
|
254 |
+
|
255 |
+
// Get taxonomy for term.
|
256 |
+
if ('created_term' === $message_key || 'deleted_term' === $message_key) {
|
257 |
+
$term_taxonomy = isset($context['term_taxonomy']) ? (string) $context['term_taxonomy'] : null;
|
258 |
+
} elseif ('edited_term' === $message_key) {
|
259 |
+
$term_taxonomy = isset($context['from_term_taxonomy']) ? (string) $context['from_term_taxonomy'] : null;
|
260 |
+
}
|
261 |
+
|
262 |
+
$tax_edit_link = add_query_arg(
|
263 |
+
array(
|
264 |
+
'taxonomy' => $term_taxonomy,
|
265 |
+
),
|
266 |
+
admin_url('term.php')
|
267 |
+
);
|
268 |
+
|
269 |
+
$context['tax_edit_link'] = $tax_edit_link;
|
270 |
+
|
271 |
+
$term_object = get_term($term_id, $term_taxonomy);
|
272 |
+
|
273 |
+
if (is_wp_error($term_object)) {
|
274 |
+
return $this->interpolate($message, $context, $row);
|
275 |
+
}
|
276 |
+
|
277 |
+
$term_edit_link = isset($term_object) ? get_edit_tag_link($term_id, $term_object->taxonomy) : null;
|
278 |
+
$context['term_edit_link'] = $term_edit_link;
|
279 |
+
|
280 |
+
// Get taxonomy name to use in log but fall back to taxonomy slug if
|
281 |
+
// taxonomy has been deleted.
|
282 |
+
$context['termTaxonomySlugOrName'] = isset($context['term_taxonomy']) ? $context['term_taxonomy'] : null;
|
283 |
+
$context['toTermTaxonomySlugOrName'] = isset($context['to_term_taxonomy']) ? $context['to_term_taxonomy'] : null;
|
284 |
+
|
285 |
+
if (isset($context['term_taxonomy']) && $context['term_taxonomy']) {
|
286 |
+
$termTaxonomyObject = get_taxonomy($context['term_taxonomy']);
|
287 |
+
if (is_a($termTaxonomyObject, 'WP_Taxonomy')) {
|
288 |
+
$termTaxonomyObjectLabels = get_taxonomy_labels($termTaxonomyObject);
|
289 |
+
$context['termTaxonomySlugOrName'] = $termTaxonomyObjectLabels->singular_name;
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
if (isset($context['to_term_taxonomy']) && $context['to_term_taxonomy']) {
|
294 |
+
$termTaxonomyObject = get_taxonomy($context['to_term_taxonomy']);
|
295 |
+
if (is_a($termTaxonomyObject, 'WP_Taxonomy')) {
|
296 |
+
$termTaxonomyObjectLabels = get_taxonomy_labels($termTaxonomyObject);
|
297 |
+
$context['toTermTaxonomySlugOrName'] = $termTaxonomyObjectLabels->singular_name;
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
if ('created_term' === $message_key && ! empty($term_edit_link) && ! empty($tax_edit_link)) {
|
302 |
+
$message = _x(
|
303 |
+
'Added term <a href="{term_edit_link}">"{term_name}"</a> in taxonomy <a href="{tax_edit_link}">"{termTaxonomySlugOrName}"</a>',
|
304 |
+
'Categories logger: detailed plain text output for created term',
|
305 |
+
'simple-history'
|
306 |
+
);
|
307 |
+
} elseif ('deleted_term' === $message_key && ! empty($tax_edit_link)) {
|
308 |
+
$message = _x(
|
309 |
+
'Deleted term "{term_name}" from taxonomy <a href="{tax_edit_link}">"{termTaxonomySlugOrName}"</a>',
|
310 |
+
'Categories logger: detailed plain text output for deleted term',
|
311 |
+
'simple-history'
|
312 |
+
);
|
313 |
+
} elseif ('edited_term' === $message_key && ! empty($term_edit_link) && ! empty($tax_edit_link)) {
|
314 |
+
$message = _x(
|
315 |
+
'Edited term <a href="{term_edit_link}">"{to_term_name}"</a> in taxonomy <a href="{tax_edit_link}">"{toTermTaxonomySlugOrName}"</a>',
|
316 |
+
'Categories logger: detailed plain text output for edited term',
|
317 |
+
'simple-history'
|
318 |
+
);
|
319 |
+
}
|
320 |
+
|
321 |
+
return $this->interpolate($message, $context, $row);
|
322 |
+
}
|
323 |
}
|
loggers/SimpleCommentsLogger.php
CHANGED
@@ -1,53 +1,55 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs things related to comments
|
7 |
*/
|
8 |
-
class SimpleCommentsLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
|
|
|
|
51 |
AND id NOT IN (
|
52 |
|
53 |
SELECT id
|
@@ -76,733 +78,712 @@ class SimpleCommentsLogger extends SimpleLogger {
|
|
76 |
)
|
77 |
', $this->db_table, $this->db_table_contexts, $this->slug);
|
78 |
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
if ( isset( $context[ $key ] ) ) {
|
727 |
-
$desc_output = esc_html( $context[ $key ] );
|
728 |
-
}
|
729 |
-
|
730 |
-
break;
|
731 |
-
}// End switch().
|
732 |
-
|
733 |
-
// Skip empty rows
|
734 |
-
if ( empty( $desc_output ) ) {
|
735 |
-
continue;
|
736 |
-
}
|
737 |
-
|
738 |
-
$output .= sprintf(
|
739 |
-
'
|
740 |
<tr>
|
741 |
<td>%1$s</td>
|
742 |
<td>%2$s</td>
|
743 |
</tr>
|
744 |
',
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
if ( $edit_comment_link && $edit_comment_link[ strlen( $edit_comment_link ) -1 ] !== '=' ) {
|
767 |
-
|
768 |
-
$output .= sprintf(
|
769 |
-
'
|
770 |
<tr>
|
771 |
<td></td>
|
772 |
<td><a href="%2$s">%1$s</a></td>
|
773 |
</tr>
|
774 |
',
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
}
|
807 |
-
|
808 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs things related to comments
|
7 |
*/
|
8 |
+
class SimpleCommentsLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
|
12 |
+
public $slug = __CLASS__;
|
13 |
+
|
14 |
+
function __construct($sh)
|
15 |
+
{
|
16 |
+
|
17 |
+
parent::__construct($sh);
|
18 |
+
|
19 |
+
// Add option to not show spam comments, because to much things getting logged
|
20 |
+
// add_filter("simple_history/log_query_sql_where", array($this, "maybe_modify_log_query_sql_where"));
|
21 |
+
add_filter('simple_history/log_query_inner_where', array( $this, 'maybe_modify_log_query_sql_where' ));
|
22 |
+
add_filter('simple_history/quick_stats_where', array( $this, 'maybe_modify_log_query_sql_where' ));
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Modify sql query to exclude comments of type spam
|
27 |
+
*
|
28 |
+
* @param string $where sql query where
|
29 |
+
*/
|
30 |
+
function maybe_modify_log_query_sql_where($where)
|
31 |
+
{
|
32 |
+
|
33 |
+
// since 19 sept 2016 we do include spam, to skip the subquery
|
34 |
+
// spam comments should not be logged anyway since some time
|
35 |
+
$include_spam = true;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Filter option to include spam or not in the gui
|
39 |
+
* By default spam is not included, because it can fill the log
|
40 |
+
* with too much events
|
41 |
+
*
|
42 |
+
* @since 2.0
|
43 |
+
*
|
44 |
+
* @param bool $include_spam Default false
|
45 |
+
*/
|
46 |
+
$include_spam = apply_filters('simple_history/comments_logger/include_spam', $include_spam);
|
47 |
+
|
48 |
+
if ($include_spam) {
|
49 |
+
return $where;
|
50 |
+
}
|
51 |
+
|
52 |
+
$where .= sprintf('
|
53 |
AND id NOT IN (
|
54 |
|
55 |
SELECT id
|
78 |
)
|
79 |
', $this->db_table, $this->db_table_contexts, $this->slug);
|
80 |
|
81 |
+
// echo $where;
|
82 |
+
return $where;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Get array with information about this logger
|
87 |
+
*
|
88 |
+
* @return array
|
89 |
+
*/
|
90 |
+
function getInfo()
|
91 |
+
{
|
92 |
+
|
93 |
+
$arr_info = array(
|
94 |
+
'name' => 'Comments Logger',
|
95 |
+
'description' => 'Logs comments, and modifications to them',
|
96 |
+
'capability' => 'moderate_comments',
|
97 |
+
'messages' => array(
|
98 |
+
|
99 |
+
// Comments
|
100 |
+
'anon_comment_added' => _x(
|
101 |
+
'Added a comment to {comment_post_type} "{comment_post_title}"',
|
102 |
+
'A comment was added to the database by a non-logged in internet user',
|
103 |
+
'simple-history'
|
104 |
+
),
|
105 |
+
|
106 |
+
'user_comment_added' => _x(
|
107 |
+
'Added a comment to {comment_post_type} "{comment_post_title}"',
|
108 |
+
'A comment was added to the database by a logged in user',
|
109 |
+
'simple-history'
|
110 |
+
),
|
111 |
+
|
112 |
+
'comment_status_approve' => _x(
|
113 |
+
'Approved a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
114 |
+
'A comment was approved',
|
115 |
+
'simple-history'
|
116 |
+
),
|
117 |
+
|
118 |
+
'comment_status_hold' => _x(
|
119 |
+
'Unapproved a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
120 |
+
'A comment was was unapproved',
|
121 |
+
'simple-history'
|
122 |
+
),
|
123 |
+
|
124 |
+
'comment_status_spam' => _x(
|
125 |
+
'Marked a comment to post "{comment_post_title}" as spam',
|
126 |
+
'A comment was marked as spam',
|
127 |
+
'simple-history'
|
128 |
+
),
|
129 |
+
|
130 |
+
'comment_status_trash' => _x(
|
131 |
+
'Trashed a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
132 |
+
'A comment was marked moved to the trash',
|
133 |
+
'simple-history'
|
134 |
+
),
|
135 |
+
|
136 |
+
'comment_untrashed' => _x(
|
137 |
+
'Restored a comment to "{comment_post_title}" by {comment_author} ({comment_author_email}) from the trash',
|
138 |
+
'A comment was restored from the trash',
|
139 |
+
'simple-history'
|
140 |
+
),
|
141 |
+
|
142 |
+
'comment_deleted' => _x(
|
143 |
+
'Deleted a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
144 |
+
'A comment was deleted',
|
145 |
+
'simple-history'
|
146 |
+
),
|
147 |
+
|
148 |
+
'comment_edited' => _x(
|
149 |
+
'Edited a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
150 |
+
'A comment was edited',
|
151 |
+
'simple-history'
|
152 |
+
),
|
153 |
+
|
154 |
+
// Trackbacks
|
155 |
+
'anon_trackback_added' => _x(
|
156 |
+
'Added a trackback to {comment_post_type} "{comment_post_title}"',
|
157 |
+
'A trackback was added to the database by a non-logged in internet user',
|
158 |
+
'simple-history'
|
159 |
+
),
|
160 |
+
|
161 |
+
'user_trackback_added' => _x(
|
162 |
+
'Added a trackback to {comment_post_type} "{comment_post_title}"',
|
163 |
+
'A trackback was added to the database by a logged in user',
|
164 |
+
'simple-history'
|
165 |
+
),
|
166 |
+
|
167 |
+
'trackback_status_approve' => _x(
|
168 |
+
'Approved a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
169 |
+
'A trackback was approved',
|
170 |
+
'simple-history'
|
171 |
+
),
|
172 |
+
|
173 |
+
'trackback_status_hold' => _x(
|
174 |
+
'Unapproved a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
175 |
+
'A trackback was was unapproved',
|
176 |
+
'simple-history'
|
177 |
+
),
|
178 |
+
|
179 |
+
'trackback_status_spam' => _x(
|
180 |
+
'Marked a trackback to post "{comment_post_title}" as spam',
|
181 |
+
'A trackback was marked as spam',
|
182 |
+
'simple-history'
|
183 |
+
),
|
184 |
+
|
185 |
+
'trackback_status_trash' => _x(
|
186 |
+
'Trashed a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
187 |
+
'A trackback was marked moved to the trash',
|
188 |
+
'simple-history'
|
189 |
+
),
|
190 |
+
|
191 |
+
'trackback_untrashed' => _x(
|
192 |
+
'Restored a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email}) from the trash',
|
193 |
+
'A trackback was restored from the trash',
|
194 |
+
'simple-history'
|
195 |
+
),
|
196 |
+
|
197 |
+
'trackback_deleted' => _x(
|
198 |
+
'Deleted a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
199 |
+
'A trackback was deleted',
|
200 |
+
'simple-history'
|
201 |
+
),
|
202 |
+
|
203 |
+
'trackback_edited' => _x(
|
204 |
+
'Edited a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
205 |
+
'A trackback was edited',
|
206 |
+
'simple-history'
|
207 |
+
),
|
208 |
+
|
209 |
+
// Pingbacks
|
210 |
+
'anon_pingback_added' => _x(
|
211 |
+
'Added a pingback to {comment_post_type} "{comment_post_title}"',
|
212 |
+
'A trackback was added to the database by a non-logged in internet user',
|
213 |
+
'simple-history'
|
214 |
+
),
|
215 |
+
|
216 |
+
'user_pingback_added' => _x(
|
217 |
+
'Added a pingback to {comment_post_type} "{comment_post_title}"',
|
218 |
+
'A pingback was added to the database by a logged in user',
|
219 |
+
'simple-history'
|
220 |
+
),
|
221 |
+
|
222 |
+
'pingback_status_approve' => _x(
|
223 |
+
'Approved a pingback to "{comment_post_title}" by "{comment_author}"" ({comment_author_email})',
|
224 |
+
'A pingback was approved',
|
225 |
+
'simple-history'
|
226 |
+
),
|
227 |
+
|
228 |
+
'pingback_status_hold' => _x(
|
229 |
+
'Unapproved a pingback to "{comment_post_title}" by "{comment_author}" ({comment_author_email})',
|
230 |
+
'A pingback was was unapproved',
|
231 |
+
'simple-history'
|
232 |
+
),
|
233 |
+
|
234 |
+
'pingback_status_spam' => _x(
|
235 |
+
'Marked a pingback to post "{comment_post_title}" as spam',
|
236 |
+
'A pingback was marked as spam',
|
237 |
+
'simple-history'
|
238 |
+
),
|
239 |
+
|
240 |
+
'pingback_status_trash' => _x(
|
241 |
+
'Trashed a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
242 |
+
'A pingback was marked moved to the trash',
|
243 |
+
'simple-history'
|
244 |
+
),
|
245 |
+
|
246 |
+
'pingback_untrashed' => _x(
|
247 |
+
'Restored a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email}) from the trash',
|
248 |
+
'A pingback was restored from the trash',
|
249 |
+
'simple-history'
|
250 |
+
),
|
251 |
+
|
252 |
+
'pingback_deleted' => _x(
|
253 |
+
'Deleted a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
254 |
+
'A pingback was deleted',
|
255 |
+
'simple-history'
|
256 |
+
),
|
257 |
+
|
258 |
+
'pingback_edited' => _x(
|
259 |
+
'Edited a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
260 |
+
'A pingback was edited',
|
261 |
+
'simple-history'
|
262 |
+
),
|
263 |
+
|
264 |
+
), // end messages
|
265 |
+
|
266 |
+
'labels' => array(
|
267 |
+
|
268 |
+
'search' => array(
|
269 |
+
'label' => _x('Comments', 'Comments logger: search', 'simple-history'),
|
270 |
+
'label_all' => _x('All comments activity', 'Comments logger: search', 'simple-history'),
|
271 |
+
'options' => array(
|
272 |
+
_x('Added comments', 'Comments logger: search', 'simple-history') => array(
|
273 |
+
'anon_comment_added',
|
274 |
+
'user_comment_added',
|
275 |
+
'anon_trackback_added',
|
276 |
+
'user_trackback_added',
|
277 |
+
'anon_pingback_added',
|
278 |
+
'user_pingback_added',
|
279 |
+
),
|
280 |
+
_x('Edited comments', 'Comments logger: search', 'simple-history') => array(
|
281 |
+
'comment_edited',
|
282 |
+
'trackback_edited',
|
283 |
+
'pingback_edited',
|
284 |
+
),
|
285 |
+
_x('Approved comments', 'Comments logger: search', 'simple-history') => array(
|
286 |
+
'comment_status_approve',
|
287 |
+
'trackback_status_approve',
|
288 |
+
'pingback_status_approve',
|
289 |
+
),
|
290 |
+
_x('Held comments', 'Comments logger: search', 'simple-history') => array(
|
291 |
+
'comment_status_hold',
|
292 |
+
'trackback_status_hold',
|
293 |
+
'pingback_status_hold',
|
294 |
+
),
|
295 |
+
_x('Comments status changed to spam', 'Comments logger: search', 'simple-history') => array(
|
296 |
+
'comment_status_spam',
|
297 |
+
'trackback_status_spam',
|
298 |
+
'pingback_status_spam',
|
299 |
+
),
|
300 |
+
_x('Trashed comments', 'Comments logger: search', 'simple-history') => array(
|
301 |
+
'comment_status_trash',
|
302 |
+
'trackback_status_trash',
|
303 |
+
'pingback_status_trash',
|
304 |
+
),
|
305 |
+
_x('Untrashed comments', 'Comments logger: search', 'simple-history') => array(
|
306 |
+
'comment_untrashed',
|
307 |
+
'trackback_untrashed',
|
308 |
+
'pingback_untrashed',
|
309 |
+
),
|
310 |
+
_x('Deleted comments', 'Comments logger: search', 'simple-history') => array(
|
311 |
+
'comment_deleted',
|
312 |
+
'trackback_deleted',
|
313 |
+
'pingback_deleted',
|
314 |
+
),
|
315 |
+
),
|
316 |
+
),// end search
|
317 |
+
|
318 |
+
),// labels
|
319 |
+
|
320 |
+
);
|
321 |
+
|
322 |
+
return $arr_info;
|
323 |
+
}
|
324 |
+
|
325 |
+
public function loaded()
|
326 |
+
{
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Fires immediately after a comment is inserted into the database.
|
330 |
+
*/
|
331 |
+
add_action('comment_post', array( $this, 'on_comment_post' ), 10, 2);
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Fires after a comment status has been updated in the database.
|
335 |
+
* The hook also fires immediately before comment status transition hooks are fired.
|
336 |
+
*/
|
337 |
+
add_action('wp_set_comment_status', array( $this, 'on_wp_set_comment_status' ), 10, 2);
|
338 |
+
|
339 |
+
/**
|
340 |
+
*Fires immediately after a comment is restored from the Trash.
|
341 |
+
*/
|
342 |
+
add_action('untrashed_comment', array( $this, 'on_untrashed_comment' ), 10, 1);
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Fires immediately before a comment is deleted from the database.
|
346 |
+
*/
|
347 |
+
add_action('delete_comment', array( $this, 'on_delete_comment' ), 10, 1);
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Fires immediately after a comment is updated in the database.
|
351 |
+
* The hook also fires immediately before comment status transition hooks are fired.
|
352 |
+
*/
|
353 |
+
add_action('edit_comment', array( $this, 'on_edit_comment' ), 10, 1);
|
354 |
+
}
|
355 |
+
|
356 |
+
/**
|
357 |
+
* Get comments context
|
358 |
+
*
|
359 |
+
* @param int $comment_ID
|
360 |
+
* @return mixed array with context if comment found, false if comment not found
|
361 |
+
*/
|
362 |
+
public function get_context_for_comment($comment_ID)
|
363 |
+
{
|
364 |
+
|
365 |
+
// get_comment passes comment_ID by reference, so it can be unset by that function
|
366 |
+
$comment_ID_original = $comment_ID;
|
367 |
+
$comment_data = get_comment($comment_ID);
|
368 |
+
|
369 |
+
if (is_null($comment_data)) {
|
370 |
+
return false;
|
371 |
+
}
|
372 |
+
|
373 |
+
$comment_parent_post = get_post($comment_data->comment_post_ID);
|
374 |
+
|
375 |
+
$context = array(
|
376 |
+
'comment_ID' => $comment_ID_original,
|
377 |
+
'comment_author' => $comment_data->comment_author,
|
378 |
+
'comment_author_email' => $comment_data->comment_author_email,
|
379 |
+
'comment_author_url' => $comment_data->comment_author_url,
|
380 |
+
'comment_author_IP' => $comment_data->comment_author_IP,
|
381 |
+
'comment_content' => $comment_data->comment_content,
|
382 |
+
'comment_approved' => $comment_data->comment_approved,
|
383 |
+
'comment_agent' => $comment_data->comment_agent,
|
384 |
+
'comment_type' => $comment_data->comment_type,
|
385 |
+
'comment_parent' => $comment_data->comment_parent,
|
386 |
+
'comment_post_ID' => $comment_data->comment_post_ID,
|
387 |
+
'comment_post_title' => $comment_parent_post->post_title,
|
388 |
+
'comment_post_type' => $comment_parent_post->post_type,
|
389 |
+
);
|
390 |
+
|
391 |
+
// Note: comment type is empty for normal comments
|
392 |
+
if (empty($context['comment_type'])) {
|
393 |
+
$context['comment_type'] = 'comment';
|
394 |
+
}
|
395 |
+
|
396 |
+
return $context;
|
397 |
+
}
|
398 |
+
|
399 |
+
public function on_edit_comment($comment_ID)
|
400 |
+
{
|
401 |
+
|
402 |
+
$context = $this->get_context_for_comment($comment_ID);
|
403 |
+
if (! $context) {
|
404 |
+
return;
|
405 |
+
}
|
406 |
+
|
407 |
+
$this->infoMessage(
|
408 |
+
"{$context["comment_type"]}_edited",
|
409 |
+
$context
|
410 |
+
);
|
411 |
+
}
|
412 |
+
|
413 |
+
public function on_delete_comment($comment_ID)
|
414 |
+
{
|
415 |
+
|
416 |
+
$context = $this->get_context_for_comment($comment_ID);
|
417 |
+
|
418 |
+
if (! $context) {
|
419 |
+
return;
|
420 |
+
}
|
421 |
+
|
422 |
+
$comment_data = get_comment($comment_ID);
|
423 |
+
|
424 |
+
// add occasions if comment was considered spam
|
425 |
+
// if not added, spam comments can easily flood the log
|
426 |
+
// Deletions of spam easiy flood log
|
427 |
+
if (isset($comment_data->comment_approved) && 'spam' === $comment_data->comment_approved) {
|
428 |
+
// since 2.5.5: don't log deletion of spam comments
|
429 |
+
return;
|
430 |
+
// $context["_occasionsID"] = __CLASS__ . '/' . __FUNCTION__ . "/anon_{$context["comment_type"]}_deleted/type:spam";
|
431 |
+
}
|
432 |
+
|
433 |
+
$this->infoMessage(
|
434 |
+
"{$context["comment_type"]}_deleted",
|
435 |
+
$context
|
436 |
+
);
|
437 |
+
}
|
438 |
+
|
439 |
+
public function on_untrashed_comment($comment_ID)
|
440 |
+
{
|
441 |
+
|
442 |
+
$context = $this->get_context_for_comment($comment_ID);
|
443 |
+
if (! $context) {
|
444 |
+
return;
|
445 |
+
}
|
446 |
+
|
447 |
+
$this->infoMessage(
|
448 |
+
"{$context["comment_type"]}_untrashed",
|
449 |
+
$context
|
450 |
+
);
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Fires after a comment status has been updated in the database.
|
455 |
+
* The hook also fires immediately before comment status transition hooks are fired.
|
456 |
+
*
|
457 |
+
* @param int $comment_id The comment ID.
|
458 |
+
* @param string|bool $comment_status The comment status. Possible values include 'hold',
|
459 |
+
* 'approve', 'spam', 'trash', or false.
|
460 |
+
* do_action( 'wp_set_comment_status', $comment_id, $comment_status );
|
461 |
+
*/
|
462 |
+
public function on_wp_set_comment_status($comment_ID, $comment_status)
|
463 |
+
{
|
464 |
+
|
465 |
+
$context = $this->get_context_for_comment($comment_ID);
|
466 |
+
|
467 |
+
if (! $context) {
|
468 |
+
return;
|
469 |
+
}
|
470 |
+
|
471 |
+
/*
|
472 |
+
$comment_status:
|
473 |
+
approve
|
474 |
+
comment was approved
|
475 |
+
spam
|
476 |
+
comment was marked as spam
|
477 |
+
trash
|
478 |
+
comment was trashed
|
479 |
+
hold
|
480 |
+
comment was un-approved
|
481 |
+
*/
|
482 |
+
$message = "{$context["comment_type"]}_status_{$comment_status}";
|
483 |
+
|
484 |
+
$this->infoMessage(
|
485 |
+
$message,
|
486 |
+
$context
|
487 |
+
);
|
488 |
+
}
|
489 |
+
|
490 |
+
/**
|
491 |
+
* Fires immediately after a comment is inserted into the database.
|
492 |
+
*/
|
493 |
+
public function on_comment_post($comment_ID, $comment_approved)
|
494 |
+
{
|
495 |
+
|
496 |
+
$context = $this->get_context_for_comment($comment_ID);
|
497 |
+
|
498 |
+
if (! $context) {
|
499 |
+
return;
|
500 |
+
}
|
501 |
+
|
502 |
+
// since 2.5.5: no more logging of spam comments
|
503 |
+
if (isset($comment_approved) && 'spam' === $comment_approved) {
|
504 |
+
return;
|
505 |
+
}
|
506 |
+
|
507 |
+
$comment_data = get_comment($comment_ID);
|
508 |
+
|
509 |
+
$message = '';
|
510 |
+
|
511 |
+
if ($comment_data->user_id) {
|
512 |
+
// comment was from a logged in user
|
513 |
+
$message = "user_{$context["comment_type"]}_added";
|
514 |
+
} else {
|
515 |
+
// comment was from a non-logged in user
|
516 |
+
$message = "anon_{$context["comment_type"]}_added";
|
517 |
+
$context['_initiator'] = SimpleLoggerLogInitiators::WEB_USER;
|
518 |
+
|
519 |
+
// add occasions if comment is considered spam
|
520 |
+
// if not added, spam comments can easily flood the log
|
521 |
+
if (isset($comment_data->comment_approved) && 'spam' === $comment_data->comment_approved) {
|
522 |
+
$context['_occasionsID'] = __CLASS__ . '/' . __FUNCTION__ . "/anon_{$context["comment_type"]}_added/type:spam";
|
523 |
+
}
|
524 |
+
}
|
525 |
+
|
526 |
+
$this->infoMessage(
|
527 |
+
$message,
|
528 |
+
$context
|
529 |
+
);
|
530 |
+
}
|
531 |
+
|
532 |
+
|
533 |
+
/**
|
534 |
+
* Modify plain output to inlcude link to post
|
535 |
+
* and link to comment
|
536 |
+
*/
|
537 |
+
public function getLogRowPlainTextOutput($row)
|
538 |
+
{
|
539 |
+
|
540 |
+
$message = $row->message;
|
541 |
+
$context = $row->context;
|
542 |
+
$message_key = $context['_message_key'];
|
543 |
+
|
544 |
+
// Message is untranslated here, so get translated text
|
545 |
+
// Can't call parent __FUNCTION__ because it will interpolate too, which we don't want
|
546 |
+
if (! empty($message_key)) {
|
547 |
+
$message = $this->messages[ $message_key ]['translated_text'];
|
548 |
+
}
|
549 |
+
|
550 |
+
// Wrap links around {comment_post_title}
|
551 |
+
$comment_post_ID = isset($context['comment_post_ID']) ? (int) $context['comment_post_ID'] : null;
|
552 |
+
if ($comment_post_ID && $comment_post = get_post($comment_post_ID)) {
|
553 |
+
$edit_post_link = get_edit_post_link($comment_post_ID);
|
554 |
+
|
555 |
+
if ($edit_post_link) {
|
556 |
+
$message = str_replace(
|
557 |
+
'"{comment_post_title}"',
|
558 |
+
"<a href='{$edit_post_link}'>\"{comment_post_title}\"</a>",
|
559 |
+
$message
|
560 |
+
);
|
561 |
+
}
|
562 |
+
}
|
563 |
+
|
564 |
+
return $this->interpolate($message, $context, $row);
|
565 |
+
}
|
566 |
+
|
567 |
+
|
568 |
+
/**
|
569 |
+
* Get output for detailed log section
|
570 |
+
*/
|
571 |
+
function getLogRowDetailsOutput($row)
|
572 |
+
{
|
573 |
+
|
574 |
+
$context = $row->context;
|
575 |
+
$message_key = $context['_message_key'];
|
576 |
+
$output = '';
|
577 |
+
// print_r($row);exit;
|
578 |
+
/*
|
579 |
+
if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching
|
580 |
+
if ( '0' == $commentdata['comment_approved'] ) { // comment not spam, but not auto-approved
|
581 |
+
wp_notify_moderator( $comment_ID );
|
582 |
+
*/
|
583 |
+
/*
|
584 |
+
if ( isset( $context["comment_approved"] ) && $context["comment_approved"] == '0' ) {
|
585 |
+
$output .= "<br>comment was automatically approved";
|
586 |
+
} else {
|
587 |
+
$output .= "<br>comment was not automatically approved";
|
588 |
+
}*/
|
589 |
+
|
590 |
+
$comment_text = '';
|
591 |
+
if (isset($context['comment_content']) && $context['comment_content']) {
|
592 |
+
$comment_text = $context['comment_content'];
|
593 |
+
$comment_text = wp_trim_words($comment_text, 20);
|
594 |
+
$comment_text = wpautop($comment_text);
|
595 |
+
}
|
596 |
+
|
597 |
+
// Keys to show
|
598 |
+
$arr_plugin_keys = array();
|
599 |
+
$comment_type = isset($context['comment_type']) ? $context['comment_type'] : '';
|
600 |
+
|
601 |
+
switch ($comment_type) {
|
602 |
+
case 'trackback';
|
603 |
+
|
604 |
+
$arr_plugin_keys = array(
|
605 |
+
'trackback_status' => _x('Status', 'comments logger - detailed output comment status', 'simple-history'),
|
606 |
+
// "trackback_type" => _x("Trackback type", "comments logger - detailed output comment type", "simple-history"),
|
607 |
+
'trackback_author' => _x('Name', 'comments logger - detailed output author', 'simple-history'),
|
608 |
+
'trackback_author_email' => _x('Email', 'comments logger - detailed output email', 'simple-history'),
|
609 |
+
'trackback_content' => _x('Content', 'comments logger - detailed output content', 'simple-history'),
|
610 |
+
);
|
611 |
+
|
612 |
+
break;
|
613 |
+
|
614 |
+
case 'pingback';
|
615 |
+
|
616 |
+
$arr_plugin_keys = array(
|
617 |
+
|
618 |
+
'pingback_status' => _x('Status', 'comments logger - detailed output comment status', 'simple-history'),
|
619 |
+
// "pingback_type" => _x("Pingback type", "comments logger - detailed output comment type", "simple-history"),
|
620 |
+
'pingback_author' => _x('Name', 'comments logger - detailed output author', 'simple-history'),
|
621 |
+
'pingback_author_email' => _x('Email', 'comments logger - detailed output email', 'simple-history'),
|
622 |
+
'pingback_content' => _x('Content', 'comments logger - detailed output content', 'simple-history'),
|
623 |
+
|
624 |
+
);
|
625 |
+
|
626 |
+
break;
|
627 |
+
|
628 |
+
case 'comment';
|
629 |
+
default;
|
630 |
+
|
631 |
+
$arr_plugin_keys = array(
|
632 |
+
'comment_status' => _x('Status', 'comments logger - detailed output comment status', 'simple-history'),
|
633 |
+
// "comment_type" => _x("Comment type", "comments logger - detailed output comment type", "simple-history"),
|
634 |
+
'comment_author' => _x('Name', 'comments logger - detailed output author', 'simple-history'),
|
635 |
+
'comment_author_email' => _x('Email', 'comments logger - detailed output email', 'simple-history'),
|
636 |
+
'comment_content' => _x('Comment', 'comments logger - detailed output content', 'simple-history'),
|
637 |
+
);
|
638 |
+
|
639 |
+
break;
|
640 |
+
|
641 |
+
// "comment_author_url" => _x("Author URL", "comments logger - detailed output author", "simple-history"),
|
642 |
+
// "comment_author_IP" => _x("IP number", "comments logger - detailed output IP", "simple-history"),
|
643 |
+
}// End switch().
|
644 |
+
|
645 |
+
$arr_plugin_keys = apply_filters('simple_history/comments_logger/row_details_plugin_info_keys', $arr_plugin_keys);
|
646 |
+
|
647 |
+
// Start output of plugin meta data table
|
648 |
+
$output .= "<table class='SimpleHistoryLogitem__keyValueTable'>";
|
649 |
+
|
650 |
+
foreach ($arr_plugin_keys as $key => $desc) {
|
651 |
+
switch ($key) {
|
652 |
+
case 'comment_content':
|
653 |
+
case 'trackback_content':
|
654 |
+
case 'pingback_content':
|
655 |
+
$desc_output = $comment_text;
|
656 |
+
break;
|
657 |
+
|
658 |
+
case 'comment_author':
|
659 |
+
case 'trackback_author':
|
660 |
+
case 'pingback_author':
|
661 |
+
$desc_output = '';
|
662 |
+
|
663 |
+
if (isset($context[ $key ])) {
|
664 |
+
$desc_output .= esc_html($context[ $key ]);
|
665 |
+
}
|
666 |
+
|
667 |
+
/*
|
668 |
+
if ( isset( $context["comment_author_email"] ) ) {
|
669 |
+
|
670 |
+
$gravatar_email = $context["comment_author_email"];
|
671 |
+
$avatar = $this->simpleHistory->get_avatar( $gravatar_email, 14, "blank" );
|
672 |
+
$desc_output .= "<span class='SimpleCommentsLogger__gravatar'>{$avatar}</span>";
|
673 |
+
|
674 |
+
}
|
675 |
+
*/
|
676 |
+
|
677 |
+
break;
|
678 |
+
|
679 |
+
case 'comment_status':
|
680 |
+
case 'trackback_status':
|
681 |
+
case 'pingback_status':
|
682 |
+
if (isset($context['comment_approved'])) {
|
683 |
+
if ($context['comment_approved'] === 'spam') {
|
684 |
+
$desc_output = __('Spam', 'simple-history');
|
685 |
+
} elseif ($context['comment_approved'] == 1) {
|
686 |
+
$desc_output = __('Approved', 'simple-history');
|
687 |
+
} elseif ($context['comment_approved'] == 0) {
|
688 |
+
$desc_output = __('Pending', 'simple-history');
|
689 |
+
}
|
690 |
+
}
|
691 |
+
|
692 |
+
break;
|
693 |
+
|
694 |
+
case 'comment_type':
|
695 |
+
case 'trackback_type':
|
696 |
+
case 'pingback_type':
|
697 |
+
if (isset($context['comment_type'])) {
|
698 |
+
if ($context['comment_type'] === 'trackback') {
|
699 |
+
$desc_output = __('Trackback', 'simple-history');
|
700 |
+
} elseif ($context['comment_type'] === 'pingback') {
|
701 |
+
$desc_output = __('Pingback', 'simple-history');
|
702 |
+
} elseif ($context['comment_type'] === 'comment') {
|
703 |
+
$desc_output = __('Comment', 'simple-history');
|
704 |
+
} else {
|
705 |
+
$desc_output = '';
|
706 |
+
}
|
707 |
+
}
|
708 |
+
|
709 |
+
break;
|
710 |
+
|
711 |
+
default;
|
712 |
+
|
713 |
+
if (isset($context[ $key ])) {
|
714 |
+
$desc_output = esc_html($context[ $key ]);
|
715 |
+
}
|
716 |
+
|
717 |
+
break;
|
718 |
+
}// End switch().
|
719 |
+
|
720 |
+
// Skip empty rows
|
721 |
+
if (empty($desc_output)) {
|
722 |
+
continue;
|
723 |
+
}
|
724 |
+
|
725 |
+
$output .= sprintf(
|
726 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
727 |
<tr>
|
728 |
<td>%1$s</td>
|
729 |
<td>%2$s</td>
|
730 |
</tr>
|
731 |
',
|
732 |
+
esc_html($desc),
|
733 |
+
$desc_output
|
734 |
+
);
|
735 |
+
}// End foreach().
|
736 |
+
|
737 |
+
// Add link to edit comment
|
738 |
+
$comment_ID = isset($context['comment_ID']) && is_numeric($context['comment_ID']) ? (int) $context['comment_ID'] : false;
|
739 |
+
|
740 |
+
if ($comment_ID) {
|
741 |
+
$comment = get_comment($comment_ID);
|
742 |
+
|
743 |
+
if ($comment) {
|
744 |
+
// http://site.local/wp/wp-admin/comment.php?action=editcomment&c=
|
745 |
+
$edit_comment_link = get_edit_comment_link($comment_ID);
|
746 |
+
|
747 |
+
// Edit link sometimes does not contain comment ID
|
748 |
+
// Probably because comment has been removed or something
|
749 |
+
// So only continue if link does not end with "=""
|
750 |
+
if ($edit_comment_link && $edit_comment_link[ strlen($edit_comment_link) -1 ] !== '=') {
|
751 |
+
$output .= sprintf(
|
752 |
+
'
|
|
|
|
|
|
|
|
|
753 |
<tr>
|
754 |
<td></td>
|
755 |
<td><a href="%2$s">%1$s</a></td>
|
756 |
</tr>
|
757 |
',
|
758 |
+
_x('View/Edit', 'comments logger - edit comment', 'simple-history'),
|
759 |
+
$edit_comment_link
|
760 |
+
);
|
761 |
+
}
|
762 |
+
}
|
763 |
+
} // End if().
|
764 |
+
|
765 |
+
// End table
|
766 |
+
$output .= '</table>';
|
767 |
+
|
768 |
+
return $output;
|
769 |
+
}
|
770 |
+
|
771 |
+
function adminCSS()
|
772 |
+
{
|
773 |
+
?>
|
774 |
+
<style>
|
775 |
+
.SimpleCommentsLogger__gravatar {
|
776 |
+
line-height: 1;
|
777 |
+
border-radius: 50%;
|
778 |
+
overflow: hidden;
|
779 |
+
margin-right: .5em;
|
780 |
+
margin-left: .5em;
|
781 |
+
display: inline-block;
|
782 |
+
}
|
783 |
+
.SimpleCommentsLogger__gravatar img {
|
784 |
+
display: block;
|
785 |
+
}
|
786 |
+
</style>
|
787 |
+
<?php
|
788 |
+
}
|
|
|
|
|
789 |
}
|
loggers/SimpleCoreUpdatesLogger.php
CHANGED
@@ -1,115 +1,116 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress core updates
|
7 |
*/
|
8 |
-
class SimpleCoreUpdatesLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
|
|
115 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress core updates
|
7 |
*/
|
8 |
+
class SimpleCoreUpdatesLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
public $slug = __CLASS__;
|
12 |
+
|
13 |
+
public function loaded()
|
14 |
+
{
|
15 |
+
|
16 |
+
add_action('_core_updated_successfully', array( $this, 'on_core_updated' ));
|
17 |
+
add_action('update_feedback', array( $this, 'on_update_feedback' ));
|
18 |
+
|
19 |
+
// Can't log db updates at the moment, because loaded() is not called yet when the action fires
|
20 |
+
// add_action( 'wp_upgrade', array( $this, "on_wp_upgrade" ), 10, 2 );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Fires after a site is fully upgraded.
|
25 |
+
* The database, that is.
|
26 |
+
*
|
27 |
+
* @param int $wp_db_version The new $wp_db_version.
|
28 |
+
* @param int $wp_current_db_version The old (current) $wp_db_version.
|
29 |
+
*/
|
30 |
+
function on_wp_upgrade($wp_db_version, $wp_current_db_version)
|
31 |
+
{
|
32 |
+
|
33 |
+
$this->debugMessage(
|
34 |
+
'core_db_version_updated',
|
35 |
+
array(
|
36 |
+
'new_version' => $wp_db_version,
|
37 |
+
'prev_version' => $wp_current_db_version,
|
38 |
+
)
|
39 |
+
);
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* We need to store the WordPress version we are updating from.
|
44 |
+
* 'update_feedback' is a suitable filter.
|
45 |
+
*/
|
46 |
+
function on_update_feedback()
|
47 |
+
{
|
48 |
+
|
49 |
+
if (! empty($GLOBALS['wp_version']) && ! isset($GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ])) {
|
50 |
+
$GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ] = $GLOBALS['wp_version'];
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Get array with information about this logger
|
56 |
+
*
|
57 |
+
* @return array
|
58 |
+
*/
|
59 |
+
function getInfo()
|
60 |
+
{
|
61 |
+
|
62 |
+
$arr_info = array(
|
63 |
+
'name' => 'Core Updates Logger',
|
64 |
+
'description' => 'Logs the update of WordPress (manual and automatic updates)',
|
65 |
+
'capability' => 'update_core',
|
66 |
+
'messages' => array(
|
67 |
+
'core_updated' => __('Updated WordPress to {new_version} from {prev_version}', 'simple-history'),
|
68 |
+
'core_auto_updated' => __('WordPress auto-updated to {new_version} from {prev_version}', 'simple-history'),
|
69 |
+
'core_db_version_updated' => __('WordPress database version updated to {new_version} from {prev_version}', 'simple-history'),
|
70 |
+
),
|
71 |
+
'labels' => array(
|
72 |
+
'search' => array(
|
73 |
+
'label' => _x('WordPress Core', 'User logger: search', 'simple-history'),
|
74 |
+
'options' => array(
|
75 |
+
_x('WordPress core updates', 'User logger: search', 'simple-history') => array(
|
76 |
+
'core_updated',
|
77 |
+
'core_auto_updated',
|
78 |
+
),
|
79 |
+
),
|
80 |
+
),// end search array
|
81 |
+
),// end labels
|
82 |
+
);
|
83 |
+
|
84 |
+
return $arr_info;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Called when WordPress is updated
|
89 |
+
*
|
90 |
+
* @param string $new_wp_version
|
91 |
+
*/
|
92 |
+
public function on_core_updated($new_wp_version)
|
93 |
+
{
|
94 |
+
|
95 |
+
$old_wp_version = empty($GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ]) ? $GLOBALS['wp_version'] : $GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ];
|
96 |
+
|
97 |
+
$auto_update = true;
|
98 |
+
if ($GLOBALS['pagenow'] == 'update-core.php') {
|
99 |
+
$auto_update = false;
|
100 |
+
}
|
101 |
+
|
102 |
+
if ($auto_update) {
|
103 |
+
$message = 'core_auto_updated';
|
104 |
+
} else {
|
105 |
+
$message = 'core_updated';
|
106 |
+
}
|
107 |
+
|
108 |
+
$this->noticeMessage(
|
109 |
+
$message,
|
110 |
+
array(
|
111 |
+
'prev_version' => $old_wp_version,
|
112 |
+
'new_version' => $new_wp_version,
|
113 |
+
)
|
114 |
+
);
|
115 |
+
}
|
116 |
}
|
loggers/SimpleExportLogger.php
CHANGED
@@ -1,75 +1,75 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress exports
|
7 |
*/
|
8 |
-
class SimpleExportLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress exports
|
7 |
*/
|
8 |
+
class SimpleExportLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
|
12 |
+
public $slug = __CLASS__;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Get array with information about this logger
|
16 |
+
*
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
function getInfo()
|
20 |
+
{
|
21 |
+
|
22 |
+
$arr_info = array(
|
23 |
+
'name' => __('Export Logger', 'simple-history'),
|
24 |
+
'description' => __('Logs updates to WordPress export', 'simple-history'),
|
25 |
+
'capability' => 'export',
|
26 |
+
'messages' => array(
|
27 |
+
'created_export' => __('Created XML export', 'simple-history'),
|
28 |
+
),
|
29 |
+
'labels' => array(
|
30 |
+
'search' => array(
|
31 |
+
'label' => _x('Export', 'Export logger: search', 'simple-history'),
|
32 |
+
'options' => array(
|
33 |
+
_x('Created exports', 'Export logger: search', 'simple-history') => array(
|
34 |
+
'created_export'
|
35 |
+
),
|
36 |
+
),
|
37 |
+
),// end search array
|
38 |
+
),// end labels
|
39 |
+
);
|
40 |
+
|
41 |
+
return $arr_info;
|
42 |
+
}
|
43 |
+
|
44 |
+
function loaded()
|
45 |
+
{
|
46 |
+
|
47 |
+
add_action('export_wp', array( $this, 'on_export_wp' ), 10, 1);
|
48 |
+
}
|
49 |
+
|
50 |
+
function on_export_wp($args)
|
51 |
+
{
|
52 |
+
|
53 |
+
$this->infoMessage(
|
54 |
+
'created_export',
|
55 |
+
array(
|
56 |
+
'args' => $this->simpleHistory->json_encode($args),
|
57 |
+
)
|
58 |
+
);
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Get detailed output
|
63 |
+
*/
|
64 |
+
/*
|
65 |
+
function getLogRowDetailsOutput($row) {
|
66 |
+
|
67 |
+
$context = $row->context;
|
68 |
+
$message_key = $context["_message_key"];
|
69 |
+
$output = "";
|
70 |
+
|
71 |
+
return $output;
|
72 |
+
|
73 |
+
}
|
74 |
+
*/
|
75 |
}
|
loggers/SimpleLegacyLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logger for events stored earlier than v2
|
@@ -8,100 +8,98 @@ defined( 'ABSPATH' ) or die();
|
|
8 |
*
|
9 |
* @since 2.0
|
10 |
*/
|
11 |
-
class SimpleLegacyLogger extends SimpleLogger
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
44 |
),
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
|
50 |
-
|
51 |
|
52 |
-
|
|
|
53 |
|
54 |
-
|
|
|
55 |
|
56 |
-
|
|
|
57 |
|
58 |
-
|
59 |
-
$context = $row->context;
|
60 |
|
61 |
-
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
$sql = sprintf('
|
67 |
SELECT * FROM %1$s
|
68 |
WHERE id = %2$d
|
69 |
',
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
$one_item = $wpdb->get_row( $sql );
|
75 |
-
|
76 |
-
// $out .= print_r($row, true);
|
77 |
-
// Code mostly from version 1.x
|
78 |
-
$object_type = ucwords( $one_item->object_type );
|
79 |
-
$object_name = esc_html( $one_item->object_name );
|
80 |
-
$user = get_user_by( 'id', $one_item->user_id );
|
81 |
-
$user_nicename = esc_html( @$user->user_nicename );
|
82 |
-
$user_email = esc_html( @$user->user_email );
|
83 |
-
$description = '';
|
84 |
-
|
85 |
-
if ( $user_nicename ) {
|
86 |
-
$description .= sprintf( __( 'By %s', 'simple-history' ), $user_nicename );
|
87 |
|
88 |
-
|
89 |
|
90 |
-
|
91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
-
|
|
|
|
|
94 |
|
95 |
-
|
96 |
-
|
|
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
return $out;
|
102 |
-
|
103 |
-
}
|
104 |
|
|
|
|
|
105 |
|
|
|
|
|
106 |
}
|
107 |
-
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logger for events stored earlier than v2
|
8 |
*
|
9 |
* @since 2.0
|
10 |
*/
|
11 |
+
class SimpleLegacyLogger extends SimpleLogger
|
12 |
+
{
|
13 |
+
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Unique slug for this logger
|
17 |
+
* Will be saved in DB and used to associate each log row with its logger
|
18 |
+
*/
|
19 |
+
public $slug = 'SimpleLegacyLogger';
|
20 |
+
|
21 |
+
public function __construct()
|
22 |
+
{
|
23 |
+
|
24 |
+
// $this->info(__CLASS__ . " construct()");
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get array with information about this logger
|
29 |
+
*
|
30 |
+
* @return array
|
31 |
+
*/
|
32 |
+
function getInfo()
|
33 |
+
{
|
34 |
+
|
35 |
+
$arr_info = array(
|
36 |
+
'name' => 'Legacy Logger',
|
37 |
+
'description' => 'Formats old events',
|
38 |
+
'capability' => 'edit_pages',
|
39 |
+
'messages' => array(),
|
40 |
+
/*
|
41 |
+
"labels" => array(
|
42 |
+
"search" => array(
|
43 |
+
"label" => _x("Export", "Export logger: search", "simple-history"),
|
44 |
+
"options" => array(
|
45 |
+
_x("Exports created", "Core updates logger: search", "simple-history") => array(
|
46 |
+
"created_export"
|
47 |
),
|
48 |
+
)
|
49 |
+
) // end search array
|
50 |
+
) // end labels
|
51 |
+
*/
|
52 |
|
53 |
+
);
|
54 |
|
55 |
+
return $arr_info;
|
56 |
+
}
|
57 |
|
58 |
+
public function getLogRowPlainTextOutput($row)
|
59 |
+
{
|
60 |
|
61 |
+
$message = $row->message;
|
62 |
+
$context = $row->context;
|
63 |
|
64 |
+
$out = '';
|
|
|
65 |
|
66 |
+
global $wpdb;
|
67 |
|
68 |
+
// Get old columns for this event
|
69 |
+
$sql = sprintf(
|
70 |
+
'
|
|
|
71 |
SELECT * FROM %1$s
|
72 |
WHERE id = %2$d
|
73 |
',
|
74 |
+
$wpdb->prefix . SimpleHistory::DBTABLE,
|
75 |
+
$row->id
|
76 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
|
78 |
+
$one_item = $wpdb->get_row($sql);
|
79 |
|
80 |
+
// $out .= print_r($row, true);
|
81 |
+
// Code mostly from version 1.x
|
82 |
+
$object_type = ucwords($one_item->object_type);
|
83 |
+
$object_name = esc_html($one_item->object_name);
|
84 |
+
$user = get_user_by('id', $one_item->user_id);
|
85 |
+
$user_nicename = esc_html(@$user->user_nicename);
|
86 |
+
$user_email = esc_html(@$user->user_email);
|
87 |
+
$description = '';
|
88 |
|
89 |
+
if ($user_nicename) {
|
90 |
+
$description .= sprintf(__('By %s', 'simple-history'), $user_nicename);
|
91 |
+
}
|
92 |
|
93 |
+
if (isset($one_item->occasions)) {
|
94 |
+
$description .= sprintf(__('%d occasions', 'simple-history'), sizeof($one_item->occasions));
|
95 |
+
}
|
96 |
|
97 |
+
$item_title = esc_html($object_type) . ' "' . esc_html($object_name) . "\" {$one_item->action}";
|
98 |
+
$item_title = html_entity_decode($item_title, ENT_COMPAT, 'UTF-8');
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
$out .= "$item_title";
|
101 |
+
$out .= "<br>$description";
|
102 |
|
103 |
+
return $out;
|
104 |
+
}
|
105 |
}
|
|
loggers/SimpleLogger.php
CHANGED
@@ -86,7 +86,7 @@ class SimpleLogger
|
|
86 |
*
|
87 |
* @return array
|
88 |
*/
|
89 |
-
|
90 |
{
|
91 |
$arr_info = array(
|
92 |
// The logger slug. Defaulting to the class name is nice and logical I think
|
@@ -115,7 +115,7 @@ class SimpleLogger
|
|
115 |
* @since 2.5.4
|
116 |
* @return Mixed
|
117 |
*/
|
118 |
-
|
119 |
{
|
120 |
$arr_info = $this->getInfo();
|
121 |
|
@@ -147,7 +147,7 @@ class SimpleLogger
|
|
147 |
* @param array $context
|
148 |
* @param array $row Currently not always passed, because loggers need to be updated to support this...
|
149 |
*/
|
150 |
-
|
151 |
{
|
152 |
if (!is_array($context)) {
|
153 |
return $message;
|
@@ -207,7 +207,7 @@ class SimpleLogger
|
|
207 |
*
|
208 |
* @return string HTML
|
209 |
*/
|
210 |
-
|
211 |
{
|
212 |
// HTML for initiator
|
213 |
$initiator_html = '';
|
@@ -473,21 +473,18 @@ class SimpleLogger
|
|
473 |
$local_date_format = $time_format;
|
474 |
|
475 |
// Show local time as date and hours when event is a bit older.
|
476 |
-
|
477 |
-
$time_current - HOUR_IN_SECONDS * 6 >
|
478 |
$date_datetime->getTimestamp()
|
479 |
) {
|
480 |
$local_date_format = $date_and_time_format;
|
481 |
}
|
482 |
|
483 |
-
|
484 |
-
$time_current - $date_datetime->getTimestamp() <=
|
485 |
$time_ago_just_now_max_time
|
486 |
) {
|
487 |
// Show "just now" if event is very recent.
|
488 |
$str_when = __('Just now', 'simple-history');
|
489 |
-
|
490 |
-
$time_current - $date_datetime->getTimestamp() >
|
491 |
$time_ago_max_time
|
492 |
) {
|
493 |
/* Translators: Date format for log row header, see http://php.net/date */
|
@@ -509,8 +506,8 @@ class SimpleLogger
|
|
509 |
);
|
510 |
}
|
511 |
|
512 |
-
$item_permalink = admin_url('index.php?page=simple_history_page');
|
513 |
-
if (!empty($row->id)) {
|
514 |
$item_permalink .= "#item/{$row->id}";
|
515 |
}
|
516 |
|
@@ -1293,8 +1290,7 @@ class SimpleLogger
|
|
1293 |
} // End if().
|
1294 |
|
1295 |
// Detect XML-RPC calls and append to context, if not already there.
|
1296 |
-
|
1297 |
-
defined('XMLRPC_REQUEST') &&
|
1298 |
XMLRPC_REQUEST &&
|
1299 |
!isset($context['_xmlrpc_request'])
|
1300 |
) {
|
@@ -1386,8 +1382,7 @@ class SimpleLogger
|
|
1386 |
true
|
1387 |
);
|
1388 |
|
1389 |
-
|
1390 |
-
$anonymize_ip_address &&
|
1391 |
function_exists('wp_privacy_anonymize_ip')
|
1392 |
) {
|
1393 |
$remote_addr = wp_privacy_anonymize_ip($remote_addr);
|
@@ -1419,8 +1414,7 @@ class SimpleLogger
|
|
1419 |
// valid, add to context, with loop index appended so we can store many IPs.
|
1420 |
$key_lower = strtolower($key);
|
1421 |
|
1422 |
-
|
1423 |
-
$anonymize_ip_address &&
|
1424 |
function_exists('wp_privacy_anonymize_ip')
|
1425 |
) {
|
1426 |
$ip = wp_privacy_anonymize_ip($ip);
|
@@ -1438,8 +1432,7 @@ class SimpleLogger
|
|
1438 |
} // End if().
|
1439 |
|
1440 |
// Append http referer.
|
1441 |
-
|
1442 |
-
!isset($context['_server_http_referer']) &&
|
1443 |
isset($_SERVER['HTTP_REFERER'])
|
1444 |
) {
|
1445 |
$context['_server_http_referer'] = $_SERVER['HTTP_REFERER'];
|
@@ -1552,7 +1545,7 @@ class SimpleLogger
|
|
1552 |
* @param array $row Row with info.
|
1553 |
* @return array Headers
|
1554 |
*/
|
1555 |
-
|
1556 |
{
|
1557 |
$ip_keys = $this->get_ip_number_header_keys();
|
1558 |
$arr_found_additional_ip_headers = array();
|
@@ -1586,10 +1579,9 @@ class SimpleLogger
|
|
1586 |
* @param string $ip IP number.
|
1587 |
* @return bool
|
1588 |
*/
|
1589 |
-
|
1590 |
{
|
1591 |
-
|
1592 |
-
filter_var(
|
1593 |
$ip,
|
1594 |
FILTER_VALIDATE_IP,
|
1595 |
FILTER_FLAG_IPV4 |
|
@@ -1608,7 +1600,7 @@ class SimpleLogger
|
|
1608 |
* The CSS that you output will only be outputed
|
1609 |
* on pages where Simple History is used.
|
1610 |
*/
|
1611 |
-
|
1612 |
{
|
1613 |
/*
|
1614 |
?>
|
@@ -1626,7 +1618,7 @@ class SimpleLogger
|
|
1626 |
* The JS that you output will only be outputed
|
1627 |
* on pages where Simple History is used.
|
1628 |
*/
|
1629 |
-
|
1630 |
{
|
1631 |
/*
|
1632 |
?>
|
86 |
*
|
87 |
* @return array
|
88 |
*/
|
89 |
+
public function getInfo()
|
90 |
{
|
91 |
$arr_info = array(
|
92 |
// The logger slug. Defaulting to the class name is nice and logical I think
|
115 |
* @since 2.5.4
|
116 |
* @return Mixed
|
117 |
*/
|
118 |
+
public function getInfoValueByKey($key)
|
119 |
{
|
120 |
$arr_info = $this->getInfo();
|
121 |
|
147 |
* @param array $context
|
148 |
* @param array $row Currently not always passed, because loggers need to be updated to support this...
|
149 |
*/
|
150 |
+
public function interpolate($message, $context = array(), $row = null)
|
151 |
{
|
152 |
if (!is_array($context)) {
|
153 |
return $message;
|
207 |
*
|
208 |
* @return string HTML
|
209 |
*/
|
210 |
+
public function getLogRowHeaderOutput($row)
|
211 |
{
|
212 |
// HTML for initiator
|
213 |
$initiator_html = '';
|
473 |
$local_date_format = $time_format;
|
474 |
|
475 |
// Show local time as date and hours when event is a bit older.
|
476 |
+
if ($time_current - HOUR_IN_SECONDS * 6 >
|
|
|
477 |
$date_datetime->getTimestamp()
|
478 |
) {
|
479 |
$local_date_format = $date_and_time_format;
|
480 |
}
|
481 |
|
482 |
+
if ($time_current - $date_datetime->getTimestamp() <=
|
|
|
483 |
$time_ago_just_now_max_time
|
484 |
) {
|
485 |
// Show "just now" if event is very recent.
|
486 |
$str_when = __('Just now', 'simple-history');
|
487 |
+
} elseif ($time_current - $date_datetime->getTimestamp() >
|
|
|
488 |
$time_ago_max_time
|
489 |
) {
|
490 |
/* Translators: Date format for log row header, see http://php.net/date */
|
506 |
);
|
507 |
}
|
508 |
|
509 |
+
$item_permalink = admin_url( apply_filters( 'simple_history/admin_location', 'index' ) . '.php?page=simple_history_page' );
|
510 |
+
if ( ! empty( $row->id ) ) {
|
511 |
$item_permalink .= "#item/{$row->id}";
|
512 |
}
|
513 |
|
1290 |
} // End if().
|
1291 |
|
1292 |
// Detect XML-RPC calls and append to context, if not already there.
|
1293 |
+
if (defined('XMLRPC_REQUEST') &&
|
|
|
1294 |
XMLRPC_REQUEST &&
|
1295 |
!isset($context['_xmlrpc_request'])
|
1296 |
) {
|
1382 |
true
|
1383 |
);
|
1384 |
|
1385 |
+
if ($anonymize_ip_address &&
|
|
|
1386 |
function_exists('wp_privacy_anonymize_ip')
|
1387 |
) {
|
1388 |
$remote_addr = wp_privacy_anonymize_ip($remote_addr);
|
1414 |
// valid, add to context, with loop index appended so we can store many IPs.
|
1415 |
$key_lower = strtolower($key);
|
1416 |
|
1417 |
+
if ($anonymize_ip_address &&
|
|
|
1418 |
function_exists('wp_privacy_anonymize_ip')
|
1419 |
) {
|
1420 |
$ip = wp_privacy_anonymize_ip($ip);
|
1432 |
} // End if().
|
1433 |
|
1434 |
// Append http referer.
|
1435 |
+
if (!isset($context['_server_http_referer']) &&
|
|
|
1436 |
isset($_SERVER['HTTP_REFERER'])
|
1437 |
) {
|
1438 |
$context['_server_http_referer'] = $_SERVER['HTTP_REFERER'];
|
1545 |
* @param array $row Row with info.
|
1546 |
* @return array Headers
|
1547 |
*/
|
1548 |
+
public function get_event_ip_number_headers($row)
|
1549 |
{
|
1550 |
$ip_keys = $this->get_ip_number_header_keys();
|
1551 |
$arr_found_additional_ip_headers = array();
|
1579 |
* @param string $ip IP number.
|
1580 |
* @return bool
|
1581 |
*/
|
1582 |
+
public function validate_ip($ip)
|
1583 |
{
|
1584 |
+
if (filter_var(
|
|
|
1585 |
$ip,
|
1586 |
FILTER_VALIDATE_IP,
|
1587 |
FILTER_FLAG_IPV4 |
|
1600 |
* The CSS that you output will only be outputed
|
1601 |
* on pages where Simple History is used.
|
1602 |
*/
|
1603 |
+
public function adminCSS()
|
1604 |
{
|
1605 |
/*
|
1606 |
?>
|
1618 |
* The JS that you output will only be outputed
|
1619 |
* on pages where Simple History is used.
|
1620 |
*/
|
1621 |
+
public function adminJS()
|
1622 |
{
|
1623 |
/*
|
1624 |
?>
|
loggers/SimpleMediaLogger.php
CHANGED
@@ -1,374 +1,351 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs media uploads
|
7 |
*/
|
8 |
-
class SimpleMediaLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
*/
|
352 |
-
public function filter_rss_item_link( $link, $row ) {
|
353 |
-
|
354 |
-
if ( $row->logger != $this->slug ) {
|
355 |
-
return $link;
|
356 |
-
}
|
357 |
-
|
358 |
-
if ( isset( $row->context['attachment_id'] ) ) {
|
359 |
-
|
360 |
-
$permalink = add_query_arg( array(
|
361 |
-
'action' => 'edit',
|
362 |
-
'post' => $row->context['attachment_id'],
|
363 |
-
), admin_url( 'post.php' ) );
|
364 |
-
|
365 |
-
if ( $permalink ) {
|
366 |
-
$link = $permalink;
|
367 |
-
}
|
368 |
-
}
|
369 |
-
|
370 |
-
return $link;
|
371 |
-
|
372 |
-
}
|
373 |
-
|
374 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs media uploads
|
7 |
*/
|
8 |
+
class SimpleMediaLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
|
12 |
+
public $slug = 'SimpleMediaLogger';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Get array with information about this logger
|
16 |
+
*
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
function getInfo()
|
20 |
+
{
|
21 |
+
|
22 |
+
$arr_info = array(
|
23 |
+
'name' => 'Media/Attachments Logger',
|
24 |
+
'description' => 'Logs media uploads and edits',
|
25 |
+
'capability' => 'edit_pages',
|
26 |
+
'messages' => array(
|
27 |
+
'attachment_created' => __('Created {post_type} "{attachment_title}"', 'simple-history'),
|
28 |
+
'attachment_updated' => __('Edited {post_type} "{attachment_title}"', 'simple-history'),
|
29 |
+
'attachment_deleted' => __('Deleted {post_type} "{attachment_title}" ("{attachment_filename}")', 'simple-history'),
|
30 |
+
),
|
31 |
+
'labels' => array(
|
32 |
+
'search' => array(
|
33 |
+
'label' => _x('Media', 'Media logger: search', 'simple-history'),
|
34 |
+
'label_all' => _x('All media activity', 'Media logger: search', 'simple-history'),
|
35 |
+
'options' => array(
|
36 |
+
_x('Added media', 'Media logger: search', 'simple-history') => array(
|
37 |
+
'attachment_created'
|
38 |
+
),
|
39 |
+
_x('Updated media', 'Media logger: search', 'simple-history') => array(
|
40 |
+
'attachment_updated'
|
41 |
+
),
|
42 |
+
_x('Deleted media', 'Media logger: search', 'simple-history') => array(
|
43 |
+
'attachment_deleted'
|
44 |
+
),
|
45 |
+
),
|
46 |
+
),// end search array
|
47 |
+
),// end labels
|
48 |
+
);
|
49 |
+
|
50 |
+
return $arr_info;
|
51 |
+
}
|
52 |
+
|
53 |
+
public function loaded()
|
54 |
+
{
|
55 |
+
|
56 |
+
add_action('admin_init', array( $this, 'on_admin_init' ));
|
57 |
+
|
58 |
+
add_action('xmlrpc_call_success_mw_newMediaObject', array( $this, 'on_mw_newMediaObject' ), 10, 2);
|
59 |
+
|
60 |
+
add_filter('simple_history/rss_item_link', array( $this, 'filter_rss_item_link' ), 10, 2);
|
61 |
+
}
|
62 |
+
|
63 |
+
function on_admin_init()
|
64 |
+
{
|
65 |
+
|
66 |
+
add_action('add_attachment', array( $this, 'on_add_attachment' ));
|
67 |
+
add_action('edit_attachment', array( $this, 'on_edit_attachment' ));
|
68 |
+
add_action('delete_attachment', array( $this, 'on_delete_attachment' ));
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Filter that fires after a new attachment has been added via the XML-RPC MovableType API.
|
73 |
+
*
|
74 |
+
* @since 2.0.21
|
75 |
+
*
|
76 |
+
* @param int $id ID of the new attachment.
|
77 |
+
* @param array $args An array of arguments to add the attachment.
|
78 |
+
*/
|
79 |
+
function on_mw_newMediaObject($attachment_id, $args)
|
80 |
+
{
|
81 |
+
|
82 |
+
$attachment_post = get_post($attachment_id);
|
83 |
+
$filename = esc_html(wp_basename($attachment_post->guid));
|
84 |
+
$mime = get_post_mime_type($attachment_post);
|
85 |
+
$file = get_attached_file($attachment_id);
|
86 |
+
$file_size = false;
|
87 |
+
|
88 |
+
if (file_exists($file)) {
|
89 |
+
$file_size = filesize($file);
|
90 |
+
}
|
91 |
+
|
92 |
+
$this->infoMessage(
|
93 |
+
'attachment_created',
|
94 |
+
array(
|
95 |
+
'post_type' => get_post_type($attachment_post),
|
96 |
+
'attachment_id' => $attachment_id,
|
97 |
+
'attachment_title' => get_the_title($attachment_post),
|
98 |
+
'attachment_filename' => $filename,
|
99 |
+
'attachment_mime' => $mime,
|
100 |
+
'attachment_filesize' => $file_size,
|
101 |
+
)
|
102 |
+
);
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Modify plain output to inlcude link to post
|
107 |
+
*/
|
108 |
+
public function getLogRowPlainTextOutput($row)
|
109 |
+
{
|
110 |
+
|
111 |
+
$message = $row->message;
|
112 |
+
$context = $row->context;
|
113 |
+
$message_key = $context['_message_key'];
|
114 |
+
|
115 |
+
$attachment_id = $context['attachment_id'];
|
116 |
+
$attachment_post = get_post($attachment_id);
|
117 |
+
$attachment_is_available = is_a($attachment_post, 'WP_Post');
|
118 |
+
|
119 |
+
// Only link to attachment if it is still available
|
120 |
+
if ($attachment_is_available) {
|
121 |
+
if ('attachment_updated' == $message_key) {
|
122 |
+
$message = __('Edited {post_type} <a href="{edit_link}">"{attachment_title}"</a>', 'simple-history');
|
123 |
+
} elseif ('attachment_created' == $message_key) {
|
124 |
+
$message = __('Uploaded {post_type} <a href="{edit_link}">"{attachment_title}"</a>', 'simple-history');
|
125 |
+
}
|
126 |
+
|
127 |
+
$context['post_type'] = esc_html($context['post_type']);
|
128 |
+
$context['attachment_filename'] = esc_html($context['attachment_filename']);
|
129 |
+
$context['edit_link'] = get_edit_post_link($attachment_id);
|
130 |
+
|
131 |
+
$message = $this->interpolate($message, $context, $row);
|
132 |
+
} else {
|
133 |
+
// Attachment post is not available, attachment has probably been deleted
|
134 |
+
$message = parent::getLogRowPlainTextOutput($row);
|
135 |
+
}
|
136 |
+
|
137 |
+
return $message;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Get output for detailed log section
|
142 |
+
*
|
143 |
+
* @param array $row Row.
|
144 |
+
*/
|
145 |
+
function getLogRowDetailsOutput($row)
|
146 |
+
{
|
147 |
+
|
148 |
+
$context = $row->context;
|
149 |
+
$message_key = $context['_message_key'];
|
150 |
+
$output = '';
|
151 |
+
|
152 |
+
$attachment_id = $context['attachment_id'];
|
153 |
+
$attachment_post = get_post($attachment_id);
|
154 |
+
$attachment_is_available = is_a($attachment_post, 'WP_Post');
|
155 |
+
|
156 |
+
if ('attachment_updated' == $message_key) {
|
157 |
+
// Attachment is changed = don't show thumbs and all
|
158 |
+
} elseif ('attachment_deleted' == $message_key) {
|
159 |
+
// Attachment is deleted = don't show thumbs and all
|
160 |
+
} elseif ('attachment_created' == $message_key) {
|
161 |
+
// Attachment is created/uploaded = show details with image thumbnail
|
162 |
+
$attachment_id = $context['attachment_id'];
|
163 |
+
$filetype = wp_check_filetype($context['attachment_filename']);
|
164 |
+
$file_url = wp_get_attachment_url($attachment_id);
|
165 |
+
$edit_link = get_edit_post_link($attachment_id);
|
166 |
+
$attached_file = get_attached_file($attachment_id);
|
167 |
+
$message = '';
|
168 |
+
$full_src = false;
|
169 |
+
|
170 |
+
// Is true if attachment is an image. But for example PDFs can have thumbnail images, but they are not considered to be image.
|
171 |
+
$is_image = wp_attachment_is_image($attachment_id);
|
172 |
+
|
173 |
+
// $message .= $is_image ? "is images yes" : "is image no";
|
174 |
+
$is_video = strpos($filetype['type'], 'video/') !== false;
|
175 |
+
$is_audio = strpos($filetype['type'], 'audio/') !== false;
|
176 |
+
|
177 |
+
$full_image_width = null;
|
178 |
+
$full_image_height = null;
|
179 |
+
|
180 |
+
if ($is_image) {
|
181 |
+
$thumb_src = wp_get_attachment_image_src($attachment_id, 'medium');
|
182 |
+
$full_src = wp_get_attachment_image_src($attachment_id, 'full');
|
183 |
+
|
184 |
+
$full_image_width = $full_src[1];
|
185 |
+
$full_image_height = $full_src[2];
|
186 |
+
|
187 |
+
// is_image is also true for mime types that WP can't create thumbs for
|
188 |
+
// so we need to check that wp got an resized version
|
189 |
+
if ($full_image_width && $full_image_height) {
|
190 |
+
$context['full_image_width'] = $full_image_width;
|
191 |
+
$context['full_image_height'] = $full_image_height;
|
192 |
+
|
193 |
+
// Only output thumb if file exists
|
194 |
+
// For example images deleted on file system but not in WP cause broken images (rare case, but has happened to me.)
|
195 |
+
if (file_exists($attached_file) && $thumb_src) {
|
196 |
+
$context['attachment_thumb'] = sprintf('<div class="SimpleHistoryLogitemThumbnail"><img src="%1$s" alt=""></div>', $thumb_src[0]);
|
197 |
+
}
|
198 |
+
}
|
199 |
+
} elseif ($is_audio) {
|
200 |
+
$content = sprintf('[audio src="%1$s"]', $file_url);
|
201 |
+
$context['attachment_thumb'] = do_shortcode($content);
|
202 |
+
} elseif ($is_video) {
|
203 |
+
$content = sprintf('[video src="%1$s"]', $file_url);
|
204 |
+
$context['attachment_thumb'] = do_shortcode($content);
|
205 |
+
} else {
|
206 |
+
// Use WordPress icon for other media types.
|
207 |
+
if ($attachment_is_available) {
|
208 |
+
$context['attachment_thumb'] = sprintf(
|
209 |
+
'%1$s',
|
210 |
+
wp_get_attachment_image($attachment_id, array( 350, 500 ), true) // Placeholder 1.
|
211 |
+
);
|
212 |
+
}
|
213 |
+
}// End if().
|
214 |
+
|
215 |
+
$context['attachment_size_format'] = size_format($row->context['attachment_filesize']);
|
216 |
+
$context['attachment_filetype_extension'] = strtoupper($filetype['ext']);
|
217 |
+
|
218 |
+
if (! empty($context['attachment_thumb'])) {
|
219 |
+
if ($is_image) {
|
220 |
+
$message .= "<a class='SimpleHistoryLogitemThumbnailLink' href='" . $edit_link . "'>";
|
221 |
+
}
|
222 |
+
|
223 |
+
$message .= __('{attachment_thumb}', 'simple-history');
|
224 |
+
|
225 |
+
if ($is_image) {
|
226 |
+
$message .= '</a>';
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
$message .= "<p class='SimpleHistoryLogitem--logger-SimpleMediaLogger--attachment-meta'>";
|
231 |
+
$message .= "<span class='SimpleHistoryLogitem__inlineDivided'>" . __('{attachment_size_format}', 'simple-history') . '</span> ';
|
232 |
+
$message .= "<span class='SimpleHistoryLogitem__inlineDivided'>" . __('{attachment_filetype_extension}', 'simple-history') . '</span>';
|
233 |
+
|
234 |
+
if ($full_image_width && $full_image_height) {
|
235 |
+
$message .= " <span class='SimpleHistoryLogitem__inlineDivided'>" . __('{full_image_width} × {full_image_height}', 'simple-history') . '</span>';
|
236 |
+
}
|
237 |
+
|
238 |
+
$message .= '</p>';
|
239 |
+
|
240 |
+
$output .= $this->interpolate($message, $context, $row);
|
241 |
+
}// End if().
|
242 |
+
|
243 |
+
return $output;
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Called when an attachment is added
|
248 |
+
*/
|
249 |
+
function on_add_attachment($attachment_id)
|
250 |
+
{
|
251 |
+
|
252 |
+
$attachment_post = get_post($attachment_id);
|
253 |
+
$filename = esc_html(wp_basename($attachment_post->guid));
|
254 |
+
$mime = get_post_mime_type($attachment_post);
|
255 |
+
$file = get_attached_file($attachment_id);
|
256 |
+
$file_size = false;
|
257 |
+
|
258 |
+
if (file_exists($file)) {
|
259 |
+
$file_size = filesize($file);
|
260 |
+
}
|
261 |
+
|
262 |
+
$this->infoMessage(
|
263 |
+
'attachment_created',
|
264 |
+
array(
|
265 |
+
'post_type' => get_post_type($attachment_post),
|
266 |
+
'attachment_id' => $attachment_id,
|
267 |
+
'attachment_title' => get_the_title($attachment_post),
|
268 |
+
'attachment_filename' => $filename,
|
269 |
+
'attachment_mime' => $mime,
|
270 |
+
'attachment_filesize' => $file_size,
|
271 |
+
)
|
272 |
+
);
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* An attachmet is changed
|
277 |
+
* is this only being called if the title of the attachment is changed?!
|
278 |
+
*
|
279 |
+
* @param int $attachment_id
|
280 |
+
*/
|
281 |
+
function on_edit_attachment($attachment_id)
|
282 |
+
{
|
283 |
+
|
284 |
+
$attachment_post = get_post($attachment_id);
|
285 |
+
$filename = esc_html(wp_basename($attachment_post->guid));
|
286 |
+
$mime = get_post_mime_type($attachment_post);
|
287 |
+
$file = get_attached_file($attachment_id);
|
288 |
+
|
289 |
+
$this->infoMessage(
|
290 |
+
'attachment_updated',
|
291 |
+
array(
|
292 |
+
'post_type' => get_post_type($attachment_post),
|
293 |
+
'attachment_id' => $attachment_id,
|
294 |
+
'attachment_title' => get_the_title($attachment_post),
|
295 |
+
'attachment_filename' => $filename,
|
296 |
+
'attachment_mime' => $mime,
|
297 |
+
)
|
298 |
+
);
|
299 |
+
}
|
300 |
+
|
301 |
+
/**
|
302 |
+
* Called when an attachment is deleted
|
303 |
+
*/
|
304 |
+
function on_delete_attachment($attachment_id)
|
305 |
+
{
|
306 |
+
|
307 |
+
$attachment_post = get_post($attachment_id);
|
308 |
+
$filename = esc_html(wp_basename($attachment_post->guid));
|
309 |
+
$mime = get_post_mime_type($attachment_post);
|
310 |
+
$file = get_attached_file($attachment_id);
|
311 |
+
|
312 |
+
$this->infoMessage(
|
313 |
+
'attachment_deleted',
|
314 |
+
array(
|
315 |
+
'post_type' => get_post_type($attachment_post),
|
316 |
+
'attachment_id' => $attachment_id,
|
317 |
+
'attachment_title' => get_the_title($attachment_post),
|
318 |
+
'attachment_filename' => $filename,
|
319 |
+
'attachment_mime' => $mime,
|
320 |
+
)
|
321 |
+
);
|
322 |
+
}
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Modify RSS links so they go directly to the correct media in wp admin
|
326 |
+
*
|
327 |
+
* @since 2.0.23
|
328 |
+
* @param string $link
|
329 |
+
* @param array $row
|
330 |
+
*/
|
331 |
+
public function filter_rss_item_link($link, $row)
|
332 |
+
{
|
333 |
+
|
334 |
+
if ($row->logger != $this->slug) {
|
335 |
+
return $link;
|
336 |
+
}
|
337 |
+
|
338 |
+
if (isset($row->context['attachment_id'])) {
|
339 |
+
$permalink = add_query_arg(array(
|
340 |
+
'action' => 'edit',
|
341 |
+
'post' => $row->context['attachment_id'],
|
342 |
+
), admin_url('post.php'));
|
343 |
+
|
344 |
+
if ($permalink) {
|
345 |
+
$link = $permalink;
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
return $link;
|
350 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
}
|
loggers/SimpleMenuLogger.php
CHANGED
@@ -1,378 +1,377 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress menu edits
|
7 |
*/
|
8 |
-
class SimpleMenuLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
}
|
378 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress menu edits
|
7 |
*/
|
8 |
+
class SimpleMenuLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
|
12 |
+
public $slug = __CLASS__;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Get array with information about this logger
|
16 |
+
*
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
function getInfo()
|
20 |
+
{
|
21 |
+
|
22 |
+
$arr_info = array(
|
23 |
+
'name' => 'Menu Logger',
|
24 |
+
'description' => 'Logs menu edits',
|
25 |
+
'capability' => 'edit_theme_options',
|
26 |
+
'messages' => array(
|
27 |
+
'created_menu' => __('Created menu "{menu_name}"', 'simple-history'),
|
28 |
+
'edited_menu' => __('Edited menu "{menu_name}"', 'simple-history'),
|
29 |
+
'deleted_menu' => __('Deleted menu "{menu_name}"', 'simple-history'),
|
30 |
+
'edited_menu_item' => __('Edited a menu item', 'simple-history'),
|
31 |
+
'edited_menu_locations' => __('Updated menu locations', 'simple-history'),
|
32 |
+
),
|
33 |
+
'labels' => array(
|
34 |
+
'search' => array(
|
35 |
+
'label' => _x('Menus', 'Menu logger: search', 'simple-history'),
|
36 |
+
'label_all' => _x('All menu activity', 'Menu updates logger: search', 'simple-history'),
|
37 |
+
'options' => array(
|
38 |
+
_x('Created menus', 'Menu updates logger: search', 'simple-history') => array(
|
39 |
+
'created_menu'
|
40 |
+
),
|
41 |
+
_x('Edited menus', 'Menu updates logger: search', 'simple-history') => array(
|
42 |
+
'edited_menu',
|
43 |
+
'edited_menu_item',
|
44 |
+
'edited_menu_locations',
|
45 |
+
),
|
46 |
+
_x('Deleted menus', 'Menu updates logger: search', 'simple-history') => array(
|
47 |
+
'deleted_menu'
|
48 |
+
),
|
49 |
+
),
|
50 |
+
),// end search array
|
51 |
+
),// end labels
|
52 |
+
);
|
53 |
+
|
54 |
+
return $arr_info;
|
55 |
+
}
|
56 |
+
|
57 |
+
function loaded()
|
58 |
+
{
|
59 |
+
|
60 |
+
/*
|
61 |
+
* Fires after a navigation menu has been successfully deleted.
|
62 |
+
*
|
63 |
+
* @since 3.0.0
|
64 |
+
*
|
65 |
+
* @param int $term_id ID of the deleted menu.
|
66 |
+
do_action( 'wp_delete_nav_menu', $menu->term_id );
|
67 |
+
*/
|
68 |
+
// add_action("wp_delete_nav_menu", array($this, "on_wp_delete_nav_menu"), 10, 1 );
|
69 |
+
add_action('load-nav-menus.php', array( $this, 'on_load_nav_menus_page_detect_delete' ));
|
70 |
+
|
71 |
+
/*
|
72 |
+
* Fires after a navigation menu is successfully created.
|
73 |
+
*
|
74 |
+
* @since 3.0.0
|
75 |
+
*
|
76 |
+
* @param int $term_id ID of the new menu.
|
77 |
+
* @param array $menu_data An array of menu data.
|
78 |
+
do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data );
|
79 |
+
*/
|
80 |
+
add_action('wp_create_nav_menu', array( $this, 'on_wp_create_nav_menu' ), 10, 2);
|
81 |
+
|
82 |
+
/*
|
83 |
+
* Fires after a navigation menu item has been updated.
|
84 |
+
*
|
85 |
+
* @since 3.0.0
|
86 |
+
*
|
87 |
+
* @see wp_update_nav_menu_items()
|
88 |
+
*
|
89 |
+
* @param int $menu_id ID of the updated menu.
|
90 |
+
* @param int $menu_item_db_id ID of the updated menu item.
|
91 |
+
* @param array $args An array of arguments used to update a menu item.
|
92 |
+
do_action( 'wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args );
|
93 |
+
*/
|
94 |
+
|
95 |
+
// This is fired when adding nav items in the editor, not at save, so not
|
96 |
+
// good to log because user might not end up saving the changes
|
97 |
+
// add_action("wp_update_nav_menu_item", array($this, "on_wp_update_nav_menu_item"), 10, 3 );
|
98 |
+
// Fired before "wp_update_nav_menu" below, to remember menu layput before it's updated
|
99 |
+
// so we can't detect changes
|
100 |
+
add_action('load-nav-menus.php', array( $this, 'on_load_nav_menus_page_detect_update' ));
|
101 |
+
|
102 |
+
/*
|
103 |
+
* Fires after a navigation menu has been successfully updated.
|
104 |
+
*
|
105 |
+
* @since 3.0.0
|
106 |
+
*
|
107 |
+
* @param int $menu_id ID of the updated menu.
|
108 |
+
* @param array $menu_data An array of menu data.
|
109 |
+
do_action( 'wp_update_nav_menu', $menu_id, $menu_data );
|
110 |
+
*/
|
111 |
+
// add_action("wp_update_nav_menu", array($this, "on_wp_update_nav_menu"), 10, 2 );
|
112 |
+
// Detect meny location change in "manage locations"
|
113 |
+
add_action('load-nav-menus.php', array( $this, 'on_load_nav_menus_page_detect_locations_update' ));
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Can't use action "wp_delete_nav_menu" beacuse
|
118 |
+
* it's fired after menu is deleted, so we don't have the name in this action
|
119 |
+
*/
|
120 |
+
function on_load_nav_menus_page_detect_delete()
|
121 |
+
{
|
122 |
+
|
123 |
+
/*
|
124 |
+
http://playground-root.ep/wp-admin/nav-menus.php?menu=22&action=delete&0=http%3A%2F%2Fplayground-root.ep%2Fwp-admin%2F&_wpnonce=f52e8a31ba
|
125 |
+
$_REQUEST:
|
126 |
+
Array
|
127 |
+
(
|
128 |
+
[menu] => 22
|
129 |
+
[action] => delete
|
130 |
+
[0] => http://playground-root.ep/wp-admin/
|
131 |
+
[_wpnonce] => f52e8a31ba
|
132 |
+
)
|
133 |
+
*/
|
134 |
+
|
135 |
+
// Check that needed vars are set
|
136 |
+
if (! isset($_REQUEST['menu'], $_REQUEST['action'])) {
|
137 |
+
return;
|
138 |
+
}
|
139 |
+
|
140 |
+
if ('delete' !== $_REQUEST['action']) {
|
141 |
+
return;
|
142 |
+
}
|
143 |
+
|
144 |
+
$menu_id = $_REQUEST['menu'];
|
145 |
+
if (! is_nav_menu($menu_id)) {
|
146 |
+
return;
|
147 |
+
}
|
148 |
+
|
149 |
+
$menu = wp_get_nav_menu_object($menu_id);
|
150 |
+
|
151 |
+
$this->infoMessage(
|
152 |
+
'deleted_menu',
|
153 |
+
array(
|
154 |
+
'menu_term_id' => $menu_id,
|
155 |
+
'menu_name' => $menu->name,
|
156 |
+
)
|
157 |
+
);
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Fired after menu is deleted, so we don't have the name in this action
|
162 |
+
* So that's why we can't use this only
|
163 |
+
*/
|
164 |
+
/*
|
165 |
+
function on_wp_delete_nav_menu($menu_term_id) {
|
166 |
+
|
167 |
+
$this->infoMessage(
|
168 |
+
"deleted_menu",
|
169 |
+
array(
|
170 |
+
"menu_term_id" => $menu_term_id,
|
171 |
+
"menu" => print_r($menu, true),
|
172 |
+
"request" => print_r($_REQUEST, true),
|
173 |
+
)
|
174 |
+
);
|
175 |
+
|
176 |
+
}
|
177 |
+
*/
|
178 |
+
|
179 |
+
function on_wp_create_nav_menu($term_id, $menu_data)
|
180 |
+
{
|
181 |
+
|
182 |
+
$menu = wp_get_nav_menu_object($term_id);
|
183 |
+
|
184 |
+
if (! $menu) {
|
185 |
+
return;
|
186 |
+
}
|
187 |
+
|
188 |
+
$this->infoMessage(
|
189 |
+
'created_menu',
|
190 |
+
array(
|
191 |
+
'term_id' => $term_id,
|
192 |
+
'menu_name' => $menu->name,
|
193 |
+
)
|
194 |
+
);
|
195 |
+
}
|
196 |
+
|
197 |
+
/*
|
198 |
+
function on_wp_update_nav_menu_item($menu_id, $menu_item_db_id, $args) {
|
199 |
+
|
200 |
+
$this->infoMessage(
|
201 |
+
"edited_menu_item",
|
202 |
+
array(
|
203 |
+
"menu_id" => $menu_id,
|
204 |
+
"menu_item_db_id" => $menu_item_db_id,
|
205 |
+
"args" => $this->simpleHistory->json_encode($args),
|
206 |
+
"request" => $this->simpleHistory->json_encode($_REQUEST)
|
207 |
+
)
|
208 |
+
);
|
209 |
+
|
210 |
+
}
|
211 |
+
*/
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Detect menu being saved
|
215 |
+
*/
|
216 |
+
function on_load_nav_menus_page_detect_update()
|
217 |
+
{
|
218 |
+
|
219 |
+
/*
|
220 |
+
This is the data to be saved
|
221 |
+
$_REQUEST:
|
222 |
+
Array
|
223 |
+
(
|
224 |
+
[action] => update
|
225 |
+
[menu] => 25
|
226 |
+
[menu-name] => Main menu edit
|
227 |
+
[menu-item-title] => Array
|
228 |
+
(
|
229 |
+
[25243] => My new page edited
|
230 |
+
[25244] => My new page
|
231 |
+
[25245] => This is my new page. How does it look in the logs? <h1>Hej!</h1>
|
232 |
+
[25264] => This page have revisions
|
233 |
+
[25265] => Lorem ipsum dolor sit amet
|
234 |
+
)
|
235 |
+
[menu-locations] => Array
|
236 |
+
(
|
237 |
+
[primary] => 25
|
238 |
+
)
|
239 |
+
)
|
240 |
+
*/
|
241 |
+
|
242 |
+
// Check that needed vars are set
|
243 |
+
if (! isset($_REQUEST['menu'], $_REQUEST['action'], $_REQUEST['menu-name'])) {
|
244 |
+
return;
|
245 |
+
}
|
246 |
+
|
247 |
+
// Only go on for update action
|
248 |
+
if ('update' !== $_REQUEST['action']) {
|
249 |
+
return;
|
250 |
+
}
|
251 |
+
|
252 |
+
// Make sure we got the id of a menu
|
253 |
+
$menu_id = $_REQUEST['menu'];
|
254 |
+
if (! is_nav_menu($menu_id)) {
|
255 |
+
return;
|
256 |
+
}
|
257 |
+
|
258 |
+
// Get saved menu. May be empty if this is the first time we save the menu
|
259 |
+
$arr_prev_menu_items = wp_get_nav_menu_items($menu_id);
|
260 |
+
|
261 |
+
// Compare new items to be saved with old version
|
262 |
+
$old_ids = wp_list_pluck($arr_prev_menu_items, 'db_id');
|
263 |
+
$new_ids = array_values(isset($_POST['menu-item-db-id']) ? $_POST['menu-item-db-id'] : array());
|
264 |
+
|
265 |
+
// Get ids of added and removed post ids
|
266 |
+
$arr_removed = array_diff($old_ids, $new_ids);
|
267 |
+
$arr_added = array_diff($new_ids, $old_ids);
|
268 |
+
|
269 |
+
// Get old version location
|
270 |
+
// $prev_menu = wp_get_nav_menu_object( $menu_id );
|
271 |
+
// $locations = get_registered_nav_menus();
|
272 |
+
// $menu_locations = get_nav_menu_locations();
|
273 |
+
$this->infoMessage(
|
274 |
+
'edited_menu',
|
275 |
+
array(
|
276 |
+
'menu_id' => $menu_id,
|
277 |
+
'menu_name' => $_POST['menu-name'],
|
278 |
+
'menu_items_added' => sizeof($arr_added),
|
279 |
+
'menu_items_removed' => sizeof($arr_removed),
|
280 |
+
// "request" => $this->simpleHistory->json_encode($_REQUEST)
|
281 |
+
)
|
282 |
+
);
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* This seems to get called twice
|
287 |
+
* one time with menu_data, a second without
|
288 |
+
*/
|
289 |
+
/*
|
290 |
+
function on_wp_update_nav_menu($menu_id, $menu_data = array()) {
|
291 |
+
|
292 |
+
if (empty($menu_data)) {
|
293 |
+
return;
|
294 |
+
}
|
295 |
+
|
296 |
+
$this->infoMessage(
|
297 |
+
"edited_menu",
|
298 |
+
array(
|
299 |
+
"menu_id" => $menu_id,
|
300 |
+
"menu_name" => $menu_data["menu-name"],
|
301 |
+
"menu_data" => $this->simpleHistory->json_encode($menu_data),
|
302 |
+
"request" => $this->simpleHistory->json_encode($_REQUEST)
|
303 |
+
)
|
304 |
+
);
|
305 |
+
|
306 |
+
}
|
307 |
+
*/
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Get detailed output
|
311 |
+
*/
|
312 |
+
function getLogRowDetailsOutput($row)
|
313 |
+
{
|
314 |
+
|
315 |
+
$context = $row->context;
|
316 |
+
$message_key = $context['_message_key'];
|
317 |
+
$output = '';
|
318 |
+
|
319 |
+
if ('edited_menu' == $message_key) {
|
320 |
+
if (! empty($context['menu_items_added']) || ! empty($context['menu_items_removed'])) {
|
321 |
+
$output .= '<p>';
|
322 |
+
|
323 |
+
$output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
|
324 |
+
$output .= sprintf(
|
325 |
+
_nx('%1$s menu item added', '%1$s menu items added', $context['menu_items_added'], 'menu logger', 'simple-history'),
|
326 |
+
esc_attr($context['menu_items_added'])
|
327 |
+
);
|
328 |
+
$output .= '</span> ';
|
329 |
+
|
330 |
+
$output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
|
331 |
+
$output .= sprintf(
|
332 |
+
_nx('%1$s menu item removed', '%1$s menu items removed', $context['menu_items_removed'], 'menu logger', 'simple-history'),
|
333 |
+
esc_attr($context['menu_items_removed'])
|
334 |
+
);
|
335 |
+
$output .= '</span> ';
|
336 |
+
|
337 |
+
$output .= '</p>';
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
return $output;
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Log updates to theme menu locations
|
346 |
+
*/
|
347 |
+
function on_load_nav_menus_page_detect_locations_update()
|
348 |
+
{
|
349 |
+
|
350 |
+
// Check that needed vars are set
|
351 |
+
if (! isset($_REQUEST['menu'], $_REQUEST['action'])) {
|
352 |
+
return;
|
353 |
+
}
|
354 |
+
|
355 |
+
if ('locations' !== $_REQUEST['action']) {
|
356 |
+
return;
|
357 |
+
}
|
358 |
+
|
359 |
+
/*
|
360 |
+
Array
|
361 |
+
(
|
362 |
+
[menu-locations] => Array
|
363 |
+
(
|
364 |
+
[primary] => 25
|
365 |
+
)
|
366 |
+
)
|
367 |
+
*/
|
368 |
+
$menu_locations = $_POST['menu-locations'];
|
369 |
+
|
370 |
+
$this->infoMessage(
|
371 |
+
'edited_menu_locations',
|
372 |
+
array(
|
373 |
+
'menu_locations' => $this->simpleHistory->json_encode($menu_locations),
|
374 |
+
)
|
375 |
+
);
|
376 |
+
}
|
|
|
377 |
}
|
loggers/SimpleOptionsLogger.php
CHANGED
@@ -1,498 +1,464 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs changes to wordpress options
|
7 |
*/
|
8 |
-
class SimpleOptionsLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
$tmpl_row = '
|
201 |
<tr>
|
202 |
<td>%1$s</td>
|
203 |
<td>%2$s</td>
|
204 |
</tr>
|
205 |
';
|
206 |
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
} // End if().
|
257 |
-
|
258 |
-
// If key option_page this was saved from regular settings pages
|
259 |
-
if ( ! empty( $option_page ) ) {
|
260 |
-
|
261 |
-
$output .= sprintf(
|
262 |
-
'
|
263 |
<tr>
|
264 |
<td>%1$s</td>
|
265 |
<td><a href="%3$s">%2$s</a></td>
|
266 |
</tr>
|
267 |
',
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
$output .= sprintf(
|
279 |
-
'
|
280 |
<tr>
|
281 |
<td>%1$s</td>
|
282 |
<td><a href="%3$s">%2$s</a></td>
|
283 |
</tr>
|
284 |
',
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
if ( $new_category_name ) {
|
477 |
-
|
478 |
-
$output .= sprintf(
|
479 |
-
$tmpl_row,
|
480 |
-
__( 'New value', 'simple-history' ),
|
481 |
-
esc_html( $new_category_name )
|
482 |
-
);
|
483 |
-
|
484 |
-
}
|
485 |
-
|
486 |
-
return $output;
|
487 |
-
|
488 |
-
}
|
489 |
-
|
490 |
-
function get_details_output_for_option_default_email_category( $context, $old_value, $new_value, $option, $option_page, $tmpl_row ) {
|
491 |
-
|
492 |
-
$output = call_user_func_array( array( $this, 'get_details_output_for_option_default_category' ), func_get_args() );
|
493 |
-
|
494 |
-
return $output;
|
495 |
-
|
496 |
-
}
|
497 |
-
|
498 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') or die();
|
4 |
|
5 |
/**
|
6 |
* Logs changes to wordpress options
|
7 |
*/
|
8 |
+
class SimpleOptionsLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
|
12 |
+
public $slug = __CLASS__;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Get array with information about this logger
|
16 |
+
*
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
function getInfo()
|
20 |
+
{
|
21 |
+
|
22 |
+
$arr_info = array(
|
23 |
+
'name' => 'Options Logger',
|
24 |
+
'description' => 'Logs updates to WordPress settings',
|
25 |
+
'capability' => 'manage_options',
|
26 |
+
'messages' => array(
|
27 |
+
// 'option_updated' => __('Updated option "{option}" on settings page "{option_page}"', "simple-history"),
|
28 |
+
'option_updated' => __('Updated option "{option}"', 'simple-history'),
|
29 |
+
/*
|
30 |
+
Updated option "default_comment_status" on settings page "discussion"
|
31 |
+
Edited option "default_comment_status" on settings page "discussion"
|
32 |
+
Modified option "default_comment_status" on settings page "discussion"
|
33 |
+
|
34 |
+
Edited settings page "discussion" and the "default_comment_status" options
|
35 |
+
|
36 |
+
*/
|
37 |
+
),
|
38 |
+
'labels' => array(
|
39 |
+
'search' => array(
|
40 |
+
'label' => _x('Options', 'Options logger: search', 'simple-history'),
|
41 |
+
'options' => array(
|
42 |
+
_x('Changed options', 'Options logger: search', 'simple-history') => array(
|
43 |
+
'option_updated'
|
44 |
+
),
|
45 |
+
),
|
46 |
+
),// end search array
|
47 |
+
),// end labels
|
48 |
+
);
|
49 |
+
|
50 |
+
return $arr_info;
|
51 |
+
}
|
52 |
+
|
53 |
+
function loaded()
|
54 |
+
{
|
55 |
+
|
56 |
+
add_action('updated_option', array( $this, 'on_updated_option' ), 10, 3);
|
57 |
+
}
|
58 |
+
|
59 |
+
function on_updated_option($option, $old_value, $new_value)
|
60 |
+
{
|
61 |
+
|
62 |
+
if (empty($_SERVER['REQUEST_URI'])) {
|
63 |
+
return;
|
64 |
+
}
|
65 |
+
|
66 |
+
$arr_option_pages = array(
|
67 |
+
0 => 'options.php',
|
68 |
+
1 => 'options-permalink.php',
|
69 |
+
);
|
70 |
+
|
71 |
+
// We only want to log options being added via pages in $arr_option_pages
|
72 |
+
if (! in_array(basename($_SERVER['REQUEST_URI']), $arr_option_pages) || basename(dirname($_SERVER['REQUEST_URI'])) !== 'wp-admin') {
|
73 |
+
return;
|
74 |
+
}
|
75 |
+
|
76 |
+
// Also only if "option_page" is set to one of these "built in" ones
|
77 |
+
// We don't wanna start loging things from other plugins, like EDD
|
78 |
+
$option_page = isset($_REQUEST['option_page']) ? $_REQUEST['option_page'] : ''; // general | discussion | ...
|
79 |
+
|
80 |
+
$arr_valid_option_pages = array(
|
81 |
+
'general',
|
82 |
+
'discussion',
|
83 |
+
'media',
|
84 |
+
'reading',
|
85 |
+
'writing',
|
86 |
+
);
|
87 |
+
|
88 |
+
$is_valid_options_page = $option_page && in_array($option_page, $arr_valid_option_pages);
|
89 |
+
|
90 |
+
// Permalink settings page does not post any "option_page", so use http referer instead
|
91 |
+
if (strpos($_SERVER['REQUEST_URI'], 'options-permalink.php') !== false) {
|
92 |
+
$is_valid_options_page = true;
|
93 |
+
$options_page = 'permalink';
|
94 |
+
}
|
95 |
+
|
96 |
+
if (! $is_valid_options_page) {
|
97 |
+
return;
|
98 |
+
}
|
99 |
+
|
100 |
+
// Check if option name is ok
|
101 |
+
// For example if you change front page displays setting the "rewrite_rules" options gets updated too
|
102 |
+
$arr_invalid_option_names = array(
|
103 |
+
'rewrite_rules'
|
104 |
+
);
|
105 |
+
|
106 |
+
if (in_array($option, $arr_invalid_option_names)) {
|
107 |
+
return;
|
108 |
+
}
|
109 |
+
|
110 |
+
$context = array(
|
111 |
+
'option' => $option,
|
112 |
+
'old_value' => $old_value,
|
113 |
+
'new_value' => $new_value,
|
114 |
+
'option_page' => $option_page,
|
115 |
+
// 'referer' => wp_get_referer(),
|
116 |
+
// 'REQUEST_URI' => $_SERVER['REQUEST_URI'],
|
117 |
+
// '$_REQUEST' => print_r($_REQUEST, true),
|
118 |
+
);
|
119 |
+
|
120 |
+
// Store a bit more about some options
|
121 |
+
// Like "page_on_front" we also store post title
|
122 |
+
// Check for a method for current option in this class and calls it automagically
|
123 |
+
$methodname = "add_context_for_option_{$option}";
|
124 |
+
if (method_exists($this, $methodname)) {
|
125 |
+
$context = $this->$methodname($context, $old_value, $new_value, $option, $option_page);
|
126 |
+
}
|
127 |
+
|
128 |
+
$this->infoMessage('option_updated', $context);
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Give some options better plain text output
|
133 |
+
*
|
134 |
+
* Not doing anything at the moment, because it was really difficaly to give them meaningful text values
|
135 |
+
*/
|
136 |
+
public function getLogRowPlainTextOutput($row)
|
137 |
+
{
|
138 |
+
|
139 |
+
$message = $row->message;
|
140 |
+
$context = $row->context;
|
141 |
+
$message_key = $context['_message_key'];
|
142 |
+
|
143 |
+
$return_message = '';
|
144 |
+
|
145 |
+
// Only link to attachment if it is still available
|
146 |
+
if ('option_updated' == $message_key) {
|
147 |
+
/*
|
148 |
+
$option = isset( $context["option"] ) ? $context["option"] : null;
|
149 |
+
$option_page = isset( $context["option_page"] ) ? $context["option_page"] : null;
|
150 |
+
$new_value = isset( $context["new_value"] ) ? $context["new_value"] : null;
|
151 |
+
$old_value = isset( $context["old_value"] ) ? $context["old_value"] : null;
|
152 |
+
|
153 |
+
# $return_message = "";
|
154 |
+
$arr_options_to_translate = array(
|
155 |
+
"$option_page/blog_public" => array(
|
156 |
+
"text" => "Updated setting Search Engine Visibility"
|
157 |
+
),
|
158 |
+
"$option_page/rss_use_excerpt" => array(
|
159 |
+
"text" => "Updated setting For each article in a feed, show"
|
160 |
+
),
|
161 |
+
"$option_page/posts_per_rss" => array(
|
162 |
+
"text" => "Updated setting for Syndication feeds show the most recent"
|
163 |
+
),
|
164 |
+
"$option_page/posts_per_page" => array(
|
165 |
+
"text" => "Updated setting for Blog pages show at most"
|
166 |
+
)
|
167 |
+
);
|
168 |
+
|
169 |
+
if ( isset( $arr_options_to_translate[ "{$option_page}/{$option}" ] ) ) {
|
170 |
+
$return_message = $arr_options_to_translate[ "{$option_page}/{$option}" ]["text"];
|
171 |
+
}
|
172 |
+
*/
|
173 |
+
}
|
174 |
+
|
175 |
+
if (empty($return_message)) {
|
176 |
+
// No specific text to output, fallback to default
|
177 |
+
$return_message = parent::getLogRowPlainTextOutput($row);
|
178 |
+
}
|
179 |
+
|
180 |
+
return $return_message;
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Get detailed output
|
185 |
+
*/
|
186 |
+
function getLogRowDetailsOutput($row)
|
187 |
+
{
|
188 |
+
|
189 |
+
$context = $row->context;
|
190 |
+
$message_key = $context['_message_key'];
|
191 |
+
$output = '';
|
192 |
+
|
193 |
+
$option = isset($context['option']) ? $context['option'] : null;
|
194 |
+
$option_page = isset($context['option_page']) ? $context['option_page'] : null;
|
195 |
+
$new_value = isset($context['new_value']) ? $context['new_value'] : null;
|
196 |
+
$old_value = isset($context['old_value']) ? $context['old_value'] : null;
|
197 |
+
|
198 |
+
$tmpl_row = '
|
|
|
|
|
199 |
<tr>
|
200 |
<td>%1$s</td>
|
201 |
<td>%2$s</td>
|
202 |
</tr>
|
203 |
';
|
204 |
|
205 |
+
if ('option_updated' == $message_key) {
|
206 |
+
// $message = 'Old value was {old_value} and new value is {new_value}';
|
207 |
+
$output .= "<table class='SimpleHistoryLogitem__keyValueTable'>";
|
208 |
+
|
209 |
+
// Output old and new values
|
210 |
+
if ($context['new_value'] || $context['old_value']) {
|
211 |
+
$option_custom_output = '';
|
212 |
+
$methodname = "get_details_output_for_option_{$option}";
|
213 |
+
|
214 |
+
if (method_exists($this, $methodname)) {
|
215 |
+
$option_custom_output = $this->$methodname($context, $old_value, $new_value, $option, $option_page, $tmpl_row);
|
216 |
+
}
|
217 |
+
|
218 |
+
if (empty($option_custom_output)) {
|
219 |
+
// all other options or fallback if custom output did not find all it's stuff
|
220 |
+
$more = __('…');
|
221 |
+
$trim_length = 250;
|
222 |
+
|
223 |
+
$trimmed_new_value = substr($new_value, 0, $trim_length);
|
224 |
+
$trimmed_old_value = substr($old_value, 0, $trim_length);
|
225 |
+
|
226 |
+
if (strlen($new_value) > $trim_length) {
|
227 |
+
$trimmed_new_value .= $more;
|
228 |
+
}
|
229 |
+
|
230 |
+
if (strlen($old_value) > $trim_length) {
|
231 |
+
$trimmed_old_value .= $more;
|
232 |
+
}
|
233 |
+
|
234 |
+
$output .= sprintf(
|
235 |
+
$tmpl_row,
|
236 |
+
__('New value', 'simple-history'),
|
237 |
+
esc_html($trimmed_new_value)
|
238 |
+
);
|
239 |
+
|
240 |
+
$output .= sprintf(
|
241 |
+
$tmpl_row,
|
242 |
+
__('Old value', 'simple-history'),
|
243 |
+
esc_html($trimmed_old_value)
|
244 |
+
);
|
245 |
+
} else {
|
246 |
+
$output .= $option_custom_output;
|
247 |
+
}
|
248 |
+
} // End if().
|
249 |
+
|
250 |
+
// If key option_page this was saved from regular settings pages
|
251 |
+
if (! empty($option_page)) {
|
252 |
+
$output .= sprintf(
|
253 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
<tr>
|
255 |
<td>%1$s</td>
|
256 |
<td><a href="%3$s">%2$s</a></td>
|
257 |
</tr>
|
258 |
',
|
259 |
+
__('Settings page', 'simple-history'),
|
260 |
+
esc_html($context['option_page']),
|
261 |
+
admin_url("options-{$option_page}.php")
|
262 |
+
);
|
263 |
+
}
|
264 |
+
|
265 |
+
// If option = permalink_structure then we did it from permalink page
|
266 |
+
if (! empty($option) && ( 'permalink_structure' == $option || 'tag_base' == $option || 'category_base' == $option )) {
|
267 |
+
$output .= sprintf(
|
268 |
+
'
|
|
|
|
|
269 |
<tr>
|
270 |
<td>%1$s</td>
|
271 |
<td><a href="%3$s">%2$s</a></td>
|
272 |
</tr>
|
273 |
',
|
274 |
+
__('Settings page', 'simple-history'),
|
275 |
+
'permalink',
|
276 |
+
admin_url('options-permalink.php')
|
277 |
+
);
|
278 |
+
}
|
279 |
+
|
280 |
+
$output .= '</table>';
|
281 |
+
}// End if().
|
282 |
+
|
283 |
+
return $output;
|
284 |
+
}
|
285 |
+
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Page on front = "Front page displays" -> Your latest posts / A static page
|
289 |
+
* value 0 = Your latest post
|
290 |
+
* value int n = A static page
|
291 |
+
*/
|
292 |
+
function add_context_for_option_page_on_front($context, $old_value, $new_value, $option, $option_page)
|
293 |
+
{
|
294 |
+
|
295 |
+
if (! empty($old_value) && is_numeric($old_value)) {
|
296 |
+
$old_post = get_post($old_value);
|
297 |
+
|
298 |
+
if ($old_post) {
|
299 |
+
$context['old_post_title'] = $old_post->post_title;
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
if (! empty($new_value) && is_numeric($new_value)) {
|
304 |
+
$new_post = get_post($new_value);
|
305 |
+
|
306 |
+
if ($new_post) {
|
307 |
+
$context['new_post_title'] = $new_post->post_title;
|
308 |
+
}
|
309 |
+
}
|
310 |
+
|
311 |
+
return $context;
|
312 |
+
}
|
313 |
+
|
314 |
+
function add_context_for_option_page_for_posts($context, $old_value, $new_value, $option, $option_page)
|
315 |
+
{
|
316 |
+
|
317 |
+
// Get same info as for page_on_front
|
318 |
+
$context = call_user_func_array(array( $this, 'add_context_for_option_page_on_front' ), func_get_args());
|
319 |
+
|
320 |
+
return $context;
|
321 |
+
}
|
322 |
+
|
323 |
+
function get_details_output_for_option_page_for_posts($context, $old_value, $new_value, $option, $option_page)
|
324 |
+
{
|
325 |
+
|
326 |
+
$output = call_user_func_array(array( $this, 'get_details_output_for_option_page_on_front' ), func_get_args());
|
327 |
+
|
328 |
+
return $output;
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Add detailed output for page_on_front
|
333 |
+
*
|
334 |
+
* @return string output
|
335 |
+
*/
|
336 |
+
function get_details_output_for_option_page_on_front($context, $old_value, $new_value, $option, $option_page, $tmpl_row)
|
337 |
+
{
|
338 |
+
|
339 |
+
$output = '';
|
340 |
+
|
341 |
+
if ($new_value && ! empty($context['new_post_title'])) {
|
342 |
+
$post_title_with_link = '';
|
343 |
+
|
344 |
+
if (get_post_status($new_value)) {
|
345 |
+
$post_title_with_link = sprintf('<a href="%1$s">%2$s</a>', get_edit_post_link($new_value), esc_html($context['new_post_title']));
|
346 |
+
} else {
|
347 |
+
$post_title_with_link = esc_html($context['new_post_title']);
|
348 |
+
}
|
349 |
+
|
350 |
+
$output .= sprintf(
|
351 |
+
$tmpl_row,
|
352 |
+
__('New value', 'simple-history'),
|
353 |
+
sprintf(__('Page %1$s', 'simple-history'), $post_title_with_link)
|
354 |
+
);
|
355 |
+
}
|
356 |
+
if (intval($new_value) == 0) {
|
357 |
+
$output .= sprintf(
|
358 |
+
$tmpl_row,
|
359 |
+
__('New value', 'simple-history'),
|
360 |
+
__('Your latests posts', 'simple-history')
|
361 |
+
);
|
362 |
+
}
|
363 |
+
|
364 |
+
if ($old_value && ! empty($context['old_post_title'])) {
|
365 |
+
$post_title_with_link = '';
|
366 |
+
|
367 |
+
if (get_post_status($old_value)) {
|
368 |
+
$post_title_with_link = sprintf('<a href="%1$s">%2$s</a>', get_edit_post_link($old_value), esc_html($context['old_post_title']));
|
369 |
+
} else {
|
370 |
+
$post_title_with_link = esc_html($context['old_post_title']);
|
371 |
+
}
|
372 |
+
|
373 |
+
$output .= sprintf(
|
374 |
+
$tmpl_row,
|
375 |
+
__('Old value', 'simple-history'),
|
376 |
+
sprintf(__('Page %1$s', 'simple-history'), $post_title_with_link)
|
377 |
+
);
|
378 |
+
}
|
379 |
+
|
380 |
+
if (intval($old_value) == 0) {
|
381 |
+
$output .= sprintf(
|
382 |
+
$tmpl_row,
|
383 |
+
__('Old value', 'simple-history'),
|
384 |
+
__('Your latests posts', 'simple-history')
|
385 |
+
);
|
386 |
+
}
|
387 |
+
|
388 |
+
return $output;
|
389 |
+
} // custom output page_on_front
|
390 |
+
|
391 |
+
|
392 |
+
/**
|
393 |
+
* "default_category" = Writing Settings » Default Post Category
|
394 |
+
*/
|
395 |
+
function add_context_for_option_default_category($context, $old_value, $new_value, $option, $option_page)
|
396 |
+
{
|
397 |
+
|
398 |
+
if (! empty($old_value) && is_numeric($old_value)) {
|
399 |
+
$old_category_name = get_the_category_by_ID($old_value);
|
400 |
+
|
401 |
+
if (! is_wp_error($old_category_name)) {
|
402 |
+
$context['old_category_name'] = $old_category_name;
|
403 |
+
}
|
404 |
+
}
|
405 |
+
|
406 |
+
if (! empty($new_value) && is_numeric($new_value)) {
|
407 |
+
$new_category_name = get_the_category_by_ID($new_value);
|
408 |
+
|
409 |
+
if (! is_wp_error($new_category_name)) {
|
410 |
+
$context['new_category_name'] = $new_category_name;
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
return $context;
|
415 |
+
}
|
416 |
+
|
417 |
+
function add_context_for_option_default_email_category($context, $old_value, $new_value, $option, $option_page)
|
418 |
+
{
|
419 |
+
|
420 |
+
$context = call_user_func_array(array( $this, 'add_context_for_option_default_category' ), func_get_args());
|
421 |
+
|
422 |
+
return $context;
|
423 |
+
}
|
424 |
+
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Add detailed output for default_category
|
428 |
+
*
|
429 |
+
* @return string output
|
430 |
+
*/
|
431 |
+
function get_details_output_for_option_default_category($context, $old_value, $new_value, $option, $option_page, $tmpl_row)
|
432 |
+
{
|
433 |
+
|
434 |
+
$old_category_name = isset($context['old_category_name']) ? $context['old_category_name'] : null;
|
435 |
+
$new_category_name = isset($context['new_category_name']) ? $context['new_category_name'] : null;
|
436 |
+
$output = '';
|
437 |
+
|
438 |
+
if ($old_category_name) {
|
439 |
+
$output .= sprintf(
|
440 |
+
$tmpl_row,
|
441 |
+
__('Old value', 'simple-history'),
|
442 |
+
esc_html($old_category_name)
|
443 |
+
);
|
444 |
+
}
|
445 |
+
|
446 |
+
if ($new_category_name) {
|
447 |
+
$output .= sprintf(
|
448 |
+
$tmpl_row,
|
449 |
+
__('New value', 'simple-history'),
|
450 |
+
esc_html($new_category_name)
|
451 |
+
);
|
452 |
+
}
|
453 |
+
|
454 |
+
return $output;
|
455 |
+
}
|
456 |
+
|
457 |
+
function get_details_output_for_option_default_email_category($context, $old_value, $new_value, $option, $option_page, $tmpl_row)
|
458 |
+
{
|
459 |
+
|
460 |
+
$output = call_user_func_array(array( $this, 'get_details_output_for_option_default_category' ), func_get_args());
|
461 |
+
|
462 |
+
return $output;
|
463 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
464 |
}
|
loggers/SimplePluginLogger.php
CHANGED
@@ -1,351 +1,359 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined(
|
4 |
|
5 |
/**
|
6 |
* Logs plugin installs, updates, and deletions.
|
7 |
*/
|
8 |
-
class SimplePluginLogger extends SimpleLogger
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
349 |
<!doctype html>
|
350 |
<style>
|
351 |
body {
|
@@ -381,835 +389,791 @@ class SimplePluginLogger extends SimpleLogger {
|
|
381 |
%2$s
|
382 |
</div>
|
383 |
',
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
// $desc_output = esc_html( sprintf( __('%1$s (uploaded ZIP archive)', "simple-history"), $plugin_upload_name ) );
|
1087 |
-
} else {
|
1088 |
-
$desc_output = esc_html( $context[ $key ] );
|
1089 |
-
}
|
1090 |
-
|
1091 |
-
break;
|
1092 |
-
|
1093 |
-
case 'plugin_install_source_file':
|
1094 |
-
if ( ! isset( $context['plugin_upload_name'] ) || ! isset( $context['plugin_install_source'] ) ) {
|
1095 |
-
break;
|
1096 |
-
}
|
1097 |
-
|
1098 |
-
if ( 'upload' == $context['plugin_install_source'] ) {
|
1099 |
-
$plugin_upload_name = $context['plugin_upload_name'];
|
1100 |
-
$desc_output = esc_html( $plugin_upload_name );
|
1101 |
-
}
|
1102 |
-
|
1103 |
-
break;
|
1104 |
-
|
1105 |
-
default:
|
1106 |
-
$desc_output = esc_html( $context[ $key ] );
|
1107 |
-
break;
|
1108 |
-
}// End switch().
|
1109 |
-
|
1110 |
-
if ( ! trim( $desc_output ) ) {
|
1111 |
-
continue;
|
1112 |
-
}
|
1113 |
-
|
1114 |
-
$output .= sprintf(
|
1115 |
-
'
|
1116 |
<tr>
|
1117 |
<td>%1$s</td>
|
1118 |
<td>%2$s</td>
|
1119 |
</tr>
|
1120 |
',
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
$output .= sprintf(
|
1137 |
-
'
|
1138 |
<tr>
|
1139 |
<td></td>
|
1140 |
<td><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></td>
|
1141 |
</tr>
|
1142 |
',
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
$output .= sprintf(
|
1154 |
-
'
|
1155 |
<tr>
|
1156 |
<td></td>
|
1157 |
<td><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></td>
|
1158 |
</tr>
|
1159 |
',
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
$link_title
|
1193 |
-
);
|
1194 |
-
|
1195 |
-
} elseif ( ! empty( $context['plugin_github_url'] ) ) {
|
1196 |
-
|
1197 |
-
$output .= sprintf(
|
1198 |
-
'
|
1199 |
<tr>
|
1200 |
<td></td>
|
1201 |
<td><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></td>
|
1202 |
</tr>
|
1203 |
',
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
} // getLogRowDetailsOutput
|
1214 |
-
|
1215 |
} // class SimplePluginLogger
|
1 |
<?php
|
2 |
|
3 |
+
defined('ABSPATH') || die();
|
4 |
|
5 |
/**
|
6 |
* Logs plugin installs, updates, and deletions.
|
7 |
*/
|
8 |
+
class SimplePluginLogger extends SimpleLogger
|
9 |
+
{
|
10 |
+
|
11 |
+
/**
|
12 |
+
* The logger slug. Defaulting to the class name is nice and logical I think.
|
13 |
+
*
|
14 |
+
* @var string $slug
|
15 |
+
*/
|
16 |
+
public $slug = __CLASS__;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* This variable is set if a plugins has been disabled due to an error,
|
20 |
+
* like when the plugin file does not exist. We need to store this in this
|
21 |
+
* weird way because there is no other way for us to get the reason.
|
22 |
+
*
|
23 |
+
* @var string $latest_plugin_deactivation_because_of_error_reason
|
24 |
+
*/
|
25 |
+
public $latest_plugin_deactivation_because_of_error_reason = array();
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Get array with information about this logger
|
29 |
+
*
|
30 |
+
* @return array
|
31 |
+
*/
|
32 |
+
public function getInfo()
|
33 |
+
{
|
34 |
+
|
35 |
+
$arr_info = array(
|
36 |
+
'name' => 'Plugin Logger',
|
37 |
+
'description' => 'Logs plugin installs, uninstalls and updates',
|
38 |
+
'capability' => 'activate_plugins',
|
39 |
+
'messages' => array(
|
40 |
+
|
41 |
+
'plugin_activated' => _x(
|
42 |
+
'Activated plugin "{plugin_name}"',
|
43 |
+
'Plugin was non-silently activated by a user',
|
44 |
+
'simple-history'
|
45 |
+
),
|
46 |
+
|
47 |
+
'plugin_deactivated' => _x(
|
48 |
+
'Deactivated plugin "{plugin_name}"',
|
49 |
+
'Plugin was non-silently deactivated by a user',
|
50 |
+
'simple-history'
|
51 |
+
),
|
52 |
+
|
53 |
+
'plugin_installed' => _x(
|
54 |
+
'Installed plugin "{plugin_name}"',
|
55 |
+
'Plugin was installed',
|
56 |
+
'simple-history'
|
57 |
+
),
|
58 |
+
|
59 |
+
'plugin_installed_failed' => _x(
|
60 |
+
'Failed to install plugin "{plugin_name}"',
|
61 |
+
'Plugin failed to install',
|
62 |
+
'simple-history'
|
63 |
+
),
|
64 |
+
|
65 |
+
'plugin_updated' => _x(
|
66 |
+
'Updated plugin "{plugin_name}" to version {plugin_version} from {plugin_prev_version}',
|
67 |
+
'Plugin was updated',
|
68 |
+
'simple-history'
|
69 |
+
),
|
70 |
+
|
71 |
+
'plugin_update_failed' => _x(
|
72 |
+
'Failed to update plugin "{plugin_name}"',
|
73 |
+
'Plugin update failed',
|
74 |
+
'simple-history'
|
75 |
+
),
|
76 |
+
|
77 |
+
'plugin_deleted' => _x(
|
78 |
+
'Deleted plugin "{plugin_name}"',
|
79 |
+
'Plugin files was deleted',
|
80 |
+
'simple-history'
|
81 |
+
),
|
82 |
+
|
83 |
+
// Bulk versions.
|
84 |
+
'plugin_bulk_updated' => _x(
|
85 |
+
'Updated plugin "{plugin_name}" to {plugin_version} from {plugin_prev_version}',
|
86 |
+
'Plugin was updated in bulk',
|
87 |
+
'simple-history'
|
88 |
+
),
|
89 |
+
|
90 |
+
// Plugin disabled due to some error.
|
91 |
+
'plugin_disabled_because_error' => _x(
|
92 |
+
'Deactivated plugin "{plugin_slug}" because of an error ("{deactivation_reason}").',
|
93 |
+
'Plugin was disabled because of an error',
|
94 |
+
'simple-history'
|
95 |
+
),
|
96 |
+
|
97 |
+
), // Messages.
|
98 |
+
'labels' => array(
|
99 |
+
'search' => array(
|
100 |
+
'label' => _x('Plugins', 'Plugin logger: search', 'simple-history'),
|
101 |
+
'label_all' => _x('All plugin activity', 'Plugin logger: search', 'simple-history'),
|
102 |
+
'options' => array(
|
103 |
+
_x('Activated plugins', 'Plugin logger: search', 'simple-history') => array(
|
104 |
+
'plugin_activated',
|
105 |
+
),
|
106 |
+
_x('Deactivated plugins', 'Plugin logger: search', 'simple-history') => array(
|
107 |
+
'plugin_deactivated',
|
108 |
+
'plugin_disabled_because_error',
|
109 |
+
),
|
110 |
+
_x('Installed plugins', 'Plugin logger: search', 'simple-history') => array(
|
111 |
+
'plugin_installed',
|
112 |
+
),
|
113 |
+
_x('Failed plugin installs', 'Plugin logger: search', 'simple-history') => array(
|
114 |
+
'plugin_installed_failed',
|
115 |
+
),
|
116 |
+
_x('Updated plugins', 'Plugin logger: search', 'simple-history') => array(
|
117 |
+
'plugin_updated',
|
118 |
+
'plugin_bulk_updated',
|
119 |
+
),
|
120 |
+
_x('Failed plugin updates', 'Plugin logger: search', 'simple-history') => array(
|
121 |
+
'plugin_update_failed',
|
122 |
+
),
|
123 |
+
_x('Deleted plugins', 'Plugin logger: search', 'simple-history') => array(
|
124 |
+
'plugin_deleted',
|
125 |
+
),
|
126 |
+
),
|
127 |
+
), // search array.
|
128 |
+
), // labels.
|
129 |
+
);
|
130 |
+
|
131 |
+
return $arr_info;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Plugin loaded
|
136 |
+
*/
|
137 |
+
public function loaded()
|
138 |
+
{
|
139 |
+
|
140 |
+
/**
|
141 |
+
* At least the plugin bulk upgrades fires this action before upgrade
|
142 |
+
* We use it to fetch the current version of all plugins, before they are upgraded
|
143 |
+
*/
|
144 |
+
add_filter('upgrader_pre_install', array( $this, 'save_versions_before_update' ), 10, 2);
|
145 |
+
|
146 |
+
// Clear our transient after an update is done
|
147 |
+
// Removed because something probably changed in core and this was fired earlier than it used to be
|
148 |
+
// add_action( 'delete_site_transient_update_plugins', array( $this, "remove_saved_versions" ) );
|
149 |
+
// Fires after a plugin has been activated.
|
150 |
+
// If a plugin is silently activated (such as during an update),
|
151 |
+
// this hook does not fire.
|
152 |
+
add_action('activated_plugin', array( $this, 'on_activated_plugin' ), 10, 2);
|
153 |
+
|
154 |
+
// Fires after a plugin is deactivated.
|
155 |
+
// If a plugin is silently deactivated (such as during an update),
|
156 |
+
// this hook does not fire.
|
157 |
+
add_action('deactivated_plugin', array( $this, 'on_deactivated_plugin' ), 10, 2);
|
158 |
+
|
159 |
+
// Fires after the upgrades has done it's thing.
|
160 |
+
// Check hook extra for upgrader initiator.
|
161 |
+
add_action('upgrader_process_complete', array( $this, 'on_upgrader_process_complete' ), 10, 2);
|
162 |
+
|
163 |
+
// Detect files removed.
|
164 |
+
add_action('setted_transient', array( $this, 'on_setted_transient_for_remove_files' ), 10, 2);
|
165 |
+
|
166 |
+
add_action('admin_action_delete-selected', array( $this, 'on_action_delete_selected' ), 10, 1);
|
167 |
+
|
168 |
+
// Ajax function to get info from GitHub repo. Used by "View plugin info"-link for plugin installs.
|
169 |
+
add_action('wp_ajax_SimplePluginLogger_GetGitHubPluginInfo', array( $this, 'ajax_GetGitHubPluginInfo' ));
|
170 |
+
|
171 |
+
// If the Github Update plugin is not installed we need to get extra fields used by it.
|
172 |
+
// So need to hook filter "extra_plugin_headers" ourself.
|
173 |
+
add_filter(
|
174 |
+
'extra_plugin_headers',
|
175 |
+
function ($arr_headers) {
|
176 |
+
$arr_headers[] = 'GitHub Plugin URI';
|
177 |
+
return $arr_headers;
|
178 |
+
}
|
179 |
+
);
|
180 |
+
|
181 |
+
// There is no way to use a filter and detect a plugin that is disabled because it can't be found or similar error.
|
182 |
+
// So we hook into gettext and look for the usage of the error that is returned when this happens.
|
183 |
+
add_filter('gettext', array( $this, 'on_gettext_detect_plugin_error_deactivation_reason' ), 10, 3);
|
184 |
+
add_filter('gettext', array( $this, 'on_gettext' ), 10, 3);
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Things
|
189 |
+
*
|
190 |
+
* @param string $translation Translation.
|
191 |
+
* @param string $text Text.
|
192 |
+
* @param string $domain Domin.
|
193 |
+
*/
|
194 |
+
function on_gettext_detect_plugin_error_deactivation_reason($translation, $text, $domain)
|
195 |
+
{
|
196 |
+
|
197 |
+
global $pagenow;
|
198 |
+
|
199 |
+
// We only act on page plugins.php.
|
200 |
+
if (! isset($pagenow) || 'plugins.php' !== $pagenow) {
|
201 |
+
return $translation;
|
202 |
+
}
|
203 |
+
|
204 |
+
// We only act if the untranslated text is among the following ones
|
205 |
+
// (Literally these, no translation).
|
206 |
+
$untranslated_texts = array(
|
207 |
+
'Plugin file does not exist.',
|
208 |
+
'Invalid plugin path.',
|
209 |
+
'The plugin does not have a valid header.',
|
210 |
+
);
|
211 |
+
|
212 |
+
if (! in_array($text, $untranslated_texts, true)) {
|
213 |
+
return $translation;
|
214 |
+
}
|
215 |
+
|
216 |
+
// Text was among our wanted texts.
|
217 |
+
switch ($text) {
|
218 |
+
case 'Plugin file does not exist.':
|
219 |
+
$this->latest_plugin_deactivation_because_of_error_reason[] = 'file_does_not_exist';
|
220 |
+
break;
|
221 |
+
case 'Invalid plugin path.':
|
222 |
+
$this->latest_plugin_deactivation_because_of_error_reason[] = 'invalid_path';
|
223 |
+
break;
|
224 |
+
case 'The plugin does not have a valid header.':
|
225 |
+
$this->latest_plugin_deactivation_because_of_error_reason[] = 'no_valid_header';
|
226 |
+
break;
|
227 |
+
}
|
228 |
+
|
229 |
+
return $translation;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* There is no way to use a filter and detect a plugin that is disabled because it can't be found or similar error.
|
234 |
+
* we hook into gettext and look for the usage of the error that is returned when this happens.
|
235 |
+
*
|
236 |
+
* A plugin gets deactivated when plugins.php is visited function validate_active_plugins()
|
237 |
+
* return new WP_Error('plugin_not_found', __('Plugin file does not exist.'));
|
238 |
+
* and if invalid plugin is found then this is outputed
|
239 |
+
* printf(
|
240 |
+
* /* translators: 1: plugin file 2: error message
|
241 |
+
* __( 'The plugin %1$s has been <strong>deactivated</strong> due to an error: %2$s' ),
|
242 |
+
* '<code>' . esc_html( $plugin_file ) . '</code>',
|
243 |
+
* $error->get_error_message() );
|
244 |
+
*
|
245 |
+
* @param string $translation Translation.
|
246 |
+
* @param string $text Text.
|
247 |
+
* @param string $domain Domin.
|
248 |
+
*/
|
249 |
+
function on_gettext($translation, $text, $domain)
|
250 |
+
{
|
251 |
+
|
252 |
+
global $pagenow;
|
253 |
+
|
254 |
+
// We only act on page plugins.php.
|
255 |
+
if (! isset($pagenow) || 'plugins.php' !== $pagenow) {
|
256 |
+
return $translation;
|
257 |
+
}
|
258 |
+
|
259 |
+
// We only act if the untranslated text is among the following ones
|
260 |
+
// (Literally these, no translation)
|
261 |
+
$untranslated_texts = array(
|
262 |
+
// This string is called later than the above
|
263 |
+
'The plugin %1$s has been <strong>deactivated</strong> due to an error: %2$s',
|
264 |
+
);
|
265 |
+
|
266 |
+
if (! in_array($text, $untranslated_texts)) {
|
267 |
+
return $translation;
|
268 |
+
}
|
269 |
+
|
270 |
+
// Directly after the string is translated 'esc_html' is called with the plugin name.
|
271 |
+
// This is one of the few ways we can get the name of the plugin.
|
272 |
+
// The esc_html filter is used pretty much but we make sure we only do our.
|
273 |
+
// stuff the first time it's called (directly after the gettet for the plugin disabled-error..).
|
274 |
+
$logger_instance = $this;
|
275 |
+
|
276 |
+
add_filter(
|
277 |
+
'esc_html',
|
278 |
+
function ($safe_text, $text) use ($logger_instance) {
|
279 |
+
static $is_called = false;
|
280 |
+
|
281 |
+
if (false === $is_called) {
|
282 |
+
$is_called = true;
|
283 |
+
|
284 |
+
$deactivation_reason = array_shift($logger_instance->latest_plugin_deactivation_because_of_error_reason);
|
285 |
+
|
286 |
+
// We don't know what plugin that was that got this error and currently there does not seem to be a way to determine that.
|
287 |
+
// So that's why we use such generic log messages.
|
288 |
+
$logger_instance->warningMessage(
|
289 |
+
'plugin_disabled_because_error',
|
290 |
+
array(
|
291 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
292 |
+
'plugin_slug' => $text,
|
293 |
+
'deactivation_reason' => $deactivation_reason,
|
294 |
+
)
|
295 |
+
);
|
296 |
+
}
|
297 |
+
|
298 |
+
return $safe_text;
|
299 |
+
},
|
300 |
+
10,
|
301 |
+
2
|
302 |
+
);
|
303 |
+
|
304 |
+
return $translation;
|
305 |
+
} // on_gettext
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Show readme from github in a modal win
|
309 |
+
*/
|
310 |
+
function ajax_GetGitHubPluginInfo()
|
311 |
+
{
|
312 |
+
|
313 |
+
if (! current_user_can('install_plugins')) {
|
314 |
+
wp_die(__("You don't have access to this page.", 'simple-history'));
|
315 |
+
}
|
316 |
+
|
317 |
+
$repo = isset($_GET['repo']) ? (string) $_GET['repo'] : '';
|
318 |
+
|
319 |
+
if (! $repo) {
|
320 |
+
wp_die(__('Could not find GitHub repository.', 'simple-history'));
|
321 |
+
}
|
322 |
+
|
323 |
+
$repo_parts = explode('/', rtrim($repo, '/'));
|
324 |
+
if (count($repo_parts) !== 5) {
|
325 |
+
wp_die(__('Could not find GitHub repository.', 'simple-history'));
|
326 |
+
}
|
327 |
+
|
328 |
+
$repo_username = $repo_parts[3];
|
329 |
+
$repo_repo = $repo_parts[4];
|
330 |
+
|
331 |
+
// https://developer.github.com/v3/repos/contents/
|
332 |
+
// https://api.github.com/repos/<username>/<repo>/readme
|
333 |
+
$api_url = sprintf('https://api.github.com/repos/%1$s/%2$s/readme', urlencode($repo_username), urlencode($repo_repo));
|
334 |
+
|
335 |
+
// Get file. Use accept-header to get file as HTML instead of JSON
|
336 |
+
$response = wp_remote_get(
|
337 |
+
$api_url,
|
338 |
+
array(
|
339 |
+
'headers' => array(
|
340 |
+
'accept' => 'application/vnd.github.VERSION.html',
|
341 |
+
),
|
342 |
+
)
|
343 |
+
);
|
344 |
+
|
345 |
+
$response_body = wp_remote_retrieve_body($response);
|
346 |
+
|
347 |
+
$repo_info = '<p>' . sprintf(
|
348 |
+
__('Viewing <code>readme</code> from repository <code><a target="_blank" href="%1$s">%2$s</a></code>.', 'simple-history'),
|
349 |
+
esc_url($repo),
|
350 |
+
esc_html($repo)
|
351 |
+
) . '</p>';
|
352 |
+
|
353 |
+
$github_markdown_css_path = SIMPLE_HISTORY_PATH . '/css/github-markdown.css';
|
354 |
+
|
355 |
+
printf(
|
356 |
+
'
|
357 |
<!doctype html>
|
358 |
<style>
|
359 |
body {
|
389 |
%2$s
|
390 |
</div>
|
391 |
',
|
392 |
+
$repo_info,
|
393 |
+
$response_body,
|
394 |
+
$github_markdown_css_path,
|
395 |
+
esc_url($repo) // 4
|
396 |
+
);
|
397 |
+
|
398 |
+
// echo($response_body);
|
399 |
+
exit;
|
400 |
+
}
|
401 |
+
|
402 |
+
/*
|
403 |
+
* When a plugin has been deleted there is no way for us to get
|
404 |
+
* the real name of the plugin, only the dir and main index file.
|
405 |
+
* So before a plugin is deleted we save all needed info in a transient
|
406 |
+
*/
|
407 |
+
function on_action_delete_selected()
|
408 |
+
{
|
409 |
+
|
410 |
+
// Same as in plugins.php
|
411 |
+
if (! current_user_can('delete_plugins')) {
|
412 |
+
wp_die(__('You do not have sufficient permissions to delete plugins for this site.'));
|
413 |
+
}
|
414 |
+
|
415 |
+
// Verify delete must be set
|
416 |
+
if (! isset($_POST['verify-delete']) || ! $_POST['verify-delete']) {
|
417 |
+
return;
|
418 |
+
}
|
419 |
+
|
420 |
+
// An arr of plugins must be set
|
421 |
+
if (! isset($_POST['checked']) || ! is_array($_POST['checked'])) {
|
422 |
+
return;
|
423 |
+
}
|
424 |
+
|
425 |
+
// If we get this far it looks like a plugin is begin deleted
|
426 |
+
// Get and save info about it
|
427 |
+
$this->save_versions_before_update();
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Saves info about all installed plugins to an option.
|
432 |
+
* When we are done logging then we remove the option.
|
433 |
+
*/
|
434 |
+
function save_versions_before_update($bool = null, $hook_extra = null)
|
435 |
+
{
|
436 |
+
|
437 |
+
$plugins = get_plugins();
|
438 |
+
|
439 |
+
// does not work
|
440 |
+
$option_name = $this->slug . '_plugin_info_before_update';
|
441 |
+
|
442 |
+
$r = update_option($option_name, SimpleHistory::json_encode($plugins));
|
443 |
+
|
444 |
+
return $bool;
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* Detect plugin being deleted
|
449 |
+
* When WP is done deleting a plugin it sets a transient called plugins_delete_result:
|
450 |
+
* set_transient('plugins_delete_result_' . $user_ID, $delete_result);
|
451 |
+
*
|
452 |
+
* We detect when that transient is set and then we have all info needed to log the plugin delete
|
453 |
+
*/
|
454 |
+
public function on_setted_transient_for_remove_files($transient = '', $value = '')
|
455 |
+
{
|
456 |
+
|
457 |
+
if (! $user_id = get_current_user_id()) {
|
458 |
+
return;
|
459 |
+
}
|
460 |
+
|
461 |
+
$transient_name = '_transient_plugins_delete_result_' . $user_id;
|
462 |
+
if ($transient_name !== $transient) {
|
463 |
+
return;
|
464 |
+
}
|
465 |
+
|
466 |
+
// We found the transient we were looking for
|
467 |
+
if (isset($_POST['action'])
|
468 |
+
&& 'delete-selected' == $_POST['action']
|
469 |
+
&& isset($_POST['checked'])
|
470 |
+
&& is_array($_POST['checked'])
|
471 |
+
) {
|
472 |
+
/*
|
473 |
+
[checked] => Array
|
474 |
+
(
|
475 |
+
[0] => the-events-calendar/the-events-calendar.php
|
476 |
+
)
|
477 |
+
*/
|
478 |
+
|
479 |
+
$plugins_deleted = $_POST['checked'];
|
480 |
+
$plugins_before_update = json_decode(get_option($this->slug . '_plugin_info_before_update', false), true);
|
481 |
+
|
482 |
+
foreach ($plugins_deleted as $plugin) {
|
483 |
+
$context = array(
|
484 |
+
'plugin' => $plugin, // plugin-name-folder/plugin-main-file.php
|
485 |
+
);
|
486 |
+
|
487 |
+
if (is_array($plugins_before_update) && isset($plugins_before_update[ $plugin ])) {
|
488 |
+
$context['plugin_name'] = $plugins_before_update[ $plugin ]['Name'];
|
489 |
+
$context['plugin_title'] = $plugins_before_update[ $plugin ]['Title'];
|
490 |
+
$context['plugin_description'] = $plugins_before_update[ $plugin ]['Description'];
|
491 |
+
$context['plugin_author'] = $plugins_before_update[ $plugin ]['Author'];
|
492 |
+
$context['plugin_version'] = $plugins_before_update[ $plugin ]['Version'];
|
493 |
+
$context['plugin_url'] = $plugins_before_update[ $plugin ]['PluginURI'];
|
494 |
+
}
|
495 |
+
|
496 |
+
$this->infoMessage(
|
497 |
+
'plugin_deleted',
|
498 |
+
$context
|
499 |
+
);
|
500 |
+
}
|
501 |
+
}
|
502 |
+
|
503 |
+
$this->remove_saved_versions();
|
504 |
+
}
|
505 |
+
|
506 |
+
/**
|
507 |
+
* Save all plugin information before a plugin is updated or removed.
|
508 |
+
* This way we can know both the old (pre updated/removed) and the current version of the plugin
|
509 |
+
*/
|
510 |
+
/*
|
511 |
+
public function save_versions_before_update() {
|
512 |
+
|
513 |
+
$current_screen = get_current_screen();
|
514 |
+
$request_uri = $_SERVER["SCRIPT_NAME"];
|
515 |
+
|
516 |
+
// Only add option on pages where needed
|
517 |
+
$do_store = false;
|
518 |
+
|
519 |
+
if (
|
520 |
+
SimpleHistory::ends_with( $request_uri, "/wp-admin/update.php" )
|
521 |
+
&& isset( $current_screen->base )
|
522 |
+
&& "update" == $current_screen->base
|
523 |
+
) {
|
524 |
+
|
525 |
+
// Plugin update screen
|
526 |
+
$do_store = true;
|
527 |
+
|
528 |
+
} else if (
|
529 |
+
SimpleHistory::ends_with( $request_uri, "/wp-admin/plugins.php" )
|
530 |
+
&& isset( $current_screen->base )
|
531 |
+
&& "plugins" == $current_screen->base
|
532 |
+
&& ( isset( $_POST["action"] ) && "delete-selected" == $_POST["action"] )
|
533 |
+
) {
|
534 |
+
|
535 |
+
// Plugin delete screen, during delete
|
536 |
+
$do_store = true;
|
537 |
+
|
538 |
+
}
|
539 |
+
|
540 |
+
if ( $do_store ) {
|
541 |
+
update_option( $this->slug . "_plugin_info_before_update", SimpleHistory::json_encode( get_plugins() ) );
|
542 |
+
}
|
543 |
+
|
544 |
+
}
|
545 |
+
*/
|
546 |
+
|
547 |
+
/**
|
548 |
+
* when plugin updates are done wp_clean_plugins_cache() is called,
|
549 |
+
* which in its turn run:
|
550 |
+
* delete_site_transient( 'update_plugins' );
|
551 |
+
* do_action( 'delete_site_transient_' . $transient, $transient );
|
552 |
+
* delete_site_transient_update_plugins
|
553 |
+
*/
|
554 |
+
public function remove_saved_versions()
|
555 |
+
{
|
556 |
+
|
557 |
+
delete_option($this->slug . '_plugin_info_before_update');
|
558 |
+
}
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Called when plugins is updated or installed
|
562 |
+
* Called from class-wp-upgrader.php
|
563 |
+
*
|
564 |
+
* @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might
|
565 |
+
* be a Theme_Upgrader or Core_Upgrade instance.
|
566 |
+
* @param array $data {
|
567 |
+
* Array of bulk item update data.
|
568 |
+
*/
|
569 |
+
function on_upgrader_process_complete($plugin_upgrader_instance, $arr_data)
|
570 |
+
{
|
571 |
+
|
572 |
+
// Can't use get_plugins() here to get version of plugins updated from
|
573 |
+
// Tested that, and it will get the new version (and that's the correct answer I guess. but too bad for us..)
|
574 |
+
/*
|
575 |
+
If an update fails then $plugin_upgrader_instance->skin->result->errors contains something like:
|
576 |
+
Array
|
577 |
+
(
|
578 |
+
[remove_old_failed] => Array
|
579 |
+
(
|
580 |
+
[0] => Could not remove the old plugin.
|
581 |
+
)
|
582 |
+
|
583 |
+
)
|
584 |
+
*/
|
585 |
+
|
586 |
+
/*
|
587 |
+
# Contents of $arr_data in different scenarios
|
588 |
+
|
589 |
+
## WordPress core update
|
590 |
+
|
591 |
+
$arr_data:
|
592 |
+
Array
|
593 |
+
(
|
594 |
+
[action] => update
|
595 |
+
[type] => core
|
596 |
+
)
|
597 |
+
|
598 |
+
|
599 |
+
# Plugin install
|
600 |
+
|
601 |
+
$arr_data:
|
602 |
+
Array
|
603 |
+
(
|
604 |
+
[type] => plugin
|
605 |
+
[action] => install
|
606 |
+
)
|
607 |
+
|
608 |
+
|
609 |
+
## Plugin update
|
610 |
+
|
611 |
+
$arr_data:
|
612 |
+
Array
|
613 |
+
(
|
614 |
+
[type] => plugin
|
615 |
+
[action] => install
|
616 |
+
)
|
617 |
+
|
618 |
+
## Bulk actions
|
619 |
+
|
620 |
+
array(
|
621 |
+
'action' => 'update',
|
622 |
+
'type' => 'plugin',
|
623 |
+
'bulk' => true,
|
624 |
+
'plugins' => $plugins,
|
625 |
+
)
|
626 |
+
|
627 |
+
*/
|
628 |
+
|
629 |
+
// To keep track of if something was logged, so wen can output debug info only
|
630 |
+
// only if we did not log anything
|
631 |
+
$did_log = false;
|
632 |
+
|
633 |
+
if (isset($arr_data['type']) && 'plugin' == $arr_data['type']) {
|
634 |
+
// Single plugin install
|
635 |
+
if (isset($arr_data['action']) && 'install' == $arr_data['action'] && ! $plugin_upgrader_instance->bulk) {
|
636 |
+
$upgrader_skin_options = isset($plugin_upgrader_instance->skin->options) && is_array($plugin_upgrader_instance->skin->options) ? $plugin_upgrader_instance->skin->options : array();
|
637 |
+
$upgrader_skin_result = isset($plugin_upgrader_instance->skin->result) && is_array($plugin_upgrader_instance->skin->result) ? $plugin_upgrader_instance->skin->result : array();
|
638 |
+
$upgrader_skin_api = isset($plugin_upgrader_instance->skin->api) ? $plugin_upgrader_instance->skin->api : (object) array();
|
639 |
+
|
640 |
+
$plugin_slug = isset($upgrader_skin_result['destination_name']) ? $upgrader_skin_result['destination_name'] : '';
|
641 |
+
|
642 |
+
// Upgrader contains current info
|
643 |
+
$context = array(
|
644 |
+
'plugin_slug' => $plugin_slug,
|
645 |
+
'plugin_name' => isset($upgrader_skin_api->name) ? $upgrader_skin_api->name : '',
|
646 |
+
'plugin_version' => isset($upgrader_skin_api->version) ? $upgrader_skin_api->version : '',
|
647 |
+
'plugin_author' => isset($upgrader_skin_api->author) ? $upgrader_skin_api->author : '',
|
648 |
+
'plugin_last_updated' => isset($upgrader_skin_api->last_updated) ? $upgrader_skin_api->last_updated : '',
|
649 |
+
'plugin_requires' => isset($upgrader_skin_api->requires) ? $upgrader_skin_api->requires : '',
|
650 |
+
'plugin_tested' => isset($upgrader_skin_api->tested) ? $upgrader_skin_api->tested : '',
|
651 |
+
'plugin_rating' => isset($upgrader_skin_api->rating) ? $upgrader_skin_api->rating : '',
|
652 |
+
'plugin_num_ratings' => isset($upgrader_skin_api->num_ratings) ? $upgrader_skin_api->num_ratings : '',
|
653 |
+
'plugin_downloaded' => isset($upgrader_skin_api->downloaded) ? $upgrader_skin_api->downloaded : '',
|
654 |
+
'plugin_added' => isset($upgrader_skin_api->added) ? $upgrader_skin_api->added : '',
|
655 |
+
'plugin_source_files' => $this->simpleHistory->json_encode($plugin_upgrader_instance->result['source_files']),
|
656 |
+
|
657 |
+
// To debug comment out these:
|
658 |
+
// "debug_skin_options" => $this->simpleHistory->json_encode( $upgrader_skin_options ),
|
659 |
+
// "debug_skin_result" => $this->simpleHistory->json_encode( $upgrader_skin_result ),
|
660 |
+
);
|
661 |
+
|
662 |
+
/*
|
663 |
+
Detect install plugin from wordpress.org
|
664 |
+
- options[type] = "web"
|
665 |
+
- options[api] contains all we need
|
666 |
+
|
667 |
+
Detect install from upload ZIP
|
668 |
+
- options[type] = "upload"
|
669 |
+
|
670 |
+
Also: plugins hosted at GitHub have a de-facto standard field of "GitHub Plugin URI"
|
671 |
+
*/
|
672 |
+
$install_source = 'unknown';
|
673 |
+
if (isset($upgrader_skin_options['type'])) {
|
674 |
+
$install_source = (string) $upgrader_skin_options['type'];
|
675 |
+
}
|
676 |
+
|
677 |
+
$context['plugin_install_source'] = $install_source;
|
678 |
+
|
679 |
+
// If uploaded plugin store name of ZIP
|
680 |
+
if ('upload' == $install_source) {
|
681 |
+
/*
|
682 |
+
_debug_files
|
683 |
+
{
|
684 |
+
"pluginzip": {
|
685 |
+
"name": "WPThumb-master.zip",
|
686 |
+
"type": "application\/zip",
|
687 |
+
"tmp_name": "\/Applications\/MAMP\/tmp\/php\/phpnThImc",
|
688 |
+
"error": 0,
|
689 |
+
"size": 2394625
|
690 |
+
}
|
691 |
+
}
|
692 |
+
*/
|
693 |
+
|
694 |
+
if (isset($_FILES['pluginzip']['name'])) {
|
695 |
+
$plugin_upload_name = $_FILES['pluginzip']['name'];
|
696 |
+
$context['plugin_upload_name'] = $plugin_upload_name;
|
697 |
+
}
|
698 |
+
}
|
699 |
+
|
700 |
+
if (is_a($plugin_upgrader_instance->skin->result, 'WP_Error')) {
|
701 |
+
// Add errors
|
702 |
+
// Errors is in original wp admin language
|
703 |
+
$context['error_messages'] = $this->simpleHistory->json_encode($plugin_upgrader_instance->skin->result->errors);
|
704 |
+
$context['error_data'] = $this->simpleHistory->json_encode($plugin_upgrader_instance->skin->result->error_data);
|
705 |
+
|
706 |
+
$this->infoMessage(
|
707 |
+
'plugin_installed_failed',
|
708 |
+
$context
|
709 |
+
);
|
710 |
+
|
711 |
+
$did_log = true;
|
712 |
+
} else {
|
713 |
+
// Plugin was successfully installed
|
714 |
+
// Try to grab more info from the readme
|
715 |
+
// Would be nice to grab a screenshot, but that is difficult since they often are stored remotely
|
716 |
+
$plugin_destination = isset($plugin_upgrader_instance->result['destination']) ? $plugin_upgrader_instance->result['destination'] : null;
|
717 |
+
|
718 |
+
if ($plugin_destination) {
|
719 |
+
$plugin_info = $plugin_upgrader_instance->plugin_info();
|
720 |
+
|
721 |
+
$plugin_data = array();
|
722 |
+
if (file_exists(WP_PLUGIN_DIR . '/' . $plugin_info)) {
|
723 |
+
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_info, true, false);
|
724 |
+
}
|
725 |
+
|
726 |
+
$context['plugin_name'] = isset($plugin_data['Name']) ? $plugin_data['Name'] : '';
|
727 |
+
$context['plugin_description'] = isset($plugin_data['Description']) ? $plugin_data['Description'] : '';
|
728 |
+
$context['plugin_url'] = isset($plugin_data['PluginURI']) ? $plugin_data['PluginURI'] : '';
|
729 |
+
$context['plugin_version'] = isset($plugin_data['Version']) ? $plugin_data['Version'] : '';
|
730 |
+
$context['plugin_author'] = isset($plugin_data['AuthorName']) ? $plugin_data['AuthorName'] : '';
|
731 |
+
|
732 |
+
// Comment out these to debug plugin installs
|
733 |
+
// $context["debug_plugin_data"] = $this->simpleHistory->json_encode( $plugin_data );
|
734 |
+
// $context["debug_plugin_info"] = $this->simpleHistory->json_encode( $plugin_info );
|
735 |
+
if (! empty($plugin_data['GitHub Plugin URI'])) {
|
736 |
+
$context['plugin_github_url'] = $plugin_data['GitHub Plugin URI'];
|
737 |
+
}
|
738 |
+
}
|
739 |
+
|
740 |
+
$this->infoMessage(
|
741 |
+
'plugin_installed',
|
742 |
+
$context
|
743 |
+
);
|
744 |
+
|
745 |
+
$did_log = true;
|
746 |
+
}// End if().
|
747 |
+
} // End if().
|
748 |
+
|
749 |
+
// Single plugin update
|
750 |
+
if (isset($arr_data['action']) && 'update' == $arr_data['action'] && ! $plugin_upgrader_instance->bulk) {
|
751 |
+
// No plugin info in instance, so get it ourself
|
752 |
+
$plugin_data = array();
|
753 |
+
if (file_exists(WP_PLUGIN_DIR . '/' . $arr_data['plugin'])) {
|
754 |
+
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $arr_data['plugin'], true, false);
|
755 |
+
}
|
756 |
+
|
757 |
+
// autoptimize/autoptimize.php
|
758 |
+
$plugin_slug = dirname($arr_data['plugin']);
|
759 |
+
|
760 |
+
$context = array(
|
761 |
+
'plugin_slug' => $plugin_slug,
|
762 |
+
'request' => $this->simpleHistory->json_encode($_REQUEST),
|
763 |
+
'plugin_name' => $plugin_data['Name'],
|
764 |
+
'plugin_title' => $plugin_data['Title'],
|
765 |
+
'plugin_description' => $plugin_data['Description'],
|
766 |
+
'plugin_author' => $plugin_data['Author'],
|
767 |
+
'plugin_version' => $plugin_data['Version'],
|
768 |
+
'plugin_url' => $plugin_data['PluginURI'],
|
769 |
+
'plugin_source_files' => $this->simpleHistory->json_encode($plugin_upgrader_instance->result['source_files']),
|
770 |
+
);
|
771 |
+
|
772 |
+
// update status for plugins are in response
|
773 |
+
// plugin folder + index file = key
|
774 |
+
// use transient to get url and package
|
775 |
+
$update_plugins = get_site_transient('update_plugins');
|
776 |
+
if ($update_plugins && isset($update_plugins->response[ $arr_data['plugin'] ])) {
|
777 |
+
/*
|
778 |
+
$update_plugins[plugin_path/slug]:
|
779 |
+
{
|
780 |
+
"id": "8986",
|
781 |
+
"slug": "autoptimize",
|
782 |
+
"plugin": "autoptimize/autoptimize.php",
|
783 |
+
"new_version": "1.9.1",
|
784 |
+
"url": "https://wordpress.org/plugins/autoptimize/",
|
785 |
+
"package": "https://downloads.wordpress.org/plugin/autoptimize.1.9.1.zip"
|
786 |
+
}
|
787 |
+
*/
|
788 |
+
// for debug purposes the update_plugins key can be added
|
789 |
+
// $context["update_plugins"] = $this->simpleHistory->json_encode( $update_plugins );
|
790 |
+
$plugin_update_info = $update_plugins->response[ $arr_data['plugin'] ];
|
791 |
+
|
792 |
+
// autoptimize/autoptimize.php
|
793 |
+
if (isset($plugin_update_info->plugin)) {
|
794 |
+
$context['plugin_update_info_plugin'] = $plugin_update_info->plugin;
|
795 |
+
}
|
796 |
+
|
797 |
+
// https://downloads.wordpress.org/plugin/autoptimize.1.9.1.zip
|
798 |
+
if (isset($plugin_update_info->package)) {
|
799 |
+
$context['plugin_update_info_package'] = $plugin_update_info->package;
|
800 |
+
}
|
801 |
+
}
|
802 |
+
|
803 |
+
// To get old version we use our option
|
804 |
+
$plugins_before_update = json_decode(get_option($this->slug . '_plugin_info_before_update', false), true);
|
805 |
+
if (is_array($plugins_before_update) && isset($plugins_before_update[ $arr_data['plugin'] ])) {
|
806 |
+
$context['plugin_prev_version'] = $plugins_before_update[ $arr_data['plugin'] ]['Version'];
|
807 |
+
}
|
808 |
+
|
809 |
+
if (is_a($plugin_upgrader_instance->skin->result, 'WP_Error')) {
|
810 |
+
// Add errors
|
811 |
+
// Errors is in original wp admin language
|
812 |
+
$context['error_messages'] = json_encode($plugin_upgrader_instance->skin->result->errors);
|
813 |
+
$context['error_data'] = json_encode($plugin_upgrader_instance->skin->result->error_data);
|
814 |
+
|
815 |
+
$this->infoMessage(
|
816 |
+
'plugin_update_failed',
|
817 |
+
$context
|
818 |
+
);
|
819 |
+
|
820 |
+
$did_log = true;
|
821 |
+
} else {
|
822 |
+
$this->infoMessage(
|
823 |
+
'plugin_updated',
|
824 |
+
$context
|
825 |
+
);
|
826 |
+
|
827 |
+
// echo "on_upgrader_process_complete";
|
828 |
+
// sf_d( $plugin_upgrader_instance, '$plugin_upgrader_instance' );
|
829 |
+
// sf_d( $arr_data, '$arr_data' );
|
830 |
+
$did_log = true;
|
831 |
+
}
|
832 |
+
} // End if().
|
833 |
+
|
834 |
+
/**
|
835 |
+
* For bulk updates $arr_data looks like:
|
836 |
+
* Array
|
837 |
+
* (
|
838 |
+
* [action] => update
|
839 |
+
* [type] => plugin
|
840 |
+
* [bulk] => 1
|
841 |
+
* [plugins] => Array
|
842 |
+
* (
|
843 |
+
* [0] => plugin-folder-1/plugin-index.php
|
844 |
+
* [1] => my-plugin-folder/my-plugin.php
|
845 |
+
* )
|
846 |
+
* )
|
847 |
+
*/
|
848 |
+
if (isset($arr_data['bulk']) && $arr_data['bulk'] && isset($arr_data['action']) && 'update' == $arr_data['action']) {
|
849 |
+
$plugins_updated = isset($arr_data['plugins']) ? (array) $arr_data['plugins'] : array();
|
850 |
+
|
851 |
+
foreach ($plugins_updated as $plugin_name) {
|
852 |
+
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_name, true, false);
|
853 |
+
|
854 |
+
$plugin_slug = dirname($plugin_name);
|
855 |
+
|
856 |
+
$context = array(
|
857 |
+
'plugin_slug' => $plugin_slug,
|
858 |
+
'plugin_name' => $plugin_data['Name'],
|
859 |
+
'plugin_title' => $plugin_data['Title'],
|
860 |
+
'plugin_description' => $plugin_data['Description'],
|
861 |
+
'plugin_author' => $plugin_data['Author'],
|
862 |
+
'plugin_version' => $plugin_data['Version'],
|
863 |
+
'plugin_url' => $plugin_data['PluginURI'],
|
864 |
+
);
|
865 |
+
|
866 |
+
// get url and package
|
867 |
+
$update_plugins = get_site_transient('update_plugins');
|
868 |
+
if ($update_plugins && isset($update_plugins->response[ $plugin_name ])) {
|
869 |
+
/*
|
870 |
+
$update_plugins[plugin_path/slug]:
|
871 |
+
{
|
872 |
+
"id": "8986",
|
873 |
+
"slug": "autoptimize",
|
874 |
+
"plugin": "autoptimize/autoptimize.php",
|
875 |
+
"new_version": "1.9.1",
|
876 |
+
"url": "https://wordpress.org/plugins/autoptimize/",
|
877 |
+
"package": "https://downloads.wordpress.org/plugin/autoptimize.1.9.1.zip"
|
878 |
+
}
|
879 |
+
*/
|
880 |
+
|
881 |
+
$plugin_update_info = $update_plugins->response[ $plugin_name ];
|
882 |
+
|
883 |
+
// autoptimize/autoptimize.php
|
884 |
+
if (isset($plugin_update_info->plugin)) {
|
885 |
+
$context['plugin_update_info_plugin'] = $plugin_update_info->plugin;
|
886 |
+
}
|
887 |
+
|
888 |
+
// https://downloads.wordpress.org/plugin/autoptimize.1.9.1.zip
|
889 |
+
if (isset($plugin_update_info->package)) {
|
890 |
+
$context['plugin_update_info_package'] = $plugin_update_info->package;
|
891 |
+
}
|
892 |
+
}
|
893 |
+
|
894 |
+
// To get old version we use our option
|
895 |
+
// @TODO: this does not always work, why?
|
896 |
+
$plugins_before_update = json_decode(get_option($this->slug . '_plugin_info_before_update', false), true);
|
897 |
+
if (is_array($plugins_before_update) && isset($plugins_before_update[ $plugin_name ])) {
|
898 |
+
$context['plugin_prev_version'] = $plugins_before_update[ $plugin_name ]['Version'];
|
899 |
+
}
|
900 |
+
|
901 |
+
$this->infoMessage(
|
902 |
+
'plugin_bulk_updated',
|
903 |
+
$context
|
904 |
+
);
|
905 |
+
}// End foreach().
|
906 |
+
}// End if().
|
907 |
+
} // End if().
|
908 |
+
|
909 |
+
if (! $did_log) {
|
910 |
+
// echo "on_upgrader_process_complete";
|
911 |
+
// sf_d( $plugin_upgrader_instance, '$plugin_upgrader_instance' );
|
912 |
+
// sf_d( $arr_data, '$arr_data' );
|
913 |
+
// exit;
|
914 |
+
}
|
915 |
+
|
916 |
+
$this->remove_saved_versions();
|
917 |
+
} // on upgrader_process_complete
|
918 |
+
|
919 |
+
|
920 |
+
/**
|
921 |
+
* Plugin is activated
|
922 |
+
* plugin_name is like admin-menu-tree-page-view/index.php
|
923 |
+
*/
|
924 |
+
function on_activated_plugin($plugin_name, $network_wide)
|
925 |
+
{
|
926 |
+
|
927 |
+
/*
|
928 |
+
Plugin data returned array contains the following:
|
929 |
+
'Name' - Name of the plugin, must be unique.
|
930 |
+
'Title' - Title of the plugin and the link to the plugin's web site.
|
931 |
+
'Description' - Description of what the plugin does and/or notes from the author.
|
932 |
+
'Author' - The author's name
|
933 |
+
'AuthorURI' - The authors web site address.
|
934 |
+
'Version' - The plugin version number.
|
935 |
+
'PluginURI' - Plugin web site address.
|
936 |
+
'TextDomain' - Plugin's text domain for localization.
|
937 |
+
'DomainPath' - Plugin's relative directory path to .mo files.
|
938 |
+
'Network' - Boolean. Whether the plugin can only be activated network wide.
|
939 |
+
*/
|
940 |
+
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_name, true, false);
|
941 |
+
|
942 |
+
$plugin_slug = dirname($plugin_name);
|
943 |
+
|
944 |
+
$context = array(
|
945 |
+
'plugin_name' => $plugin_data['Name'],
|
946 |
+
'plugin_slug' => $plugin_slug,
|
947 |
+
'plugin_title' => $plugin_data['Title'],
|
948 |
+
'plugin_description' => $plugin_data['Description'],
|
949 |
+
'plugin_author' => $plugin_data['Author'],
|
950 |
+
'plugin_version' => $plugin_data['Version'],
|
951 |
+
'plugin_url' => $plugin_data['PluginURI'],
|
952 |
+
);
|
953 |
+
|
954 |
+
if (! empty($plugin_data['GitHub Plugin URI'])) {
|
955 |
+
$context['plugin_github_url'] = $plugin_data['GitHub Plugin URI'];
|
956 |
+
}
|
957 |
+
|
958 |
+
$this->infoMessage('plugin_activated', $context);
|
959 |
+
} // on_activated_plugin
|
960 |
+
|
961 |
+
/**
|
962 |
+
* Plugin is deactivated
|
963 |
+
* plugin_name is like admin-menu-tree-page-view/index.php
|
964 |
+
*/
|
965 |
+
function on_deactivated_plugin($plugin_name)
|
966 |
+
{
|
967 |
+
|
968 |
+
$plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_name, true, false);
|
969 |
+
$plugin_slug = dirname($plugin_name);
|
970 |
+
|
971 |
+
$context = array(
|
972 |
+
'plugin_name' => $plugin_data['Name'],
|
973 |
+
'plugin_slug' => $plugin_slug,
|
974 |
+
'plugin_title' => $plugin_data['Title'],
|
975 |
+
'plugin_description' => $plugin_data['Description'],
|
976 |
+
'plugin_author' => $plugin_data['Author'],
|
977 |
+
'plugin_version' => $plugin_data['Version'],
|
978 |
+
'plugin_url' => $plugin_data['PluginURI'],
|
979 |
+
);
|
980 |
+
|
981 |
+
if (! empty($plugin_data['GitHub Plugin URI'])) {
|
982 |
+
$context['plugin_github_url'] = $plugin_data['GitHub Plugin URI'];
|
983 |
+
}
|
984 |
+
|
985 |
+
$this->infoMessage('plugin_deactivated', $context);
|
986 |
+
} // on_deactivated_plugin
|
987 |
+
|
988 |
+
|
989 |
+
/**
|
990 |
+
* Get output for detailed log section
|
991 |
+
*/
|
992 |
+
function getLogRowDetailsOutput($row)
|
993 |
+
{
|
994 |
+
|
995 |
+
$context = $row->context;
|
996 |
+
$message_key = $context['_message_key'];
|
997 |
+
$output = '';
|
998 |
+
|
999 |
+
// When a plugin is installed we show a bit more information
|
1000 |
+
// We do it only on install because we don't want to clutter to log,
|
1001 |
+
// and when something is installed the description is most useul for other
|
1002 |
+
// admins on the site
|
1003 |
+
if ('plugin_installed' === $message_key) {
|
1004 |
+
if (isset($context['plugin_description'])) {
|
1005 |
+
// Description includes a link to author, remove that, i.e. all text after and including <cite>
|
1006 |
+
$plugin_description = $context['plugin_description'];
|
1007 |
+
$cite_pos = strpos($plugin_description, '<cite>');
|
1008 |
+
if ($cite_pos) {
|
1009 |
+
$plugin_description = substr($plugin_description, 0, $cite_pos);
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
// Keys to show
|
1013 |
+
$arr_plugin_keys = array(
|
1014 |
+
'plugin_description' => _x('Description', 'plugin logger - detailed output', 'simple-history'),
|
1015 |
+
'plugin_install_source' => _x('Source', 'plugin logger - detailed output install source', 'simple-history'),
|
1016 |
+
'plugin_install_source_file' => _x('Source file name', 'plugin logger - detailed output install source', 'simple-history'),
|
1017 |
+
'plugin_version' => _x('Version', 'plugin logger - detailed output version', 'simple-history'),
|
1018 |
+
'plugin_author' => _x('Author', 'plugin logger - detailed output author', 'simple-history'),
|
1019 |
+
'plugin_url' => _x('URL', 'plugin logger - detailed output url', 'simple-history'),
|
1020 |
+
// "plugin_downloaded" => _x("Downloads", "plugin logger - detailed output downloaded", "simple-history"),
|
1021 |
+
// "plugin_requires" => _x("Requires", "plugin logger - detailed output author", "simple-history"),
|
1022 |
+
// "plugin_tested" => _x("Compatible up to", "plugin logger - detailed output compatible", "simple-history"),
|
1023 |
+
// also available: plugin_rating, plugin_num_ratings
|
1024 |
+
);
|
1025 |
+
|
1026 |
+
$arr_plugin_keys = apply_filters('simple_history/plugin_logger/row_details_plugin_info_keys', $arr_plugin_keys);
|
1027 |
+
|
1028 |
+
// Start output of plugin meta data table
|
1029 |
+
$output .= "<table class='SimpleHistoryLogitem__keyValueTable'>";
|
1030 |
+
|
1031 |
+
foreach ($arr_plugin_keys as $key => $desc) {
|
1032 |
+
$desc_output = '';
|
1033 |
+
|
1034 |
+
switch ($key) {
|
1035 |
+
case 'plugin_downloaded':
|
1036 |
+
$desc_output = esc_html(number_format_i18n((int) $context[ $key ]));
|
1037 |
+
break;
|
1038 |
+
|
1039 |
+
// author is already formatted
|
1040 |
+
case 'plugin_author':
|
1041 |
+
$desc_output = $context[ $key ];
|
1042 |
+
break;
|
1043 |
+
|
1044 |
+
// URL needs a link
|
1045 |
+
case 'plugin_url':
|
1046 |
+
$desc_output = sprintf('<a href="%1$s">%2$s</a>', esc_attr($context['plugin_url']), esc_html($context['plugin_url']));
|
1047 |
+
break;
|
1048 |
+
|
1049 |
+
case 'plugin_description':
|
1050 |
+
$desc_output = $plugin_description;
|
1051 |
+
break;
|
1052 |
+
|
1053 |
+
case 'plugin_install_source':
|
1054 |
+
if (! isset($context[ $key ])) {
|
1055 |
+
break;
|
1056 |
+
}
|
1057 |
+
|
1058 |
+
if ('web' == $context[ $key ]) {
|
1059 |
+
$desc_output = esc_html(__('WordPress Plugin Repository', 'simple-history'));
|
1060 |
+
} elseif ('upload' == $context[ $key ]) {
|
1061 |
+
// $plugin_upload_name = isset( $context["plugin_upload_name"] ) ? $context["plugin_upload_name"] : __("Unknown archive name", "simple-history");
|
1062 |
+
$desc_output = esc_html(__('Uploaded ZIP archive', 'simple-history'));
|
1063 |
+
// $desc_output = esc_html( sprintf( __('Uploaded ZIP archive (%1$s)', "simple-history"), $plugin_upload_name ) );
|
1064 |
+
// $desc_output = esc_html( sprintf( __('%1$s (uploaded ZIP archive)', "simple-history"), $plugin_upload_name ) );
|
1065 |
+
} else {
|
1066 |
+
$desc_output = esc_html($context[ $key ]);
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
break;
|
1070 |
+
|
1071 |
+
case 'plugin_install_source_file':
|
1072 |
+
if (! isset($context['plugin_upload_name']) || ! isset($context['plugin_install_source'])) {
|
1073 |
+
break;
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
if ('upload' == $context['plugin_install_source']) {
|
1077 |
+
$plugin_upload_name = $context['plugin_upload_name'];
|
1078 |
+
$desc_output = esc_html($plugin_upload_name);
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
break;
|
1082 |
+
|
1083 |
+
default:
|
1084 |
+
$desc_output = esc_html($context[ $key ]);
|
1085 |
+
break;
|
1086 |
+
}// End switch().
|
1087 |
+
|
1088 |
+
if (! trim($desc_output)) {
|
1089 |
+
continue;
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
$output .= sprintf(
|
1093 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1094 |
<tr>
|
1095 |
<td>%1$s</td>
|
1096 |
<td>%2$s</td>
|
1097 |
</tr>
|
1098 |
',
|
1099 |
+
esc_html($desc),
|
1100 |
+
$desc_output
|
1101 |
+
);
|
1102 |
+
}// End foreach().
|
1103 |
+
|
1104 |
+
// Add link with more info about the plugin
|
1105 |
+
// If plugin_install_source = web then it should be a wordpress.org-plugin
|
1106 |
+
// If plugin_github_url is set then it's a zip from a github thingie
|
1107 |
+
// so use link to that.
|
1108 |
+
$plugin_slug = ! empty($context['plugin_slug']) ? $context['plugin_slug'] : '';
|
1109 |
+
|
1110 |
+
// Slug + web as install source = show link to wordpress.org
|
1111 |
+
if ($plugin_slug && isset($context['plugin_install_source']) && $context['plugin_install_source'] == 'web') {
|
1112 |
+
$output .= sprintf(
|
1113 |
+
'
|
|
|
|
|
1114 |
<tr>
|
1115 |
<td></td>
|
1116 |
<td><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></td>
|
1117 |
</tr>
|
1118 |
',
|
1119 |
+
admin_url("plugin-install.php?tab=plugin-information&plugin={$plugin_slug}&section=&TB_iframe=true&width=640&height=550"),
|
1120 |
+
esc_html_x('View plugin info', 'plugin logger: plugin info thickbox title view all info', 'simple-history')
|
1121 |
+
);
|
1122 |
+
} // End if().
|
1123 |
+
elseif (isset($context['plugin_install_source']) && $context['plugin_install_source'] == 'upload' && ! empty($context['plugin_github_url'])) {
|
1124 |
+
// Can't embed iframe
|
1125 |
+
// Must use API instead
|
1126 |
+
// https://api.github.com/repos/<username>/<repo>/readme?callback=<callbackname>
|
1127 |
+
$output .= sprintf(
|
1128 |
+
'
|
|
|
|
|
1129 |
<tr>
|
1130 |
<td></td>
|
1131 |
<td><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></td>
|
1132 |
</tr>
|
1133 |
',
|
1134 |
+
admin_url(sprintf('admin-ajax.php?action=SimplePluginLogger_GetGitHubPluginInfo&getrepo&repo=%1$s&TB_iframe=true&width=640&height=550', esc_url_raw($context['plugin_github_url']))),
|
1135 |
+
esc_html_x('View plugin info', 'plugin logger: plugin info thickbox title view all info', 'simple-history')
|
1136 |
+
);
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
$output .= '</table>';
|
1140 |
+
}// End if().
|
1141 |
+
} elseif ('plugin_bulk_updated' === $message_key || 'plugin_updated' === $message_key || 'plugin_activated' === $message_key || 'plugin_deactivated' === $message_key) {
|
1142 |
+
$plugin_slug = ! empty($context['plugin_slug']) ? $context['plugin_slug'] : '';
|
1143 |
+
|
1144 |
+
if ($plugin_slug && empty($context['plugin_github_url'])) {
|
1145 |
+
$link_title = esc_html_x('View plugin info', 'plugin logger: plugin info thickbox title', 'simple-history');
|
1146 |
+
$url = admin_url("plugin-install.php?tab=plugin-information&plugin={$plugin_slug}&section=&TB_iframe=true&width=640&height=550");
|
1147 |
+
|
1148 |
+
if ('plugin_updated' == $message_key || 'plugin_bulk_updated' == $message_key) {
|
1149 |
+
$link_title = esc_html_x('View changelog', 'plugin logger: plugin info thickbox title', 'simple-history');
|
1150 |
+
|
1151 |
+
if (is_multisite()) {
|
1152 |
+
$url = network_admin_url("plugin-install.php?tab=plugin-information&plugin={$plugin_slug}&section=changelog&TB_iframe=true&width=772&height=550");
|
1153 |
+
} else {
|
1154 |
+
$url = admin_url("plugin-install.php?tab=plugin-information&plugin={$plugin_slug}&section=changelog&TB_iframe=true&width=772&height=550");
|
1155 |
+
}
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
$output .= sprintf(
|
1159 |
+
'<p><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></p>',
|
1160 |
+
$url,
|
1161 |
+
$link_title
|
1162 |
+
);
|
1163 |
+
} elseif (! empty($context['plugin_github_url'])) {
|
1164 |
+
$output .= sprintf(
|
1165 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1166 |
<tr>
|
1167 |
<td></td>
|
1168 |
<td><a title="%2$s" class="thickbox" href="%1$s">%2$s</a></td>
|
1169 |
</tr>
|
1170 |
',
|
1171 |
+
admin_url(sprintf('admin-ajax.php?action=SimplePluginLogger_GetGitHubPluginInfo&getrepo&repo=%1$s&TB_iframe=true&width=640&height=550', esc_url_raw($context['plugin_github_url']))),
|
1172 |
+
esc_html_x('View plugin info', 'plugin logger: plugin info thickbox title view all info', 'simple-history')
|
1173 |
+
);
|
1174 |
+
} // End if().
|
1175 |
+
} // End if().
|
1176 |
+
|
1177 |
+
return $output;
|
1178 |
+
} // getLogRowDetailsOutput
|
|
|
|
|
|
|
1179 |
} // class SimplePluginLogger
|
loggers/SimplePostLogger.php
CHANGED
@@ -5,9 +5,9 @@ defined('ABSPATH') || die();
|
|
5 |
/**
|
6 |
* Todo/@HERE
|
7 |
* - [ ] install and test with ACF again
|
8 |
-
*
|
9 |
* - The second save saves all the post meta. So it's technically two saves but not for the user.
|
10 |
-
*
|
11 |
* - [ ] test REST API update from curl or similar
|
12 |
* - [ ] test REST API from Android/Ios-apps
|
13 |
* - [ ] Save auto-saves? Not done by user but still done...
|
@@ -18,1684 +18,1405 @@ defined('ABSPATH') || die();
|
|
18 |
*/
|
19 |
class SimplePostLogger extends SimpleLogger
|
20 |
{
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
$raw_post_data = null;
|
211 |
-
$message = null;
|
212 |
-
$context = array();
|
213 |
-
|
214 |
-
if (in_array($method, $arr_methods_to_act_on)) {
|
215 |
-
// Setup common stuff
|
216 |
-
$raw_post_data = file_get_contents('php://input');
|
217 |
-
$context[
|
218 |
-
'wp.deletePost.xmldata'
|
219 |
-
] = $this->simpleHistory->json_encode($raw_post_data);
|
220 |
-
$message = new IXR_Message($raw_post_data);
|
221 |
-
|
222 |
-
if (!$message->parse()) {
|
223 |
-
return;
|
224 |
-
}
|
225 |
-
|
226 |
-
$context[
|
227 |
-
'wp.deletePost.xmlrpc_message'
|
228 |
-
] = $this->simpleHistory->json_encode($message);
|
229 |
-
$context[
|
230 |
-
'wp.deletePost.xmlrpc_message.messageType'
|
231 |
-
] = $this->simpleHistory->json_encode($message->messageType);
|
232 |
-
$context[
|
233 |
-
'wp.deletePost.xmlrpc_message.methodName'
|
234 |
-
] = $this->simpleHistory->json_encode($message->methodName);
|
235 |
-
$context[
|
236 |
-
'wp.deletePost.xmlrpc_message.messageParams'
|
237 |
-
] = $this->simpleHistory->json_encode($message->params);
|
238 |
-
|
239 |
-
// Actions for delete post
|
240 |
-
if ('wp.deletePost' == $method) {
|
241 |
-
// 4 params, where the last is the post id
|
242 |
-
if (!isset($message->params[3])) {
|
243 |
-
return;
|
244 |
-
}
|
245 |
-
|
246 |
-
$post_ID = $message->params[3];
|
247 |
-
|
248 |
-
$post = get_post($post_ID);
|
249 |
-
|
250 |
-
$context = array(
|
251 |
-
'post_id' => $post->ID,
|
252 |
-
'post_type' => get_post_type($post),
|
253 |
-
'post_title' => get_the_title($post)
|
254 |
-
);
|
255 |
-
|
256 |
-
$this->infoMessage('post_trashed', $context);
|
257 |
-
}
|
258 |
-
} // End if().
|
259 |
-
}
|
260 |
-
|
261 |
-
/**
|
262 |
-
* Get array with information about this logger
|
263 |
-
*
|
264 |
-
* @return array
|
265 |
-
*/
|
266 |
-
function getInfo()
|
267 |
-
{
|
268 |
-
$arr_info = array(
|
269 |
-
'name' => 'Post Logger',
|
270 |
-
'description' =>
|
271 |
-
'Logs the creation and modification of posts and pages',
|
272 |
-
'capability' => 'edit_pages',
|
273 |
-
'messages' => array(
|
274 |
-
'post_created' => __(
|
275 |
-
'Created {post_type} "{post_title}"',
|
276 |
-
'simple-history'
|
277 |
-
),
|
278 |
-
'post_updated' => __(
|
279 |
-
'Updated {post_type} "{post_title}"',
|
280 |
-
'simple-history'
|
281 |
-
),
|
282 |
-
'post_restored' => __(
|
283 |
-
'Restored {post_type} "{post_title}" from trash',
|
284 |
-
'simple-history'
|
285 |
-
),
|
286 |
-
'post_deleted' => __(
|
287 |
-
'Deleted {post_type} "{post_title}"',
|
288 |
-
'simple-history'
|
289 |
-
),
|
290 |
-
'post_trashed' => __(
|
291 |
-
'Moved {post_type} "{post_title}" to the trash',
|
292 |
-
'simple-history'
|
293 |
-
)
|
294 |
-
),
|
295 |
-
'labels' => array(
|
296 |
-
'search' => array(
|
297 |
-
'label' => _x(
|
298 |
-
'Posts & Pages',
|
299 |
-
'Post logger: search',
|
300 |
-
'simple-history'
|
301 |
-
),
|
302 |
-
'label_all' => _x(
|
303 |
-
'All posts & pages activity',
|
304 |
-
'Post logger: search',
|
305 |
-
'simple-history'
|
306 |
-
),
|
307 |
-
'options' => array(
|
308 |
-
_x(
|
309 |
-
'Posts created',
|
310 |
-
'Post logger: search',
|
311 |
-
'simple-history'
|
312 |
-
) => array('post_created'),
|
313 |
-
_x(
|
314 |
-
'Posts updated',
|
315 |
-
'Post logger: search',
|
316 |
-
'simple-history'
|
317 |
-
) => array('post_updated'),
|
318 |
-
_x(
|
319 |
-
'Posts trashed',
|
320 |
-
'Post logger: search',
|
321 |
-
'simple-history'
|
322 |
-
) => array('post_trashed'),
|
323 |
-
_x(
|
324 |
-
'Posts deleted',
|
325 |
-
'Post logger: search',
|
326 |
-
'simple-history'
|
327 |
-
) => array('post_deleted'),
|
328 |
-
_x(
|
329 |
-
'Posts restored',
|
330 |
-
'Post logger: search',
|
331 |
-
'simple-history'
|
332 |
-
) => array('post_restored')
|
333 |
-
)
|
334 |
-
) // end search array
|
335 |
-
) // end labels
|
336 |
-
);
|
337 |
-
|
338 |
-
return $arr_info;
|
339 |
-
}
|
340 |
-
|
341 |
-
/**
|
342 |
-
* Get and store old info about a post that is being edited.
|
343 |
-
* Needed to later compare old data with new data, to detect differences.
|
344 |
-
* This function is called on edit screen but before post edits are saved.
|
345 |
-
*
|
346 |
-
* Can't use the regular filters like "pre_post_update" because custom fields are already written by then.
|
347 |
-
*
|
348 |
-
* @since 2.0.29
|
349 |
-
*/
|
350 |
-
function on_admin_action_editpost()
|
351 |
-
{
|
352 |
-
$post_ID = isset($_POST['post_ID']) ? (int) $_POST['post_ID'] : 0;
|
353 |
-
|
354 |
-
if (!$post_ID) {
|
355 |
-
return;
|
356 |
-
}
|
357 |
-
|
358 |
-
if (!current_user_can('edit_post', $post_ID)) {
|
359 |
-
return;
|
360 |
-
}
|
361 |
-
|
362 |
-
$prev_post_data = get_post($post_ID);
|
363 |
-
|
364 |
-
if (is_wp_error($prev_post_data)) {
|
365 |
-
return;
|
366 |
-
}
|
367 |
-
|
368 |
-
$this->old_post_data[$post_ID] = array(
|
369 |
-
'post_data' => $prev_post_data,
|
370 |
-
'post_meta' => get_post_custom($post_ID)
|
371 |
-
);
|
372 |
-
}
|
373 |
-
|
374 |
-
/**
|
375 |
-
* Fires after a post has been successfully deleted via the XML-RPC Blogger API.
|
376 |
-
*
|
377 |
-
* @since 2.0.21
|
378 |
-
*
|
379 |
-
* @param int $post_ID ID of the deleted post.
|
380 |
-
* @param array $args An array of arguments to delete the post.
|
381 |
-
*/
|
382 |
-
function on_xmlrpc_deletePost($post_ID, $args)
|
383 |
-
{
|
384 |
-
$post = get_post($post_ID);
|
385 |
-
|
386 |
-
$context = array(
|
387 |
-
'post_id' => $post->ID,
|
388 |
-
'post_type' => get_post_type($post),
|
389 |
-
'post_title' => get_the_title($post)
|
390 |
-
);
|
391 |
-
|
392 |
-
$this->infoMessage('post_deleted', $context);
|
393 |
-
}
|
394 |
-
|
395 |
-
/**
|
396 |
-
* Fires after a post has been successfully updated via the XML-RPC API.
|
397 |
-
*
|
398 |
-
* @since 2.0.21
|
399 |
-
*
|
400 |
-
* @param int $post_ID ID of the updated post.
|
401 |
-
* @param array $args An array of arguments for the post to edit.
|
402 |
-
*/
|
403 |
-
function on_xmlrpc_editPost($post_ID, $args)
|
404 |
-
{
|
405 |
-
$post = get_post($post_ID);
|
406 |
-
|
407 |
-
$context = array(
|
408 |
-
'post_id' => $post->ID,
|
409 |
-
'post_type' => get_post_type($post),
|
410 |
-
'post_title' => get_the_title($post)
|
411 |
-
);
|
412 |
-
|
413 |
-
$this->infoMessage('post_updated', $context);
|
414 |
-
}
|
415 |
-
|
416 |
-
/**
|
417 |
-
* Fires after a new post has been successfully created via the XML-RPC API.
|
418 |
-
*
|
419 |
-
* @since 2.0.21
|
420 |
-
*
|
421 |
-
* @param int $post_ID ID of the new post.
|
422 |
-
* @param array $args An array of new post arguments.
|
423 |
-
*/
|
424 |
-
function on_xmlrpc_newPost($post_ID, $args)
|
425 |
-
{
|
426 |
-
$post = get_post($post_ID);
|
427 |
-
|
428 |
-
$context = array(
|
429 |
-
'post_id' => $post->ID,
|
430 |
-
'post_type' => get_post_type($post),
|
431 |
-
'post_title' => get_the_title($post)
|
432 |
-
);
|
433 |
-
|
434 |
-
$this->infoMessage('post_created', $context);
|
435 |
-
}
|
436 |
-
|
437 |
-
/**
|
438 |
-
* Called when a post is restored from the trash
|
439 |
-
* @param int $post_id
|
440 |
-
*/
|
441 |
-
function on_untrash_post($post_id)
|
442 |
-
{
|
443 |
-
$post = get_post($post_id);
|
444 |
-
|
445 |
-
if (!$this->ok_to_log_post_posttype($post)) {
|
446 |
-
return;
|
447 |
-
}
|
448 |
-
|
449 |
-
$this->infoMessage('post_restored', array(
|
450 |
-
'post_id' => $post_id,
|
451 |
-
'post_type' => get_post_type($post),
|
452 |
-
'post_title' => get_the_title($post)
|
453 |
-
));
|
454 |
-
}
|
455 |
-
|
456 |
-
/**
|
457 |
-
* Fired immediately before a post is deleted from the database.
|
458 |
-
*
|
459 |
-
* @param int $postid Post ID.
|
460 |
-
*/
|
461 |
-
function on_delete_post($post_id)
|
462 |
-
{
|
463 |
-
$post = get_post($post_id);
|
464 |
-
|
465 |
-
if (wp_is_post_revision($post_id)) {
|
466 |
-
return;
|
467 |
-
}
|
468 |
-
|
469 |
-
if (
|
470 |
-
$post->post_status === 'auto-draft' ||
|
471 |
-
$post->post_status === 'inherit'
|
472 |
-
) {
|
473 |
-
return;
|
474 |
-
}
|
475 |
-
|
476 |
-
$ok_to_log = true;
|
477 |
-
|
478 |
-
if (!$this->ok_to_log_post_posttype($post)) {
|
479 |
-
$ok_to_log = false;
|
480 |
-
}
|
481 |
-
|
482 |
-
/**
|
483 |
-
* Filter to control logging.
|
484 |
-
*
|
485 |
-
* @param bool $ok_to_log If this post deletion should be logged.
|
486 |
-
* @param int $post_id
|
487 |
-
*
|
488 |
-
* @return bool True to log, false to not log.
|
489 |
-
*
|
490 |
-
* @since 2.21
|
491 |
-
*/
|
492 |
-
$ok_to_log = apply_filters(
|
493 |
-
'simple_history/post_logger/post_deleted/ok_to_log',
|
494 |
-
$ok_to_log,
|
495 |
-
$post_id
|
496 |
-
);
|
497 |
-
|
498 |
-
if (!$ok_to_log) {
|
499 |
-
return;
|
500 |
-
}
|
501 |
-
|
502 |
-
/*
|
503 |
-
Posts that have been in the trash for 30 days (default)
|
504 |
-
are deleted using a cron job that is called with action hook "wp_scheduled_delete".
|
505 |
-
We skip logging these because users are confused and think that the real post has been
|
506 |
-
deleted.
|
507 |
-
We detect this by checking $wp_current_filter for 'wp_scheduled_delete'
|
508 |
-
[
|
509 |
-
"wp_scheduled_delete",
|
510 |
-
"delete_post",
|
511 |
-
"simple_history\/log_argument\/context"
|
512 |
-
]
|
513 |
-
*/
|
514 |
-
global $wp_current_filter;
|
515 |
-
if (isset($wp_current_filter) && is_array($wp_current_filter)) {
|
516 |
-
if (in_array('wp_scheduled_delete', $wp_current_filter, true)) {
|
517 |
-
return;
|
518 |
-
}
|
519 |
-
}
|
520 |
-
|
521 |
-
$this->infoMessage('post_deleted', array(
|
522 |
-
'post_id' => $post_id,
|
523 |
-
'post_type' => get_post_type($post),
|
524 |
-
'post_title' => get_the_title($post)
|
525 |
-
));
|
526 |
-
}
|
527 |
-
|
528 |
-
/**
|
529 |
-
* Get an array of post types that should not be logged by this logger.
|
530 |
-
*
|
531 |
-
* @return Array with post type slugs to skip.
|
532 |
-
*/
|
533 |
-
public function get_skip_posttypes()
|
534 |
-
{
|
535 |
-
$skip_posttypes = array(
|
536 |
-
// Don't log nav_menu_updates.
|
537 |
-
'nav_menu_item',
|
538 |
-
// Don't log jetpack migration-things.
|
539 |
-
// https://wordpress.org/support/topic/updated-jetpack_migration-sidebars_widgets/.
|
540 |
-
'jetpack_migration',
|
541 |
-
'jp_sitemap',
|
542 |
-
'jp_img_sitemap',
|
543 |
-
'jp_sitemap_master'
|
544 |
-
);
|
545 |
-
|
546 |
-
/**
|
547 |
-
* Filter to log what post types not to log
|
548 |
-
*
|
549 |
-
* @since 2.18
|
550 |
-
*/
|
551 |
-
$skip_posttypes = apply_filters(
|
552 |
-
'simple_history/post_logger/skip_posttypes',
|
553 |
-
$skip_posttypes
|
554 |
-
);
|
555 |
-
|
556 |
-
return $skip_posttypes;
|
557 |
-
}
|
558 |
-
|
559 |
-
/**
|
560 |
-
* Check if post type is ok to log by logger
|
561 |
-
*
|
562 |
-
* @param Int or WP_Post $post Post the check.
|
563 |
-
*
|
564 |
-
* @return bool
|
565 |
-
*/
|
566 |
-
public function ok_to_log_post_posttype($post)
|
567 |
-
{
|
568 |
-
$ok_to_log = true;
|
569 |
-
$skip_posttypes = $this->get_skip_posttypes();
|
570 |
-
|
571 |
-
if (in_array(get_post_type($post), $skip_posttypes, true)) {
|
572 |
-
$ok_to_log = false;
|
573 |
-
}
|
574 |
-
|
575 |
-
return $ok_to_log;
|
576 |
-
}
|
577 |
-
|
578 |
-
/**
|
579 |
-
* Maybe log a post creation, modification or deletion.
|
580 |
-
*
|
581 |
-
* Todo:
|
582 |
-
* - support password protect.
|
583 |
-
* - post_password is set
|
584 |
-
*
|
585 |
-
* @param array $args Array with old and new post data.
|
586 |
-
*/
|
587 |
-
public function maybe_log_post_change($args)
|
588 |
-
{
|
589 |
-
$default_args = array(
|
590 |
-
'new_post',
|
591 |
-
'new_post_meta',
|
592 |
-
'old_post',
|
593 |
-
'old_post_meta',
|
594 |
-
// Old status is included because that's the value we get in filter
|
595 |
-
// "transation_post_status", when a previous post may not exist.
|
596 |
-
'old_status'
|
597 |
-
);
|
598 |
-
|
599 |
-
$args = wp_parse_args($args, $default_args);
|
600 |
-
|
601 |
-
// Bail if needed args not set.
|
602 |
-
if (!isset($args['new_post']) || !isset($args['new_post_meta'])) {
|
603 |
-
return;
|
604 |
-
}
|
605 |
-
|
606 |
-
$new_status = isset($args['new_post']->post_status)
|
607 |
-
? $args['new_post']->post_status
|
608 |
-
: null;
|
609 |
-
$post = $args['new_post'];
|
610 |
-
$new_post_data = array(
|
611 |
-
'post_data' => $post,
|
612 |
-
'post_meta' => $args['new_post_meta']
|
613 |
-
);
|
614 |
-
|
615 |
-
// Set old status to status from old post with fallback to old_status variable.
|
616 |
-
$old_status = isset($args['old_post']->post_status)
|
617 |
-
? $args['old_post']->post_status
|
618 |
-
: null;
|
619 |
-
$old_status =
|
620 |
-
!isset($old_status) && isset($args['old_status'])
|
621 |
-
? $args['old_status']
|
622 |
-
: $old_status;
|
623 |
-
|
624 |
-
$old_post = isset($args['old_post']) ? $args['old_post'] : null;
|
625 |
-
$old_post_meta = isset($args['old_post_meta'])
|
626 |
-
? $args['old_post_meta']
|
627 |
-
: null;
|
628 |
-
$old_post_data = array(
|
629 |
-
'post_data' => $old_post,
|
630 |
-
'post_meta' => $old_post_meta
|
631 |
-
);
|
632 |
-
|
633 |
-
// Default to log.
|
634 |
-
$ok_to_log = true;
|
635 |
-
|
636 |
-
// Calls from the WordPress ios app/jetpack comes from non-admin-area
|
637 |
-
// i.e. is_admin() is false
|
638 |
-
// so don't log when outside admin area.
|
639 |
-
if (!is_admin()) {
|
640 |
-
$ok_to_log = false;
|
641 |
-
}
|
642 |
-
|
643 |
-
// Except when calls are from/for Jetpack/WordPress apps.
|
644 |
-
// seems to be jetpack/app request when $_GET["for"] == "jetpack.
|
645 |
-
$isXmlRpcRequest = defined('XMLRPC_REQUEST') && XMLRPC_REQUEST;
|
646 |
-
if (
|
647 |
-
$isXmlRpcRequest &&
|
648 |
-
isset($_GET['for']) &&
|
649 |
-
'jetpack' === $_GET['for']
|
650 |
-
) {
|
651 |
-
$ok_to_log = true;
|
652 |
-
}
|
653 |
-
|
654 |
-
// Also accept calls from REST API
|
655 |
-
$isRestApiRequest =
|
656 |
-
(defined('REST_API_REQUEST') && REST_API_REQUEST) ||
|
657 |
-
(defined('REST_REQUEST') && REST_REQUEST);
|
658 |
-
if ($isRestApiRequest) {
|
659 |
-
$ok_to_log = true;
|
660 |
-
}
|
661 |
-
|
662 |
-
// Don't log revisions.
|
663 |
-
if (wp_is_post_revision($post)) {
|
664 |
-
$ok_to_log = false;
|
665 |
-
}
|
666 |
-
|
667 |
-
// Don't log Gutenberg saving meta boxes.
|
668 |
-
if (isset($_GET['meta-box-loader']) && $_GET['meta-box-loader']) {
|
669 |
-
$ok_to_log = false;
|
670 |
-
}
|
671 |
-
|
672 |
-
if (!$this->ok_to_log_post_posttype($post)) {
|
673 |
-
$ok_to_log = false;
|
674 |
-
}
|
675 |
-
|
676 |
-
/**
|
677 |
-
* Filter to control logging.
|
678 |
-
*
|
679 |
-
* @param bool $ok_to_log
|
680 |
-
* @param $new_status
|
681 |
-
* @param $old_status
|
682 |
-
* @param $post
|
683 |
-
*
|
684 |
-
* @return bool True to log, false to not log.
|
685 |
-
*
|
686 |
-
* @since 2.21
|
687 |
-
*/
|
688 |
-
$ok_to_log = apply_filters(
|
689 |
-
'simple_history/post_logger/post_updated/ok_to_log',
|
690 |
-
$ok_to_log,
|
691 |
-
$new_status,
|
692 |
-
$old_status,
|
693 |
-
$post
|
694 |
-
);
|
695 |
-
|
696 |
-
if (!$ok_to_log) {
|
697 |
-
return;
|
698 |
-
}
|
699 |
-
|
700 |
-
/*
|
701 |
-
From new to auto-draft <- ignore
|
702 |
-
From new to inherit <- ignore
|
703 |
-
From auto-draft to draft <- page/post created
|
704 |
-
From draft to draft
|
705 |
-
From draft to pending
|
706 |
-
From pending to publish
|
707 |
-
From pending to trash
|
708 |
-
From something to publish = post published
|
709 |
-
if not from & to = same, then user has changed something
|
710 |
-
From draft to publish in future: status = "future"
|
711 |
-
*/
|
712 |
-
$context = array(
|
713 |
-
'post_id' => $post->ID,
|
714 |
-
'post_type' => get_post_type($post),
|
715 |
-
'post_title' => get_the_title($post)
|
716 |
-
);
|
717 |
-
|
718 |
-
if (
|
719 |
-
'auto-draft' === $old_status &&
|
720 |
-
('auto-draft' !== $new_status && 'inherit' !== $new_status)
|
721 |
-
) {
|
722 |
-
// Post created
|
723 |
-
$this->infoMessage('post_created', $context);
|
724 |
-
} elseif (
|
725 |
-
'auto-draft' === $new_status ||
|
726 |
-
('new' === $old_status && 'inherit' === $new_status)
|
727 |
-
) {
|
728 |
-
// Post was automagically saved by WordPress
|
729 |
-
return;
|
730 |
-
} elseif ('trash' === $new_status) {
|
731 |
-
// Post trashed
|
732 |
-
$this->infoMessage('post_trashed', $context);
|
733 |
-
} else {
|
734 |
-
// Existing post was updated.
|
735 |
-
|
736 |
-
// Also add diff between previous saved data and new data.
|
737 |
-
if (isset($old_post_data) && isset($new_post_data)) {
|
738 |
-
// Now we have both old and new post data, including custom fields, in the same format
|
739 |
-
// So let's compare!
|
740 |
-
$context = $this->add_post_data_diff_to_context(
|
741 |
-
$context,
|
742 |
-
$old_post_data,
|
743 |
-
$new_post_data
|
744 |
-
);
|
745 |
-
}
|
746 |
-
|
747 |
-
$context['_occasionsID'] =
|
748 |
-
__CLASS__ . '/' . __FUNCTION__ . "/post_updated/{$post->ID}";
|
749 |
-
|
750 |
-
/**
|
751 |
-
* Modify the context saved.
|
752 |
-
*
|
753 |
-
* @param array $context
|
754 |
-
* @param WP_Post $post
|
755 |
-
*/
|
756 |
-
$context = apply_filters(
|
757 |
-
'simple_history/post_logger/post_updated/context',
|
758 |
-
$context,
|
759 |
-
$post
|
760 |
-
);
|
761 |
-
|
762 |
-
$this->infoMessage('post_updated', $context);
|
763 |
-
} // End if().
|
764 |
-
}
|
765 |
-
|
766 |
-
/**
|
767 |
-
* Fired when a post has changed status in the classical editor.
|
768 |
-
* Only run in certain cases,
|
769 |
-
* because when always enabled it catches a lots of edits made by plugins during cron jobs etc,
|
770 |
-
* which by definition is not wrong, but perhaps not wanted/annoying.
|
771 |
-
*
|
772 |
-
* @param string $new_status One of auto-draft, inherit, draft, pending, publish, future.
|
773 |
-
* @param string $old_status Same as above.
|
774 |
-
* @param WP_Post $post New updated post.
|
775 |
-
*/
|
776 |
-
function on_transition_post_status($new_status, $old_status, $post)
|
777 |
-
{
|
778 |
-
// $isRestApiRequest = ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST );
|
779 |
-
// $is_admin = is_admin();
|
780 |
-
// False if not a revision, ID of revision's parent otherwise.
|
781 |
-
// $post_is_revision = wp_is_post_revision( $post );
|
782 |
-
// sh_error_log('on_transition_post_status', '$new_status', $new_status, '$old_status', $old_status, '$isRestApiRequest', $isRestApiRequest, '$is_admin', $is_admin, '$post_is_revision', $post_is_revision);
|
783 |
-
// Bail if post is not a post.
|
784 |
-
if (!is_a($post, 'WP_Post')) {
|
785 |
-
return;
|
786 |
-
}
|
787 |
-
|
788 |
-
// $old_post_data_exists = ! empty( $this->old_post_data[ $post->ID ] );
|
789 |
-
|
790 |
-
$old_post = null;
|
791 |
-
$old_post_meta = null;
|
792 |
-
|
793 |
-
if (!empty($this->old_post_data[$post->ID])) {
|
794 |
-
$old_post = $this->old_post_data[$post->ID]['post_data'];
|
795 |
-
$old_post_meta = $this->old_post_data[$post->ID]['post_meta'];
|
796 |
-
}
|
797 |
-
|
798 |
-
$args = array(
|
799 |
-
'new_post' => $post,
|
800 |
-
'new_post_meta' => get_post_custom($post->ID),
|
801 |
-
'old_post' => $old_post,
|
802 |
-
'old_post_meta' => $old_post_meta,
|
803 |
-
'old_status' => $old_status,
|
804 |
-
'_debug_caller_method' => __METHOD__
|
805 |
-
);
|
806 |
-
|
807 |
-
$this->maybe_log_post_change($args);
|
808 |
-
}
|
809 |
-
|
810 |
-
/**
|
811 |
-
* Adds diff data to the context array. Is called just before the event is logged.
|
812 |
-
*
|
813 |
-
* Since 2.0.29
|
814 |
-
*
|
815 |
-
* To detect
|
816 |
-
* - categories
|
817 |
-
* - tags
|
818 |
-
*
|
819 |
-
* @param array $context Array with context.
|
820 |
-
* @param array $old_post_data Old/prev post data.
|
821 |
-
* @param array $new_post_data New post data.
|
822 |
-
* @return array $context with diff data added.
|
823 |
-
*/
|
824 |
-
function add_post_data_diff_to_context(
|
825 |
-
$context,
|
826 |
-
$old_post_data,
|
827 |
-
$new_post_data
|
828 |
-
) {
|
829 |
-
$old_data = $old_post_data['post_data'];
|
830 |
-
$new_data = $new_post_data['post_data'];
|
831 |
-
|
832 |
-
// Will contain the differences.
|
833 |
-
$post_data_diff = array();
|
834 |
-
|
835 |
-
$arr_keys_to_diff = array(
|
836 |
-
'post_title',
|
837 |
-
'post_name',
|
838 |
-
'post_content',
|
839 |
-
'post_status',
|
840 |
-
'menu_order',
|
841 |
-
'post_date',
|
842 |
-
'post_date_gmt',
|
843 |
-
'post_excerpt',
|
844 |
-
'comment_status',
|
845 |
-
'ping_status',
|
846 |
-
'post_parent', // only id, need to get context for that, like name of parent at least?
|
847 |
-
'post_author' // only id, need to get more info for user.
|
848 |
-
);
|
849 |
-
|
850 |
-
foreach ($arr_keys_to_diff as $key) {
|
851 |
-
if (isset($old_data->$key) && isset($new_data->$key)) {
|
852 |
-
$post_data_diff = $this->add_diff(
|
853 |
-
$post_data_diff,
|
854 |
-
$key,
|
855 |
-
$old_data->$key,
|
856 |
-
$new_data->$key
|
857 |
-
);
|
858 |
-
}
|
859 |
-
}
|
860 |
-
|
861 |
-
// If changes where detected.
|
862 |
-
if ($post_data_diff) {
|
863 |
-
// Save at least 2 values for each detected value change, i.e. the old value and the new value.
|
864 |
-
foreach ($post_data_diff as $diff_key => $diff_values) {
|
865 |
-
$context["post_prev_{$diff_key}"] = $diff_values['old'];
|
866 |
-
$context["post_new_{$diff_key}"] = $diff_values['new'];
|
867 |
-
|
868 |
-
// If post_author then get more author info,
|
869 |
-
// because just a user ID does not get us far.
|
870 |
-
if ('post_author' == $diff_key) {
|
871 |
-
$old_author_user = get_userdata((int) $diff_values['old']);
|
872 |
-
$new_author_user = get_userdata((int) $diff_values['new']);
|
873 |
-
|
874 |
-
if (
|
875 |
-
is_a($old_author_user, 'WP_User') &&
|
876 |
-
is_a($new_author_user, 'WP_User')
|
877 |
-
) {
|
878 |
-
$context["post_prev_{$diff_key}/user_login"] =
|
879 |
-
$old_author_user->user_login;
|
880 |
-
$context["post_prev_{$diff_key}/user_email"] =
|
881 |
-
$old_author_user->user_email;
|
882 |
-
$context["post_prev_{$diff_key}/display_name"] =
|
883 |
-
$old_author_user->display_name;
|
884 |
-
|
885 |
-
$context["post_new_{$diff_key}/user_login"] =
|
886 |
-
$new_author_user->user_login;
|
887 |
-
$context["post_new_{$diff_key}/user_email"] =
|
888 |
-
$new_author_user->user_email;
|
889 |
-
$context["post_new_{$diff_key}/display_name"] =
|
890 |
-
$new_author_user->display_name;
|
891 |
-
}
|
892 |
-
}
|
893 |
-
}
|
894 |
-
} // End if().
|
895 |
-
|
896 |
-
// Compare custom fields.
|
897 |
-
// Array with custom field keys to ignore because changed everytime or very internal.
|
898 |
-
$arr_meta_keys_to_ignore = array(
|
899 |
-
'_edit_lock',
|
900 |
-
'_edit_last',
|
901 |
-
'_post_restored_from',
|
902 |
-
'_wp_page_template',
|
903 |
-
'_thumbnail_id'
|
904 |
-
);
|
905 |
-
|
906 |
-
$meta_changes = array(
|
907 |
-
'added' => array(),
|
908 |
-
'removed' => array(),
|
909 |
-
'changed' => array()
|
910 |
-
);
|
911 |
-
|
912 |
-
$old_meta = isset($old_post_data['post_meta'])
|
913 |
-
? (array) $old_post_data['post_meta']
|
914 |
-
: array();
|
915 |
-
$new_meta = isset($new_post_data['post_meta'])
|
916 |
-
? (array) $new_post_data['post_meta']
|
917 |
-
: array();
|
918 |
-
|
919 |
-
// Add post featured thumb data.
|
920 |
-
$context = $this->add_post_thumb_diff($context, $old_meta, $new_meta);
|
921 |
-
|
922 |
-
// Page template is stored in _wp_page_template.
|
923 |
-
if (
|
924 |
-
isset($old_meta['_wp_page_template'][0]) &&
|
925 |
-
isset($new_meta['_wp_page_template'][0])
|
926 |
-
) {
|
927 |
-
/*
|
928 |
-
Var is string with length 7: default
|
929 |
-
Var is string with length 20: template-builder.php
|
930 |
-
*/
|
931 |
-
|
932 |
-
if (
|
933 |
-
$old_meta['_wp_page_template'][0] !==
|
934 |
-
$new_meta['_wp_page_template'][0]
|
935 |
-
) {
|
936 |
-
// Prev page template is different from new page template,
|
937 |
-
// store template php file name.
|
938 |
-
$context['post_prev_page_template'] =
|
939 |
-
$old_meta['_wp_page_template'][0];
|
940 |
-
$context['post_new_page_template'] =
|
941 |
-
$new_meta['_wp_page_template'][0];
|
942 |
-
|
943 |
-
$theme_templates = (array) $this->get_theme_templates();
|
944 |
-
|
945 |
-
if (
|
946 |
-
isset($theme_templates[$context['post_prev_page_template']])
|
947 |
-
) {
|
948 |
-
$context['post_prev_page_template_name'] =
|
949 |
-
$theme_templates[$context['post_prev_page_template']];
|
950 |
-
}
|
951 |
-
|
952 |
-
if (
|
953 |
-
isset($theme_templates[$context['post_new_page_template']])
|
954 |
-
) {
|
955 |
-
$context['post_new_page_template_name'] =
|
956 |
-
$theme_templates[$context['post_new_page_template']];
|
957 |
-
}
|
958 |
-
}
|
959 |
-
}
|
960 |
-
|
961 |
-
// Remove fields that we have checked already and other that should be ignored.
|
962 |
-
foreach ($arr_meta_keys_to_ignore as $key_to_ignore) {
|
963 |
-
unset($old_meta[$key_to_ignore]);
|
964 |
-
unset($new_meta[$key_to_ignore]);
|
965 |
-
}
|
966 |
-
|
967 |
-
// Look for added custom fields.
|
968 |
-
foreach ($new_meta as $meta_key => $meta_value) {
|
969 |
-
if (!isset($old_meta[$meta_key])) {
|
970 |
-
$meta_changes['added'][$meta_key] = true;
|
971 |
-
}
|
972 |
-
}
|
973 |
-
|
974 |
-
// Look for removed meta.
|
975 |
-
// Does not work, if user clicks "delete" in edit screen then meta is removed using ajax.
|
976 |
-
/*
|
977 |
-
foreach ( $old_meta as $meta_key => $meta_value ) {
|
978 |
-
|
979 |
-
if ( ! isset($new_meta[ $meta_key ] ) ) {
|
980 |
-
$meta_changes["removed"][ $meta_key ] = true;
|
981 |
-
}
|
982 |
-
|
983 |
-
}
|
984 |
-
*/
|
985 |
-
|
986 |
-
// Look for changed meta.
|
987 |
-
foreach ($old_meta as $meta_key => $meta_value) {
|
988 |
-
if (isset($new_meta[$meta_key])) {
|
989 |
-
if (
|
990 |
-
json_encode($old_meta[$meta_key]) !=
|
991 |
-
json_encode($new_meta[$meta_key])
|
992 |
-
) {
|
993 |
-
$meta_changes['changed'][$meta_key] = true;
|
994 |
-
}
|
995 |
-
}
|
996 |
-
}
|
997 |
-
|
998 |
-
if ($meta_changes['added']) {
|
999 |
-
$context['post_meta_added'] = count($meta_changes['added']);
|
1000 |
-
}
|
1001 |
-
|
1002 |
-
if ($meta_changes['removed']) {
|
1003 |
-
$context['post_meta_removed'] = count($meta_changes['removed']);
|
1004 |
-
}
|
1005 |
-
|
1006 |
-
if ($meta_changes['changed']) {
|
1007 |
-
$context['post_meta_changed'] = count($meta_changes['changed']);
|
1008 |
-
}
|
1009 |
-
|
1010 |
-
// Check for changes in post visbility and post password usage and store in context.
|
1011 |
-
// publish = public
|
1012 |
-
// publish + post_password = password protected
|
1013 |
-
// private = post private
|
1014 |
-
$old_post_has_password = !empty($old_data->post_password);
|
1015 |
-
$old_post_password = $old_post_has_password
|
1016 |
-
? $old_data->post_password
|
1017 |
-
: null;
|
1018 |
-
$old_post_status = isset($old_data->post_status)
|
1019 |
-
? $old_data->post_status
|
1020 |
-
: null;
|
1021 |
-
|
1022 |
-
$new_post_has_password = !empty($new_data->post_password);
|
1023 |
-
$new_post_password = $new_post_has_password
|
1024 |
-
? $new_data->post_password
|
1025 |
-
: null;
|
1026 |
-
$new_post_status = isset($new_data->post_status)
|
1027 |
-
? $new_data->post_status
|
1028 |
-
: null;
|
1029 |
-
|
1030 |
-
if (
|
1031 |
-
false === $old_post_has_password &&
|
1032 |
-
'publish' === $new_post_status &&
|
1033 |
-
$new_post_has_password
|
1034 |
-
) {
|
1035 |
-
// If updated post is published and password is set and old post did not have password set
|
1036 |
-
// = post changed to be password protected.
|
1037 |
-
$context['post_password_protected'] = true;
|
1038 |
-
} elseif (
|
1039 |
-
$old_post_has_password &&
|
1040 |
-
'publish' === $old_post_status &&
|
1041 |
-
false === $new_post_has_password &&
|
1042 |
-
'publish' === $new_post_status
|
1043 |
-
) {
|
1044 |
-
// Old post is publish and had password protection and new post is publish but no password
|
1045 |
-
// = post changed to be un-password protected
|
1046 |
-
$context['post_password_unprotected'] = true;
|
1047 |
-
} elseif (
|
1048 |
-
$old_post_has_password &&
|
1049 |
-
$new_post_has_password &&
|
1050 |
-
$old_post_password !== $new_post_password
|
1051 |
-
) {
|
1052 |
-
// If old post had password and new post has password, but passwords are note same
|
1053 |
-
// = post has changed password.
|
1054 |
-
$context['post_password_changed'] = true;
|
1055 |
-
} elseif (
|
1056 |
-
'private' === $new_post_status &&
|
1057 |
-
'private' !== $old_post_status
|
1058 |
-
) {
|
1059 |
-
// If new status is private and old is not
|
1060 |
-
// = post is changed to be private.
|
1061 |
-
$context['post_private'] = true;
|
1062 |
-
// Also check if password was set before.
|
1063 |
-
if ($old_post_has_password) {
|
1064 |
-
$context['post_password_unprotected'] = true;
|
1065 |
-
}
|
1066 |
-
}
|
1067 |
-
|
1068 |
-
// Todo: detect sticky.
|
1069 |
-
// Sticky is stored in option:
|
1070 |
-
// $sticky_posts = get_option('sticky_posts');
|
1071 |
-
|
1072 |
-
return $context;
|
1073 |
-
}
|
1074 |
-
|
1075 |
-
/**
|
1076 |
-
* Return the current theme templates.
|
1077 |
-
* Template will return untranslated.
|
1078 |
-
* Uses the same approach as in class-wp-theme.php to get templates.
|
1079 |
-
*
|
1080 |
-
* @since 2.0.29
|
1081 |
-
*/
|
1082 |
-
public function get_theme_templates()
|
1083 |
-
{
|
1084 |
-
$theme = wp_get_theme();
|
1085 |
-
$page_templates = array();
|
1086 |
-
|
1087 |
-
$files = (array) $theme->get_files('php', 1);
|
1088 |
-
|
1089 |
-
foreach ($files as $file => $full_path) {
|
1090 |
-
if (
|
1091 |
-
!preg_match(
|
1092 |
-
'|Template Name:(.*)$|mi',
|
1093 |
-
file_get_contents($full_path),
|
1094 |
-
$header
|
1095 |
-
)
|
1096 |
-
) {
|
1097 |
-
continue;
|
1098 |
-
}
|
1099 |
-
$page_templates[$file] = _cleanup_header_comment($header[1]);
|
1100 |
-
}
|
1101 |
-
|
1102 |
-
return $page_templates;
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
/**
|
1106 |
-
* Add diff to array if old and new values are different
|
1107 |
-
*
|
1108 |
-
* Since 2.0.29
|
1109 |
-
*
|
1110 |
-
* @param array $post_data_diff Post data diff.
|
1111 |
-
* @param string $key Key.
|
1112 |
-
* @param mixed $old_value Old value.
|
1113 |
-
* @param mixed $new_value New value.
|
1114 |
-
* @return array
|
1115 |
-
*/
|
1116 |
-
public function add_diff($post_data_diff, $key, $old_value, $new_value)
|
1117 |
-
{
|
1118 |
-
if ($old_value != $new_value) {
|
1119 |
-
$post_data_diff[$key] = array(
|
1120 |
-
'old' => $old_value,
|
1121 |
-
'new' => $new_value
|
1122 |
-
);
|
1123 |
-
}
|
1124 |
-
|
1125 |
-
return $post_data_diff;
|
1126 |
-
}
|
1127 |
-
|
1128 |
-
/**
|
1129 |
-
* Modify plain output to include link to post.
|
1130 |
-
*
|
1131 |
-
* @param array $row Row data.
|
1132 |
-
*/
|
1133 |
-
public function getLogRowPlainTextOutput($row)
|
1134 |
-
{
|
1135 |
-
$context = $row->context;
|
1136 |
-
$post_id = isset($context['post_id']) ? $context['post_id'] : 0;
|
1137 |
-
|
1138 |
-
// Default to original log message.
|
1139 |
-
$message = $row->message;
|
1140 |
-
|
1141 |
-
// Check if post still is available.
|
1142 |
-
// It will return a WP_Post Object if post still is in system.
|
1143 |
-
// If post is deleted from trash (not just moved there), then null is returned.
|
1144 |
-
$post = get_post($post_id);
|
1145 |
-
$post_is_available = is_a($post, 'WP_Post');
|
1146 |
-
|
1147 |
-
$message_key = isset($context['_message_key'])
|
1148 |
-
? $context['_message_key']
|
1149 |
-
: null;
|
1150 |
-
|
1151 |
-
// Try to get singular name.
|
1152 |
-
$post_type = isset($context['post_type']) ? $context['post_type'] : '';
|
1153 |
-
$post_type_obj = get_post_type_object($post_type);
|
1154 |
-
if (!is_null($post_type_obj)) {
|
1155 |
-
if (!empty($post_type_obj->labels->singular_name)) {
|
1156 |
-
$context['post_type'] = strtolower(
|
1157 |
-
$post_type_obj->labels->singular_name
|
1158 |
-
);
|
1159 |
-
}
|
1160 |
-
}
|
1161 |
-
|
1162 |
-
$context['edit_link'] = get_edit_post_link($post_id);
|
1163 |
-
|
1164 |
-
// If post is not available any longer then we can't link to it, so keep plain message then.
|
1165 |
-
// Also keep plain format if user is not allowed to edit post (edit link is empty).
|
1166 |
-
if ($post_is_available && $context['edit_link']) {
|
1167 |
-
if ('post_updated' == $message_key) {
|
1168 |
-
$message = __(
|
1169 |
-
'Updated {post_type} <a href="{edit_link}">"{post_title}"</a>',
|
1170 |
-
'simple-history'
|
1171 |
-
);
|
1172 |
-
} elseif ('post_deleted' == $message_key) {
|
1173 |
-
$message = __(
|
1174 |
-
'Deleted {post_type} "{post_title}"',
|
1175 |
-
'simple-history'
|
1176 |
-
);
|
1177 |
-
} elseif ('post_created' == $message_key) {
|
1178 |
-
$message = __(
|
1179 |
-
'Created {post_type} <a href="{edit_link}">"{post_title}"</a>',
|
1180 |
-
'simple-history'
|
1181 |
-
);
|
1182 |
-
} elseif ('post_trashed' == $message_key) {
|
1183 |
-
// While in trash we can still get actions to delete or restore if we follow the edit link.
|
1184 |
-
$message = __(
|
1185 |
-
'Moved {post_type} <a href="{edit_link}">"{post_title}"</a> to the trash',
|
1186 |
-
'simple-history'
|
1187 |
-
);
|
1188 |
-
}
|
1189 |
-
} // End if().
|
1190 |
-
|
1191 |
-
$context['post_type'] = isset($context['post_type'])
|
1192 |
-
? esc_html($context['post_type'])
|
1193 |
-
: '';
|
1194 |
-
$context['post_title'] = isset($context['post_title'])
|
1195 |
-
? esc_html($context['post_title'])
|
1196 |
-
: '';
|
1197 |
-
|
1198 |
-
return $this->interpolate($message, $context, $row);
|
1199 |
-
}
|
1200 |
-
|
1201 |
-
/**
|
1202 |
-
* Get details output for row.
|
1203 |
-
*
|
1204 |
-
* @param array $row Row data.
|
1205 |
-
*/
|
1206 |
-
public function getLogRowDetailsOutput($row)
|
1207 |
-
{
|
1208 |
-
$context = $row->context;
|
1209 |
-
$message_key = $context['_message_key'];
|
1210 |
-
|
1211 |
-
$out = '';
|
1212 |
-
|
1213 |
-
if ('post_updated' == $message_key) {
|
1214 |
-
// Check for keys like "post_prev_post_title" and "post_new_post_title".
|
1215 |
-
$diff_table_output = '';
|
1216 |
-
$has_diff_values = false;
|
1217 |
-
|
1218 |
-
foreach ($context as $key => $val) {
|
1219 |
-
if (strpos($key, 'post_prev_') !== false) {
|
1220 |
-
// Old value exists, new value must also exist for diff to be calculates.
|
1221 |
-
$key_to_diff = substr($key, strlen('post_prev_'));
|
1222 |
-
|
1223 |
-
$key_for_new_val = "post_new_{$key_to_diff}";
|
1224 |
-
|
1225 |
-
if (isset($context[$key_for_new_val])) {
|
1226 |
-
$post_old_value = $context[$key];
|
1227 |
-
$post_new_value = $context[$key_for_new_val];
|
1228 |
-
if ($post_old_value != $post_new_value) {
|
1229 |
-
// Different diffs for different keys.
|
1230 |
-
if ('post_title' == $key_to_diff) {
|
1231 |
-
$has_diff_values = true;
|
1232 |
-
|
1233 |
-
$diff_table_output .= sprintf(
|
1234 |
-
'<tr><td>%1$s</td><td>%2$s</td></tr>',
|
1235 |
-
__('Title', 'simple-history'),
|
1236 |
-
simple_history_text_diff(
|
1237 |
-
$post_old_value,
|
1238 |
-
$post_new_value
|
1239 |
-
)
|
1240 |
-
);
|
1241 |
-
} elseif ('post_content' == $key_to_diff) {
|
1242 |
-
// Problem: to much text/content.
|
1243 |
-
// Risks to fill the visual output.
|
1244 |
-
// Maybe solution: use own diff function, that uses none or few context lines.
|
1245 |
-
$has_diff_values = true;
|
1246 |
-
$key_text_diff = simple_history_text_diff(
|
1247 |
-
$post_old_value,
|
1248 |
-
$post_new_value
|
1249 |
-
);
|
1250 |
-
|
1251 |
-
if ($key_text_diff) {
|
1252 |
-
$diff_table_output .= sprintf(
|
1253 |
-
'<tr><td>%1$s</td><td>%2$s</td></tr>',
|
1254 |
-
__('Content', 'simple-history'),
|
1255 |
-
$key_text_diff
|
1256 |
-
);
|
1257 |
-
}
|
1258 |
-
} elseif ('post_status' == $key_to_diff) {
|
1259 |
-
$has_diff_values = true;
|
1260 |
-
$diff_table_output .= sprintf(
|
1261 |
-
'<tr>
|
5 |
/**
|
6 |
* Todo/@HERE
|
7 |
* - [ ] install and test with ACF again
|
8 |
+
* - Install 5.7.13 and then each save or preview results in 2 or 3 adds to the log.
|
9 |
* - The second save saves all the post meta. So it's technically two saves but not for the user.
|
10 |
+
* Both requests have the same HTTP_X_WP_NONCE
|
11 |
* - [ ] test REST API update from curl or similar
|
12 |
* - [ ] test REST API from Android/Ios-apps
|
13 |
* - [ ] Save auto-saves? Not done by user but still done...
|
18 |
*/
|
19 |
class SimplePostLogger extends SimpleLogger
|
20 |
{
|
21 |
+
// The logger slug. Defaulting to the class name is nice and logical I think.
|
22 |
+
public $slug = __CLASS__;
|
23 |
+
|
24 |
+
// Array that will contain previous post data, before data is updated.
|
25 |
+
// Array format is
|
26 |
+
// [post_id] => [post_data, post_meta].
|
27 |
+
// post_data = WP_Post object, post_meta = post meta array.
|
28 |
+
protected $old_post_data = array();
|
29 |
+
|
30 |
+
public function loaded()
|
31 |
+
{
|
32 |
+
add_action('admin_action_editpost', array($this, 'on_admin_action_editpost'));
|
33 |
+
add_action('transition_post_status', array($this, 'on_transition_post_status'), 10, 3);
|
34 |
+
add_action('delete_post', array($this, 'on_delete_post'));
|
35 |
+
add_action('untrash_post', array($this, 'on_untrash_post'));
|
36 |
+
|
37 |
+
$this->add_xml_rpc_hooks();
|
38 |
+
$this->add_rest_hooks();
|
39 |
+
|
40 |
+
add_filter('simple_history/rss_item_link', array($this, 'filter_rss_item_link'), 10, 2);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Add hooks to catch updates via REST API, i.e. the new Gutenberg editor.
|
45 |
+
*/
|
46 |
+
public function add_rest_hooks()
|
47 |
+
{
|
48 |
+
// Get all post types.
|
49 |
+
$post_types = get_post_types(array(), 'objects');
|
50 |
+
|
51 |
+
// Add actions for each post type.
|
52 |
+
foreach ($post_types as $post_type) {
|
53 |
+
// class-wp-rest-posts-controller.php fires two actions in
|
54 |
+
// the update_item() method: pre_insert and after_insert.
|
55 |
+
|
56 |
+
// Rest pre insert is fired before an updated post is inserted into db.
|
57 |
+
add_action("rest_pre_insert_{$post_type->name}", array($this, 'on_rest_pre_insert'), 10, 2);
|
58 |
+
|
59 |
+
// Rest insert happens after the post has been updated: "Fires after a single post is completely created or updated via the REST API."
|
60 |
+
// add_action( "rest_after_insert_{$post_type->name}", array( $this, 'on_rest_after_insert' ), 10, 3 );
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Filter "rest_pre_insert_{$this->post_type}" filters a post before it is inserted via the REST API.
|
66 |
+
* Fired from class-wp-rest-posts-controller.php.
|
67 |
+
*
|
68 |
+
* Here we can get the old post object.
|
69 |
+
*
|
70 |
+
* @param stdClass $prepared_post An object representing a single post prepared
|
71 |
+
* for inserting or updating the database, i.e. the new updated post.
|
72 |
+
* @param WP_REST_Request $request Request object.
|
73 |
+
* @return stdClass $prepared_post
|
74 |
+
*/
|
75 |
+
public function on_rest_pre_insert($prepared_post, $request)
|
76 |
+
{
|
77 |
+
// $prepared_post = stdClass Object with new and modified content.
|
78 |
+
// changes are not saved to post in db yet, so get_post( $prepared_post->ID ) will get old contents.
|
79 |
+
/*
|
80 |
+
stdClass Object
|
81 |
+
(
|
82 |
+
[ID] => 889
|
83 |
+
[post_title] => gutenberg 1
|
84 |
+
[post_content] => <!-- wp:paragraph -->
|
85 |
+
<p>hejsan</p>
|
86 |
+
<!-- /wp:paragraph -->
|
87 |
+
[post_excerpt] =>
|
88 |
+
[post_type] => post
|
89 |
+
[page_template] =>
|
90 |
+
)
|
91 |
+
*/
|
92 |
+
|
93 |
+
// $old_post = post with old content and old meta
|
94 |
+
$old_post = get_post($prepared_post->ID);
|
95 |
+
|
96 |
+
$this->old_post_data[$old_post->ID] = array(
|
97 |
+
'post_data' => $old_post,
|
98 |
+
'post_meta' => get_post_custom($old_post->ID)
|
99 |
+
);
|
100 |
+
|
101 |
+
return $prepared_post;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Fires after a single post is completely created or updated via the REST API.
|
106 |
+
*
|
107 |
+
* Here we can get the updated post, after it's updated in the db.
|
108 |
+
*
|
109 |
+
* @param WP_Post $post Inserted or updated post object.
|
110 |
+
* @param WP_REST_Request $request Request object.
|
111 |
+
* @param bool $creating True when creating a post, false when updating.
|
112 |
+
*/
|
113 |
+
public function on_rest_after_insert($post, $request, $creating)
|
114 |
+
{
|
115 |
+
$post = get_post($post->ID);
|
116 |
+
$post_meta = get_post_custom($post->ID);
|
117 |
+
|
118 |
+
$old_post = $this->old_post_data[$post->ID]['post_data'];
|
119 |
+
$old_post_meta = $this->old_post_data[$post->ID]['post_meta'];
|
120 |
+
|
121 |
+
$args = array(
|
122 |
+
'new_post' => $post,
|
123 |
+
'new_post_meta' => $post_meta,
|
124 |
+
'old_post' => $old_post,
|
125 |
+
'old_post_meta' => $old_post_meta,
|
126 |
+
'old_status' => $old_post->post_status,
|
127 |
+
'_debug_caller_method' => __METHOD__
|
128 |
+
);
|
129 |
+
|
130 |
+
$this->maybe_log_post_change($args);
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Filters to XML RPC calls needs to be added early, admin_init is to late.
|
135 |
+
*/
|
136 |
+
public function add_xml_rpc_hooks()
|
137 |
+
{
|
138 |
+
// Debug: log all XML-RPC requests
|
139 |
+
/*
|
140 |
+
add_action("xmlrpc_call", function($method) {
|
141 |
+
SimpleLogger()->debug("XML-RPC call for method '{method}'", array("method" => $method));
|
142 |
+
}, 10, 1);
|
143 |
+
*/
|
144 |
+
|
145 |
+
add_action('xmlrpc_call_success_blogger_newPost', array($this, 'on_xmlrpc_newPost'), 10, 2);
|
146 |
+
add_action('xmlrpc_call_success_mw_newPost', array($this, 'on_xmlrpc_newPost'), 10, 2);
|
147 |
+
|
148 |
+
add_action('xmlrpc_call_success_blogger_editPost', array($this, 'on_xmlrpc_editPost'), 10, 2);
|
149 |
+
add_action('xmlrpc_call_success_mw_editPost', array($this, 'on_xmlrpc_editPost'), 10, 2);
|
150 |
+
|
151 |
+
add_action('xmlrpc_call_success_blogger_deletePost', array($this, 'on_xmlrpc_deletePost'), 10, 2);
|
152 |
+
add_action('xmlrpc_call_success_wp_deletePage', array($this, 'on_xmlrpc_deletePost'), 10, 2);
|
153 |
+
|
154 |
+
add_action('xmlrpc_call', array($this, 'on_xmlrpc_call'), 10, 1);
|
155 |
+
}
|
156 |
+
|
157 |
+
public function on_xmlrpc_call($method)
|
158 |
+
{
|
159 |
+
$arr_methods_to_act_on = array('wp.deletePost');
|
160 |
+
|
161 |
+
$raw_post_data = null;
|
162 |
+
$message = null;
|
163 |
+
$context = array();
|
164 |
+
|
165 |
+
if (in_array($method, $arr_methods_to_act_on)) {
|
166 |
+
// Setup common stuff
|
167 |
+
$raw_post_data = file_get_contents('php://input');
|
168 |
+
$context['wp.deletePost.xmldata'] = $this->simpleHistory->json_encode($raw_post_data);
|
169 |
+
$message = new IXR_Message($raw_post_data);
|
170 |
+
|
171 |
+
if (!$message->parse()) {
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
|
175 |
+
$context['wp.deletePost.xmlrpc_message'] = $this->simpleHistory->json_encode($message);
|
176 |
+
$context['wp.deletePost.xmlrpc_message.messageType'] = $this->simpleHistory->json_encode(
|
177 |
+
$message->messageType
|
178 |
+
);
|
179 |
+
$context['wp.deletePost.xmlrpc_message.methodName'] = $this->simpleHistory->json_encode(
|
180 |
+
$message->methodName
|
181 |
+
);
|
182 |
+
$context['wp.deletePost.xmlrpc_message.messageParams'] = $this->simpleHistory->json_encode(
|
183 |
+
$message->params
|
184 |
+
);
|
185 |
+
|
186 |
+
// Actions for delete post
|
187 |
+
if ('wp.deletePost' == $method) {
|
188 |
+
// 4 params, where the last is the post id
|
189 |
+
if (!isset($message->params[3])) {
|
190 |
+
return;
|
191 |
+
}
|
192 |
+
|
193 |
+
$post_ID = $message->params[3];
|
194 |
+
|
195 |
+
$post = get_post($post_ID);
|
196 |
+
|
197 |
+
$context = array(
|
198 |
+
'post_id' => $post->ID,
|
199 |
+
'post_type' => get_post_type($post),
|
200 |
+
'post_title' => get_the_title($post)
|
201 |
+
);
|
202 |
+
|
203 |
+
$this->infoMessage('post_trashed', $context);
|
204 |
+
}
|
205 |
+
} // End if().
|
206 |
+
}
|
207 |
+
|
208 |
+
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|