Version Description
(January 2022) =
- Fixed: Used wrong text domain for some strings in Limit Login Attempts logger.
- Fixed: Post logger now ignores changes to the
_encloseme
meta key. - Fixed: Readme text loaded from GitHub repo is now filtered using
wp_kses()
. - Fixed: Links in readme text loaded from GitHub repo now opens in new window/tab by default (instead of loading in the modal/thickbox iframe).
- Added: Logger messages is shown when clicking number of message strings in settings debug tab.
- Added: Num occasions in RSS feed is now wrapped in a
<p>
tag. - Removed: "Simple Legacy Logger" is removed because it has not been used for a very long time.
- Removed: "GitHub Plugin URI" header removed from index file, so installs of Simple History from Github using Git Updater are not supported from now on.
- Removed: Box with translations notice removed from sidebar because it did not work properly when using different languages as site language and user language.
- Internal: Code formatting to better match the WordPress coding standards, code cleanup, text escaping. (#243)
Download this release
Release Info
Developer | eskapism |
Plugin | Simple History |
Version | 3.0.0 |
Comparing to | |
See all releases |
Code changes from version 2.43.0 to 3.0.0
- CHANGELOG.md +196 -10
- code.md +8 -0
- composer.json +16 -6
- composer.lock +340 -1768
- css/styles.css +0 -32
- dropins/SimpleHistoryDebugDropin.php +49 -51
- dropins/SimpleHistoryDonateDropin.php +53 -69
- dropins/SimpleHistoryExportDropin.php +215 -232
- dropins/SimpleHistoryFilterDropin.php +607 -567
- dropins/SimpleHistoryIpInfoDropin.php +195 -201
- dropins/SimpleHistoryNewRowsNotifier.php +67 -64
- dropins/SimpleHistoryPluginPatchesDropin.php +153 -161
- dropins/SimpleHistoryRSSDropin.php +426 -397
- dropins/SimpleHistorySettingsDebugDropin.php +16 -31
- dropins/SimpleHistorySettingsLogtestDropin.php +238 -282
- dropins/SimpleHistorySettingsStatsDropin.php +66 -78
- dropins/SimpleHistorySidebarDropin.php +89 -191
- dropins/SimpleHistorySidebarSettings.php +78 -81
- dropins/SimpleHistorySidebarStats.php +195 -194
- dropins/SimpleHistoryWPCLIDropin.php +144 -155
- examples/example-dropin.php +40 -47
- examples/example-logger.php +77 -77
- examples/examples.php +285 -211
- inc/SimpleHistory.php +3095 -3147
- inc/SimpleHistoryLogQuery.php +616 -683
- inc/helpers.php +138 -134
- inc/oldversions.php +37 -37
- index.php +27 -27
- loggers/AvailableUpdatesLogger.php +302 -299
- loggers/FileEditsLogger.php +252 -248
- loggers/PluginEnableMediaReplaceLogger.php +96 -94
- loggers/PluginUserSwitchingLogger.php +125 -130
- loggers/PluginWPCrontrolLogger.php +399 -406
- loggers/Plugin_ACF.php +1043 -1045
- loggers/Plugin_BeaverBuilder.php +96 -99
- loggers/Plugin_DuplicatePost.php +138 -142
- loggers/Plugin_LimitLoginAttempts.php +220 -223
- loggers/Plugin_Redirection.php +376 -388
- loggers/Plugin_UltimateMembers_Logger.php +45 -45
- loggers/SimpleCategoriesLogger.php +307 -316
- loggers/SimpleCommentsLogger.php +730 -736
- loggers/SimpleCoreUpdatesLogger.php +104 -109
- loggers/SimpleExportLogger.php +46 -49
- loggers/SimpleLegacyLogger.php +0 -104
- loggers/SimpleLogger.php +803 -1708
CHANGELOG.md
CHANGED
@@ -1,6 +1,146 @@
|
|
1 |
-
|
2 |
# Changelog for 2015 an earlier
|
3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
= 2.5 (December 2015) =
|
5 |
|
6 |
- Added: Category edits are now logged, so now you can see terms, categories and taxonomies that are added, changed, and deleted. Fixes for example https://wordpress.org/support/topic/view-changes-to-categories and https://twitter.com/hmarafi/status/655994402037362688.
|
@@ -192,7 +332,7 @@
|
|
192 |
- Fixed: Plugin installs from uploaded ZIP files are now logged correctly. Fixes https://github.com/bonny/WordPress-Simple-History/issues/59.
|
193 |
- Fixed: Check that JavaScript variables it set and that the object have properties set. Fixes https://wordpress.org/support/topic/firefox-37-js-error-generated-by-simplehistoryipinfodropinjs.
|
194 |
- Updated: German translation updated.
|
195 |
-
- Changed: Loading of loggers, dropins, and so one are moved from action `plugins_loaded` to `after_setup_theme` so themes can actually use for example the
|
196 |
- Changed: Misc small design fixes.
|
197 |
|
198 |
= 2.0.23 (March 2015) =
|
@@ -314,7 +454,7 @@
|
|
314 |
- Added: [WordPress 4.1 added the feature to log out a user from all their sessions](http://codex.wordpress.org/Version_4.1#Users). Simple History now logs when a user is logged out from all their sessions except the current browser, or if an admin destroys all sessions for a user. [View screenshot of new session logout log item](https://dl.dropboxusercontent.com/s/k4cmfmncekmfiib/2014-12-simple-history-changelog-user-sessions.png)
|
315 |
|
316 |
- Added: filter to shortcut loading of a dropin. Example that completely skips loading the RSS-feed-dropin:
|
317 |
-
`add_filter("simple_history/dropin/load_dropin_SimpleHistoryRSSDropin", "__return_false");`
|
318 |
|
319 |
= 2.0.5 (November 2014) =
|
320 |
|
@@ -356,30 +496,37 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
356 |
- Much much more.
|
357 |
|
358 |
= 1.3.11 =
|
|
|
359 |
- Don't use deprecated function get_commentdata(). Fixes https://wordpress.org/support/topic/get_commentdata-function-is-deprecated.
|
360 |
- Don't use mysql_query() directly. Fixes https://wordpress.org/support/topic/deprecated-mysql-warning.
|
361 |
- Beta testers wanted! I'm working on the next version of Simple History and now I need some beta testers. If you want to try out the shiny new and cool version please download the [v2 branch](https://github.com/bonny/WordPress-Simple-History/tree/v2) over at GitHub. Thanks!
|
362 |
|
363 |
= 1.3.10 =
|
|
|
364 |
- Fix: correct usage of "its"
|
365 |
- Fix: removed serif font in log. Fixes https://wordpress.org/support/topic/two-irritations-and-pleas-for-change.
|
366 |
|
367 |
= 1.3.9 =
|
|
|
368 |
- Fixed strict standards warning
|
369 |
- Tested on WordPress 4.0
|
370 |
|
371 |
= 1.3.8 =
|
|
|
372 |
- Added filter for rss feed: `simple_history/rss_feed_show`. Fixes more things in this thread: http://wordpress.org/support/topic/more-rss-feed-items.
|
373 |
|
374 |
= 1.3.7 =
|
|
|
375 |
- Added filter for rss feed: `simple_history/rss_feed_args`. Fixes http://wordpress.org/support/topic/more-rss-feed-items.
|
376 |
|
377 |
= 1.3.6 =
|
|
|
378 |
- Added Polish translation
|
379 |
- Added correct XML encoding and header
|
380 |
- Fixed notice warnings when media did not exist on file system
|
381 |
|
382 |
= 1.3.5 =
|
|
|
383 |
- Added a reload-button at top. Click it to reload the history. No need to refresh page no more!
|
384 |
- Fixed items being reloaded when just clicking the dropdown (not having selected anything yet)
|
385 |
- Fixed bug with keyboard navigation
|
@@ -387,28 +534,34 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
387 |
- Use less SQL queries
|
388 |
|
389 |
= 1.3.4 =
|
|
|
390 |
- Changed the way post types show in the dropdown. Now uses plural names + not prefixed with main post type. Looks better I think. Thank to Hassan for the suggestion!
|
391 |
- Added "bytes" to size units that an attachment can have. Also fixes undefined notice warning when attachment had a size less that 1 KB.
|
392 |
|
393 |
= 1.3.3 =
|
|
|
394 |
- Capability for viewing settings changed from edit_pages to the more correct [manage_options](http://codex.wordpress.org/Roles_and_Capabilities#manage_options)
|
395 |
|
396 |
= 1.3.2 =
|
|
|
397 |
- Could get php notice warning if rss secret was not set. Also: make sure both public and private secret exists.
|
398 |
|
399 |
= 1.3.1 =
|
|
|
400 |
- Improved contrast for details view
|
401 |
- Fix sql error on installation due to missing column
|
402 |
- Remove options and database table during removal of plugin
|
403 |
- Added: German translation for extender module
|
404 |
|
405 |
= 1.3 =
|
|
|
406 |
- Added: history events can store text description with a more detailed explanation of the history item
|
407 |
- Added: now logs failed login attempts for existing username. Uses the new text description to store more info, for example user agent and remote ip address (REMOTE_ADDR)
|
408 |
- Fixed: box did not change height when clicking on occasions
|
409 |
- Fixed: use on() instead of live() in JavaScript
|
410 |
|
411 |
= 1.2 =
|
|
|
412 |
- Fixed: Plugin name is included when plugins is activated or deactivated. Previosuly only folder name and name of php file was included.
|
413 |
- Added: Attachment thumbnails are now visible if history item is an attachment. Also includes some metadata.
|
414 |
- Changed: Filters now use dropdowns for type and user. When a site had lots of users and lots of post types, the filter section could be way to big.
|
@@ -419,6 +572,7 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
419 |
- POT-file updated
|
420 |
|
421 |
= 1.1 =
|
|
|
422 |
- Added the Simple History Extender-module/plugin. With this great addon to Simple History it is very easy for other developers to add their own actions to simple history, including a settings panel to check actions on/off. All work on this module was made by Laurens Offereins (lmoffereins@gmail.com). Super thanks!
|
423 |
- With the help of Simple History Extender this plugin also tracks changes made in bbPress, Gravity Forms and in Widges. Awesome!
|
424 |
- Added user email to RSS feed + some other small changed to make it compatible with IFTTT.com. Thanks to phoenixMagoo for the code changes. Fixes http://wordpress.org/support/topic/suggestions-a-couple-of-tweaks-to-the-rss-feed.
|
@@ -429,23 +583,29 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
429 |
- Added new filter: simple_history_db_purge_days_interval. Hook it to change default clear interval of 60 days.
|
430 |
|
431 |
= 1.0.9 =
|
|
|
432 |
- Added French translation
|
433 |
|
434 |
= 1.0.8 =
|
|
|
435 |
- Added: filter simple_history_allow_db_purge that is used to determine if the history should be purged/cleaned after 60 days or not. Return false and it will never be cleaned.
|
436 |
- Fixed: fixed a security issue with the RSS feed. User who should not be able to view the feed could get access to it. Please update to this version to keep your change log private!
|
437 |
|
438 |
= 1.0.7 =
|
|
|
439 |
- Fixed: Used a PHP shorthand opening tag at a place. Sorry!
|
440 |
- Fixed: Now loads scripts and styles over HTTPS, if that's being used. Thanks to "llch" for the patch.
|
441 |
|
442 |
= 1.0.6 =
|
|
|
443 |
- Added: option to set number of items to show, per page. Default i 5 history log items.
|
444 |
|
445 |
= 1.0.5 =
|
|
|
446 |
- Fixed: some translation issues, including updated POT-file for translators.
|
447 |
|
448 |
= 1.0.4 =
|
|
|
449 |
- You may want to clear the history database after this update because the items in the log will have mixed translate/untranslated status and it may look/work a bit strange.
|
450 |
- Added: Option to clear the database of log items.
|
451 |
- Changed: No longer stored translated history items in the log. This makes the history work even if/when you switch langauge of WordPress.
|
@@ -453,14 +613,17 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
453 |
- Some more items are translateable
|
454 |
|
455 |
= 1.0.3 =
|
|
|
456 |
- Updated German translation
|
457 |
- Some translation fixes
|
458 |
|
459 |
= 1.0.2 =
|
|
|
460 |
- Fixed a translation bug
|
461 |
- Added updated German translation
|
462 |
|
463 |
= 1.0.1 =
|
|
|
464 |
- The pagination no longer disappear after clickin "occasions"
|
465 |
- Fixed: AJAX loading of new history items didn't work.
|
466 |
- New filter: simple_history_view_history_capability. Default is "edit_pages". Modify this to change what cabability is required to view the history.
|
@@ -468,13 +631,16 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
468 |
- Updated: new POT file. So translators my want to update their translations...
|
469 |
|
470 |
= 1.0 =
|
|
|
471 |
- Added: pagination. Gives you more information, for example the number of items, and quicker access to older history items. Also looks more like the rest of the WordPress GUI.
|
472 |
- Modified: search now searches type of action (added, modified, deleted, etc.).
|
473 |
|
474 |
= 0.8.1 =
|
|
|
475 |
- Fixed some annoying errors that slipt through testing.
|
476 |
|
477 |
= 0.8 =
|
|
|
478 |
- Added: now also logs when a user saves any of the built in settings page (general, writing, reading, discussion, media, privacy, and permalinks. What more things do you want to see in the history? Let me know in the [support forum](http://wordpress.org/support/plugin/simple-history).
|
479 |
- Added: gravatar of user performing action is always shown
|
480 |
- Fixed: history items that was posts/pages/custom post types now get linked again
|
@@ -484,18 +650,22 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
484 |
- Also added donate-links. Tried to keep them discrete. Anyway: please [donate](http://eskapism.se/sida/donate/?utm_source=wordpress&utm_medium=changelog&utm_campaign=simplehistory) if you use this plugin regularly.
|
485 |
|
486 |
= 0.7.2 =
|
|
|
487 |
- Default settings should be to show on page, missed that one. Sorry!
|
488 |
|
489 |
= 0.7.1 =
|
|
|
490 |
- Fixed a PHP shorttag
|
491 |
|
492 |
= 0.7 =
|
|
|
493 |
- Do not show on dashboard by default to avoid clutter. Can be enabled in settings.
|
494 |
- Add link to settings from plugin list
|
495 |
- Settings are now available as it's own page under Settings -> Simple Fields. It was previosly on the General settings page and some people had difficulties finding it there.
|
496 |
- Added filters: simple_history_show_settings_page, simple_history_show_on_dashboard, simple_history_show_as_page
|
497 |
|
498 |
= 0.6 =
|
|
|
499 |
- Changed widget name to just "History" instead of "Simple History". Keep it simple. Previous name implied there also was an "Advanced History" somewhere.
|
500 |
- Made the widget look a bit WordPress-ish by borrwing some of the looks from the comments widget.
|
501 |
- Fix for database that didn't use UTF-8 (sorry international users!)
|
@@ -503,61 +673,75 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
503 |
- Updated POT-file
|
504 |
|
505 |
= 0.5 =
|
|
|
506 |
- Added author to RSS
|
507 |
- Added german translation, thanks http://www.fuerther-freiheit.info/
|
508 |
- Added swedish translation, thanks http://jockegustin.se
|
509 |
- Better support for translation
|
510 |
|
511 |
= 0.4 =
|
|
|
512 |
- Added: Now you can search the history
|
513 |
- Added: Choose if you wan't to load/show more than just 5 rows from the history
|
514 |
|
515 |
= 0.3.11 =
|
|
|
516 |
- Fixed: titles are now escaped
|
517 |
|
518 |
= 0.3.10 =
|
|
|
519 |
- Added chinese translation
|
520 |
- Fixed a variable notice
|
521 |
- More visible ok-message after setting a new RSS secret
|
522 |
|
523 |
= 0.3.9 =
|
|
|
524 |
- Attachment names were urlencoded and looked wierd. Now they're not.
|
525 |
- Started to store plugin version number
|
526 |
|
527 |
= 0.3.8 =
|
|
|
528 |
- Added chinese translation
|
529 |
- Uses WordPress own human_time_diff() instead of own version
|
530 |
- Fix for time zones
|
531 |
|
532 |
= 0.3.7 =
|
|
|
533 |
- Directly after installation of Simple History you could view the history RSS feed without using any secret. Now a secret is automatically set during installation.
|
534 |
|
535 |
= 0.3.6 =
|
|
|
536 |
- Made the RSS-feature a bit easier to find: added a RSS-icon to the dashboard window - it's very discrete, you can find it at the bottom right corner. On the Simple History page it's a bit more clear, at the bottom, with text and all. Enjoy!
|
537 |
- Added POT-file
|
538 |
|
539 |
= 0.3.5 =
|
|
|
540 |
- using get_the_title instead of fetching the title directly from the post object. should make plugins like qtranslate work a bit better.
|
541 |
-
- preparing for translation by using
|
542 |
- Could get cryptic "simpleHistoryNoMoreItems"-text when loading a type with no items.
|
543 |
|
544 |
= 0.3.4 =
|
|
|
545 |
- RSS-feed is now valid, and should work at more places (could be broken because of html entities and stuff)
|
546 |
|
547 |
= 0.3.3 =
|
|
|
548 |
- Moved JavaScript to own file
|
549 |
- Added comments to the history, so now you can see who approved a comment (or unapproved, or marked as spam, or moved to trash, or restored from the trash)
|
550 |
|
551 |
= 0.3.2 =
|
|
|
552 |
- fixed some php notice messages + some other small things I don't remember..
|
553 |
|
554 |
= 0.3.1 =
|
|
|
555 |
- forgot to escape html for posts
|
556 |
- reduced memory usage... I think/hope...
|
557 |
- changes internal verbs for actions. some old history items may look a bit weird.
|
558 |
- added RSS feed for recent changes - keep track of changes via your favorite RSS-reader
|
559 |
|
560 |
= 0.3 =
|
|
|
561 |
- page is now added under dashboard (was previously under tools). just feel better.
|
562 |
- mouse over on date now display detailed date a bit faster
|
563 |
- layout fixes to make it cooler, better, faster, stronger
|
@@ -565,14 +749,16 @@ I've spend hundreds of hours making this update, so if you use it and like it pl
|
|
565 |
- the name of deleted items now show up, instead of "Unknown name" or similar
|
566 |
- added support for plugins (who activated/deactivated what plugin)
|
567 |
- support for third party history items. Use like this:
|
568 |
-
simple_history_add("action=repaired&object_type=starship&object_name=USS Enterprise");
|
569 |
-
this would result in somehting like this:
|
570 |
-
Starship "USS Enterprise" repaired
|
571 |
-
by admin (John Doe), just now
|
572 |
- capability edit_pages needed to show history. Is this an appropriate capability do you think?
|
573 |
|
574 |
= 0.2 =
|
575 |
-
|
|
|
576 |
|
577 |
= 0.1 =
|
578 |
-
|
|
|
|
1 |
# Changelog for 2015 an earlier
|
2 |
|
3 |
+
= 2.13 (November 2016) =
|
4 |
+
|
5 |
+
- Added filter `simple_history_log` that is a simplified way to add message to the log, without the need to check for the existance of Simple History or its SimpleLogger function. Use it like this: `apply_filters("simple_history_log", "This is a logged message");` See the [examples file](https://github.com/bonny/WordPress-Simple-History/blob/master/examples/examples.php) for more examples.
|
6 |
+
- IP info now displays a popup with map + geolocation info for users using HTTPS again. Thanks to the great https://twitter.com/ipinfoio for letting all users use their service :)
|
7 |
+
- Fix notice warning for missing `$data_parent_row`
|
8 |
+
|
9 |
+
= 2.12 (September 2016) =
|
10 |
+
|
11 |
+
- You can show a different number of log items in the log on the dashboard and on the dedicated history page. By default the dashboard will show 5 items and the page will show 30.
|
12 |
+
- On multisites the user search filter now only search users in the current site.
|
13 |
+
- The statistics chart using Chart.js now uses the namespace window.Simple_History_Chart instead of window.Chart, decreasing the risk that two versions of the Chart.js library overwriting each others. Fixes https://wordpress.org/support/topic/comet-cache-breaks-simple-history/. (Note to future me: this was fixed by renaming the `window.chart` variable to `window.chart.Simple_history_chart` in the line `window.Chart = module.exports = Chart;`)
|
14 |
+
- If spam comments are logged they are now included in the log. Change made to make sql query shorter and easier. Should not actually show any spam comments anyway because we don't log them since version 2.5.5 anyway. If you want to revert this behavior for some reason you can use the filter `simple_history/comments_logger/include_spam`.
|
15 |
+
|
16 |
+
= 2.11 (September 2016) =
|
17 |
+
|
18 |
+
- Added support for plugin [Redirection](https://wordpress.org/plugins/redirection/).
|
19 |
+
Redirects and groups that are created, changed, enabled and disabled will be logged. Also when the plugin global settings are changed that will be logged.
|
20 |
+
- Fix possible notice error from User logger.
|
21 |
+
- "View changelog" link now works on multisite.
|
22 |
+
|
23 |
+
= 2.10 (September 2016) =
|
24 |
+
|
25 |
+
- Available updates to plugins, themes, and WordPress itself is now logged.
|
26 |
+
Pretty great if you subscribe to the RSS feed to get the changes on a site. No need to manually check the updates-page to see if there are any updates.
|
27 |
+
- Changed to logic used to determine if a post edit should be logged or not. Version 2.9 used a version that started to log a bit to much for some plugins. This should fix the problems with the Nextgen Gallery, All-In-One Events Calendar, and Membership 2 plugins. If you still have problems with a plugin that is causing to many events to be logged, please let me know!
|
28 |
+
|
29 |
+
= 2.9.1 (August 2016) =
|
30 |
+
|
31 |
+
- Fixed an issue where the logged time was off by some hours, due to timezone being manually set elsewhere.
|
32 |
+
Should fix https://wordpress.org/support/topic/logged-time-off-by-2-hours and https://wordpress.org/support/topic/different-time-between-dashboard-and-logger.
|
33 |
+
- Fixed Nextgen Gallery and Nextgen Gallery Plus logging lots and lots of event when viewing posts with galleries. The posts was actually updated, so this plugin did nothing wrong. But it was indeed a bit annoying and most likely something you didn't want in your log. Fixes https://wordpress.org/support/topic/non-stop-logging-nextgen-gallery-items.
|
34 |
+
|
35 |
+
= 2.9 (August 2016) =
|
36 |
+
|
37 |
+
- Added custom date ranges to the dates filter. Just select "Custom date range..." in the dates dropdown and you can choose to see the log between any two exact dates.
|
38 |
+
- The values in the statistics graph can now be clicked and when clicked the log is filtered to only show logged events from that day. Very convenient if you have a larger number of events logged for one day and quickly want to find out what exactly was logged that day.
|
39 |
+
- Dates filter no longer accepts multi values. It was indeed a bit confusing that you could select both "Last 7 days" and "Last 3 days".
|
40 |
+
- Fix for empty previous plugin version (the `{plugin_prev_version}` placeholder) when updating plugins.
|
41 |
+
- Post and pages updates done in the WordPress apps for Ios and Android should be logged again.
|
42 |
+
|
43 |
+
= 2.8 (August 2016) =
|
44 |
+
|
45 |
+
- Theme installs are now logged
|
46 |
+
- ...and so are theme updates
|
47 |
+
- ...and theme deletions. Awesome!
|
48 |
+
- Support for plugin [Limit Login Attempts](https://wordpress.org/plugins/limit-login-attempts/).
|
49 |
+
Failed login attempts, lockouts and configuration changes will be logged.
|
50 |
+
- Correct message is now used when a plugin update fails, i.e. the message for key `plugin_update_failed`.
|
51 |
+
- The original untranslated strings for plugin name and so on are stored when storing info for plugin installs and updates and similar.
|
52 |
+
- Default number of events to show is now 10 instead of 5.
|
53 |
+
|
54 |
+
= 2.7.5 (August 2016) =
|
55 |
+
|
56 |
+
- User logins using e-mail are now logged correctly. Previously the user would be logged in successfully but the log said that they failed.
|
57 |
+
- Security fix: only users with [`list_users`](https://codex.wordpress.org/Roles_and_Capabilities#list_users) capability can view the users filter and use the autocomplete api for users.
|
58 |
+
Previously the autocomplete function could be used by all logged in users.
|
59 |
+
- Add labels to search filters. (I do really hate label-less forms so it's kinda very strange that this was not in place before.)
|
60 |
+
- Misc other internal fixes
|
61 |
+
|
62 |
+
= 2.7.4 (July 2016) =
|
63 |
+
|
64 |
+
- Log a warning message if a plugin gets disabled automatically by WordPress because of any of these errors: "Plugin file does not exist.", "Invalid plugin path.", "The plugin does not have a valid header."
|
65 |
+
- Fix warning error if `on_wp_login()` was called without second argument.
|
66 |
+
- Fix options diff not being shown correctly.
|
67 |
+
- Fix notice if no message key did exist for a log message.
|
68 |
+
|
69 |
+
= 2.7.3 (June 2016) =
|
70 |
+
|
71 |
+
- Removed the usage of the mb\_\* functions and mbstring is no longer a requirement.
|
72 |
+
- Added a new debug tab to the settings page. On the debug page you can see stuff like how large your database is and how many rows that are stored in the database. Also, a list of all loggers are listed there together with some useful (for developers anyway) information.
|
73 |
+
|
74 |
+
= 2.7.2 (June 2016) =
|
75 |
+
|
76 |
+
- Fixed message about mbstring required not being echo'ed.
|
77 |
+
- Fixed notice errors for users not allowed to view the log.
|
78 |
+
|
79 |
+
= 2.7.1 (June 2016) =
|
80 |
+
|
81 |
+
- Added: Add shortcut to history in Admin bar for current site and in Network Admin Bar for each site where plugin is installed. Can be disabled using filters `simple_history/add_admin_bar_menu_item` and `simple_history/add_admin_bar_network_menu_item`.
|
82 |
+
- Added: Add check that [´mbstring´](http://php.net/manual/en/book.mbstring.php) is enabled and show a warning if it's not.
|
83 |
+
- Changed: Changes to "Front Page Displays" in "Reading Settings" now show the name of the old and new page (before only id was logged).
|
84 |
+
- Changed: Changes to "Default Post Category" and "Default Mail Category" in "Writing Settings" now show the name of the old and new category (before only id was logged).
|
85 |
+
- Fixed: When changing "Front Page Displays" in "Reading Settings" the option "rewrite_rules" also got logged.
|
86 |
+
- Fixed: Changes in Permalink Settings were not logged correctly.
|
87 |
+
- Fixed: Actions done with [WP-CLI](https://wp-cli.org/) was not correctly attributed. Now the log should say "WP-CLI" intead of "Other" for actions done in WP CLI.
|
88 |
+
|
89 |
+
= 2.7 (May 2016) =
|
90 |
+
|
91 |
+
- Added: When a user is created or edited the log now shows what fields have changed and from what old value to what new value. A much requested feature!
|
92 |
+
- Fixed: If you edited your own profile the log would say that you edited "their profile". Now it says that you edited "your profile" instead.
|
93 |
+
- Changed: Post diffs could get very tall. Now they are max approx 8 rows by default, but if you hover the diff (or give it focus with your keyboard) you get a scrollbar and can scroll the contents. Fixes https://wordpress.org/support/topic/dashboard-max-length-of-content and https://wordpress.org/support/topic/feature-request-make-content-diff-report-expandable-and-closed-by-default.
|
94 |
+
- Fixed: Maybe fix a notice varning if a transient was missing a name or value.
|
95 |
+
|
96 |
+
= 2.6 (May 2016) =
|
97 |
+
|
98 |
+
- Added: A nice little graph in the sidebar that displays the number of logged events per day the last 28 days. Graph is powered by [Chart.js](http://www.chartjs.org/).
|
99 |
+
- Added: Function `get_num_events_last_n_days()`
|
100 |
+
- Added: Function `get_num_events_per_day_last_n_days()`
|
101 |
+
- Changed: Switched to transients from cache at some places, because more people will benefit from transients instead of cache (that requires object cache to be installed).
|
102 |
+
- Changed: New constant `SETTINGS_GENERAL_OPTION_GROUP`. Fixes https://wordpress.org/support/topic/constant-for-settings-option-group-name-option_group.
|
103 |
+
- Fixed: Long log messages with no spaces would get cut of. Now all the message is shown, but with one or several line breaks. Fixes https://github.com/bonny/WordPress-Simple-History/pull/112.
|
104 |
+
- Fixed: Some small CSS modification to make the page less "jumpy" while loading (for example setting a default height to the select2 input box).
|
105 |
+
|
106 |
+
= 2.5.5 (April 2016) =
|
107 |
+
|
108 |
+
- Changed: The logger for Enable Media Replace required the capability `edit_files` to view the logged events, but since this also made it impossible to view events if the constant `DISALLOW_FILE_EDIT` was true. Now Enable Media Replace requires the capability `upload_files` instead. Makes more sense. Fixes https://wordpress.org/support/topic/simple-history-and-disallow_file_edit.
|
109 |
+
- Changed: No longer log spam trackbacks or comments. Before this version these where logged, but not shown.
|
110 |
+
- Fixed: Translations was not loaded for Select2. Fixes https://wordpress.org/support/topic/found-a-string-thats-not-translatable-v-254.
|
111 |
+
- Fixed: LogQuery `date_to`-argument was using `date_from`.
|
112 |
+
- Changed: The changelog for 2015 and earlier are now moved to [CHANGELOG.md](https://github.com/bonny/WordPress-Simple-History/blob/master/CHANGELOG.md).
|
113 |
+
|
114 |
+
= 2.5.4 (March 2016) =
|
115 |
+
|
116 |
+
- Added: Support for new key in info array from logger: "name_via". Set this value in a logger and the string will be shown next to the date of the logged event. Useful when logging actions from third party plugins, or any kind of other logging that is not from WordPress core.
|
117 |
+
- Added: Method `getInfoValueByKey` added to the SimpleLogger class, for easier retrieval of values from the info array of a logger.
|
118 |
+
- Fixed: Themes could no be deleted. Fixes https://github.com/bonny/WordPress-Simple-History/issues/98 and https://wordpress.org/support/topic/deleting-theme-1.
|
119 |
+
- Fixed: Notice error when generating permalink for event.
|
120 |
+
- Fixed: Removed a `console.log()`.
|
121 |
+
- Changed: Check that array key is integer or string. Hopefully fixes https://wordpress.org/support/topic/error-in-wp-adminerror_log.
|
122 |
+
|
123 |
+
= 2.5.3 (February 2016) =
|
124 |
+
|
125 |
+
- Fixed: Old entries was not correctly removed. Fixes https://github.com/bonny/WordPress-Simple-History/issues/108.
|
126 |
+
|
127 |
+
= 2.5.2 (February 2016) =
|
128 |
+
|
129 |
+
- Added: The GUI log now updates the relative "fuzzy" timestamps in real time. This means that if you keep the log opened, the relative date for each event, for example "2 minutes ago" or "2 hours ago", will always be up to date (hah!). Keep the log opened for 5 minutes and you will see that the event that previously said "2 minutes ago" now says "7 minutes ago". Fixes https://github.com/bonny/WordPress-Simple-History/issues/88 and is implemented using the great [timeago jquery plugin](http://timeago.yarp.com/).
|
130 |
+
- Added: Filter `simple_history/user_logger/plain_text_output_use_you`. Works the same way as the `simple_history/header_initiator_use_you` filter, but for the rich text part when a user has edited their profile.
|
131 |
+
- Fixed: Logger slugs that contained for example backslashes (becuase they where namespaced) would not show up in the log. Now logger slugs are escaped. Fixes https://github.com/bonny/WordPress-Simple-History/issues/103.
|
132 |
+
- Changed: Actions and things that only is needed in admin area are now only called if `is_admin()`. Fixes https://github.com/bonny/WordPress-Simple-History/issues/105.
|
133 |
+
|
134 |
+
= 2.5.1 (February 2016) =
|
135 |
+
|
136 |
+
- Fixed: No longer assume that the ajaxurl don't already contains query params. Should fix problems with third party plugins like [WPML](https://wpml.org/).
|
137 |
+
- Fixed: Notice if context key did not exist. Should fix https://github.com/bonny/WordPress-Simple-History/issues/100.
|
138 |
+
- Fixed: Name and title on dashboard and settings page were not translateable. Fixes https://wordpress.org/support/topic/dashboard-max-length-of-content.
|
139 |
+
- Fixed: Typo when user resets password.
|
140 |
+
- Added: Filter `simple_history/row_header_date_output`.
|
141 |
+
- Added: Filter `simple_history/log/inserted`.
|
142 |
+
- Added: Filter `simple_history/row_header_date_output`.
|
143 |
+
|
144 |
= 2.5 (December 2015) =
|
145 |
|
146 |
- Added: Category edits are now logged, so now you can see terms, categories and taxonomies that are added, changed, and deleted. Fixes for example https://wordpress.org/support/topic/view-changes-to-categories and https://twitter.com/hmarafi/status/655994402037362688.
|
332 |
- Fixed: Plugin installs from uploaded ZIP files are now logged correctly. Fixes https://github.com/bonny/WordPress-Simple-History/issues/59.
|
333 |
- Fixed: Check that JavaScript variables it set and that the object have properties set. Fixes https://wordpress.org/support/topic/firefox-37-js-error-generated-by-simplehistoryipinfodropinjs.
|
334 |
- Updated: German translation updated.
|
335 |
+
- Changed: Loading of loggers, dropins, and so one are moved from action `plugins_loaded` to `after_setup_theme` so themes can actually use for example the load*dropin*\*-filters...
|
336 |
- Changed: Misc small design fixes.
|
337 |
|
338 |
= 2.0.23 (March 2015) =
|
454 |
- Added: [WordPress 4.1 added the feature to log out a user from all their sessions](http://codex.wordpress.org/Version_4.1#Users). Simple History now logs when a user is logged out from all their sessions except the current browser, or if an admin destroys all sessions for a user. [View screenshot of new session logout log item](https://dl.dropboxusercontent.com/s/k4cmfmncekmfiib/2014-12-simple-history-changelog-user-sessions.png)
|
455 |
|
456 |
- Added: filter to shortcut loading of a dropin. Example that completely skips loading the RSS-feed-dropin:
|
457 |
+
`add_filter("simple_history/dropin/load_dropin_SimpleHistoryRSSDropin", "__return_false");`
|
458 |
|
459 |
= 2.0.5 (November 2014) =
|
460 |
|
496 |
- Much much more.
|
497 |
|
498 |
= 1.3.11 =
|
499 |
+
|
500 |
- Don't use deprecated function get_commentdata(). Fixes https://wordpress.org/support/topic/get_commentdata-function-is-deprecated.
|
501 |
- Don't use mysql_query() directly. Fixes https://wordpress.org/support/topic/deprecated-mysql-warning.
|
502 |
- Beta testers wanted! I'm working on the next version of Simple History and now I need some beta testers. If you want to try out the shiny new and cool version please download the [v2 branch](https://github.com/bonny/WordPress-Simple-History/tree/v2) over at GitHub. Thanks!
|
503 |
|
504 |
= 1.3.10 =
|
505 |
+
|
506 |
- Fix: correct usage of "its"
|
507 |
- Fix: removed serif font in log. Fixes https://wordpress.org/support/topic/two-irritations-and-pleas-for-change.
|
508 |
|
509 |
= 1.3.9 =
|
510 |
+
|
511 |
- Fixed strict standards warning
|
512 |
- Tested on WordPress 4.0
|
513 |
|
514 |
= 1.3.8 =
|
515 |
+
|
516 |
- Added filter for rss feed: `simple_history/rss_feed_show`. Fixes more things in this thread: http://wordpress.org/support/topic/more-rss-feed-items.
|
517 |
|
518 |
= 1.3.7 =
|
519 |
+
|
520 |
- Added filter for rss feed: `simple_history/rss_feed_args`. Fixes http://wordpress.org/support/topic/more-rss-feed-items.
|
521 |
|
522 |
= 1.3.6 =
|
523 |
+
|
524 |
- Added Polish translation
|
525 |
- Added correct XML encoding and header
|
526 |
- Fixed notice warnings when media did not exist on file system
|
527 |
|
528 |
= 1.3.5 =
|
529 |
+
|
530 |
- Added a reload-button at top. Click it to reload the history. No need to refresh page no more!
|
531 |
- Fixed items being reloaded when just clicking the dropdown (not having selected anything yet)
|
532 |
- Fixed bug with keyboard navigation
|
534 |
- Use less SQL queries
|
535 |
|
536 |
= 1.3.4 =
|
537 |
+
|
538 |
- Changed the way post types show in the dropdown. Now uses plural names + not prefixed with main post type. Looks better I think. Thank to Hassan for the suggestion!
|
539 |
- Added "bytes" to size units that an attachment can have. Also fixes undefined notice warning when attachment had a size less that 1 KB.
|
540 |
|
541 |
= 1.3.3 =
|
542 |
+
|
543 |
- Capability for viewing settings changed from edit_pages to the more correct [manage_options](http://codex.wordpress.org/Roles_and_Capabilities#manage_options)
|
544 |
|
545 |
= 1.3.2 =
|
546 |
+
|
547 |
- Could get php notice warning if rss secret was not set. Also: make sure both public and private secret exists.
|
548 |
|
549 |
= 1.3.1 =
|
550 |
+
|
551 |
- Improved contrast for details view
|
552 |
- Fix sql error on installation due to missing column
|
553 |
- Remove options and database table during removal of plugin
|
554 |
- Added: German translation for extender module
|
555 |
|
556 |
= 1.3 =
|
557 |
+
|
558 |
- Added: history events can store text description with a more detailed explanation of the history item
|
559 |
- Added: now logs failed login attempts for existing username. Uses the new text description to store more info, for example user agent and remote ip address (REMOTE_ADDR)
|
560 |
- Fixed: box did not change height when clicking on occasions
|
561 |
- Fixed: use on() instead of live() in JavaScript
|
562 |
|
563 |
= 1.2 =
|
564 |
+
|
565 |
- Fixed: Plugin name is included when plugins is activated or deactivated. Previosuly only folder name and name of php file was included.
|
566 |
- Added: Attachment thumbnails are now visible if history item is an attachment. Also includes some metadata.
|
567 |
- Changed: Filters now use dropdowns for type and user. When a site had lots of users and lots of post types, the filter section could be way to big.
|
572 |
- POT-file updated
|
573 |
|
574 |
= 1.1 =
|
575 |
+
|
576 |
- Added the Simple History Extender-module/plugin. With this great addon to Simple History it is very easy for other developers to add their own actions to simple history, including a settings panel to check actions on/off. All work on this module was made by Laurens Offereins (lmoffereins@gmail.com). Super thanks!
|
577 |
- With the help of Simple History Extender this plugin also tracks changes made in bbPress, Gravity Forms and in Widges. Awesome!
|
578 |
- Added user email to RSS feed + some other small changed to make it compatible with IFTTT.com. Thanks to phoenixMagoo for the code changes. Fixes http://wordpress.org/support/topic/suggestions-a-couple-of-tweaks-to-the-rss-feed.
|
583 |
- Added new filter: simple_history_db_purge_days_interval. Hook it to change default clear interval of 60 days.
|
584 |
|
585 |
= 1.0.9 =
|
586 |
+
|
587 |
- Added French translation
|
588 |
|
589 |
= 1.0.8 =
|
590 |
+
|
591 |
- Added: filter simple_history_allow_db_purge that is used to determine if the history should be purged/cleaned after 60 days or not. Return false and it will never be cleaned.
|
592 |
- Fixed: fixed a security issue with the RSS feed. User who should not be able to view the feed could get access to it. Please update to this version to keep your change log private!
|
593 |
|
594 |
= 1.0.7 =
|
595 |
+
|
596 |
- Fixed: Used a PHP shorthand opening tag at a place. Sorry!
|
597 |
- Fixed: Now loads scripts and styles over HTTPS, if that's being used. Thanks to "llch" for the patch.
|
598 |
|
599 |
= 1.0.6 =
|
600 |
+
|
601 |
- Added: option to set number of items to show, per page. Default i 5 history log items.
|
602 |
|
603 |
= 1.0.5 =
|
604 |
+
|
605 |
- Fixed: some translation issues, including updated POT-file for translators.
|
606 |
|
607 |
= 1.0.4 =
|
608 |
+
|
609 |
- You may want to clear the history database after this update because the items in the log will have mixed translate/untranslated status and it may look/work a bit strange.
|
610 |
- Added: Option to clear the database of log items.
|
611 |
- Changed: No longer stored translated history items in the log. This makes the history work even if/when you switch langauge of WordPress.
|
613 |
- Some more items are translateable
|
614 |
|
615 |
= 1.0.3 =
|
616 |
+
|
617 |
- Updated German translation
|
618 |
- Some translation fixes
|
619 |
|
620 |
= 1.0.2 =
|
621 |
+
|
622 |
- Fixed a translation bug
|
623 |
- Added updated German translation
|
624 |
|
625 |
= 1.0.1 =
|
626 |
+
|
627 |
- The pagination no longer disappear after clickin "occasions"
|
628 |
- Fixed: AJAX loading of new history items didn't work.
|
629 |
- New filter: simple_history_view_history_capability. Default is "edit_pages". Modify this to change what cabability is required to view the history.
|
631 |
- Updated: new POT file. So translators my want to update their translations...
|
632 |
|
633 |
= 1.0 =
|
634 |
+
|
635 |
- Added: pagination. Gives you more information, for example the number of items, and quicker access to older history items. Also looks more like the rest of the WordPress GUI.
|
636 |
- Modified: search now searches type of action (added, modified, deleted, etc.).
|
637 |
|
638 |
= 0.8.1 =
|
639 |
+
|
640 |
- Fixed some annoying errors that slipt through testing.
|
641 |
|
642 |
= 0.8 =
|
643 |
+
|
644 |
- Added: now also logs when a user saves any of the built in settings page (general, writing, reading, discussion, media, privacy, and permalinks. What more things do you want to see in the history? Let me know in the [support forum](http://wordpress.org/support/plugin/simple-history).
|
645 |
- Added: gravatar of user performing action is always shown
|
646 |
- Fixed: history items that was posts/pages/custom post types now get linked again
|
650 |
- Also added donate-links. Tried to keep them discrete. Anyway: please [donate](http://eskapism.se/sida/donate/?utm_source=wordpress&utm_medium=changelog&utm_campaign=simplehistory) if you use this plugin regularly.
|
651 |
|
652 |
= 0.7.2 =
|
653 |
+
|
654 |
- Default settings should be to show on page, missed that one. Sorry!
|
655 |
|
656 |
= 0.7.1 =
|
657 |
+
|
658 |
- Fixed a PHP shorttag
|
659 |
|
660 |
= 0.7 =
|
661 |
+
|
662 |
- Do not show on dashboard by default to avoid clutter. Can be enabled in settings.
|
663 |
- Add link to settings from plugin list
|
664 |
- Settings are now available as it's own page under Settings -> Simple Fields. It was previosly on the General settings page and some people had difficulties finding it there.
|
665 |
- Added filters: simple_history_show_settings_page, simple_history_show_on_dashboard, simple_history_show_as_page
|
666 |
|
667 |
= 0.6 =
|
668 |
+
|
669 |
- Changed widget name to just "History" instead of "Simple History". Keep it simple. Previous name implied there also was an "Advanced History" somewhere.
|
670 |
- Made the widget look a bit WordPress-ish by borrwing some of the looks from the comments widget.
|
671 |
- Fix for database that didn't use UTF-8 (sorry international users!)
|
673 |
- Updated POT-file
|
674 |
|
675 |
= 0.5 =
|
676 |
+
|
677 |
- Added author to RSS
|
678 |
- Added german translation, thanks http://www.fuerther-freiheit.info/
|
679 |
- Added swedish translation, thanks http://jockegustin.se
|
680 |
- Better support for translation
|
681 |
|
682 |
= 0.4 =
|
683 |
+
|
684 |
- Added: Now you can search the history
|
685 |
- Added: Choose if you wan't to load/show more than just 5 rows from the history
|
686 |
|
687 |
= 0.3.11 =
|
688 |
+
|
689 |
- Fixed: titles are now escaped
|
690 |
|
691 |
= 0.3.10 =
|
692 |
+
|
693 |
- Added chinese translation
|
694 |
- Fixed a variable notice
|
695 |
- More visible ok-message after setting a new RSS secret
|
696 |
|
697 |
= 0.3.9 =
|
698 |
+
|
699 |
- Attachment names were urlencoded and looked wierd. Now they're not.
|
700 |
- Started to store plugin version number
|
701 |
|
702 |
= 0.3.8 =
|
703 |
+
|
704 |
- Added chinese translation
|
705 |
- Uses WordPress own human_time_diff() instead of own version
|
706 |
- Fix for time zones
|
707 |
|
708 |
= 0.3.7 =
|
709 |
+
|
710 |
- Directly after installation of Simple History you could view the history RSS feed without using any secret. Now a secret is automatically set during installation.
|
711 |
|
712 |
= 0.3.6 =
|
713 |
+
|
714 |
- Made the RSS-feature a bit easier to find: added a RSS-icon to the dashboard window - it's very discrete, you can find it at the bottom right corner. On the Simple History page it's a bit more clear, at the bottom, with text and all. Enjoy!
|
715 |
- Added POT-file
|
716 |
|
717 |
= 0.3.5 =
|
718 |
+
|
719 |
- using get_the_title instead of fetching the title directly from the post object. should make plugins like qtranslate work a bit better.
|
720 |
+
- preparing for translation by using \_\_() and \_e() functions. POT-file will be available shortly.
|
721 |
- Could get cryptic "simpleHistoryNoMoreItems"-text when loading a type with no items.
|
722 |
|
723 |
= 0.3.4 =
|
724 |
+
|
725 |
- RSS-feed is now valid, and should work at more places (could be broken because of html entities and stuff)
|
726 |
|
727 |
= 0.3.3 =
|
728 |
+
|
729 |
- Moved JavaScript to own file
|
730 |
- Added comments to the history, so now you can see who approved a comment (or unapproved, or marked as spam, or moved to trash, or restored from the trash)
|
731 |
|
732 |
= 0.3.2 =
|
733 |
+
|
734 |
- fixed some php notice messages + some other small things I don't remember..
|
735 |
|
736 |
= 0.3.1 =
|
737 |
+
|
738 |
- forgot to escape html for posts
|
739 |
- reduced memory usage... I think/hope...
|
740 |
- changes internal verbs for actions. some old history items may look a bit weird.
|
741 |
- added RSS feed for recent changes - keep track of changes via your favorite RSS-reader
|
742 |
|
743 |
= 0.3 =
|
744 |
+
|
745 |
- page is now added under dashboard (was previously under tools). just feel better.
|
746 |
- mouse over on date now display detailed date a bit faster
|
747 |
- layout fixes to make it cooler, better, faster, stronger
|
749 |
- the name of deleted items now show up, instead of "Unknown name" or similar
|
750 |
- added support for plugins (who activated/deactivated what plugin)
|
751 |
- support for third party history items. Use like this:
|
752 |
+
simple_history_add("action=repaired&object_type=starship&object_name=USS Enterprise");
|
753 |
+
this would result in somehting like this:
|
754 |
+
Starship "USS Enterprise" repaired
|
755 |
+
by admin (John Doe), just now
|
756 |
- capability edit_pages needed to show history. Is this an appropriate capability do you think?
|
757 |
|
758 |
= 0.2 =
|
759 |
+
|
760 |
+
- Compatible with 2.9.2
|
761 |
|
762 |
= 0.1 =
|
763 |
+
|
764 |
+
- First public version. It works!
|
code.md
CHANGED
@@ -35,3 +35,11 @@ Fix things:
|
|
35 |
|
36 |
- Will try to follow OneFlow:
|
37 |
https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
- Will try to follow OneFlow:
|
37 |
https://www.endoflineblog.com/oneflow-a-git-branching-model-and-workflow
|
38 |
+
|
39 |
+
## Update match 2021
|
40 |
+
|
41 |
+
Code standards is updated to WordPress own.
|
42 |
+
|
43 |
+
Uses composer package `dealerdirect/phpcodesniffer-composer-installer` to find PHP_CodeSniffer rules automagically. Just run `composer install` and then `vendor/bin/phpcs`.
|
44 |
+
|
45 |
+
Use PHP 7 for now, the WordPress rules crashes on PHP 8 so far (bug fixed but no version with fix released).
|
composer.json
CHANGED
@@ -7,11 +7,13 @@
|
|
7 |
"log",
|
8 |
"history"
|
9 |
],
|
10 |
-
"homepage": "
|
11 |
"minimum-stability": "dev",
|
12 |
"require-dev": {
|
13 |
-
"
|
14 |
-
"
|
|
|
|
|
15 |
},
|
16 |
"require": {
|
17 |
"php": ">=5.2.0"
|
@@ -19,11 +21,14 @@
|
|
19 |
"authors": [
|
20 |
{
|
21 |
"name": "Pär Thernström",
|
22 |
-
"
|
23 |
-
"homepage": "https://eskapism.se/",
|
24 |
-
"role": "Developer"
|
25 |
}
|
26 |
],
|
|
|
|
|
|
|
|
|
|
|
27 |
"dist": {
|
28 |
"url": "https://downloads.wordpress.org/plugin/simple-history.zip",
|
29 |
"type": "zip"
|
@@ -32,5 +37,10 @@
|
|
32 |
"lint": "./vendor/bin/phpcs .",
|
33 |
"lint-fix": "./vendor/bin/phpcbf .",
|
34 |
"test": "./vendor/bin/phpunit"
|
|
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
}
|
7 |
"log",
|
8 |
"history"
|
9 |
],
|
10 |
+
"homepage": "https://simple-history.com/",
|
11 |
"minimum-stability": "dev",
|
12 |
"require-dev": {
|
13 |
+
"dealerdirect/phpcodesniffer-composer-installer": "*",
|
14 |
+
"phpcompatibility/php-compatibility": "*",
|
15 |
+
"wp-coding-standards/wpcs": "*",
|
16 |
+
"phpcompatibility/phpcompatibility-wp": "*"
|
17 |
},
|
18 |
"require": {
|
19 |
"php": ">=5.2.0"
|
21 |
"authors": [
|
22 |
{
|
23 |
"name": "Pär Thernström",
|
24 |
+
"homepage": "https://eskapism.se/"
|
|
|
|
|
25 |
}
|
26 |
],
|
27 |
+
"support": {
|
28 |
+
"issues": "https://github.com/bonny/WordPress-Simple-History/issues",
|
29 |
+
"forum": "https://wordpress.org/support/plugin/simple-history/",
|
30 |
+
"source": "https://github.com/bonny/WordPress-Simple-History"
|
31 |
+
},
|
32 |
"dist": {
|
33 |
"url": "https://downloads.wordpress.org/plugin/simple-history.zip",
|
34 |
"type": "zip"
|
37 |
"lint": "./vendor/bin/phpcs .",
|
38 |
"lint-fix": "./vendor/bin/phpcbf .",
|
39 |
"test": "./vendor/bin/phpunit"
|
40 |
+
},
|
41 |
+
"config": {
|
42 |
+
"allow-plugins": {
|
43 |
+
"dealerdirect/phpcodesniffer-composer-installer": true
|
44 |
+
}
|
45 |
}
|
46 |
}
|
composer.lock
CHANGED
@@ -1,1770 +1,342 @@
|
|
1 |
{
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
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 |
-
|
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 |
-
"authors": [
|
343 |
-
{
|
344 |
-
"name": "Mike van Riel",
|
345 |
-
"email": "me@mikevanriel.com"
|
346 |
-
},
|
347 |
-
{
|
348 |
-
"name": "Jaap van Otterdijk",
|
349 |
-
"email": "account@ijaap.nl"
|
350 |
-
}
|
351 |
-
],
|
352 |
-
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
353 |
-
"support": {
|
354 |
-
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
|
355 |
-
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
|
356 |
-
},
|
357 |
-
"time": "2020-11-18T14:27:38+00:00"
|
358 |
-
},
|
359 |
-
{
|
360 |
-
"name": "phpdocumentor/type-resolver",
|
361 |
-
"version": "1.x-dev",
|
362 |
-
"source": {
|
363 |
-
"type": "git",
|
364 |
-
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
365 |
-
"reference": "6759f2268deb9f329812679e9dcb2d0083b2a30b"
|
366 |
-
},
|
367 |
-
"dist": {
|
368 |
-
"type": "zip",
|
369 |
-
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6759f2268deb9f329812679e9dcb2d0083b2a30b",
|
370 |
-
"reference": "6759f2268deb9f329812679e9dcb2d0083b2a30b",
|
371 |
-
"shasum": ""
|
372 |
-
},
|
373 |
-
"require": {
|
374 |
-
"php": "^7.2 || ^8.0",
|
375 |
-
"phpdocumentor/reflection-common": "^2.0"
|
376 |
-
},
|
377 |
-
"require-dev": {
|
378 |
-
"ext-tokenizer": "*"
|
379 |
-
},
|
380 |
-
"default-branch": true,
|
381 |
-
"type": "library",
|
382 |
-
"extra": {
|
383 |
-
"branch-alias": {
|
384 |
-
"dev-1.x": "1.x-dev"
|
385 |
-
}
|
386 |
-
},
|
387 |
-
"autoload": {
|
388 |
-
"psr-4": {
|
389 |
-
"phpDocumentor\\Reflection\\": "src"
|
390 |
-
}
|
391 |
-
},
|
392 |
-
"notification-url": "https://packagist.org/downloads/",
|
393 |
-
"license": [
|
394 |
-
"MIT"
|
395 |
-
],
|
396 |
-
"authors": [
|
397 |
-
{
|
398 |
-
"name": "Mike van Riel",
|
399 |
-
"email": "me@mikevanriel.com"
|
400 |
-
}
|
401 |
-
],
|
402 |
-
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
403 |
-
"support": {
|
404 |
-
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
|
405 |
-
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.x"
|
406 |
-
},
|
407 |
-
"time": "2021-02-02T21:09:27+00:00"
|
408 |
-
},
|
409 |
-
{
|
410 |
-
"name": "phpspec/prophecy",
|
411 |
-
"version": "1.12.2",
|
412 |
-
"source": {
|
413 |
-
"type": "git",
|
414 |
-
"url": "https://github.com/phpspec/prophecy.git",
|
415 |
-
"reference": "245710e971a030f42e08f4912863805570f23d39"
|
416 |
-
},
|
417 |
-
"dist": {
|
418 |
-
"type": "zip",
|
419 |
-
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
|
420 |
-
"reference": "245710e971a030f42e08f4912863805570f23d39",
|
421 |
-
"shasum": ""
|
422 |
-
},
|
423 |
-
"require": {
|
424 |
-
"doctrine/instantiator": "^1.2",
|
425 |
-
"php": "^7.2 || ~8.0, <8.1",
|
426 |
-
"phpdocumentor/reflection-docblock": "^5.2",
|
427 |
-
"sebastian/comparator": "^3.0 || ^4.0",
|
428 |
-
"sebastian/recursion-context": "^3.0 || ^4.0"
|
429 |
-
},
|
430 |
-
"require-dev": {
|
431 |
-
"phpspec/phpspec": "^6.0",
|
432 |
-
"phpunit/phpunit": "^8.0 || ^9.0"
|
433 |
-
},
|
434 |
-
"type": "library",
|
435 |
-
"extra": {
|
436 |
-
"branch-alias": {
|
437 |
-
"dev-master": "1.11.x-dev"
|
438 |
-
}
|
439 |
-
},
|
440 |
-
"autoload": {
|
441 |
-
"psr-4": {
|
442 |
-
"Prophecy\\": "src/Prophecy"
|
443 |
-
}
|
444 |
-
},
|
445 |
-
"notification-url": "https://packagist.org/downloads/",
|
446 |
-
"license": [
|
447 |
-
"MIT"
|
448 |
-
],
|
449 |
-
"authors": [
|
450 |
-
{
|
451 |
-
"name": "Konstantin Kudryashov",
|
452 |
-
"email": "ever.zet@gmail.com",
|
453 |
-
"homepage": "http://everzet.com"
|
454 |
-
},
|
455 |
-
{
|
456 |
-
"name": "Marcello Duarte",
|
457 |
-
"email": "marcello.duarte@gmail.com"
|
458 |
-
}
|
459 |
-
],
|
460 |
-
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
461 |
-
"homepage": "https://github.com/phpspec/prophecy",
|
462 |
-
"keywords": [
|
463 |
-
"Double",
|
464 |
-
"Dummy",
|
465 |
-
"fake",
|
466 |
-
"mock",
|
467 |
-
"spy",
|
468 |
-
"stub"
|
469 |
-
],
|
470 |
-
"support": {
|
471 |
-
"issues": "https://github.com/phpspec/prophecy/issues",
|
472 |
-
"source": "https://github.com/phpspec/prophecy/tree/1.12.2"
|
473 |
-
},
|
474 |
-
"time": "2020-12-19T10:15:11+00:00"
|
475 |
-
},
|
476 |
-
{
|
477 |
-
"name": "phpunit/php-code-coverage",
|
478 |
-
"version": "6.1.4",
|
479 |
-
"source": {
|
480 |
-
"type": "git",
|
481 |
-
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
482 |
-
"reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
|
483 |
-
},
|
484 |
-
"dist": {
|
485 |
-
"type": "zip",
|
486 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
|
487 |
-
"reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
|
488 |
-
"shasum": ""
|
489 |
-
},
|
490 |
-
"require": {
|
491 |
-
"ext-dom": "*",
|
492 |
-
"ext-xmlwriter": "*",
|
493 |
-
"php": "^7.1",
|
494 |
-
"phpunit/php-file-iterator": "^2.0",
|
495 |
-
"phpunit/php-text-template": "^1.2.1",
|
496 |
-
"phpunit/php-token-stream": "^3.0",
|
497 |
-
"sebastian/code-unit-reverse-lookup": "^1.0.1",
|
498 |
-
"sebastian/environment": "^3.1 || ^4.0",
|
499 |
-
"sebastian/version": "^2.0.1",
|
500 |
-
"theseer/tokenizer": "^1.1"
|
501 |
-
},
|
502 |
-
"require-dev": {
|
503 |
-
"phpunit/phpunit": "^7.0"
|
504 |
-
},
|
505 |
-
"suggest": {
|
506 |
-
"ext-xdebug": "^2.6.0"
|
507 |
-
},
|
508 |
-
"type": "library",
|
509 |
-
"extra": {
|
510 |
-
"branch-alias": {
|
511 |
-
"dev-master": "6.1-dev"
|
512 |
-
}
|
513 |
-
},
|
514 |
-
"autoload": {
|
515 |
-
"classmap": [
|
516 |
-
"src/"
|
517 |
-
]
|
518 |
-
},
|
519 |
-
"notification-url": "https://packagist.org/downloads/",
|
520 |
-
"license": [
|
521 |
-
"BSD-3-Clause"
|
522 |
-
],
|
523 |
-
"authors": [
|
524 |
-
{
|
525 |
-
"name": "Sebastian Bergmann",
|
526 |
-
"email": "sebastian@phpunit.de",
|
527 |
-
"role": "lead"
|
528 |
-
}
|
529 |
-
],
|
530 |
-
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
|
531 |
-
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
|
532 |
-
"keywords": [
|
533 |
-
"coverage",
|
534 |
-
"testing",
|
535 |
-
"xunit"
|
536 |
-
],
|
537 |
-
"support": {
|
538 |
-
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
539 |
-
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master"
|
540 |
-
},
|
541 |
-
"time": "2018-10-31T16:06:48+00:00"
|
542 |
-
},
|
543 |
-
{
|
544 |
-
"name": "phpunit/php-file-iterator",
|
545 |
-
"version": "2.0.x-dev",
|
546 |
-
"source": {
|
547 |
-
"type": "git",
|
548 |
-
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
549 |
-
"reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357"
|
550 |
-
},
|
551 |
-
"dist": {
|
552 |
-
"type": "zip",
|
553 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357",
|
554 |
-
"reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357",
|
555 |
-
"shasum": ""
|
556 |
-
},
|
557 |
-
"require": {
|
558 |
-
"php": ">=7.1"
|
559 |
-
},
|
560 |
-
"require-dev": {
|
561 |
-
"phpunit/phpunit": "^8.5"
|
562 |
-
},
|
563 |
-
"type": "library",
|
564 |
-
"extra": {
|
565 |
-
"branch-alias": {
|
566 |
-
"dev-master": "2.0.x-dev"
|
567 |
-
}
|
568 |
-
},
|
569 |
-
"autoload": {
|
570 |
-
"classmap": [
|
571 |
-
"src/"
|
572 |
-
]
|
573 |
-
},
|
574 |
-
"notification-url": "https://packagist.org/downloads/",
|
575 |
-
"license": [
|
576 |
-
"BSD-3-Clause"
|
577 |
-
],
|
578 |
-
"authors": [
|
579 |
-
{
|
580 |
-
"name": "Sebastian Bergmann",
|
581 |
-
"email": "sebastian@phpunit.de",
|
582 |
-
"role": "lead"
|
583 |
-
}
|
584 |
-
],
|
585 |
-
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
|
586 |
-
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
|
587 |
-
"keywords": [
|
588 |
-
"filesystem",
|
589 |
-
"iterator"
|
590 |
-
],
|
591 |
-
"support": {
|
592 |
-
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
|
593 |
-
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0"
|
594 |
-
},
|
595 |
-
"funding": [
|
596 |
-
{
|
597 |
-
"url": "https://github.com/sebastianbergmann",
|
598 |
-
"type": "github"
|
599 |
-
}
|
600 |
-
],
|
601 |
-
"time": "2020-11-30T08:25:21+00:00"
|
602 |
-
},
|
603 |
-
{
|
604 |
-
"name": "phpunit/php-text-template",
|
605 |
-
"version": "1.2.1",
|
606 |
-
"source": {
|
607 |
-
"type": "git",
|
608 |
-
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
609 |
-
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
|
610 |
-
},
|
611 |
-
"dist": {
|
612 |
-
"type": "zip",
|
613 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
614 |
-
"reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
|
615 |
-
"shasum": ""
|
616 |
-
},
|
617 |
-
"require": {
|
618 |
-
"php": ">=5.3.3"
|
619 |
-
},
|
620 |
-
"type": "library",
|
621 |
-
"autoload": {
|
622 |
-
"classmap": [
|
623 |
-
"src/"
|
624 |
-
]
|
625 |
-
},
|
626 |
-
"notification-url": "https://packagist.org/downloads/",
|
627 |
-
"license": [
|
628 |
-
"BSD-3-Clause"
|
629 |
-
],
|
630 |
-
"authors": [
|
631 |
-
{
|
632 |
-
"name": "Sebastian Bergmann",
|
633 |
-
"email": "sebastian@phpunit.de",
|
634 |
-
"role": "lead"
|
635 |
-
}
|
636 |
-
],
|
637 |
-
"description": "Simple template engine.",
|
638 |
-
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
|
639 |
-
"keywords": [
|
640 |
-
"template"
|
641 |
-
],
|
642 |
-
"support": {
|
643 |
-
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
|
644 |
-
"source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
|
645 |
-
},
|
646 |
-
"time": "2015-06-21T13:50:34+00:00"
|
647 |
-
},
|
648 |
-
{
|
649 |
-
"name": "phpunit/php-timer",
|
650 |
-
"version": "2.1.x-dev",
|
651 |
-
"source": {
|
652 |
-
"type": "git",
|
653 |
-
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
654 |
-
"reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
|
655 |
-
},
|
656 |
-
"dist": {
|
657 |
-
"type": "zip",
|
658 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
|
659 |
-
"reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
|
660 |
-
"shasum": ""
|
661 |
-
},
|
662 |
-
"require": {
|
663 |
-
"php": ">=7.1"
|
664 |
-
},
|
665 |
-
"require-dev": {
|
666 |
-
"phpunit/phpunit": "^8.5"
|
667 |
-
},
|
668 |
-
"type": "library",
|
669 |
-
"extra": {
|
670 |
-
"branch-alias": {
|
671 |
-
"dev-master": "2.1-dev"
|
672 |
-
}
|
673 |
-
},
|
674 |
-
"autoload": {
|
675 |
-
"classmap": [
|
676 |
-
"src/"
|
677 |
-
]
|
678 |
-
},
|
679 |
-
"notification-url": "https://packagist.org/downloads/",
|
680 |
-
"license": [
|
681 |
-
"BSD-3-Clause"
|
682 |
-
],
|
683 |
-
"authors": [
|
684 |
-
{
|
685 |
-
"name": "Sebastian Bergmann",
|
686 |
-
"email": "sebastian@phpunit.de",
|
687 |
-
"role": "lead"
|
688 |
-
}
|
689 |
-
],
|
690 |
-
"description": "Utility class for timing",
|
691 |
-
"homepage": "https://github.com/sebastianbergmann/php-timer/",
|
692 |
-
"keywords": [
|
693 |
-
"timer"
|
694 |
-
],
|
695 |
-
"support": {
|
696 |
-
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
|
697 |
-
"source": "https://github.com/sebastianbergmann/php-timer/tree/2.1"
|
698 |
-
},
|
699 |
-
"funding": [
|
700 |
-
{
|
701 |
-
"url": "https://github.com/sebastianbergmann",
|
702 |
-
"type": "github"
|
703 |
-
}
|
704 |
-
],
|
705 |
-
"time": "2020-11-30T08:20:02+00:00"
|
706 |
-
},
|
707 |
-
{
|
708 |
-
"name": "phpunit/php-token-stream",
|
709 |
-
"version": "3.1.x-dev",
|
710 |
-
"source": {
|
711 |
-
"type": "git",
|
712 |
-
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
713 |
-
"reference": "472b687829041c24b25f475e14c2f38a09edf1c2"
|
714 |
-
},
|
715 |
-
"dist": {
|
716 |
-
"type": "zip",
|
717 |
-
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2",
|
718 |
-
"reference": "472b687829041c24b25f475e14c2f38a09edf1c2",
|
719 |
-
"shasum": ""
|
720 |
-
},
|
721 |
-
"require": {
|
722 |
-
"ext-tokenizer": "*",
|
723 |
-
"php": ">=7.1"
|
724 |
-
},
|
725 |
-
"require-dev": {
|
726 |
-
"phpunit/phpunit": "^7.0"
|
727 |
-
},
|
728 |
-
"type": "library",
|
729 |
-
"extra": {
|
730 |
-
"branch-alias": {
|
731 |
-
"dev-master": "3.1-dev"
|
732 |
-
}
|
733 |
-
},
|
734 |
-
"autoload": {
|
735 |
-
"classmap": [
|
736 |
-
"src/"
|
737 |
-
]
|
738 |
-
},
|
739 |
-
"notification-url": "https://packagist.org/downloads/",
|
740 |
-
"license": [
|
741 |
-
"BSD-3-Clause"
|
742 |
-
],
|
743 |
-
"authors": [
|
744 |
-
{
|
745 |
-
"name": "Sebastian Bergmann",
|
746 |
-
"email": "sebastian@phpunit.de"
|
747 |
-
}
|
748 |
-
],
|
749 |
-
"description": "Wrapper around PHP's tokenizer extension.",
|
750 |
-
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
|
751 |
-
"keywords": [
|
752 |
-
"tokenizer"
|
753 |
-
],
|
754 |
-
"support": {
|
755 |
-
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
|
756 |
-
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1"
|
757 |
-
},
|
758 |
-
"funding": [
|
759 |
-
{
|
760 |
-
"url": "https://github.com/sebastianbergmann",
|
761 |
-
"type": "github"
|
762 |
-
}
|
763 |
-
],
|
764 |
-
"abandoned": true,
|
765 |
-
"time": "2020-11-30T08:38:46+00:00"
|
766 |
-
},
|
767 |
-
{
|
768 |
-
"name": "phpunit/phpunit",
|
769 |
-
"version": "7.5.20",
|
770 |
-
"source": {
|
771 |
-
"type": "git",
|
772 |
-
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
773 |
-
"reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
|
774 |
-
},
|
775 |
-
"dist": {
|
776 |
-
"type": "zip",
|
777 |
-
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
|
778 |
-
"reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
|
779 |
-
"shasum": ""
|
780 |
-
},
|
781 |
-
"require": {
|
782 |
-
"doctrine/instantiator": "^1.1",
|
783 |
-
"ext-dom": "*",
|
784 |
-
"ext-json": "*",
|
785 |
-
"ext-libxml": "*",
|
786 |
-
"ext-mbstring": "*",
|
787 |
-
"ext-xml": "*",
|
788 |
-
"myclabs/deep-copy": "^1.7",
|
789 |
-
"phar-io/manifest": "^1.0.2",
|
790 |
-
"phar-io/version": "^2.0",
|
791 |
-
"php": "^7.1",
|
792 |
-
"phpspec/prophecy": "^1.7",
|
793 |
-
"phpunit/php-code-coverage": "^6.0.7",
|
794 |
-
"phpunit/php-file-iterator": "^2.0.1",
|
795 |
-
"phpunit/php-text-template": "^1.2.1",
|
796 |
-
"phpunit/php-timer": "^2.1",
|
797 |
-
"sebastian/comparator": "^3.0",
|
798 |
-
"sebastian/diff": "^3.0",
|
799 |
-
"sebastian/environment": "^4.0",
|
800 |
-
"sebastian/exporter": "^3.1",
|
801 |
-
"sebastian/global-state": "^2.0",
|
802 |
-
"sebastian/object-enumerator": "^3.0.3",
|
803 |
-
"sebastian/resource-operations": "^2.0",
|
804 |
-
"sebastian/version": "^2.0.1"
|
805 |
-
},
|
806 |
-
"conflict": {
|
807 |
-
"phpunit/phpunit-mock-objects": "*"
|
808 |
-
},
|
809 |
-
"require-dev": {
|
810 |
-
"ext-pdo": "*"
|
811 |
-
},
|
812 |
-
"suggest": {
|
813 |
-
"ext-soap": "*",
|
814 |
-
"ext-xdebug": "*",
|
815 |
-
"phpunit/php-invoker": "^2.0"
|
816 |
-
},
|
817 |
-
"bin": [
|
818 |
-
"phpunit"
|
819 |
-
],
|
820 |
-
"type": "library",
|
821 |
-
"extra": {
|
822 |
-
"branch-alias": {
|
823 |
-
"dev-master": "7.5-dev"
|
824 |
-
}
|
825 |
-
},
|
826 |
-
"autoload": {
|
827 |
-
"classmap": [
|
828 |
-
"src/"
|
829 |
-
]
|
830 |
-
},
|
831 |
-
"notification-url": "https://packagist.org/downloads/",
|
832 |
-
"license": [
|
833 |
-
"BSD-3-Clause"
|
834 |
-
],
|
835 |
-
"authors": [
|
836 |
-
{
|
837 |
-
"name": "Sebastian Bergmann",
|
838 |
-
"email": "sebastian@phpunit.de",
|
839 |
-
"role": "lead"
|
840 |
-
}
|
841 |
-
],
|
842 |
-
"description": "The PHP Unit Testing framework.",
|
843 |
-
"homepage": "https://phpunit.de/",
|
844 |
-
"keywords": [
|
845 |
-
"phpunit",
|
846 |
-
"testing",
|
847 |
-
"xunit"
|
848 |
-
],
|
849 |
-
"support": {
|
850 |
-
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
851 |
-
"source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20"
|
852 |
-
},
|
853 |
-
"time": "2020-01-08T08:45:45+00:00"
|
854 |
-
},
|
855 |
-
{
|
856 |
-
"name": "sebastian/code-unit-reverse-lookup",
|
857 |
-
"version": "1.0.x-dev",
|
858 |
-
"source": {
|
859 |
-
"type": "git",
|
860 |
-
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
|
861 |
-
"reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
|
862 |
-
},
|
863 |
-
"dist": {
|
864 |
-
"type": "zip",
|
865 |
-
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
|
866 |
-
"reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
|
867 |
-
"shasum": ""
|
868 |
-
},
|
869 |
-
"require": {
|
870 |
-
"php": ">=5.6"
|
871 |
-
},
|
872 |
-
"require-dev": {
|
873 |
-
"phpunit/phpunit": "^8.5"
|
874 |
-
},
|
875 |
-
"type": "library",
|
876 |
-
"extra": {
|
877 |
-
"branch-alias": {
|
878 |
-
"dev-master": "1.0.x-dev"
|
879 |
-
}
|
880 |
-
},
|
881 |
-
"autoload": {
|
882 |
-
"classmap": [
|
883 |
-
"src/"
|
884 |
-
]
|
885 |
-
},
|
886 |
-
"notification-url": "https://packagist.org/downloads/",
|
887 |
-
"license": [
|
888 |
-
"BSD-3-Clause"
|
889 |
-
],
|
890 |
-
"authors": [
|
891 |
-
{
|
892 |
-
"name": "Sebastian Bergmann",
|
893 |
-
"email": "sebastian@phpunit.de"
|
894 |
-
}
|
895 |
-
],
|
896 |
-
"description": "Looks up which function or method a line of code belongs to",
|
897 |
-
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
|
898 |
-
"support": {
|
899 |
-
"issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
|
900 |
-
"source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0"
|
901 |
-
},
|
902 |
-
"funding": [
|
903 |
-
{
|
904 |
-
"url": "https://github.com/sebastianbergmann",
|
905 |
-
"type": "github"
|
906 |
-
}
|
907 |
-
],
|
908 |
-
"time": "2020-11-30T08:15:22+00:00"
|
909 |
-
},
|
910 |
-
{
|
911 |
-
"name": "sebastian/comparator",
|
912 |
-
"version": "3.0.x-dev",
|
913 |
-
"source": {
|
914 |
-
"type": "git",
|
915 |
-
"url": "https://github.com/sebastianbergmann/comparator.git",
|
916 |
-
"reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
|
917 |
-
},
|
918 |
-
"dist": {
|
919 |
-
"type": "zip",
|
920 |
-
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
|
921 |
-
"reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
|
922 |
-
"shasum": ""
|
923 |
-
},
|
924 |
-
"require": {
|
925 |
-
"php": ">=7.1",
|
926 |
-
"sebastian/diff": "^3.0",
|
927 |
-
"sebastian/exporter": "^3.1"
|
928 |
-
},
|
929 |
-
"require-dev": {
|
930 |
-
"phpunit/phpunit": "^8.5"
|
931 |
-
},
|
932 |
-
"type": "library",
|
933 |
-
"extra": {
|
934 |
-
"branch-alias": {
|
935 |
-
"dev-master": "3.0-dev"
|
936 |
-
}
|
937 |
-
},
|
938 |
-
"autoload": {
|
939 |
-
"classmap": [
|
940 |
-
"src/"
|
941 |
-
]
|
942 |
-
},
|
943 |
-
"notification-url": "https://packagist.org/downloads/",
|
944 |
-
"license": [
|
945 |
-
"BSD-3-Clause"
|
946 |
-
],
|
947 |
-
"authors": [
|
948 |
-
{
|
949 |
-
"name": "Sebastian Bergmann",
|
950 |
-
"email": "sebastian@phpunit.de"
|
951 |
-
},
|
952 |
-
{
|
953 |
-
"name": "Jeff Welch",
|
954 |
-
"email": "whatthejeff@gmail.com"
|
955 |
-
},
|
956 |
-
{
|
957 |
-
"name": "Volker Dusch",
|
958 |
-
"email": "github@wallbash.com"
|
959 |
-
},
|
960 |
-
{
|
961 |
-
"name": "Bernhard Schussek",
|
962 |
-
"email": "bschussek@2bepublished.at"
|
963 |
-
}
|
964 |
-
],
|
965 |
-
"description": "Provides the functionality to compare PHP values for equality",
|
966 |
-
"homepage": "https://github.com/sebastianbergmann/comparator",
|
967 |
-
"keywords": [
|
968 |
-
"comparator",
|
969 |
-
"compare",
|
970 |
-
"equality"
|
971 |
-
],
|
972 |
-
"support": {
|
973 |
-
"issues": "https://github.com/sebastianbergmann/comparator/issues",
|
974 |
-
"source": "https://github.com/sebastianbergmann/comparator/tree/3.0"
|
975 |
-
},
|
976 |
-
"funding": [
|
977 |
-
{
|
978 |
-
"url": "https://github.com/sebastianbergmann",
|
979 |
-
"type": "github"
|
980 |
-
}
|
981 |
-
],
|
982 |
-
"time": "2020-11-30T08:04:30+00:00"
|
983 |
-
},
|
984 |
-
{
|
985 |
-
"name": "sebastian/diff",
|
986 |
-
"version": "3.0.x-dev",
|
987 |
-
"source": {
|
988 |
-
"type": "git",
|
989 |
-
"url": "https://github.com/sebastianbergmann/diff.git",
|
990 |
-
"reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
|
991 |
-
},
|
992 |
-
"dist": {
|
993 |
-
"type": "zip",
|
994 |
-
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
|
995 |
-
"reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
|
996 |
-
"shasum": ""
|
997 |
-
},
|
998 |
-
"require": {
|
999 |
-
"php": ">=7.1"
|
1000 |
-
},
|
1001 |
-
"require-dev": {
|
1002 |
-
"phpunit/phpunit": "^7.5 || ^8.0",
|
1003 |
-
"symfony/process": "^2 || ^3.3 || ^4"
|
1004 |
-
},
|
1005 |
-
"type": "library",
|
1006 |
-
"extra": {
|
1007 |
-
"branch-alias": {
|
1008 |
-
"dev-master": "3.0-dev"
|
1009 |
-
}
|
1010 |
-
},
|
1011 |
-
"autoload": {
|
1012 |
-
"classmap": [
|
1013 |
-
"src/"
|
1014 |
-
]
|
1015 |
-
},
|
1016 |
-
"notification-url": "https://packagist.org/downloads/",
|
1017 |
-
"license": [
|
1018 |
-
"BSD-3-Clause"
|
1019 |
-
],
|
1020 |
-
"authors": [
|
1021 |
-
{
|
1022 |
-
"name": "Sebastian Bergmann",
|
1023 |
-
"email": "sebastian@phpunit.de"
|
1024 |
-
},
|
1025 |
-
{
|
1026 |
-
"name": "Kore Nordmann",
|
1027 |
-
"email": "mail@kore-nordmann.de"
|
1028 |
-
}
|
1029 |
-
],
|
1030 |
-
"description": "Diff implementation",
|
1031 |
-
"homepage": "https://github.com/sebastianbergmann/diff",
|
1032 |
-
"keywords": [
|
1033 |
-
"diff",
|
1034 |
-
"udiff",
|
1035 |
-
"unidiff",
|
1036 |
-
"unified diff"
|
1037 |
-
],
|
1038 |
-
"support": {
|
1039 |
-
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
1040 |
-
"source": "https://github.com/sebastianbergmann/diff/tree/3.0"
|
1041 |
-
},
|
1042 |
-
"funding": [
|
1043 |
-
{
|
1044 |
-
"url": "https://github.com/sebastianbergmann",
|
1045 |
-
"type": "github"
|
1046 |
-
}
|
1047 |
-
],
|
1048 |
-
"time": "2020-11-30T07:59:04+00:00"
|
1049 |
-
},
|
1050 |
-
{
|
1051 |
-
"name": "sebastian/environment",
|
1052 |
-
"version": "4.2.x-dev",
|
1053 |
-
"source": {
|
1054 |
-
"type": "git",
|
1055 |
-
"url": "https://github.com/sebastianbergmann/environment.git",
|
1056 |
-
"reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
|
1057 |
-
},
|
1058 |
-
"dist": {
|
1059 |
-
"type": "zip",
|
1060 |
-
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
|
1061 |
-
"reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
|
1062 |
-
"shasum": ""
|
1063 |
-
},
|
1064 |
-
"require": {
|
1065 |
-
"php": ">=7.1"
|
1066 |
-
},
|
1067 |
-
"require-dev": {
|
1068 |
-
"phpunit/phpunit": "^7.5"
|
1069 |
-
},
|
1070 |
-
"suggest": {
|
1071 |
-
"ext-posix": "*"
|
1072 |
-
},
|
1073 |
-
"type": "library",
|
1074 |
-
"extra": {
|
1075 |
-
"branch-alias": {
|
1076 |
-
"dev-master": "4.2-dev"
|
1077 |
-
}
|
1078 |
-
},
|
1079 |
-
"autoload": {
|
1080 |
-
"classmap": [
|
1081 |
-
"src/"
|
1082 |
-
]
|
1083 |
-
},
|
1084 |
-
"notification-url": "https://packagist.org/downloads/",
|
1085 |
-
"license": [
|
1086 |
-
"BSD-3-Clause"
|
1087 |
-
],
|
1088 |
-
"authors": [
|
1089 |
-
{
|
1090 |
-
"name": "Sebastian Bergmann",
|
1091 |
-
"email": "sebastian@phpunit.de"
|
1092 |
-
}
|
1093 |
-
],
|
1094 |
-
"description": "Provides functionality to handle HHVM/PHP environments",
|
1095 |
-
"homepage": "http://www.github.com/sebastianbergmann/environment",
|
1096 |
-
"keywords": [
|
1097 |
-
"Xdebug",
|
1098 |
-
"environment",
|
1099 |
-
"hhvm"
|
1100 |
-
],
|
1101 |
-
"support": {
|
1102 |
-
"issues": "https://github.com/sebastianbergmann/environment/issues",
|
1103 |
-
"source": "https://github.com/sebastianbergmann/environment/tree/4.2"
|
1104 |
-
},
|
1105 |
-
"funding": [
|
1106 |
-
{
|
1107 |
-
"url": "https://github.com/sebastianbergmann",
|
1108 |
-
"type": "github"
|
1109 |
-
}
|
1110 |
-
],
|
1111 |
-
"time": "2020-11-30T07:53:42+00:00"
|
1112 |
-
},
|
1113 |
-
{
|
1114 |
-
"name": "sebastian/exporter",
|
1115 |
-
"version": "3.1.x-dev",
|
1116 |
-
"source": {
|
1117 |
-
"type": "git",
|
1118 |
-
"url": "https://github.com/sebastianbergmann/exporter.git",
|
1119 |
-
"reference": "6b853149eab67d4da22291d36f5b0631c0fd856e"
|
1120 |
-
},
|
1121 |
-
"dist": {
|
1122 |
-
"type": "zip",
|
1123 |
-
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e",
|
1124 |
-
"reference": "6b853149eab67d4da22291d36f5b0631c0fd856e",
|
1125 |
-
"shasum": ""
|
1126 |
-
},
|
1127 |
-
"require": {
|
1128 |
-
"php": ">=7.0",
|
1129 |
-
"sebastian/recursion-context": "^3.0"
|
1130 |
-
},
|
1131 |
-
"require-dev": {
|
1132 |
-
"ext-mbstring": "*",
|
1133 |
-
"phpunit/phpunit": "^6.0"
|
1134 |
-
},
|
1135 |
-
"type": "library",
|
1136 |
-
"extra": {
|
1137 |
-
"branch-alias": {
|
1138 |
-
"dev-master": "3.1.x-dev"
|
1139 |
-
}
|
1140 |
-
},
|
1141 |
-
"autoload": {
|
1142 |
-
"classmap": [
|
1143 |
-
"src/"
|
1144 |
-
]
|
1145 |
-
},
|
1146 |
-
"notification-url": "https://packagist.org/downloads/",
|
1147 |
-
"license": [
|
1148 |
-
"BSD-3-Clause"
|
1149 |
-
],
|
1150 |
-
"authors": [
|
1151 |
-
{
|
1152 |
-
"name": "Sebastian Bergmann",
|
1153 |
-
"email": "sebastian@phpunit.de"
|
1154 |
-
},
|
1155 |
-
{
|
1156 |
-
"name": "Jeff Welch",
|
1157 |
-
"email": "whatthejeff@gmail.com"
|
1158 |
-
},
|
1159 |
-
{
|
1160 |
-
"name": "Volker Dusch",
|
1161 |
-
"email": "github@wallbash.com"
|
1162 |
-
},
|
1163 |
-
{
|
1164 |
-
"name": "Adam Harvey",
|
1165 |
-
"email": "aharvey@php.net"
|
1166 |
-
},
|
1167 |
-
{
|
1168 |
-
"name": "Bernhard Schussek",
|
1169 |
-
"email": "bschussek@gmail.com"
|
1170 |
-
}
|
1171 |
-
],
|
1172 |
-
"description": "Provides the functionality to export PHP variables for visualization",
|
1173 |
-
"homepage": "http://www.github.com/sebastianbergmann/exporter",
|
1174 |
-
"keywords": [
|
1175 |
-
"export",
|
1176 |
-
"exporter"
|
1177 |
-
],
|
1178 |
-
"support": {
|
1179 |
-
"issues": "https://github.com/sebastianbergmann/exporter/issues",
|
1180 |
-
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1"
|
1181 |
-
},
|
1182 |
-
"funding": [
|
1183 |
-
{
|
1184 |
-
"url": "https://github.com/sebastianbergmann",
|
1185 |
-
"type": "github"
|
1186 |
-
}
|
1187 |
-
],
|
1188 |
-
"time": "2020-11-30T07:47:53+00:00"
|
1189 |
-
},
|
1190 |
-
{
|
1191 |
-
"name": "sebastian/global-state",
|
1192 |
-
"version": "2.0.0",
|
1193 |
-
"source": {
|
1194 |
-
"type": "git",
|
1195 |
-
"url": "https://github.com/sebastianbergmann/global-state.git",
|
1196 |
-
"reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
|
1197 |
-
},
|
1198 |
-
"dist": {
|
1199 |
-
"type": "zip",
|
1200 |
-
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
|
1201 |
-
"reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
|
1202 |
-
"shasum": ""
|
1203 |
-
},
|
1204 |
-
"require": {
|
1205 |
-
"php": "^7.0"
|
1206 |
-
},
|
1207 |
-
"require-dev": {
|
1208 |
-
"phpunit/phpunit": "^6.0"
|
1209 |
-
},
|
1210 |
-
"suggest": {
|
1211 |
-
"ext-uopz": "*"
|
1212 |
-
},
|
1213 |
-
"type": "library",
|
1214 |
-
"extra": {
|
1215 |
-
"branch-alias": {
|
1216 |
-
"dev-master": "2.0-dev"
|
1217 |
-
}
|
1218 |
-
},
|
1219 |
-
"autoload": {
|
1220 |
-
"classmap": [
|
1221 |
-
"src/"
|
1222 |
-
]
|
1223 |
-
},
|
1224 |
-
"notification-url": "https://packagist.org/downloads/",
|
1225 |
-
"license": [
|
1226 |
-
"BSD-3-Clause"
|
1227 |
-
],
|
1228 |
-
"authors": [
|
1229 |
-
{
|
1230 |
-
"name": "Sebastian Bergmann",
|
1231 |
-
"email": "sebastian@phpunit.de"
|
1232 |
-
}
|
1233 |
-
],
|
1234 |
-
"description": "Snapshotting of global state",
|
1235 |
-
"homepage": "http://www.github.com/sebastianbergmann/global-state",
|
1236 |
-
"keywords": [
|
1237 |
-
"global state"
|
1238 |
-
],
|
1239 |
-
"support": {
|
1240 |
-
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
1241 |
-
"source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
|
1242 |
-
},
|
1243 |
-
"time": "2017-04-27T15:39:26+00:00"
|
1244 |
-
},
|
1245 |
-
{
|
1246 |
-
"name": "sebastian/object-enumerator",
|
1247 |
-
"version": "3.0.x-dev",
|
1248 |
-
"source": {
|
1249 |
-
"type": "git",
|
1250 |
-
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
|
1251 |
-
"reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
|
1252 |
-
},
|
1253 |
-
"dist": {
|
1254 |
-
"type": "zip",
|
1255 |
-
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
|
1256 |
-
"reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
|
1257 |
-
"shasum": ""
|
1258 |
-
},
|
1259 |
-
"require": {
|
1260 |
-
"php": ">=7.0",
|
1261 |
-
"sebastian/object-reflector": "^1.1.1",
|
1262 |
-
"sebastian/recursion-context": "^3.0"
|
1263 |
-
},
|
1264 |
-
"require-dev": {
|
1265 |
-
"phpunit/phpunit": "^6.0"
|
1266 |
-
},
|
1267 |
-
"type": "library",
|
1268 |
-
"extra": {
|
1269 |
-
"branch-alias": {
|
1270 |
-
"dev-master": "3.0.x-dev"
|
1271 |
-
}
|
1272 |
-
},
|
1273 |
-
"autoload": {
|
1274 |
-
"classmap": [
|
1275 |
-
"src/"
|
1276 |
-
]
|
1277 |
-
},
|
1278 |
-
"notification-url": "https://packagist.org/downloads/",
|
1279 |
-
"license": [
|
1280 |
-
"BSD-3-Clause"
|
1281 |
-
],
|
1282 |
-
"authors": [
|
1283 |
-
{
|
1284 |
-
"name": "Sebastian Bergmann",
|
1285 |
-
"email": "sebastian@phpunit.de"
|
1286 |
-
}
|
1287 |
-
],
|
1288 |
-
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
|
1289 |
-
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
|
1290 |
-
"support": {
|
1291 |
-
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
|
1292 |
-
"source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0"
|
1293 |
-
},
|
1294 |
-
"funding": [
|
1295 |
-
{
|
1296 |
-
"url": "https://github.com/sebastianbergmann",
|
1297 |
-
"type": "github"
|
1298 |
-
}
|
1299 |
-
],
|
1300 |
-
"time": "2020-11-30T07:40:27+00:00"
|
1301 |
-
},
|
1302 |
-
{
|
1303 |
-
"name": "sebastian/object-reflector",
|
1304 |
-
"version": "1.1.x-dev",
|
1305 |
-
"source": {
|
1306 |
-
"type": "git",
|
1307 |
-
"url": "https://github.com/sebastianbergmann/object-reflector.git",
|
1308 |
-
"reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
|
1309 |
-
},
|
1310 |
-
"dist": {
|
1311 |
-
"type": "zip",
|
1312 |
-
"url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
|
1313 |
-
"reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
|
1314 |
-
"shasum": ""
|
1315 |
-
},
|
1316 |
-
"require": {
|
1317 |
-
"php": ">=7.0"
|
1318 |
-
},
|
1319 |
-
"require-dev": {
|
1320 |
-
"phpunit/phpunit": "^6.0"
|
1321 |
-
},
|
1322 |
-
"type": "library",
|
1323 |
-
"extra": {
|
1324 |
-
"branch-alias": {
|
1325 |
-
"dev-master": "1.1-dev"
|
1326 |
-
}
|
1327 |
-
},
|
1328 |
-
"autoload": {
|
1329 |
-
"classmap": [
|
1330 |
-
"src/"
|
1331 |
-
]
|
1332 |
-
},
|
1333 |
-
"notification-url": "https://packagist.org/downloads/",
|
1334 |
-
"license": [
|
1335 |
-
"BSD-3-Clause"
|
1336 |
-
],
|
1337 |
-
"authors": [
|
1338 |
-
{
|
1339 |
-
"name": "Sebastian Bergmann",
|
1340 |
-
"email": "sebastian@phpunit.de"
|
1341 |
-
}
|
1342 |
-
],
|
1343 |
-
"description": "Allows reflection of object attributes, including inherited and non-public ones",
|
1344 |
-
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
|
1345 |
-
"support": {
|
1346 |
-
"issues": "https://github.com/sebastianbergmann/object-reflector/issues",
|
1347 |
-
"source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1"
|
1348 |
-
},
|
1349 |
-
"funding": [
|
1350 |
-
{
|
1351 |
-
"url": "https://github.com/sebastianbergmann",
|
1352 |
-
"type": "github"
|
1353 |
-
}
|
1354 |
-
],
|
1355 |
-
"time": "2020-11-30T07:37:18+00:00"
|
1356 |
-
},
|
1357 |
-
{
|
1358 |
-
"name": "sebastian/recursion-context",
|
1359 |
-
"version": "3.0.x-dev",
|
1360 |
-
"source": {
|
1361 |
-
"type": "git",
|
1362 |
-
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
1363 |
-
"reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
|
1364 |
-
},
|
1365 |
-
"dist": {
|
1366 |
-
"type": "zip",
|
1367 |
-
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
|
1368 |
-
"reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
|
1369 |
-
"shasum": ""
|
1370 |
-
},
|
1371 |
-
"require": {
|
1372 |
-
"php": ">=7.0"
|
1373 |
-
},
|
1374 |
-
"require-dev": {
|
1375 |
-
"phpunit/phpunit": "^6.0"
|
1376 |
-
},
|
1377 |
-
"type": "library",
|
1378 |
-
"extra": {
|
1379 |
-
"branch-alias": {
|
1380 |
-
"dev-master": "3.0.x-dev"
|
1381 |
-
}
|
1382 |
-
},
|
1383 |
-
"autoload": {
|
1384 |
-
"classmap": [
|
1385 |
-
"src/"
|
1386 |
-
]
|
1387 |
-
},
|
1388 |
-
"notification-url": "https://packagist.org/downloads/",
|
1389 |
-
"license": [
|
1390 |
-
"BSD-3-Clause"
|
1391 |
-
],
|
1392 |
-
"authors": [
|
1393 |
-
{
|
1394 |
-
"name": "Sebastian Bergmann",
|
1395 |
-
"email": "sebastian@phpunit.de"
|
1396 |
-
},
|
1397 |
-
{
|
1398 |
-
"name": "Jeff Welch",
|
1399 |
-
"email": "whatthejeff@gmail.com"
|
1400 |
-
},
|
1401 |
-
{
|
1402 |
-
"name": "Adam Harvey",
|
1403 |
-
"email": "aharvey@php.net"
|
1404 |
-
}
|
1405 |
-
],
|
1406 |
-
"description": "Provides functionality to recursively process PHP variables",
|
1407 |
-
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
1408 |
-
"support": {
|
1409 |
-
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
|
1410 |
-
"source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0"
|
1411 |
-
},
|
1412 |
-
"funding": [
|
1413 |
-
{
|
1414 |
-
"url": "https://github.com/sebastianbergmann",
|
1415 |
-
"type": "github"
|
1416 |
-
}
|
1417 |
-
],
|
1418 |
-
"time": "2020-11-30T07:34:24+00:00"
|
1419 |
-
},
|
1420 |
-
{
|
1421 |
-
"name": "sebastian/resource-operations",
|
1422 |
-
"version": "2.0.x-dev",
|
1423 |
-
"source": {
|
1424 |
-
"type": "git",
|
1425 |
-
"url": "https://github.com/sebastianbergmann/resource-operations.git",
|
1426 |
-
"reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
|
1427 |
-
},
|
1428 |
-
"dist": {
|
1429 |
-
"type": "zip",
|
1430 |
-
"url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
|
1431 |
-
"reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
|
1432 |
-
"shasum": ""
|
1433 |
-
},
|
1434 |
-
"require": {
|
1435 |
-
"php": ">=7.1"
|
1436 |
-
},
|
1437 |
-
"type": "library",
|
1438 |
-
"extra": {
|
1439 |
-
"branch-alias": {
|
1440 |
-
"dev-master": "2.0-dev"
|
1441 |
-
}
|
1442 |
-
},
|
1443 |
-
"autoload": {
|
1444 |
-
"classmap": [
|
1445 |
-
"src/"
|
1446 |
-
]
|
1447 |
-
},
|
1448 |
-
"notification-url": "https://packagist.org/downloads/",
|
1449 |
-
"license": [
|
1450 |
-
"BSD-3-Clause"
|
1451 |
-
],
|
1452 |
-
"authors": [
|
1453 |
-
{
|
1454 |
-
"name": "Sebastian Bergmann",
|
1455 |
-
"email": "sebastian@phpunit.de"
|
1456 |
-
}
|
1457 |
-
],
|
1458 |
-
"description": "Provides a list of PHP built-in functions that operate on resources",
|
1459 |
-
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
|
1460 |
-
"support": {
|
1461 |
-
"issues": "https://github.com/sebastianbergmann/resource-operations/issues",
|
1462 |
-
"source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0"
|
1463 |
-
},
|
1464 |
-
"funding": [
|
1465 |
-
{
|
1466 |
-
"url": "https://github.com/sebastianbergmann",
|
1467 |
-
"type": "github"
|
1468 |
-
}
|
1469 |
-
],
|
1470 |
-
"time": "2020-11-30T07:30:19+00:00"
|
1471 |
-
},
|
1472 |
-
{
|
1473 |
-
"name": "sebastian/version",
|
1474 |
-
"version": "2.0.1",
|
1475 |
-
"source": {
|
1476 |
-
"type": "git",
|
1477 |
-
"url": "https://github.com/sebastianbergmann/version.git",
|
1478 |
-
"reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
|
1479 |
-
},
|
1480 |
-
"dist": {
|
1481 |
-
"type": "zip",
|
1482 |
-
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
|
1483 |
-
"reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
|
1484 |
-
"shasum": ""
|
1485 |
-
},
|
1486 |
-
"require": {
|
1487 |
-
"php": ">=5.6"
|
1488 |
-
},
|
1489 |
-
"type": "library",
|
1490 |
-
"extra": {
|
1491 |
-
"branch-alias": {
|
1492 |
-
"dev-master": "2.0.x-dev"
|
1493 |
-
}
|
1494 |
-
},
|
1495 |
-
"autoload": {
|
1496 |
-
"classmap": [
|
1497 |
-
"src/"
|
1498 |
-
]
|
1499 |
-
},
|
1500 |
-
"notification-url": "https://packagist.org/downloads/",
|
1501 |
-
"license": [
|
1502 |
-
"BSD-3-Clause"
|
1503 |
-
],
|
1504 |
-
"authors": [
|
1505 |
-
{
|
1506 |
-
"name": "Sebastian Bergmann",
|
1507 |
-
"email": "sebastian@phpunit.de",
|
1508 |
-
"role": "lead"
|
1509 |
-
}
|
1510 |
-
],
|
1511 |
-
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
|
1512 |
-
"homepage": "https://github.com/sebastianbergmann/version",
|
1513 |
-
"support": {
|
1514 |
-
"issues": "https://github.com/sebastianbergmann/version/issues",
|
1515 |
-
"source": "https://github.com/sebastianbergmann/version/tree/master"
|
1516 |
-
},
|
1517 |
-
"time": "2016-10-03T07:35:21+00:00"
|
1518 |
-
},
|
1519 |
-
{
|
1520 |
-
"name": "squizlabs/php_codesniffer",
|
1521 |
-
"version": "dev-master",
|
1522 |
-
"source": {
|
1523 |
-
"type": "git",
|
1524 |
-
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
1525 |
-
"reference": "75ff420b23c0866c99c350099381a93b8602ebe6"
|
1526 |
-
},
|
1527 |
-
"dist": {
|
1528 |
-
"type": "zip",
|
1529 |
-
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/75ff420b23c0866c99c350099381a93b8602ebe6",
|
1530 |
-
"reference": "75ff420b23c0866c99c350099381a93b8602ebe6",
|
1531 |
-
"shasum": ""
|
1532 |
-
},
|
1533 |
-
"require": {
|
1534 |
-
"ext-simplexml": "*",
|
1535 |
-
"ext-tokenizer": "*",
|
1536 |
-
"ext-xmlwriter": "*",
|
1537 |
-
"php": ">=5.4.0"
|
1538 |
-
},
|
1539 |
-
"require-dev": {
|
1540 |
-
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
1541 |
-
},
|
1542 |
-
"bin": [
|
1543 |
-
"bin/phpcs",
|
1544 |
-
"bin/phpcbf"
|
1545 |
-
],
|
1546 |
-
"type": "library",
|
1547 |
-
"extra": {
|
1548 |
-
"branch-alias": {
|
1549 |
-
"dev-master": "3.x-dev"
|
1550 |
-
}
|
1551 |
-
},
|
1552 |
-
"notification-url": "https://packagist.org/downloads/",
|
1553 |
-
"license": [
|
1554 |
-
"BSD-3-Clause"
|
1555 |
-
],
|
1556 |
-
"authors": [
|
1557 |
-
{
|
1558 |
-
"name": "Greg Sherwood",
|
1559 |
-
"role": "lead"
|
1560 |
-
}
|
1561 |
-
],
|
1562 |
-
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
1563 |
-
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
1564 |
-
"keywords": [
|
1565 |
-
"phpcs",
|
1566 |
-
"standards"
|
1567 |
-
],
|
1568 |
-
"time": "2020-05-21T06:41:29+00:00"
|
1569 |
-
},
|
1570 |
-
{
|
1571 |
-
"name": "symfony/polyfill-ctype",
|
1572 |
-
"version": "dev-main",
|
1573 |
-
"source": {
|
1574 |
-
"type": "git",
|
1575 |
-
"url": "https://github.com/symfony/polyfill-ctype.git",
|
1576 |
-
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
|
1577 |
-
},
|
1578 |
-
"dist": {
|
1579 |
-
"type": "zip",
|
1580 |
-
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
|
1581 |
-
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
|
1582 |
-
"shasum": ""
|
1583 |
-
},
|
1584 |
-
"require": {
|
1585 |
-
"php": ">=7.1"
|
1586 |
-
},
|
1587 |
-
"suggest": {
|
1588 |
-
"ext-ctype": "For best performance"
|
1589 |
-
},
|
1590 |
-
"default-branch": true,
|
1591 |
-
"type": "library",
|
1592 |
-
"extra": {
|
1593 |
-
"branch-alias": {
|
1594 |
-
"dev-main": "1.22-dev"
|
1595 |
-
},
|
1596 |
-
"thanks": {
|
1597 |
-
"name": "symfony/polyfill",
|
1598 |
-
"url": "https://github.com/symfony/polyfill"
|
1599 |
-
}
|
1600 |
-
},
|
1601 |
-
"autoload": {
|
1602 |
-
"psr-4": {
|
1603 |
-
"Symfony\\Polyfill\\Ctype\\": ""
|
1604 |
-
},
|
1605 |
-
"files": [
|
1606 |
-
"bootstrap.php"
|
1607 |
-
]
|
1608 |
-
},
|
1609 |
-
"notification-url": "https://packagist.org/downloads/",
|
1610 |
-
"license": [
|
1611 |
-
"MIT"
|
1612 |
-
],
|
1613 |
-
"authors": [
|
1614 |
-
{
|
1615 |
-
"name": "Gert de Pagter",
|
1616 |
-
"email": "BackEndTea@gmail.com"
|
1617 |
-
},
|
1618 |
-
{
|
1619 |
-
"name": "Symfony Community",
|
1620 |
-
"homepage": "https://symfony.com/contributors"
|
1621 |
-
}
|
1622 |
-
],
|
1623 |
-
"description": "Symfony polyfill for ctype functions",
|
1624 |
-
"homepage": "https://symfony.com",
|
1625 |
-
"keywords": [
|
1626 |
-
"compatibility",
|
1627 |
-
"ctype",
|
1628 |
-
"polyfill",
|
1629 |
-
"portable"
|
1630 |
-
],
|
1631 |
-
"support": {
|
1632 |
-
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0"
|
1633 |
-
},
|
1634 |
-
"funding": [
|
1635 |
-
{
|
1636 |
-
"url": "https://symfony.com/sponsor",
|
1637 |
-
"type": "custom"
|
1638 |
-
},
|
1639 |
-
{
|
1640 |
-
"url": "https://github.com/fabpot",
|
1641 |
-
"type": "github"
|
1642 |
-
},
|
1643 |
-
{
|
1644 |
-
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
1645 |
-
"type": "tidelift"
|
1646 |
-
}
|
1647 |
-
],
|
1648 |
-
"time": "2021-01-07T16:49:33+00:00"
|
1649 |
-
},
|
1650 |
-
{
|
1651 |
-
"name": "theseer/tokenizer",
|
1652 |
-
"version": "1.2.0",
|
1653 |
-
"source": {
|
1654 |
-
"type": "git",
|
1655 |
-
"url": "https://github.com/theseer/tokenizer.git",
|
1656 |
-
"reference": "75a63c33a8577608444246075ea0af0d052e452a"
|
1657 |
-
},
|
1658 |
-
"dist": {
|
1659 |
-
"type": "zip",
|
1660 |
-
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
|
1661 |
-
"reference": "75a63c33a8577608444246075ea0af0d052e452a",
|
1662 |
-
"shasum": ""
|
1663 |
-
},
|
1664 |
-
"require": {
|
1665 |
-
"ext-dom": "*",
|
1666 |
-
"ext-tokenizer": "*",
|
1667 |
-
"ext-xmlwriter": "*",
|
1668 |
-
"php": "^7.2 || ^8.0"
|
1669 |
-
},
|
1670 |
-
"type": "library",
|
1671 |
-
"autoload": {
|
1672 |
-
"classmap": [
|
1673 |
-
"src/"
|
1674 |
-
]
|
1675 |
-
},
|
1676 |
-
"notification-url": "https://packagist.org/downloads/",
|
1677 |
-
"license": [
|
1678 |
-
"BSD-3-Clause"
|
1679 |
-
],
|
1680 |
-
"authors": [
|
1681 |
-
{
|
1682 |
-
"name": "Arne Blankerts",
|
1683 |
-
"email": "arne@blankerts.de",
|
1684 |
-
"role": "Developer"
|
1685 |
-
}
|
1686 |
-
],
|
1687 |
-
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
1688 |
-
"support": {
|
1689 |
-
"issues": "https://github.com/theseer/tokenizer/issues",
|
1690 |
-
"source": "https://github.com/theseer/tokenizer/tree/master"
|
1691 |
-
},
|
1692 |
-
"funding": [
|
1693 |
-
{
|
1694 |
-
"url": "https://github.com/theseer",
|
1695 |
-
"type": "github"
|
1696 |
-
}
|
1697 |
-
],
|
1698 |
-
"time": "2020-07-12T23:59:07+00:00"
|
1699 |
-
},
|
1700 |
-
{
|
1701 |
-
"name": "webmozart/assert",
|
1702 |
-
"version": "dev-master",
|
1703 |
-
"source": {
|
1704 |
-
"type": "git",
|
1705 |
-
"url": "https://github.com/webmozarts/assert.git",
|
1706 |
-
"reference": "9c89b265ccc4092d58e66d72af5d343ee77a41ae"
|
1707 |
-
},
|
1708 |
-
"dist": {
|
1709 |
-
"type": "zip",
|
1710 |
-
"url": "https://api.github.com/repos/webmozarts/assert/zipball/9c89b265ccc4092d58e66d72af5d343ee77a41ae",
|
1711 |
-
"reference": "9c89b265ccc4092d58e66d72af5d343ee77a41ae",
|
1712 |
-
"shasum": ""
|
1713 |
-
},
|
1714 |
-
"require": {
|
1715 |
-
"php": "^7.2 || ^8.0",
|
1716 |
-
"symfony/polyfill-ctype": "^1.8"
|
1717 |
-
},
|
1718 |
-
"conflict": {
|
1719 |
-
"phpstan/phpstan": "<0.12.20",
|
1720 |
-
"vimeo/psalm": "<3.9.1"
|
1721 |
-
},
|
1722 |
-
"require-dev": {
|
1723 |
-
"phpunit/phpunit": "^8.5.13"
|
1724 |
-
},
|
1725 |
-
"default-branch": true,
|
1726 |
-
"type": "library",
|
1727 |
-
"extra": {
|
1728 |
-
"branch-alias": {
|
1729 |
-
"dev-master": "1.10-dev"
|
1730 |
-
}
|
1731 |
-
},
|
1732 |
-
"autoload": {
|
1733 |
-
"psr-4": {
|
1734 |
-
"Webmozart\\Assert\\": "src/"
|
1735 |
-
}
|
1736 |
-
},
|
1737 |
-
"notification-url": "https://packagist.org/downloads/",
|
1738 |
-
"license": [
|
1739 |
-
"MIT"
|
1740 |
-
],
|
1741 |
-
"authors": [
|
1742 |
-
{
|
1743 |
-
"name": "Bernhard Schussek",
|
1744 |
-
"email": "bschussek@gmail.com"
|
1745 |
-
}
|
1746 |
-
],
|
1747 |
-
"description": "Assertions to validate method input/output with nice error messages.",
|
1748 |
-
"keywords": [
|
1749 |
-
"assert",
|
1750 |
-
"check",
|
1751 |
-
"validate"
|
1752 |
-
],
|
1753 |
-
"support": {
|
1754 |
-
"issues": "https://github.com/webmozarts/assert/issues",
|
1755 |
-
"source": "https://github.com/webmozarts/assert/tree/master"
|
1756 |
-
},
|
1757 |
-
"time": "2021-01-18T12:52:36+00:00"
|
1758 |
-
}
|
1759 |
-
],
|
1760 |
-
"aliases": [],
|
1761 |
-
"minimum-stability": "dev",
|
1762 |
-
"stability-flags": [],
|
1763 |
-
"prefer-stable": false,
|
1764 |
-
"prefer-lowest": false,
|
1765 |
-
"platform": {
|
1766 |
-
"php": ">=5.2.0"
|
1767 |
-
},
|
1768 |
-
"platform-dev": [],
|
1769 |
-
"plugin-api-version": "2.0.0"
|
1770 |
}
|
1 |
{
|
2 |
+
"_readme": [
|
3 |
+
"This file locks the dependencies of your project to a known state",
|
4 |
+
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
5 |
+
"This file is @generated automatically"
|
6 |
+
],
|
7 |
+
"content-hash": "9f6bb942a3e83517b7d1712f1e1e49df",
|
8 |
+
"packages": [],
|
9 |
+
"packages-dev": [
|
10 |
+
{
|
11 |
+
"name": "dealerdirect/phpcodesniffer-composer-installer",
|
12 |
+
"version": "dev-master",
|
13 |
+
"source": {
|
14 |
+
"type": "git",
|
15 |
+
"url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
|
16 |
+
"reference": "858566c0b7fe3798f91f1918e1b455636cbf57af"
|
17 |
+
},
|
18 |
+
"dist": {
|
19 |
+
"type": "zip",
|
20 |
+
"url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/858566c0b7fe3798f91f1918e1b455636cbf57af",
|
21 |
+
"reference": "858566c0b7fe3798f91f1918e1b455636cbf57af",
|
22 |
+
"shasum": ""
|
23 |
+
},
|
24 |
+
"require": {
|
25 |
+
"composer-plugin-api": "^1.0 || ^2.0",
|
26 |
+
"php": ">=5.3",
|
27 |
+
"squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0"
|
28 |
+
},
|
29 |
+
"require-dev": {
|
30 |
+
"composer/composer": "*",
|
31 |
+
"php-parallel-lint/php-parallel-lint": "^1.3.1",
|
32 |
+
"phpcompatibility/php-compatibility": "^9.0"
|
33 |
+
},
|
34 |
+
"default-branch": true,
|
35 |
+
"type": "composer-plugin",
|
36 |
+
"extra": {
|
37 |
+
"class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
|
38 |
+
},
|
39 |
+
"autoload": {
|
40 |
+
"psr-4": {
|
41 |
+
"Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
|
42 |
+
}
|
43 |
+
},
|
44 |
+
"notification-url": "https://packagist.org/downloads/",
|
45 |
+
"license": ["MIT"],
|
46 |
+
"authors": [
|
47 |
+
{
|
48 |
+
"name": "Franck Nijhof",
|
49 |
+
"email": "franck.nijhof@dealerdirect.com",
|
50 |
+
"homepage": "http://www.frenck.nl",
|
51 |
+
"role": "Developer / IT Manager"
|
52 |
+
}
|
53 |
+
],
|
54 |
+
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
|
55 |
+
"homepage": "http://www.dealerdirect.com",
|
56 |
+
"keywords": [
|
57 |
+
"PHPCodeSniffer",
|
58 |
+
"PHP_CodeSniffer",
|
59 |
+
"code quality",
|
60 |
+
"codesniffer",
|
61 |
+
"composer",
|
62 |
+
"installer",
|
63 |
+
"phpcs",
|
64 |
+
"plugin",
|
65 |
+
"qa",
|
66 |
+
"quality",
|
67 |
+
"standard",
|
68 |
+
"standards",
|
69 |
+
"style guide",
|
70 |
+
"stylecheck",
|
71 |
+
"tests"
|
72 |
+
],
|
73 |
+
"support": {
|
74 |
+
"issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
|
75 |
+
"source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
|
76 |
+
},
|
77 |
+
"time": "2021-11-30T15:06:39+00:00"
|
78 |
+
},
|
79 |
+
{
|
80 |
+
"name": "phpcompatibility/php-compatibility",
|
81 |
+
"version": "9.3.5",
|
82 |
+
"source": {
|
83 |
+
"type": "git",
|
84 |
+
"url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
|
85 |
+
"reference": "9fb324479acf6f39452e0655d2429cc0d3914243"
|
86 |
+
},
|
87 |
+
"dist": {
|
88 |
+
"type": "zip",
|
89 |
+
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243",
|
90 |
+
"reference": "9fb324479acf6f39452e0655d2429cc0d3914243",
|
91 |
+
"shasum": ""
|
92 |
+
},
|
93 |
+
"require": {
|
94 |
+
"php": ">=5.3",
|
95 |
+
"squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
|
96 |
+
},
|
97 |
+
"conflict": {
|
98 |
+
"squizlabs/php_codesniffer": "2.6.2"
|
99 |
+
},
|
100 |
+
"require-dev": {
|
101 |
+
"phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
|
102 |
+
},
|
103 |
+
"suggest": {
|
104 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
|
105 |
+
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
|
106 |
+
},
|
107 |
+
"type": "phpcodesniffer-standard",
|
108 |
+
"notification-url": "https://packagist.org/downloads/",
|
109 |
+
"license": ["LGPL-3.0-or-later"],
|
110 |
+
"authors": [
|
111 |
+
{
|
112 |
+
"name": "Wim Godden",
|
113 |
+
"homepage": "https://github.com/wimg",
|
114 |
+
"role": "lead"
|
115 |
+
},
|
116 |
+
{
|
117 |
+
"name": "Juliette Reinders Folmer",
|
118 |
+
"homepage": "https://github.com/jrfnl",
|
119 |
+
"role": "lead"
|
120 |
+
},
|
121 |
+
{
|
122 |
+
"name": "Contributors",
|
123 |
+
"homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
|
124 |
+
}
|
125 |
+
],
|
126 |
+
"description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
|
127 |
+
"homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
|
128 |
+
"keywords": ["compatibility", "phpcs", "standards"],
|
129 |
+
"support": {
|
130 |
+
"issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues",
|
131 |
+
"source": "https://github.com/PHPCompatibility/PHPCompatibility"
|
132 |
+
},
|
133 |
+
"time": "2019-12-27T09:44:58+00:00"
|
134 |
+
},
|
135 |
+
{
|
136 |
+
"name": "phpcompatibility/phpcompatibility-paragonie",
|
137 |
+
"version": "1.3.1",
|
138 |
+
"source": {
|
139 |
+
"type": "git",
|
140 |
+
"url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
|
141 |
+
"reference": "ddabec839cc003651f2ce695c938686d1086cf43"
|
142 |
+
},
|
143 |
+
"dist": {
|
144 |
+
"type": "zip",
|
145 |
+
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/ddabec839cc003651f2ce695c938686d1086cf43",
|
146 |
+
"reference": "ddabec839cc003651f2ce695c938686d1086cf43",
|
147 |
+
"shasum": ""
|
148 |
+
},
|
149 |
+
"require": {
|
150 |
+
"phpcompatibility/php-compatibility": "^9.0"
|
151 |
+
},
|
152 |
+
"require-dev": {
|
153 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.7",
|
154 |
+
"paragonie/random_compat": "dev-master",
|
155 |
+
"paragonie/sodium_compat": "dev-master"
|
156 |
+
},
|
157 |
+
"suggest": {
|
158 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
|
159 |
+
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
|
160 |
+
},
|
161 |
+
"type": "phpcodesniffer-standard",
|
162 |
+
"notification-url": "https://packagist.org/downloads/",
|
163 |
+
"license": ["LGPL-3.0-or-later"],
|
164 |
+
"authors": [
|
165 |
+
{
|
166 |
+
"name": "Wim Godden",
|
167 |
+
"role": "lead"
|
168 |
+
},
|
169 |
+
{
|
170 |
+
"name": "Juliette Reinders Folmer",
|
171 |
+
"role": "lead"
|
172 |
+
}
|
173 |
+
],
|
174 |
+
"description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
|
175 |
+
"homepage": "http://phpcompatibility.com/",
|
176 |
+
"keywords": [
|
177 |
+
"compatibility",
|
178 |
+
"paragonie",
|
179 |
+
"phpcs",
|
180 |
+
"polyfill",
|
181 |
+
"standards"
|
182 |
+
],
|
183 |
+
"support": {
|
184 |
+
"issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues",
|
185 |
+
"source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie"
|
186 |
+
},
|
187 |
+
"time": "2021-02-15T10:24:51+00:00"
|
188 |
+
},
|
189 |
+
{
|
190 |
+
"name": "phpcompatibility/phpcompatibility-wp",
|
191 |
+
"version": "dev-master",
|
192 |
+
"source": {
|
193 |
+
"type": "git",
|
194 |
+
"url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
|
195 |
+
"reference": "d55de55f88697b9cdb94bccf04f14eb3b11cf308"
|
196 |
+
},
|
197 |
+
"dist": {
|
198 |
+
"type": "zip",
|
199 |
+
"url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/d55de55f88697b9cdb94bccf04f14eb3b11cf308",
|
200 |
+
"reference": "d55de55f88697b9cdb94bccf04f14eb3b11cf308",
|
201 |
+
"shasum": ""
|
202 |
+
},
|
203 |
+
"require": {
|
204 |
+
"phpcompatibility/php-compatibility": "^9.0",
|
205 |
+
"phpcompatibility/phpcompatibility-paragonie": "^1.0"
|
206 |
+
},
|
207 |
+
"require-dev": {
|
208 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.7"
|
209 |
+
},
|
210 |
+
"suggest": {
|
211 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
|
212 |
+
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
|
213 |
+
},
|
214 |
+
"default-branch": true,
|
215 |
+
"type": "phpcodesniffer-standard",
|
216 |
+
"notification-url": "https://packagist.org/downloads/",
|
217 |
+
"license": ["LGPL-3.0-or-later"],
|
218 |
+
"authors": [
|
219 |
+
{
|
220 |
+
"name": "Wim Godden",
|
221 |
+
"role": "lead"
|
222 |
+
},
|
223 |
+
{
|
224 |
+
"name": "Juliette Reinders Folmer",
|
225 |
+
"role": "lead"
|
226 |
+
}
|
227 |
+
],
|
228 |
+
"description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
|
229 |
+
"homepage": "http://phpcompatibility.com/",
|
230 |
+
"keywords": ["compatibility", "phpcs", "standards", "wordpress"],
|
231 |
+
"support": {
|
232 |
+
"issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues",
|
233 |
+
"source": "https://github.com/PHPCompatibility/PHPCompatibilityWP"
|
234 |
+
},
|
235 |
+
"time": "2021-12-30T16:37:40+00:00"
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"name": "squizlabs/php_codesniffer",
|
239 |
+
"version": "dev-master",
|
240 |
+
"source": {
|
241 |
+
"type": "git",
|
242 |
+
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
|
243 |
+
"reference": "67c82d975fc15b67725c7e4a0312bf8f28354c0d"
|
244 |
+
},
|
245 |
+
"dist": {
|
246 |
+
"type": "zip",
|
247 |
+
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/67c82d975fc15b67725c7e4a0312bf8f28354c0d",
|
248 |
+
"reference": "67c82d975fc15b67725c7e4a0312bf8f28354c0d",
|
249 |
+
"shasum": ""
|
250 |
+
},
|
251 |
+
"require": {
|
252 |
+
"ext-simplexml": "*",
|
253 |
+
"ext-tokenizer": "*",
|
254 |
+
"ext-xmlwriter": "*",
|
255 |
+
"php": ">=5.4.0"
|
256 |
+
},
|
257 |
+
"require-dev": {
|
258 |
+
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
259 |
+
},
|
260 |
+
"default-branch": true,
|
261 |
+
"bin": ["bin/phpcs", "bin/phpcbf"],
|
262 |
+
"type": "library",
|
263 |
+
"extra": {
|
264 |
+
"branch-alias": {
|
265 |
+
"dev-master": "3.x-dev"
|
266 |
+
}
|
267 |
+
},
|
268 |
+
"notification-url": "https://packagist.org/downloads/",
|
269 |
+
"license": ["BSD-3-Clause"],
|
270 |
+
"authors": [
|
271 |
+
{
|
272 |
+
"name": "Greg Sherwood",
|
273 |
+
"role": "lead"
|
274 |
+
}
|
275 |
+
],
|
276 |
+
"description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
|
277 |
+
"homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
|
278 |
+
"keywords": ["phpcs", "standards"],
|
279 |
+
"support": {
|
280 |
+
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
|
281 |
+
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
|
282 |
+
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
|
283 |
+
},
|
284 |
+
"time": "2021-12-20T06:20:45+00:00"
|
285 |
+
},
|
286 |
+
{
|
287 |
+
"name": "wp-coding-standards/wpcs",
|
288 |
+
"version": "2.3.0",
|
289 |
+
"source": {
|
290 |
+
"type": "git",
|
291 |
+
"url": "https://github.com/WordPress/WordPress-Coding-Standards.git",
|
292 |
+
"reference": "7da1894633f168fe244afc6de00d141f27517b62"
|
293 |
+
},
|
294 |
+
"dist": {
|
295 |
+
"type": "zip",
|
296 |
+
"url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62",
|
297 |
+
"reference": "7da1894633f168fe244afc6de00d141f27517b62",
|
298 |
+
"shasum": ""
|
299 |
+
},
|
300 |
+
"require": {
|
301 |
+
"php": ">=5.4",
|
302 |
+
"squizlabs/php_codesniffer": "^3.3.1"
|
303 |
+
},
|
304 |
+
"require-dev": {
|
305 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6",
|
306 |
+
"phpcompatibility/php-compatibility": "^9.0",
|
307 |
+
"phpcsstandards/phpcsdevtools": "^1.0",
|
308 |
+
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
|
309 |
+
},
|
310 |
+
"suggest": {
|
311 |
+
"dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
|
312 |
+
},
|
313 |
+
"type": "phpcodesniffer-standard",
|
314 |
+
"notification-url": "https://packagist.org/downloads/",
|
315 |
+
"license": ["MIT"],
|
316 |
+
"authors": [
|
317 |
+
{
|
318 |
+
"name": "Contributors",
|
319 |
+
"homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors"
|
320 |
+
}
|
321 |
+
],
|
322 |
+
"description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
|
323 |
+
"keywords": ["phpcs", "standards", "wordpress"],
|
324 |
+
"support": {
|
325 |
+
"issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues",
|
326 |
+
"source": "https://github.com/WordPress/WordPress-Coding-Standards",
|
327 |
+
"wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki"
|
328 |
+
},
|
329 |
+
"time": "2020-05-13T23:57:56+00:00"
|
330 |
+
}
|
331 |
+
],
|
332 |
+
"aliases": [],
|
333 |
+
"minimum-stability": "dev",
|
334 |
+
"stability-flags": [],
|
335 |
+
"prefer-stable": false,
|
336 |
+
"prefer-lowest": false,
|
337 |
+
"platform": {
|
338 |
+
"php": ">=5.2.0"
|
339 |
+
},
|
340 |
+
"platform-dev": [],
|
341 |
+
"plugin-api-version": "2.2.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
342 |
}
|
css/styles.css
CHANGED
@@ -231,10 +231,6 @@ Style different log levels.
|
|
231 |
margin-top: 5px;
|
232 |
}
|
233 |
|
234 |
-
.SimpleHistoryLogitem:hover .SimpleHistoryLogitem__senderImage {
|
235 |
-
/*opacity: 1;*/
|
236 |
-
}
|
237 |
-
|
238 |
.SimpleHistoryLogitem__senderImage img {
|
239 |
display: block;
|
240 |
max-width: 100%;
|
@@ -259,7 +255,6 @@ Style different log levels.
|
|
259 |
.SimpleHistoryLogitem__text,
|
260 |
.SimpleHistoryLogitem__details,
|
261 |
.SimpleHistoryLogitem__details p {
|
262 |
-
xfont-size: 16px;
|
263 |
line-height: 1.4;
|
264 |
}
|
265 |
|
@@ -378,14 +373,6 @@ Images/thumbs can be styles nicely
|
|
378 |
height: auto;
|
379 |
}
|
380 |
|
381 |
-
/*
|
382 |
-
when occasions are added
|
383 |
-
*/
|
384 |
-
.SimpleHistoryLogitem--occasionsOpened {
|
385 |
-
/*box-shadow: 0px 10px 10px -6px rgba(0, 0, 0, 0.3);
|
386 |
-
z-index: 1;*/
|
387 |
-
}
|
388 |
-
|
389 |
/* remove border below */
|
390 |
.SimpleHistoryLogitem--occasionsOpened::before {
|
391 |
opacity: 0;
|
@@ -471,9 +458,6 @@ when occasions are added
|
|
471 |
customizations for the dashboard
|
472 |
i.e. the log is inside a .postbox element
|
473 |
*/
|
474 |
-
|
475 |
-
.postbox {
|
476 |
-
}
|
477 |
#simple_history_dashboard_widget .inside {
|
478 |
padding: 0;
|
479 |
margin-top: 0;
|
@@ -497,10 +481,6 @@ i.e. the log is inside a .postbox element
|
|
497 |
padding: 12px 5px 12px 16px;
|
498 |
}
|
499 |
|
500 |
-
.postbox .SimpleHistoryLogitem:first-child {
|
501 |
-
/*padding-top: 0;*/
|
502 |
-
}
|
503 |
-
|
504 |
.postbox .SimpleHistoryLogitem::before {
|
505 |
left: 55px;
|
506 |
}
|
@@ -571,10 +551,6 @@ Styles for filter
|
|
571 |
/*
|
572 |
Pagination, below logRows
|
573 |
*/
|
574 |
-
|
575 |
-
.SimpleHistoryLogitems__pagination {
|
576 |
-
}
|
577 |
-
|
578 |
.SimpleHistoryPaginationPages {
|
579 |
text-align: center;
|
580 |
padding-top: 20px;
|
@@ -625,9 +601,6 @@ animations/effects
|
|
625 |
/*
|
626 |
Modal window with detailss
|
627 |
*/
|
628 |
-
.SimpleHistory-modal {
|
629 |
-
}
|
630 |
-
|
631 |
.SimpleHistory-modal__background {
|
632 |
position: fixed;
|
633 |
top: 0;
|
@@ -751,9 +724,6 @@ Modal window with detailss
|
|
751 |
background: inherit;
|
752 |
}
|
753 |
|
754 |
-
.SimpleHistory-modal .SimpleHistoryLogitem__senderImage {
|
755 |
-
/*opacity: 1;*/
|
756 |
-
}
|
757 |
|
758 |
.SimpleHistoryLogitem__moreDetails {
|
759 |
border-top: 1px solid rgb(229, 229, 229);
|
@@ -888,8 +858,6 @@ Modal window with detailss
|
|
888 |
}
|
889 |
|
890 |
/* if not hits when using filter function + if ajax error */
|
891 |
-
.SimpleHistory--hasNoHits {
|
892 |
-
}
|
893 |
|
894 |
.SimpleHistory--hasNoHits .SimpleHistoryLogitems__pagination {
|
895 |
display: none;
|
231 |
margin-top: 5px;
|
232 |
}
|
233 |
|
|
|
|
|
|
|
|
|
234 |
.SimpleHistoryLogitem__senderImage img {
|
235 |
display: block;
|
236 |
max-width: 100%;
|
255 |
.SimpleHistoryLogitem__text,
|
256 |
.SimpleHistoryLogitem__details,
|
257 |
.SimpleHistoryLogitem__details p {
|
|
|
258 |
line-height: 1.4;
|
259 |
}
|
260 |
|
373 |
height: auto;
|
374 |
}
|
375 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
/* remove border below */
|
377 |
.SimpleHistoryLogitem--occasionsOpened::before {
|
378 |
opacity: 0;
|
458 |
customizations for the dashboard
|
459 |
i.e. the log is inside a .postbox element
|
460 |
*/
|
|
|
|
|
|
|
461 |
#simple_history_dashboard_widget .inside {
|
462 |
padding: 0;
|
463 |
margin-top: 0;
|
481 |
padding: 12px 5px 12px 16px;
|
482 |
}
|
483 |
|
|
|
|
|
|
|
|
|
484 |
.postbox .SimpleHistoryLogitem::before {
|
485 |
left: 55px;
|
486 |
}
|
551 |
/*
|
552 |
Pagination, below logRows
|
553 |
*/
|
|
|
|
|
|
|
|
|
554 |
.SimpleHistoryPaginationPages {
|
555 |
text-align: center;
|
556 |
padding-top: 20px;
|
601 |
/*
|
602 |
Modal window with detailss
|
603 |
*/
|
|
|
|
|
|
|
604 |
.SimpleHistory-modal__background {
|
605 |
position: fixed;
|
606 |
top: 0;
|
724 |
background: inherit;
|
725 |
}
|
726 |
|
|
|
|
|
|
|
727 |
|
728 |
.SimpleHistoryLogitem__moreDetails {
|
729 |
border-top: 1px solid rgb(229, 229, 229);
|
858 |
}
|
859 |
|
860 |
/* if not hits when using filter function + if ajax error */
|
|
|
|
|
861 |
|
862 |
.SimpleHistory--hasNoHits .SimpleHistoryLogitems__pagination {
|
863 |
display: none;
|
dropins/SimpleHistoryDebugDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Dropin Name: Debug
|
@@ -8,54 +8,52 @@ defined('ABSPATH') or die();
|
|
8 |
* Dropin URI: http://simple-history.com/
|
9 |
* Author: Pär Thernström
|
10 |
*/
|
11 |
-
class SimpleHistoryDebugDropin
|
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 |
-
return $context;
|
60 |
-
}
|
61 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Dropin Name: Debug
|
8 |
* Dropin URI: http://simple-history.com/
|
9 |
* Author: Pär Thernström
|
10 |
*/
|
11 |
+
class SimpleHistoryDebugDropin {
|
12 |
+
|
13 |
+
public function __construct( $sh ) {
|
14 |
+
// Bail if Simple History debug mode is not active.
|
15 |
+
if ( ! defined( 'SIMPLE_HISTORY_LOG_DEBUG' ) || ! SIMPLE_HISTORY_LOG_DEBUG ) {
|
16 |
+
return;
|
17 |
+
}
|
18 |
+
|
19 |
+
add_action( 'simple_history/log_argument/context', array( $this, 'onLogArgumentContext' ), 10, 4 );
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Modify the context to add debug information.
|
24 |
+
*
|
25 |
+
* @param array $context
|
26 |
+
* @param string $level
|
27 |
+
* @param string $message
|
28 |
+
* @param SimpleLogger $logger
|
29 |
+
*/
|
30 |
+
public function onLogArgumentContext( $context, $level, $message, $logger ) {
|
31 |
+
$sh = SimpleHistory::get_instance();
|
32 |
+
$context['_debug_get'] = $sh->json_encode( $_GET );
|
33 |
+
$context['_debug_post'] = $sh->json_encode( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
34 |
+
$context['_debug_server'] = $sh->json_encode( $_SERVER );
|
35 |
+
$context['_debug_files'] = $sh->json_encode( $_FILES );
|
36 |
+
$context['_debug_php_sapi_name'] = php_sapi_name();
|
37 |
+
|
38 |
+
global $argv;
|
39 |
+
$context['_debug_argv'] = $sh->json_encode( $argv );
|
40 |
+
|
41 |
+
$consts = get_defined_constants( true );
|
42 |
+
$consts = $consts['user'];
|
43 |
+
$context['_debug_user_constants'] = $sh->json_encode( $consts );
|
44 |
+
|
45 |
+
$postdata = file_get_contents( 'php://input' );
|
46 |
+
$context['_debug_http_raw_post_data'] = $sh->json_encode( $postdata );
|
47 |
+
|
48 |
+
$context['_debug_wp_debug_backtrace_summary'] = wp_debug_backtrace_summary();
|
49 |
+
$context['_debug_is_admin'] = json_encode( is_admin() );
|
50 |
+
$context['_debug_is_ajax'] = json_encode( defined( 'DOING_AJAX' ) && DOING_AJAX );
|
51 |
+
$context['_debug_is_doing_cron'] = json_encode( defined( 'DOING_CRON' ) && DOING_CRON );
|
52 |
+
|
53 |
+
global $wp_current_filter;
|
54 |
+
$context['_debug_current_filter_array'] = $wp_current_filter;
|
55 |
+
$context['_debug_current_filter'] = current_filter();
|
56 |
+
|
57 |
+
return $context;
|
58 |
+
}
|
|
|
|
|
59 |
}
|
dropins/SimpleHistoryDonateDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Donate things
|
@@ -12,72 +12,56 @@ 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 |
-
public 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 |
-
public function settings_field_donate()
|
81 |
-
{
|
82 |
-
}
|
83 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
private $simple_history;
|
17 |
+
|
18 |
+
public function __construct( $simple_history ) {
|
19 |
+
$this->simple_history = $simple_history;
|
20 |
+
|
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 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Add link to the donate page in the Plugins » Installed plugins screen
|
27 |
+
* Called from filter 'plugin_row_meta'
|
28 |
+
*/
|
29 |
+
public function action_plugin_row_meta( $links, $file ) {
|
30 |
+
|
31 |
+
if ( $file == $this->simple_history->plugin_basename ) {
|
32 |
+
$links = array_merge(
|
33 |
+
$links,
|
34 |
+
array( sprintf( '<a href="https://www.paypal.me/eskapism">%1$s</a>', __( 'Donate', 'simple-history' ) ) )
|
35 |
+
);
|
36 |
+
}
|
37 |
+
|
38 |
+
return $links;
|
39 |
+
}
|
40 |
+
|
41 |
+
public function add_settings() {
|
42 |
+
|
43 |
+
$settings_section_id = 'simple_history_settings_section_donate';
|
44 |
+
|
45 |
+
add_settings_section(
|
46 |
+
$settings_section_id,
|
47 |
+
_x( 'Donate', 'donate settings headline', 'simple-history' ), // No title __("General", "simple-history"),
|
48 |
+
array( $this, 'settings_section_output' ),
|
49 |
+
SimpleHistory::SETTINGS_MENU_SLUG // same slug as for options menu page
|
50 |
+
);
|
51 |
+
}
|
52 |
+
|
53 |
+
public function settings_section_output() {
|
54 |
+
|
55 |
+
printf(
|
56 |
+
wp_kses(
|
57 |
+
__( 'If you find Simple History useful please <a href="%1$s">donate</a>.', 'simple-history' ),
|
58 |
+
array(
|
59 |
+
'a' => array(
|
60 |
+
'href' => array(),
|
61 |
+
),
|
62 |
+
)
|
63 |
+
),
|
64 |
+
'https://www.paypal.me/eskapism'
|
65 |
+
);
|
66 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
dropins/SimpleHistoryExportDropin.php
CHANGED
@@ -6,247 +6,230 @@
|
|
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 |
-
$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 |
-
|
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 |
<li>
|
150 |
<div>%1$s</div>
|
151 |
<div>%2$s</div>
|
152 |
<div>%3$s</div>
|
153 |
</li>
|
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 |
-
</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 |
}
|
6 |
* Dropin URI: http://simple-history.com/
|
7 |
* Author: Pär Thernström
|
8 |
*/
|
9 |
+
class SimpleHistoryExportDropin {
|
10 |
+
/**
|
11 |
+
* Simple History instance.
|
12 |
+
*
|
13 |
+
* @var $sh
|
14 |
+
*/
|
15 |
+
private $sh;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Constructor.
|
19 |
+
*
|
20 |
+
* @param instance $sh Simple History instance.
|
21 |
+
*/
|
22 |
+
public function __construct( $sh ) {
|
23 |
+
|
24 |
+
$this->sh = $sh;
|
25 |
+
|
26 |
+
// Add tab to settings page.
|
27 |
+
$sh->registerSettingsTab(
|
28 |
+
array(
|
29 |
+
'slug' => 'export',
|
30 |
+
'name' => _x( 'Export', 'Export dropin: Tab name on settings page', 'simple-history' ),
|
31 |
+
'function' => array( $this, 'output' ),
|
32 |
+
)
|
33 |
+
);
|
34 |
+
|
35 |
+
add_action( 'init', array( $this, 'downloadExport' ) );
|
36 |
+
}
|
37 |
+
|
38 |
+
public function downloadExport() {
|
39 |
+
|
40 |
+
global $wpdb;
|
41 |
+
|
42 |
+
if ( isset( $_POST['simple-history-action'] ) && $_POST['simple-history-action'] === 'export-history' ) {
|
43 |
+
// Will die if nonce not valid.
|
44 |
+
check_admin_referer( __CLASS__ . '-action-export' );
|
45 |
+
|
46 |
+
$export_format = isset( $_POST['format'] ) ? $_POST['format'] : 'json';
|
47 |
+
|
48 |
+
// Disable relative time output in header.
|
49 |
+
add_filter( 'simple_history/header_time_ago_max_time', '__return_zero' );
|
50 |
+
add_filter( 'simple_history/header_just_now_max_time', '__return_zero' );
|
51 |
+
|
52 |
+
// Don't use "You" if event is initiated by the same user that does the export
|
53 |
+
add_filter( 'simple_history/header_initiator_use_you', '__return_false' );
|
54 |
+
|
55 |
+
$query = new SimpleHistoryLogQuery();
|
56 |
+
|
57 |
+
$query_args = array(
|
58 |
+
'paged' => 1,
|
59 |
+
'posts_per_page' => 3000,
|
60 |
+
);
|
61 |
+
|
62 |
+
$events = $query->query( $query_args );
|
63 |
+
|
64 |
+
// $events->total_row_count;
|
65 |
+
$pages_count = $events['pages_count'];
|
66 |
+
$page_current = $events['page_current'];
|
67 |
+
|
68 |
+
$fp = fopen( 'php://output', 'w' );
|
69 |
+
|
70 |
+
$attachment_header_template = 'Content-Disposition: attachment; filename="%1$s"';
|
71 |
+
|
72 |
+
if ( 'csv' == $export_format ) {
|
73 |
+
$filename = 'simple-history-export-' . time() . '.csv';
|
74 |
+
header( 'Content-Type: text/plain' );
|
75 |
+
header( sprintf( $attachment_header_template, $filename ) );
|
76 |
+
} elseif ( 'json' == $export_format ) {
|
77 |
+
$filename = 'simple-history-export-' . time() . '.json';
|
78 |
+
header( 'Content-Type: application/json' );
|
79 |
+
header( sprintf( $attachment_header_template, $filename ) );
|
80 |
+
} elseif ( 'html' == $export_format ) {
|
81 |
+
$filename = 'simple-history-export-' . time() . '.html';
|
82 |
+
header( 'Content-Type: text/html' );
|
83 |
+
// header("Content-Disposition: attachment; filename='{$filename}'");
|
84 |
+
}
|
85 |
+
|
86 |
+
// Some formats need to output some stuff before the actual loops
|
87 |
+
if ( 'json' == $export_format ) {
|
88 |
+
$json_row = '[';
|
89 |
+
fwrite( $fp, $json_row );
|
90 |
+
} elseif ( 'html' == $export_format ) {
|
91 |
+
$html = sprintf(
|
92 |
+
'
|
|
|
|
|
|
|
|
|
|
|
93 |
<!doctype html>
|
94 |
<meta charset="utf-8">
|
95 |
<title>Simple History export</title>
|
96 |
<ul>
|
97 |
'
|
98 |
+
);
|
99 |
+
fwrite( $fp, $html );
|
100 |
+
}
|
101 |
+
|
102 |
+
// Paginate through all pages and all their rows.
|
103 |
+
$row_loop = 0;
|
104 |
+
while ( $page_current <= $pages_count + 1 ) {
|
105 |
+
// if ($page_current > 1) { break; } # To debug/test
|
106 |
+
foreach ( $events['log_rows'] as $one_row ) {
|
107 |
+
// if ( $row_loop > 10) { break; } # To debug/test
|
108 |
+
set_time_limit( 30 );
|
109 |
+
|
110 |
+
if ( 'csv' == $export_format ) {
|
111 |
+
$header_output = strip_tags( html_entity_decode( $this->sh->getLogRowHeaderOutput( $one_row ), ENT_QUOTES, 'UTF-8' ) );
|
112 |
+
$header_output = trim( preg_replace( '/\s\s+/', ' ', $header_output ) );
|
113 |
+
|
114 |
+
$message_output = strip_tags( html_entity_decode( $this->sh->getLogRowPlainTextOutput( $one_row ), ENT_QUOTES, 'UTF-8' ) );
|
115 |
+
|
116 |
+
$user_email = empty( $one_row->context['_user_email'] ) ? null : $one_row->context['_user_email'];
|
117 |
+
$user_login = empty( $one_row->context['_user_login'] ) ? null : $one_row->context['_user_login'];
|
118 |
+
|
119 |
+
fputcsv(
|
120 |
+
$fp,
|
121 |
+
array(
|
122 |
+
$one_row->date,
|
123 |
+
$one_row->logger,
|
124 |
+
$one_row->level,
|
125 |
+
$one_row->initiator,
|
126 |
+
$one_row->context_message_key,
|
127 |
+
$user_email,
|
128 |
+
$user_login,
|
129 |
+
$header_output,
|
130 |
+
$message_output,
|
131 |
+
$one_row->subsequentOccasions,
|
132 |
+
)
|
133 |
+
);
|
134 |
+
} elseif ( 'json' == $export_format ) {
|
135 |
+
// If not first loop then add a comma between all json objects.
|
136 |
+
if ( $row_loop == 0 ) {
|
137 |
+
$comma = "\n";
|
138 |
+
} else {
|
139 |
+
$comma = ",\n";
|
140 |
+
}
|
141 |
+
|
142 |
+
$json_row = $comma . $this->sh->json_encode( $one_row );
|
143 |
+
fwrite( $fp, $json_row );
|
144 |
+
} elseif ( 'html' == $export_format ) {
|
145 |
+
$html = sprintf(
|
146 |
+
'
|
147 |
<li>
|
148 |
<div>%1$s</div>
|
149 |
<div>%2$s</div>
|
150 |
<div>%3$s</div>
|
151 |
</li>
|
152 |
',
|
153 |
+
$this->sh->getLogRowHeaderOutput( $one_row ),
|
154 |
+
$this->sh->getLogRowPlainTextOutput( $one_row ),
|
155 |
+
$this->sh->getLogRowDetailsOutput( $one_row )
|
156 |
+
);
|
157 |
+
|
158 |
+
fwrite( $fp, $html );
|
159 |
+
}// End if().
|
160 |
+
|
161 |
+
$row_loop++;
|
162 |
+
}// End foreach().
|
163 |
+
|
164 |
+
// echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
165 |
+
// echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
166 |
+
// echo "<br>fetch next page";
|
167 |
+
flush();
|
168 |
+
|
169 |
+
// Fetch next page
|
170 |
+
// @TODO: must take into consideration that new items can be added while we do the fetch
|
171 |
+
$page_current++;
|
172 |
+
$query_args['paged'] = $page_current;
|
173 |
+
$events = $query->query( $query_args );
|
174 |
+
|
175 |
+
// echo "<br>did fetch next page";
|
176 |
+
// echo "<br>memory_get_usage:<br>"; print_r(memory_get_usage());
|
177 |
+
// echo "<br>memory_get_peak_usage:<br>"; print_r(memory_get_peak_usage());
|
178 |
+
}// End while().
|
179 |
+
|
180 |
+
if ( 'json' == $export_format ) {
|
181 |
+
$json_row = ']';
|
182 |
+
fwrite( $fp, $json_row );
|
183 |
+
} elseif ( 'html' == $export_format ) {
|
184 |
+
$html = sprintf( '</ul>' );
|
185 |
+
fwrite( $fp, $html );
|
186 |
+
}
|
187 |
+
|
188 |
+
fclose( $fp );
|
189 |
+
flush();
|
190 |
+
|
191 |
+
exit;
|
192 |
+
|
193 |
+
// echo "<br>done";
|
194 |
+
}// End if().
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
public function output() {
|
199 |
+
?>
|
200 |
+
<p><?php echo esc_html_x( 'The export function will export the full history.', 'Export dropin: introtext', 'simple-history' ); ?></p>
|
201 |
+
|
202 |
+
<form method="post">
|
203 |
+
|
204 |
+
<h3><?php echo esc_html_x( 'Choose format to export to', 'Export dropin: format', 'simple-history' ); ?></h3>
|
205 |
+
|
206 |
+
<p>
|
207 |
+
<label>
|
208 |
+
<input type="radio" name="format" value="json" checked>
|
209 |
+
<?php echo esc_html_x( 'JSON', 'Export dropin: export format', 'simple-history' ); ?>
|
210 |
+
</label>
|
211 |
+
</p>
|
212 |
+
|
213 |
+
<p>
|
214 |
+
<label>
|
215 |
+
<input type="radio" name="format" value="csv">
|
216 |
+
<?php echo esc_html_x( 'CSV', 'Export dropin: export format', 'simple-history' ); ?>
|
217 |
+
</label>
|
218 |
+
</p>
|
219 |
+
|
220 |
+
<p>
|
221 |
+
<button type="submit" class="button button-primary">
|
222 |
+
<?php echo esc_html_x( 'Download Export File', 'Export dropin: submit button', 'simple-history' ); ?>
|
223 |
+
</button>
|
224 |
+
<input type="hidden" name="simple-history-action" value="export-history">
|
225 |
+
</p>
|
226 |
+
|
227 |
+
<?php
|
228 |
+
wp_nonce_field( __CLASS__ . '-action-export' );
|
229 |
+
?>
|
230 |
+
|
231 |
+
</form>
|
232 |
+
|
233 |
+
<?php
|
234 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
}
|
dropins/SimpleHistoryFilterDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Filter GUI
|
@@ -8,593 +8,633 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistoryFilterDropin
|
12 |
-
{
|
13 |
|
14 |
-
// Simple History instance
|
15 |
-
private $sh;
|
16 |
|
17 |
-
|
18 |
-
|
19 |
|
20 |
-
|
21 |
|
22 |
-
|
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 |
-
|
29 |
-
|
|
|
|
|
|
|
30 |
|
31 |
-
|
32 |
|
33 |
-
|
34 |
|
35 |
-
|
36 |
-
}
|
37 |
|
|
|
|
|
38 |
|
39 |
-
public function gui_page_filters()
|
40 |
-
{
|
41 |
|
42 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
-
|
|
|
61 |
|
62 |
-
|
|
|
63 |
|
64 |
-
|
|
|
|
|
|
|
65 |
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
$loggers_user_can_read_sql_in = $this->sh->getLoggersThatUserCanRead(null, 'sql');
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
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 |
-
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
public function __construct( $sh ) {
|
18 |
|
19 |
+
$this->sh = $sh;
|
|
|
|
|
|
|
|
|
20 |
|
21 |
+
add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
22 |
+
add_action( 'simple_history/history_page/before_gui', array( $this, 'gui_page_filters' ) );
|
23 |
+
add_action( 'simple_history/dashboard/before_gui', array( $this, 'gui_page_filters' ) );
|
24 |
+
add_action( 'wp_ajax_simple_history_filters_search_user', array( $this, 'ajax_simple_history_filters_search_user' ) );
|
25 |
+
}
|
26 |
|
27 |
+
public function enqueue_admin_scripts() {
|
28 |
|
29 |
+
$file_url = plugin_dir_url( __FILE__ );
|
30 |
|
31 |
+
wp_enqueue_script( 'simple_history_FilterDropin', $file_url . 'SimpleHistoryFilterDropin.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true );
|
|
|
32 |
|
33 |
+
wp_enqueue_style( 'simple_history_FilterDropin', $file_url . 'SimpleHistoryFilterDropin.css', null, SIMPLE_HISTORY_VERSION );
|
34 |
+
}
|
35 |
|
|
|
|
|
36 |
|
37 |
+
public function gui_page_filters() {
|
38 |
|
39 |
+
$loggers_user_can_read = $this->sh->getLoggersThatUserCanRead();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
+
/**
|
42 |
+
* Filter that determines if search filters should be visible directly on page load
|
43 |
+
*
|
44 |
+
* Set to true to show the filters when page is loaded
|
45 |
+
* If false then user must click "Show options"
|
46 |
+
*
|
47 |
+
* @since 2.1.2
|
48 |
+
*
|
49 |
+
* @param bool $show_more_filters_on_load Default false
|
50 |
+
*/
|
51 |
+
$show_more_filters_on_load = false;
|
52 |
+
$show_more_filters_on_load = apply_filters( 'SimpleHistoryFilterDropin/show_more_filters_on_load', $show_more_filters_on_load );
|
53 |
|
54 |
+
?>
|
55 |
+
<div class="SimpleHistory__filters <?php echo $show_more_filters_on_load ? 'is-showingMoreFilters' : ''; ?>">
|
56 |
|
57 |
+
<form class="SimpleHistory__filters__form js-SimpleHistory__filters__form">
|
58 |
+
<?php
|
59 |
|
60 |
+
// Start months filter
|
61 |
+
global $wpdb;
|
62 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
63 |
+
$loggers_user_can_read_sql_in = $this->sh->getLoggersThatUserCanRead( null, 'sql' );
|
64 |
|
65 |
+
// Get unique months
|
66 |
+
$cache_key = 'sh_filter_unique_months';
|
67 |
+
$result_months = get_transient( $cache_key );
|
|
|
68 |
|
69 |
+
if ( false === $result_months ) {
|
70 |
+
$sql_dates = sprintf(
|
71 |
+
'
|
|
|
|
|
|
|
|
|
72 |
SELECT DISTINCT ( date_format(DATE, "%%Y-%%m") ) AS yearMonth
|
73 |
FROM %s
|
74 |
WHERE logger IN %s
|
75 |
ORDER BY yearMonth DESC
|
76 |
',
|
77 |
+
$table_name, // 1
|
78 |
+
$loggers_user_can_read_sql_in // 2
|
79 |
+
);
|
80 |
+
|
81 |
+
$result_months = $wpdb->get_results( $sql_dates ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
82 |
+
|
83 |
+
set_transient( $cache_key, $result_months, HOUR_IN_SECONDS );
|
84 |
+
}
|
85 |
+
|
86 |
+
$arr_days_and_pages = array();
|
87 |
+
|
88 |
+
// Default month = current month
|
89 |
+
// Mainly for performance reasons, since often
|
90 |
+
// it's not the users intention to view all events,
|
91 |
+
// but just the latest
|
92 |
+
|
93 |
+
// Determine if we limit the date range by default
|
94 |
+
$daysToShow = 1;
|
95 |
+
|
96 |
+
// Start with the latest day
|
97 |
+
$numEvents = $this->sh->get_unique_events_for_days( $daysToShow );
|
98 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
99 |
+
|
100 |
+
$arr_days_and_pages[] = array(
|
101 |
+
'daysToShow' => $daysToShow,
|
102 |
+
'numPages' => $numPages,
|
103 |
+
);
|
104 |
+
|
105 |
+
// Example on my server with lots of brute force attacks (causing log to not load)
|
106 |
+
// 166434 / 15 = 11 000 pages for last 7 days
|
107 |
+
// 1 day = 3051 / 15 = 203 pages = still much but better than 11000 pages!
|
108 |
+
if ( $numPages < 20 ) {
|
109 |
+
// Not that many things the last day. Let's try to expand to 7 days instead.
|
110 |
+
$daysToShow = 7;
|
111 |
+
$numEvents = $this->sh->get_unique_events_for_days( $daysToShow );
|
112 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
113 |
+
|
114 |
+
$arr_days_and_pages[] = array(
|
115 |
+
'daysToShow' => $daysToShow,
|
116 |
+
'numPages' => $numPages,
|
117 |
+
);
|
118 |
+
|
119 |
+
if ( $numPages < 20 ) {
|
120 |
+
// Not that many things the last 7 days. Let's try to expand to 14 days instead.
|
121 |
+
$daysToShow = 14;
|
122 |
+
$numEvents = $this->sh->get_unique_events_for_days( $daysToShow );
|
123 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
124 |
+
|
125 |
+
$arr_days_and_pages[] = array(
|
126 |
+
'daysToShow' => $daysToShow,
|
127 |
+
'numPages' => $numPages,
|
128 |
+
);
|
129 |
+
|
130 |
+
if ( $numPages < 20 ) {
|
131 |
+
// Not many things the last 14 days either. Let try with 30 days.
|
132 |
+
$daysToShow = 30;
|
133 |
+
$numEvents = $this->sh->get_unique_events_for_days( $daysToShow );
|
134 |
+
$numPages = $numEvents / $this->sh->get_pager_size();
|
135 |
+
|
136 |
+
$arr_days_and_pages[] = array(
|
137 |
+
'daysToShow' => $daysToShow,
|
138 |
+
'numPages' => $numPages,
|
139 |
+
);
|
140 |
+
|
141 |
+
// If 30 days gives a big amount of pages, go back to 14 days
|
142 |
+
if ( $numPages > 1000 ) {
|
143 |
+
$daysToShow = 14;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
}
|
147 |
+
}// End if().
|
148 |
+
|
149 |
+
?>
|
150 |
+
|
151 |
+
<p class="SimpleHistory__filters__filterRow SimpleHistory__filters__filterRow--date" data-debug-daysAndPages='<?php echo json_encode( $arr_days_and_pages ); ?>'>
|
152 |
+
|
153 |
+
<label class="SimpleHistory__filters__filterLabel"><?php echo esc_html_x( 'Dates:', 'Filter label', 'simple-history' ); ?></label>
|
154 |
+
|
155 |
+
<select class="SimpleHistory__filters__filter SimpleHistory__filters__filter--date"
|
156 |
+
name="dates"
|
157 |
+
placeholder="<?php esc_attr_e( 'All dates', 'simple-history' ); ?>"
|
158 |
+
NOTmultiple
|
159 |
+
>
|
160 |
+
<?php
|
161 |
+
|
162 |
+
// custom date range
|
163 |
+
// since 2.8.1
|
164 |
+
printf(
|
165 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
166 |
+
'customRange', // 1 - value
|
167 |
+
esc_attr_x( 'Custom date range...', 'Filter dropin: filter custom range', 'simple-history' ), // 2 text
|
168 |
+
selected( $daysToShow, 'customRange', 0 )
|
169 |
+
);
|
170 |
+
|
171 |
+
// One day+ Last week + two weeks back + 30 days back
|
172 |
+
printf(
|
173 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
174 |
+
'lastdays:1', // 1 - value
|
175 |
+
esc_attr_x( 'Last day', 'Filter dropin: filter week', 'simple-history' ), // 2 text
|
176 |
+
selected( $daysToShow, 1, 0 )
|
177 |
+
);
|
178 |
+
|
179 |
+
printf(
|
180 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
181 |
+
'lastdays:7', // 1 - value
|
182 |
+
esc_attr_x( 'Last 7 days', 'Filter dropin: filter week', 'simple-history' ), // 2 text
|
183 |
+
selected( $daysToShow, 7, 0 )
|
184 |
+
);
|
185 |
+
|
186 |
+
printf(
|
187 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
188 |
+
'lastdays:14', // 1 - value
|
189 |
+
esc_attr_x( 'Last 14 days', 'Filter dropin: filter week', 'simple-history' ), // 2 text
|
190 |
+
selected( $daysToShow, 14, 0 )
|
191 |
+
);
|
192 |
+
|
193 |
+
printf(
|
194 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
195 |
+
'lastdays:30', // 1 - value
|
196 |
+
esc_attr_x( 'Last 30 days', 'Filter dropin: filter week', 'simple-history' ), // 2 text
|
197 |
+
selected( $daysToShow, 30, 0 )
|
198 |
+
);
|
199 |
+
|
200 |
+
printf(
|
201 |
+
'<option value="%1$s" %3$s>%2$s</option>',
|
202 |
+
'lastdays:60', // 1 - value
|
203 |
+
esc_attr_x( 'Last 60 days', 'Filter dropin: filter week', 'simple-history' ), // 2 text
|
204 |
+
selected( $daysToShow, 60, 0 )
|
205 |
+
);
|
206 |
+
|
207 |
+
// Months
|
208 |
+
foreach ( $result_months as $row ) {
|
209 |
+
printf(
|
210 |
+
'<option value="%1$s">%2$s</option>',
|
211 |
+
'month:' . esc_attr( $row->yearMonth ),
|
212 |
+
esc_attr(
|
213 |
+
date_i18n(
|
214 |
+
'F Y',
|
215 |
+
strtotime( $row->yearMonth )
|
216 |
+
)
|
217 |
+
)
|
218 |
+
);
|
219 |
+
}
|
220 |
+
|
221 |
+
?>
|
222 |
+
</select>
|
223 |
+
|
224 |
+
<span class="SimpleHistory__filters__filter--dayValuesWrap">
|
225 |
+
<?php
|
226 |
+
$this->touch_time( 'from' );
|
227 |
+
$this->touch_time( 'to' );
|
228 |
+
?>
|
229 |
+
</span>
|
230 |
+
|
231 |
+
</p><!-- end months -->
|
232 |
+
|
233 |
+
<?php
|
234 |
+
/**
|
235 |
+
* Filter to control what the default search string is. Default to empty string.
|
236 |
+
*
|
237 |
+
* @since 2.1.2
|
238 |
+
*
|
239 |
+
* @param string Default search string
|
240 |
+
*/
|
241 |
+
$default_search_string = apply_filters( 'SimpleHistoryFilterDropin/filter_default_search_string', '' );
|
242 |
+
?>
|
243 |
+
|
244 |
+
<p>
|
245 |
+
<label class="SimpleHistory__filters__filterLabel">
|
246 |
+
<?php echo esc_html_x( 'Containing words:', 'Filter label', 'simple-history' ); ?>
|
247 |
+
</label>
|
248 |
+
|
249 |
+
<input
|
250 |
+
type="search"
|
251 |
+
class="SimpleHistoryFilterDropin-searchInput"
|
252 |
+
placeholder=""
|
253 |
+
name="search"
|
254 |
+
value="<?php echo esc_attr( $default_search_string ); ?>"
|
255 |
+
>
|
256 |
+
</p>
|
257 |
+
|
258 |
+
<p class="SimpleHistory__filters__filterSubmitWrap">
|
259 |
+
<button class="button SimpleHistoryFilterDropin-doFilterButton SimpleHistoryFilterDropin-doFilterButton--first js-SimpleHistoryFilterDropin-doFilter">
|
260 |
+
<?php esc_html_e( 'Search events', 'simple-history' ); ?>
|
261 |
+
</button>
|
262 |
+
<button type="button" class="SimpleHistoryFilterDropin-showMoreFilters SimpleHistoryFilterDropin-showMoreFilters--first js-SimpleHistoryFilterDropin-showMoreFilters">
|
263 |
+
<?php echo esc_html_x( 'Show search options', 'Filter dropin: button to show more search options', 'simple-history' ); ?>
|
264 |
+
</button>
|
265 |
+
</p>
|
266 |
+
|
267 |
+
<?php
|
268 |
+
/**
|
269 |
+
* Filter to control what the default loglevels are.
|
270 |
+
*
|
271 |
+
* @since 2.1.2
|
272 |
+
*
|
273 |
+
* @param array Array with loglevel sugs. Default empty = show all.
|
274 |
+
*/
|
275 |
+
$arr_default_loglevels = apply_filters( 'SimpleHistoryFilterDropin/filter_default_loglevel', array() );
|
276 |
+
?>
|
277 |
+
<div class="SimpleHistory__filters__moreFilters js-SimpleHistory__filters__moreFilters">
|
278 |
+
|
279 |
+
<p>
|
280 |
+
<label class="SimpleHistory__filters__filterLabel">
|
281 |
+
<?php echo esc_html_x( 'Log levels:', 'Filter label', 'simple-history' ); ?>
|
282 |
+
</label>
|
283 |
+
|
284 |
+
<select
|
285 |
+
name="loglevels"
|
286 |
+
class="SimpleHistory__filters__filter SimpleHistory__filters__filter--loglevel"
|
287 |
+
placeholder="<?php esc_attr_e( 'All log levels', 'simple-history' ); ?>"
|
288 |
+
multiple
|
289 |
+
>
|
290 |
+
<option <?php selected( in_array( 'debug', $arr_default_loglevels ) ); ?> value="debug" data-color="#CEF6D8">
|
291 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Debug' ) ); ?>
|
292 |
+
</option>
|
293 |
+
<option <?php selected( in_array( 'info', $arr_default_loglevels ) ); ?> value="info" data-color="white">
|
294 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Info' ) ); ?>
|
295 |
+
</option>
|
296 |
+
<option <?php selected( in_array( 'notice', $arr_default_loglevels ) ); ?> value="notice" data-color="rgb(219, 219, 183)">
|
297 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Notice' ) ); ?>
|
298 |
+
</option>
|
299 |
+
<option <?php selected( in_array( 'warning', $arr_default_loglevels ) ); ?> value="warning" data-color="#F7D358">
|
300 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Warning' ) ); ?>
|
301 |
+
</option>
|
302 |
+
<option <?php selected( in_array( 'error', $arr_default_loglevels ) ); ?> value="error" data-color="#F79F81">
|
303 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Error' ) ); ?>
|
304 |
+
</option>
|
305 |
+
<option <?php selected( in_array( 'critical', $arr_default_loglevels ) ); ?> value="critical" data-color="#FA5858">
|
306 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Critical' ) ); ?>
|
307 |
+
</option>
|
308 |
+
<option <?php selected( in_array( 'alert', $arr_default_loglevels ) ); ?> value="alert" data-color="rgb(199, 69, 69)">
|
309 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Alert' ) ); ?>
|
310 |
+
</option>
|
311 |
+
<option <?php selected( in_array( 'emergency', $arr_default_loglevels ) ); ?> value="emergency" data-color="#DF0101">
|
312 |
+
<?php echo esc_html( $this->sh->getLogLevelTranslated( 'Emergency' ) ); ?>
|
313 |
+
</option>
|
314 |
+
</select>
|
315 |
+
|
316 |
+
</p>
|
317 |
+
|
318 |
+
<?php
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Todo: Filter to control what the default messages to filter/search.
|
322 |
+
* Message in in format: LoggerSlug:MessageKey
|
323 |
+
* For example:
|
324 |
+
* - SimplePluginLogger:plugin_activated
|
325 |
+
* - SimpleCommentsLogger:user_comment_added
|
326 |
+
*
|
327 |
+
* @since 2.1.2
|
328 |
+
*
|
329 |
+
* @param array Array with loglevel sugs. Default empty = show all.
|
330 |
+
*/
|
331 |
+
// $arr_default_messages = apply_filters("SimpleHistoryFilterDropin/filter_default_messages", array());
|
332 |
+
?>
|
333 |
+
<p>
|
334 |
+
<label class="SimpleHistory__filters__filterLabel">
|
335 |
+
<?php echo esc_html_x( 'Message types:', 'Filter label', 'simple-history' ); ?>
|
336 |
+
</label>
|
337 |
+
|
338 |
+
<select
|
339 |
+
name="messages"
|
340 |
+
class="SimpleHistory__filters__filter SimpleHistory__filters__filter--logger"
|
341 |
+
placeholder="<?php esc_attr_e( 'All messages', 'simple-history' ); ?>"
|
342 |
+
multiple
|
343 |
+
>
|
344 |
+
<?php
|
345 |
+
foreach ( $loggers_user_can_read as $logger ) {
|
346 |
+
$logger_info = $logger['instance']->getInfo();
|
347 |
+
$logger_slug = $logger['instance']->slug;
|
348 |
+
|
349 |
+
// Get labels for logger
|
350 |
+
if ( isset( $logger_info['labels']['search'] ) ) {
|
351 |
+
printf( '<optgroup label="%1$s">', esc_attr( $logger_info['labels']['search']['label'] ) );
|
352 |
+
|
353 |
+
// If all activity
|
354 |
+
if ( ! empty( $logger_info['labels']['search']['label_all'] ) ) {
|
355 |
+
$arr_all_search_messages = array();
|
356 |
+
foreach ( $logger_info['labels']['search']['options'] as $option_key => $option_messages ) {
|
357 |
+
$arr_all_search_messages = array_merge( $arr_all_search_messages, $option_messages );
|
358 |
+
}
|
359 |
+
|
360 |
+
foreach ( $arr_all_search_messages as $key => $val ) {
|
361 |
+
$arr_all_search_messages[ $key ] = $logger_slug . ':' . $val;
|
362 |
+
}
|
363 |
+
|
364 |
+
printf( '<option value="%2$s">%1$s</option>', esc_attr( $logger_info['labels']['search']['label_all'] ), esc_attr( implode( ',', $arr_all_search_messages ) ) );
|
365 |
+
}
|
366 |
+
|
367 |
+
// For each specific search option
|
368 |
+
foreach ( $logger_info['labels']['search']['options'] as $option_key => $option_messages ) {
|
369 |
+
foreach ( $option_messages as $key => $val ) {
|
370 |
+
$option_messages[ $key ] = $logger_slug . ':' . $val;
|
371 |
+
}
|
372 |
+
|
373 |
+
$str_option_messages = implode( ',', $option_messages );
|
374 |
+
printf(
|
375 |
+
'<option value="%2$s">%1$s</option>',
|
376 |
+
esc_attr( $option_key ), // 1
|
377 |
+
esc_attr( $str_option_messages ) // 2
|
378 |
+
);
|
379 |
+
}
|
380 |
+
|
381 |
+
printf( '</optgroup>' );
|
382 |
+
}// End if().
|
383 |
+
}// End foreach().
|
384 |
+
?>
|
385 |
+
</select>
|
386 |
+
</p>
|
387 |
+
|
388 |
+
<?php
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Filter what users to search for by default
|
392 |
+
*
|
393 |
+
* Example:
|
394 |
+
*
|
395 |
+
* add_filter("SimpleHistoryFilterDropin/filter_default_user_ids", function() { return array(1,4); });
|
396 |
+
*
|
397 |
+
* @since 2.1.2
|
398 |
+
*
|
399 |
+
* @param array Array with user ids. Default is an empty array = show all users.
|
400 |
+
*/
|
401 |
+
|
402 |
+
/*
|
403 |
+
add_filter("SimpleHistoryFilterDropin/filter_default_user_ids", function($arr) {
|
404 |
+
$arr = array(
|
405 |
+
1,
|
406 |
+
4
|
407 |
+
);
|
408 |
+
return $arr;
|
409 |
+
});
|
410 |
+
//*/
|
411 |
+
|
412 |
+
$default_user_ids = apply_filters( 'SimpleHistoryFilterDropin/filter_default_user_ids', array() ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
|
413 |
+
$arr_default_user_data = array();
|
414 |
+
|
415 |
+
foreach ( $default_user_ids as $user_id ) {
|
416 |
+
$arr_default_user_data[] = $this->get_data_for_user( $user_id );
|
417 |
+
}
|
418 |
+
|
419 |
+
if ( current_user_can( 'list_users' ) ) {
|
420 |
+
?>
|
421 |
+
<p>
|
422 |
+
<label class="SimpleHistory__filters__filterLabel">
|
423 |
+
<?php echo esc_html_x( 'Users:', 'Filter label', 'simple-history' ); ?>
|
424 |
+
</label>
|
425 |
+
<select
|
426 |
+
name="users"
|
427 |
+
class="SimpleHistory__filters__filter SimpleHistory__filters__filter--user"
|
428 |
+
data-placeholder="<?php esc_html_e( 'All users', 'simple-history' ); ?>"
|
429 |
+
value="<?php echo esc_attr( implode( ',', $default_user_ids ) ); ?>"
|
430 |
+
data-default-user-data="<?php echo esc_attr( json_encode( $arr_default_user_data ) ); ?>"
|
431 |
+
>
|
432 |
+
</select>
|
433 |
+
</p>
|
434 |
+
<?php
|
435 |
+
}
|
436 |
+
|
437 |
+
?>
|
438 |
+
|
439 |
+
<p class="SimpleHistory__filters__filterSubmitWrap">
|
440 |
+
<button class="button SimpleHistoryFilterDropin-doFilterButton SimpleHistoryFilterDropin-doFilterButton--second js-SimpleHistoryFilterDropin-doFilter">
|
441 |
+
<?php esc_html_e( 'Search events', 'simple-history' ); ?>
|
442 |
+
</button>
|
443 |
+
<button type="button" class="SimpleHistoryFilterDropin-showMoreFilters SimpleHistoryFilterDropin-showMoreFilters--second js-SimpleHistoryFilterDropin-showMoreFilters">
|
444 |
+
<?php esc_html_x( 'Hide search options', 'Filter dropin: button to hide more search options', 'simple-history' ); ?>
|
445 |
+
</button>
|
446 |
+
</p>
|
447 |
+
|
448 |
+
</div><!-- // more filters -->
|
449 |
+
|
450 |
+
</form>
|
451 |
+
|
452 |
+
</div>
|
453 |
+
<?php
|
454 |
+
}
|
455 |
+
|
456 |
+
/**
|
457 |
+
* Return format used for select2 for a single user id.
|
458 |
+
*
|
459 |
+
* @param int $userID
|
460 |
+
* @return array Array with each user as an object
|
461 |
+
*/
|
462 |
+
public function get_data_for_user( $userID ) {
|
463 |
+
if ( ! $userID || ! is_numeric( $userID ) ) {
|
464 |
+
return false;
|
465 |
+
}
|
466 |
+
|
467 |
+
$user = get_user_by( 'id', $userID );
|
468 |
+
|
469 |
+
if ( false == $user ) {
|
470 |
+
return false;
|
471 |
+
}
|
472 |
+
|
473 |
+
$userdata = (object) array(
|
474 |
+
'id' => $user->ID,
|
475 |
+
'user_email' => $user->user_email,
|
476 |
+
'user_login' => $user->user_login,
|
477 |
+
'user_nicename' => $user->user_nicename,
|
478 |
+
);
|
479 |
+
|
480 |
+
$this->add_gravatar_to_user_array( $userdata );
|
481 |
+
|
482 |
+
return $userdata;
|
483 |
+
}
|
484 |
+
|
485 |
+
/**
|
486 |
+
* Return users
|
487 |
+
*/
|
488 |
+
public function ajax_simple_history_filters_search_user() {
|
489 |
+
|
490 |
+
$q = isset( $_GET['q'] ) ? $_GET['q'] : '';
|
491 |
+
$page_limit = isset( $_GET['page_limit'] ) ? (int) $_GET['page_limit'] : '';
|
492 |
+
|
493 |
+
// query and page limit must be set
|
494 |
+
if ( ! $q || ! $page_limit ) {
|
495 |
+
wp_send_json_error();
|
496 |
+
}
|
497 |
+
|
498 |
+
// user must have list_users capability (default super admin + administrators have this)
|
499 |
+
if ( ! current_user_can( 'list_users' ) ) {
|
500 |
+
wp_send_json_error();
|
501 |
+
}
|
502 |
+
|
503 |
+
// Search both current users and all logged rows,
|
504 |
+
// because a user can change email
|
505 |
+
// search in context: user_id, user_email, user_login
|
506 |
+
// search in wp_users: login, nicename, user_email
|
507 |
+
// 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
|
508 |
+
$results_user = get_users(
|
509 |
+
array(
|
510 |
+
'search' => "*{$q}*",
|
511 |
+
'fields' => array( 'ID', 'user_login', 'user_nicename', 'user_email', 'display_name' ),
|
512 |
+
'number' => 20,
|
513 |
+
)
|
514 |
+
);
|
515 |
+
|
516 |
+
// add lower case id to user array
|
517 |
+
array_walk(
|
518 |
+
$results_user,
|
519 |
+
function ( $val ) {
|
520 |
+
$val->id = $val->ID;
|
521 |
+
}
|
522 |
+
);
|
523 |
+
|
524 |
+
// add gravatars to user array
|
525 |
+
array_walk( $results_user, array( $this, 'add_gravatar_to_user_array' ) );
|
526 |
+
|
527 |
+
$data = array(
|
528 |
+
'results' => array(),
|
529 |
+
'more' => false,
|
530 |
+
'context' => array(),
|
531 |
+
'count' => count( $results_user ),
|
532 |
+
);
|
533 |
+
|
534 |
+
$data['results'] = array_merge( $data['results'], $results_user );
|
535 |
+
|
536 |
+
wp_send_json_success( $data );
|
537 |
+
}
|
538 |
+
|
539 |
+
public function add_gravatar_to_user_array( &$val, $index = null ) {
|
540 |
+
$val->text = sprintf(
|
541 |
+
'%1$s - %2$s',
|
542 |
+
$val->user_login,
|
543 |
+
$val->user_email
|
544 |
+
);
|
545 |
+
|
546 |
+
$val->gravatar = $this->sh->get_avatar( $val->user_email, '18', 'mm' );
|
547 |
+
}
|
548 |
+
|
549 |
+
|
550 |
+
/**
|
551 |
+
* Print out HTML form date elements for editing post or comment publish date.
|
552 |
+
*
|
553 |
+
* Based on the wordpress function touch_time();
|
554 |
+
*
|
555 |
+
* @global WP_Locale $wp_locale
|
556 |
+
*
|
557 |
+
* @param int|bool $edit Accepts 1|true for editing the date, 0|false for adding the date.
|
558 |
+
* @param int|bool $for_post Accepts 1|true for applying the date to a post, 0|false for a comment.
|
559 |
+
* @param int $tab_index The tabindex attribute to add. Default 0.
|
560 |
+
* @param int|bool $multi Optional. Whether the additional fields and buttons should be added.
|
561 |
+
* Default 0|false.
|
562 |
+
*/
|
563 |
+
public function touch_time( $from_or_to, $edit = 1 ) {
|
564 |
+
global $wp_locale;
|
565 |
+
|
566 |
+
// Prefix = text before the inputs
|
567 |
+
$prefix = '';
|
568 |
+
$input_prefix = '';
|
569 |
+
if ( 'from' == $from_or_to ) {
|
570 |
+
$prefix = _x( 'From', 'Filter dropin, custom date range', 'simple-history' );
|
571 |
+
$input_prefix = 'from_';
|
572 |
+
} elseif ( 'to' == $from_or_to ) {
|
573 |
+
$prefix = _x( 'To', 'Filter dropin, custom date range', 'simple-history' );
|
574 |
+
$input_prefix = 'to_';
|
575 |
+
}
|
576 |
+
|
577 |
+
// The default date to show in the inputs
|
578 |
+
$date = gmdate( 'Y-m-d' );
|
579 |
+
|
580 |
+
$jj = mysql2date( 'd', $date, false );
|
581 |
+
$mm = mysql2date( 'm', $date, false );
|
582 |
+
$aa = mysql2date( 'Y', $date, false );
|
583 |
+
|
584 |
+
$month = "<select name='{$input_prefix}mm'>";
|
585 |
+
|
586 |
+
for ( $i = 1; $i < 13; ++$i ) {
|
587 |
+
$monthnum = zeroise( $i, 2 );
|
588 |
+
$monthtext = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) );
|
589 |
+
$month .= "\t\t\t" . '<option value="' . $monthnum . '" data-text="' . $monthtext . '" ' . selected( $monthnum, $mm, false ) . '>';
|
590 |
+
/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
|
591 |
+
$month .= sprintf( __( '%1$s-%2$s', 'simple-history' ), $monthnum, $monthtext ) . "</option>\n";
|
592 |
+
}
|
593 |
+
$month .= '</select>';
|
594 |
+
$month .= '</label>';
|
595 |
+
|
596 |
+
$day = '<label><span class="screen-reader-text">' . __( 'Day', 'simple-history' ) . '</span><input type="text" name="' . $input_prefix . 'jj" value="' . $jj . '" size="2" maxlength="2" autocomplete="off" /></label>';
|
597 |
+
$year = '<label><span class="screen-reader-text">' . __( 'Year', 'simple-history' ) . '</span><input type="text" name="' . $input_prefix . 'aa" value="' . $aa . '" size="4" maxlength="4" autocomplete="off" /></label>';
|
598 |
+
|
599 |
+
echo '<span class="SimpleHistory__filters__filter SimpleHistory__filters__filter--day">';
|
600 |
+
|
601 |
+
echo esc_html( $prefix ) . '<br>';
|
602 |
+
|
603 |
+
$wp_kses_args = array(
|
604 |
+
'select' => array(
|
605 |
+
'name' => array(),
|
606 |
+
),
|
607 |
+
'label' => array(),
|
608 |
+
'option' => array(
|
609 |
+
'value' => array(),
|
610 |
+
'data-text' => array(),
|
611 |
+
'selected' => array(),
|
612 |
+
|
613 |
+
),
|
614 |
+
'span' => array(
|
615 |
+
'class' => array(),
|
616 |
+
),
|
617 |
+
'input' => array(
|
618 |
+
'type' => array(),
|
619 |
+
'name' => array(),
|
620 |
+
'value' => array(),
|
621 |
+
'size' => array(),
|
622 |
+
'maxlength' => array(),
|
623 |
+
'autocomplete' => array(),
|
624 |
+
),
|
625 |
+
);
|
626 |
+
|
627 |
+
/* translators: 1: month, 2: day, 3: year */
|
628 |
+
echo wp_kses(
|
629 |
+
sprintf(
|
630 |
+
__( '%1$s %2$s, %3$s', 'simple-history' ),
|
631 |
+
$month,
|
632 |
+
$day,
|
633 |
+
$year
|
634 |
+
),
|
635 |
+
$wp_kses_args
|
636 |
+
);
|
637 |
+
|
638 |
+
echo '</span>';
|
639 |
+
}
|
640 |
}
|
dropins/SimpleHistoryIpInfoDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: IP Info
|
@@ -8,204 +8,198 @@ 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 |
-
|
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 |
-
</script>
|
209 |
-
<?php
|
210 |
-
}
|
211 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: IP Info
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistoryIpInfoDropin {
|
12 |
+
private $sh;
|
13 |
+
|
14 |
+
public function __construct( $sh ) {
|
15 |
+
|
16 |
+
$this->sh = $sh;
|
17 |
+
|
18 |
+
add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
19 |
+
add_action( 'simple_history/admin_footer', array( $this, 'add_js_template' ) );
|
20 |
+
|
21 |
+
add_filter(
|
22 |
+
'simple_history/row_header_output/display_ip_address',
|
23 |
+
array( $this, 'row_header_display_ip_address_filter' ),
|
24 |
+
10,
|
25 |
+
2
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Display IP Addressses for login related messages.
|
31 |
+
*
|
32 |
+
* @param bool $bool
|
33 |
+
* @param object $row
|
34 |
+
* @return bool
|
35 |
+
*/
|
36 |
+
public function row_header_display_ip_address_filter( $bool, $row ) {
|
37 |
+
// Bail if log row in not from our logger.
|
38 |
+
if ( 'SimpleUserLogger' !== $row->logger ) {
|
39 |
+
return $bool;
|
40 |
+
}
|
41 |
+
|
42 |
+
// Message keys to show IP Addresses for.
|
43 |
+
$arr_keys_to_log = array(
|
44 |
+
'user_logged_in',
|
45 |
+
'user_login_failed',
|
46 |
+
'user_unknown_login_failed',
|
47 |
+
'user_unknown_logged_in',
|
48 |
+
);
|
49 |
+
|
50 |
+
// Bail if not correct message key.
|
51 |
+
if ( ! in_array( $row->context_message_key, $arr_keys_to_log ) ) {
|
52 |
+
return $bool;
|
53 |
+
}
|
54 |
+
|
55 |
+
return true;
|
56 |
+
}
|
57 |
+
|
58 |
+
public function enqueue_admin_scripts() {
|
59 |
+
|
60 |
+
$file_url = plugin_dir_url( __FILE__ );
|
61 |
+
|
62 |
+
wp_enqueue_script( 'simple_history_IpInfoDropin', $file_url . 'SimpleHistoryIpInfoDropin.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true );
|
63 |
+
|
64 |
+
wp_enqueue_style( 'simple_history_IpInfoDropin', $file_url . 'SimpleHistoryIpInfoDropin.css', null, SIMPLE_HISTORY_VERSION );
|
65 |
+
}
|
66 |
+
|
67 |
+
public function add_js_template() {
|
68 |
+
?>
|
69 |
+
|
70 |
+
<div class="SimpleHistoryIpInfoDropin__popup">
|
71 |
+
<div class="SimpleHistoryIpInfoDropin__popupArrow"></div>
|
72 |
+
<div class="SimpleHistoryIpInfoDropin__popupClose"><button class="SimpleHistoryIpInfoDropin__popupCloseButton">×</button></div>
|
73 |
+
<div class="SimpleHistoryIpInfoDropin__popupContent"></div>
|
74 |
+
</div>
|
75 |
+
|
76 |
+
<script type="text/html" id="tmpl-simple-history-ipinfodropin-popup-loading">
|
77 |
+
<p><?php echo esc_html_x( 'Getting IP info ...', 'IP Info Dropin', 'simple-history' ); ?></p>
|
78 |
+
</script>
|
79 |
+
|
80 |
+
<script type="text/html" id="tmpl-simple-history-ipinfodropin-popup-error">
|
81 |
+
<p><?php echo esc_html_x( 'Could not get info about IP address.', 'IP Info Dropin', 'simple-history' ); ?></p>
|
82 |
+
</script>
|
83 |
+
|
84 |
+
<script type="text/html" id="tmpl-simple-history-ipinfodropin-popup-loaded">
|
85 |
+
<!--
|
86 |
+
{
|
87 |
+
"ip": "8.8.8.8",
|
88 |
+
"hostname": "google-public-dns-a.google.com",
|
89 |
+
"city": "Mountain View",
|
90 |
+
"region": "California",
|
91 |
+
"country": "US",
|
92 |
+
"loc": "37.3860,-122.0838",
|
93 |
+
"org": "AS15169 Google Inc.",
|
94 |
+
"postal": "94035"
|
95 |
+
}
|
96 |
+
-->
|
97 |
+
<# if ( typeof(data.bogon) != "undefined" ) { #>
|
98 |
+
|
99 |
+
<p><?php echo esc_html_x( 'That IP address does not seem like a public one.', 'IP Info Dropin', 'simple-history' ); ?></p>
|
100 |
+
|
101 |
+
<# } else { #>
|
102 |
+
|
103 |
+
<table class="SimpleHistoryIpInfoDropin__ipInfoTable">
|
104 |
+
|
105 |
+
<tr class="SimpleHistoryIpInfoDropin__ipInfoTable__mapRow">
|
106 |
+
<td colspan="2">
|
107 |
+
<!--
|
108 |
+
<# if ( typeof(data.loc) != "undefined" && data.loc ) { #>
|
109 |
+
<a href="https://www.google.com/maps/place/{{ data.loc }}/@{{ data.loc }},6z" target="_blank">
|
110 |
+
<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">
|
111 |
+
</a>
|
112 |
+
<# } #>
|
113 |
+
-->
|
114 |
+
</td>
|
115 |
+
</tr>
|
116 |
+
|
117 |
+
<# if ( typeof(data.ip) != "undefined" && data.ip ) { #>
|
118 |
+
<tr>
|
119 |
+
<td>
|
120 |
+
<?php echo esc_html_x( 'IP address', 'IP Info Dropin', 'simple-history' ); ?>
|
121 |
+
</td>
|
122 |
+
<td>
|
123 |
+
{{ data.ip }}
|
124 |
+
</td>
|
125 |
+
</tr>
|
126 |
+
<# } #>
|
127 |
+
|
128 |
+
<# if ( typeof(data.hostname) != "undefined" && data.hostname ) { #>
|
129 |
+
<tr>
|
130 |
+
<td>
|
131 |
+
<?php echo esc_html_x( 'Hostname', 'IP Info Dropin', 'simple-history' ); ?>
|
132 |
+
</td>
|
133 |
+
<td>
|
134 |
+
{{ data.hostname }}
|
135 |
+
</td>
|
136 |
+
</tr>
|
137 |
+
<# } #>
|
138 |
+
|
139 |
+
<# if ( typeof(data.org) != "undefined" && data.org ) { #>
|
140 |
+
<tr>
|
141 |
+
<td>
|
142 |
+
<?php echo esc_html_x( 'Network', 'IP Info Dropin', 'simple-history' ); ?>
|
143 |
+
</td>
|
144 |
+
<td>
|
145 |
+
{{ data.org }}
|
146 |
+
</td>
|
147 |
+
</tr>
|
148 |
+
<# } #>
|
149 |
+
|
150 |
+
<# if ( typeof(data.network) != "undefined" && data.network ) { #>
|
151 |
+
<tr>
|
152 |
+
<td>
|
153 |
+
<?php echo esc_html_x( 'Network', 'IP Info Dropin', 'simple-history' ); ?>
|
154 |
+
</td>
|
155 |
+
<td>
|
156 |
+
{{ data.network }}
|
157 |
+
</td>
|
158 |
+
</tr>
|
159 |
+
<# } #>
|
160 |
+
|
161 |
+
<# if ( typeof(data.city) != "undefined" && data.city ) { #>
|
162 |
+
<tr>
|
163 |
+
<td>
|
164 |
+
<?php echo esc_html_x( 'City', 'IP Info Dropin', 'simple-history' ); ?>
|
165 |
+
</td>
|
166 |
+
<td>
|
167 |
+
{{ data.city }}
|
168 |
+
</td>
|
169 |
+
</tr>
|
170 |
+
<# } #>
|
171 |
+
|
172 |
+
<# if ( typeof(data.region) != "undefined" && data.region ) { #>
|
173 |
+
<tr>
|
174 |
+
<td>
|
175 |
+
<?php echo esc_html_x( 'Region', 'IP Info Dropin', 'simple-history' ); ?>
|
176 |
+
</td>
|
177 |
+
<td>
|
178 |
+
{{ data.region }}
|
179 |
+
</td>
|
180 |
+
</tr>
|
181 |
+
<# } #>
|
182 |
+
|
183 |
+
<# if ( typeof(data.country) != "undefined" && data.country ) { #>
|
184 |
+
<tr>
|
185 |
+
<td>
|
186 |
+
<?php echo esc_html_x( 'Country', 'IP Info Dropin', 'simple-history' ); ?>
|
187 |
+
</td>
|
188 |
+
<td>
|
189 |
+
{{ data.country }}
|
190 |
+
</td>
|
191 |
+
</tr>
|
192 |
+
<# } #>
|
193 |
+
|
194 |
+
</table>
|
195 |
+
|
196 |
+
<p class="SimpleHistoryIpInfoDropin__provider">
|
197 |
+
<?php printf( esc_html_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>' ); ?>
|
198 |
+
</p>
|
199 |
+
|
200 |
+
<# } #>
|
201 |
+
|
202 |
+
</script>
|
203 |
+
<?php
|
204 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
}
|
dropins/SimpleHistoryNewRowsNotifier.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Dropin Name: New Items Notifier
|
@@ -9,90 +9,93 @@ defined('ABSPATH') or die();
|
|
9 |
* Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
-
class SimpleHistoryNewRowsNotifier
|
13 |
-
{
|
14 |
|
15 |
-
// Simple History instance
|
16 |
-
private $sh;
|
17 |
|
18 |
-
|
19 |
-
|
20 |
|
21 |
-
|
22 |
-
|
23 |
|
24 |
-
|
25 |
|
26 |
-
|
27 |
-
$this->interval = (int) apply_filters('SimpleHistoryNewRowsNotifier/interval', $this->interval);
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
}
|
32 |
|
33 |
-
|
34 |
-
|
|
|
35 |
|
36 |
-
|
37 |
|
38 |
-
|
39 |
|
40 |
-
|
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 |
-
|
|
|
|
|
|
|
46 |
|
47 |
-
|
48 |
-
}
|
49 |
|
50 |
-
|
51 |
-
|
52 |
|
53 |
-
|
54 |
|
55 |
-
|
56 |
-
wp_send_json_error(array(
|
57 |
-
'error' => 'MISSING_APIARGS',
|
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 |
-
$json_data['num_mysql_queries'] = get_num_queries();
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
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 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
public function __construct( $sh ) {
|
22 |
|
23 |
+
$this->sh = $sh;
|
|
|
24 |
|
25 |
+
// How often the script checks for new rows
|
26 |
+
$this->interval = (int) apply_filters( 'SimpleHistoryNewRowsNotifier/interval', $this->interval );
|
|
|
27 |
|
28 |
+
add_action( 'wp_ajax_SimpleHistoryNewRowsNotifier', array( $this, 'ajax' ) );
|
29 |
+
add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
30 |
+
}
|
31 |
|
32 |
+
public function enqueue_admin_scripts() {
|
33 |
|
34 |
+
$file_url = plugin_dir_url( __FILE__ );
|
35 |
|
36 |
+
wp_enqueue_script( 'simple_history_NewRowsNotifierDropin', $file_url . 'SimpleHistoryNewRowsNotifierDropin.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true );
|
|
|
|
|
|
|
37 |
|
38 |
+
$arr_localize_data = array(
|
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 |
+
wp_localize_script( 'simple_history_NewRowsNotifierDropin', 'simple_history_NewRowsNotifierDropin', $arr_localize_data );
|
|
|
44 |
|
45 |
+
wp_enqueue_style( 'simple_history_NewRowsNotifierDropin', $file_url . 'SimpleHistoryNewRowsNotifierDropin.css', null, SIMPLE_HISTORY_VERSION );
|
46 |
+
}
|
47 |
|
48 |
+
public function ajax() {
|
49 |
|
50 |
+
$apiArgs = isset( $_GET['apiArgs'] ) ? $_GET['apiArgs'] : array();
|
|
|
|
|
|
|
|
|
51 |
|
52 |
+
if ( ! $apiArgs ) {
|
53 |
+
wp_send_json_error(
|
54 |
+
array(
|
55 |
+
'error' => 'MISSING_APIARGS',
|
56 |
+
)
|
57 |
+
);
|
58 |
+
}
|
59 |
|
60 |
+
if ( empty( $apiArgs['since_id'] ) || ! is_numeric( $apiArgs['since_id'] ) ) {
|
61 |
+
wp_send_json_error(
|
62 |
+
array(
|
63 |
+
'error' => 'MISSING_SINCE_ID',
|
64 |
+
)
|
65 |
+
);
|
66 |
+
}
|
67 |
|
68 |
+
// User must have capability to view the history page
|
69 |
+
if ( ! current_user_can( $this->sh->get_view_history_capability() ) ) {
|
70 |
+
wp_send_json_error(
|
71 |
+
array(
|
72 |
+
'error' => 'CAPABILITY_ERROR',
|
73 |
+
)
|
74 |
+
);
|
75 |
+
}
|
76 |
|
77 |
+
// $since_id = isset( $_GET["since_id"] ) ? absint($_GET["since_id"]) : null;
|
78 |
+
$logQueryArgs = $apiArgs;
|
79 |
|
80 |
+
$logQuery = new SimpleHistoryLogQuery();
|
81 |
+
$answer = $logQuery->query( $logQueryArgs );
|
82 |
|
83 |
+
// Use our own response array instead of $answer to keep size down
|
84 |
+
$json_data = array();
|
|
|
85 |
|
86 |
+
$numNewRows = isset( $answer['total_row_count'] ) ? $answer['total_row_count'] : 0;
|
87 |
+
$json_data['num_new_rows'] = $numNewRows;
|
88 |
+
$json_data['num_mysql_queries'] = get_num_queries();
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
+
if ( $numNewRows ) {
|
91 |
+
// We have new rows
|
92 |
+
// Append strings
|
93 |
+
$textRowsFound = sprintf( _n( '%s new event', '%s new events', $numNewRows, 'simple-history' ), $numNewRows );
|
94 |
+
$json_data['strings'] = array(
|
95 |
+
'newRowsFound' => $textRowsFound,
|
96 |
+
);
|
97 |
+
}
|
98 |
+
|
99 |
+
wp_send_json_success( $json_data );
|
100 |
+
}
|
101 |
}
|
dropins/SimpleHistoryPluginPatchesDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Plugin Patches
|
@@ -8,164 +8,156 @@ Dropin Description: Used to patch plugins that behave wierd
|
|
8 |
Dropin URI: http://simple-history.com/
|
9 |
Author: Pär Thernström
|
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 |
-
$userLogger->warningMessage('user_login_failed', $context);
|
165 |
-
|
166 |
-
// Cancel original log event
|
167 |
-
$doLog = false;
|
168 |
-
|
169 |
-
return $doLog;
|
170 |
-
}
|
171 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Plugin Patches
|
8 |
Dropin URI: http://simple-history.com/
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
+
class SimpleHistoryPluginPatchesDropin {
|
12 |
+
private $sh;
|
13 |
+
|
14 |
+
public function __construct( $sh ) {
|
15 |
+
$this->sh = $sh;
|
16 |
+
|
17 |
+
$this->patch_captcha_on_login();
|
18 |
+
|
19 |
+
add_filter(
|
20 |
+
'simple_history/post_logger/skip_posttypes',
|
21 |
+
array( $this, 'woocommerce_skip_scheduled_actions_posttype' )
|
22 |
+
);
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Skip logging of WooCommerce scheduled actions/cron related things,
|
27 |
+
* stored in the scheduled-action"post type. If not disabled the log can be filled with
|
28 |
+
* a large amount of actions for this postype.
|
29 |
+
*
|
30 |
+
* @since 2.3
|
31 |
+
*/
|
32 |
+
public function woocommerce_skip_scheduled_actions_posttype( $skip_posttypes ) {
|
33 |
+
$skip_posttypes[] = 'scheduled-action';
|
34 |
+
return $skip_posttypes;
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Captcha on Login
|
39 |
+
*
|
40 |
+
* Calls wp_logut() wrongly when
|
41 |
+
* - a user IP is blocked
|
42 |
+
* - when max num of tries is reached
|
43 |
+
* - or when the capcha is not correct
|
44 |
+
*
|
45 |
+
* So the event logged will be logged_out but should be user_login_failed or user_unknown_login_failed.
|
46 |
+
* Wrong events logged reported here:
|
47 |
+
* https://wordpress.org/support/topic/many-unknown-logged-out-entries
|
48 |
+
*
|
49 |
+
* Plugin also gives lots of errors, reported by me here:
|
50 |
+
* https://wordpress.org/support/topic/errors-has_cap-deprecated-strict-standards-warning
|
51 |
+
*/
|
52 |
+
public function patch_captcha_on_login() {
|
53 |
+
|
54 |
+
add_action( 'simple_history/log/do_log', array( $this, 'patch_captcha_on_login_on_log' ), 10, 5 );
|
55 |
+
}
|
56 |
+
|
57 |
+
// Detect that this log message is being called from Captha on login
|
58 |
+
// and that the message is "user_logged_out"
|
59 |
+
public function patch_captcha_on_login_on_log( $doLog, $level = null, $message = null, $context = null, $loggerInstance = null ) {
|
60 |
+
|
61 |
+
if ( empty( $context ) || ! isset( $context['_message_key'] ) || 'user_logged_out' != $context['_message_key'] ) {
|
62 |
+
// Message key did not exist or was not "user_logged_out"
|
63 |
+
return $doLog;
|
64 |
+
}
|
65 |
+
|
66 |
+
// 22 nov 2015: disabled this check beacuse for example robots/scripts don't pass all args
|
67 |
+
// instead they only post "log" and "pwd"
|
68 |
+
// codiga is the input with the captcha
|
69 |
+
/*
|
70 |
+
if ( ! isset( $_POST["log"], $_POST["pwd"], $_POST["wp-submit"], $_POST["codigo"] ) ) {
|
71 |
+
// All needed post variables was not set
|
72 |
+
return $doLog;
|
73 |
+
}
|
74 |
+
*/
|
75 |
+
|
76 |
+
// The Captcha on login uses a class called 'Anderson_Makiyama_Captcha_On_Login'
|
77 |
+
// and also a global variable called $global $anderson_makiyama
|
78 |
+
global $anderson_makiyama;
|
79 |
+
if ( ! class_exists( 'Anderson_Makiyama_Captcha_On_Login' ) || ! isset( $anderson_makiyama ) ) {
|
80 |
+
return $doLog;
|
81 |
+
}
|
82 |
+
|
83 |
+
// We must come from wp-login
|
84 |
+
// Disabled 22 nov 2015 because robots/scripts dont send referer
|
85 |
+
/*
|
86 |
+
$wp_referer = wp_get_referer();
|
87 |
+
if ( ! $wp_referer || ! "wp-login.php" == basename( $wp_referer ) ) {
|
88 |
+
return $doLog;
|
89 |
+
}
|
90 |
+
*/
|
91 |
+
|
92 |
+
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
|
93 |
+
return $doLog;
|
94 |
+
}
|
95 |
+
|
96 |
+
// File must be wp-login.php (can it even be another?)
|
97 |
+
$request_uri = basename( wp_unslash( $_SERVER['REQUEST_URI'] ) );
|
98 |
+
if ( 'wp-login.php' !== $request_uri ) {
|
99 |
+
return $doLog;
|
100 |
+
}
|
101 |
+
|
102 |
+
$anderson_makiyama_indice = Anderson_Makiyama_Captcha_On_Login::PLUGIN_ID;
|
103 |
+
$capcha_on_login_class_name = $anderson_makiyama[ $anderson_makiyama_indice ]::CLASS_NAME;
|
104 |
+
|
105 |
+
$capcha_on_login_options = (array) get_option( $capcha_on_login_class_name . '_options', array() );
|
106 |
+
$last_100_logins = isset( $capcha_on_login_options['last_100_logins'] ) ? (array) $capcha_on_login_options['last_100_logins'] : array();
|
107 |
+
$last_100_logins = array_reverse( $last_100_logins );
|
108 |
+
|
109 |
+
// Possible messages
|
110 |
+
// - Failed: IP already blocked
|
111 |
+
// - Failed: exceeded max number of tries
|
112 |
+
// - Failed: image code did not match
|
113 |
+
// - Failed: Login or Password did not match
|
114 |
+
// - Success
|
115 |
+
$last_login_status = isset( $last_100_logins[0][2] ) ? $last_100_logins[0][2] : '';
|
116 |
+
|
117 |
+
// If we get here we're pretty sure we come from Captcha on login
|
118 |
+
// and that we should cancel the wp_logout message and log an failed login instead
|
119 |
+
// Get the user logger
|
120 |
+
$userLogger = $this->sh->getInstantiatedLoggerBySlug( 'SimpleUserLogger' );
|
121 |
+
|
122 |
+
if ( ! $userLogger ) {
|
123 |
+
return $doLog;
|
124 |
+
}
|
125 |
+
|
126 |
+
// $userLogger->warningMessage("user_unknown_login_failed", $context);
|
127 |
+
// Same context as in SimpleUserLogger
|
128 |
+
$context = array(
|
129 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
130 |
+
'server_http_user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null,
|
131 |
+
'_occasionsID' => 'SimpleUserLogger/failed_user_login',
|
132 |
+
'patch_using_patch' => true,
|
133 |
+
'patch_name' => 'captcha_on_login',
|
134 |
+
);
|
135 |
+
|
136 |
+
// Append capcha message
|
137 |
+
if ( $last_login_status ) {
|
138 |
+
$context['patch_last_login_status'] = $last_login_status;
|
139 |
+
}
|
140 |
+
|
141 |
+
// Get user id and email and login
|
142 |
+
// Not passed to filter, but we have it in $_POST
|
143 |
+
$login_username = isset( $_POST['log'] ) ? sanitize_user( $_POST['log'] ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
144 |
+
|
145 |
+
if ( $login_username ) {
|
146 |
+
$context['login_user_login'] = $login_username;
|
147 |
+
|
148 |
+
$user = get_user_by( 'login', $login_username );
|
149 |
+
|
150 |
+
if ( is_a( $user, 'WP_User' ) ) {
|
151 |
+
$context['login_user_id'] = $user->ID;
|
152 |
+
$context['login_user_email'] = $user->user_email;
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
$userLogger->warningMessage( 'user_login_failed', $context );
|
157 |
+
|
158 |
+
// Cancel original log event
|
159 |
+
$doLog = false;
|
160 |
+
|
161 |
+
return $doLog;
|
162 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
}
|
dropins/SimpleHistoryRSSDropin.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
|
|
4 |
/*
|
5 |
Dropin Name: Global RSS Feed
|
6 |
Dropin URI: http://simple-history.com/
|
@@ -10,400 +11,428 @@ 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 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
+
|
5 |
/*
|
6 |
Dropin Name: Global RSS Feed
|
7 |
Dropin URI: http://simple-history.com/
|
11 |
/**
|
12 |
* Simple History RSS Feed drop-in
|
13 |
*/
|
14 |
+
class SimpleHistoryRSSDropin {
|
15 |
+
|
16 |
+
public function __construct( $sh ) {
|
17 |
+
|
18 |
+
$this->sh = $sh;
|
19 |
+
|
20 |
+
if ( ! function_exists( 'get_editable_roles' ) ) {
|
21 |
+
require_once( ABSPATH . '/wp-admin/includes/user.php' );
|
22 |
+
}
|
23 |
+
|
24 |
+
// Check the status of the RSS feed
|
25 |
+
$this->isRssEnabled();
|
26 |
+
|
27 |
+
// Generate a rss secret, if it does not exist
|
28 |
+
if ( ! get_option( 'simple_history_rss_secret' ) ) {
|
29 |
+
$this->updateRssSecret();
|
30 |
+
}
|
31 |
+
|
32 |
+
add_action( 'init', array( $this, 'checkForRssFeedRequest' ) );
|
33 |
+
|
34 |
+
// Add settings with prio 11 so it' added after the main Simple History settings
|
35 |
+
add_action( 'admin_menu', array( $this, 'addSettings' ), 11 );
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Add settings for the RSS feed
|
40 |
+
* + also regenerates the secret if requested
|
41 |
+
*/
|
42 |
+
public function addSettings() {
|
43 |
+
|
44 |
+
// we register a setting to keep track of the RSS feed status (enabled/disabled)
|
45 |
+
register_setting(
|
46 |
+
SimpleHistory::SETTINGS_GENERAL_OPTION_GROUP,
|
47 |
+
'simple_history_enable_rss_feed',
|
48 |
+
array(
|
49 |
+
$this,
|
50 |
+
'public updateRssStatus',
|
51 |
+
)
|
52 |
+
);
|
53 |
+
/**
|
54 |
+
* Start new section for RSS feed
|
55 |
+
*/
|
56 |
+
$settings_section_rss_id = 'simple_history_settings_section_rss';
|
57 |
+
|
58 |
+
add_settings_section(
|
59 |
+
$settings_section_rss_id,
|
60 |
+
_x( 'RSS feed', 'rss settings headline', 'simple-history' ), // No title __("General", "simple-history"),
|
61 |
+
array( $this, 'settingsSectionOutput' ),
|
62 |
+
SimpleHistory::SETTINGS_MENU_SLUG // same slug as for options menu page
|
63 |
+
);
|
64 |
+
|
65 |
+
// Enable/Disabled RSS feed
|
66 |
+
add_settings_field(
|
67 |
+
'simple_history_enable_rss_feed',
|
68 |
+
__( 'Enable', 'simple-history' ),
|
69 |
+
array( $this, 'settingsFieldRssEnable' ),
|
70 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
71 |
+
$settings_section_rss_id
|
72 |
+
);
|
73 |
+
|
74 |
+
// if RSS is activated we display other fields
|
75 |
+
if ( $this->isRssEnabled() ) {
|
76 |
+
// RSS address
|
77 |
+
add_settings_field(
|
78 |
+
'simple_history_rss_feed',
|
79 |
+
__( 'Address', 'simple-history' ),
|
80 |
+
array( $this, 'settingsFieldRss' ),
|
81 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
82 |
+
$settings_section_rss_id
|
83 |
+
);
|
84 |
+
|
85 |
+
// Regnerate address
|
86 |
+
add_settings_field(
|
87 |
+
'simple_history_rss_feed_regenerate_secret',
|
88 |
+
__( 'Regenerate', 'simple-history' ),
|
89 |
+
array( $this, 'settingsFieldRssRegenerate' ),
|
90 |
+
SimpleHistory::SETTINGS_MENU_SLUG,
|
91 |
+
$settings_section_rss_id
|
92 |
+
);
|
93 |
+
}
|
94 |
+
|
95 |
+
// Create new RSS secret
|
96 |
+
$create_new_secret = false;
|
97 |
+
$create_secret_nonce_name = 'simple_history_rss_secret_regenerate_nonce';
|
98 |
+
$createNonceOk = isset( $_GET[ $create_secret_nonce_name ] ) && wp_verify_nonce( $_GET[ $create_secret_nonce_name ], 'simple_history_rss_update_secret' );
|
99 |
+
|
100 |
+
if ( $createNonceOk ) {
|
101 |
+
$create_new_secret = true;
|
102 |
+
$this->updateRssSecret();
|
103 |
+
|
104 |
+
// Add updated-message and store in transient and then redirect
|
105 |
+
// This is the way options.php does it.
|
106 |
+
$msg = __( 'Created new secret RSS address', 'simple-history' );
|
107 |
+
add_settings_error( 'simple_history_rss_feed_regenerate_secret', 'simple_history_rss_feed_regenerate_secret', $msg, 'updated' );
|
108 |
+
set_transient( 'settings_errors', get_settings_errors(), 30 );
|
109 |
+
|
110 |
+
$goback = esc_url_raw( add_query_arg( 'settings-updated', 'true', wp_get_referer() ) );
|
111 |
+
wp_redirect( $goback );
|
112 |
+
exit;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Check if RSS feed is enabled or disabled
|
118 |
+
*/
|
119 |
+
public function isRssEnabled() {
|
120 |
+
|
121 |
+
// User has never used the plugin we disable RSS feed
|
122 |
+
if ( get_option( 'simple_history_rss_secret' ) === false && get_option( 'simple_history_enable_rss_feed' ) === false ) {
|
123 |
+
// We disable RSS by default, we use 0/1 to prevent fake disabled with bools from functions returning false for unset
|
124 |
+
update_option( 'simple_history_enable_rss_feed', '0' );
|
125 |
+
} elseif ( get_option( 'simple_history_enable_rss_feed' ) === false ) {
|
126 |
+
// User was using the plugin before RSS feed became disabled by default
|
127 |
+
// We activate RSS to prevent a "breaking change"
|
128 |
+
update_option( 'simple_history_enable_rss_feed', '1' );
|
129 |
+
return true;
|
130 |
+
} elseif ( get_option( 'simple_history_enable_rss_feed' ) === '1' ) {
|
131 |
+
return true;
|
132 |
+
}
|
133 |
+
|
134 |
+
return false;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Output for settings field that show current RSS address
|
139 |
+
*/
|
140 |
+
public function settingsFieldRssEnable() {
|
141 |
+
?>
|
142 |
+
<input value="1" type="checkbox" id="simple_history_enable_rss_feed" name="simple_history_enable_rss_feed" <?php checked( $this->isRssEnabled(), 1 ); ?> />
|
143 |
+
<label for="simple_history_enable_rss_feed"><?php esc_html_e( 'Enable RSS feed', 'simple-history' ); ?></label>
|
144 |
+
<?php
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Sanitize RSS enabled/disabled status on update settings
|
149 |
+
*/
|
150 |
+
public function updateRssStatus( $field ) {
|
151 |
+
|
152 |
+
if ( $field === '1' ) {
|
153 |
+
return '1';
|
154 |
+
}
|
155 |
+
|
156 |
+
return '0';
|
157 |
+
}
|
158 |
+
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Check if current request is a request for the RSS feed
|
162 |
+
*/
|
163 |
+
public function checkForRssFeedRequest() {
|
164 |
+
// check for RSS
|
165 |
+
// don't know if this is the right way to do this, but it seems to work!
|
166 |
+
if ( isset( $_GET['simple_history_get_rss'] ) ) {
|
167 |
+
$this->outputRss();
|
168 |
+
exit;
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Modify capability check so all users reading rss feed (logged in or not) can read all loggers
|
174 |
+
*/
|
175 |
+
public function onCanReadSingleLogger( $user_can_read_logger, $logger_instance, $user_id ) {
|
176 |
+
$user_can_read_logger = true;
|
177 |
+
|
178 |
+
return $user_can_read_logger;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Output RSS
|
183 |
+
*/
|
184 |
+
public function outputRss() {
|
185 |
+
|
186 |
+
$rss_secret_option = get_option( 'simple_history_rss_secret' );
|
187 |
+
$rss_secret_get = isset( $_GET['rss_secret'] ) ? $_GET['rss_secret'] : '';
|
188 |
+
|
189 |
+
if ( empty( $rss_secret_option ) || empty( $rss_secret_get ) ) {
|
190 |
+
die();
|
191 |
+
}
|
192 |
+
|
193 |
+
$rss_show = true;
|
194 |
+
$rss_show = apply_filters( 'simple_history/rss_feed_show', $rss_show );
|
195 |
+
if ( ! $rss_show || ! $this->isRssEnabled() ) {
|
196 |
+
wp_die( 'Nothing here.' );
|
197 |
+
}
|
198 |
+
|
199 |
+
header( 'Content-Type: text/xml; charset=utf-8' );
|
200 |
+
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
201 |
+
$self_link = $this->getRssAddress();
|
202 |
+
|
203 |
+
if ( $rss_secret_option === $rss_secret_get ) {
|
204 |
+
?>
|
205 |
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
206 |
+
<channel>
|
207 |
+
<title><![CDATA[<?php printf( esc_html__( 'History for %s', 'simple-history' ), esc_html( get_bloginfo( 'name' ) ) ); ?>]]></title>
|
208 |
+
<description><![CDATA[<?php printf( esc_html__( 'WordPress History for %s', 'simple-history' ), esc_html( get_bloginfo( 'name' ) ) ); ?>]]></description>
|
209 |
+
<link><?php echo esc_url( get_bloginfo( 'url' ) ); ?></link>
|
210 |
+
<atom:link href="<?php echo esc_url( $self_link ); ?>" rel="self" type="application/atom+xml" />
|
211 |
+
<?php
|
212 |
+
|
213 |
+
// Override capability check: if you have a valid rss_secret_key you can read it all
|
214 |
+
$action_tag = 'simple_history/loggers_user_can_read/can_read_single_logger';
|
215 |
+
add_action( $action_tag, array( $this, 'onCanReadSingleLogger' ), 10, 3 );
|
216 |
+
|
217 |
+
// Modify header time output so it does not show relative date or time ago-format
|
218 |
+
// Because we don't know when a user reads the RSS feed, time ago format may be very inaccurate
|
219 |
+
add_action( 'simple_history/header_just_now_max_time', '__return_zero' );
|
220 |
+
add_action( 'simple_history/header_time_ago_max_time', '__return_zero' );
|
221 |
+
|
222 |
+
// Get log rows
|
223 |
+
$args = array(
|
224 |
+
'posts_per_page' => 10,
|
225 |
+
);
|
226 |
+
|
227 |
+
$args = apply_filters( 'simple_history/rss_feed_args', $args );
|
228 |
+
|
229 |
+
$logQuery = new SimpleHistoryLogQuery();
|
230 |
+
$queryResults = $logQuery->query( $args );
|
231 |
+
|
232 |
+
// Remove capability override after query is done
|
233 |
+
// remove_action( $action_tag, array($this, "onCanReadSingleLogger") );
|
234 |
+
foreach ( $queryResults['log_rows'] as $row ) {
|
235 |
+
$header_output = $this->sh->getLogRowHeaderOutput( $row );
|
236 |
+
$text_output = $this->sh->getLogRowPlainTextOutput( $row );
|
237 |
+
$details_output = $this->sh->getLogRowDetailsOutput( $row );
|
238 |
+
|
239 |
+
// http://cyber.law.harvard.edu/rss/rss.html#ltguidgtSubelementOfLtitemgt
|
240 |
+
// $item_guid = home_url() . "?SimpleHistoryGuid=" . $row->id;
|
241 |
+
$item_guid = esc_url( add_query_arg( 'SimpleHistoryGuid', $row->id, home_url() ) );
|
242 |
+
$item_link = esc_url( add_query_arg( 'SimpleHistoryGuid', $row->id, home_url() ) );
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Filter the guid/link URL used in RSS feed.
|
246 |
+
* Link will be esc_url'ed by simple history, so no need to do that in your filter
|
247 |
+
*
|
248 |
+
* @since 2.0.23
|
249 |
+
*
|
250 |
+
* @param string $item_guid link.
|
251 |
+
* @param object $row
|
252 |
+
*/
|
253 |
+
$item_link = apply_filters( 'simple_history/rss_item_link', $item_link, $row );
|
254 |
+
$item_link = esc_url( $item_link );
|
255 |
+
|
256 |
+
$item_title = sprintf(
|
257 |
+
'%2$s',
|
258 |
+
$this->sh->getLogLevelTranslated( $row->level ),
|
259 |
+
wp_kses( $text_output, array() )
|
260 |
+
);
|
261 |
+
|
262 |
+
$level_output = sprintf( esc_html__( 'Severity level: %1$s', 'simple-history' ), $this->sh->getLogLevelTranslated( $row->level ) );
|
263 |
+
|
264 |
+
$wp_kses_attrs = array(
|
265 |
+
'a' => array(
|
266 |
+
'href' => array(),
|
267 |
+
'class' => array(),
|
268 |
+
'data-ip-address' => array(),
|
269 |
+
'target' => array(),
|
270 |
+
'title' => array(),
|
271 |
+
),
|
272 |
+
'em' => array(),
|
273 |
+
'span' => array(
|
274 |
+
'class' => array(),
|
275 |
+
'title' => array(),
|
276 |
+
'aria-hidden' => array(),
|
277 |
+
),
|
278 |
+
'time' => array(
|
279 |
+
'datetime' => array(),
|
280 |
+
'class' => array(),
|
281 |
+
),
|
282 |
+
'strong' => array(
|
283 |
+
'class' => array(),
|
284 |
+
),
|
285 |
+
'div' => array(
|
286 |
+
'class' => array(),
|
287 |
+
'tabindex' => array(),
|
288 |
+
),
|
289 |
+
'p' => array(),
|
290 |
+
'del' => array(),
|
291 |
+
'ins' => array(),
|
292 |
+
'table' => array(
|
293 |
+
'class' => array(),
|
294 |
+
),
|
295 |
+
'tbody' => array(),
|
296 |
+
'tr' => array(),
|
297 |
+
'td' => array(
|
298 |
+
'class' => array(),
|
299 |
+
),
|
300 |
+
'col' => array(
|
301 |
+
'class' => array(),
|
302 |
+
),
|
303 |
+
);
|
304 |
+
?>
|
305 |
+
<item>
|
306 |
+
<title><![CDATA[<?php echo esc_html( $item_title ); ?>]]></title>
|
307 |
+
<description><![CDATA[
|
308 |
+
<p><?php echo wp_kses( $header_output, $wp_kses_attrs ); ?></p>
|
309 |
+
<p><?php echo wp_kses( $text_output, $wp_kses_attrs ); ?></p>
|
310 |
+
<div><?php echo wp_kses( $details_output, $wp_kses_attrs ); ?></div>
|
311 |
+
<p><?php echo wp_kses( $level_output, $wp_kses_attrs ); ?></p>
|
312 |
+
<?php
|
313 |
+
$occasions = $row->subsequentOccasions - 1;
|
314 |
+
if ( $occasions ) {
|
315 |
+
echo '<p>';
|
316 |
+
printf(
|
317 |
+
esc_html( _n( '+%1$s occasion', '+%1$s occasions', $occasions, 'simple-history' ) ),
|
318 |
+
(int) $occasions
|
319 |
+
);
|
320 |
+
echo '</p>';
|
321 |
+
}
|
322 |
+
?>
|
323 |
+
]]></description>
|
324 |
+
<?php
|
325 |
+
// author must be email to validate, but the field is optional, so we skip it
|
326 |
+
/* <author><?php echo $row->initiator ?></author> */
|
327 |
+
?>
|
328 |
+
<pubDate><?php echo esc_html( gmdate( 'D, d M Y H:i:s', strtotime( $row->date ) ) ); ?> GMT</pubDate>
|
329 |
+
<guid isPermaLink="false"><![CDATA[<?php echo esc_html( $item_guid ); ?>]]></guid>
|
330 |
+
<link><![CDATA[<?php echo esc_url( $item_link ); ?>]]></link>
|
331 |
+
</item>
|
332 |
+
<?php
|
333 |
+
} // End foreach().
|
334 |
+
|
335 |
+
?>
|
336 |
+
</channel>
|
337 |
+
</rss>
|
338 |
+
<?php
|
339 |
+
} else {
|
340 |
+
// RSS secret was not ok
|
341 |
+
?>
|
342 |
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
343 |
+
<channel>
|
344 |
+
<title><?php printf( esc_html__( 'History for %s', 'simple-history' ), esc_html( get_bloginfo( 'name' ) ) ); ?></title>
|
345 |
+
<description><?php printf( esc_html__( 'WordPress History for %s', 'simple-history' ), esc_html( get_bloginfo( 'name' ) ) ); ?></description>
|
346 |
+
<link><?php echo esc_url( home_url() ); ?></link>
|
347 |
+
<item>
|
348 |
+
<title><?php esc_html_e( 'Wrong RSS secret', 'simple-history' ); ?></title>
|
349 |
+
<description><?php esc_html_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>
|
350 |
+
<pubDate><?php echo esc_html( gmdate( 'D, d M Y H:i:s', time() ) ); ?> GMT</pubDate>
|
351 |
+
<guid><?php echo esc_url( home_url() . '?SimpleHistoryGuid=wrong-secret' ); ?></guid>
|
352 |
+
</item>
|
353 |
+
</channel>
|
354 |
+
</rss>
|
355 |
+
<?php
|
356 |
+
}// End if().
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Create a new RSS secret
|
361 |
+
*
|
362 |
+
* @return string new secret
|
363 |
+
*/
|
364 |
+
public function updateRssSecret() {
|
365 |
+
|
366 |
+
$rss_secret = '';
|
367 |
+
|
368 |
+
for ( $i = 0; $i < 20; $i++ ) {
|
369 |
+
$rss_secret .= chr( rand( 97, 122 ) );
|
370 |
+
}
|
371 |
+
|
372 |
+
update_option( 'simple_history_rss_secret', $rss_secret );
|
373 |
+
|
374 |
+
return $rss_secret;
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Output for settings field that show current RSS address
|
379 |
+
*/
|
380 |
+
public function settingsFieldRss() {
|
381 |
+
printf(
|
382 |
+
'<p><code><a href="%1$s">%1$s</a></code></p>',
|
383 |
+
esc_url( $this->getRssAddress() )
|
384 |
+
);
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Output for settings field that regenerates the RSS adress/secret
|
389 |
+
*/
|
390 |
+
public function settingsFieldRssRegenerate() {
|
391 |
+
|
392 |
+
$update_link = esc_url( add_query_arg( '', '' ) );
|
393 |
+
$update_link = wp_nonce_url( $update_link, 'simple_history_rss_update_secret', 'simple_history_rss_secret_regenerate_nonce' );
|
394 |
+
|
395 |
+
echo '<p>';
|
396 |
+
esc_html_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' );
|
397 |
+
echo '</p>';
|
398 |
+
|
399 |
+
echo '<p>';
|
400 |
+
printf(
|
401 |
+
'<a class="button" href="%1$s">%2$s</a>',
|
402 |
+
esc_url( $update_link ), // 1
|
403 |
+
esc_html( 'Generate new address', 'simple-history' ) // 2
|
404 |
+
);
|
405 |
+
|
406 |
+
echo '</p>';
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Get the URL to the RSS feed
|
411 |
+
*
|
412 |
+
* @return string URL
|
413 |
+
*/
|
414 |
+
public function getRssAddress() {
|
415 |
+
|
416 |
+
$rss_secret = get_option( 'simple_history_rss_secret' );
|
417 |
+
$rss_address = add_query_arg(
|
418 |
+
array(
|
419 |
+
'simple_history_get_rss' => '1',
|
420 |
+
'rss_secret' => $rss_secret,
|
421 |
+
),
|
422 |
+
get_bloginfo( 'url' ) . '/'
|
423 |
+
);
|
424 |
+
$rss_address = esc_url( $rss_address );
|
425 |
+
|
426 |
+
return $rss_address;
|
427 |
+
}
|
428 |
+
|
429 |
+
/**
|
430 |
+
* Content for section intro. Leave it be, even if empty.
|
431 |
+
* Called from add_sections_setting.
|
432 |
+
*/
|
433 |
+
public function settingsSectionOutput() {
|
434 |
+
echo '<p>';
|
435 |
+
esc_html_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' );
|
436 |
+
echo '</p>';
|
437 |
+
}
|
438 |
}
|
dropins/SimpleHistorySettingsDebugDropin.php
CHANGED
@@ -7,42 +7,27 @@ Dropin URI: http://simple-history.com/
|
|
7 |
Author: Pär Thernström
|
8 |
*/
|
9 |
|
10 |
-
defined('ABSPATH')
|
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 |
-
$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 |
}
|
7 |
Author: Pär Thernström
|
8 |
*/
|
9 |
|
10 |
+
defined( 'ABSPATH' ) || die();
|
11 |
|
12 |
+
class SimpleHistorySettingsDebugDropin {
|
|
|
13 |
|
14 |
+
private $sh;
|
15 |
|
16 |
+
public function __construct( $sh ) {
|
|
|
17 |
|
18 |
+
$this->sh = $sh;
|
19 |
|
20 |
+
$this->sh->registerSettingsTab(
|
21 |
+
array(
|
22 |
+
'slug' => 'debug',
|
23 |
+
'name' => __( 'Debug', 'simple-history' ),
|
24 |
+
'function' => array( $this, 'output' ),
|
25 |
+
)
|
26 |
+
);
|
27 |
+
}
|
28 |
|
29 |
+
public function output() {
|
|
|
30 |
|
31 |
+
include SIMPLE_HISTORY_PATH . 'templates/template-settings-tab-debug.php';
|
32 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
dropins/SimpleHistorySettingsLogtestDropin.php
CHANGED
@@ -1,300 +1,256 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
|
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 |
-
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 |
-
*/
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
// Log testing beloe
|
298 |
-
// return;
|
299 |
-
// *
|
300 |
-
// */
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
+
class SimpleHistorySettingsLogtestDropin {
|
|
|
6 |
|
7 |
+
// Simple History instance
|
8 |
+
private $sh;
|
9 |
|
10 |
+
public function __construct( $sh ) {
|
|
|
11 |
|
12 |
+
// Since it's not quite done yet, it's for da devs only for now
|
13 |
+
if ( ! defined( 'SIMPLE_HISTORY_DEV' ) || ! SIMPLE_HISTORY_DEV ) {
|
14 |
+
return;
|
15 |
+
}
|
16 |
|
17 |
+
$this->sh = $sh;
|
18 |
|
19 |
+
// How do we register this to the settings array?
|
20 |
+
$sh->registerSettingsTab(
|
21 |
+
array(
|
22 |
+
'slug' => 'testLog',
|
23 |
+
'name' => __( 'Test data (debug)', 'simple-history' ),
|
24 |
+
'function' => array( $this, 'output' ),
|
25 |
+
)
|
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 |
+
$this->doLogTestThings();
|
36 |
|
37 |
+
$arr = array(
|
38 |
+
'message' => 'did it!',
|
39 |
+
);
|
40 |
|
41 |
+
wp_send_json_success( $arr );
|
42 |
+
}
|
43 |
|
44 |
+
public function on_admin_head() {
|
|
|
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 |
+
public function output() {
|
79 |
+
|
80 |
+
?>
|
81 |
+
<h1>Test data</h1>
|
82 |
+
|
83 |
+
<p>Add lots of test data to the log database.</p>
|
84 |
+
|
85 |
+
<p>
|
86 |
+
<button class="button js-SimpleHistorySettingsLogtestDropin-addStuff">Ok, add lots of stuff to the log!</button>
|
87 |
+
</p>
|
88 |
+
|
89 |
+
<div class="updated hidden js-SimpleHistorySettingsLogtestDropin-addStuffDone">
|
90 |
+
<p>Done! Added lots of test rows</p>
|
91 |
+
</div>
|
92 |
+
|
93 |
+
<div class="updated hidden js-SimpleHistorySettingsLogtestDropin-addStuffWorking">
|
94 |
+
<p>Adding...</p>
|
95 |
+
</div>
|
96 |
+
|
97 |
+
<?php
|
98 |
+
}
|
99 |
+
|
100 |
+
public function doLogTestThings() {
|
101 |
+
|
102 |
+
// Add some data random back in time, to fill up the log to test much data
|
103 |
+
for ( $j = 0; $j < 50; $j++ ) {
|
104 |
+
// between yesteday and a month back in time
|
105 |
+
for ( $i = 0; $i < rand( 1, 30 ); $i++ ) {
|
106 |
+
$str_date = gmdate( 'Y-m-d H:i:s', strtotime( "now -{$i}days" ) );
|
107 |
+
SimpleLogger()->info(
|
108 |
+
'Entry with date in the past',
|
109 |
+
array(
|
110 |
+
'_date' => $str_date,
|
111 |
+
'_occasionsID' => "past_date:{$str_date}",
|
112 |
+
)
|
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(
|
149 |
+
'User {username} edited page {pagename}',
|
150 |
+
array(
|
151 |
+
'username' => 'admin',
|
152 |
+
'pagename' => 'My test page',
|
153 |
+
'_occasionsID' => 'username:1,postID:24884,action:edited',
|
154 |
+
)
|
155 |
+
);
|
156 |
+
}
|
157 |
+
|
158 |
+
SimpleLogger()->info(
|
159 |
+
'WordPress updated itself from version {from_version} to {to_version}',
|
160 |
+
array(
|
161 |
+
'from_version' => '3.8',
|
162 |
+
'to_version' => '3.8.1',
|
163 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
164 |
+
)
|
165 |
+
);
|
166 |
+
|
167 |
+
SimpleLogger()->info(
|
168 |
+
'Plugin {plugin_name} was updated from version {plugin_from_version} to version {plugin_to_version}',
|
169 |
+
array(
|
170 |
+
'plugin_name' => 'CMS Tree Page View',
|
171 |
+
'plugin_from_version' => '4.0',
|
172 |
+
'plugin_to_version' => '4.2',
|
173 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
174 |
+
)
|
175 |
+
);
|
176 |
+
|
177 |
+
SimpleLogger()->info(
|
178 |
+
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
179 |
+
array(
|
180 |
+
'plugin_name' => 'Ninja Forms',
|
181 |
+
'plugin_from_version' => '1.1',
|
182 |
+
'plugin_to_version' => '1.1.2',
|
183 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
184 |
+
)
|
185 |
+
);
|
186 |
+
|
187 |
+
SimpleLogger()->warning(
|
188 |
+
"An attempt to login as user 'administrator' failed to login because the wrong password was entered",
|
189 |
+
array(
|
190 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
191 |
+
)
|
192 |
+
);
|
193 |
+
|
194 |
+
SimpleLogger()->info(
|
195 |
+
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
196 |
+
array(
|
197 |
+
'plugin_name' => 'Simple Fields',
|
198 |
+
'plugin_from_version' => '1.3.7',
|
199 |
+
'plugin_to_version' => '1.3.8',
|
200 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
201 |
+
)
|
202 |
+
);
|
203 |
+
|
204 |
+
SimpleLogger()->error(
|
205 |
+
"A JavaScript error was detected on page 'About us'",
|
206 |
+
array(
|
207 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
208 |
+
)
|
209 |
+
);
|
210 |
+
|
211 |
+
SimpleLogger()->debug(
|
212 |
+
"WP Cron 'my_test_cron_job' finished in 0.012 seconds",
|
213 |
+
array(
|
214 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
215 |
+
)
|
216 |
+
);
|
217 |
+
|
218 |
+
for ( $i = 0; $i < rand( 50, 1000 ); $i++ ) {
|
219 |
+
SimpleLogger()->warning(
|
220 |
+
'An attempt to login as user "{user_login}" failed to login because the wrong password was entered',
|
221 |
+
array(
|
222 |
+
'user_login' => 'admin',
|
223 |
+
'_userID' => null,
|
224 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
225 |
+
)
|
226 |
+
);
|
227 |
+
}
|
228 |
+
|
229 |
+
// Add more data to context array. Data can be used later on to show detailed info about a log entry.
|
230 |
+
SimpleLogger()->info(
|
231 |
+
"Edited product '{pagename}'",
|
232 |
+
array(
|
233 |
+
'pagename' => 'We are hiring!',
|
234 |
+
'_postType' => 'product',
|
235 |
+
'_userID' => 1,
|
236 |
+
'_userLogin' => 'jessie',
|
237 |
+
'_userEmail' => 'jessie@example.com',
|
238 |
+
'_occasionsID' => 'username:1,postID:24885,action:edited',
|
239 |
+
)
|
240 |
+
);
|
241 |
+
|
242 |
+
SimpleLogger()->debug( 'This is a message with no translation' );
|
243 |
+
SimpleLogger()->debug(
|
244 |
+
'Plugin',
|
245 |
+
array(
|
246 |
+
'comment' => "This message is 'Plugin' and should contain text domain 'default' since it's a translation that comes with WordPress",
|
247 |
+
)
|
248 |
+
);
|
249 |
+
SimpleLogger()->debug(
|
250 |
+
'Enter title of new page',
|
251 |
+
array(
|
252 |
+
'comment' => 'A translation used in CMS Tree Page View',
|
253 |
+
)
|
254 |
+
);
|
255 |
+
}
|
256 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dropins/SimpleHistorySettingsStatsDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Settings stats
|
@@ -9,105 +9,93 @@ Dropin URI: http://simple-history.com/
|
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
-
class SimpleHistorySettingsStatsDropin
|
13 |
-
{
|
14 |
|
15 |
-
// Simple History instance
|
16 |
-
private $sh;
|
17 |
|
18 |
-
|
19 |
-
|
20 |
|
21 |
-
|
22 |
-
if (! defined('SIMPLE_HISTORY_DEV') || ! SIMPLE_HISTORY_DEV) {
|
23 |
-
return;
|
24 |
-
}
|
25 |
|
26 |
-
|
|
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
$sh->registerSettingsTab(array(
|
30 |
-
'slug' => 'stats',
|
31 |
-
'name' => __('Stats', 'simple-history'),
|
32 |
-
'function' => array( $this, 'output' ),
|
33 |
-
));
|
34 |
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
-
|
39 |
-
|
40 |
|
41 |
-
|
42 |
|
43 |
-
|
44 |
-
wp_enqueue_style('simple_history_SettingsStatsDropin', $file_url . 'SimpleHistorySettingsStatsDropin.css', null, SIMPLE_HISTORY_VERSION);
|
45 |
-
}
|
46 |
|
47 |
-
|
48 |
-
|
|
|
49 |
|
50 |
-
|
51 |
-
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
52 |
-
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
$period_end_date = DateTime::createFromFormat('U', time());
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
google.load('visualization', '1', {'packages':['corechart']});
|
67 |
-
</script>
|
68 |
-
<?php
|
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 |
-
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--initiators'>
|
100 |
-
<?php include(SIMPLE_HISTORY_PATH . 'templates/settings-statsInitiators.php') ?>
|
101 |
-
</div>
|
102 |
-
-->
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
<?php
|
108 |
-
|
109 |
-
include(SIMPLE_HISTORY_PATH . 'templates/settings-statsForGeeks.php');
|
110 |
-
}
|
111 |
}
|
112 |
|
113 |
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
// Since it's not quite done yet, it's for da devs only for now
|
21 |
+
if ( ! defined( 'SIMPLE_HISTORY_DEV' ) || ! SIMPLE_HISTORY_DEV ) {
|
22 |
+
return;
|
23 |
+
}
|
24 |
|
25 |
+
$this->sh = $sh;
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
+
// How do we register this to the settings array?
|
28 |
+
$sh->registerSettingsTab(
|
29 |
+
array(
|
30 |
+
'slug' => 'stats',
|
31 |
+
'name' => __( 'Stats', 'simple-history' ),
|
32 |
+
'function' => array( $this, 'output' ),
|
33 |
+
)
|
34 |
+
);
|
35 |
|
36 |
+
add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'on_admin_enqueue_scripts' ) );
|
37 |
+
}
|
38 |
|
39 |
+
public function on_admin_enqueue_scripts() {
|
40 |
|
41 |
+
$file_url = plugin_dir_url( __FILE__ );
|
|
|
|
|
42 |
|
43 |
+
wp_enqueue_script( 'google-ajax-api', 'https://www.google.com/jsapi', array(), 1 );
|
44 |
+
wp_enqueue_style( 'simple_history_SettingsStatsDropin', $file_url . 'SimpleHistorySettingsStatsDropin.css', null, SIMPLE_HISTORY_VERSION );
|
45 |
+
}
|
46 |
|
47 |
+
public function output() {
|
|
|
|
|
48 |
|
49 |
+
global $wpdb;
|
50 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
51 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
|
|
52 |
|
53 |
+
// $period_days = (int) 28;
|
54 |
+
$period_days = (int) 14;
|
55 |
+
$period_start_date = DateTime::createFromFormat( 'U', strtotime( "-$period_days days" ) );
|
56 |
+
$period_end_date = DateTime::createFromFormat( 'U', time() );
|
57 |
|
58 |
+
// Colors taken from the gogole chart example that was found in this Stack Overflow thread:
|
59 |
+
// http://stackoverflow.com/questions/236936/how-pick-colors-for-a-pie-chart
|
60 |
+
$arr_colors = explode( ',', '8a56e2,cf56e2,e256ae,e25668,e28956,e2cf56,aee256,68e256,56e289,56e2cf,56aee2,5668e2' );
|
|
|
|
|
|
|
61 |
|
62 |
+
// Load google charts libraries
|
63 |
+
?>
|
64 |
+
<script>
|
65 |
+
google.load('visualization', '1', {'packages':['corechart']});
|
66 |
+
</script>
|
67 |
+
<!-- Overview, larger text -->
|
68 |
+
<div class='SimpleHistoryStats__intro'>
|
69 |
+
<?php
|
70 |
+
include( SIMPLE_HISTORY_PATH . 'templates/settings-statsIntro.php' );
|
71 |
+
?>
|
72 |
+
</div>
|
73 |
|
74 |
+
<!-- Start charts wrap -->
|
75 |
+
<div class='SimpleHistoryStats__graphs SimpleHistory__cf'>
|
76 |
|
77 |
+
<!-- bar chart with rows per day -->
|
78 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--rowsPerDay'>
|
79 |
+
<?php include( SIMPLE_HISTORY_PATH . 'templates/settings-statsRowsPerDay.php' ); ?>
|
80 |
+
</div><!-- // end bar chart rows per day -->
|
81 |
|
82 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--loggersPie'>
|
83 |
+
<?php include( SIMPLE_HISTORY_PATH . 'templates/settings-statsLoggers.php' ); ?>
|
84 |
+
</div>
|
85 |
|
86 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--logLevels'>
|
87 |
+
<?php include( SIMPLE_HISTORY_PATH . 'templates/settings-statsLogLevels.php' ); ?>
|
88 |
+
</div>
|
89 |
|
90 |
+
<div class='SimpleHistoryStats__graph SimpleHistoryStats__graph--users'>
|
91 |
+
<?php include( SIMPLE_HISTORY_PATH . 'templates/settings-statsUsers.php' ); ?>
|
92 |
+
</div>
|
93 |
+
</div><!-- // end charts wrapper -->
|
94 |
|
95 |
+
<?php
|
|
|
|
|
|
|
|
|
96 |
|
97 |
+
include( SIMPLE_HISTORY_PATH . 'templates/settings-statsForGeeks.php' );
|
98 |
+
}
|
|
|
|
|
|
|
|
|
|
|
99 |
}
|
100 |
|
101 |
|
dropins/SimpleHistorySidebarDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar
|
@@ -9,57 +9,28 @@ 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 |
-
add_action('simple_history/history_page/after_gui', array( $this, 'output_sidebar_html' ));
|
24 |
-
add_action('simple_history/dropin/sidebar/sidebar_html', array( $this, 'default_sidebar_contents' ));
|
25 |
-
}
|
26 |
-
|
27 |
-
public function default_sidebar_contents()
|
28 |
-
{
|
29 |
-
|
30 |
-
// Boxes that will appear randomly
|
31 |
-
// Box about GitHub
|
32 |
-
$headline = _x('Simple History is on GitHub', 'Sidebar box', 'simple-history');
|
33 |
-
|
34 |
-
$body = sprintf(
|
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">
|
43 |
-
<p>' . $body . '</p>
|
44 |
-
</div>
|
45 |
-
</div>
|
46 |
-
';
|
47 |
-
|
48 |
-
// Box about donation
|
49 |
-
$headline = _x('Donate to support development', 'Sidebar box', 'simple-history');
|
50 |
-
|
51 |
-
$bodyDonate = sprintf(
|
52 |
-
_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'),
|
53 |
-
'https://eskapism.se/sida/donate/'
|
54 |
-
);
|
55 |
-
|
56 |
-
$bodyGithubSponsors = sprintf(
|
57 |
-
_x('You can also <a href="%1$s">sponsor me at Github</a>.', 'Sidebar box', 'simple-history'),
|
58 |
-
'https://github.com/sponsors/bonny/'
|
59 |
-
);
|
60 |
-
|
61 |
-
|
62 |
-
$boxDonate = '
|
63 |
<div class="postbox">
|
64 |
<h3 class="hndle">' . $headline . '</h3>
|
65 |
<div class="inside">
|
@@ -69,17 +40,17 @@ class SimpleHistorySidebarDropin
|
|
69 |
</div>
|
70 |
';
|
71 |
|
72 |
-
|
73 |
-
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
|
80 |
-
|
81 |
|
82 |
-
|
83 |
<div class="postbox">
|
84 |
<h3 class="hndle">' . $headline . '</h3>
|
85 |
<div class="inside">
|
@@ -89,147 +60,74 @@ class SimpleHistorySidebarDropin
|
|
89 |
</div>
|
90 |
';
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
<div class="postbox">
|
96 |
-
<h3 class="hndle">Blog or tweet</h3>
|
97 |
-
<div class="inside">
|
98 |
-
<p>Yeah, how about that yo.</p>
|
99 |
-
</div>
|
100 |
-
</div>
|
101 |
-
';
|
102 |
-
*/
|
103 |
-
|
104 |
-
// Box about possible events missing
|
105 |
-
$boxMissingEvents = sprintf(
|
106 |
-
'
|
107 |
<div class="postbox">
|
108 |
<h3 class="hndle">%1$s</h3>
|
109 |
<div class="inside">
|
110 |
<p>%2$s</p>
|
111 |
-
<p><a href="hello@simple-history.com">hello@simple-history.com</a></p>
|
112 |
</div>
|
113 |
</div>
|
114 |
',
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
</div>
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
$arrBoxes = array(
|
134 |
-
'boxReview' => $boxReview,
|
135 |
-
'boxSupport' => $boxSupport,
|
136 |
-
// "boxMissingEvents" => $boxMissingEvents,
|
137 |
-
'boxDonate' => $boxDonate,
|
138 |
-
// "boxGithub" => $boxGithub,
|
139 |
-
);
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Filter the default boxes to output in the sidebar
|
143 |
-
*
|
144 |
-
* @since 2.0.17
|
145 |
-
*
|
146 |
-
* @param array $arrBoxes array with boxes to output. Check the key to determine which box is which.
|
147 |
-
*/
|
148 |
-
$arrBoxes = apply_filters('simple_history/SidebarDropin/default_sidebar_boxes', $arrBoxes);
|
149 |
-
|
150 |
-
echo implode('', $arrBoxes);
|
151 |
-
|
152 |
-
// Box to encourage people translate plugin.
|
153 |
-
$current_locale = get_locale();
|
154 |
-
|
155 |
-
/** WordPress Translation Install API. This file exists only since 4.0. */
|
156 |
-
$translation_install_file = ABSPATH . 'wp-admin/includes/translation-install.php';
|
157 |
-
|
158 |
-
// Show only the translation box if current language is not an english language
|
159 |
-
if (in_array($current_locale, array( 'en_US', 'en_GB', 'en_CA', 'en_NZ', 'en_AU' )) != $current_locale && file_exists($translation_install_file)) {
|
160 |
-
require_once $translation_install_file;
|
161 |
-
|
162 |
-
$translations = wp_get_available_translations();
|
163 |
-
|
164 |
-
// This text does not need translation since is's only shown in English
|
165 |
-
$boxTranslationTmpl = '
|
166 |
-
<div class="postbox">
|
167 |
-
<h3 class="hndle">Translate Simple History to %1$s</h3>
|
168 |
-
<div class="inside">
|
169 |
-
|
170 |
-
<p>
|
171 |
-
It looks like Simple History is not yet translated to your language.
|
172 |
-
</p>
|
173 |
-
|
174 |
-
<p>
|
175 |
-
If you\'re interested in translating it please check out the
|
176 |
-
<a href="https://developer.wordpress.org/plugins/internationalization/localization/">localization</a>
|
177 |
-
part of the Plugin Handbook for info on how to translate plugins.
|
178 |
-
</p>
|
179 |
-
</div>
|
180 |
-
</div>
|
181 |
-
';
|
182 |
-
|
183 |
-
if (isset($translations[ $current_locale ])) {
|
184 |
-
// Check if an existing text string returns something else, and that current lang is not en
|
185 |
-
$teststring_translated = __('Just now', 'simple-history');
|
186 |
-
$teststring_untranslated = 'Just now';
|
187 |
-
if ($teststring_untranslated == $teststring_translated) {
|
188 |
-
// strings are the same, so plugin probably not translated
|
189 |
-
printf($boxTranslationTmpl, $translations[ $current_locale ]['english_name']);
|
190 |
-
}
|
191 |
-
}
|
192 |
-
} // End if().
|
193 |
-
}
|
194 |
-
|
195 |
-
public function enqueue_admin_scripts()
|
196 |
-
{
|
197 |
-
$file_url = plugin_dir_url(__FILE__);
|
198 |
-
|
199 |
-
wp_enqueue_style('simple_history_SidebarDropin', $file_url . 'SimpleHistorySidebarDropin.css', null, SIMPLE_HISTORY_VERSION);
|
200 |
-
}
|
201 |
-
|
202 |
-
/**
|
203 |
-
* Output the outline for the sidebar
|
204 |
-
* Plugins and dropins simple use the filters to output contents to the sidebar
|
205 |
-
* Example HTML code to generate meta box:
|
206 |
-
*
|
207 |
-
* <div class="postbox">
|
208 |
-
* <h3 class="hndle">Title</h3>
|
209 |
-
* <div class="inside">
|
210 |
-
* <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
211 |
-
* </div>
|
212 |
-
* </div>
|
213 |
-
*/
|
214 |
-
public function output_sidebar_html()
|
215 |
-
{
|
216 |
-
|
217 |
-
?>
|
218 |
-
<div class="SimpleHistory__pageSidebar">
|
219 |
-
|
220 |
-
<div class="metabox-holder">
|
221 |
-
|
222 |
-
<?php
|
223 |
-
/**
|
224 |
-
* Allows to output HTML in sidebar
|
225 |
-
*
|
226 |
-
* @since 2.0.16
|
227 |
-
*/
|
228 |
-
do_action('simple_history/dropin/sidebar/sidebar_html');
|
229 |
-
?>
|
230 |
-
</div>
|
231 |
-
|
232 |
-
</div>
|
233 |
-
<?php
|
234 |
-
}
|
235 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar
|
9 |
Author: Pär Thernström
|
10 |
*/
|
11 |
|
12 |
+
class SimpleHistorySidebarDropin {
|
13 |
+
public function __construct( $sh ) {
|
14 |
+
add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
15 |
+
add_action( 'simple_history/history_page/after_gui', array( $this, 'output_sidebar_html' ) );
|
16 |
+
add_action( 'simple_history/dropin/sidebar/sidebar_html', array( $this, 'default_sidebar_contents' ) );
|
17 |
+
}
|
18 |
|
19 |
+
public function default_sidebar_contents() {
|
20 |
+
// Box about donation
|
21 |
+
$headline = _x( 'Donate to support development', 'Sidebar box', 'simple-history' );
|
22 |
|
23 |
+
$bodyDonate = sprintf(
|
24 |
+
_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' ),
|
25 |
+
'https://eskapism.se/sida/donate/'
|
26 |
+
);
|
27 |
|
28 |
+
$bodyGithubSponsors = sprintf(
|
29 |
+
_x( 'You can also <a href="%1$s">sponsor me at Github</a>.', 'Sidebar box', 'simple-history' ),
|
30 |
+
'https://github.com/sponsors/bonny/'
|
31 |
+
);
|
32 |
|
33 |
+
$boxDonate = '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
<div class="postbox">
|
35 |
<h3 class="hndle">' . $headline . '</h3>
|
36 |
<div class="inside">
|
40 |
</div>
|
41 |
';
|
42 |
|
43 |
+
// Box about review
|
44 |
+
$headline = _x( 'Review this plugin if you like it', 'Sidebar box', 'simple-history' );
|
45 |
|
46 |
+
$body1 = sprintf(
|
47 |
+
_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' ),
|
48 |
+
'https://wordpress.org/support/view/plugin-reviews/simple-history'
|
49 |
+
);
|
50 |
|
51 |
+
$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' );
|
52 |
|
53 |
+
$boxReview = '
|
54 |
<div class="postbox">
|
55 |
<h3 class="hndle">' . $headline . '</h3>
|
56 |
<div class="inside">
|
60 |
</div>
|
61 |
';
|
62 |
|
63 |
+
// Box about support
|
64 |
+
$boxSupport = sprintf(
|
65 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
<div class="postbox">
|
67 |
<h3 class="hndle">%1$s</h3>
|
68 |
<div class="inside">
|
69 |
<p>%2$s</p>
|
|
|
70 |
</div>
|
71 |
</div>
|
72 |
',
|
73 |
+
_x( 'Support', 'Sidebar box', 'simple-history' ), // 1
|
74 |
+
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
|
75 |
+
);
|
76 |
+
|
77 |
+
$arrBoxes = array(
|
78 |
+
'boxReview' => $boxReview,
|
79 |
+
'boxSupport' => $boxSupport,
|
80 |
+
'boxDonate' => $boxDonate,
|
81 |
+
);
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Filter the default boxes to output in the sidebar
|
85 |
+
*
|
86 |
+
* @since 2.0.17
|
87 |
+
*
|
88 |
+
* @param array $arrBoxes array with boxes to output. Check the key to determine which box is which.
|
89 |
+
*/
|
90 |
+
$arrBoxes = apply_filters( 'simple_history/SidebarDropin/default_sidebar_boxes', $arrBoxes );
|
91 |
+
|
92 |
+
echo implode( '', $arrBoxes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
93 |
+
}
|
94 |
+
|
95 |
+
public function enqueue_admin_scripts() {
|
96 |
+
$file_url = plugin_dir_url( __FILE__ );
|
97 |
+
|
98 |
+
wp_enqueue_style( 'simple_history_SidebarDropin', $file_url . 'SimpleHistorySidebarDropin.css', null, SIMPLE_HISTORY_VERSION );
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Output the outline for the sidebar
|
103 |
+
* Plugins and dropins simple use the filters to output contents to the sidebar
|
104 |
+
* Example HTML code to generate meta box:
|
105 |
+
*
|
106 |
+
* <div class="postbox">
|
107 |
+
* <h3 class="hndle">Title</h3>
|
108 |
+
* <div class="inside">
|
109 |
+
* <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
|
110 |
+
* </div>
|
111 |
+
* </div>
|
112 |
+
*/
|
113 |
+
public function output_sidebar_html() {
|
114 |
+
|
115 |
+
?>
|
116 |
+
<div class="SimpleHistory__pageSidebar">
|
117 |
+
|
118 |
+
<div class="metabox-holder">
|
119 |
+
|
120 |
+
<?php
|
121 |
+
/**
|
122 |
+
* Allows to output HTML in sidebar
|
123 |
+
*
|
124 |
+
* @since 2.0.16
|
125 |
+
*/
|
126 |
+
do_action( 'simple_history/dropin/sidebar/sidebar_html' );
|
127 |
+
?>
|
128 |
</div>
|
129 |
+
|
130 |
+
</div>
|
131 |
+
<?php
|
132 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
dropins/SimpleHistorySidebarSettings.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with link to settings
|
@@ -8,84 +8,81 @@ 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 |
-
<?php
|
90 |
-
}
|
91 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
public function __construct( $sh ) {
|
27 |
+
|
28 |
+
$this->init( $sh );
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Init
|
33 |
+
*
|
34 |
+
* @param object $sh Simple History instance.
|
35 |
+
*/
|
36 |
+
public function init( $sh ) {
|
37 |
+
|
38 |
+
$this->sh = $sh;
|
39 |
+
|
40 |
+
add_action( 'simple_history/dropin/sidebar/sidebar_html', array( $this, 'on_sidebar_html' ), 5 );
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Output HTML
|
45 |
+
*/
|
46 |
+
public function on_sidebar_html() {
|
47 |
+
|
48 |
+
?>
|
49 |
+
|
50 |
+
<div class="postbox">
|
51 |
+
|
52 |
+
<h3 class="hndle"><?php esc_html_e( 'Settings', 'simple-history' ); ?></h3>
|
53 |
+
|
54 |
+
<div class="inside">
|
55 |
+
|
56 |
+
<p>
|
57 |
+
<?php
|
58 |
+
|
59 |
+
/*
|
60 |
+
Visit the settings page to change the number of items to show and
|
61 |
+
where to show
|
62 |
+
rss feed
|
63 |
+
clear log
|
64 |
+
|
65 |
+
- Visit the settings page to change the number of events to show, to get
|
66 |
+
- Visit the settings page
|
67 |
+
*/
|
68 |
+
printf(
|
69 |
+
wp_kses(
|
70 |
+
/* translators: 1: URL to settings page */
|
71 |
+
__( '<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' ),
|
72 |
+
array(
|
73 |
+
'a' => array(
|
74 |
+
'href' => array(),
|
75 |
+
),
|
76 |
+
)
|
77 |
+
),
|
78 |
+
esc_url( menu_page_url( SimpleHistory::SETTINGS_MENU_SLUG, false ) )
|
79 |
+
);
|
80 |
+
?>
|
81 |
+
</p>
|
82 |
+
|
83 |
+
</div>
|
84 |
+
</div>
|
85 |
+
|
86 |
+
<?php
|
87 |
+
}
|
|
|
|
|
|
|
88 |
}
|
dropins/SimpleHistorySidebarStats.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with short stats
|
@@ -8,237 +8,238 @@ Dropin URI: http://simple-history.com/
|
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
-
class SimpleHistorySidebarStats
|
12 |
-
|
13 |
-
|
14 |
-
private $sh;
|
15 |
|
16 |
-
|
17 |
-
{
|
18 |
-
|
19 |
-
$this->init($sh);
|
20 |
-
}
|
21 |
-
|
22 |
-
public function init($sh)
|
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 |
-
* JavaScript for SimpleHistory_SidebarChart
|
48 |
-
*/
|
49 |
-
(function($) {
|
50 |
|
51 |
-
|
|
|
52 |
|
53 |
-
|
|
|
|
|
|
|
54 |
|
55 |
-
|
56 |
-
return;
|
57 |
-
}
|
58 |
|
59 |
-
|
60 |
-
var chartLabelsToDates = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabelsToDates").val() );
|
61 |
-
var chartDatasetData = JSON.parse( $(".SimpleHistory_SidebarChart_ChartDatasetData").val() );
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
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 |
-
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
|
95 |
-
var chartElmClicked = this.getElementAtEvent(e)[0];
|
96 |
|
97 |
-
|
98 |
-
|
99 |
-
return;
|
100 |
-
}
|
101 |
|
102 |
-
|
103 |
-
// var value = this.data.datasets[chartElmClicked._datasetIndex].data[chartElmClicked._index];
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
for (idx in chartLabelsToDates) {
|
110 |
-
if (label == chartLabelsToDates[idx].label) {
|
111 |
-
//console.log(chartLabelsToDates[idx]);
|
112 |
-
labelDate = chartLabelsToDates[idx];
|
113 |
-
}
|
114 |
-
}
|
115 |
|
116 |
-
|
117 |
-
|
118 |
-
}
|
119 |
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
-
|
124 |
-
|
|
|
125 |
|
126 |
-
|
127 |
-
|
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 |
-
|
|
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
})(jQuery);
|
138 |
-
|
139 |
-
</script>
|
140 |
-
|
141 |
-
<?php
|
142 |
-
}
|
143 |
-
|
144 |
-
public 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: Sidebar with short stats
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistorySidebarStats {
|
12 |
+
private $sh;
|
|
|
|
|
13 |
|
14 |
+
public function __construct( $sh ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
$this->init( $sh );
|
17 |
+
}
|
18 |
|
19 |
+
public function init( $sh ) {
|
20 |
|
21 |
+
$this->sh = $sh;
|
22 |
|
23 |
+
add_action( 'simple_history/dropin/sidebar/sidebar_html', array( $this, 'on_sidebar_html' ), 5 );
|
|
|
24 |
|
25 |
+
add_action( 'simple_history/enqueue_admin_scripts', array( $this, 'on_admin_enqueue_scripts' ) );
|
|
|
26 |
|
27 |
+
add_action( 'simple_history/admin_footer', array( $this, 'on_admin_footer' ) );
|
28 |
+
}
|
29 |
|
30 |
+
public function on_admin_enqueue_scripts() {
|
|
|
31 |
|
32 |
+
wp_enqueue_script( 'simple_history_chart.js', SIMPLE_HISTORY_DIR_URL . 'js/Chart.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION, true );
|
33 |
+
}
|
34 |
|
35 |
+
public function on_admin_footer() {
|
|
|
|
|
|
|
36 |
|
37 |
+
?>
|
38 |
+
<script>
|
39 |
|
40 |
+
/**
|
41 |
+
* JavaScript for SimpleHistory_SidebarChart
|
42 |
+
*/
|
43 |
+
(function($) {
|
44 |
|
45 |
+
$(function() {
|
|
|
|
|
46 |
|
47 |
+
var ctx = $(".SimpleHistory_SidebarChart_ChartCanvas");
|
|
|
|
|
48 |
|
49 |
+
if ( ! ctx.length ) {
|
50 |
+
return;
|
51 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
var chartLabels = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabels").val() );
|
54 |
+
var chartLabelsToDates = JSON.parse( $(".SimpleHistory_SidebarChart_ChartLabelsToDates").val() );
|
55 |
+
var chartDatasetData = JSON.parse( $(".SimpleHistory_SidebarChart_ChartDatasetData").val() );
|
56 |
|
57 |
+
var myChart = new Simple_History_Chart(ctx, {
|
58 |
+
type: 'bar',
|
59 |
+
data: {
|
60 |
+
labels: chartLabels,
|
61 |
+
datasets: [{
|
62 |
+
data: chartDatasetData,
|
63 |
+
backgroundColor: "rgb(210,210,210)",
|
64 |
+
hoverBackgroundColor: "rgb(175,175,175)",
|
65 |
+
}]
|
66 |
+
},
|
67 |
+
options: {
|
68 |
+
legend: {
|
69 |
+
display: false
|
70 |
+
},
|
71 |
+
scales: {
|
72 |
+
yAxes: [{
|
73 |
+
ticks: {
|
74 |
+
beginAtZero:true
|
75 |
+
},
|
76 |
+
}],
|
77 |
+
xAxes: [{
|
78 |
+
display: false
|
79 |
+
}]
|
80 |
+
},
|
81 |
+
onClick: clickChart
|
82 |
+
},
|
83 |
+
});
|
84 |
|
|
|
85 |
|
86 |
+
// when chart is clicked determine what value/day was clicked
|
87 |
+
function clickChart(e) {
|
|
|
|
|
88 |
|
89 |
+
var chartElmClicked = this.getElementAtEvent(e)[0];
|
|
|
90 |
|
91 |
+
if (!chartElmClicked || !chartElmClicked._index) {
|
92 |
+
console.log("No value found for click");
|
93 |
+
return;
|
94 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
|
96 |
+
var label = this.data.labels[chartElmClicked._index];
|
97 |
+
// var value = this.data.datasets[chartElmClicked._datasetIndex].data[chartElmClicked._index];
|
|
|
98 |
|
99 |
+
// now we have the label which is like "July 23" or "23 juli" depending on language
|
100 |
+
// look for that label value in chartLabelsToDates and there we get the date in format Y-m-d
|
101 |
+
//console.log("chartLabelsToDates", chartLabelsToDates);
|
102 |
+
var labelDate;
|
103 |
+
for (idx in chartLabelsToDates) {
|
104 |
+
if (label == chartLabelsToDates[idx].label) {
|
105 |
+
//console.log(chartLabelsToDates[idx]);
|
106 |
+
labelDate = chartLabelsToDates[idx];
|
107 |
+
}
|
108 |
+
}
|
109 |
|
110 |
+
if (!labelDate) {
|
111 |
+
return;
|
112 |
+
}
|
113 |
|
114 |
+
// got a date, now reload the history/post search filter form again
|
115 |
+
var labelDateParts = labelDate.date.split("-"); ["2016", "07", "18"]
|
|
|
|
|
116 |
|
117 |
+
// show custom date range
|
118 |
+
$(".SimpleHistory__filters__filter--date").val("customRange").trigger("change");
|
119 |
|
120 |
+
// set values, same for both from and to because we only want to show one day
|
121 |
+
SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_aa'], [name='to_aa']").val(labelDateParts[0]);
|
122 |
+
SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_jj'], [name='to_jj']").val(labelDateParts[2]);
|
123 |
+
SimpleHistoryFilterDropin.$elms.filter_form.find("[name='from_mm'], [name='to_mm']").val(labelDateParts[1]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
125 |
+
SimpleHistoryFilterDropin.$elms.filter_form.trigger("submit");
|
126 |
+
|
127 |
+
}
|
128 |
+
|
129 |
+
});
|
130 |
+
|
131 |
+
})(jQuery);
|
132 |
+
|
133 |
+
</script>
|
134 |
+
|
135 |
+
<?php
|
136 |
+
}
|
137 |
+
|
138 |
+
public function on_sidebar_html() {
|
139 |
+
|
140 |
+
$num_days = 28;
|
141 |
+
|
142 |
+
$num_events_per_day_for_period = $this->sh->get_num_events_per_day_last_n_days( $num_days );
|
143 |
+
|
144 |
+
// Period = all dates, so empty ones don't get lost
|
145 |
+
$period_start_date = DateTime::createFromFormat( 'U', strtotime( "-$num_days days" ) );
|
146 |
+
$period_end_date = DateTime::createFromFormat( 'U', time() );
|
147 |
+
$interval = DateInterval::createFromDateString( '1 day' );
|
148 |
+
$period = new DatePeriod( $period_start_date, $interval, $period_end_date->add( date_interval_create_from_date_string( '1 days' ) ) );
|
149 |
+
|
150 |
+
?>
|
151 |
+
|
152 |
+
<div class="postbox">
|
153 |
+
|
154 |
+
<h3 class="hndle"><?php esc_html_e( 'Stats', 'simple-history' ); ?></h3>
|
155 |
+
|
156 |
+
<div class="inside">
|
157 |
+
|
158 |
+
<p>
|
159 |
+
<?php
|
160 |
+
|
161 |
+
echo wp_kses(
|
162 |
+
sprintf(
|
163 |
+
__( '<b>%1$s events</b> have been logged the last <b>%2$s days</b>.', 'simple-history' ),
|
164 |
+
$this->sh->get_num_events_last_n_days( $num_days ),
|
165 |
+
number_format_i18n( $num_days )
|
166 |
+
),
|
167 |
+
array(
|
168 |
+
'b' => array(),
|
169 |
+
)
|
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 esc_html_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 |
+
$datef = _x( 'M j', 'stats: date in rows per day chart', 'simple-history' );
|
192 |
+
$str_date = date_i18n( $datef, $dt->getTimestamp() );
|
193 |
+
$str_date_ymd = gmdate( 'Y-m-d', $dt->getTimestamp() );
|
194 |
|
195 |
+
// Get data for this day, if exist
|
196 |
+
// Day in object is in format '2014-09-07'
|
197 |
+
$yearDate = $dt->format( 'Y-m-d' );
|
198 |
+
$day_data = wp_filter_object_list(
|
199 |
+
$num_events_per_day_for_period,
|
200 |
+
array(
|
201 |
+
'yearDate' => $yearDate,
|
202 |
+
)
|
203 |
+
);
|
204 |
|
205 |
+
$arr_labels[] = $str_date;
|
206 |
|
207 |
+
$arr_labels_to_datetime[] = array(
|
208 |
+
'label' => $str_date,
|
209 |
+
'date' => $str_date_ymd,
|
210 |
+
);
|
211 |
|
212 |
+
if ( $day_data ) {
|
213 |
+
$day_data = reset( $day_data );
|
214 |
+
$arr_dataset_data[] = $day_data->count;
|
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 echo esc_attr( json_encode( $arr_labels ) ); ?>"
|
226 |
+
/>
|
227 |
|
228 |
+
<input
|
229 |
+
type="hidden"
|
230 |
+
class="SimpleHistory_SidebarChart_ChartLabelsToDates"
|
231 |
+
value="<?php echo esc_attr( json_encode( $arr_labels_to_datetime ) ); ?>"
|
232 |
+
/>
|
233 |
+
|
234 |
+
<input
|
235 |
+
type="hidden"
|
236 |
+
class="SimpleHistory_SidebarChart_ChartDatasetData"
|
237 |
+
value="<?php echo esc_attr( json_encode( $arr_dataset_data ) ); ?>"
|
238 |
+
/>
|
239 |
+
|
240 |
+
</div>
|
241 |
+
</div>
|
242 |
+
|
243 |
+
<?php
|
244 |
+
}
|
245 |
}
|
dropins/SimpleHistoryWPCLIDropin.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/*
|
6 |
Dropin Name: WP CLI
|
@@ -8,158 +8,147 @@ 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 |
-
$fields = array(
|
156 |
-
'date',
|
157 |
-
'initiator',
|
158 |
-
'description',
|
159 |
-
'level',
|
160 |
-
'count',
|
161 |
-
);
|
162 |
-
|
163 |
-
WP_CLI\Utils\format_items($assoc_args['format'], $eventsCleaned, $fields);
|
164 |
-
}
|
165 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/*
|
6 |
Dropin Name: WP CLI
|
8 |
Author: Pär Thernström
|
9 |
*/
|
10 |
|
11 |
+
class SimpleHistoryWPCLIDropin {
|
12 |
+
|
13 |
+
// Simple History instance
|
14 |
+
private $sh;
|
15 |
+
|
16 |
+
public function __construct( $sh ) {
|
17 |
+
$this->sh = $sh;
|
18 |
+
|
19 |
+
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
20 |
+
$this->register_commands();
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
private function register_commands() {
|
25 |
+
$commandConfigurationOptions = array(
|
26 |
+
'shortdesc' => 'Lists the history log',
|
27 |
+
'synopsis' => array(
|
28 |
+
array(
|
29 |
+
'type' => 'assoc',
|
30 |
+
'name' => 'format',
|
31 |
+
'optional' => true,
|
32 |
+
'default' => 'table',
|
33 |
+
'options' => array( 'table', 'json', 'csv', 'yaml' ),
|
34 |
+
),
|
35 |
+
array(
|
36 |
+
'type' => 'assoc',
|
37 |
+
'name' => 'count',
|
38 |
+
'optional' => true,
|
39 |
+
'default' => '10',
|
40 |
+
),
|
41 |
+
),
|
42 |
+
'when' => 'after_wp_load',
|
43 |
+
);
|
44 |
+
|
45 |
+
WP_CLI::add_command( 'simple-history list', array( $this, 'commandList' ), $commandConfigurationOptions );
|
46 |
+
}
|
47 |
+
|
48 |
+
private function getInitiatorTextFromRow( $row ) {
|
49 |
+
if ( ! isset( $row->initiator ) ) {
|
50 |
+
return false;
|
51 |
+
}
|
52 |
+
|
53 |
+
$initiator = $row->initiator;
|
54 |
+
$initiatorText = '';
|
55 |
+
|
56 |
+
switch ( $initiator ) {
|
57 |
+
case 'wp':
|
58 |
+
$initiatorText = 'WordPress';
|
59 |
+
break;
|
60 |
+
case 'wp_cli':
|
61 |
+
$initiatorText = 'WP-CLI';
|
62 |
+
break;
|
63 |
+
case 'wp_user':
|
64 |
+
$user_id = isset( $row->context['_user_id'] ) ? $row->context['_user_id'] : null;
|
65 |
+
$user = get_user_by( 'id', $user_id );
|
66 |
+
|
67 |
+
if ( $user_id > 0 && $user ) {
|
68 |
+
// User still exists
|
69 |
+
$initiatorText = sprintf(
|
70 |
+
'%1$s (%2$s)',
|
71 |
+
$user->user_login, // 1
|
72 |
+
$user->user_email // 2
|
73 |
+
);
|
74 |
+
} elseif ( $user_id > 0 ) {
|
75 |
+
// Sender was a user, but user is deleted now.
|
76 |
+
$initiatorText = sprintf(
|
77 |
+
__( 'Deleted user (had id %1$s, email %2$s, login %3$s)', 'simple-history' ),
|
78 |
+
$context['_user_id'], // 1
|
79 |
+
$context['_user_email'], // 2
|
80 |
+
$context['_user_login'] // 3
|
81 |
+
);
|
82 |
+
} // End if().
|
83 |
+
break;
|
84 |
+
case 'web_user':
|
85 |
+
$initiatorText = __( 'Anonymous web user', 'simple-history' );
|
86 |
+
break;
|
87 |
+
case 'other':
|
88 |
+
$initiatorText = _x( 'Other', 'Event header output, when initiator is unknown', 'simple-history' );
|
89 |
+
break;
|
90 |
+
default:
|
91 |
+
$initiatorText = $initiator;
|
92 |
+
}// End switch().
|
93 |
+
|
94 |
+
return $initiatorText;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* The function for the command "list"
|
99 |
+
*/
|
100 |
+
public function commandList( $args, $assoc_args ) {
|
101 |
+
|
102 |
+
if ( ! is_numeric( $assoc_args['count'] ) ) {
|
103 |
+
WP_CLI::error( __( 'Error: parameter "count" must be a number', 'simple-history' ) );
|
104 |
+
}
|
105 |
+
|
106 |
+
// Override capability check: if you can run wp cli commands you can read all loggers
|
107 |
+
add_action( 'simple_history/loggers_user_can_read/can_read_single_logger', '__return_true', 10, 3 );
|
108 |
+
|
109 |
+
// WP_CLI::log( sprintf( 'Showing %1$d events from Simple History', $assoc_args["count"] ) );
|
110 |
+
$query = new SimpleHistoryLogQuery();
|
111 |
+
|
112 |
+
$query_args = array(
|
113 |
+
'paged' => 1,
|
114 |
+
'posts_per_page' => $assoc_args['count'],
|
115 |
+
);
|
116 |
+
|
117 |
+
$events = $query->query( $query_args );
|
118 |
+
|
119 |
+
// A cleaned version of the events, formatted for wp cli table output
|
120 |
+
$eventsCleaned = array();
|
121 |
+
|
122 |
+
foreach ( $events['log_rows'] as $row ) {
|
123 |
+
$header_output = $this->sh->getLogRowHeaderOutput( $row );
|
124 |
+
$text_output = $this->sh->getLogRowPlainTextOutput( $row );
|
125 |
+
// $details_output = $this->sh->getLogRowDetailsOutput($row);
|
126 |
+
$header_output = strip_tags( html_entity_decode( $header_output, ENT_QUOTES, 'UTF-8' ) );
|
127 |
+
$header_output = trim( preg_replace( '/\s\s+/', ' ', $header_output ) );
|
128 |
+
|
129 |
+
$text_output = strip_tags( html_entity_decode( $text_output, ENT_QUOTES, 'UTF-8' ) );
|
130 |
+
|
131 |
+
$eventsCleaned[] = array(
|
132 |
+
'date' => get_date_from_gmt( $row->date ),
|
133 |
+
// "initiator" => $row->initiator,
|
134 |
+
'initiator' => $this->getInitiatorTextFromRow( $row ),
|
135 |
+
'logger' => $row->logger,
|
136 |
+
'level' => $row->level,
|
137 |
+
'who_when' => $header_output,
|
138 |
+
'description' => $text_output,
|
139 |
+
'count' => $row->subsequentOccasions,
|
140 |
+
// "details" => $details_output
|
141 |
+
);
|
142 |
+
}
|
143 |
+
|
144 |
+
$fields = array(
|
145 |
+
'date',
|
146 |
+
'initiator',
|
147 |
+
'description',
|
148 |
+
'level',
|
149 |
+
'count',
|
150 |
+
);
|
151 |
+
|
152 |
+
WP_CLI\Utils\format_items( $assoc_args['format'], $eventsCleaned, $fields );
|
153 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
}
|
examples/example-dropin.php
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
// No external calls allowed to test file
|
|
|
4 |
exit;
|
5 |
|
6 |
/**
|
@@ -8,56 +9,48 @@ exit;
|
|
8 |
* that will add a tab to the simple history settings page
|
9 |
*/
|
10 |
|
11 |
-
// We use the function "register_dropin" to tell tell
|
12 |
// We call it from inside the filter "simple_history/add_custom_logger".
|
13 |
-
add_action(
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
16 |
|
17 |
|
18 |
/**
|
19 |
* This is the class that does the main work!
|
20 |
*/
|
21 |
-
class AddSettingsPageTab
|
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 |
-
public function settingsTabOutput()
|
53 |
-
{
|
54 |
-
|
55 |
-
?>
|
56 |
-
|
57 |
-
<h3>Hi there!</h3>
|
58 |
-
|
59 |
-
<p>I'm the output from on settings tab.</p>
|
60 |
-
|
61 |
-
<?php
|
62 |
-
}
|
63 |
}
|
1 |
<?php
|
2 |
|
3 |
+
// No external calls allowed to test file.
|
4 |
+
// Remove this exit call if you use this file as a template for your own dropin.
|
5 |
exit;
|
6 |
|
7 |
/**
|
9 |
* that will add a tab to the simple history settings page
|
10 |
*/
|
11 |
|
12 |
+
// We use the function "register_dropin" to tell tell Simple History that our custom logger exists.
|
13 |
// We call it from inside the filter "simple_history/add_custom_logger".
|
14 |
+
add_action(
|
15 |
+
'simple_history/add_custom_dropin',
|
16 |
+
function ( $simpleHistory ) {
|
17 |
+
$simpleHistory->register_dropin( 'AddSettingsPageTab' );
|
18 |
+
}
|
19 |
+
);
|
20 |
|
21 |
|
22 |
/**
|
23 |
* This is the class that does the main work!
|
24 |
*/
|
25 |
+
class AddSettingsPageTab {
|
26 |
+
|
27 |
+
// This will hold a reference to the simple history instance.
|
28 |
+
private $sh;
|
29 |
+
|
30 |
+
// Simple History will pass itself to the constructor.
|
31 |
+
public function __construct( $sh ) {
|
32 |
+
$this->sh = $sh;
|
33 |
+
$this->init();
|
34 |
+
}
|
35 |
+
|
36 |
+
public function init() {
|
37 |
+
add_action( 'init', array( $this, 'add_settings_tab' ) );
|
38 |
+
}
|
39 |
+
|
40 |
+
public function add_settings_tab() {
|
41 |
+
$this->sh->registerSettingsTab(
|
42 |
+
array(
|
43 |
+
'slug' => 'my_unique_settings_tab_slug',
|
44 |
+
'name' => __( 'Example tab', 'simple-history' ),
|
45 |
+
'function' => array( $this, 'settings_tab_output' ),
|
46 |
+
)
|
47 |
+
);
|
48 |
+
}
|
49 |
+
|
50 |
+
public function settings_tab_output() {
|
51 |
+
?>
|
52 |
+
<h3>Hi there!</h3>
|
53 |
+
<p>I'm the output from on settings tab.</p>
|
54 |
+
<?php
|
55 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
examples/example-logger.php
CHANGED
@@ -10,84 +10,84 @@ exit;
|
|
10 |
|
11 |
// We use the function "register_logger" to tell tell SimpleHistory that our custom logger exists.
|
12 |
// We call it from inside the filter "simple_history/add_custom_logger".
|
13 |
-
add_action(
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
16 |
|
17 |
// We make sure that the SimpleLogger class exists before trying to extend it.
|
18 |
// This prevents error if the Simple History plugin gets inactivated.
|
19 |
-
if (class_exists('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 |
-
return $template;
|
91 |
-
}
|
92 |
-
}
|
93 |
}// End if().
|
10 |
|
11 |
// We use the function "register_logger" to tell tell SimpleHistory that our custom logger exists.
|
12 |
// We call it from inside the filter "simple_history/add_custom_logger".
|
13 |
+
add_action(
|
14 |
+
'simple_history/add_custom_logger',
|
15 |
+
function ( $simpleHistory ) {
|
16 |
+
$simpleHistory->register_logger( 'FourOhFourLogger' );
|
17 |
+
}
|
18 |
+
);
|
19 |
|
20 |
// We make sure that the SimpleLogger class exists before trying to extend it.
|
21 |
// This prevents error if the Simple History plugin gets inactivated.
|
22 |
+
if ( class_exists( 'SimpleLogger' ) ) {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* This is the class that does the main work!
|
26 |
+
*/
|
27 |
+
class FourOhFourLogger extends SimpleLogger {
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* The slug is ised to identify this logger in various places.
|
32 |
+
* We use the name of the class too keep it simple.
|
33 |
+
*/
|
34 |
+
public $slug = __CLASS__;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Return information about this logger.
|
38 |
+
* Used to show info about the logger at various places.
|
39 |
+
*/
|
40 |
+
public function getInfo() {
|
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 |
+
public function loaded() {
|
70 |
+
|
71 |
+
// Call a function when WordPress finds a 404 page
|
72 |
+
add_action( '404_template', array( $this, 'on404Template' ), 10, 1 );
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Function that is called when WordPress finds a 404 page.
|
77 |
+
* It collects some info and then it logs a warning message
|
78 |
+
* to the log.
|
79 |
+
*/
|
80 |
+
public function on404Template( $template ) {
|
81 |
+
|
82 |
+
$context = array(
|
83 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
84 |
+
'request_uri' => isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '',
|
85 |
+
'http_referer' => isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : '',
|
86 |
+
);
|
87 |
+
|
88 |
+
$this->warningMessage( 'page_not_found', $context );
|
89 |
+
|
90 |
+
return $template;
|
91 |
+
}
|
92 |
+
}
|
|
|
|
|
|
|
93 |
}// End if().
|
examples/examples.php
CHANGED
@@ -14,7 +14,7 @@ exit;
|
|
14 |
*/
|
15 |
|
16 |
// Add $_GET, $_POST, and more info to each logged event.
|
17 |
-
define('SIMPLE_HISTORY_LOG_DEBUG', true);
|
18 |
|
19 |
|
20 |
/**
|
@@ -25,61 +25,79 @@ define('SIMPLE_HISTORY_LOG_DEBUG', true);
|
|
25 |
* Remove the "Clear log"-button, so a user with admin access can not clear the log
|
26 |
* and wipe their mischievous behavior from the log.
|
27 |
*/
|
28 |
-
add_filter(
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
32 |
|
33 |
// Modify who can read a logger.
|
34 |
// Modify the if part to give users access or no access to a logger.
|
35 |
-
add_filter(
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
|
49 |
// Do not log some post types, for example pages and attachments in this case
|
50 |
-
add_filter(
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
// Disable all logging
|
65 |
-
add_filter('simple_history/log/do_log', '__return_false');
|
66 |
|
67 |
/**
|
68 |
* Example that modifies the parameters sent to the message template
|
69 |
* This example will change the post type from "post" or "page" or similar to "my own page type"
|
70 |
*/
|
71 |
-
add_filter(
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
|
85 |
|
@@ -87,11 +105,14 @@ add_filter('simple_history/logger/interpolate/context', function ($context, $mes
|
|
87 |
* Change capability required to manage the options page of simple history.
|
88 |
* Default capability is "manage_options"
|
89 |
*/
|
90 |
-
add_filter(
|
|
|
|
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
}
|
|
|
95 |
|
96 |
|
97 |
/**
|
@@ -99,249 +120,302 @@ add_filter('simple_history/view_settings_capability', function ($capability) {
|
|
99 |
* Default capability is "edit_pages". Change to for example "manage options"
|
100 |
* to only allow admins to view the history log.
|
101 |
*/
|
102 |
-
add_filter(
|
|
|
|
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
}
|
|
|
107 |
|
108 |
|
109 |
// Skip adding things to the context table during logging.
|
110 |
// Useful if you don't want to add cool and possible super useful info to your logged events.
|
111 |
// Also nice to have if you want to make sure your database does not grow.
|
112 |
-
add_filter(
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
// Hide some columns from the detailed context view popup window
|
123 |
-
add_filter(
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
|
|
|
|
|
|
|
|
|
|
132 |
|
133 |
|
134 |
// Hide some more columns from the detailed context view popup window
|
135 |
-
add_filter(
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
|
|
|
|
|
|
|
|
|
|
144 |
|
145 |
|
146 |
|
147 |
// Allow only the users specified in $allowed_users to show the history page, the history widget on the dashboard, or the history settings page
|
148 |
-
add_filter('simple_history/show_dashboard_page', 'function_show_history_dashboard_or_page');
|
149 |
-
add_filter('simple_history/show_dashboard_widget', 'function_show_history_dashboard_or_page');
|
150 |
-
add_filter('simple_history/show_settings_page', 'function_show_history_dashboard_or_page');
|
151 |
-
function function_show_history_dashboard_or_page($show)
|
152 |
-
{
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
|
159 |
-
|
160 |
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
|
165 |
-
|
166 |
}
|
167 |
|
168 |
|
169 |
// Skip loading of loggers
|
170 |
-
add_filter(
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
/**
|
181 |
* Load only the loggers that are specified in the $do_log_us array
|
182 |
*/
|
183 |
-
add_filter(
|
|
|
|
|
184 |
|
185 |
-
|
186 |
-
|
187 |
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
|
192 |
-
|
193 |
-
},
|
|
|
|
|
|
|
194 |
|
195 |
|
196 |
// Skip the loading of dropins
|
197 |
-
add_filter(
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
|
213 |
// Don't log failed logins
|
214 |
-
add_filter(
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
|
|
|
|
|
|
|
|
|
|
228 |
|
229 |
// Never clear the log (default is 60 days)
|
230 |
-
add_filter('simple_history/db_purge_days_interval', '__return_zero');
|
231 |
|
232 |
// Clear items that are older than a 7 days (i.e. keep only the most recent 7 days in the log)
|
233 |
-
add_filter(
|
|
|
|
|
234 |
|
235 |
-
|
236 |
|
237 |
-
|
238 |
-
}
|
|
|
239 |
|
240 |
// Don't let anyone - even with the correct secret - view the RSS feed
|
241 |
-
add_filter('simple_history/rss_feed_show', '__return_false');
|
242 |
|
243 |
// Skip loading of a dropin completely (in this case the RSS dropin)
|
244 |
-
add_filter('simple_history/dropin/load_dropin_SimpleHistoryRSSDropin', '__return_false');
|
245 |
|
246 |
/**
|
247 |
* Example of logging
|
248 |
*/
|
249 |
|
250 |
// This is the easiest and safest way to add messages to the log:
|
251 |
-
apply_filters('simple_history_log', 'This is a logged message');
|
252 |
-
apply_filters(
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
|
|
|
|
|
|
|
|
257 |
|
258 |
// Below is the function way of adding things to the log
|
259 |
// Remember to check that the SimpleLogger function exists before trying to log anything,
|
260 |
// or else your site will break if you disable the Simple History plugin
|
261 |
// (Use the apply_filters method above if you want to stay safer!)
|
262 |
-
if (function_exists('SimpleLogger')) {
|
263 |
-
|
264 |
}
|
265 |
|
266 |
// Add a message to the history log
|
267 |
-
SimpleLogger()->info('This is a message sent to the log');
|
268 |
|
269 |
// Add log entries with different severities
|
270 |
-
SimpleLogger()->warning("User 'Jessie' deleted user 'Kim'");
|
271 |
-
SimpleLogger()->debug('Ok, cron job is running!');
|
272 |
|
273 |
// Add a message to the history log
|
274 |
// and then add a second log entry with same info and Simple History
|
275 |
// will make these two become an "occasionGroup",
|
276 |
// i.e. collapsing their entries into one expandable log item
|
277 |
-
SimpleLogger()->info('This is a message sent to the log');
|
278 |
-
SimpleLogger()->info('This is a message sent to the log');
|
279 |
|
280 |
// Log entries can have placeholders and context
|
281 |
// This makes log entried translatable and filterable
|
282 |
SimpleLogger()->notice(
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
);
|
293 |
|
294 |
// Log entried can have custom occasionsID
|
295 |
// This will group items together and a log entry will only be shown once
|
296 |
// in the log overview, even if the logged messages are different
|
297 |
-
for ($i = 0; $i < rand(1, 50); $i++) {
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
|
|
|
|
|
|
303 |
}
|
304 |
|
305 |
// Events can have different "initiators",
|
306 |
// i.e. who was responsible for the logged event
|
307 |
// Initiator "WORDPRESS" means that WordPress did something on it's own
|
308 |
SimpleLogger()->info(
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
);
|
316 |
|
317 |
// Initiator "WP_USER" means that a logged in user did someting
|
318 |
SimpleLogger()->info(
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
);
|
327 |
|
328 |
// // Initiator "WEB_USER" means that an unknown internet user did something
|
329 |
-
SimpleLogger()->warning(
|
330 |
-
|
331 |
-
|
|
|
|
|
|
|
332 |
|
333 |
|
334 |
// Use the "context array" to add more data to your logged event
|
335 |
// Data can be used later on to show detailed info about a log entry
|
336 |
// and does not need to be shown on the overview screen
|
337 |
-
SimpleLogger()->info(
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
|
|
|
|
|
|
345 |
|
346 |
|
347 |
// Test log cron things
|
@@ -352,31 +426,31 @@ wp_schedule_event( time(), "hourly", "simple_history_cron_testhook");
|
|
352 |
wp_clear_scheduled_hook("simple_history_cron_testhook");
|
353 |
add_action( 'simple_history_cron_testhook', 'simple_history_cron_testhook_function' );
|
354 |
function simple_history_cron_testhook_function() {
|
355 |
-
|
356 |
}
|
357 |
*/
|
358 |
|
359 |
/*
|
360 |
add_action("init", function() {
|
361 |
|
362 |
-
|
363 |
|
364 |
-
|
365 |
-
|
366 |
|
367 |
-
|
368 |
|
369 |
-
|
370 |
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
|
379 |
-
|
380 |
|
381 |
}, 100);
|
382 |
*/
|
@@ -385,7 +459,7 @@ add_action("init", function() {
|
|
385 |
/*
|
386 |
add_action("init", function() {
|
387 |
|
388 |
-
|
389 |
|
390 |
}, 100);
|
391 |
// */
|
14 |
*/
|
15 |
|
16 |
// Add $_GET, $_POST, and more info to each logged event.
|
17 |
+
define( 'SIMPLE_HISTORY_LOG_DEBUG', true );
|
18 |
|
19 |
|
20 |
/**
|
25 |
* Remove the "Clear log"-button, so a user with admin access can not clear the log
|
26 |
* and wipe their mischievous behavior from the log.
|
27 |
*/
|
28 |
+
add_filter(
|
29 |
+
'simple_history/user_can_clear_log',
|
30 |
+
function ( $user_can_clear_log ) {
|
31 |
+
$user_can_clear_log = false;
|
32 |
+
return $user_can_clear_log;
|
33 |
+
}
|
34 |
+
);
|
35 |
|
36 |
// Modify who can read a logger.
|
37 |
// Modify the if part to give users access or no access to a logger.
|
38 |
+
add_filter(
|
39 |
+
'simple_history/loggers_user_can_read/can_read_single_logger',
|
40 |
+
function ( $user_can_read_logger, $logger_instance, $user_id ) {
|
41 |
+
|
42 |
+
// in this example user with id 3 gets access to the post logger
|
43 |
+
// while user with id 8 does not get any access to it
|
44 |
+
if ( $logger_instance->slug == 'SimplePostLogger' && $user_id === 3 ) {
|
45 |
+
$user_can_read_logger = true;
|
46 |
+
} elseif ( $logger_instance->slug == 'SimplePostLogger' && $user_id === 9 ) {
|
47 |
+
$user_can_read_logger = false;
|
48 |
+
}
|
49 |
+
|
50 |
+
return $user_can_read_logger;
|
51 |
+
},
|
52 |
+
10,
|
53 |
+
3
|
54 |
+
);
|
55 |
|
56 |
|
57 |
// Do not log some post types, for example pages and attachments in this case
|
58 |
+
add_filter(
|
59 |
+
'simple_history/log/do_log',
|
60 |
+
function ( $do_log = null, $level = null, $message = null, $context = null, $logger = null ) {
|
61 |
+
|
62 |
+
$post_types_to_not_log = array(
|
63 |
+
'page',
|
64 |
+
'attachment',
|
65 |
+
);
|
66 |
+
|
67 |
+
if ( ( isset( $logger->slug ) && ( $logger->slug === 'SimplePostLogger' || $logger->slug === 'SimpleMediaLogger' ) ) && ( isset( $context['post_type'] ) && in_array( $context['post_type'], $post_types_to_not_log ) ) ) {
|
68 |
+
$do_log = false;
|
69 |
+
}
|
70 |
+
|
71 |
+
return $do_log;
|
72 |
+
},
|
73 |
+
10,
|
74 |
+
5
|
75 |
+
);
|
76 |
|
77 |
// Disable all logging
|
78 |
+
add_filter( 'simple_history/log/do_log', '__return_false' );
|
79 |
|
80 |
/**
|
81 |
* Example that modifies the parameters sent to the message template
|
82 |
* This example will change the post type from "post" or "page" or similar to "my own page type"
|
83 |
*/
|
84 |
+
add_filter(
|
85 |
+
'simple_history/logger/interpolate/context',
|
86 |
+
function ( $context, $message, $row ) {
|
87 |
+
|
88 |
+
if ( empty( $row ) ) {
|
89 |
+
return $context;
|
90 |
+
}
|
91 |
+
|
92 |
+
if ( $row->logger == 'SimplePostLogger' && $row->context_message_key == 'post_updated' ) {
|
93 |
+
$context['post_type'] = 'my own page type';
|
94 |
+
}
|
95 |
+
|
96 |
+
return $context;
|
97 |
+
},
|
98 |
+
10,
|
99 |
+
3
|
100 |
+
);
|
101 |
|
102 |
|
103 |
|
105 |
* Change capability required to manage the options page of simple history.
|
106 |
* Default capability is "manage_options"
|
107 |
*/
|
108 |
+
add_filter(
|
109 |
+
'simple_history/view_settings_capability',
|
110 |
+
function ( $capability ) {
|
111 |
|
112 |
+
$capability = 'manage_options';
|
113 |
+
return $capability;
|
114 |
+
}
|
115 |
+
);
|
116 |
|
117 |
|
118 |
/**
|
120 |
* Default capability is "edit_pages". Change to for example "manage options"
|
121 |
* to only allow admins to view the history log.
|
122 |
*/
|
123 |
+
add_filter(
|
124 |
+
'simple_history/view_history_capability',
|
125 |
+
function ( $capability ) {
|
126 |
|
127 |
+
$capability = 'manage_options';
|
128 |
+
return $capability;
|
129 |
+
}
|
130 |
+
);
|
131 |
|
132 |
|
133 |
// Skip adding things to the context table during logging.
|
134 |
// Useful if you don't want to add cool and possible super useful info to your logged events.
|
135 |
// Also nice to have if you want to make sure your database does not grow.
|
136 |
+
add_filter(
|
137 |
+
'simple_history/log_insert_context',
|
138 |
+
function ( $context, $data ) {
|
139 |
+
|
140 |
+
unset( $context['_user_id'] );
|
141 |
+
unset( $context['_user_login'] );
|
142 |
+
unset( $context['_user_email'] );
|
143 |
+
unset( $context['server_http_user_agent'] );
|
144 |
+
|
145 |
+
return $context;
|
146 |
+
},
|
147 |
+
10,
|
148 |
+
2
|
149 |
+
);
|
150 |
|
151 |
// Hide some columns from the detailed context view popup window
|
152 |
+
add_filter(
|
153 |
+
'simple_history/log_html_output_details_table/row_keys_to_show',
|
154 |
+
function ( $logRowKeysToShow, $oneLogRow ) {
|
155 |
+
|
156 |
+
$logRowKeysToShow['id'] = false;
|
157 |
+
$logRowKeysToShow['logger'] = false;
|
158 |
+
$logRowKeysToShow['level'] = false;
|
159 |
+
$logRowKeysToShow['message'] = false;
|
160 |
+
|
161 |
+
return $logRowKeysToShow;
|
162 |
+
},
|
163 |
+
10,
|
164 |
+
2
|
165 |
+
);
|
166 |
|
167 |
|
168 |
// Hide some more columns from the detailed context view popup window
|
169 |
+
add_filter(
|
170 |
+
'simple_history/log_html_output_details_table/context_keys_to_show',
|
171 |
+
function ( $logRowContextKeysToShow, $oneLogRow ) {
|
172 |
+
|
173 |
+
$logRowContextKeysToShow['plugin_slug'] = false;
|
174 |
+
$logRowContextKeysToShow['plugin_name'] = false;
|
175 |
+
$logRowContextKeysToShow['plugin_title'] = false;
|
176 |
+
$logRowContextKeysToShow['plugin_description'] = false;
|
177 |
+
|
178 |
+
return $logRowContextKeysToShow;
|
179 |
+
},
|
180 |
+
10,
|
181 |
+
2
|
182 |
+
);
|
183 |
|
184 |
|
185 |
|
186 |
// Allow only the users specified in $allowed_users to show the history page, the history widget on the dashboard, or the history settings page
|
187 |
+
add_filter( 'simple_history/show_dashboard_page', 'function_show_history_dashboard_or_page' );
|
188 |
+
add_filter( 'simple_history/show_dashboard_widget', 'function_show_history_dashboard_or_page' );
|
189 |
+
add_filter( 'simple_history/show_settings_page', 'function_show_history_dashboard_or_page' );
|
190 |
+
function function_show_history_dashboard_or_page( $show ) {
|
|
|
191 |
|
192 |
+
$allowed_users = array(
|
193 |
+
'user1@example.com',
|
194 |
+
'anotheruser@example.com',
|
195 |
+
);
|
196 |
|
197 |
+
$user = wp_get_current_user();
|
198 |
|
199 |
+
if ( ! in_array( $user->user_email, $allowed_users ) ) {
|
200 |
+
$show = false;
|
201 |
+
}
|
202 |
|
203 |
+
return $show;
|
204 |
}
|
205 |
|
206 |
|
207 |
// Skip loading of loggers
|
208 |
+
add_filter(
|
209 |
+
'simple_history/logger/load_logger',
|
210 |
+
function ( $load_logger, $oneLoggerFile ) {
|
211 |
+
|
212 |
+
// Don't load loggers for comments or menus, i.e. don't log changes to comments or to menus
|
213 |
+
if ( in_array( $oneLoggerFile, array( 'SimpleCommentsLogger', 'SimpleMenuLogger' ) ) ) {
|
214 |
+
$load_logger = false;
|
215 |
+
}
|
216 |
+
|
217 |
+
return $load_logger;
|
218 |
+
},
|
219 |
+
10,
|
220 |
+
2
|
221 |
+
);
|
222 |
|
223 |
/**
|
224 |
* Load only the loggers that are specified in the $do_log_us array
|
225 |
*/
|
226 |
+
add_filter(
|
227 |
+
'simple_history/logger/load_logger',
|
228 |
+
function ( $load_logger, $logger_basename ) {
|
229 |
|
230 |
+
$load_logger = false;
|
231 |
+
$do_log_us = array( 'SimplePostLogger', 'SimplePluginLogger', 'SimpleLogger' );
|
232 |
|
233 |
+
if ( in_array( $logger_basename, $do_log_us ) ) {
|
234 |
+
$load_logger = true;
|
235 |
+
}
|
236 |
|
237 |
+
return $load_logger;
|
238 |
+
},
|
239 |
+
10,
|
240 |
+
2
|
241 |
+
);
|
242 |
|
243 |
|
244 |
// Skip the loading of dropins
|
245 |
+
add_filter(
|
246 |
+
'simple_history/dropin/load_dropin',
|
247 |
+
function ( $load_dropin, $dropinFileBasename ) {
|
248 |
+
|
249 |
+
// Don't load the RSS feed dropin
|
250 |
+
if ( $dropinFileBasename == 'SimpleHistoryRSSDropin' ) {
|
251 |
+
$load_dropin = false;
|
252 |
+
}
|
253 |
+
|
254 |
+
// Don't load the dropin that polls for changes
|
255 |
+
if ( $dropinFileBasename == 'SimpleHistoryNewRowsNotifier' ) {
|
256 |
+
$load_dropin = false;
|
257 |
+
}
|
258 |
+
|
259 |
+
return $load_dropin;
|
260 |
+
},
|
261 |
+
10,
|
262 |
+
2
|
263 |
+
);
|
264 |
|
265 |
|
266 |
// Don't log failed logins
|
267 |
+
add_filter(
|
268 |
+
'simple_history/simple_logger/log_message_key',
|
269 |
+
function ( $doLog, $loggerSlug, $messageKey, $SimpleLoggerLogLevelsLevel, $context ) {
|
270 |
+
|
271 |
+
// Don't log login attempts to non existing users
|
272 |
+
if ( 'SimpleUserLogger' == $loggerSlug && 'user_unknown_login_failed' == $messageKey ) {
|
273 |
+
$doLog = false;
|
274 |
+
}
|
275 |
+
|
276 |
+
// Don't log failed logins to existing users
|
277 |
+
if ( 'SimpleUserLogger' == $loggerSlug && 'user_login_failed' == $messageKey ) {
|
278 |
+
$doLog = false;
|
279 |
+
}
|
280 |
+
|
281 |
+
return $doLog;
|
282 |
+
},
|
283 |
+
10,
|
284 |
+
5
|
285 |
+
);
|
286 |
|
287 |
// Never clear the log (default is 60 days)
|
288 |
+
add_filter( 'simple_history/db_purge_days_interval', '__return_zero' );
|
289 |
|
290 |
// Clear items that are older than a 7 days (i.e. keep only the most recent 7 days in the log)
|
291 |
+
add_filter(
|
292 |
+
'simple_history/db_purge_days_interval',
|
293 |
+
function ( $days ) {
|
294 |
|
295 |
+
$days = 7;
|
296 |
|
297 |
+
return $days;
|
298 |
+
}
|
299 |
+
);
|
300 |
|
301 |
// Don't let anyone - even with the correct secret - view the RSS feed
|
302 |
+
add_filter( 'simple_history/rss_feed_show', '__return_false' );
|
303 |
|
304 |
// Skip loading of a dropin completely (in this case the RSS dropin)
|
305 |
+
add_filter( 'simple_history/dropin/load_dropin_SimpleHistoryRSSDropin', '__return_false' );
|
306 |
|
307 |
/**
|
308 |
* Example of logging
|
309 |
*/
|
310 |
|
311 |
// This is the easiest and safest way to add messages to the log:
|
312 |
+
apply_filters( 'simple_history_log', 'This is a logged message' );
|
313 |
+
apply_filters(
|
314 |
+
'simple_history_log',
|
315 |
+
'This is a message with some context added',
|
316 |
+
array(
|
317 |
+
'isATestMessage' => 'yup',
|
318 |
+
'debugRequestData' => $_REQUEST,
|
319 |
+
)
|
320 |
+
);
|
321 |
+
apply_filters( 'simple_history_log', 'This is another logged message, with another severity level', null, 'debug' );
|
322 |
|
323 |
// Below is the function way of adding things to the log
|
324 |
// Remember to check that the SimpleLogger function exists before trying to log anything,
|
325 |
// or else your site will break if you disable the Simple History plugin
|
326 |
// (Use the apply_filters method above if you want to stay safer!)
|
327 |
+
if ( function_exists( 'SimpleLogger' ) ) {
|
328 |
+
SimpleLogger()->info( 'This is a message added to the log' );
|
329 |
}
|
330 |
|
331 |
// Add a message to the history log
|
332 |
+
SimpleLogger()->info( 'This is a message sent to the log' );
|
333 |
|
334 |
// Add log entries with different severities
|
335 |
+
SimpleLogger()->warning( "User 'Jessie' deleted user 'Kim'" );
|
336 |
+
SimpleLogger()->debug( 'Ok, cron job is running!' );
|
337 |
|
338 |
// Add a message to the history log
|
339 |
// and then add a second log entry with same info and Simple History
|
340 |
// will make these two become an "occasionGroup",
|
341 |
// i.e. collapsing their entries into one expandable log item
|
342 |
+
SimpleLogger()->info( 'This is a message sent to the log' );
|
343 |
+
SimpleLogger()->info( 'This is a message sent to the log' );
|
344 |
|
345 |
// Log entries can have placeholders and context
|
346 |
// This makes log entried translatable and filterable
|
347 |
SimpleLogger()->notice(
|
348 |
+
'User {username} edited page {pagename}',
|
349 |
+
array(
|
350 |
+
'username' => 'jessie',
|
351 |
+
'pagename' => 'My test page',
|
352 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
353 |
+
'_user_id' => 5,
|
354 |
+
'_user_login' => 'jess',
|
355 |
+
'_user_email' => 'jessie@example.com',
|
356 |
+
)
|
357 |
);
|
358 |
|
359 |
// Log entried can have custom occasionsID
|
360 |
// This will group items together and a log entry will only be shown once
|
361 |
// in the log overview, even if the logged messages are different
|
362 |
+
for ( $i = 0; $i < rand( 1, 50 ); $i++ ) {
|
363 |
+
SimpleLogger()->notice(
|
364 |
+
'User {username} edited page {pagename}',
|
365 |
+
array(
|
366 |
+
'username' => "example_user_{$i}",
|
367 |
+
'pagename' => 'My test page',
|
368 |
+
'_occasionsID' => 'postID:24884,action:edited',
|
369 |
+
)
|
370 |
+
);
|
371 |
}
|
372 |
|
373 |
// Events can have different "initiators",
|
374 |
// i.e. who was responsible for the logged event
|
375 |
// Initiator "WORDPRESS" means that WordPress did something on it's own
|
376 |
SimpleLogger()->info(
|
377 |
+
'WordPress updated itself from version {from_version} to {to_version}',
|
378 |
+
array(
|
379 |
+
'from_version' => '3.8',
|
380 |
+
'to_version' => '3.8.1',
|
381 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
382 |
+
)
|
383 |
);
|
384 |
|
385 |
// Initiator "WP_USER" means that a logged in user did someting
|
386 |
SimpleLogger()->info(
|
387 |
+
'Updated plugin {plugin_name} from version {plugin_from_version} to version {plugin_to_version}',
|
388 |
+
array(
|
389 |
+
'plugin_name' => 'Ninja Forms',
|
390 |
+
'plugin_from_version' => '1.1',
|
391 |
+
'plugin_to_version' => '1.1.2',
|
392 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
393 |
+
)
|
394 |
);
|
395 |
|
396 |
// // Initiator "WEB_USER" means that an unknown internet user did something
|
397 |
+
SimpleLogger()->warning(
|
398 |
+
"An attempt to login as user 'administrator' failed to login because the wrong password was entered",
|
399 |
+
array(
|
400 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
401 |
+
)
|
402 |
+
);
|
403 |
|
404 |
|
405 |
// Use the "context array" to add more data to your logged event
|
406 |
// Data can be used later on to show detailed info about a log entry
|
407 |
// and does not need to be shown on the overview screen
|
408 |
+
SimpleLogger()->info(
|
409 |
+
"Edited product '{pagename}'",
|
410 |
+
array(
|
411 |
+
'pagename' => 'We are hiring!',
|
412 |
+
'_postType' => 'product',
|
413 |
+
'_userID' => 1,
|
414 |
+
'_userLogin' => 'jessie',
|
415 |
+
'_userEmail' => 'jessie@example.com',
|
416 |
+
'_occasionsID' => 'username:1,postID:24885,action:edited',
|
417 |
+
)
|
418 |
+
);
|
419 |
|
420 |
|
421 |
// Test log cron things
|
426 |
wp_clear_scheduled_hook("simple_history_cron_testhook");
|
427 |
add_action( 'simple_history_cron_testhook', 'simple_history_cron_testhook_function' );
|
428 |
function simple_history_cron_testhook_function() {
|
429 |
+
SimpleLogger()->info("This is a message inside a cron function");
|
430 |
}
|
431 |
*/
|
432 |
|
433 |
/*
|
434 |
add_action("init", function() {
|
435 |
|
436 |
+
global $wp_current_filter;
|
437 |
|
438 |
+
$doing_cron = get_transient( 'doing_cron' );
|
439 |
+
$const_doing_cron = defined('DOING_CRON') && DOING_CRON;
|
440 |
|
441 |
+
if ($const_doing_cron) {
|
442 |
|
443 |
+
$current_filter = current_filter();
|
444 |
|
445 |
+
SimpleLogger()->info("This is a message inside init, trying to log crons", array(
|
446 |
+
"doing_cron" => simpleHistory::json_encode($doing_cron),
|
447 |
+
"current_filter" => $current_filter,
|
448 |
+
"wp_current_filter" => $wp_current_filter,
|
449 |
+
"wp_current_filter" => simpleHistory::json_encode( $wp_current_filter ),
|
450 |
+
"const_doing_cron" => simpleHistory::json_encode($const_doing_cron)
|
451 |
+
));
|
452 |
|
453 |
+
}
|
454 |
|
455 |
}, 100);
|
456 |
*/
|
459 |
/*
|
460 |
add_action("init", function() {
|
461 |
|
462 |
+
#SimpleLogger()->info("This is a regular info message" . time());
|
463 |
|
464 |
}, 100);
|
465 |
// */
|
inc/SimpleHistory.php
CHANGED
@@ -2,1509 +2,1478 @@
|
|
2 |
|
3 |
// phpcs:disable PSR12.Properties.ConstantVisibility.NotFound
|
4 |
|
5 |
-
defined('ABSPATH')
|
6 |
|
7 |
/**
|
8 |
* Main class for Simple History
|
9 |
*/
|
10 |
-
class SimpleHistory
|
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 |
-
public function filter_option_page_capability($capability)
|
1413 |
-
{
|
1414 |
-
return $capability;
|
1415 |
-
}
|
1416 |
-
|
1417 |
-
/**
|
1418 |
-
* Check if plugin version have changed, i.e. has been upgraded
|
1419 |
-
* If upgrade is detected then maybe modify database and so on for that version
|
1420 |
-
*/
|
1421 |
-
public function check_for_upgrade()
|
1422 |
-
{
|
1423 |
-
global $wpdb;
|
1424 |
-
|
1425 |
-
$db_version = get_option('simple_history_db_version');
|
1426 |
-
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
1427 |
-
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
1428 |
-
$first_install = false;
|
1429 |
-
|
1430 |
-
// If no db_version is set then this
|
1431 |
-
// is a version of Simple History < 0.4
|
1432 |
-
// or it's a first install
|
1433 |
-
// Fix database not using UTF-8
|
1434 |
-
if (false === $db_version || intval($db_version) == 0) {
|
1435 |
-
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1436 |
-
|
1437 |
-
// Table creation, used to be in register_activation_hook
|
1438 |
-
// We change the varchar size to add one num just to force update of encoding. dbdelta didn't see it otherwise.
|
1439 |
-
$sql =
|
1440 |
-
'CREATE TABLE ' .
|
1441 |
-
$table_name .
|
1442 |
-
' (
|
1443 |
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1444 |
date datetime NOT NULL,
|
1445 |
PRIMARY KEY (id)
|
1446 |
) CHARACTER SET=utf8;';
|
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 |
CREATE TABLE {$table_name} (
|
1509 |
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1510 |
date datetime NOT NULL,
|
@@ -1518,10 +1487,10 @@ class SimpleHistory
|
|
1518 |
KEY loggerdate (logger,date)
|
1519 |
) CHARSET=utf8;";
|
1520 |
|
1521 |
-
|
1522 |
|
1523 |
-
|
1524 |
-
|
1525 |
CREATE TABLE IF NOT EXISTS {$table_name_contexts} (
|
1526 |
context_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
1527 |
history_id bigint(20) unsigned NOT NULL,
|
@@ -1533,49 +1502,51 @@ class SimpleHistory
|
|
1533 |
) CHARSET=utf8;
|
1534 |
";
|
1535 |
|
1536 |
-
|
|
|
1537 |
|
1538 |
-
|
1539 |
-
|
1540 |
-
update_option('simple_history_db_version', $db_version);
|
1541 |
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
UPDATE %1$s
|
1546 |
SET
|
1547 |
-
logger = "
|
1548 |
level = "info"
|
1549 |
WHERE logger IS NULL
|
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 |
ALTER TABLE %1$s
|
1580 |
MODIFY `action` varchar(255) NULL,
|
1581 |
MODIFY `object_type` varchar(255) NULL,
|
@@ -1584,1045 +1555,1045 @@ class SimpleHistory
|
|
1584 |
MODIFY `object_id` int(10) NULL,
|
1585 |
MODIFY `object_name` varchar(255) NULL
|
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 |
-
|
1662 |
-
|
1663 |
-
|
1664 |
-
if (!$db_data_exists) {
|
1665 |
-
$welcome_message_1 = __(
|
1666 |
-
'
|
1667 |
Welcome to Simple History!
|
1668 |
|
1669 |
This is the main history feed. It will contain events that this plugin has logged.
|
1670 |
',
|
1671 |
-
|
1672 |
-
|
1673 |
|
1674 |
-
|
1675 |
-
|
1676 |
Because Simple History was only recently installed, this feed does not display many events yet. As long as the plugin remains activated you will soon see detailed information about page edits, plugin updates, users logging in, and much more.
|
1677 |
',
|
1678 |
-
|
1679 |
-
|
1680 |
-
|
1681 |
-
|
1682 |
-
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
|
1687 |
-
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
|
1693 |
-
|
1694 |
-
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
1699 |
-
|
1700 |
-
|
1701 |
-
|
1702 |
-
|
1703 |
-
|
1704 |
-
|
1705 |
-
|
1706 |
-
|
1707 |
-
|
1708 |
-
|
1709 |
-
|
1710 |
-
|
1711 |
-
|
1712 |
-
|
1713 |
-
|
1714 |
-
|
1715 |
-
|
1716 |
-
|
1717 |
-
|
1718 |
-
|
1719 |
-
|
1720 |
-
|
1721 |
-
|
1722 |
-
|
1723 |
-
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
1727 |
-
|
1728 |
-
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
|
1751 |
-
|
1752 |
-
|
1753 |
-
|
1754 |
-
|
1755 |
-
|
1756 |
-
|
1757 |
-
|
1758 |
-
|
1759 |
-
|
1760 |
-
|
1761 |
-
|
1762 |
-
|
1763 |
-
|
1764 |
-
|
1765 |
-
|
1766 |
-
|
1767 |
-
|
1768 |
-
|
1769 |
-
|
1770 |
-
|
1771 |
-
|
1772 |
-
|
1773 |
-
|
1774 |
-
|
1775 |
-
|
1776 |
-
|
1777 |
-
|
1778 |
-
|
1779 |
-
|
1780 |
-
|
1781 |
-
|
1782 |
-
|
1783 |
-
|
1784 |
-
|
1785 |
-
|
1786 |
-
|
1787 |
-
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
1791 |
-
|
1792 |
-
|
1793 |
-
|
1794 |
-
|
1795 |
-
|
1796 |
-
|
1797 |
-
|
1798 |
-
|
1799 |
-
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
|
1811 |
-
|
1812 |
-
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
|
1825 |
-
|
1826 |
-
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
-
|
1831 |
-
|
1832 |
-
|
1833 |
-
|
1834 |
-
|
1835 |
-
|
1836 |
-
|
1837 |
-
|
1838 |
-
|
1839 |
-
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
|
1846 |
-
|
1847 |
-
|
1848 |
-
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
|
1856 |
-
|
1857 |
-
|
1858 |
-
|
1859 |
-
|
1860 |
-
|
1861 |
-
|
1862 |
-
|
1863 |
-
|
1864 |
-
|
1865 |
-
|
1866 |
-
|
1867 |
-
|
1868 |
-
|
1869 |
-
|
1870 |
-
|
1871 |
-
|
1872 |
-
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
1877 |
-
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
1882 |
-
|
1883 |
-
|
1884 |
-
|
1885 |
-
|
1886 |
-
|
1887 |
-
|
1888 |
-
|
1889 |
-
|
1890 |
-
|
1891 |
-
|
1892 |
-
|
1893 |
-
|
1894 |
-
|
1895 |
-
|
1896 |
-
|
1897 |
-
|
1898 |
-
|
1899 |
-
|
1900 |
-
|
1901 |
-
|
1902 |
-
|
1903 |
-
|
1904 |
-
|
1905 |
-
|
1906 |
-
|
1907 |
-
|
1908 |
-
|
1909 |
-
|
1910 |
-
|
1911 |
-
|
1912 |
-
|
1913 |
-
|
1914 |
-
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
|
1920 |
-
|
1921 |
-
|
1922 |
-
|
1923 |
-
|
1924 |
-
|
1925 |
-
|
1926 |
-
|
1927 |
-
|
1928 |
-
|
1929 |
-
|
1930 |
-
|
1931 |
-
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
|
1936 |
-
|
1937 |
-
|
1938 |
-
|
1939 |
-
|
1940 |
-
|
1941 |
-
|
1942 |
-
|
1943 |
-
|
1944 |
-
|
1945 |
-
|
1946 |
-
|
1947 |
-
|
1948 |
-
|
1949 |
-
|
1950 |
-
|
1951 |
-
|
1952 |
-
|
1953 |
-
|
1954 |
-
|
1955 |
-
|
1956 |
-
|
1957 |
-
|
1958 |
-
|
1959 |
-
|
1960 |
-
|
1961 |
-
|
1962 |
-
|
1963 |
-
|
1964 |
-
|
1965 |
-
|
1966 |
-
|
1967 |
-
|
1968 |
-
|
1969 |
-
|
1970 |
-
|
1971 |
-
|
1972 |
-
|
1973 |
-
|
1974 |
-
|
1975 |
-
|
1976 |
-
|
1977 |
-
|
1978 |
-
|
1979 |
-
|
1980 |
-
|
1981 |
-
|
1982 |
-
|
1983 |
-
|
1984 |
-
|
1985 |
-
|
1986 |
-
|
1987 |
-
|
1988 |
-
|
1989 |
-
|
1990 |
-
|
1991 |
-
|
1992 |
-
|
1993 |
-
|
1994 |
-
|
1995 |
-
|
1996 |
-
|
1997 |
-
|
1998 |
-
|
1999 |
-
|
2000 |
-
|
2001 |
-
|
2002 |
-
|
2003 |
-
|
2004 |
-
|
2005 |
-
|
2006 |
-
|
2007 |
-
|
2008 |
-
|
2009 |
-
|
2010 |
-
|
2011 |
-
|
2012 |
-
|
2013 |
-
|
2014 |
-
|
2015 |
-
|
2016 |
-
|
2017 |
-
|
2018 |
-
|
2019 |
-
|
2020 |
-
|
2021 |
-
|
2022 |
-
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
|
2027 |
-
|
2028 |
-
|
2029 |
-
|
2030 |
-
|
2031 |
-
|
2032 |
-
|
2033 |
-
|
2034 |
-
|
2035 |
-
|
2036 |
-
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
-
|
2043 |
-
|
2044 |
-
|
2045 |
-
|
2046 |
-
|
2047 |
-
|
2048 |
-
|
2049 |
-
|
2050 |
-
|
2051 |
-
|
2052 |
-
|
2053 |
-
|
2054 |
-
|
2055 |
-
|
2056 |
-
|
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 |
-
|
2358 |
-
|
2359 |
-
|
2360 |
-
|
2361 |
-
|
2362 |
-
|
2363 |
-
|
2364 |
-
|
2365 |
-
|
2366 |
-
|
2367 |
-
|
2368 |
-
|
2369 |
-
|
2370 |
-
|
2371 |
-
|
2372 |
-
|
2373 |
-
|
2374 |
-
|
2375 |
-
|
2376 |
-
|
2377 |
-
|
2378 |
-
|
2379 |
-
|
2380 |
-
|
2381 |
-
|
2382 |
-
|
2383 |
-
|
2384 |
-
|
2385 |
-
|
2386 |
-
|
2387 |
-
|
2388 |
-
|
2389 |
-
|
2390 |
-
|
2391 |
-
|
2392 |
-
|
2393 |
-
|
2394 |
-
|
2395 |
-
|
2396 |
-
|
2397 |
-
|
2398 |
-
|
2399 |
-
|
2400 |
-
|
2401 |
-
|
2402 |
-
|
2403 |
-
|
2404 |
-
|
2405 |
-
|
2406 |
-
|
2407 |
-
|
2408 |
-
|
2409 |
-
|
2410 |
-
|
2411 |
-
|
2412 |
-
|
2413 |
-
|
2414 |
-
|
2415 |
-
|
2416 |
-
|
2417 |
-
|
2418 |
-
|
2419 |
-
|
2420 |
-
|
2421 |
-
|
2422 |
-
|
2423 |
-
|
2424 |
-
|
2425 |
-
|
2426 |
-
|
2427 |
-
|
2428 |
-
|
2429 |
-
|
2430 |
-
|
2431 |
-
|
2432 |
-
|
2433 |
-
|
2434 |
-
|
2435 |
-
|
2436 |
-
|
2437 |
-
|
2438 |
-
|
2439 |
-
|
2440 |
-
|
2441 |
-
|
2442 |
-
|
2443 |
-
|
2444 |
-
|
2445 |
-
|
2446 |
-
|
2447 |
-
|
2448 |
-
|
2449 |
-
|
2450 |
-
|
2451 |
-
|
2452 |
-
|
2453 |
-
|
2454 |
-
|
2455 |
-
|
2456 |
-
|
2457 |
-
|
2458 |
-
|
2459 |
-
|
2460 |
-
|
2461 |
-
|
2462 |
-
|
|
|
|
|
|
|
2463 |
<th>%1$s</th>
|
2464 |
<th>%2$s</th>
|
2465 |
</tr>',
|
2466 |
-
|
2467 |
-
|
2468 |
-
|
2469 |
-
|
2470 |
-
|
2471 |
-
|
2472 |
-
|
2473 |
-
|
2474 |
-
|
2475 |
-
|
2476 |
-
|
2477 |
-
|
2478 |
-
|
2479 |
-
|
2480 |
-
|
2481 |
-
|
2482 |
-
|
2483 |
-
|
2484 |
-
|
2485 |
-
|
2486 |
-
|
2487 |
-
|
2488 |
-
|
2489 |
-
|
2490 |
-
|
2491 |
-
|
2492 |
-
|
2493 |
-
|
2494 |
-
|
2495 |
-
|
2496 |
-
|
2497 |
-
|
2498 |
-
|
2499 |
-
|
2500 |
-
|
2501 |
-
|
2502 |
-
|
2503 |
-
|
2504 |
-
|
2505 |
-
|
2506 |
-
|
2507 |
-
|
2508 |
-
|
2509 |
-
|
2510 |
-
|
2511 |
-
|
2512 |
-
|
2513 |
-
|
2514 |
-
|
2515 |
-
|
2516 |
-
|
2517 |
-
|
2518 |
-
|
2519 |
-
|
2520 |
<td>%1$s</td>
|
2521 |
<td>%2$s</td>
|
2522 |
</tr>',
|
2523 |
-
|
2524 |
-
|
2525 |
-
|
2526 |
-
|
2527 |
-
|
2528 |
-
|
2529 |
-
|
2530 |
-
|
2531 |
-
|
2532 |
-
|
2533 |
-
|
2534 |
-
|
2535 |
-
|
2536 |
-
|
2537 |
-
|
2538 |
-
|
2539 |
-
|
2540 |
-
|
2541 |
-
|
2542 |
-
|
2543 |
-
|
2544 |
-
|
2545 |
-
|
2546 |
-
|
2547 |
-
|
2548 |
-
|
2549 |
-
|
2550 |
-
|
2551 |
-
|
2552 |
-
|
2553 |
-
|
2554 |
-
|
2555 |
-
|
2556 |
-
|
2557 |
-
|
2558 |
-
|
2559 |
-
|
2560 |
-
|
2561 |
-
|
2562 |
-
|
2563 |
-
|
2564 |
-
|
2565 |
-
|
2566 |
-
|
2567 |
-
|
2568 |
<td>%1$s</td>
|
2569 |
<td>%2$s</td>
|
2570 |
</tr>',
|
2571 |
-
|
2572 |
-
|
2573 |
-
|
2574 |
-
|
2575 |
-
|
2576 |
-
|
2577 |
-
|
2578 |
-
|
2579 |
-
|
2580 |
-
|
2581 |
-
|
2582 |
-
|
2583 |
-
|
2584 |
-
|
2585 |
-
|
2586 |
-
|
2587 |
-
|
2588 |
-
|
2589 |
-
|
2590 |
-
|
2591 |
-
|
2592 |
-
|
2593 |
-
|
2594 |
-
|
2595 |
-
|
2596 |
-
|
2597 |
-
|
2598 |
-
|
2599 |
-
|
2600 |
-
|
2601 |
-
|
2602 |
-
|
2603 |
-
|
2604 |
-
|
2605 |
-
|
2606 |
-
|
2607 |
-
|
2608 |
-
|
2609 |
-
|
2610 |
-
|
2611 |
-
|
2612 |
-
|
2613 |
-
|
2614 |
-
|
2615 |
-
|
2616 |
-
|
2617 |
-
|
2618 |
-
|
2619 |
-
|
2620 |
-
|
2621 |
-
|
2622 |
-
|
2623 |
-
|
2624 |
-
|
2625 |
-
|
2626 |
<li %8$s class="%10$s">
|
2627 |
<div class="SimpleHistoryLogitem__firstcol">
|
2628 |
<div class="SimpleHistoryLogitem__senderImage">%3$s</div>
|
@@ -2636,344 +2607,338 @@ Because Simple History was only recently installed, this feed does not display m
|
|
2636 |
</div>
|
2637 |
</li>
|
2638 |
',
|
2639 |
-
|
2640 |
-
|
2641 |
-
|
2642 |
-
|
2643 |
-
|
2644 |
-
|
2645 |
-
|
2646 |
-
|
2647 |
-
|
2648 |
-
|
2649 |
-
|
2650 |
-
|
2651 |
-
|
2652 |
-
|
2653 |
-
|
2654 |
-
|
2655 |
-
|
2656 |
-
|
2657 |
-
|
2658 |
-
|
2659 |
-
|
2660 |
-
|
2661 |
-
|
2662 |
-
|
2663 |
-
|
2664 |
-
|
2665 |
-
|
2666 |
-
|
2667 |
-
|
2668 |
-
|
2669 |
-
|
2670 |
-
|
2671 |
-
|
2672 |
-
|
2673 |
-
|
2674 |
-
|
2675 |
-
|
2676 |
-
|
2677 |
-
|
2678 |
-
|
2679 |
-
|
2680 |
-
|
2681 |
-
|
2682 |
-
|
2683 |
-
|
2684 |
-
|
2685 |
-
|
2686 |
-
|
2687 |
-
|
2688 |
-
|
2689 |
-
|
2690 |
-
|
2691 |
-
|
2692 |
-
|
2693 |
-
|
2694 |
-
|
2695 |
-
|
2696 |
-
|
2697 |
-
|
2698 |
-
|
2699 |
-
|
2700 |
-
|
2701 |
-
|
2702 |
-
|
2703 |
-
|
2704 |
-
|
2705 |
-
|
2706 |
-
|
2707 |
-
|
2708 |
-
|
2709 |
-
|
2710 |
-
|
2711 |
-
|
2712 |
-
|
2713 |
-
|
2714 |
-
|
2715 |
-
|
2716 |
-
|
2717 |
-
|
2718 |
-
|
2719 |
-
|
2720 |
-
|
2721 |
-
|
2722 |
-
|
2723 |
-
|
2724 |
-
|
2725 |
-
|
2726 |
-
|
2727 |
-
|
2728 |
-
|
2729 |
-
|
2730 |
-
|
2731 |
-
|
2732 |
-
|
2733 |
-
|
2734 |
-
|
2735 |
-
|
2736 |
-
|
2737 |
-
|
2738 |
-
|
2739 |
-
|
2740 |
-
|
2741 |
-
|
2742 |
-
|
2743 |
-
|
2744 |
-
|
2745 |
-
|
2746 |
-
|
2747 |
-
|
2748 |
-
|
2749 |
-
|
2750 |
-
|
2751 |
-
|
2752 |
-
|
2753 |
-
|
2754 |
-
|
2755 |
-
|
2756 |
-
|
2757 |
-
|
2758 |
-
|
2759 |
-
|
2760 |
-
|
2761 |
-
|
2762 |
-
|
2763 |
-
|
2764 |
-
|
2765 |
-
|
2766 |
-
|
2767 |
-
|
2768 |
-
|
2769 |
-
|
2770 |
-
|
2771 |
-
|
2772 |
-
|
2773 |
-
|
2774 |
-
|
2775 |
-
|
2776 |
-
|
2777 |
-
|
2778 |
-
|
2779 |
-
|
2780 |
-
|
2781 |
-
|
2782 |
-
|
2783 |
-
|
2784 |
-
|
2785 |
-
|
2786 |
-
|
2787 |
-
|
2788 |
-
|
2789 |
-
|
2790 |
-
|
2791 |
-
|
2792 |
-
|
2793 |
-
|
2794 |
-
|
2795 |
-
|
2796 |
-
|
2797 |
-
|
2798 |
-
|
2799 |
-
|
2800 |
-
|
2801 |
-
|
2802 |
-
|
2803 |
-
|
2804 |
-
|
2805 |
-
|
2806 |
-
|
2807 |
-
|
2808 |
-
|
2809 |
-
|
2810 |
-
|
2811 |
-
|
2812 |
-
|
2813 |
-
|
2814 |
-
|
2815 |
-
|
2816 |
-
|
2817 |
-
|
2818 |
-
|
2819 |
-
|
2820 |
-
|
2821 |
-
|
2822 |
-
|
2823 |
-
|
2824 |
-
|
2825 |
-
|
2826 |
-
|
2827 |
-
|
2828 |
-
|
2829 |
-
|
2830 |
-
|
2831 |
-
|
2832 |
-
|
2833 |
-
|
2834 |
-
|
2835 |
-
|
2836 |
-
|
2837 |
-
|
2838 |
-
|
2839 |
-
|
2840 |
-
|
2841 |
-
|
2842 |
-
|
2843 |
-
|
2844 |
-
|
2845 |
-
|
2846 |
-
|
2847 |
-
|
2848 |
-
|
2849 |
-
|
2850 |
-
|
2851 |
-
|
2852 |
-
|
2853 |
-
|
2854 |
-
|
2855 |
-
|
2856 |
-
|
2857 |
-
|
2858 |
-
|
2859 |
-
|
2860 |
-
|
2861 |
-
|
2862 |
-
|
2863 |
-
|
2864 |
-
|
2865 |
-
|
2866 |
-
|
2867 |
-
|
2868 |
-
|
2869 |
-
|
2870 |
-
|
2871 |
-
|
2872 |
-
|
2873 |
-
|
2874 |
-
|
2875 |
-
|
2876 |
-
|
2877 |
-
|
2878 |
-
|
2879 |
-
|
2880 |
-
|
2881 |
-
|
2882 |
-
|
2883 |
-
|
2884 |
-
|
2885 |
-
|
2886 |
-
|
2887 |
-
|
2888 |
-
|
2889 |
-
|
2890 |
-
|
2891 |
-
|
2892 |
-
|
2893 |
-
|
2894 |
-
|
2895 |
-
|
2896 |
-
|
2897 |
-
|
2898 |
-
|
2899 |
-
|
2900 |
-
|
2901 |
-
|
2902 |
-
|
2903 |
-
|
2904 |
-
|
2905 |
-
|
2906 |
-
|
2907 |
-
|
2908 |
-
|
2909 |
-
|
2910 |
-
|
2911 |
-
|
2912 |
-
|
2913 |
-
|
2914 |
-
|
2915 |
-
|
2916 |
-
|
2917 |
-
|
2918 |
-
|
2919 |
-
|
2920 |
-
|
2921 |
-
|
2922 |
-
|
2923 |
-
|
2924 |
-
|
2925 |
-
|
2926 |
-
|
2927 |
-
|
2928 |
-
|
2929 |
-
|
2930 |
-
|
2931 |
-
|
2932 |
-
|
2933 |
-
|
2934 |
-
|
2935 |
-
|
2936 |
-
|
2937 |
-
|
2938 |
-
|
2939 |
-
|
2940 |
-
|
2941 |
-
|
2942 |
-
|
2943 |
-
|
2944 |
-
|
2945 |
-
|
2946 |
-
|
2947 |
-
|
2948 |
-
|
2949 |
-
|
2950 |
-
|
2951 |
-
|
2952 |
-
|
2953 |
-
|
2954 |
-
|
2955 |
-
|
2956 |
-
|
2957 |
-
|
2958 |
-
|
2959 |
-
|
2960 |
-
|
2961 |
-
|
2962 |
-
|
2963 |
-
|
2964 |
-
|
2965 |
-
|
2966 |
-
|
2967 |
-
|
2968 |
-
|
2969 |
-
$sql_loggers_in = $this->getLoggersThatUserCanRead(get_current_user_id(), 'sql');
|
2970 |
-
|
2971 |
-
// Get number of users today, i.e. events with wp_user as initiator
|
2972 |
-
$sql_users_today = sprintf(
|
2973 |
-
'
|
2974 |
SELECT
|
2975 |
DISTINCT(c.value) AS user_id
|
2976 |
-
#h.id, h.logger, h.level, h.initiator, h.date
|
2977 |
FROM %3$s AS h
|
2978 |
INNER JOIN %4$s AS c
|
2979 |
ON c.history_id = h.id AND c.key = "_user_id"
|
@@ -2982,226 +2947,208 @@ Because Simple History was only recently installed, this feed does not display m
|
|
2982 |
AND logger IN %1$s
|
2983 |
AND date > "%2$s"
|
2984 |
',
|
2985 |
-
|
2986 |
-
|
2987 |
-
|
2988 |
-
|
2989 |
-
|
2990 |
-
|
2991 |
-
|
2992 |
-
|
2993 |
-
|
2994 |
-
|
2995 |
-
|
2996 |
-
|
2997 |
-
|
2998 |
-
|
2999 |
-
|
3000 |
-
|
3001 |
-
|
3002 |
-
|
3003 |
-
|
3004 |
-
|
3005 |
initiator <> "wp_user"
|
3006 |
AND logger IN %1$s
|
3007 |
AND date > "%2$s"
|
3008 |
',
|
3009 |
-
|
3010 |
-
|
3011 |
-
|
3012 |
-
|
3013 |
-
|
3014 |
|
3015 |
-
|
3016 |
|
3017 |
-
|
3018 |
-
|
3019 |
SELECT
|
3020 |
DISTINCT(h.initiator) AS initiator
|
3021 |
FROM %3$s AS h
|
3022 |
WHERE
|
3023 |
%5$s
|
3024 |
',
|
3025 |
-
|
3026 |
-
|
3027 |
-
|
3028 |
-
|
3029 |
-
|
3030 |
-
|
3031 |
-
|
3032 |
-
|
3033 |
-
|
3034 |
-
|
3035 |
-
|
3036 |
-
|
3037 |
-
|
3038 |
-
|
3039 |
-
|
3040 |
-
|
3041 |
-
|
3042 |
-
|
3043 |
-
|
3044 |
-
|
3045 |
-
|
3046 |
-
|
3047 |
-
|
3048 |
-
|
3049 |
-
|
3050 |
-
|
3051 |
-
|
3052 |
-
|
3053 |
-
|
3054 |
-
|
3055 |
-
|
3056 |
-
|
3057 |
-
|
3058 |
-
|
3059 |
-
|
3060 |
-
|
3061 |
-
|
3062 |
-
|
3063 |
-
|
3064 |
-
|
3065 |
-
|
3066 |
-
|
3067 |
-
|
3068 |
-
|
3069 |
-
|
3070 |
-
|
3071 |
-
|
3072 |
-
|
3073 |
-
|
3074 |
-
|
3075 |
-
|
3076 |
-
|
3077 |
-
|
3078 |
-
|
3079 |
-
|
3080 |
-
|
3081 |
-
|
3082 |
-
|
3083 |
-
|
3084 |
-
|
3085 |
-
|
3086 |
-
|
3087 |
-
|
3088 |
-
|
3089 |
-
|
3090 |
-
|
3091 |
-
|
3092 |
-
|
3093 |
-
|
3094 |
-
|
3095 |
-
|
3096 |
-
|
3097 |
-
|
3098 |
-
|
3099 |
-
|
3100 |
-
|
3101 |
-
|
3102 |
-
|
3103 |
-
|
3104 |
-
|
3105 |
-
|
3106 |
-
|
3107 |
-
|
3108 |
-
|
3109 |
-
|
3110 |
-
|
3111 |
-
|
3112 |
-
|
3113 |
-
|
3114 |
-
|
3115 |
-
|
3116 |
-
|
3117 |
-
|
3118 |
-
|
3119 |
-
|
3120 |
-
|
3121 |
-
|
3122 |
-
|
3123 |
-
|
3124 |
-
|
3125 |
-
|
3126 |
-
|
3127 |
-
|
3128 |
-
|
3129 |
-
|
3130 |
-
|
3131 |
-
|
3132 |
-
|
3133 |
-
|
3134 |
-
|
3135 |
-
|
3136 |
-
|
3137 |
-
|
3138 |
-
|
3139 |
-
|
3140 |
-
|
3141 |
-
|
3142 |
-
|
3143 |
-
|
3144 |
-
|
3145 |
-
|
3146 |
-
|
3147 |
-
|
3148 |
-
|
3149 |
-
|
3150 |
-
|
3151 |
-
|
3152 |
-
|
3153 |
-
|
3154 |
-
|
3155 |
-
|
3156 |
-
|
3157 |
-
|
3158 |
-
}
|
3159 |
-
|
3160 |
-
// Number of rows the last n days
|
3161 |
-
public function get_num_events_last_n_days($period_days = 28)
|
3162 |
-
{
|
3163 |
-
$transient_key = 'sh_' . md5(__METHOD__ . $period_days . '_2');
|
3164 |
-
|
3165 |
-
$count = get_transient($transient_key);
|
3166 |
-
|
3167 |
-
if (false === $count) {
|
3168 |
-
global $wpdb;
|
3169 |
-
|
3170 |
-
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead(null, 'sql');
|
3171 |
-
|
3172 |
-
$sql = sprintf(
|
3173 |
-
'
|
3174 |
SELECT count(*)
|
3175 |
FROM %1$s
|
3176 |
WHERE UNIX_TIMESTAMP(date) >= %2$d
|
3177 |
AND logger IN %3$s
|
3178 |
',
|
3179 |
-
|
3180 |
-
|
3181 |
-
|
3182 |
-
|
3183 |
|
3184 |
-
|
3185 |
|
3186 |
-
|
3187 |
-
|
3188 |
|
3189 |
-
|
3190 |
-
|
3191 |
|
3192 |
-
|
3193 |
-
|
3194 |
-
|
3195 |
|
3196 |
-
|
|
|
3197 |
|
3198 |
-
|
3199 |
-
global $wpdb;
|
3200 |
|
3201 |
-
|
3202 |
-
|
3203 |
-
$sql = sprintf(
|
3204 |
-
'
|
3205 |
SELECT
|
3206 |
date_format(date, "%%Y-%%m-%%d") AS yearDate,
|
3207 |
count(date) AS count
|
@@ -3213,66 +3160,67 @@ Because Simple History was only recently installed, this feed does not display m
|
|
3213 |
GROUP BY yearDate
|
3214 |
ORDER BY yearDate ASC
|
3215 |
',
|
3216 |
-
|
3217 |
-
|
3218 |
-
|
3219 |
-
|
3220 |
-
|
3221 |
-
|
3222 |
-
|
3223 |
-
|
3224 |
-
|
3225 |
-
|
3226 |
-
|
3227 |
-
|
3228 |
-
|
3229 |
-
|
3230 |
-
|
3231 |
-
|
3232 |
-
|
3233 |
-
|
3234 |
-
|
3235 |
-
|
3236 |
-
|
3237 |
-
|
3238 |
-
|
3239 |
-
|
3240 |
-
|
3241 |
-
|
3242 |
-
|
3243 |
-
|
3244 |
-
|
3245 |
-
|
3246 |
-
$sql = $wpdb->prepare(
|
3247 |
-
"
|
3248 |
SELECT count( DISTINCT occasionsID )
|
3249 |
FROM $table_name
|
3250 |
WHERE date >= DATE_ADD(CURDATE(), INTERVAL -%d DAY)
|
3251 |
-
|
3252 |
-
|
3253 |
-
|
3254 |
-
|
3255 |
-
|
3256 |
-
|
3257 |
-
|
3258 |
-
|
3259 |
-
|
3260 |
-
|
3261 |
-
|
3262 |
-
|
3263 |
-
|
3264 |
-
|
3265 |
-
|
3266 |
-
|
3267 |
-
|
3268 |
-
|
3269 |
-
|
3270 |
-
|
3271 |
-
|
3272 |
-
|
3273 |
-
|
3274 |
-
|
3275 |
-
|
3276 |
-
|
3277 |
-
|
|
|
|
|
|
|
3278 |
}
|
2 |
|
3 |
// phpcs:disable PSR12.Properties.ConstantVisibility.NotFound
|
4 |
|
5 |
+
defined( 'ABSPATH' ) || die();
|
6 |
|
7 |
/**
|
8 |
* Main class for Simple History
|
9 |
*/
|
10 |
+
class SimpleHistory {
|
11 |
+
|
12 |
+
const NAME = 'Simple History';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* For singleton
|
16 |
+
*/
|
17 |
+
private static $instance;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Array with external loggers to load
|
21 |
+
*/
|
22 |
+
private $externalLoggers;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Array with external dropins to load
|
26 |
+
*/
|
27 |
+
private $externalDropins;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Array with all instantiated loggers
|
31 |
+
*/
|
32 |
+
private $instantiatedLoggers;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Array with all instantiated dropins
|
36 |
+
*/
|
37 |
+
private $instantiatedDropins;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Bool if gettext filter function should be active
|
41 |
+
* Should only be active during the load of a logger
|
42 |
+
*/
|
43 |
+
private $doFilterGettext = false;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Used by gettext filter to temporarily store current logger
|
47 |
+
*/
|
48 |
+
private $doFilterGettext_currentLogger = null;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Used to store latest translations used by __()
|
52 |
+
* Required to automagically determine orginal text and text domain
|
53 |
+
* for calls like this `SimpleLogger()->log( __("My translated message") );`
|
54 |
+
*/
|
55 |
+
public $gettextLatestTranslations = array();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* All registered settings tabs
|
59 |
+
*/
|
60 |
+
private $arr_settings_tabs = array();
|
61 |
+
|
62 |
+
const DBTABLE = 'simple_history';
|
63 |
+
const DBTABLE_CONTEXTS = 'simple_history_contexts';
|
64 |
+
|
65 |
+
/** Slug for the settings menu */
|
66 |
+
const SETTINGS_MENU_SLUG = 'simple_history_settings_menu_slug';
|
67 |
+
|
68 |
+
/** Slug for the settings menu */
|
69 |
+
const SETTINGS_GENERAL_OPTION_GROUP = 'simple_history_settings_group';
|
70 |
+
|
71 |
+
/** ID for the general settings section */
|
72 |
+
const SETTINGS_SECTION_GENERAL_ID = 'simple_history_settings_section_general';
|
73 |
+
|
74 |
+
public function __construct() {
|
75 |
+
$this->init();
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* @since 2.5.2
|
80 |
+
*/
|
81 |
+
public function init() {
|
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 |
+
SimpleLogger()->log( $level, $message, $context );
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_emergency'.
|
180 |
+
*
|
181 |
+
* @param string $message The message to log.
|
182 |
+
* @param array $context The context (optional).
|
183 |
+
*/
|
184 |
+
public function on_filter_simple_history_log_emergency( $message = null, $context = null ) {
|
185 |
+
SimpleLogger()->log( 'emergency', $message, $context );
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_alert'.
|
190 |
+
*
|
191 |
+
* @param string $message The message to log.
|
192 |
+
* @param array $context The context (optional).
|
193 |
+
*/
|
194 |
+
public function on_filter_simple_history_log_alert( $message = null, $context = null ) {
|
195 |
+
SimpleLogger()->log( 'alert', $message, $context );
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_critical'.
|
200 |
+
*
|
201 |
+
* @param string $message The message to log.
|
202 |
+
* @param array $context The context (optional).
|
203 |
+
*/
|
204 |
+
public function on_filter_simple_history_log_critical( $message = null, $context = null ) {
|
205 |
+
SimpleLogger()->log( 'critical', $message, $context );
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_error'.
|
210 |
+
*
|
211 |
+
* @param string $message The message to log.
|
212 |
+
* @param array $context The context (optional).
|
213 |
+
*/
|
214 |
+
public function on_filter_simple_history_log_error( $message = null, $context = null ) {
|
215 |
+
SimpleLogger()->log( 'error', $message, $context );
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_warning'.
|
220 |
+
*
|
221 |
+
* @param string $message The message to log.
|
222 |
+
* @param array $context The context (optional).
|
223 |
+
*/
|
224 |
+
public function on_filter_simple_history_log_warning( $message = null, $context = null ) {
|
225 |
+
SimpleLogger()->log( 'warning', $message, $context );
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_notice'.
|
230 |
+
*
|
231 |
+
* @param string $message The message to log.
|
232 |
+
* @param array $context The context (optional).
|
233 |
+
*/
|
234 |
+
public function on_filter_simple_history_log_notice( $message = null, $context = null ) {
|
235 |
+
SimpleLogger()->log( 'notice', $message, $context );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_info'.
|
240 |
+
*
|
241 |
+
* @param string $message The message to log.
|
242 |
+
* @param array $context The context (optional).
|
243 |
+
*/
|
244 |
+
public function on_filter_simple_history_log_info( $message = null, $context = null ) {
|
245 |
+
SimpleLogger()->log( 'info', $message, $context );
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Log a message, triggered by filter 'on_filter_simple_history_log_debug'.
|
250 |
+
*
|
251 |
+
* @param string $message The message to log.
|
252 |
+
* @param array $context The context (optional).
|
253 |
+
*/
|
254 |
+
public function on_filter_simple_history_log_debug( $message = null, $context = null ) {
|
255 |
+
SimpleLogger()->log( 'debug', $message, $context );
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* @since 2.5.2
|
260 |
+
*/
|
261 |
+
private function add_admin_actions() {
|
262 |
+
add_action( 'admin_menu', array( $this, 'add_admin_pages' ) );
|
263 |
+
add_action( 'admin_menu', array( $this, 'add_settings' ) );
|
264 |
+
|
265 |
+
add_action( 'admin_footer', array( $this, 'add_js_templates' ) );
|
266 |
+
|
267 |
+
add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widget' ) );
|
268 |
+
|
269 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
|
270 |
+
|
271 |
+
add_action( 'admin_head', array( $this, 'onAdminHead' ) );
|
272 |
+
add_action( 'admin_footer', array( $this, 'onAdminFooter' ) );
|
273 |
+
|
274 |
+
add_action( 'simple_history/history_page/before_gui', array( $this, 'output_quick_stats' ) );
|
275 |
+
add_action( 'simple_history/dashboard/before_gui', array( $this, 'output_quick_stats' ) );
|
276 |
+
|
277 |
+
add_action( 'wp_ajax_simple_history_api', array( $this, 'api' ) );
|
278 |
+
|
279 |
+
add_filter( 'plugin_action_links_simple-history/index.php', array( $this, 'plugin_action_links' ), 10, 4 );
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Adds a "View history" item/shortcut to the network admin, on blogs where Simple History is installed
|
284 |
+
*
|
285 |
+
* Useful because Simple History is something at least the author of this plugin often use on a site :)
|
286 |
+
*
|
287 |
+
* @since 2.7.1
|
288 |
+
*/
|
289 |
+
public function add_admin_bar_network_menu_item( $wp_admin_bar ) {
|
290 |
+
/**
|
291 |
+
* Filter to control if admin bar shortcut should be added
|
292 |
+
*
|
293 |
+
* @since 2.7.1
|
294 |
+
*
|
295 |
+
* @param bool Add item
|
296 |
+
*/
|
297 |
+
$add_items = apply_filters( 'simple_history/add_admin_bar_network_menu_item', true );
|
298 |
+
|
299 |
+
if ( ! $add_items ) {
|
300 |
+
return;
|
301 |
+
}
|
302 |
+
|
303 |
+
// Don't show for logged out users or single site mode.
|
304 |
+
if ( ! is_user_logged_in() || ! is_multisite() ) {
|
305 |
+
return;
|
306 |
+
}
|
307 |
+
|
308 |
+
// Show only when the user has at least one site, or they're a super admin.
|
309 |
+
if ( count( $wp_admin_bar->user->blogs ) < 1 && ! is_super_admin() ) {
|
310 |
+
return;
|
311 |
+
}
|
312 |
+
|
313 |
+
// Setting to show as page must be true
|
314 |
+
if ( ! $this->setting_show_as_page() ) {
|
315 |
+
return;
|
316 |
+
}
|
317 |
+
|
318 |
+
// User must have capability to view the history page
|
319 |
+
if ( ! current_user_can( $this->get_view_history_capability() ) ) {
|
320 |
+
return;
|
321 |
+
}
|
322 |
+
|
323 |
+
/*
|
324 |
+
menu_page_url() is defined in the WordPress Plugin Administration API, which is not loaded here by default */
|
325 |
+
/* dito for is_plugin_active() */
|
326 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
327 |
+
|
328 |
+
foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
|
329 |
+
switch_to_blog( $blog->userblog_id );
|
330 |
+
|
331 |
+
if ( is_plugin_active( SIMPLE_HISTORY_BASENAME ) ) {
|
332 |
+
$menu_id = 'simple-history-blog-' . $blog->userblog_id;
|
333 |
+
$parent_menu_id = 'blog-' . $blog->userblog_id;
|
334 |
+
$url = admin_url(
|
335 |
+
apply_filters( 'simple_history/admin_location', 'index' ) . '.php?page=simple_history_page'
|
336 |
+
);
|
337 |
+
|
338 |
+
// Each network site is added by WP core with id "blog-1", "blog-2" ... "blog-n"
|
339 |
+
// https://codex.wordpress.org/Function_Reference/add_node
|
340 |
+
$args = array(
|
341 |
+
'id' => $menu_id,
|
342 |
+
'parent' => $parent_menu_id,
|
343 |
+
'title' => _x( 'View History', 'Admin bar network name', 'simple-history' ),
|
344 |
+
'href' => $url,
|
345 |
+
'meta' => array(
|
346 |
+
'class' => 'ab-item--simplehistory',
|
347 |
+
),
|
348 |
+
);
|
349 |
+
|
350 |
+
$wp_admin_bar->add_node( $args );
|
351 |
+
} // End if().
|
352 |
+
|
353 |
+
restore_current_blog();
|
354 |
+
} // End foreach().
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Adds a "View history" item/shortcut to the admin bar
|
359 |
+
*
|
360 |
+
* Useful because Simple History is something at least the author of this plugin often use on a site :)
|
361 |
+
*
|
362 |
+
* @since 2.7.1
|
363 |
+
*/
|
364 |
+
public function add_admin_bar_menu_item( $wp_admin_bar ) {
|
365 |
+
/**
|
366 |
+
* Filter to control if admin bar shortcut should be added
|
367 |
+
*
|
368 |
+
* @since 2.7.1
|
369 |
+
*
|
370 |
+
* @param bool Add item
|
371 |
+
*/
|
372 |
+
$add_item = apply_filters( 'simple_history/add_admin_bar_menu_item', true );
|
373 |
+
|
374 |
+
if ( ! $add_item ) {
|
375 |
+
return;
|
376 |
+
}
|
377 |
+
|
378 |
+
// Don't show for logged out users
|
379 |
+
if ( ! is_user_logged_in() ) {
|
380 |
+
return;
|
381 |
+
}
|
382 |
+
|
383 |
+
// Setting to show as page must be true
|
384 |
+
if ( ! $this->setting_show_as_page() ) {
|
385 |
+
return;
|
386 |
+
}
|
387 |
+
|
388 |
+
// User must have capability to view the history page
|
389 |
+
if ( ! current_user_can( $this->get_view_history_capability() ) ) {
|
390 |
+
return;
|
391 |
+
}
|
392 |
+
|
393 |
+
/* menu_page_url() and is_plugin_active()is defined in the WordPress Plugin Administration API, which is not loaded here by default */
|
394 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
395 |
+
|
396 |
+
$menu_id = 'simple-history-view-history';
|
397 |
+
$parent_menu_id = 'site-name';
|
398 |
+
$url = admin_url( apply_filters( 'simple_history/admin_location', 'index' ) . '.php?page=simple_history_page' );
|
399 |
+
|
400 |
+
$args = array(
|
401 |
+
'id' => $menu_id,
|
402 |
+
'parent' => $parent_menu_id,
|
403 |
+
'title' => _x( 'Simple History', 'Admin bar name', 'simple-history' ),
|
404 |
+
'href' => $url,
|
405 |
+
'meta' => array(
|
406 |
+
'class' => 'ab-item--simplehistory',
|
407 |
+
),
|
408 |
+
);
|
409 |
+
|
410 |
+
$wp_admin_bar->add_node( $args );
|
411 |
+
}
|
412 |
+
|
413 |
+
/**
|
414 |
+
* Get singleton intance
|
415 |
+
*
|
416 |
+
* @return SimpleHistory instance
|
417 |
+
*/
|
418 |
+
public static function get_instance() {
|
419 |
+
if ( ! isset( self::$instance ) ) {
|
420 |
+
self::$instance = new SimpleHistory();
|
421 |
+
}
|
422 |
+
|
423 |
+
return self::$instance;
|
424 |
+
}
|
425 |
+
|
426 |
+
public function filter_gettext_storeLatestTranslations( $translation, $text, $domain ) {
|
427 |
+
// Check that translation is a string or integer, i.ex. the valid values for an array key
|
428 |
+
if ( ! is_string( $translation ) || ! is_integer( $translation ) ) {
|
429 |
+
return $translation;
|
430 |
+
}
|
431 |
+
|
432 |
+
$array_max_size = 5;
|
433 |
+
|
434 |
+
// Keep a listing of the n latest translation
|
435 |
+
// when SimpleLogger->log() is called from anywhere we can then search for the
|
436 |
+
// translated string among our n latest things and find it there, if it's translated
|
437 |
+
// global $sh_latest_translations;
|
438 |
+
$sh_latest_translations = $this->gettextLatestTranslations;
|
439 |
+
|
440 |
+
$sh_latest_translations[ $translation ] = array(
|
441 |
+
'translation' => $translation,
|
442 |
+
'text' => $text,
|
443 |
+
'domain' => $domain,
|
444 |
+
);
|
445 |
+
|
446 |
+
$arr_length = count( $sh_latest_translations );
|
447 |
+
if ( $arr_length > $array_max_size ) {
|
448 |
+
$sh_latest_translations = array_slice( $sh_latest_translations, $arr_length - $array_max_size );
|
449 |
+
}
|
450 |
+
|
451 |
+
$this->gettextLatestTranslations = $sh_latest_translations;
|
452 |
+
|
453 |
+
return $translation;
|
454 |
+
}
|
455 |
+
|
456 |
+
public function setup_cron() {
|
457 |
+
add_filter( 'simple_history/maybe_purge_db', array( $this, 'maybe_purge_db' ) );
|
458 |
+
|
459 |
+
if ( ! wp_next_scheduled( 'simple_history/maybe_purge_db' ) ) {
|
460 |
+
wp_schedule_event( time(), 'daily', 'simple_history/maybe_purge_db' );
|
461 |
+
}
|
462 |
+
|
463 |
+
// Remove old schedule (only author dev sites should have it)
|
464 |
+
$old_next_scheduled = wp_next_scheduled( 'simple_history/purge_db' );
|
465 |
+
if ( $old_next_scheduled ) {
|
466 |
+
wp_unschedule_event( $old_next_scheduled, 'simple_history/purge_db' );
|
467 |
+
}
|
468 |
+
}
|
469 |
+
|
470 |
+
public function onAdminHead() {
|
471 |
+
if ( $this->is_on_our_own_pages() ) {
|
472 |
+
do_action( 'simple_history/admin_head', $this );
|
473 |
+
}
|
474 |
+
}
|
475 |
+
|
476 |
+
public function onAdminFooter() {
|
477 |
+
if ( $this->is_on_our_own_pages() ) {
|
478 |
+
do_action( 'simple_history/admin_footer', $this );
|
479 |
+
}
|
480 |
+
}
|
481 |
+
|
482 |
+
/**
|
483 |
+
* Output JS templated into footer
|
484 |
+
*/
|
485 |
+
public function add_js_templates( $hook ) {
|
486 |
+
if ( $this->is_on_our_own_pages() ) {
|
487 |
+
?>
|
488 |
+
<script type="text/html" id="tmpl-simple-history-base">
|
489 |
+
|
490 |
+
<div class="SimpleHistory__waitingForFirstLoad">
|
491 |
+
<img src="<?php echo esc_url( admin_url( '/images/spinner.gif' ) ); ?>" alt="" width="20" height="20">
|
492 |
+
<?php
|
493 |
+
echo esc_html_x(
|
494 |
+
'Loading history...',
|
495 |
+
'Message visible while waiting for log to load from server the first time',
|
496 |
+
'simple-history'
|
497 |
+
);
|
498 |
+
?>
|
499 |
+
</div>
|
500 |
+
|
501 |
+
<div class="SimpleHistoryLogitemsWrap">
|
502 |
+
<div class="SimpleHistoryLogitems__beforeTopPagination"></div>
|
503 |
+
<div class="SimpleHistoryLogitems__above"></div>
|
504 |
+
<ul class="SimpleHistoryLogitems"></ul>
|
505 |
+
<div class="SimpleHistoryLogitems__below"></div>
|
506 |
+
<div class="SimpleHistoryLogitems__pagination"></div>
|
507 |
+
<div class="SimpleHistoryLogitems__afterBottomPagination"></div>
|
508 |
+
</div>
|
509 |
+
|
510 |
+
<div class="SimpleHistoryLogitems__debug"></div>
|
511 |
+
|
512 |
+
</script>
|
513 |
+
|
514 |
+
<script type="text/html" id="tmpl-simple-history-logitems-pagination">
|
515 |
+
|
516 |
+
<!-- this uses the (almost) the same html as WP does -->
|
517 |
+
<div class="SimpleHistoryPaginationPages">
|
518 |
+
<!--
|
519 |
+
{{ data.page_rows_from }}–{{ data.page_rows_to }}
|
520 |
+
<span class="SimpleHistoryPaginationDisplayNum"> of {{ data.total_row_count }} </span>
|
521 |
+
-->
|
522 |
+
<span class="SimpleHistoryPaginationLinks">
|
523 |
+
<a
|
524 |
+
data-direction="first"
|
525 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--firstPage <# if ( data.api_args.paged <= 1 ) { #> disabled <# } #>"
|
526 |
+
title="{{ data.strings.goToTheFirstPage }}"
|
527 |
+
href="#">«</a>
|
528 |
+
<a
|
529 |
+
data-direction="prev"
|
530 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--prevPage <# if ( data.api_args.paged <= 1 ) { #> disabled <# } #>"
|
531 |
+
title="{{ data.strings.goToThePrevPage }}"
|
532 |
+
href="#">‹</a>
|
533 |
+
<span class="SimpleHistoryPaginationInput">
|
534 |
+
<input class="SimpleHistoryPaginationCurrentPage" title="{{ data.strings.currentPage }}" type="text" name="paged" value="{{ data.api_args.paged }}" size="4">
|
535 |
+
<?php _x( 'of', 'page n of n', 'simple-history' ); ?>
|
536 |
+
<span class="total-pages">{{ data.pages_count }}</span>
|
537 |
+
</span>
|
538 |
+
<a
|
539 |
+
data-direction="next"
|
540 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--nextPage <# if ( data.api_args.paged >= data.pages_count ) { #> disabled <# } #>"
|
541 |
+
title="{{ data.strings.goToTheNextPage }}"
|
542 |
+
href="#">›</a>
|
543 |
+
<a
|
544 |
+
data-direction="last"
|
545 |
+
class="button SimpleHistoryPaginationLink SimpleHistoryPaginationLink--lastPage <# if ( data.api_args.paged >= data.pages_count ) { #> disabled <# } #>"
|
546 |
+
title="{{ data.strings.goToTheLastPage }}"
|
547 |
+
href="#">»</a>
|
548 |
+
</span>
|
549 |
+
</div>
|
550 |
+
|
551 |
+
</script>
|
552 |
+
|
553 |
+
<script type="text/html" id="tmpl-simple-history-logitems-modal">
|
554 |
+
|
555 |
+
<div class="SimpleHistory-modal">
|
556 |
+
<div class="SimpleHistory-modal__background"></div>
|
557 |
+
<div class="SimpleHistory-modal__content">
|
558 |
+
<div class="SimpleHistory-modal__contentInner">
|
559 |
+
<img class="SimpleHistory-modal__contentSpinner" src="<?php echo esc_url( admin_url( '/images/spinner.gif' ) ); ?>" alt="">
|
560 |
+
</div>
|
561 |
+
<div class="SimpleHistory-modal__contentClose">
|
562 |
+
<button class="button">✕</button>
|
563 |
+
</div>
|
564 |
+
</div>
|
565 |
+
</div>
|
566 |
+
|
567 |
+
</script>
|
568 |
+
|
569 |
+
<script type="text/html" id="tmpl-simple-history-occasions-too-many">
|
570 |
+
<li
|
571 |
+
class="SimpleHistoryLogitem
|
572 |
+
SimpleHistoryLogitem--occasion
|
573 |
+
SimpleHistoryLogitem--occasion-tooMany
|
574 |
+
">
|
575 |
+
<div class="SimpleHistoryLogitem__firstcol"></div>
|
576 |
+
<div class="SimpleHistoryLogitem__secondcol">
|
577 |
+
<div class="SimpleHistoryLogitem__text">
|
578 |
+
<?php esc_html_e( 'Sorry, but there are too many similar events to show.', 'simple-history' ); ?>
|
579 |
+
</div>
|
580 |
+
</div>
|
581 |
+
</li>
|
582 |
+
</script>
|
583 |
+
|
584 |
+
<?php
|
585 |
+
// Call plugins so they can add their js.
|
586 |
+
foreach ( $this->instantiatedLoggers as $one_logger ) {
|
587 |
+
if ( method_exists( $one_logger['instance'], 'adminJS' ) ) {
|
588 |
+
$one_logger['instance']->adminJS();
|
589 |
+
}
|
590 |
+
}
|
591 |
+
}
|
592 |
+
}
|
593 |
+
|
594 |
+
/**
|
595 |
+
* Base url is:
|
596 |
+
* /wp-admin/admin-ajax.php?action=simple_history_api
|
597 |
+
*
|
598 |
+
* Examples:
|
599 |
+
* http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&posts_per_page=5&paged=1&format=html
|
600 |
+
*/
|
601 |
+
public function api() {
|
602 |
+
global $wpdb;
|
603 |
+
|
604 |
+
// Fake slow answers
|
605 |
+
// sleep(2);
|
606 |
+
// sleep(rand(0,3));
|
607 |
+
$args = $_GET;
|
608 |
+
unset( $args['action'] );
|
609 |
+
|
610 |
+
// Type = overview | ...
|
611 |
+
$type = isset( $_GET['type'] ) ? $_GET['type'] : null;
|
612 |
+
|
613 |
+
if ( empty( $args ) || ! $type ) {
|
614 |
+
wp_send_json_error(
|
615 |
+
array(
|
616 |
+
_x( 'Not enough args specified', 'API: not enought arguments passed', 'simple-history' ),
|
617 |
+
)
|
618 |
+
);
|
619 |
+
}
|
620 |
+
|
621 |
+
// User must have capability to view the history page
|
622 |
+
if ( ! current_user_can( $this->get_view_history_capability() ) ) {
|
623 |
+
wp_send_json_error(
|
624 |
+
array(
|
625 |
+
'error' => 'CAPABILITY_ERROR',
|
626 |
+
)
|
627 |
+
);
|
628 |
+
}
|
629 |
+
|
630 |
+
if ( isset( $args['id'] ) ) {
|
631 |
+
$args['post__in'] = array( $args['id'] );
|
632 |
+
}
|
633 |
+
|
634 |
+
$data = array();
|
635 |
+
|
636 |
+
switch ( $type ) {
|
637 |
+
case 'overview':
|
638 |
+
case 'occasions':
|
639 |
+
case 'single':
|
640 |
+
// API use SimpleHistoryLogQuery, so simply pass args on to that
|
641 |
+
$logQuery = new SimpleHistoryLogQuery();
|
642 |
+
$data = $logQuery->query( $args );
|
643 |
+
|
644 |
+
$data['api_args'] = $args;
|
645 |
+
|
646 |
+
// Output can be array or HMTL
|
647 |
+
if ( isset( $args['format'] ) && 'html' === $args['format'] ) {
|
648 |
+
$data['log_rows_raw'] = array();
|
649 |
+
|
650 |
+
foreach ( $data['log_rows'] as $key => $oneLogRow ) {
|
651 |
+
$args = array();
|
652 |
+
if ( $type == 'single' ) {
|
653 |
+
$args['type'] = 'single';
|
654 |
+
}
|
655 |
+
|
656 |
+
$data['log_rows'][ $key ] = $this->getLogRowHTMLOutput( $oneLogRow, $args );
|
657 |
+
$data['num_queries'] = get_num_queries();
|
658 |
+
}
|
659 |
+
}
|
660 |
+
|
661 |
+
break;
|
662 |
+
|
663 |
+
default:
|
664 |
+
$data[] = 'Nah.';
|
665 |
+
} // End switch().
|
666 |
+
|
667 |
+
wp_send_json_success( $data );
|
668 |
+
}
|
669 |
+
|
670 |
+
/**
|
671 |
+
* During the load of info for a logger we want to get a reference
|
672 |
+
* to the untranslated text too, because that's the version we want to store
|
673 |
+
* in the database.
|
674 |
+
*/
|
675 |
+
public function filter_gettext( $translated_text, $untranslated_text, $domain ) {
|
676 |
+
if ( isset( $this->doFilterGettext ) && $this->doFilterGettext ) {
|
677 |
+
$this->doFilterGettext_currentLogger->messages[] = array(
|
678 |
+
'untranslated_text' => $untranslated_text,
|
679 |
+
'translated_text' => $translated_text,
|
680 |
+
'domain' => $domain,
|
681 |
+
'context' => null,
|
682 |
+
);
|
683 |
+
}
|
684 |
+
|
685 |
+
return $translated_text;
|
686 |
+
}
|
687 |
+
|
688 |
+
/**
|
689 |
+
* Store messages with context
|
690 |
+
*/
|
691 |
+
public function filter_gettext_with_context( $translated_text, $untranslated_text, $context, $domain ) {
|
692 |
+
if ( isset( $this->doFilterGettext ) && $this->doFilterGettext ) {
|
693 |
+
$this->doFilterGettext_currentLogger->messages[] = array(
|
694 |
+
'untranslated_text' => $untranslated_text,
|
695 |
+
'translated_text' => $translated_text,
|
696 |
+
'domain' => $domain,
|
697 |
+
'context' => $context,
|
698 |
+
);
|
699 |
+
}
|
700 |
+
|
701 |
+
return $translated_text;
|
702 |
+
}
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Load language files.
|
706 |
+
* Uses the method described here:
|
707 |
+
* http://geertdedeckere.be/article/loading-wordpress-language-files-the-right-way
|
708 |
+
*
|
709 |
+
* @since 2.0
|
710 |
+
*/
|
711 |
+
public function load_plugin_textdomain() {
|
712 |
+
$domain = 'simple-history';
|
713 |
+
|
714 |
+
// The "plugin_locale" filter is also used in load_plugin_textdomain()
|
715 |
+
$locale = apply_filters( 'plugin_locale', get_locale(), $domain ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
716 |
+
load_textdomain( $domain, WP_LANG_DIR . '/simple-history/' . $domain . '-' . $locale . '.mo' );
|
717 |
+
load_plugin_textdomain( $domain, false, dirname( $this->plugin_basename ) . '/languages/' );
|
718 |
+
}
|
719 |
+
|
720 |
+
/**
|
721 |
+
* Setup variables and things
|
722 |
+
*/
|
723 |
+
public function setup_variables() {
|
724 |
+
$this->externalLoggers = array();
|
725 |
+
$this->externalDropins = array();
|
726 |
+
$this->instantiatedLoggers = array();
|
727 |
+
$this->instantiatedDropins = array();
|
728 |
+
|
729 |
+
$this->plugin_basename = SIMPLE_HISTORY_BASENAME;
|
730 |
+
}
|
731 |
+
|
732 |
+
/**
|
733 |
+
* Return capability required to view history = for who will the History page be added
|
734 |
+
*
|
735 |
+
* @since 2.1.5
|
736 |
+
* @return string capability
|
737 |
+
*/
|
738 |
+
public function get_view_history_capability() {
|
739 |
+
$view_history_capability = 'edit_pages';
|
740 |
+
$view_history_capability = apply_filters( 'simple_history_view_history_capability', $view_history_capability );
|
741 |
+
$view_history_capability = apply_filters( 'simple_history/view_history_capability', $view_history_capability );
|
742 |
+
|
743 |
+
return $view_history_capability;
|
744 |
+
}
|
745 |
+
|
746 |
+
/**
|
747 |
+
* Return capability required to view settings
|
748 |
+
*
|
749 |
+
* @since 2.1.5
|
750 |
+
* @return string capability
|
751 |
+
*/
|
752 |
+
public function get_view_settings_capability() {
|
753 |
+
$view_settings_capability = 'manage_options';
|
754 |
+
$view_settings_capability = apply_filters( 'simple_history_view_settings_capability', $view_settings_capability );
|
755 |
+
$view_settings_capability = apply_filters( 'simple_history/view_settings_capability', $view_settings_capability );
|
756 |
+
|
757 |
+
return $view_settings_capability;
|
758 |
+
}
|
759 |
+
|
760 |
+
/**
|
761 |
+
* Check if the current user can clear the log
|
762 |
+
*
|
763 |
+
* @since 2.19
|
764 |
+
* @return bool
|
765 |
+
*/
|
766 |
+
public function user_can_clear_log() {
|
767 |
+
$user_can_clear_log = apply_filters( 'simple_history/user_can_clear_log', true );
|
768 |
+
|
769 |
+
return $user_can_clear_log;
|
770 |
+
}
|
771 |
+
|
772 |
+
/**
|
773 |
+
* Adds default tabs to settings
|
774 |
+
*/
|
775 |
+
public function add_default_settings_tabs() {
|
776 |
+
// Add default settings tabs
|
777 |
+
$this->arr_settings_tabs = array(
|
778 |
+
array(
|
779 |
+
'slug' => 'settings',
|
780 |
+
'name' => __( 'Settings', 'simple-history' ),
|
781 |
+
'function' => array( $this, 'settings_output_general' ),
|
782 |
+
),
|
783 |
+
);
|
784 |
+
|
785 |
+
if ( defined( 'SIMPLE_HISTORY_DEV' ) && SIMPLE_HISTORY_DEV ) {
|
786 |
+
$arr_dev_tabs = array(
|
787 |
+
array(
|
788 |
+
'slug' => 'log',
|
789 |
+
'name' => __( 'Log (debug)', 'simple-history' ),
|
790 |
+
'function' => array( $this, 'settings_output_log' ),
|
791 |
+
),
|
792 |
+
array(
|
793 |
+
'slug' => 'styles-example',
|
794 |
+
'name' => __( 'Styles example (debug)', 'simple-history' ),
|
795 |
+
'function' => array( $this, 'settings_output_styles_example' ),
|
796 |
+
),
|
797 |
+
);
|
798 |
+
|
799 |
+
$this->arr_settings_tabs = array_merge( $this->arr_settings_tabs, $arr_dev_tabs );
|
800 |
+
}
|
801 |
+
}
|
802 |
+
|
803 |
+
/**
|
804 |
+
* Register an external logger so Simple History knows about it.
|
805 |
+
* Does not load the logger, so file with logger class must be loaded already.
|
806 |
+
*
|
807 |
+
* See example-logger.php for an example on how to use this.
|
808 |
+
*
|
809 |
+
* @since 2.1
|
810 |
+
*/
|
811 |
+
public function register_logger( $loggerClassName ) {
|
812 |
+
$this->externalLoggers[] = $loggerClassName;
|
813 |
+
}
|
814 |
+
|
815 |
+
/**
|
816 |
+
* Register an external dropin so Simple History knows about it.
|
817 |
+
* Does not load the dropin, so file with dropin class must be loaded already.
|
818 |
+
*
|
819 |
+
* See example-dropin.php for an example on how to use this.
|
820 |
+
*
|
821 |
+
* @since 2.1
|
822 |
+
*/
|
823 |
+
public function register_dropin( $dropinClassName ) {
|
824 |
+
$this->externalDropins[] = $dropinClassName;
|
825 |
+
}
|
826 |
+
|
827 |
+
/**
|
828 |
+
* Load built in loggers from all files in /loggers
|
829 |
+
* and instantiates them
|
830 |
+
*/
|
831 |
+
public function load_loggers() {
|
832 |
+
$loggersDir = SIMPLE_HISTORY_PATH . 'loggers/';
|
833 |
+
|
834 |
+
// SimpleLogger.php must be loaded first and always since the other loggers extend it.
|
835 |
+
// Load it manually so no risk of anyone using filters or similar disables it.
|
836 |
+
// Also load files that contain constants used by the SimpleLogger.
|
837 |
+
include_once $loggersDir . 'SimpleLogger.php';
|
838 |
+
include_once $loggersDir . 'SimpleLoggerLogInitiators.php';
|
839 |
+
include_once $loggersDir . 'SimpleLoggerLogTypes.php';
|
840 |
+
include_once $loggersDir . 'SimpleLoggerLogLevels.php';
|
841 |
+
|
842 |
+
// Bail if we are not in filter after_setup_theme,
|
843 |
+
// i.e. we are probably calling SimpleLogger() early.
|
844 |
+
if ( ! doing_action( 'after_setup_theme' ) ) {
|
845 |
+
return;
|
846 |
+
}
|
847 |
+
|
848 |
+
$loggersFiles = array(
|
849 |
+
// Main loggers.
|
850 |
+
$loggersDir . 'SimpleCommentsLogger.php',
|
851 |
+
$loggersDir . 'SimpleCoreUpdatesLogger.php',
|
852 |
+
$loggersDir . 'SimpleExportLogger.php',
|
853 |
+
$loggersDir . 'SimpleLogger.php',
|
854 |
+
$loggersDir . 'SimpleMediaLogger.php',
|
855 |
+
$loggersDir . 'SimpleMenuLogger.php',
|
856 |
+
$loggersDir . 'SimpleOptionsLogger.php',
|
857 |
+
$loggersDir . 'SimplePluginLogger.php',
|
858 |
+
$loggersDir . 'SimplePostLogger.php',
|
859 |
+
$loggersDir . 'SimpleThemeLogger.php',
|
860 |
+
$loggersDir . 'SimpleUserLogger.php',
|
861 |
+
$loggersDir . 'SimpleCategoriesLogger.php',
|
862 |
+
$loggersDir . 'AvailableUpdatesLogger.php',
|
863 |
+
$loggersDir . 'FileEditsLogger.php',
|
864 |
+
$loggersDir . 'class-sh-privacy-logger.php',
|
865 |
+
$loggersDir . 'class-sh-translations-logger.php',
|
866 |
+
$loggersDir . 'class-sh-jetpack-logger.php',
|
867 |
+
|
868 |
+
// Loggers for third party plugins.
|
869 |
+
$loggersDir . 'PluginUserSwitchingLogger.php',
|
870 |
+
$loggersDir . 'PluginWPCrontrolLogger.php',
|
871 |
+
$loggersDir . 'PluginEnableMediaReplaceLogger.php',
|
872 |
+
$loggersDir . 'Plugin_UltimateMembers_Logger.php',
|
873 |
+
$loggersDir . 'Plugin_LimitLoginAttempts.php',
|
874 |
+
$loggersDir . 'Plugin_Redirection.php',
|
875 |
+
$loggersDir . 'Plugin_DuplicatePost.php',
|
876 |
+
$loggersDir . 'Plugin_ACF.php',
|
877 |
+
$loggersDir . 'Plugin_BeaverBuilder.php',
|
878 |
+
);
|
879 |
+
|
880 |
+
/**
|
881 |
+
* Filter the array with absolute paths to logger files to be loaded.
|
882 |
+
*
|
883 |
+
* Each file will be loaded and will be assumed to be a logger with a classname
|
884 |
+
* the same as the filename.
|
885 |
+
*
|
886 |
+
* @since 2.0
|
887 |
+
*
|
888 |
+
* @param array $loggersFiles Array with filenames
|
889 |
+
*/
|
890 |
+
$loggersFiles = apply_filters( 'simple_history/loggers_files', $loggersFiles );
|
891 |
+
|
892 |
+
// Array with slug of loggers to instantiate.
|
893 |
+
// Slug of logger must also be the name of the logger class.
|
894 |
+
$arr_loggers_to_instantiate = array();
|
895 |
+
|
896 |
+
// $one_logger_file = "SimpleCommentsLogger.php", "class-privacy-logger.php", and so on.
|
897 |
+
foreach ( $loggersFiles as $one_logger_file ) {
|
898 |
+
$load_logger = true;
|
899 |
+
|
900 |
+
// SimpleCommentsLogger.php -> SimpleCommentsLogger.
|
901 |
+
// class-privacy-logger.php -> class-privacy-logger.
|
902 |
+
$basename_no_suffix = basename( $one_logger_file, '.php' );
|
903 |
+
|
904 |
+
/**
|
905 |
+
* Filter to completely skip loading of a logger
|
906 |
+
*
|
907 |
+
* @since 2.0.22
|
908 |
+
*
|
909 |
+
* @param bool if to load the logger. return false to not load it.
|
910 |
+
* @param string basename of logger, i.e. "SimpleCommentsLogger" or "class-privacy-logger"
|
911 |
+
*/
|
912 |
+
$load_logger = apply_filters( 'simple_history/logger/load_logger', $load_logger, $basename_no_suffix );
|
913 |
+
|
914 |
+
// If logger was SimpleLogger then force it to be loaded because for example
|
915 |
+
// custom extended plugins added later probably depends on it.
|
916 |
+
if ( 'SimpleLogger' === $basename_no_suffix ) {
|
917 |
+
$load_logger = true;
|
918 |
+
}
|
919 |
+
|
920 |
+
if ( ! $load_logger ) {
|
921 |
+
continue;
|
922 |
+
}
|
923 |
+
|
924 |
+
include_once $one_logger_file;
|
925 |
+
|
926 |
+
$arr_loggers_to_instantiate[] = $basename_no_suffix;
|
927 |
+
}
|
928 |
+
|
929 |
+
/**
|
930 |
+
* Action that plugins can use to add their custom loggers.
|
931 |
+
* See register_logger() for more info.
|
932 |
+
*
|
933 |
+
* @since 2.1
|
934 |
+
*
|
935 |
+
* @param SimpleHistory instance
|
936 |
+
*/
|
937 |
+
do_action( 'simple_history/add_custom_logger', $this );
|
938 |
+
|
939 |
+
$arr_loggers_to_instantiate = array_merge( $arr_loggers_to_instantiate, $this->externalLoggers );
|
940 |
+
|
941 |
+
/**
|
942 |
+
* Filter the array with names of loggers to instantiate.
|
943 |
+
*
|
944 |
+
* Array
|
945 |
+
* (
|
946 |
+
* [0] => SimpleCommentsLogger
|
947 |
+
* [1] => SimpleCoreUpdatesLogger
|
948 |
+
* ...
|
949 |
+
* )
|
950 |
+
*
|
951 |
+
* @since 2.0
|
952 |
+
*
|
953 |
+
* @param array $arr_loggers_to_instantiate Array with class names
|
954 |
+
*/
|
955 |
+
$arr_loggers_to_instantiate = apply_filters(
|
956 |
+
'simple_history/loggers_to_instantiate',
|
957 |
+
$arr_loggers_to_instantiate
|
958 |
+
);
|
959 |
+
|
960 |
+
// Instantiate each logger.
|
961 |
+
foreach ( $arr_loggers_to_instantiate as $one_logger_name ) {
|
962 |
+
// Detect logger class name.
|
963 |
+
$logger_class_name = null;
|
964 |
+
|
965 |
+
if ( class_exists( $one_logger_name ) ) {
|
966 |
+
// Logger name is "SimpleCommentsLogger".
|
967 |
+
$logger_class_name = $one_logger_name;
|
968 |
+
} else {
|
969 |
+
// Check if class is "class-privacy-logger".
|
970 |
+
$logger_snaked_name = substr( $one_logger_name, 6 );
|
971 |
+
// "privacy-logger" -> "privacy_logger" -> Privacy_Logger
|
972 |
+
$logger_snaked_name = str_replace( '-', '_', $logger_snaked_name );
|
973 |
+
$logger_snaked_name = sh_ucwords( $logger_snaked_name, '_' );
|
974 |
+
|
975 |
+
if ( class_exists( $logger_snaked_name ) ) {
|
976 |
+
$logger_class_name = $logger_snaked_name;
|
977 |
+
}
|
978 |
+
}
|
979 |
+
|
980 |
+
// Continue to load next logger if no valid logger class found.
|
981 |
+
if ( ! $logger_class_name ) {
|
982 |
+
continue;
|
983 |
+
}
|
984 |
+
|
985 |
+
// Init found logger class.
|
986 |
+
$logger_instance = new $logger_class_name( $this );
|
987 |
+
|
988 |
+
if ( ! is_subclass_of( $logger_instance, 'SimpleLogger' ) && ! is_a( $logger_instance, 'SimpleLogger' ) ) {
|
989 |
+
continue;
|
990 |
+
}
|
991 |
+
|
992 |
+
$logger_instance->loaded();
|
993 |
+
|
994 |
+
// Tell gettext-filter to add untranslated messages.
|
995 |
+
$this->doFilterGettext = true;
|
996 |
+
$this->doFilterGettext_currentLogger = $logger_instance;
|
997 |
+
|
998 |
+
$logger_info = $logger_instance->getInfo();
|
999 |
+
|
1000 |
+
// Check so no logger has a logger slug with more than 30 chars,
|
1001 |
+
// because db column is only 30 chars.
|
1002 |
+
if ( strlen( $logger_instance->slug ) > 30 ) {
|
1003 |
+
add_action( 'admin_notices', array( $this, 'admin_notice_logger_slug_to_long' ) );
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
// Un-tell gettext filter.
|
1007 |
+
$this->doFilterGettext = false;
|
1008 |
+
$this->doFilterGettext_currentLogger = null;
|
1009 |
+
|
1010 |
+
// LoggerInfo contains all messages, both translated an not, by key.
|
1011 |
+
// Add messages to the loggerInstance.
|
1012 |
+
$arr_messages_by_message_key = array();
|
1013 |
+
|
1014 |
+
if ( isset( $logger_info['messages'] ) && is_array( $logger_info['messages'] ) ) {
|
1015 |
+
foreach ( (array) $logger_info['messages'] as $message_key => $message_translated ) {
|
1016 |
+
// Find message in array with both translated and non translated strings.
|
1017 |
+
foreach ( $logger_instance->messages as $one_message_with_translation_info ) {
|
1018 |
+
if ( $message_translated == $one_message_with_translation_info['translated_text'] ) {
|
1019 |
+
$arr_messages_by_message_key[ $message_key ] = $one_message_with_translation_info;
|
1020 |
+
continue;
|
1021 |
+
}
|
1022 |
+
}
|
1023 |
+
}
|
1024 |
+
}
|
1025 |
+
|
1026 |
+
$logger_instance->messages = $arr_messages_by_message_key;
|
1027 |
+
|
1028 |
+
// Add logger to array of loggers.
|
1029 |
+
$this->instantiatedLoggers[ $logger_instance->slug ] = array(
|
1030 |
+
'name' => $logger_info['name'],
|
1031 |
+
'instance' => $logger_instance,
|
1032 |
+
);
|
1033 |
+
} // End foreach().
|
1034 |
+
|
1035 |
+
do_action( 'simple_history/loggers_loaded' );
|
1036 |
+
}
|
1037 |
+
|
1038 |
+
/**
|
1039 |
+
* Load built in dropins from all files in /dropins
|
1040 |
+
* and instantiates them
|
1041 |
+
*/
|
1042 |
+
public function load_dropins() {
|
1043 |
+
$dropinsDir = SIMPLE_HISTORY_PATH . 'dropins/';
|
1044 |
+
|
1045 |
+
$dropinsFiles = array(
|
1046 |
+
$dropinsDir . 'SimpleHistoryPluginPatchesDropin.php',
|
1047 |
+
$dropinsDir . 'SimpleHistoryDonateDropin.php',
|
1048 |
+
$dropinsDir . 'SimpleHistoryExportDropin.php',
|
1049 |
+
$dropinsDir . 'SimpleHistoryFilterDropin.php',
|
1050 |
+
$dropinsDir . 'SimpleHistoryIpInfoDropin.php',
|
1051 |
+
$dropinsDir . 'SimpleHistoryNewRowsNotifier.php',
|
1052 |
+
$dropinsDir . 'SimpleHistoryRSSDropin.php',
|
1053 |
+
$dropinsDir . 'SimpleHistorySettingsLogtestDropin.php',
|
1054 |
+
$dropinsDir . 'SimpleHistorySettingsStatsDropin.php',
|
1055 |
+
$dropinsDir . 'SimpleHistorySettingsDebugDropin.php',
|
1056 |
+
$dropinsDir . 'SimpleHistorySidebarDropin.php',
|
1057 |
+
$dropinsDir . 'SimpleHistorySidebarStats.php',
|
1058 |
+
$dropinsDir . 'SimpleHistorySidebarSettings.php',
|
1059 |
+
$dropinsDir . 'SimpleHistoryWPCLIDropin.php',
|
1060 |
+
$dropinsDir . 'SimpleHistoryDebugDropin.php',
|
1061 |
+
);
|
1062 |
+
|
1063 |
+
/**
|
1064 |
+
* Filter the array with absolute paths to files as returned by glob function.
|
1065 |
+
* Each file will be loaded and will be assumed to be a dropin with a classname
|
1066 |
+
* the same as the filename.
|
1067 |
+
*
|
1068 |
+
* @since 2.0
|
1069 |
+
*
|
1070 |
+
* @param array $dropinsFiles Array with filenames
|
1071 |
+
*/
|
1072 |
+
$dropinsFiles = apply_filters( 'simple_history/dropins_files', $dropinsFiles );
|
1073 |
+
|
1074 |
+
$arrDropinsToInstantiate = array();
|
1075 |
+
|
1076 |
+
foreach ( $dropinsFiles as $oneDropinFile ) {
|
1077 |
+
// path/path/simplehistory/dropins/SimpleHistoryDonateDropin.php => SimpleHistoryDonateDropin
|
1078 |
+
$oneDropinFileBasename = basename( $oneDropinFile, '.php' );
|
1079 |
+
|
1080 |
+
$load_dropin = true;
|
1081 |
+
|
1082 |
+
/**
|
1083 |
+
* Filter to completely skip loading of dropin
|
1084 |
+
* complete filer name will be like:
|
1085 |
+
* simple_history/dropin/load_dropin_SimpleHistoryRSSDropin
|
1086 |
+
*
|
1087 |
+
* @since 2.0.6
|
1088 |
+
*
|
1089 |
+
* @param bool if to load the dropin. return false to not load it.
|
1090 |
+
*/
|
1091 |
+
$load_dropin = apply_filters( "simple_history/dropin/load_dropin_{$oneDropinFileBasename}", $load_dropin );
|
1092 |
+
|
1093 |
+
/**
|
1094 |
+
* Filter to completely skip loading of a dropin
|
1095 |
+
*
|
1096 |
+
* @since 2.0.22
|
1097 |
+
*
|
1098 |
+
* @param bool if to load the dropin. return false to not load it.
|
1099 |
+
* @param string slug of dropin
|
1100 |
+
*/
|
1101 |
+
$load_dropin = apply_filters( 'simple_history/dropin/load_dropin', $load_dropin, $oneDropinFileBasename );
|
1102 |
+
|
1103 |
+
if ( ! $load_dropin ) {
|
1104 |
+
continue;
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
include_once $oneDropinFile;
|
1108 |
+
|
1109 |
+
$arrDropinsToInstantiate[] = $oneDropinFileBasename;
|
1110 |
+
} // End foreach().
|
1111 |
+
|
1112 |
+
/**
|
1113 |
+
* Action that dropins can use to add their custom loggers.
|
1114 |
+
* See register_dropin() for more info.
|
1115 |
+
*
|
1116 |
+
* @since 2.3.2
|
1117 |
+
*
|
1118 |
+
* @param array $arrDropinsToInstantiate Array with class names
|
1119 |
+
*/
|
1120 |
+
do_action( 'simple_history/add_custom_dropin', $this );
|
1121 |
+
|
1122 |
+
/**
|
1123 |
+
* Filter the array with names of dropin to instantiate.
|
1124 |
+
*
|
1125 |
+
* @since 2.0
|
1126 |
+
*
|
1127 |
+
* @param array $arrDropinsToInstantiate Array with class names
|
1128 |
+
*/
|
1129 |
+
$arrDropinsToInstantiate = apply_filters( 'simple_history/dropins_to_instantiate', $arrDropinsToInstantiate );
|
1130 |
+
|
1131 |
+
$arrDropinsToInstantiate = array_merge( $arrDropinsToInstantiate, $this->externalDropins );
|
1132 |
+
|
1133 |
+
// Instantiate each dropin
|
1134 |
+
foreach ( $arrDropinsToInstantiate as $oneDropinName ) {
|
1135 |
+
if ( ! class_exists( $oneDropinName ) ) {
|
1136 |
+
continue;
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
$this->instantiatedDropins[ $oneDropinName ] = array(
|
1140 |
+
'name' => $oneDropinName,
|
1141 |
+
'instance' => new $oneDropinName( $this ),
|
1142 |
+
);
|
1143 |
+
}
|
1144 |
+
}
|
1145 |
+
|
1146 |
+
/**
|
1147 |
+
* Gets the pager size,
|
1148 |
+
* i.e. the number of items to show on each page in the history
|
1149 |
+
*
|
1150 |
+
* @return int
|
1151 |
+
*/
|
1152 |
+
public function get_pager_size() {
|
1153 |
+
$pager_size = get_option( 'simple_history_pager_size', 20 );
|
1154 |
+
|
1155 |
+
/**
|
1156 |
+
* Filter the pager size setting
|
1157 |
+
*
|
1158 |
+
* @since 2.0
|
1159 |
+
*
|
1160 |
+
* @param int $pager_size
|
1161 |
+
*/
|
1162 |
+
$pager_size = apply_filters( 'simple_history/pager_size', $pager_size );
|
1163 |
+
|
1164 |
+
return $pager_size;
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
/**
|
1168 |
+
* Gets the pager size,
|
1169 |
+
* i.e. the number of items to show on each page in the history
|
1170 |
+
*
|
1171 |
+
* @since 2.12
|
1172 |
+
* @return int
|
1173 |
+
*/
|
1174 |
+
public function get_pager_size_dashboard() {
|
1175 |
+
$pager_size = get_option( 'simple_history_pager_size_dashboard', 5 );
|
1176 |
+
|
1177 |
+
/**
|
1178 |
+
* Filter the pager size setting
|
1179 |
+
*
|
1180 |
+
* @since 2.12
|
1181 |
+
*
|
1182 |
+
* @param int $pager_size
|
1183 |
+
*/
|
1184 |
+
$pager_size = apply_filters( 'simple_history/pager_size_dashboard', $pager_size );
|
1185 |
+
|
1186 |
+
return $pager_size;
|
1187 |
+
}
|
1188 |
+
|
1189 |
+
/**
|
1190 |
+
* Show a link to our settings page on the Plugins -> Installed Plugins screen
|
1191 |
+
*/
|
1192 |
+
public function plugin_action_links( $actions, $b, $c, $d ) {
|
1193 |
+
// Only add link if user has the right to view the settings page
|
1194 |
+
if ( ! current_user_can( $this->get_view_settings_capability() ) ) {
|
1195 |
+
return $actions;
|
1196 |
+
}
|
1197 |
+
|
1198 |
+
$settings_page_url = menu_page_url( self::SETTINGS_MENU_SLUG, 0 );
|
1199 |
+
|
1200 |
+
if ( empty( $actions ) ) {
|
1201 |
+
// 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)
|
1202 |
+
$actions = array();
|
1203 |
+
} elseif ( is_string( $actions ) ) {
|
1204 |
+
// Convert the string (which it might've been retrieved as) to an array for future use as an array
|
1205 |
+
$actions = array( $actions );
|
1206 |
+
}
|
1207 |
+
$actions[] = "<a href='$settings_page_url'>" . __( 'Settings', 'simple-history' ) . '</a>';
|
1208 |
+
|
1209 |
+
return $actions;
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
/**
|
1213 |
+
* Maybe add a dashboard widget,
|
1214 |
+
* requires current user to have view history capability
|
1215 |
+
* and a setting to show dashboard to be set
|
1216 |
+
*/
|
1217 |
+
public function add_dashboard_widget() {
|
1218 |
+
if ( $this->setting_show_on_dashboard() && current_user_can( $this->get_view_history_capability() ) ) {
|
1219 |
+
/**
|
1220 |
+
* Filter to determine if history page should be added to page below dashboard or not
|
1221 |
+
*
|
1222 |
+
* @since 2.0.23
|
1223 |
+
*
|
1224 |
+
* @param bool Show the page or not
|
1225 |
+
*/
|
1226 |
+
$show_dashboard_widget = apply_filters( 'simple_history/show_dashboard_widget', true );
|
1227 |
+
|
1228 |
+
if ( $show_dashboard_widget ) {
|
1229 |
+
wp_add_dashboard_widget(
|
1230 |
+
'simple_history_dashboard_widget',
|
1231 |
+
__( 'Simple History', 'simple-history' ),
|
1232 |
+
array(
|
1233 |
+
$this,
|
1234 |
+
'dashboard_widget_output',
|
1235 |
+
)
|
1236 |
+
);
|
1237 |
+
}
|
1238 |
+
}
|
1239 |
+
}
|
1240 |
+
|
1241 |
+
/**
|
1242 |
+
* Output html for the dashboard widget
|
1243 |
+
*/
|
1244 |
+
public function dashboard_widget_output() {
|
1245 |
+
$pager_size = $this->get_pager_size_dashboard();
|
1246 |
+
|
1247 |
+
/**
|
1248 |
+
* Filter the pager size setting for the dashboard
|
1249 |
+
*
|
1250 |
+
* @since 2.0
|
1251 |
+
*
|
1252 |
+
* @param int $pager_size
|
1253 |
+
*/
|
1254 |
+
$pager_size = apply_filters( 'simple_history/dashboard_pager_size', $pager_size );
|
1255 |
+
|
1256 |
+
do_action( 'simple_history/dashboard/before_gui', $this );
|
1257 |
+
?>
|
1258 |
+
<div class="SimpleHistoryGui"
|
1259 |
+
data-pager-size='<?php echo esc_attr( $pager_size ); ?>'
|
1260 |
+
></div>
|
1261 |
+
<?php
|
1262 |
+
}
|
1263 |
+
|
1264 |
+
public function is_on_our_own_pages( $hook = '' ) {
|
1265 |
+
$current_screen = get_current_screen();
|
1266 |
+
|
1267 |
+
$basePrefix = apply_filters( 'simple_history/admin_location', 'index' );
|
1268 |
+
$basePrefix = $basePrefix === 'index' ? 'dashboard' : $basePrefix;
|
1269 |
+
|
1270 |
+
if ( $current_screen && $current_screen->base == 'settings_page_' . self::SETTINGS_MENU_SLUG ) {
|
1271 |
+
return true;
|
1272 |
+
} elseif ( $current_screen && $current_screen->base == $basePrefix . '_page_simple_history_page' ) {
|
1273 |
+
return true;
|
1274 |
+
} elseif (
|
1275 |
+
$hook == 'settings_page_' . self::SETTINGS_MENU_SLUG ||
|
1276 |
+
( $this->setting_show_on_dashboard() && $hook == 'index.php' ) ||
|
1277 |
+
( $this->setting_show_as_page() && $hook == $basePrefix . '_page_simple_history_page' )
|
1278 |
+
) {
|
1279 |
+
return true;
|
1280 |
+
} elseif ( $current_screen && $current_screen->base == 'dashboard' && $this->setting_show_on_dashboard() ) {
|
1281 |
+
return true;
|
1282 |
+
}
|
1283 |
+
|
1284 |
+
return false;
|
1285 |
+
}
|
1286 |
+
|
1287 |
+
/**
|
1288 |
+
* Enqueue styles and scripts for Simple History but only to our own pages.
|
1289 |
+
*
|
1290 |
+
* Only adds scripts to pages where the log is shown or the settings page.
|
1291 |
+
*/
|
1292 |
+
public function enqueue_admin_scripts( $hook ) {
|
1293 |
+
if ( $this->is_on_our_own_pages() ) {
|
1294 |
+
add_thickbox();
|
1295 |
+
|
1296 |
+
wp_enqueue_style(
|
1297 |
+
'simple_history_styles',
|
1298 |
+
SIMPLE_HISTORY_DIR_URL . 'css/styles.css',
|
1299 |
+
false,
|
1300 |
+
SIMPLE_HISTORY_VERSION
|
1301 |
+
);
|
1302 |
+
wp_enqueue_script(
|
1303 |
+
'simple_history_script',
|
1304 |
+
SIMPLE_HISTORY_DIR_URL . 'js/scripts.js',
|
1305 |
+
array( 'jquery', 'backbone', 'wp-util' ),
|
1306 |
+
SIMPLE_HISTORY_VERSION,
|
1307 |
+
true
|
1308 |
+
);
|
1309 |
+
|
1310 |
+
wp_enqueue_script( 'select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.full.min.js', array( 'jquery' ), SIMPLE_HISTORY_VERSION );
|
1311 |
+
wp_enqueue_style( 'select2', SIMPLE_HISTORY_DIR_URL . 'js/select2/select2.min.css', array(), SIMPLE_HISTORY_VERSION );
|
1312 |
+
|
1313 |
+
// Translations that we use in JavaScript
|
1314 |
+
wp_localize_script(
|
1315 |
+
'simple_history_script',
|
1316 |
+
'simple_history_script_vars',
|
1317 |
+
array(
|
1318 |
+
'settingsConfirmClearLog' => __( 'Remove all log items?', 'simple-history' ),
|
1319 |
+
'pagination' => array(
|
1320 |
+
'goToTheFirstPage' => __( 'Go to the first page', 'simple-history' ),
|
1321 |
+
'goToThePrevPage' => __( 'Go to the previous page', 'simple-history' ),
|
1322 |
+
'goToTheNextPage' => __( 'Go to the next page', 'simple-history' ),
|
1323 |
+
'goToTheLastPage' => __( 'Go to the last page', 'simple-history' ),
|
1324 |
+
'currentPage' => __( 'Current page', 'simple-history' ),
|
1325 |
+
),
|
1326 |
+
'loadLogAPIError' => __( 'Oups, the log could not be loaded right now.', 'simple-history' ),
|
1327 |
+
'ajaxLoadError' => __(
|
1328 |
+
'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.',
|
1329 |
+
'simple-history'
|
1330 |
+
),
|
1331 |
+
'logNoHits' => __( 'Your search did not match any history events.', 'simple-history' ),
|
1332 |
+
)
|
1333 |
+
);
|
1334 |
+
|
1335 |
+
// Call plugins adminCSS-method, so they can add their CSS
|
1336 |
+
foreach ( $this->instantiatedLoggers as $one_logger ) {
|
1337 |
+
if ( method_exists( $one_logger['instance'], 'adminCSS' ) ) {
|
1338 |
+
$one_logger['instance']->adminCSS();
|
1339 |
+
}
|
1340 |
+
}
|
1341 |
+
|
1342 |
+
// Add timeago.js
|
1343 |
+
wp_enqueue_script(
|
1344 |
+
'timeago',
|
1345 |
+
SIMPLE_HISTORY_DIR_URL . 'js/timeago/jquery.timeago.js',
|
1346 |
+
array( 'jquery' ),
|
1347 |
+
'1.5.2',
|
1348 |
+
true
|
1349 |
+
);
|
1350 |
+
|
1351 |
+
// Determine current locale to load timeago locale
|
1352 |
+
$locale = strtolower( substr( get_locale(), 0, 2 ) );
|
1353 |
+
$locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/timeago/locales/jquery.timeago.%s.js';
|
1354 |
+
$locale_dir_path = SIMPLE_HISTORY_PATH . 'js/timeago/locales/jquery.timeago.%s.js';
|
1355 |
+
|
1356 |
+
// Only enqueue if locale-file exists on file system
|
1357 |
+
if ( file_exists( sprintf( $locale_dir_path, $locale ) ) ) {
|
1358 |
+
wp_enqueue_script( 'timeago-locale', sprintf( $locale_url_path, $locale ), array( 'jquery' ), '1.5.2', true );
|
1359 |
+
} else {
|
1360 |
+
wp_enqueue_script( 'timeago-locale', sprintf( $locale_url_path, 'en' ), array( 'jquery' ), '1.5.2', true );
|
1361 |
+
}
|
1362 |
+
// end add timeago
|
1363 |
+
// Load Select2 locale
|
1364 |
+
$locale_url_path = SIMPLE_HISTORY_DIR_URL . 'js/select2/i18n/%s.js';
|
1365 |
+
$locale_dir_path = SIMPLE_HISTORY_PATH . 'js/select2/i18n/%s.js';
|
1366 |
+
|
1367 |
+
if ( file_exists( sprintf( $locale_dir_path, $locale ) ) ) {
|
1368 |
+
wp_enqueue_script( 'select2-locale', sprintf( $locale_url_path, $locale ), array( 'jquery' ), '3.5.1', true );
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
/**
|
1372 |
+
* Fires when the admin scripts have been enqueued.
|
1373 |
+
* Only fires on any of the pages where Simple History is used
|
1374 |
+
*
|
1375 |
+
* @since 2.0
|
1376 |
+
*
|
1377 |
+
* @param SimpleHistory $SimpleHistory This class.
|
1378 |
+
*/
|
1379 |
+
do_action( 'simple_history/enqueue_admin_scripts', $this );
|
1380 |
+
} // End if().
|
1381 |
+
}
|
1382 |
+
|
1383 |
+
public function filter_option_page_capability( $capability ) {
|
1384 |
+
return $capability;
|
1385 |
+
}
|
1386 |
+
|
1387 |
+
/**
|
1388 |
+
* Check if plugin version have changed, i.e. has been upgraded
|
1389 |
+
* If upgrade is detected then maybe modify database and so on for that version
|
1390 |
+
*/
|
1391 |
+
public function check_for_upgrade() {
|
1392 |
+
global $wpdb;
|
1393 |
+
|
1394 |
+
$db_version = get_option( 'simple_history_db_version' );
|
1395 |
+
$table_name = $wpdb->prefix . self::DBTABLE;
|
1396 |
+
$table_name_contexts = $wpdb->prefix . self::DBTABLE_CONTEXTS;
|
1397 |
+
$first_install = false;
|
1398 |
+
|
1399 |
+
// If no db_version is set then this
|
1400 |
+
// is a version of Simple History < 0.4
|
1401 |
+
// or it's a first install
|
1402 |
+
// Fix database not using UTF-8
|
1403 |
+
if ( false === $db_version || intval( $db_version ) == 0 ) {
|
1404 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1405 |
+
|
1406 |
+
// Table creation, used to be in register_activation_hook
|
1407 |
+
// We change the varchar size to add one num just to force update of encoding. dbdelta didn't see it otherwise.
|
1408 |
+
$sql =
|
1409 |
+
'CREATE TABLE ' .
|
1410 |
+
$table_name .
|
1411 |
+
' (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1412 |
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1413 |
date datetime NOT NULL,
|
1414 |
PRIMARY KEY (id)
|
1415 |
) CHARACTER SET=utf8;';
|
1416 |
|
1417 |
+
// Upgrade db / fix utf for varchars
|
1418 |
+
dbDelta( $sql );
|
1419 |
+
|
1420 |
+
// Fix UTF-8 for table
|
1421 |
+
$sql = sprintf( 'alter table %1$s charset=utf8;', $table_name );
|
1422 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1423 |
+
$wpdb->query( $sql );
|
1424 |
+
|
1425 |
+
$db_version = 1;
|
1426 |
+
|
1427 |
+
update_option( 'simple_history_db_version', $db_version );
|
1428 |
+
|
1429 |
+
// We are not 100% sure that this is a first install,
|
1430 |
+
// but it is at least a very old version that is being updated
|
1431 |
+
$first_install = true;
|
1432 |
+
} // End if().
|
1433 |
+
|
1434 |
+
// If db version is 1 then upgrade to 2
|
1435 |
+
// Version 2 added the action_description column
|
1436 |
+
if ( 1 == intval( $db_version ) ) {
|
1437 |
+
// V2 used to add column "action_description"
|
1438 |
+
// but it's not used any more so don't do i
|
1439 |
+
$db_version = 2;
|
1440 |
+
|
1441 |
+
update_option( 'simple_history_db_version', $db_version );
|
1442 |
+
}
|
1443 |
+
|
1444 |
+
// Check that all options we use are set to their defaults, if they miss value
|
1445 |
+
// Each option that is missing a value will make a sql call otherwise = unnecessary
|
1446 |
+
$arr_options = array(
|
1447 |
+
array(
|
1448 |
+
'name' => 'simple_history_show_as_page',
|
1449 |
+
'default_value' => 1,
|
1450 |
+
),
|
1451 |
+
array(
|
1452 |
+
'name' => 'simple_history_show_on_dashboard',
|
1453 |
+
'default_value' => 1,
|
1454 |
+
),
|
1455 |
+
);
|
1456 |
+
|
1457 |
+
foreach ( $arr_options as $one_option ) {
|
1458 |
+
$option_value = get_option( $one_option['name'] );
|
1459 |
+
if ( false === ( $option_value ) ) {
|
1460 |
+
// Value is not set in db, so set it to a default
|
1461 |
+
update_option( $one_option['name'], $one_option['default_value'] );
|
1462 |
+
}
|
1463 |
+
}
|
1464 |
+
|
1465 |
+
/**
|
1466 |
+
* If db_version is 2 then upgrade to 3:
|
1467 |
+
* - Add some fields to existing table wp_simple_history_contexts
|
1468 |
+
* - Add all new table wp_simple_history_contexts
|
1469 |
+
*
|
1470 |
+
* @since 2.0
|
1471 |
+
*/
|
1472 |
+
if ( 2 == intval( $db_version ) ) {
|
1473 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1474 |
+
|
1475 |
+
// Update old table
|
1476 |
+
$sql = "
|
1477 |
CREATE TABLE {$table_name} (
|
1478 |
id bigint(20) NOT NULL AUTO_INCREMENT,
|
1479 |
date datetime NOT NULL,
|
1487 |
KEY loggerdate (logger,date)
|
1488 |
) CHARSET=utf8;";
|
1489 |
|
1490 |
+
dbDelta( $sql );
|
1491 |
|
1492 |
+
// Add context table
|
1493 |
+
$sql = "
|
1494 |
CREATE TABLE IF NOT EXISTS {$table_name_contexts} (
|
1495 |
context_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
1496 |
history_id bigint(20) unsigned NOT NULL,
|
1502 |
) CHARSET=utf8;
|
1503 |
";
|
1504 |
|
1505 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1506 |
+
$wpdb->query( $sql );
|
1507 |
|
1508 |
+
$db_version = 3;
|
1509 |
+
update_option( 'simple_history_db_version', $db_version );
|
|
|
1510 |
|
1511 |
+
// Update possible old items to use SimpleLogger.
|
1512 |
+
$sql = sprintf(
|
1513 |
+
'
|
1514 |
UPDATE %1$s
|
1515 |
SET
|
1516 |
+
logger = "SimpleLogger",
|
1517 |
level = "info"
|
1518 |
WHERE logger IS NULL
|
1519 |
',
|
1520 |
+
$table_name
|
1521 |
+
);
|
1522 |
+
|
1523 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1524 |
+
$wpdb->query( $sql );
|
1525 |
+
|
1526 |
+
// Say welcome, however loggers are not added this early so we need to
|
1527 |
+
// use a filter to load it later
|
1528 |
+
add_action( 'simple_history/loggers_loaded', array( $this, 'addWelcomeLogMessage' ) );
|
1529 |
+
} // End if().
|
1530 |
+
|
1531 |
+
/**
|
1532 |
+
* If db version = 3
|
1533 |
+
* then we need to update database to allow null values for some old columns
|
1534 |
+
* that used to work in pre wp 4.1 beta, but since 4.1 wp uses STRICT_ALL_TABLES
|
1535 |
+
* WordPress Commit: https://github.com/WordPress/WordPress/commit/f17d168a0f72211a9bfd9d3fa680713069871bb6
|
1536 |
+
*
|
1537 |
+
* @since 2.0
|
1538 |
+
*/
|
1539 |
+
if ( 3 == intval( $db_version ) ) {
|
1540 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
1541 |
+
|
1542 |
+
// If old columns exist = this is an old install, then modify the columns so we still can keep them
|
1543 |
+
// we want to keep them because user may have logged items that they want to keep
|
1544 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1545 |
+
$db_cools = $wpdb->get_col( "DESCRIBE $table_name" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
1546 |
+
|
1547 |
+
if ( in_array( 'action', $db_cools ) ) {
|
1548 |
+
$sql = sprintf(
|
1549 |
+
'
|
1550 |
ALTER TABLE %1$s
|
1551 |
MODIFY `action` varchar(255) NULL,
|
1552 |
MODIFY `object_type` varchar(255) NULL,
|
1555 |
MODIFY `object_id` int(10) NULL,
|
1556 |
MODIFY `object_name` varchar(255) NULL
|
1557 |
',
|
1558 |
+
$table_name
|
1559 |
+
);
|
1560 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1561 |
+
$wpdb->query( $sql );
|
1562 |
+
}
|
1563 |
+
|
1564 |
+
$db_version = 4;
|
1565 |
+
|
1566 |
+
update_option( 'simple_history_db_version', $db_version );
|
1567 |
+
} // End if().
|
1568 |
+
|
1569 |
+
// Some installs on 2.2.2 got failed installs
|
1570 |
+
// We detect these by checking for db_version and then running the install stuff again
|
1571 |
+
if ( 4 == intval( $db_version ) ) {
|
1572 |
+
if ( ! $this->does_database_have_data() ) {
|
1573 |
+
// not ok, decrease db number so installs will run again and hopefully fix things
|
1574 |
+
$db_version = 0;
|
1575 |
+
} else {
|
1576 |
+
// all looks ok, upgrade to db version 5, so this part is not done again
|
1577 |
+
$db_version = 5;
|
1578 |
+
}
|
1579 |
+
|
1580 |
+
update_option( 'simple_history_db_version', $db_version );
|
1581 |
+
}
|
1582 |
+
}
|
1583 |
+
|
1584 |
+
/**
|
1585 |
+
* Check if the database has data/rows
|
1586 |
+
*
|
1587 |
+
* @since 2.1.6
|
1588 |
+
* @return bool True if database is not empty, false if database is empty = contains no data
|
1589 |
+
*/
|
1590 |
+
public function does_database_have_data() {
|
1591 |
+
global $wpdb;
|
1592 |
+
|
1593 |
+
$tableprefix = $wpdb->prefix;
|
1594 |
+
$simple_history_table = self::DBTABLE;
|
1595 |
+
|
1596 |
+
$sql_data_exists = "SELECT id AS id_exists FROM {$tableprefix}{$simple_history_table} LIMIT 1";
|
1597 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1598 |
+
$data_exists = (bool) $wpdb->get_var( $sql_data_exists, 0 );
|
1599 |
+
|
1600 |
+
return $data_exists;
|
1601 |
+
}
|
1602 |
+
|
1603 |
+
/**
|
1604 |
+
* Greet users to version 2!
|
1605 |
+
* Is only called after database has been upgraded, so only on first install (or upgrade).
|
1606 |
+
* Not called after only plugin activation.
|
1607 |
+
*/
|
1608 |
+
public function addWelcomeLogMessage() {
|
1609 |
+
$db_data_exists = $this->does_database_have_data();
|
1610 |
+
// $db_data_exists = false;
|
1611 |
+
$pluginLogger = $this->getInstantiatedLoggerBySlug( 'SimplePluginLogger' );
|
1612 |
+
if ( $pluginLogger ) {
|
1613 |
+
// Add plugin installed message
|
1614 |
+
$context = array(
|
1615 |
+
'plugin_name' => 'Simple History',
|
1616 |
+
'plugin_description' =>
|
1617 |
+
'Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.',
|
1618 |
+
'plugin_url' => 'https://simple-history.com',
|
1619 |
+
'plugin_version' => SIMPLE_HISTORY_VERSION,
|
1620 |
+
'plugin_author' => 'Pär Thernström',
|
1621 |
+
);
|
1622 |
+
|
1623 |
+
$pluginLogger->infoMessage( 'plugin_installed', $context );
|
1624 |
+
|
1625 |
+
// Add plugin activated message
|
1626 |
+
$context['plugin_slug'] = 'simple-history';
|
1627 |
+
$context['plugin_title'] = '<a href="https://simple-history.com/">Simple History</a>';
|
1628 |
+
|
1629 |
+
$pluginLogger->infoMessage( 'plugin_activated', $context );
|
1630 |
+
}
|
1631 |
+
|
1632 |
+
if ( ! $db_data_exists ) {
|
1633 |
+
$welcome_message_1 = __(
|
1634 |
+
'
|
|
|
|
|
|
|
1635 |
Welcome to Simple History!
|
1636 |
|
1637 |
This is the main history feed. It will contain events that this plugin has logged.
|
1638 |
',
|
1639 |
+
'simple-history'
|
1640 |
+
);
|
1641 |
|
1642 |
+
$welcome_message_2 = __(
|
1643 |
+
'
|
1644 |
Because Simple History was only recently installed, this feed does not display many events yet. As long as the plugin remains activated you will soon see detailed information about page edits, plugin updates, users logging in, and much more.
|
1645 |
',
|
1646 |
+
'simple-history'
|
1647 |
+
);
|
1648 |
+
|
1649 |
+
SimpleLogger()->info(
|
1650 |
+
$welcome_message_2,
|
1651 |
+
array(
|
1652 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
1653 |
+
)
|
1654 |
+
);
|
1655 |
+
|
1656 |
+
SimpleLogger()->info(
|
1657 |
+
$welcome_message_1,
|
1658 |
+
array(
|
1659 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
1660 |
+
)
|
1661 |
+
);
|
1662 |
+
}
|
1663 |
+
}
|
1664 |
+
|
1665 |
+
public function registerSettingsTab( $arr_tab_settings ) {
|
1666 |
+
$this->arr_settings_tabs[] = $arr_tab_settings;
|
1667 |
+
}
|
1668 |
+
|
1669 |
+
public function getSettingsTabs() {
|
1670 |
+
return $this->arr_settings_tabs;
|
1671 |
+
}
|
1672 |
+
|
1673 |
+
/**
|
1674 |
+
* Output HTML for the settings page
|
1675 |
+
* Called from add_options_page
|
1676 |
+
*/
|
1677 |
+
public function settings_page_output() {
|
1678 |
+
$arr_settings_tabs = $this->getSettingsTabs();
|
1679 |
+
?>
|
1680 |
+
<div class="wrap">
|
1681 |
+
|
1682 |
+
<h1 class="SimpleHistoryPageHeadline">
|
1683 |
+
<div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
|
1684 |
+
<?php esc_html_e( 'Simple History Settings', 'simple-history' ); ?>
|
1685 |
+
</h1>
|
1686 |
+
|
1687 |
+
<?php
|
1688 |
+
$active_tab = isset( $_GET['selected-tab'] ) ? $_GET['selected-tab'] : 'settings';
|
1689 |
+
$settings_base_url = menu_page_url( self::SETTINGS_MENU_SLUG, 0 );
|
1690 |
+
?>
|
1691 |
+
|
1692 |
+
<h2 class="nav-tab-wrapper">
|
1693 |
+
<?php
|
1694 |
+
foreach ( $arr_settings_tabs as $one_tab ) {
|
1695 |
+
$tab_slug = $one_tab['slug'];
|
1696 |
+
|
1697 |
+
printf(
|
1698 |
+
'<a href="%3$s" class="nav-tab %4$s">%1$s</a>',
|
1699 |
+
$one_tab['name'], // 1
|
1700 |
+
$tab_slug, // 2
|
1701 |
+
esc_url( add_query_arg( 'selected-tab', $tab_slug, $settings_base_url ) ), // 3
|
1702 |
+
$active_tab == $tab_slug ? 'nav-tab-active' : '' // 4
|
1703 |
+
);
|
1704 |
+
}
|
1705 |
+
?>
|
1706 |
+
</h2>
|
1707 |
+
|
1708 |
+
<?php
|
1709 |
+
// Output contents for selected tab
|
1710 |
+
$arr_active_tab = wp_filter_object_list(
|
1711 |
+
$arr_settings_tabs,
|
1712 |
+
array(
|
1713 |
+
'slug' => $active_tab,
|
1714 |
+
)
|
1715 |
+
);
|
1716 |
+
$arr_active_tab = current( $arr_active_tab );
|
1717 |
+
|
1718 |
+
// We must have found an active tab and it must have a callable function
|
1719 |
+
if ( ! $arr_active_tab || ! is_callable( $arr_active_tab['function'] ) ) {
|
1720 |
+
wp_die( esc_html__( 'No valid callback found', 'simple-history' ) );
|
1721 |
+
}
|
1722 |
+
|
1723 |
+
$args = array(
|
1724 |
+
'arr_active_tab' => $arr_active_tab,
|
1725 |
+
);
|
1726 |
+
|
1727 |
+
call_user_func_array( $arr_active_tab['function'], array_values( $args ) );
|
1728 |
+
?>
|
1729 |
+
|
1730 |
+
</div>
|
1731 |
+
<?php
|
1732 |
+
}
|
1733 |
+
|
1734 |
+
public function settings_output_log() {
|
1735 |
+
include SIMPLE_HISTORY_PATH . 'templates/settings-log.php';
|
1736 |
+
}
|
1737 |
+
|
1738 |
+
public function settings_output_general() {
|
1739 |
+
include SIMPLE_HISTORY_PATH . 'templates/settings-general.php';
|
1740 |
+
}
|
1741 |
+
|
1742 |
+
public function settings_output_styles_example() {
|
1743 |
+
include SIMPLE_HISTORY_PATH . 'templates/settings-style-example.php';
|
1744 |
+
}
|
1745 |
+
|
1746 |
+
/**
|
1747 |
+
* Content for section intro. Leave it be, even if empty.
|
1748 |
+
* Called from add_sections_setting.
|
1749 |
+
*/
|
1750 |
+
public function settings_section_output() {
|
1751 |
+
}
|
1752 |
+
|
1753 |
+
/**
|
1754 |
+
* Add pages (history page and settings page)
|
1755 |
+
*/
|
1756 |
+
public function add_admin_pages() {
|
1757 |
+
// Add a history page as a sub-page below the Dashboard menu item
|
1758 |
+
if ( $this->setting_show_as_page() ) {
|
1759 |
+
/**
|
1760 |
+
* Filter to determine if history page should be added to page below dashboard or not
|
1761 |
+
*
|
1762 |
+
* @since 2.0.23
|
1763 |
+
*
|
1764 |
+
* @param bool Show the page or not
|
1765 |
+
*/
|
1766 |
+
$show_dashboard_page = apply_filters( 'simple_history/show_dashboard_page', true );
|
1767 |
+
|
1768 |
+
if ( $show_dashboard_page ) {
|
1769 |
+
add_submenu_page(
|
1770 |
+
apply_filters( 'simple_history/admin_location', 'index' ) . '.php',
|
1771 |
+
_x( 'Simple History', 'dashboard title name', 'simple-history' ),
|
1772 |
+
_x( 'Simple History', 'dashboard menu name', 'simple-history' ),
|
1773 |
+
$this->get_view_history_capability(),
|
1774 |
+
'simple_history_page',
|
1775 |
+
array( $this, 'history_page_output' )
|
1776 |
+
);
|
1777 |
+
}
|
1778 |
+
}
|
1779 |
+
|
1780 |
+
// Add a settings page
|
1781 |
+
$show_settings_page = true;
|
1782 |
+
$show_settings_page = apply_filters( 'simple_history_show_settings_page', $show_settings_page );
|
1783 |
+
$show_settings_page = apply_filters( 'simple_history/show_settings_page', $show_settings_page );
|
1784 |
+
|
1785 |
+
if ( $show_settings_page ) {
|
1786 |
+
add_options_page(
|
1787 |
+
__( 'Simple History Settings', 'simple-history' ),
|
1788 |
+
_x( 'Simple History', 'Options page menu title', 'simple-history' ),
|
1789 |
+
$this->get_view_settings_capability(),
|
1790 |
+
self::SETTINGS_MENU_SLUG,
|
1791 |
+
array( $this, 'settings_page_output' )
|
1792 |
+
);
|
1793 |
+
}
|
1794 |
+
}
|
1795 |
+
|
1796 |
+
/**
|
1797 |
+
* Add setting sections and settings for the settings page
|
1798 |
+
* Also maybe save some settings before outputing them
|
1799 |
+
*/
|
1800 |
+
public function add_settings() {
|
1801 |
+
// Clear the log if clear button was clicked in settings
|
1802 |
+
// and redirect user to show message.
|
1803 |
+
if (
|
1804 |
+
isset( $_GET['simple_history_clear_log_nonce'] ) &&
|
1805 |
+
wp_verify_nonce( $_GET['simple_history_clear_log_nonce'], 'simple_history_clear_log' )
|
1806 |
+
) {
|
1807 |
+
if ( $this->user_can_clear_log() ) {
|
1808 |
+
$this->clear_log();
|
1809 |
+
}
|
1810 |
+
|
1811 |
+
$msg = __( 'Cleared database', 'simple-history' );
|
1812 |
+
|
1813 |
+
add_settings_error(
|
1814 |
+
'simple_history_rss_feed_regenerate_secret',
|
1815 |
+
'simple_history_rss_feed_regenerate_secret',
|
1816 |
+
$msg,
|
1817 |
+
'updated'
|
1818 |
+
);
|
1819 |
+
|
1820 |
+
set_transient( 'settings_errors', get_settings_errors(), 30 );
|
1821 |
+
|
1822 |
+
$goback = esc_url_raw( add_query_arg( 'settings-updated', 'true', wp_get_referer() ) );
|
1823 |
+
wp_redirect( $goback );
|
1824 |
+
exit();
|
1825 |
+
}
|
1826 |
+
|
1827 |
+
// Section for general options.
|
1828 |
+
// Will contain settings like where to show simple history and number of items.
|
1829 |
+
$settings_section_general_id = self::SETTINGS_SECTION_GENERAL_ID;
|
1830 |
+
add_settings_section(
|
1831 |
+
$settings_section_general_id,
|
1832 |
+
'',
|
1833 |
+
array( $this, 'settings_section_output' ),
|
1834 |
+
self::SETTINGS_MENU_SLUG // Same slug as for options menu page.
|
1835 |
+
);
|
1836 |
+
|
1837 |
+
// Settings for the general settings section
|
1838 |
+
// Each setting = one row in the settings section
|
1839 |
+
// add_settings_field( $id, $title, $callback, $page, $section, $args );
|
1840 |
+
// Checkboxes for where to show simple history
|
1841 |
+
add_settings_field(
|
1842 |
+
'simple_history_show_where',
|
1843 |
+
__( 'Show history', 'simple-history' ),
|
1844 |
+
array( $this, 'settings_field_where_to_show' ),
|
1845 |
+
self::SETTINGS_MENU_SLUG,
|
1846 |
+
$settings_section_general_id
|
1847 |
+
);
|
1848 |
+
|
1849 |
+
// Nonces for show where inputs.
|
1850 |
+
register_setting( self::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_show_on_dashboard' );
|
1851 |
+
register_setting( self::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_show_as_page' );
|
1852 |
+
|
1853 |
+
// Number if items to show on the history page.
|
1854 |
+
add_settings_field(
|
1855 |
+
'simple_history_number_of_items',
|
1856 |
+
__( 'Number of items per page on the log page', 'simple-history' ),
|
1857 |
+
array( $this, 'settings_field_number_of_items' ),
|
1858 |
+
self::SETTINGS_MENU_SLUG,
|
1859 |
+
$settings_section_general_id
|
1860 |
+
);
|
1861 |
+
|
1862 |
+
// Nonces for number of items inputs.
|
1863 |
+
register_setting( self::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_pager_size' );
|
1864 |
+
|
1865 |
+
// Number if items to show on dashboard.
|
1866 |
+
add_settings_field(
|
1867 |
+
'simple_history_number_of_items_dashboard',
|
1868 |
+
__( 'Number of items per page on the dashboard', 'simple-history' ),
|
1869 |
+
array( $this, 'settings_field_number_of_items_dashboard' ),
|
1870 |
+
self::SETTINGS_MENU_SLUG,
|
1871 |
+
$settings_section_general_id
|
1872 |
+
);
|
1873 |
+
|
1874 |
+
// Nonces for number of items inputs.
|
1875 |
+
register_setting( self::SETTINGS_GENERAL_OPTION_GROUP, 'simple_history_pager_size_dashboard' );
|
1876 |
+
|
1877 |
+
// Link/button to clear log.
|
1878 |
+
if ( $this->user_can_clear_log() ) {
|
1879 |
+
add_settings_field(
|
1880 |
+
'simple_history_clear_log',
|
1881 |
+
__( 'Clear log', 'simple-history' ),
|
1882 |
+
array( $this, 'settings_field_clear_log' ),
|
1883 |
+
self::SETTINGS_MENU_SLUG,
|
1884 |
+
$settings_section_general_id
|
1885 |
+
);
|
1886 |
+
}
|
1887 |
+
}
|
1888 |
+
|
1889 |
+
/**
|
1890 |
+
* Output for page with the history
|
1891 |
+
*/
|
1892 |
+
public function history_page_output() {
|
1893 |
+
$pager_size = $this->get_pager_size();
|
1894 |
+
|
1895 |
+
/**
|
1896 |
+
* Filter the pager size setting for the history page
|
1897 |
+
*
|
1898 |
+
* @since 2.0
|
1899 |
+
*
|
1900 |
+
* @param int $pager_size
|
1901 |
+
*/
|
1902 |
+
$pager_size = apply_filters( 'simple_history/page_pager_size', $pager_size );
|
1903 |
+
?>
|
1904 |
+
|
1905 |
+
<div class="wrap SimpleHistoryWrap">
|
1906 |
+
|
1907 |
+
<h1 class="SimpleHistoryPageHeadline">
|
1908 |
+
<div class="dashicons dashicons-backup SimpleHistoryPageHeadline__icon"></div>
|
1909 |
+
<?php echo esc_html_x( 'Simple History', 'history page headline', 'simple-history' ); ?>
|
1910 |
+
</h1>
|
1911 |
+
|
1912 |
+
<?php
|
1913 |
+
/**
|
1914 |
+
* Fires before the gui div
|
1915 |
+
*
|
1916 |
+
* @since 2.0
|
1917 |
+
*
|
1918 |
+
* @param SimpleHistory $SimpleHistory This class.
|
1919 |
+
*/
|
1920 |
+
do_action( 'simple_history/history_page/before_gui', $this );
|
1921 |
+
?>
|
1922 |
+
|
1923 |
+
<div class="SimpleHistoryGuiWrap">
|
1924 |
+
|
1925 |
+
<div class="SimpleHistoryGui"
|
1926 |
+
data-pager-size='<?php echo esc_attr( $pager_size ); ?>'
|
1927 |
+
></div>
|
1928 |
+
<?php
|
1929 |
+
/**
|
1930 |
+
* Fires after the gui div
|
1931 |
+
*
|
1932 |
+
* @since 2.0
|
1933 |
+
*
|
1934 |
+
* @param SimpleHistory $SimpleHistory This class.
|
1935 |
+
*/
|
1936 |
+
do_action( 'simple_history/history_page/after_gui', $this );
|
1937 |
+
?>
|
1938 |
+
</div>
|
1939 |
+
</div>
|
1940 |
+
<?php
|
1941 |
+
}
|
1942 |
+
|
1943 |
+
/**
|
1944 |
+
* Get setting if plugin should be visible on dasboard.
|
1945 |
+
* Defaults to true
|
1946 |
+
*
|
1947 |
+
* @return bool
|
1948 |
+
*/
|
1949 |
+
public function setting_show_on_dashboard() {
|
1950 |
+
$show_on_dashboard = get_option( 'simple_history_show_on_dashboard', 1 );
|
1951 |
+
$show_on_dashboard = apply_filters( 'simple_history_show_on_dashboard', $show_on_dashboard );
|
1952 |
+
return (bool) $show_on_dashboard;
|
1953 |
+
}
|
1954 |
+
|
1955 |
+
/**
|
1956 |
+
* Should simple history be shown as a page
|
1957 |
+
* Defaults to true
|
1958 |
+
*
|
1959 |
+
* @return bool
|
1960 |
+
*/
|
1961 |
+
public function setting_show_as_page() {
|
1962 |
+
$setting = get_option( 'simple_history_show_as_page', 1 );
|
1963 |
+
$setting = apply_filters( 'simple_history_show_as_page', $setting );
|
1964 |
+
|
1965 |
+
return (bool) $setting;
|
1966 |
+
}
|
1967 |
+
|
1968 |
+
/**
|
1969 |
+
* Settings field for how many rows/items to show in log on the log page
|
1970 |
+
*/
|
1971 |
+
public function settings_field_number_of_items() {
|
1972 |
+
$current_pager_size = $this->get_pager_size();
|
1973 |
+
?>
|
1974 |
+
<select name="simple_history_pager_size">
|
1975 |
+
<option <?php echo $current_pager_size == 5 ? 'selected' : ''; ?> value="5">5</option>
|
1976 |
+
<option <?php echo $current_pager_size == 10 ? 'selected' : ''; ?> value="10">10</option>
|
1977 |
+
<option <?php echo $current_pager_size == 15 ? 'selected' : ''; ?> value="15">15</option>
|
1978 |
+
<option <?php echo $current_pager_size == 20 ? 'selected' : ''; ?> value="20">20</option>
|
1979 |
+
<option <?php echo $current_pager_size == 25 ? 'selected' : ''; ?> value="25">25</option>
|
1980 |
+
<option <?php echo $current_pager_size == 30 ? 'selected' : ''; ?> value="30">30</option>
|
1981 |
+
<option <?php echo $current_pager_size == 40 ? 'selected' : ''; ?> value="40">40</option>
|
1982 |
+
<option <?php echo $current_pager_size == 50 ? 'selected' : ''; ?> value="50">50</option>
|
1983 |
+
<option <?php echo $current_pager_size == 75 ? 'selected' : ''; ?> value="75">75</option>
|
1984 |
+
<option <?php echo $current_pager_size == 100 ? 'selected' : ''; ?> value="100">100</option>
|
1985 |
+
</select>
|
1986 |
+
<?php
|
1987 |
+
}
|
1988 |
+
|
1989 |
+
/**
|
1990 |
+
* Settings field for how many rows/items to show in log on the dashboard
|
1991 |
+
*/
|
1992 |
+
public function settings_field_number_of_items_dashboard() {
|
1993 |
+
$current_pager_size = $this->get_pager_size_dashboard();
|
1994 |
+
?>
|
1995 |
+
<select name="simple_history_pager_size_dashboard">
|
1996 |
+
<option <?php echo $current_pager_size == 5 ? 'selected' : ''; ?> value="5">5</option>
|
1997 |
+
<option <?php echo $current_pager_size == 10 ? 'selected' : ''; ?> value="10">10</option>
|
1998 |
+
<option <?php echo $current_pager_size == 15 ? 'selected' : ''; ?> value="15">15</option>
|
1999 |
+
<option <?php echo $current_pager_size == 20 ? 'selected' : ''; ?> value="20">20</option>
|
2000 |
+
<option <?php echo $current_pager_size == 25 ? 'selected' : ''; ?> value="25">25</option>
|
2001 |
+
<option <?php echo $current_pager_size == 30 ? 'selected' : ''; ?> value="30">30</option>
|
2002 |
+
<option <?php echo $current_pager_size == 40 ? 'selected' : ''; ?> value="40">40</option>
|
2003 |
+
<option <?php echo $current_pager_size == 50 ? 'selected' : ''; ?> value="50">50</option>
|
2004 |
+
<option <?php echo $current_pager_size == 75 ? 'selected' : ''; ?> value="75">75</option>
|
2005 |
+
<option <?php echo $current_pager_size == 100 ? 'selected' : ''; ?> value="100">100</option>
|
2006 |
+
</select>
|
2007 |
+
<?php
|
2008 |
+
}
|
2009 |
+
|
2010 |
+
/**
|
2011 |
+
* Settings field for where to show the log, page or dashboard
|
2012 |
+
*/
|
2013 |
+
public function settings_field_where_to_show() {
|
2014 |
+
$show_on_dashboard = $this->setting_show_on_dashboard();
|
2015 |
+
$show_as_page = $this->setting_show_as_page();
|
2016 |
+
?>
|
2017 |
+
|
2018 |
+
<input
|
2019 |
+
<?php
|
2020 |
+
echo $show_on_dashboard
|
2021 |
+
? "checked='checked'"
|
2022 |
+
: '';
|
2023 |
+
?>
|
2024 |
+
type="checkbox" value="1" name="simple_history_show_on_dashboard" id="simple_history_show_on_dashboard" class="simple_history_show_on_dashboard" />
|
2025 |
+
<label for="simple_history_show_on_dashboard"><?php esc_html_e( 'on the dashboard', 'simple-history' ); ?></label>
|
2026 |
+
|
2027 |
+
<br />
|
2028 |
+
|
2029 |
+
<input
|
2030 |
+
<?php
|
2031 |
+
echo $show_as_page
|
2032 |
+
? "checked='checked'"
|
2033 |
+
: '';
|
2034 |
+
?>
|
2035 |
+
type="checkbox" value="1" name="simple_history_show_as_page" id="simple_history_show_as_page" class="simple_history_show_as_page" />
|
2036 |
+
<label for="simple_history_show_as_page">
|
2037 |
+
<?php esc_html_e( 'as a page under the dashboard menu', 'simple-history' ); ?>
|
2038 |
+
</label>
|
2039 |
+
|
2040 |
+
<?php
|
2041 |
+
}
|
2042 |
+
|
2043 |
+
/**
|
2044 |
+
* Settings section to clear database
|
2045 |
+
*/
|
2046 |
+
public function settings_field_clear_log() {
|
2047 |
+
// Get base URL to current page.
|
2048 |
+
// Will be like "/wordpress/wp-admin/options-general.php?page=simple_history_settings_menu_slug&"
|
2049 |
+
$clear_link = add_query_arg( '', '' );
|
2050 |
+
|
2051 |
+
// Append nonce to URL.
|
2052 |
+
$clear_link = wp_nonce_url( $clear_link, 'simple_history_clear_log', 'simple_history_clear_log_nonce' );
|
2053 |
+
|
2054 |
+
$clear_days = $this->get_clear_history_interval();
|
2055 |
+
|
2056 |
+
echo '<p>';
|
2057 |
+
|
2058 |
+
if ( $clear_days > 0 ) {
|
2059 |
+
echo sprintf(
|
2060 |
+
esc_html__( 'Items in the database are automatically removed after %1$s days.', 'simple-history' ),
|
2061 |
+
esc_html( $clear_days )
|
2062 |
+
);
|
2063 |
+
} else {
|
2064 |
+
esc_html_e( 'Items in the database are kept forever.', 'simple-history' );
|
2065 |
+
}
|
2066 |
+
|
2067 |
+
echo '</p>';
|
2068 |
+
|
2069 |
+
printf(
|
2070 |
+
'<p><a class="button js-SimpleHistory-Settings-ClearLog" href="%2$s">%1$s</a></p>',
|
2071 |
+
esc_html__( 'Clear log now', 'simple-history' ),
|
2072 |
+
esc_url( $clear_link )
|
2073 |
+
);
|
2074 |
+
}
|
2075 |
+
|
2076 |
+
/**
|
2077 |
+
* How old log entried are allowed to be.
|
2078 |
+
* 0 = don't delete old entries.
|
2079 |
+
*
|
2080 |
+
* @return int Number of days.
|
2081 |
+
*/
|
2082 |
+
public function get_clear_history_interval() {
|
2083 |
+
$days = 60;
|
2084 |
+
|
2085 |
+
/**
|
2086 |
+
* Filter to modify number of days of history to keep.
|
2087 |
+
* Default is 60 days.
|
2088 |
+
*
|
2089 |
+
* @param $days Number of days of history to keep
|
2090 |
+
*/
|
2091 |
+
$days = (int) apply_filters( 'simple_history_db_purge_days_interval', $days );
|
2092 |
+
$days = (int) apply_filters( 'simple_history/db_purge_days_interval', $days );
|
2093 |
+
|
2094 |
+
return $days;
|
2095 |
+
}
|
2096 |
+
|
2097 |
+
/**
|
2098 |
+
* Removes all items from the log
|
2099 |
+
*/
|
2100 |
+
public function clear_log() {
|
2101 |
+
global $wpdb;
|
2102 |
+
|
2103 |
+
$tableprefix = $wpdb->prefix;
|
2104 |
+
|
2105 |
+
$simple_history_table = self::DBTABLE;
|
2106 |
+
$simple_history_context_table = self::DBTABLE_CONTEXTS;
|
2107 |
+
|
2108 |
+
// Get number of rows before delete.
|
2109 |
+
$sql_num_rows = "SELECT count(id) AS num_rows FROM {$tableprefix}{$simple_history_table}";
|
2110 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2111 |
+
$num_rows = $wpdb->get_var( $sql_num_rows, 0 );
|
2112 |
+
|
2113 |
+
// Use truncate instead of delete because it's much faster (I think, writing this much later).
|
2114 |
+
$sql = "TRUNCATE {$tableprefix}{$simple_history_table}";
|
2115 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2116 |
+
$wpdb->query( $sql );
|
2117 |
+
|
2118 |
+
$sql = "TRUNCATE {$tableprefix}{$simple_history_context_table}";
|
2119 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2120 |
+
$wpdb->query( $sql );
|
2121 |
+
|
2122 |
+
// Zero state sucks
|
2123 |
+
SimpleLogger()->info(
|
2124 |
+
__( 'The log for Simple History was cleared ({num_rows} rows were removed).', 'simple-history' ),
|
2125 |
+
array(
|
2126 |
+
'num_rows' => $num_rows,
|
2127 |
+
)
|
2128 |
+
);
|
2129 |
+
|
2130 |
+
$this->get_cache_incrementor( true );
|
2131 |
+
}
|
2132 |
+
|
2133 |
+
/**
|
2134 |
+
* Runs the purge_db() method sometimes
|
2135 |
+
* We don't want to call it each time because it performs SQL queries
|
2136 |
+
*
|
2137 |
+
* @since 2.0.17
|
2138 |
+
*/
|
2139 |
+
public function maybe_purge_db() {
|
2140 |
+
// How often should we try to do this?
|
2141 |
+
// Once a day = a bit tiresome.
|
2142 |
+
// Let's go with sundays; purge the log on sundays.
|
2143 |
+
// Day of week, 1 = mon, 7 = sun.
|
2144 |
+
$day_of_week = gmdate( 'N' );
|
2145 |
+
if ( 7 === (int) $day_of_week ) {
|
2146 |
+
$this->purge_db();
|
2147 |
+
}
|
2148 |
+
}
|
2149 |
+
|
2150 |
+
/**
|
2151 |
+
* Removes old entries from the db
|
2152 |
+
*/
|
2153 |
+
public function purge_db() {
|
2154 |
+
$do_purge_history = true;
|
2155 |
+
|
2156 |
+
$do_purge_history = apply_filters( 'simple_history_allow_db_purge', $do_purge_history );
|
2157 |
+
$do_purge_history = apply_filters( 'simple_history/allow_db_purge', $do_purge_history );
|
2158 |
+
|
2159 |
+
if ( ! $do_purge_history ) {
|
2160 |
+
return;
|
2161 |
+
}
|
2162 |
+
|
2163 |
+
$days = $this->get_clear_history_interval();
|
2164 |
+
|
2165 |
+
// Never clear log if days = 0.
|
2166 |
+
if ( 0 == $days ) {
|
2167 |
+
return;
|
2168 |
+
}
|
2169 |
+
|
2170 |
+
global $wpdb;
|
2171 |
+
|
2172 |
+
$table_name = $wpdb->prefix . self::DBTABLE;
|
2173 |
+
$table_name_contexts = $wpdb->prefix . self::DBTABLE_CONTEXTS;
|
2174 |
+
|
2175 |
+
while ( 1 > 0 ) {
|
2176 |
+
// Get id of rows to delete.
|
2177 |
+
$sql = $wpdb->prepare(
|
2178 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
|
2179 |
+
"SELECT id FROM $table_name WHERE DATE_ADD(date, INTERVAL %d DAY) < now() LIMIT 100000",
|
2180 |
+
$days
|
2181 |
+
);
|
2182 |
+
|
2183 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2184 |
+
$ids_to_delete = $wpdb->get_col( $sql );
|
2185 |
+
|
2186 |
+
if ( empty( $ids_to_delete ) ) {
|
2187 |
+
// Nothing to delete.
|
2188 |
+
return;
|
2189 |
+
}
|
2190 |
+
|
2191 |
+
$sql_ids_in = implode( ',', $ids_to_delete );
|
2192 |
+
|
2193 |
+
// Add number of deleted rows to total_rows option.
|
2194 |
+
$prev_total_rows = (int) get_option( 'simple_history_total_rows', 0 );
|
2195 |
+
$total_rows = $prev_total_rows + count( $ids_to_delete );
|
2196 |
+
update_option( 'simple_history_total_rows', $total_rows );
|
2197 |
+
|
2198 |
+
// Remove rows + contexts.
|
2199 |
+
$sql_delete_history = "DELETE FROM {$table_name} WHERE id IN ($sql_ids_in)";
|
2200 |
+
$sql_delete_history_context = "DELETE FROM {$table_name_contexts} WHERE history_id IN ($sql_ids_in)";
|
2201 |
+
|
2202 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2203 |
+
$wpdb->query( $sql_delete_history );
|
2204 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2205 |
+
$wpdb->query( $sql_delete_history_context );
|
2206 |
+
|
2207 |
+
$message = _nx(
|
2208 |
+
'Simple History removed one event that were older than {days} days',
|
2209 |
+
'Simple History removed {num_rows} events that were older than {days} days',
|
2210 |
+
count( $ids_to_delete ),
|
2211 |
+
'Database is being cleared automagically',
|
2212 |
+
'simple-history'
|
2213 |
+
);
|
2214 |
+
|
2215 |
+
SimpleLogger()->info(
|
2216 |
+
$message,
|
2217 |
+
array(
|
2218 |
+
'days' => $days,
|
2219 |
+
'num_rows' => count( $ids_to_delete ),
|
2220 |
+
)
|
2221 |
+
);
|
2222 |
+
|
2223 |
+
$this->get_cache_incrementor( true );
|
2224 |
+
}
|
2225 |
+
}
|
2226 |
+
|
2227 |
+
/**
|
2228 |
+
* Return plain text output for a log row
|
2229 |
+
* Uses the getLogRowPlainTextOutput of the logger that logged the row
|
2230 |
+
* with fallback to SimpleLogger if logger is not available.
|
2231 |
+
*
|
2232 |
+
* @param context $row
|
2233 |
+
* @return string
|
2234 |
+
*/
|
2235 |
+
public function getLogRowPlainTextOutput( $row ) {
|
2236 |
+
$row_logger = $row->logger;
|
2237 |
+
$logger = null;
|
2238 |
+
$row->context = isset( $row->context ) && is_array( $row->context ) ? $row->context : array();
|
2239 |
+
|
2240 |
+
if ( ! isset( $row->context['_message_key'] ) ) {
|
2241 |
+
$row->context['_message_key'] = null;
|
2242 |
+
}
|
2243 |
+
|
2244 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2245 |
+
if ( ! isset( $this->instantiatedLoggers[ $row_logger ] ) ) {
|
2246 |
+
$row_logger = 'SimpleLogger';
|
2247 |
+
}
|
2248 |
+
|
2249 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2250 |
+
|
2251 |
+
return $logger->getLogRowPlainTextOutput( $row );
|
2252 |
+
}
|
2253 |
+
|
2254 |
+
/**
|
2255 |
+
* Return header output for a log row.
|
2256 |
+
*
|
2257 |
+
* Uses the getLogRowHeaderOutput of the logger that logged the row
|
2258 |
+
* with fallback to SimpleLogger if logger is not available.
|
2259 |
+
*
|
2260 |
+
* Loggers are discouraged to override this in the loggers,
|
2261 |
+
* because the output should be the same for all items in the GUI.
|
2262 |
+
*
|
2263 |
+
* @param object $row
|
2264 |
+
* @return string
|
2265 |
+
*/
|
2266 |
+
public function getLogRowHeaderOutput( $row ) {
|
2267 |
+
$row_logger = $row->logger;
|
2268 |
+
$logger = null;
|
2269 |
+
$row->context = isset( $row->context ) && is_array( $row->context ) ? $row->context : array();
|
2270 |
+
|
2271 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2272 |
+
if ( ! isset( $this->instantiatedLoggers[ $row_logger ] ) ) {
|
2273 |
+
$row_logger = 'SimpleLogger';
|
2274 |
+
}
|
2275 |
+
|
2276 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2277 |
+
|
2278 |
+
return $logger->getLogRowHeaderOutput( $row );
|
2279 |
+
}
|
2280 |
+
|
2281 |
+
/**
|
2282 |
+
*
|
2283 |
+
*
|
2284 |
+
* @param object $row
|
2285 |
+
* @return string
|
2286 |
+
*/
|
2287 |
+
private function getLogRowSenderImageOutput( $row ) {
|
2288 |
+
$row_logger = $row->logger;
|
2289 |
+
$logger = null;
|
2290 |
+
$row->context = isset( $row->context ) && is_array( $row->context ) ? $row->context : array();
|
2291 |
+
|
2292 |
+
// Fallback to SimpleLogger if no logger exists for row
|
2293 |
+
if ( ! isset( $this->instantiatedLoggers[ $row_logger ] ) ) {
|
2294 |
+
$row_logger = 'SimpleLogger';
|
2295 |
+
}
|
2296 |
+
|
2297 |
+
$logger = $this->instantiatedLoggers[ $row_logger ]['instance'];
|
2298 |
+
|
2299 |
+
return $logger->getLogRowSenderImageOutput( $row );
|
2300 |
+
}
|
2301 |
+
|
2302 |
+
public function getLogRowDetailsOutput( $row ) {
|
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->getLogRowDetailsOutput( $row );
|
2315 |
+
}
|
2316 |
+
|
2317 |
+
/**
|
2318 |
+
* Works like json_encode, but adds JSON_PRETTY_PRINT if the current php version supports it
|
2319 |
+
* i.e. PHP is 5.4.0 or greated
|
2320 |
+
*
|
2321 |
+
* @param mixed $value array|object|string|whatever that is json_encode'able.
|
2322 |
+
*/
|
2323 |
+
public static function json_encode( $value ) {
|
2324 |
+
return version_compare( PHP_VERSION, '5.4.0' ) >= 0
|
2325 |
+
? json_encode( $value, JSON_PRETTY_PRINT )
|
2326 |
+
: json_encode( $value );
|
2327 |
+
}
|
2328 |
+
|
2329 |
+
/**
|
2330 |
+
* Returns true if $haystack ends with $needle
|
2331 |
+
*
|
2332 |
+
* @param string $haystack
|
2333 |
+
* @param string $needle
|
2334 |
+
*/
|
2335 |
+
public static function ends_with( $haystack, $needle ) {
|
2336 |
+
return $needle === substr( $haystack, -strlen( $needle ) );
|
2337 |
+
}
|
2338 |
+
|
2339 |
+
/**
|
2340 |
+
* Returns the HTML output for a log row, to be used in the GUI/Activity Feed.
|
2341 |
+
* This includes HTML for the header, the sender image, and the details.
|
2342 |
+
*
|
2343 |
+
* @param object $oneLogRow SimpleHistoryLogQuery array with data from SimpleHistoryLogQuery
|
2344 |
+
* @return string
|
2345 |
+
*/
|
2346 |
+
public function getLogRowHTMLOutput( $oneLogRow, $args ) {
|
2347 |
+
$defaults = array(
|
2348 |
+
'type' => 'overview', // or "single" to include more stuff (used in for example modal details window)
|
2349 |
+
);
|
2350 |
+
|
2351 |
+
$args = wp_parse_args( $args, $defaults );
|
2352 |
+
|
2353 |
+
$header_html = $this->getLogRowHeaderOutput( $oneLogRow );
|
2354 |
+
$plain_text_html = $this->getLogRowPlainTextOutput( $oneLogRow );
|
2355 |
+
$sender_image_html = $this->getLogRowSenderImageOutput( $oneLogRow );
|
2356 |
+
|
2357 |
+
// Details = for example thumbnail of media
|
2358 |
+
$details_html = trim( $this->getLogRowDetailsOutput( $oneLogRow ) );
|
2359 |
+
if ( $details_html ) {
|
2360 |
+
$details_html = sprintf( '<div class="SimpleHistoryLogitem__details">%1$s</div>', $details_html );
|
2361 |
+
}
|
2362 |
+
|
2363 |
+
// subsequentOccasions = including the current one
|
2364 |
+
$occasions_count = $oneLogRow->subsequentOccasions - 1;
|
2365 |
+
$occasions_html = '';
|
2366 |
+
|
2367 |
+
if ( $occasions_count > 0 ) {
|
2368 |
+
$occasions_html = '<div class="SimpleHistoryLogitem__occasions">';
|
2369 |
+
|
2370 |
+
$occasions_html .= '<a href="#" class="SimpleHistoryLogitem__occasionsLink">';
|
2371 |
+
$occasions_html .= sprintf(
|
2372 |
+
_n( '+%1$s similar event', '+%1$s similar events', $occasions_count, 'simple-history' ),
|
2373 |
+
$occasions_count
|
2374 |
+
);
|
2375 |
+
$occasions_html .= '</a>';
|
2376 |
+
|
2377 |
+
$occasions_html .= '<span class="SimpleHistoryLogitem__occasionsLoading">';
|
2378 |
+
$occasions_html .= sprintf( __( 'Loading…', 'simple-history' ), $occasions_count );
|
2379 |
+
$occasions_html .= '</span>';
|
2380 |
+
|
2381 |
+
$occasions_html .= '<span class="SimpleHistoryLogitem__occasionsLoaded">';
|
2382 |
+
$occasions_html .= sprintf( __( 'Showing %1$s more', 'simple-history' ), $occasions_count );
|
2383 |
+
$occasions_html .= '</span>';
|
2384 |
+
|
2385 |
+
$occasions_html .= '</div>';
|
2386 |
+
}
|
2387 |
+
|
2388 |
+
// Add data attributes to log row, so plugins can do stuff.
|
2389 |
+
$data_attrs = '';
|
2390 |
+
$data_attrs .= sprintf( ' data-row-id="%1$d" ', $oneLogRow->id );
|
2391 |
+
$data_attrs .= sprintf( ' data-occasions-count="%1$d" ', $occasions_count );
|
2392 |
+
$data_attrs .= sprintf( ' data-occasions-id="%1$s" ', esc_attr( $oneLogRow->occasionsID ) );
|
2393 |
+
|
2394 |
+
// Add data attributes for remote address and other ip number headers.
|
2395 |
+
if ( isset( $oneLogRow->context['_server_remote_addr'] ) ) {
|
2396 |
+
$data_attrs .= sprintf( ' data-ip-address="%1$s" ', esc_attr( $oneLogRow->context['_server_remote_addr'] ) );
|
2397 |
+
}
|
2398 |
+
|
2399 |
+
$arr_found_additional_ip_headers = $this->instantiatedLoggers['SimpleLogger']['instance']->get_event_ip_number_headers( $oneLogRow );
|
2400 |
+
|
2401 |
+
if ( $arr_found_additional_ip_headers ) {
|
2402 |
+
$data_attrs .= sprintf( ' data-ip-address-multiple="1" ' );
|
2403 |
+
}
|
2404 |
+
|
2405 |
+
// Add data attributes info for common things like logger, level, data, initiation.
|
2406 |
+
$data_attrs .= sprintf( ' data-logger="%1$s" ', esc_attr( $oneLogRow->logger ) );
|
2407 |
+
$data_attrs .= sprintf( ' data-level="%1$s" ', esc_attr( $oneLogRow->level ) );
|
2408 |
+
$data_attrs .= sprintf( ' data-date="%1$s" ', esc_attr( $oneLogRow->date ) );
|
2409 |
+
$data_attrs .= sprintf( ' data-initiator="%1$s" ', esc_attr( $oneLogRow->initiator ) );
|
2410 |
+
|
2411 |
+
if ( isset( $oneLogRow->context['_user_id'] ) ) {
|
2412 |
+
$data_attrs .= sprintf( ' data-initiator-user-id="%1$d" ', $oneLogRow->context['_user_id'] );
|
2413 |
+
}
|
2414 |
+
|
2415 |
+
// If type is single then include more details.
|
2416 |
+
// This is typically shown in the modal window when clickin the event date and time.
|
2417 |
+
$more_details_html = '';
|
2418 |
+
if ( $args['type'] == 'single' ) {
|
2419 |
+
$more_details_html = apply_filters(
|
2420 |
+
'simple_history/log_html_output_details_single/html_before_context_table',
|
2421 |
+
$more_details_html,
|
2422 |
+
$oneLogRow
|
2423 |
+
);
|
2424 |
+
|
2425 |
+
$more_details_html .= sprintf(
|
2426 |
+
'<h2 class="SimpleHistoryLogitem__moreDetailsHeadline">%1$s</h2>',
|
2427 |
+
__( 'Context data', 'simple-history' )
|
2428 |
+
);
|
2429 |
+
$more_details_html .=
|
2430 |
+
'<p>' . __( 'This is potentially useful meta data that a logger has saved.', 'simple-history' ) . '</p>';
|
2431 |
+
$more_details_html .= "<table class='SimpleHistoryLogitem__moreDetailsContext'>";
|
2432 |
+
$more_details_html .= sprintf(
|
2433 |
+
'<tr>
|
2434 |
<th>%1$s</th>
|
2435 |
<th>%2$s</th>
|
2436 |
</tr>',
|
2437 |
+
'Key',
|
2438 |
+
'Value'
|
2439 |
+
);
|
2440 |
+
|
2441 |
+
$logRowKeysToShow = array_fill_keys( array_keys( (array) $oneLogRow ), true );
|
2442 |
+
|
2443 |
+
/**
|
2444 |
+
* Filter what keys to show from oneLogRow
|
2445 |
+
*
|
2446 |
+
* Array is in format
|
2447 |
+
*
|
2448 |
+
* Array
|
2449 |
+
* (
|
2450 |
+
* [id] => 1
|
2451 |
+
* [logger] => 1
|
2452 |
+
* [level] => 1
|
2453 |
+
* ...
|
2454 |
+
* )
|
2455 |
+
*
|
2456 |
+
* @since 2.0.29
|
2457 |
+
*
|
2458 |
+
* @param array with keys to show. key to show = key. value = boolean to show or not.
|
2459 |
+
* @param object log row to show details from
|
2460 |
+
*/
|
2461 |
+
$logRowKeysToShow = apply_filters(
|
2462 |
+
'simple_history/log_html_output_details_table/row_keys_to_show',
|
2463 |
+
$logRowKeysToShow,
|
2464 |
+
$oneLogRow
|
2465 |
+
);
|
2466 |
+
|
2467 |
+
// Hide some keys by default
|
2468 |
+
unset(
|
2469 |
+
$logRowKeysToShow['occasionsID'],
|
2470 |
+
$logRowKeysToShow['subsequentOccasions'],
|
2471 |
+
$logRowKeysToShow['rep'],
|
2472 |
+
$logRowKeysToShow['repeated'],
|
2473 |
+
$logRowKeysToShow['occasionsIDType'],
|
2474 |
+
$logRowKeysToShow['context'],
|
2475 |
+
$logRowKeysToShow['type']
|
2476 |
+
);
|
2477 |
+
|
2478 |
+
foreach ( $oneLogRow as $rowKey => $rowVal ) {
|
2479 |
+
// Only columns from oneLogRow that exist in logRowKeysToShow will be outputed
|
2480 |
+
if ( ! array_key_exists( $rowKey, $logRowKeysToShow ) || ! $logRowKeysToShow[ $rowKey ] ) {
|
2481 |
+
continue;
|
2482 |
+
}
|
2483 |
+
|
2484 |
+
// skip arrays and objects and such
|
2485 |
+
if ( is_array( $rowVal ) || is_object( $rowVal ) ) {
|
2486 |
+
continue;
|
2487 |
+
}
|
2488 |
+
|
2489 |
+
$more_details_html .= sprintf(
|
2490 |
+
'<tr>
|
2491 |
<td>%1$s</td>
|
2492 |
<td>%2$s</td>
|
2493 |
</tr>',
|
2494 |
+
esc_html( $rowKey ),
|
2495 |
+
esc_html( $rowVal )
|
2496 |
+
);
|
2497 |
+
}
|
2498 |
+
|
2499 |
+
$logRowContextKeysToShow = array_fill_keys( array_keys( (array) $oneLogRow->context ), true );
|
2500 |
+
|
2501 |
+
/**
|
2502 |
+
* Filter what keys to show from the row context
|
2503 |
+
*
|
2504 |
+
* Array is in format
|
2505 |
+
*
|
2506 |
+
* Array
|
2507 |
+
* (
|
2508 |
+
* [plugin_slug] => 1
|
2509 |
+
* [plugin_name] => 1
|
2510 |
+
* [plugin_title] => 1
|
2511 |
+
* [plugin_description] => 1
|
2512 |
+
* [plugin_author] => 1
|
2513 |
+
* [plugin_version] => 1
|
2514 |
+
* ...
|
2515 |
+
* )
|
2516 |
+
*
|
2517 |
+
* @since 2.0.29
|
2518 |
+
*
|
2519 |
+
* @param array with keys to show. key to show = key. value = boolean to show or not.
|
2520 |
+
* @param object log row to show details from
|
2521 |
+
*/
|
2522 |
+
$logRowContextKeysToShow = apply_filters(
|
2523 |
+
'simple_history/log_html_output_details_table/context_keys_to_show',
|
2524 |
+
$logRowContextKeysToShow,
|
2525 |
+
$oneLogRow
|
2526 |
+
);
|
2527 |
+
|
2528 |
+
foreach ( $oneLogRow->context as $contextKey => $contextVal ) {
|
2529 |
+
// Only columns from context that exist in logRowContextKeysToShow will be outputed
|
2530 |
+
if (
|
2531 |
+
! array_key_exists( $contextKey, $logRowContextKeysToShow ) ||
|
2532 |
+
! $logRowContextKeysToShow[ $contextKey ]
|
2533 |
+
) {
|
2534 |
+
continue;
|
2535 |
+
}
|
2536 |
+
|
2537 |
+
$more_details_html .= sprintf(
|
2538 |
+
'<tr>
|
2539 |
<td>%1$s</td>
|
2540 |
<td>%2$s</td>
|
2541 |
</tr>',
|
2542 |
+
esc_html( $contextKey ),
|
2543 |
+
esc_html( $contextVal )
|
2544 |
+
);
|
2545 |
+
}
|
2546 |
+
|
2547 |
+
$more_details_html .= '</table>';
|
2548 |
+
|
2549 |
+
$more_details_html = apply_filters(
|
2550 |
+
'simple_history/log_html_output_details_single/html_after_context_table',
|
2551 |
+
$more_details_html,
|
2552 |
+
$oneLogRow
|
2553 |
+
);
|
2554 |
+
|
2555 |
+
$more_details_html = sprintf(
|
2556 |
+
'<div class="SimpleHistoryLogitem__moreDetails">%1$s</div>',
|
2557 |
+
$more_details_html
|
2558 |
+
);
|
2559 |
+
} // End if().
|
2560 |
+
|
2561 |
+
// Classes to add to log item li element
|
2562 |
+
$classes = array(
|
2563 |
+
'SimpleHistoryLogitem',
|
2564 |
+
"SimpleHistoryLogitem--loglevel-{$oneLogRow->level}",
|
2565 |
+
"SimpleHistoryLogitem--logger-{$oneLogRow->logger}",
|
2566 |
+
);
|
2567 |
+
|
2568 |
+
if ( isset( $oneLogRow->initiator ) && ! empty( $oneLogRow->initiator ) ) {
|
2569 |
+
$classes[] = 'SimpleHistoryLogitem--initiator-' . $oneLogRow->initiator;
|
2570 |
+
}
|
2571 |
+
|
2572 |
+
if ( $arr_found_additional_ip_headers ) {
|
2573 |
+
$classes[] = 'SimpleHistoryLogitem--IPAddress-multiple';
|
2574 |
+
}
|
2575 |
+
|
2576 |
+
// Always append the log level tag
|
2577 |
+
$log_level_tag_html = sprintf(
|
2578 |
+
' <span class="SimpleHistoryLogitem--logleveltag SimpleHistoryLogitem--logleveltag-%1$s">%2$s</span>',
|
2579 |
+
$oneLogRow->level,
|
2580 |
+
$this->getLogLevelTranslated( $oneLogRow->level )
|
2581 |
+
);
|
2582 |
+
|
2583 |
+
$plain_text_html .= $log_level_tag_html;
|
2584 |
+
|
2585 |
+
/**
|
2586 |
+
* Filter to modify classes added to item li element
|
2587 |
+
*
|
2588 |
+
* @since 2.0.7
|
2589 |
+
*
|
2590 |
+
* @param $classes Array with classes
|
2591 |
+
*/
|
2592 |
+
$classes = apply_filters( 'simple_history/logrowhtmloutput/classes', $classes );
|
2593 |
+
|
2594 |
+
// Generate the HTML output for a row
|
2595 |
+
$output = sprintf(
|
2596 |
+
'
|
2597 |
<li %8$s class="%10$s">
|
2598 |
<div class="SimpleHistoryLogitem__firstcol">
|
2599 |
<div class="SimpleHistoryLogitem__senderImage">%3$s</div>
|
2607 |
</div>
|
2608 |
</li>
|
2609 |
',
|
2610 |
+
$header_html, // 1
|
2611 |
+
$plain_text_html, // 2
|
2612 |
+
$sender_image_html, // 3
|
2613 |
+
$occasions_html, // 4
|
2614 |
+
$oneLogRow->level, // 5
|
2615 |
+
$details_html, // 6
|
2616 |
+
$oneLogRow->logger, // 7
|
2617 |
+
$data_attrs, // 8 data attributes
|
2618 |
+
$more_details_html, // 9
|
2619 |
+
esc_attr( join( ' ', $classes ) ) // 10
|
2620 |
+
);
|
2621 |
+
|
2622 |
+
// Get the main message row.
|
2623 |
+
// Should be as plain as possible, like plain text
|
2624 |
+
// but with links to for example users and posts
|
2625 |
+
// SimpleLoggerFormatter::getRowTextOutput($oneLogRow);
|
2626 |
+
// Get detailed HTML-based output
|
2627 |
+
// May include images, lists, any cool stuff needed to view
|
2628 |
+
// SimpleLoggerFormatter::getRowHTMLOutput($oneLogRow);
|
2629 |
+
return trim( $output );
|
2630 |
+
}
|
2631 |
+
|
2632 |
+
/**
|
2633 |
+
* Return translated loglevel
|
2634 |
+
*
|
2635 |
+
* @since 2.0.14
|
2636 |
+
* @param string $loglevel
|
2637 |
+
* @return string translated loglevel
|
2638 |
+
*/
|
2639 |
+
public function getLogLevelTranslated( $loglevel ) {
|
2640 |
+
$str_translated = '';
|
2641 |
+
|
2642 |
+
switch ( $loglevel ) {
|
2643 |
+
// Lowercase
|
2644 |
+
case 'emergency':
|
2645 |
+
$str_translated = _x( 'emergency', 'Log level in gui', 'simple-history' );
|
2646 |
+
break;
|
2647 |
+
|
2648 |
+
case 'alert':
|
2649 |
+
$str_translated = _x( 'alert', 'Log level in gui', 'simple-history' );
|
2650 |
+
break;
|
2651 |
+
|
2652 |
+
case 'critical':
|
2653 |
+
$str_translated = _x( 'critical', 'Log level in gui', 'simple-history' );
|
2654 |
+
break;
|
2655 |
+
|
2656 |
+
case 'error':
|
2657 |
+
$str_translated = _x( 'error', 'Log level in gui', 'simple-history' );
|
2658 |
+
break;
|
2659 |
+
|
2660 |
+
case 'warning':
|
2661 |
+
$str_translated = _x( 'warning', 'Log level in gui', 'simple-history' );
|
2662 |
+
break;
|
2663 |
+
|
2664 |
+
case 'notice':
|
2665 |
+
$str_translated = _x( 'notice', 'Log level in gui', 'simple-history' );
|
2666 |
+
break;
|
2667 |
+
|
2668 |
+
case 'info':
|
2669 |
+
$str_translated = _x( 'info', 'Log level in gui', 'simple-history' );
|
2670 |
+
break;
|
2671 |
+
|
2672 |
+
case 'debug':
|
2673 |
+
$str_translated = _x( 'debug', 'Log level in gui', 'simple-history' );
|
2674 |
+
break;
|
2675 |
+
|
2676 |
+
// Uppercase
|
2677 |
+
case 'Emergency':
|
2678 |
+
$str_translated = _x( 'Emergency', 'Log level in gui', 'simple-history' );
|
2679 |
+
break;
|
2680 |
+
|
2681 |
+
case 'Alert':
|
2682 |
+
$str_translated = _x( 'Alert', 'Log level in gui', 'simple-history' );
|
2683 |
+
break;
|
2684 |
+
|
2685 |
+
case 'Critical':
|
2686 |
+
$str_translated = _x( 'Critical', 'Log level in gui', 'simple-history' );
|
2687 |
+
break;
|
2688 |
+
|
2689 |
+
case 'Error':
|
2690 |
+
$str_translated = _x( 'Error', 'Log level in gui', 'simple-history' );
|
2691 |
+
break;
|
2692 |
+
|
2693 |
+
case 'Warning':
|
2694 |
+
$str_translated = _x( 'Warning', 'Log level in gui', 'simple-history' );
|
2695 |
+
break;
|
2696 |
+
|
2697 |
+
case 'Notice':
|
2698 |
+
$str_translated = _x( 'Notice', 'Log level in gui', 'simple-history' );
|
2699 |
+
break;
|
2700 |
+
|
2701 |
+
case 'Info':
|
2702 |
+
$str_translated = _x( 'Info', 'Log level in gui', 'simple-history' );
|
2703 |
+
break;
|
2704 |
+
|
2705 |
+
case 'Debug':
|
2706 |
+
$str_translated = _x( 'Debug', 'Log level in gui', 'simple-history' );
|
2707 |
+
break;
|
2708 |
+
|
2709 |
+
default:
|
2710 |
+
$str_translated = $loglevel;
|
2711 |
+
} // End switch().
|
2712 |
+
|
2713 |
+
return $str_translated;
|
2714 |
+
}
|
2715 |
+
|
2716 |
+
public function getInstantiatedLoggers() {
|
2717 |
+
return $this->instantiatedLoggers;
|
2718 |
+
}
|
2719 |
+
|
2720 |
+
public function getInstantiatedDropins() {
|
2721 |
+
return $this->instantiatedDropins;
|
2722 |
+
}
|
2723 |
+
|
2724 |
+
/**
|
2725 |
+
* @param string $slug
|
2726 |
+
* @return mixed logger instance if found, bool false if logger not found
|
2727 |
+
*/
|
2728 |
+
public function getInstantiatedLoggerBySlug( $slug = '' ) {
|
2729 |
+
if ( empty( $slug ) ) {
|
2730 |
+
return false;
|
2731 |
+
}
|
2732 |
+
|
2733 |
+
foreach ( $this->getInstantiatedLoggers() as $one_logger ) {
|
2734 |
+
if ( $slug == $one_logger['instance']->slug ) {
|
2735 |
+
return $one_logger['instance'];
|
2736 |
+
}
|
2737 |
+
}
|
2738 |
+
|
2739 |
+
return false;
|
2740 |
+
}
|
2741 |
+
|
2742 |
+
/**
|
2743 |
+
* Check which loggers a user has the right to read and return an array
|
2744 |
+
* with all loggers they are allowed to read
|
2745 |
+
*
|
2746 |
+
* @param int $user_id Id of user to get loggers for. Defaults to current user id.
|
2747 |
+
* @param string $format format to return loggers in. Default is array. Can also be "sql"
|
2748 |
+
* @return array
|
2749 |
+
*/
|
2750 |
+
public function getLoggersThatUserCanRead( $user_id = '', $format = 'array' ) {
|
2751 |
+
$arr_loggers_user_can_view = array();
|
2752 |
+
|
2753 |
+
if ( ! is_numeric( $user_id ) ) {
|
2754 |
+
$user_id = get_current_user_id();
|
2755 |
+
}
|
2756 |
+
|
2757 |
+
$loggers = $this->getInstantiatedLoggers();
|
2758 |
+
foreach ( $loggers as $one_logger ) {
|
2759 |
+
$logger_capability = $one_logger['instance']->getCapability();
|
2760 |
+
|
2761 |
+
// $arr_loggers_user_can_view = apply_filters("simple_history/loggers_user_can_read", $user_id, $arr_loggers_user_can_view);
|
2762 |
+
$user_can_read_logger = user_can( $user_id, $logger_capability );
|
2763 |
+
$user_can_read_logger = apply_filters(
|
2764 |
+
'simple_history/loggers_user_can_read/can_read_single_logger',
|
2765 |
+
$user_can_read_logger,
|
2766 |
+
$one_logger['instance'],
|
2767 |
+
$user_id
|
2768 |
+
);
|
2769 |
+
|
2770 |
+
if ( $user_can_read_logger ) {
|
2771 |
+
$arr_loggers_user_can_view[] = $one_logger;
|
2772 |
+
}
|
2773 |
+
}
|
2774 |
+
|
2775 |
+
/**
|
2776 |
+
* Fires before Simple History does it's init stuff
|
2777 |
+
*
|
2778 |
+
* @since 2.0
|
2779 |
+
*
|
2780 |
+
* @param array $arr_loggers_user_can_view Array with loggers that user $user_id can read
|
2781 |
+
* @param int user_id ID of user to check read capability for
|
2782 |
+
*/
|
2783 |
+
$arr_loggers_user_can_view = apply_filters(
|
2784 |
+
'simple_history/loggers_user_can_read',
|
2785 |
+
$arr_loggers_user_can_view,
|
2786 |
+
$user_id
|
2787 |
+
);
|
2788 |
+
|
2789 |
+
// just return array with slugs in parenthesis suitable for sql-where
|
2790 |
+
if ( 'sql' == $format ) {
|
2791 |
+
$str_return = '(';
|
2792 |
+
|
2793 |
+
if ( count( $arr_loggers_user_can_view ) ) {
|
2794 |
+
foreach ( $arr_loggers_user_can_view as $one_logger ) {
|
2795 |
+
$str_return .= sprintf( '"%1$s", ', esc_sql( $one_logger['instance']->slug ) );
|
2796 |
+
}
|
2797 |
+
|
2798 |
+
$str_return = rtrim( $str_return, ' ,' );
|
2799 |
+
} else {
|
2800 |
+
// user was not allowed to read any loggers, return in (NULL) to return nothing
|
2801 |
+
$str_return .= 'NULL';
|
2802 |
+
}
|
2803 |
+
|
2804 |
+
$str_return .= ')';
|
2805 |
+
|
2806 |
+
return $str_return;
|
2807 |
+
}
|
2808 |
+
|
2809 |
+
return $arr_loggers_user_can_view;
|
2810 |
+
}
|
2811 |
+
|
2812 |
+
/**
|
2813 |
+
* Retrieve the avatar for a user who provided a user ID or email address.
|
2814 |
+
* A modified version of the function that comes with WordPress, but we
|
2815 |
+
* want to allow/show gravatars even if they are disabled in discussion settings
|
2816 |
+
*
|
2817 |
+
* @since 2.0
|
2818 |
+
*
|
2819 |
+
* @param string $email email address
|
2820 |
+
* @param int $size Size of the avatar image
|
2821 |
+
* @param string $default URL to a default image to use if no avatar is available
|
2822 |
+
* @param string $alt Alternative text to use in image tag. Defaults to blank
|
2823 |
+
* @return string <img> tag for the user's avatar
|
2824 |
+
*/
|
2825 |
+
public function get_avatar( $email, $size = '96', $default = '', $alt = false ) {
|
2826 |
+
// WP setting for avatars is to show, so just use the built in function
|
2827 |
+
if ( get_option( 'show_avatars' ) ) {
|
2828 |
+
$avatar = get_avatar( $email, $size, $default, $alt );
|
2829 |
+
|
2830 |
+
return $avatar;
|
2831 |
+
} else {
|
2832 |
+
// WP setting for avatar was to not show, but we do it anyway, using the same code as get_avatar() would have used
|
2833 |
+
if ( false === $alt ) {
|
2834 |
+
$safe_alt = '';
|
2835 |
+
} else {
|
2836 |
+
$safe_alt = esc_attr( $alt );
|
2837 |
+
}
|
2838 |
+
|
2839 |
+
if ( ! is_numeric( $size ) ) {
|
2840 |
+
$size = '96';
|
2841 |
+
}
|
2842 |
+
|
2843 |
+
if ( empty( $default ) ) {
|
2844 |
+
$avatar_default = get_option( 'avatar_default' );
|
2845 |
+
if ( empty( $avatar_default ) ) {
|
2846 |
+
$default = 'mystery';
|
2847 |
+
} else {
|
2848 |
+
$default = $avatar_default;
|
2849 |
+
}
|
2850 |
+
}
|
2851 |
+
|
2852 |
+
if ( ! empty( $email ) ) {
|
2853 |
+
$email_hash = md5( strtolower( trim( $email ) ) );
|
2854 |
+
}
|
2855 |
+
|
2856 |
+
if ( is_ssl() ) {
|
2857 |
+
$host = 'https://secure.gravatar.com';
|
2858 |
+
} else {
|
2859 |
+
if ( ! empty( $email ) ) {
|
2860 |
+
$host = sprintf( 'http://%d.gravatar.com', hexdec( $email_hash[0] ) % 2 );
|
2861 |
+
} else {
|
2862 |
+
$host = 'http://0.gravatar.com';
|
2863 |
+
}
|
2864 |
+
}
|
2865 |
+
|
2866 |
+
if ( 'mystery' == $default ) {
|
2867 |
+
$default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}";
|
2868 |
+
} elseif ( 'blank' == $default ) {
|
2869 |
+
$default = $email ? 'blank' : includes_url( 'images/blank.gif' );
|
2870 |
+
} elseif ( ! empty( $email ) && 'gravatar_default' == $default ) {
|
2871 |
+
$default = '';
|
2872 |
+
} elseif ( 'gravatar_default' == $default ) {
|
2873 |
+
$default = "$host/avatar/?s={$size}";
|
2874 |
+
} elseif ( empty( $email ) ) {
|
2875 |
+
$default = "$host/avatar/?d=$default&s={$size}";
|
2876 |
+
} elseif ( strpos( $default, 'http://' ) === 0 ) {
|
2877 |
+
$default = add_query_arg( 's', $size, $default );
|
2878 |
+
}
|
2879 |
+
|
2880 |
+
if ( ! empty( $email ) ) {
|
2881 |
+
$out = "$host/avatar/";
|
2882 |
+
$out .= $email_hash;
|
2883 |
+
$out .= '?s=' . $size;
|
2884 |
+
$out .= '&d=' . urlencode( $default );
|
2885 |
+
|
2886 |
+
$rating = get_option( 'avatar_rating' );
|
2887 |
+
if ( ! empty( $rating ) ) {
|
2888 |
+
$out .= "&r={$rating}";
|
2889 |
+
}
|
2890 |
+
|
2891 |
+
$out = str_replace( '&', '&', esc_url( $out ) );
|
2892 |
+
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
|
2893 |
+
} else {
|
2894 |
+
$out = esc_url( $default );
|
2895 |
+
$avatar = "<img alt='{$safe_alt}' src='{$out}' class='avatar avatar-{$size} photo avatar-default' height='{$size}' width='{$size}' />";
|
2896 |
+
}
|
2897 |
+
|
2898 |
+
/**
|
2899 |
+
* Filter the avatar to retrieve.
|
2900 |
+
* Same filter WordPress uses
|
2901 |
+
*
|
2902 |
+
* @since 2.0.19
|
2903 |
+
*
|
2904 |
+
* @param string $avatar Image tag for the user's avatar.
|
2905 |
+
* @param int|object|string $id_or_email A user ID, email address, or comment object.
|
2906 |
+
* @param int $size Square avatar width and height in pixels to retrieve.
|
2907 |
+
* @param string $alt Alternative text to use in the avatar image tag.
|
2908 |
+
* Default empty.
|
2909 |
+
*/
|
2910 |
+
$avatar = apply_filters( 'get_avatar', $avatar, $email, $size, $default, $alt ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
2911 |
+
|
2912 |
+
return $avatar;
|
2913 |
+
} // End if().
|
2914 |
+
}
|
2915 |
+
|
2916 |
+
/**
|
2917 |
+
* Quick stats above the log
|
2918 |
+
* Uses filter "simple_history/history_page/before_gui" to output its contents
|
2919 |
+
*/
|
2920 |
+
public function output_quick_stats() {
|
2921 |
+
global $wpdb;
|
2922 |
+
|
2923 |
+
// Get number of events today
|
2924 |
+
$logQuery = new SimpleHistoryLogQuery();
|
2925 |
+
$logResults = $logQuery->query(
|
2926 |
+
array(
|
2927 |
+
'posts_per_page' => 1,
|
2928 |
+
'date_from' => strtotime( 'today' ),
|
2929 |
+
)
|
2930 |
+
);
|
2931 |
+
|
2932 |
+
$total_row_count = (int) $logResults['total_row_count'];
|
2933 |
+
|
2934 |
+
// Get sql query for where to read only loggers current user is allowed to read/view
|
2935 |
+
$sql_loggers_in = $this->getLoggersThatUserCanRead( get_current_user_id(), 'sql' );
|
2936 |
+
|
2937 |
+
// Get number of users today, i.e. events with wp_user as initiator
|
2938 |
+
$sql_users_today = sprintf(
|
2939 |
+
'
|
|
|
|
|
|
|
|
|
|
|
2940 |
SELECT
|
2941 |
DISTINCT(c.value) AS user_id
|
|
|
2942 |
FROM %3$s AS h
|
2943 |
INNER JOIN %4$s AS c
|
2944 |
ON c.history_id = h.id AND c.key = "_user_id"
|
2947 |
AND logger IN %1$s
|
2948 |
AND date > "%2$s"
|
2949 |
',
|
2950 |
+
$sql_loggers_in,
|
2951 |
+
gmdate( 'Y-m-d H:i', strtotime( 'today' ) ),
|
2952 |
+
$wpdb->prefix . self::DBTABLE,
|
2953 |
+
$wpdb->prefix . self::DBTABLE_CONTEXTS
|
2954 |
+
);
|
2955 |
+
|
2956 |
+
$cache_key = 'quick_stats_users_today_' . md5( serialize( $sql_loggers_in ) );
|
2957 |
+
$cache_group = 'simple-history-' . $this->get_cache_incrementor();
|
2958 |
+
$results_users_today = wp_cache_get( $cache_key, $cache_group );
|
2959 |
+
|
2960 |
+
if ( false === $results_users_today ) {
|
2961 |
+
$results_users_today = $wpdb->get_results( $sql_users_today ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2962 |
+
wp_cache_set( $cache_key, $results_users_today, $cache_group );
|
2963 |
+
}
|
2964 |
+
|
2965 |
+
$count_users_today = count( $results_users_today );
|
2966 |
+
|
2967 |
+
// Get number of other sources (not wp_user).
|
2968 |
+
$sql_other_sources_where = sprintf(
|
2969 |
+
'
|
2970 |
initiator <> "wp_user"
|
2971 |
AND logger IN %1$s
|
2972 |
AND date > "%2$s"
|
2973 |
',
|
2974 |
+
$sql_loggers_in,
|
2975 |
+
gmdate( 'Y-m-d H:i', strtotime( 'today' ) ),
|
2976 |
+
$wpdb->prefix . self::DBTABLE,
|
2977 |
+
$wpdb->prefix . self::DBTABLE_CONTEXTS
|
2978 |
+
);
|
2979 |
|
2980 |
+
$sql_other_sources_where = apply_filters( 'simple_history/quick_stats_where', $sql_other_sources_where );
|
2981 |
|
2982 |
+
$sql_other_sources = sprintf(
|
2983 |
+
'
|
2984 |
SELECT
|
2985 |
DISTINCT(h.initiator) AS initiator
|
2986 |
FROM %3$s AS h
|
2987 |
WHERE
|
2988 |
%5$s
|
2989 |
',
|
2990 |
+
$sql_loggers_in,
|
2991 |
+
gmdate( 'Y-m-d H:i', strtotime( 'today' ) ),
|
2992 |
+
$wpdb->prefix . self::DBTABLE,
|
2993 |
+
$wpdb->prefix . self::DBTABLE_CONTEXTS,
|
2994 |
+
$sql_other_sources_where // 5
|
2995 |
+
);
|
2996 |
+
|
2997 |
+
$cache_key = 'quick_stats_results_other_sources_today_' . md5( serialize( $sql_other_sources ) );
|
2998 |
+
$results_other_sources_today = wp_cache_get( $cache_key, $cache_group );
|
2999 |
+
|
3000 |
+
if ( false === $results_other_sources_today ) {
|
3001 |
+
$results_other_sources_today = $wpdb->get_results( $sql_other_sources ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
3002 |
+
wp_cache_set( $cache_key, $results_other_sources_today, $cache_group );
|
3003 |
+
}
|
3004 |
+
|
3005 |
+
$count_other_sources = count( $results_other_sources_today );
|
3006 |
+
?>
|
3007 |
+
<div class="SimpleHistoryQuickStats">
|
3008 |
+
<p>
|
3009 |
+
<?php
|
3010 |
+
$msg_tmpl = '';
|
3011 |
+
|
3012 |
+
// No results today at all
|
3013 |
+
if ( $total_row_count == 0 ) {
|
3014 |
+
$msg_tmpl = __( 'No events today so far.', 'simple-history' );
|
3015 |
+
} else {
|
3016 |
+
/*
|
3017 |
+
Type of results
|
3018 |
+
x1 event today from 1 user.
|
3019 |
+
x1 event today from 1 source.
|
3020 |
+
3 events today from 1 user.
|
3021 |
+
x2 events today from 2 users.
|
3022 |
+
x2 events today from 1 user and 1 other source.
|
3023 |
+
x3 events today from 2 users and 1 other source.
|
3024 |
+
x3 events today from 1 user and 2 other sources.
|
3025 |
+
x4 events today from 2 users and 2 other sources.
|
3026 |
+
*/
|
3027 |
+
|
3028 |
+
// A single event existed and was from a user
|
3029 |
+
// 1 event today from 1 user.
|
3030 |
+
if ( $total_row_count == 1 && $count_users_today == 1 ) {
|
3031 |
+
$msg_tmpl .= __( 'One event today from one user.', 'simple-history' );
|
3032 |
+
}
|
3033 |
+
|
3034 |
+
// A single event existed and was from another source
|
3035 |
+
// 1 event today from 1 source.
|
3036 |
+
if ( $total_row_count == 1 && ! $count_users_today ) {
|
3037 |
+
$msg_tmpl .= __( 'One event today from one source.', 'simple-history' );
|
3038 |
+
}
|
3039 |
+
|
3040 |
+
// Multiple events from a single user
|
3041 |
+
// 3 events today from one user.
|
3042 |
+
if ( $total_row_count > 1 && $count_users_today == 1 && ! $count_other_sources ) {
|
3043 |
+
$msg_tmpl .= __( '%1$d events today from one user.', 'simple-history' );
|
3044 |
+
}
|
3045 |
+
|
3046 |
+
// Multiple events from only users
|
3047 |
+
// 2 events today from 2 users.
|
3048 |
+
if ( $total_row_count > 1 && $count_users_today == $total_row_count ) {
|
3049 |
+
$msg_tmpl .= __( '%1$d events today from %2$d users.', 'simple-history' );
|
3050 |
+
}
|
3051 |
+
|
3052 |
+
// Multiple events from 1 single user and 1 single other source
|
3053 |
+
// 2 events today from 1 user and 1 other source.
|
3054 |
+
if ( $total_row_count && 1 == $count_users_today && 1 == $count_other_sources ) {
|
3055 |
+
$msg_tmpl .= __( '%1$d events today from one user and one other source.', 'simple-history' );
|
3056 |
+
}
|
3057 |
+
|
3058 |
+
// Multiple events from multple users but from only 1 single other source
|
3059 |
+
// 3 events today from 2 users and 1 other source.
|
3060 |
+
if ( $total_row_count > 1 && $count_users_today > 1 && $count_other_sources == 1 ) {
|
3061 |
+
$msg_tmpl .= __( '%1$d events today from one user and one other source.', 'simple-history' );
|
3062 |
+
}
|
3063 |
+
|
3064 |
+
// Multiple events from 1 user but from multiple other source
|
3065 |
+
// 3 events today from 1 user and 2 other sources.
|
3066 |
+
if ( $total_row_count > 1 && 1 == $count_users_today && $count_other_sources > 1 ) {
|
3067 |
+
$msg_tmpl .= __( '%1$d events today from one user and %3$d other sources.', 'simple-history' );
|
3068 |
+
}
|
3069 |
+
|
3070 |
+
// Multiple events from multiple user and from multiple other sources
|
3071 |
+
// 4 events today from 2 users and 2 other sources.
|
3072 |
+
if ( $total_row_count > 1 && $count_users_today > 1 && $count_other_sources > 1 ) {
|
3073 |
+
$msg_tmpl .= __( '%1$s events today from %2$d users and %3$d other sources.', 'simple-history' );
|
3074 |
+
}
|
3075 |
+
} // End if().
|
3076 |
+
|
3077 |
+
// Show stats if we have something to output.
|
3078 |
+
if ( $msg_tmpl ) {
|
3079 |
+
printf(
|
3080 |
+
esc_html( $msg_tmpl ),
|
3081 |
+
(int) $logResults['total_row_count'], // 1
|
3082 |
+
(int) $count_users_today, // 2
|
3083 |
+
(int) $count_other_sources // 3
|
3084 |
+
);
|
3085 |
+
}
|
3086 |
+
?>
|
3087 |
+
</p>
|
3088 |
+
</div>
|
3089 |
+
<?php
|
3090 |
+
}
|
3091 |
+
|
3092 |
+
/**
|
3093 |
+
* https://www.tollmanz.com/invalidation-schemes/
|
3094 |
+
*
|
3095 |
+
* @param $refresh bool
|
3096 |
+
* @return string
|
3097 |
+
*/
|
3098 |
+
public static function get_cache_incrementor( $refresh = false ) {
|
3099 |
+
$incrementor_key = 'simple_history_incrementor';
|
3100 |
+
$incrementor_value = wp_cache_get( $incrementor_key );
|
3101 |
+
|
3102 |
+
if ( false === $incrementor_value || true === $refresh ) {
|
3103 |
+
$incrementor_value = time();
|
3104 |
+
wp_cache_set( $incrementor_key, $incrementor_value );
|
3105 |
+
}
|
3106 |
+
|
3107 |
+
return $incrementor_value;
|
3108 |
+
}
|
3109 |
+
|
3110 |
+
// Number of rows the last n days.
|
3111 |
+
public function get_num_events_last_n_days( $period_days = 28 ) {
|
3112 |
+
$transient_key = 'sh_' . md5( __METHOD__ . $period_days . '_2' );
|
3113 |
+
|
3114 |
+
$count = get_transient( $transient_key );
|
3115 |
+
|
3116 |
+
if ( false === $count ) {
|
3117 |
+
global $wpdb;
|
3118 |
+
|
3119 |
+
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead( null, 'sql' );
|
3120 |
+
|
3121 |
+
$sql = sprintf(
|
3122 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3123 |
SELECT count(*)
|
3124 |
FROM %1$s
|
3125 |
WHERE UNIX_TIMESTAMP(date) >= %2$d
|
3126 |
AND logger IN %3$s
|
3127 |
',
|
3128 |
+
$wpdb->prefix . self::DBTABLE,
|
3129 |
+
strtotime( "-$period_days days" ),
|
3130 |
+
$sqlStringLoggersUserCanRead
|
3131 |
+
);
|
3132 |
|
3133 |
+
$count = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
3134 |
|
3135 |
+
set_transient( $transient_key, $count, HOUR_IN_SECONDS );
|
3136 |
+
}
|
3137 |
|
3138 |
+
return $count;
|
3139 |
+
}
|
3140 |
|
3141 |
+
public function get_num_events_per_day_last_n_days( $period_days = 28 ) {
|
3142 |
+
$transient_key = 'sh_' . md5( __METHOD__ . $period_days . '_2' );
|
3143 |
+
$dates = get_transient( $transient_key );
|
3144 |
|
3145 |
+
if ( false === $dates ) {
|
3146 |
+
global $wpdb;
|
3147 |
|
3148 |
+
$sqlStringLoggersUserCanRead = $this->getLoggersThatUserCanRead( null, 'sql' );
|
|
|
3149 |
|
3150 |
+
$sql = sprintf(
|
3151 |
+
'
|
|
|
|
|
3152 |
SELECT
|
3153 |
date_format(date, "%%Y-%%m-%%d") AS yearDate,
|
3154 |
count(date) AS count
|
3160 |
GROUP BY yearDate
|
3161 |
ORDER BY yearDate ASC
|
3162 |
',
|
3163 |
+
$wpdb->prefix . self::DBTABLE,
|
3164 |
+
strtotime( "-$period_days days" ),
|
3165 |
+
$sqlStringLoggersUserCanRead
|
3166 |
+
);
|
3167 |
+
|
3168 |
+
$dates = $wpdb->get_results( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
3169 |
+
|
3170 |
+
set_transient( $transient_key, $dates, HOUR_IN_SECONDS );
|
3171 |
+
}
|
3172 |
+
|
3173 |
+
return $dates;
|
3174 |
+
}
|
3175 |
+
|
3176 |
+
/**
|
3177 |
+
* Get number of unique events the last n days.
|
3178 |
+
*
|
3179 |
+
* @param int $days
|
3180 |
+
* @return int Number of days.
|
3181 |
+
*/
|
3182 |
+
public function get_unique_events_for_days( $days = 7 ) {
|
3183 |
+
global $wpdb;
|
3184 |
+
$days = (int) $days;
|
3185 |
+
$table_name = $wpdb->prefix . self::DBTABLE;
|
3186 |
+
$cache_key = 'sh_' . md5( __METHOD__ . $days );
|
3187 |
+
$numEvents = get_transient( $cache_key );
|
3188 |
+
|
3189 |
+
if ( false == $numEvents ) {
|
3190 |
+
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
3191 |
+
$sql = $wpdb->prepare(
|
3192 |
+
"
|
|
|
|
|
3193 |
SELECT count( DISTINCT occasionsID )
|
3194 |
FROM $table_name
|
3195 |
WHERE date >= DATE_ADD(CURDATE(), INTERVAL -%d DAY)
|
3196 |
+
",
|
3197 |
+
$days
|
3198 |
+
);
|
3199 |
+
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
3200 |
+
|
3201 |
+
$numEvents = $wpdb->get_var( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
3202 |
+
|
3203 |
+
set_transient( $cache_key, $numEvents, HOUR_IN_SECONDS );
|
3204 |
+
}
|
3205 |
+
|
3206 |
+
return $numEvents;
|
3207 |
+
}
|
3208 |
+
|
3209 |
+
/**
|
3210 |
+
* Output an admin notice about logger slug being to long
|
3211 |
+
*/
|
3212 |
+
public function admin_notice_logger_slug_to_long() {
|
3213 |
+
?>
|
3214 |
+
<div class="error notice">
|
3215 |
+
<p>
|
3216 |
+
<?php
|
3217 |
+
echo esc_html__(
|
3218 |
+
'The slug for a logger in Simple History can be max 30 chars long.',
|
3219 |
+
'simple-history'
|
3220 |
+
);
|
3221 |
+
?>
|
3222 |
+
</p>
|
3223 |
+
</div>
|
3224 |
+
<?php
|
3225 |
+
}
|
3226 |
}
|
inc/SimpleHistoryLogQuery.php
CHANGED
@@ -1,134 +1,128 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
-
// 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,18 +168,18 @@ class SimpleHistoryLogQuery
|
|
174 |
%2$s
|
175 |
';
|
176 |
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
SELECT h.*,
|
190 |
# fake columns that exist in overview query
|
191 |
1 as subsequentOccasions
|
@@ -195,147 +189,154 @@ class SimpleHistoryLogQuery
|
|
195 |
%2$s
|
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 |
# lastdays
|
309 |
AND date >= DATE(NOW()) - INTERVAL %d DAY
|
310 |
-
',
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
|
|
|
|
322 |
# sql_months
|
323 |
AND (
|
324 |
';
|
325 |
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
|
337 |
-
|
338 |
-
|
339 |
(
|
340 |
date >= "%1$s"
|
341 |
AND date <= "%2$s"
|
@@ -343,446 +344,378 @@ class SimpleHistoryLogQuery
|
|
343 |
|
344 |
OR
|
345 |
',
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
|
351 |
-
|
352 |
-
|
353 |
|
354 |
-
|
355 |
# end sql_months and wrap
|
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 |
h.logger = "%1$s"
|
492 |
-
|
493 |
)
|
494 |
OR ',
|
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 |
-
[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 |
-
|
594 |
-
|
595 |
-
|
596 |
|
597 |
-
|
598 |
-
|
599 |
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
|
610 |
-
|
611 |
-
|
612 |
|
613 |
-
|
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 |
-
|
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 |
-
$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 |
-
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Queries the Simple History Log
|
7 |
*/
|
8 |
+
class SimpleHistoryLogQuery {
|
|
|
9 |
|
10 |
+
/**
|
11 |
+
* Query the log.
|
12 |
+
*
|
13 |
+
* @param string|array|object $args
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
public function query( $args ) {
|
17 |
+
$defaults = array(
|
18 |
|
19 |
+
// overview | occasions
|
20 |
+
'type' => 'overview',
|
21 |
|
22 |
+
// Number of posts to show per page. 0 to show all.
|
23 |
+
'posts_per_page' => 0,
|
24 |
+
|
25 |
+
// Page to show. 1 = first page
|
26 |
+
'paged' => 1,
|
27 |
+
|
28 |
+
// Array. Only get posts that are in array.
|
29 |
+
'post__in' => null,
|
30 |
+
|
31 |
+
// array or html
|
32 |
+
'format' => 'array',
|
33 |
+
|
34 |
+
// If max_id_first_page is set then only get rows
|
35 |
+
// that have id equal or lower than this, to make
|
36 |
+
'max_id_first_page' => null,
|
37 |
+
|
38 |
+
// if since_id is set the rows returned will only be rows with an ID greater than (i.e. more recent than) since_id
|
39 |
+
'since_id' => null,
|
40 |
+
|
41 |
+
// date range
|
42 |
+
// in unix datetime or Y-m-d H:i (or format compatible with strtotime())
|
43 |
+
'date_from' => null,
|
44 |
+
'date_to' => null,
|
45 |
+
|
46 |
+
// months in format "Y-m"
|
47 |
+
// array or comma separated
|
48 |
+
'months' => null,
|
49 |
+
|
50 |
+
// dates in format
|
51 |
+
// "month:2015-06" for june 2015
|
52 |
+
// "lastdays:7" for the last 7 days
|
53 |
+
'dates' => null,
|
54 |
+
|
55 |
+
// search
|
56 |
+
'search' => null,
|
57 |
+
|
58 |
+
// log levels to include. comma separated or as array. defaults to all.
|
59 |
+
'loglevels' => null,
|
60 |
+
|
61 |
+
// loggers to include. comma separated. defaults to all the user can read
|
62 |
+
'loggers' => null,
|
63 |
+
|
64 |
+
'messages' => null,
|
65 |
+
|
66 |
+
// userID as number
|
67 |
+
'user' => null,
|
68 |
+
|
69 |
+
// user ids, comma separated
|
70 |
+
'users' => null,
|
71 |
+
|
72 |
+
// Can also contain:
|
73 |
+
// occasionsCount
|
74 |
+
// occasionsCountMaxReturn
|
75 |
+
// occasionsID
|
76 |
+
// If rows should be returned, or the actualy sql query used
|
77 |
+
'returnQuery' => false,
|
78 |
+
|
79 |
+
);
|
80 |
+
|
81 |
+
$args = wp_parse_args( $args, $defaults );
|
82 |
+
|
83 |
+
// Create cache key based on args and request and current user.
|
84 |
+
$cache_key = 'SimpleHistoryLogQuery_' . md5( serialize( $args ) ) . '_get_' . md5( serialize( $_GET ) ) . '_userid_' . get_current_user_id();
|
85 |
+
$cache_group = 'simple-history-' . SimpleHistory::get_cache_incrementor();
|
86 |
+
$arr_return = wp_cache_get( $cache_key, $cache_group );
|
87 |
+
|
88 |
+
if ( false !== $arr_return ) {
|
89 |
+
return $arr_return;
|
90 |
+
}
|
91 |
+
|
92 |
+
/*
|
93 |
+
Subequent occasions query thanks to this Stack Overflow thread:
|
94 |
+
http://stackoverflow.com/questions/13566303/how-to-group-subsequent-rows-based-on-a-criteria-and-then-count-them-mysql/13567320#13567320
|
95 |
+
Similar questions that I didn't manage to understand, work, or did try:
|
96 |
+
- http://stackoverflow.com/questions/23651176/mysql-query-if-dates-are-subsequent
|
97 |
+
- http://stackoverflow.com/questions/17651868/mysql-group-by-subsequent
|
98 |
+
- http://stackoverflow.com/questions/4495242/mysql-number-of-subsequent-occurrences
|
99 |
+
- http://stackoverflow.com/questions/20446242/postgresql-group-subsequent-rows
|
100 |
+
- http://stackoverflow.com/questions/17061156/mysql-group-by-range
|
101 |
+
- http://stackoverflow.com/questions/6602006/complicated-query-with-group-by-and-range-of-prices-in-mysql
|
102 |
+
*/
|
103 |
+
|
104 |
+
global $wpdb;
|
105 |
+
|
106 |
+
$table_name = $wpdb->prefix . SimpleHistory::DBTABLE;
|
107 |
+
$table_name_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
108 |
+
|
109 |
+
$where = '1 = 1';
|
110 |
+
$limit = '';
|
111 |
+
$inner_where = '1 = 1';
|
112 |
+
|
113 |
+
if ( 'overview' === $args['type'] || 'single' === $args['type'] ) {
|
114 |
+
// Set variables used by query.
|
115 |
+
$sql_set_var = "SET @a:='', @counter:=1, @groupby:=0";
|
116 |
+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
117 |
+
$wpdb->query( $sql_set_var );
|
118 |
|
119 |
+
// Main query
|
120 |
+
// 1 = where
|
121 |
+
// 2 = limit
|
122 |
+
// 3 = db name
|
123 |
+
// 4 = where for inner calc sql query thingie
|
124 |
+
// 5 = db name contexts
|
125 |
+
$sql_tmpl = '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
/*NO_SELECT_FOUND_ROWS*/
|
127 |
SELECT
|
128 |
SQL_CALC_FOUND_ROWS
|
168 |
%2$s
|
169 |
';
|
170 |
|
171 |
+
$sh = SimpleHistory::get_instance();
|
172 |
+
|
173 |
+
// Only include loggers that the current user can view
|
174 |
+
// @TODO: this causes error if user has no access to any logger at all
|
175 |
+
$sql_loggers_user_can_view = $sh->getLoggersThatUserCanRead( get_current_user_id(), 'sql' );
|
176 |
+
$inner_where .= " AND logger IN {$sql_loggers_user_can_view}";
|
177 |
+
} elseif ( 'occasions' === $args['type'] ) {
|
178 |
+
// Query template
|
179 |
+
// 1 = where
|
180 |
+
// 2 = limit
|
181 |
+
// 3 = db name
|
182 |
+
$sql_tmpl = '
|
183 |
SELECT h.*,
|
184 |
# fake columns that exist in overview query
|
185 |
1 as subsequentOccasions
|
189 |
%2$s
|
190 |
';
|
191 |
|
192 |
+
$where .= ' AND h.id < ' . (int) $args['logRowID'];
|
193 |
+
$where .= " AND h.occasionsID = '" . esc_sql( $args['occasionsID'] ) . "'";
|
194 |
+
|
195 |
+
if ( isset( $args['occasionsCountMaxReturn'] ) && (int) $args['occasionsCountMaxReturn'] < (int) $args['occasionsCount'] ) {
|
196 |
+
// Limit to max nn events if occasionsCountMaxReturn is set.
|
197 |
+
// Used in gui to prevent to many events returned, that can stall the browser.
|
198 |
+
$limit = 'LIMIT ' . (int) $args['occasionsCountMaxReturn'];
|
199 |
+
} else {
|
200 |
+
// Regular limit that gets all occasions
|
201 |
+
$limit = 'LIMIT ' . (int) $args['occasionsCount'];
|
202 |
+
}
|
203 |
+
}// End if().
|
204 |
+
|
205 |
+
// Determine limit
|
206 |
+
// Both posts_per_page and paged must be set
|
207 |
+
$is_limit_query = ( is_numeric( $args['posts_per_page'] ) && $args['posts_per_page'] > 0 );
|
208 |
+
$is_limit_query = $is_limit_query && ( is_numeric( $args['paged'] ) && $args['paged'] > 0 );
|
209 |
+
if ( $is_limit_query ) {
|
210 |
+
$limit_offset = ( $args['paged'] - 1 ) * $args['posts_per_page'];
|
211 |
+
$limit .= sprintf( 'LIMIT %1$d, %2$d', $limit_offset, $args['posts_per_page'] );
|
212 |
+
}
|
213 |
+
|
214 |
+
// Determine where
|
215 |
+
if ( $args['post__in'] && is_array( $args['post__in'] ) ) {
|
216 |
+
// make sure all vals are integers
|
217 |
+
$args['post__in'] = array_map( 'intval', $args['post__in'] );
|
218 |
+
|
219 |
+
$inner_where .= sprintf( ' AND id IN (%1$s)', implode( ',', $args['post__in'] ) );
|
220 |
+
}
|
221 |
+
|
222 |
+
// If max_id_first_page is then then only include rows
|
223 |
+
// with id equal to or earlier
|
224 |
+
if ( isset( $args['max_id_first_page'] ) && is_numeric( $args['max_id_first_page'] ) ) {
|
225 |
+
$max_id_first_page = (int) $args['max_id_first_page'];
|
226 |
+
$inner_where .= sprintf(
|
227 |
+
' AND id <= %1$d',
|
228 |
+
$max_id_first_page
|
229 |
+
);
|
230 |
+
}
|
231 |
+
|
232 |
+
if ( isset( $args['since_id'] ) && is_numeric( $args['since_id'] ) ) {
|
233 |
+
$since_id = (int) $args['since_id'];
|
234 |
+
// Add where to inner because that's faster
|
235 |
+
$inner_where .= sprintf(
|
236 |
+
' AND id > %1$d',
|
237 |
+
$since_id
|
238 |
+
);
|
239 |
+
}
|
240 |
+
|
241 |
+
// Append date where
|
242 |
+
if ( ! empty( $args['date_from'] ) ) {
|
243 |
+
// date_from=2014-08-01
|
244 |
+
// if date is not numeric assume Y-m-d H:i-format
|
245 |
+
$date_from = $args['date_from'];
|
246 |
+
if ( ! is_numeric( $date_from ) ) {
|
247 |
+
$date_from = strtotime( $date_from );
|
248 |
+
}
|
249 |
+
|
250 |
+
$inner_where .= "\n" . sprintf( ' AND date >= "%1$s"', gmdate( 'Y-m-d H:i:s', $date_from ) );
|
251 |
+
}
|
252 |
+
|
253 |
+
if ( ! empty( $args['date_to'] ) ) {
|
254 |
+
// date_to=2014-08-01
|
255 |
+
// if date is not numeric assume Y-m-d H:i-format
|
256 |
+
$date_to = $args['date_to'];
|
257 |
+
if ( ! is_numeric( $date_to ) ) {
|
258 |
+
$date_to = strtotime( $date_to );
|
259 |
+
}
|
260 |
+
|
261 |
+
$inner_where .= "\n" . sprintf( ' AND date <= "%1$s"', gmdate( 'Y-m-d H:i:s', $date_to ) );
|
262 |
+
}
|
263 |
+
|
264 |
+
// If months they translate to $args["months"] because we already have support for that
|
265 |
+
// can't use months and dates and the same time.
|
266 |
+
if ( ! empty( $args['dates'] ) ) {
|
267 |
+
if ( is_array( $args['dates'] ) ) {
|
268 |
+
$arr_dates = $args['dates'];
|
269 |
+
} else {
|
270 |
+
$arr_dates = explode( ',', $args['dates'] );
|
271 |
+
}
|
272 |
+
|
273 |
+
/*
|
274 |
+
$arr_dates can be a month:
|
275 |
+
|
276 |
+
Array
|
277 |
+
(
|
278 |
+
[0] => month:2021-11
|
279 |
+
)
|
280 |
+
|
281 |
+
$arr_dates can be a number of days:
|
282 |
+
Array
|
283 |
+
(
|
284 |
+
[0] => lastdays:7
|
285 |
+
)
|
286 |
+
*/
|
287 |
+
|
288 |
+
$args['months'] = array();
|
289 |
+
$args['lastdays'] = 0;
|
290 |
+
|
291 |
+
foreach ( $arr_dates as $one_date ) {
|
292 |
+
if ( strpos( $one_date, 'month:' ) === 0 ) {
|
293 |
+
// If begins with "month:" then strip string and keep only month numbers.
|
294 |
+
$args['months'][] = substr( $one_date, strlen( 'month:' ) );
|
295 |
+
// If begins with "lastdays:" then strip string and keep only number of days.
|
296 |
+
} elseif ( strpos( $one_date, 'lastdays:' ) === 0 ) {
|
297 |
+
// Only keep largest lastdays value
|
298 |
+
$args['lastdays'] = max( $args['lastdays'], substr( $one_date, strlen( 'lastdays:' ) ) );
|
299 |
+
}
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
// lastdays, as int
|
304 |
+
if ( ! empty( $args['lastdays'] ) ) {
|
305 |
+
$inner_where .= "\n" . sprintf(
|
306 |
+
'
|
307 |
# lastdays
|
308 |
AND date >= DATE(NOW()) - INTERVAL %d DAY
|
309 |
+
',
|
310 |
+
$args['lastdays']
|
311 |
+
);
|
312 |
+
}
|
313 |
+
|
314 |
+
// months, in format "Y-m"
|
315 |
+
if ( ! empty( $args['months'] ) ) {
|
316 |
+
if ( is_array( $args['months'] ) ) {
|
317 |
+
$arr_months = $args['months'];
|
318 |
+
} else {
|
319 |
+
$arr_months = explode( ',', $args['months'] );
|
320 |
+
}
|
321 |
+
|
322 |
+
$sql_months = "\n" . '
|
323 |
# sql_months
|
324 |
AND (
|
325 |
';
|
326 |
|
327 |
+
foreach ( $arr_months as $one_month ) {
|
328 |
+
// beginning of month
|
329 |
+
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08") ) . "\n";
|
330 |
+
// >> 2014-08-01 00:00
|
331 |
+
$date_month_beginning = strtotime( $one_month );
|
332 |
|
333 |
+
// end of month
|
334 |
+
// $ php -r ' echo date("Y-m-d H:i", strtotime("2014-08 + 1 month") ) . "\n";'
|
335 |
+
// >> 2014-09-01 00:00
|
336 |
+
$date_month_end = strtotime( "{$one_month} + 1 month" );
|
337 |
|
338 |
+
$sql_months .= sprintf(
|
339 |
+
'
|
340 |
(
|
341 |
date >= "%1$s"
|
342 |
AND date <= "%2$s"
|
344 |
|
345 |
OR
|
346 |
',
|
347 |
+
gmdate( 'Y-m-d H:i:s', $date_month_beginning ), // 1
|
348 |
+
gmdate( 'Y-m-d H:i:s', $date_month_end ) // 2
|
349 |
+
);
|
350 |
+
}
|
351 |
|
352 |
+
$sql_months = trim( $sql_months );
|
353 |
+
$sql_months = rtrim( $sql_months, ' OR ' );
|
354 |
|
355 |
+
$sql_months .= '
|
356 |
# end sql_months and wrap
|
357 |
)
|
358 |
';
|
359 |
|
360 |
+
$inner_where .= $sql_months;
|
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 |
+
$str_like = esc_sql( $wpdb->esc_like( $one_search_word ) );
|
378 |
+
|
379 |
+
$str_sql_search_words .= sprintf(
|
380 |
+
' AND %1$s LIKE "%2$s" ',
|
381 |
+
$one_col,
|
382 |
+
"%{$str_like}%"
|
383 |
+
);
|
384 |
+
}
|
385 |
+
|
386 |
+
$str_sql_search_words = ltrim( $str_sql_search_words, ' AND ' );
|
387 |
+
|
388 |
+
$str_search_conditions .= "\n" . sprintf(
|
389 |
+
' OR ( %1$s ) ',
|
390 |
+
$str_sql_search_words
|
391 |
+
);
|
392 |
+
}
|
393 |
+
|
394 |
+
$str_search_conditions = preg_replace( '/^OR /', ' ', trim( $str_search_conditions ) );
|
395 |
+
|
396 |
+
// Also search contexts.
|
397 |
+
$str_search_conditions .= "\n OR ( ";
|
398 |
+
foreach ( $arr_search_words as $one_search_word ) {
|
399 |
+
$str_like = esc_sql( $wpdb->esc_like( $one_search_word ) );
|
400 |
+
|
401 |
+
$str_search_conditions .= "\n" . sprintf(
|
402 |
+
' id IN ( SELECT history_id FROM %1$s AS c WHERE c.value LIKE "%2$s" ) AND ',
|
403 |
+
$table_name_contexts, // 1
|
404 |
+
'%' . $str_like . '%' // 2
|
405 |
+
);
|
406 |
+
}
|
407 |
+
$str_search_conditions = preg_replace( '/ AND $/', '', $str_search_conditions );
|
408 |
+
|
409 |
+
$str_search_conditions .= "\n ) "; // end OR for contexts
|
410 |
+
|
411 |
+
$inner_where .= "\n AND \n(\n {$str_search_conditions} \n ) ";
|
412 |
+
}// End if().
|
413 |
+
|
414 |
+
// log levels
|
415 |
+
// comma separated
|
416 |
+
// http://playground-root.ep/wp-admin/admin-ajax.php?action=simple_history_api&type=overview&format=&posts_per_page=10&paged=1&max_id_first_page=27273&SimpleHistoryLogQuery-showDebug=0&loglevel=error,warn
|
417 |
+
if ( ! empty( $args['loglevels'] ) ) {
|
418 |
+
$sql_loglevels = '';
|
419 |
+
|
420 |
+
if ( is_array( $args['loglevels'] ) ) {
|
421 |
+
$arr_loglevels = $args['loglevels'];
|
422 |
+
} else {
|
423 |
+
$arr_loglevels = explode( ',', $args['loglevels'] );
|
424 |
+
}
|
425 |
+
|
426 |
+
foreach ( $arr_loglevels as $one_loglevel ) {
|
427 |
+
$sql_loglevels .= sprintf( ' "%s", ', esc_sql( $one_loglevel ) );
|
428 |
+
}
|
429 |
+
|
430 |
+
if ( $sql_loglevels ) {
|
431 |
+
$sql_loglevels = rtrim( $sql_loglevels, ' ,' );
|
432 |
+
$sql_loglevels = "\n AND level IN ({$sql_loglevels}) ";
|
433 |
+
}
|
434 |
+
|
435 |
+
$inner_where .= $sql_loglevels;
|
436 |
+
}
|
437 |
+
|
438 |
+
// messages
|
439 |
+
if ( ! empty( $args['messages'] ) ) {
|
440 |
+
/*
|
441 |
+
$args['messages']:
|
442 |
+
Array
|
443 |
+
(
|
444 |
+
[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
|
445 |
+
[1] => SimpleCommentsLogger:SimpleCommentsLogger:comment_status_spam,SimpleCommentsLogger:trackback_status_spam,SimpleCommentsLogger:pingback_status_spam
|
446 |
+
)
|
447 |
+
*/
|
448 |
+
|
449 |
+
// Array with loggers and messages.
|
450 |
+
$arr_loggers_and_messages = array();
|
451 |
+
|
452 |
+
// Tranform from get'et format to our own internal format.
|
453 |
+
foreach ( (array) $args['messages'] as $one_arr_messages_row ) {
|
454 |
+
$arr_row_messages = explode( ',', $one_arr_messages_row );
|
455 |
+
/*
|
456 |
+
$one_arr_messages_row:
|
457 |
+
Array
|
458 |
+
(
|
459 |
+
[0] => SimpleCommentsLogger:anon_comment_added
|
460 |
+
[1] => SimpleCommentsLogger:user_comment_added
|
461 |
+
[2] => SimpleCommentsLogger:anon_trackback_added
|
462 |
+
*/
|
463 |
+
foreach ( $arr_row_messages as $one_row_logger_and_message ) {
|
464 |
+
$arr_one_logger_and_message = explode( ':', $one_row_logger_and_message );
|
465 |
+
|
466 |
+
if ( ! isset( $arr_loggers_and_messages[ $arr_one_logger_and_message[0] ] ) ) {
|
467 |
+
$arr_loggers_and_messages[ $arr_one_logger_and_message[0] ] = array();
|
468 |
+
}
|
469 |
+
|
470 |
+
$arr_loggers_and_messages[ $arr_one_logger_and_message[0] ][] = $arr_one_logger_and_message[1];
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
// Create sql where based on loggers and messages.
|
475 |
+
$sql_messages_where = ' AND (';
|
476 |
+
|
477 |
+
foreach ( $arr_loggers_and_messages as $logger_slug => $logger_messages ) {
|
478 |
+
|
479 |
+
$sql_logger_messages_in = '';
|
480 |
+
foreach ( $logger_messages as $one_logger_message ) {
|
481 |
+
$sql_logger_messages_in .= sprintf( '"%s",', esc_sql( $one_logger_message ) );
|
482 |
+
}
|
483 |
+
|
484 |
+
if ( $sql_logger_messages_in ) {
|
485 |
+
$sql_logger_messages_in = rtrim( $sql_logger_messages_in, ' ,' );
|
486 |
+
$sql_logger_messages_in = "\n AND c1.value IN ({$sql_logger_messages_in}) ";
|
487 |
+
}
|
488 |
+
|
489 |
+
$sql_messages_where .= sprintf(
|
490 |
+
'
|
491 |
(
|
492 |
h.logger = "%1$s"
|
493 |
+
%2$s
|
494 |
)
|
495 |
OR ',
|
496 |
+
esc_sql( $logger_slug ),
|
497 |
+
$sql_logger_messages_in
|
498 |
+
);
|
499 |
+
}
|
500 |
+
// remove last or
|
501 |
+
$sql_messages_where = preg_replace( '/OR $/', '', $sql_messages_where );
|
502 |
+
|
503 |
+
$sql_messages_where .= "\n )";
|
504 |
+
$where .= $sql_messages_where;
|
505 |
+
} // End if().
|
506 |
+
|
507 |
+
// loggers
|
508 |
+
// comma separated
|
509 |
+
// 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
|
510 |
+
if ( ! empty( $args['loggers'] ) ) {
|
511 |
+
$sql_loggers = '';
|
512 |
+
if ( is_array( $args['loggers'] ) ) {
|
513 |
+
$arr_loggers = $args['loggers'];
|
514 |
+
} else {
|
515 |
+
$arr_loggers = explode( ',', $args['loggers'] );
|
516 |
+
}
|
517 |
+
|
518 |
+
foreach ( $arr_loggers as $one_logger ) {
|
519 |
+
$sql_loggers .= sprintf( ' "%s", ', esc_sql( $one_logger ) );
|
520 |
+
}
|
521 |
+
|
522 |
+
if ( $sql_loggers ) {
|
523 |
+
$sql_loggers = rtrim( $sql_loggers, ' ,' );
|
524 |
+
$sql_loggers = "\n AND logger IN ({$sql_loggers}) ";
|
525 |
+
}
|
526 |
+
|
527 |
+
$inner_where .= $sql_loggers;
|
528 |
+
}
|
529 |
+
|
530 |
+
// user, a single userID
|
531 |
+
if ( ! empty( $args['user'] ) && is_numeric( $args['user'] ) ) {
|
532 |
+
$userID = (int) $args['user'];
|
533 |
+
$sql_user = sprintf(
|
534 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
535 |
AND id IN ( SELECT history_id FROM %1$s AS c WHERE c.key = "_user_id" AND c.value = %2$s )
|
536 |
',
|
537 |
+
$table_name_contexts, // 1
|
538 |
+
$userID // 2
|
539 |
+
);
|
540 |
|
541 |
+
$inner_where .= $sql_user;
|
542 |
+
}
|
543 |
|
544 |
+
// If users is array, make it comma separated.
|
545 |
+
if ( isset( $args['users'] ) && is_array( $args['users'] ) ) {
|
546 |
+
$args['users'] = implode( ',', $args['users'] );
|
547 |
+
}
|
548 |
|
549 |
+
// Users, comma separated.
|
550 |
+
if ( ! empty( $args['users'] ) && is_string( $args['users'] ) ) {
|
551 |
+
$users = explode( ',', $args['users'] );
|
552 |
+
$users = array_map( 'intval', $users );
|
553 |
|
554 |
+
if ( $users ) {
|
555 |
+
$users_in = implode( ',', $users );
|
556 |
|
557 |
+
$sql_user = sprintf(
|
558 |
+
'
|
559 |
AND id IN ( SELECT history_id FROM %1$s AS c WHERE c.key = "_user_id" AND c.value IN (%2$s) )
|
560 |
',
|
561 |
+
$table_name_contexts, // 1
|
562 |
+
$users_in // 2
|
563 |
+
);
|
564 |
+
|
565 |
+
$inner_where .= $sql_user;
|
566 |
+
|
567 |
+
// echo $inner_where;exit;
|
568 |
+
}
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Filter the sql template
|
573 |
+
*
|
574 |
+
* @since 2.0
|
575 |
+
*
|
576 |
+
* @param string $sql_tmpl
|
577 |
+
*/
|
578 |
+
$sql_tmpl = apply_filters( 'simple_history/log_query_sql_template', $sql_tmpl );
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Filter the sql template where clause
|
582 |
+
*
|
583 |
+
* @since 2.0
|
584 |
+
*
|
585 |
+
* @param string $where
|
586 |
+
*/
|
587 |
+
$where = apply_filters( 'simple_history/log_query_sql_where', $where );
|
588 |
+
|
589 |
+
/**
|
590 |
+
* Filter the sql template limit
|
591 |
+
*
|
592 |
+
* @since 2.0
|
593 |
+
*
|
594 |
+
* @param string $limit
|
595 |
+
*/
|
596 |
+
$limit = apply_filters( 'simple_history/log_query_limit', $limit );
|
597 |
+
|
598 |
+
/**
|
599 |
+
* Filter the sql template limit
|
600 |
+
*
|
601 |
+
* @since 2.0
|
602 |
+
*
|
603 |
+
* @param string $limit
|
604 |
+
*/
|
605 |
+
$inner_where = apply_filters( 'simple_history/log_query_inner_where', $inner_where );
|
606 |
+
|
607 |
+
$sql = sprintf(
|
608 |
+
$sql_tmpl, // sprintf template
|
609 |
+
$where, // 1
|
610 |
+
$limit, // 2
|
611 |
+
$table_name, // 3
|
612 |
+
$inner_where, // 4
|
613 |
+
$table_name_contexts // 5
|
614 |
+
);
|
615 |
+
|
616 |
+
/**
|
617 |
+
* Filter the final sql query
|
618 |
+
*
|
619 |
+
* @since 2.0
|
620 |
+
*
|
621 |
+
* @param string $sql
|
622 |
+
*/
|
623 |
+
$sql = apply_filters( 'simple_history/log_query_sql', $sql );
|
624 |
+
|
625 |
+
// Only return sql query
|
626 |
+
if ( $args['returnQuery'] ) {
|
627 |
+
return $sql;
|
628 |
+
}
|
629 |
+
|
630 |
+
$log_rows = $wpdb->get_results( $sql, OBJECT_K ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
631 |
+
|
632 |
+
// Find total number of rows that we would have gotten without pagination
|
633 |
+
// This is the number of rows with occasions taken into consideration
|
634 |
+
$sql_found_rows = 'SELECT FOUND_ROWS()';
|
635 |
+
$total_found_rows = (int) $wpdb->get_var( $sql_found_rows ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
636 |
+
|
637 |
+
// Add context
|
638 |
+
$post_ids = wp_list_pluck( $log_rows, 'id' );
|
639 |
+
|
640 |
+
if ( empty( $post_ids ) ) {
|
641 |
+
$context_results = array();
|
642 |
+
} else {
|
643 |
+
$sql_context = sprintf( 'SELECT * FROM %2$s WHERE history_id IN (%1$s)', join( ',', $post_ids ), $table_name_contexts );
|
644 |
+
$context_results = $wpdb->get_results( $sql_context ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
645 |
+
}
|
646 |
+
|
647 |
+
foreach ( $context_results as $context_row ) {
|
648 |
+
if ( ! isset( $log_rows[ $context_row->history_id ]->context ) ) {
|
649 |
+
$log_rows[ $context_row->history_id ]->context = array();
|
650 |
+
}
|
651 |
+
|
652 |
+
$log_rows[ $context_row->history_id ]->context[ $context_row->key ] = $context_row->value;
|
653 |
+
}
|
654 |
+
|
655 |
+
// Remove id from keys, because they are cumbersome when working with JSON.
|
656 |
+
$log_rows = array_values( $log_rows );
|
657 |
+
$min_id = null;
|
658 |
+
$max_id = null;
|
659 |
+
|
660 |
+
if ( count( $log_rows ) ) {
|
661 |
+
// Max id is simply the id of the first row.
|
662 |
+
$max_id = reset( $log_rows )->id;
|
663 |
+
|
664 |
+
// Min id = to find the lowest id we must take occasions into consideration
|
665 |
+
$last_row = end( $log_rows );
|
666 |
+
$last_row_occasions_count = (int) $last_row->subsequentOccasions - 1;
|
667 |
+
if ( $last_row_occasions_count === 0 ) {
|
668 |
+
// Last row did not have any more occasions, so get min_id directly from the row.
|
669 |
+
$min_id = $last_row->id;
|
670 |
+
} else {
|
671 |
+
// Last row did have occasions, so fetch all occasions, and find id of last one.
|
672 |
+
$db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
673 |
+
$sql = sprintf(
|
674 |
+
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
675 |
SELECT id, date, occasionsID
|
676 |
FROM %1$s
|
677 |
WHERE id <= %2$s
|
678 |
ORDER BY id DESC
|
679 |
LIMIT %3$s
|
680 |
',
|
681 |
+
$db_table,
|
682 |
+
$last_row->id,
|
683 |
+
$last_row_occasions_count + 1
|
684 |
+
);
|
685 |
+
|
686 |
+
$results = $wpdb->get_results( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
687 |
+
|
688 |
+
// the last occasion has the id we consider last in this paged result
|
689 |
+
$min_id = end( $results )->id;
|
690 |
+
}
|
691 |
+
} // End if().
|
692 |
+
|
693 |
+
// Calc pages.
|
694 |
+
if ( $args['posts_per_page'] ) {
|
695 |
+
$pages_count = Ceil( $total_found_rows / (int) $args['posts_per_page'] );
|
696 |
+
} else {
|
697 |
+
$pages_count = 1;
|
698 |
+
}
|
699 |
+
|
700 |
+
// Create array to return.
|
701 |
+
// Make all rows a sub key because we want to add some meta info too.
|
702 |
+
$log_rows_count = count( $log_rows );
|
703 |
+
$page_rows_from = ( (int) $args['paged'] * (int) $args['posts_per_page'] ) - (int) $args['posts_per_page'] + 1;
|
704 |
+
$page_rows_to = $page_rows_from + $log_rows_count - 1;
|
705 |
+
$arr_return = array(
|
706 |
+
'total_row_count' => $total_found_rows,
|
707 |
+
'pages_count' => $pages_count,
|
708 |
+
'page_current' => (int) $args['paged'],
|
709 |
+
'page_rows_from' => $page_rows_from,
|
710 |
+
'page_rows_to' => $page_rows_to,
|
711 |
+
'max_id' => (int) $max_id,
|
712 |
+
'min_id' => (int) $min_id,
|
713 |
+
'log_rows_count' => $log_rows_count,
|
714 |
+
'log_rows' => $log_rows,
|
715 |
+
);
|
716 |
+
|
717 |
+
wp_cache_set( $cache_key, $arr_return, $cache_group );
|
718 |
+
|
719 |
+
return $arr_return;
|
720 |
+
}
|
|
|
721 |
}
|
inc/helpers.php
CHANGED
@@ -6,15 +6,14 @@
|
|
6 |
* Makes call like this possible:
|
7 |
* SimpleLogger()->info("This is a message sent to the log");
|
8 |
*/
|
9 |
-
function SimpleLogger()
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
return new SimpleLogger(SimpleHistory::get_instance());
|
18 |
}
|
19 |
|
20 |
/**
|
@@ -23,24 +22,34 @@ function SimpleLogger()
|
|
23 |
* If you use this please consider using
|
24 |
* SimpleHistory()->info();
|
25 |
* instead
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
*/
|
27 |
-
function simple_history_add($args)
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
);
|
38 |
|
39 |
-
|
40 |
|
41 |
-
|
42 |
|
43 |
-
|
44 |
}
|
45 |
|
46 |
/**
|
@@ -48,7 +57,6 @@ function simple_history_add($args)
|
|
48 |
*
|
49 |
* @since 2.0.29
|
50 |
*
|
51 |
-
*
|
52 |
* Original description from wp_text_diff():
|
53 |
*
|
54 |
* Displays a human readable HTML representation of the difference between two strings.
|
@@ -75,76 +83,75 @@ function simple_history_add($args)
|
|
75 |
* @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. And leading_context_lines and trailing_context_lines.
|
76 |
* @return string Empty string if strings are equivalent or HTML with differences.
|
77 |
*/
|
78 |
-
function simple_history_text_diff($left_string, $right_string, $args = null)
|
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 |
/**
|
@@ -159,18 +166,17 @@ function simple_history_text_diff($left_string, $right_string, $args = null)
|
|
159 |
* $handler['callback'][1]
|
160 |
* );
|
161 |
*/
|
162 |
-
function sh_error_log()
|
163 |
-
{
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
}
|
174 |
}
|
175 |
|
176 |
/**
|
@@ -184,32 +190,32 @@ function sh_error_log()
|
|
184 |
*
|
185 |
* @mixed Vars Variables to output.
|
186 |
*/
|
187 |
-
function sh_d()
|
188 |
-
|
189 |
-
$output = '';
|
190 |
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
<pre>%1$s</pre>
|
206 |
',
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
|
|
213 |
}
|
214 |
|
215 |
/**
|
@@ -229,21 +235,20 @@ function sh_d()
|
|
229 |
* @param callable $callable The callable thing to check.
|
230 |
* @return string Name of callable.
|
231 |
*/
|
232 |
-
function sh_get_callable_name($callable)
|
233 |
-
{
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
}
|
247 |
}
|
248 |
|
249 |
/**
|
@@ -255,10 +260,9 @@ function sh_get_callable_name($callable)
|
|
255 |
*
|
256 |
* @return string with words uppercased.
|
257 |
*/
|
258 |
-
function sh_ucwords($str, $separator = ' ')
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
return $str;
|
264 |
}
|
6 |
* Makes call like this possible:
|
7 |
* SimpleLogger()->info("This is a message sent to the log");
|
8 |
*/
|
9 |
+
function SimpleLogger() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
|
10 |
+
// Load loggers if main SimpleLogger class is not yet available.
|
11 |
+
// Makes it possible to log things early,
|
12 |
+
// before loggers are loaded "normally" on filter "after_setup_theme".
|
13 |
+
if ( ! class_exists( 'SimpleLogger' ) ) {
|
14 |
+
SimpleHistory::get_instance()->load_loggers();
|
15 |
+
}
|
16 |
+
return new SimpleLogger( SimpleHistory::get_instance() );
|
|
|
17 |
}
|
18 |
|
19 |
/**
|
22 |
* If you use this please consider using
|
23 |
* SimpleHistory()->info();
|
24 |
* instead
|
25 |
+
*
|
26 |
+
* Example usage:
|
27 |
+
* simple_history_add(
|
28 |
+
* array(
|
29 |
+
* 'object_type' => 'post',
|
30 |
+
* 'object_name' => 'Lorem ispum dolor',
|
31 |
+
* 'action' => 'updated',
|
32 |
+
* )
|
33 |
+
* );
|
34 |
+
*
|
35 |
+
* @param array $args Array with at least keys object_type, object_name, action.
|
36 |
*/
|
37 |
+
function simple_history_add( $args ) {
|
38 |
+
$defaults = array(
|
39 |
+
'action' => null,
|
40 |
+
'object_type' => null,
|
41 |
+
'object_subtype' => null,
|
42 |
+
'object_id' => null,
|
43 |
+
'object_name' => null,
|
44 |
+
'user_id' => null,
|
45 |
+
'description' => null,
|
46 |
+
);
|
|
|
47 |
|
48 |
+
$context = wp_parse_args( $args, $defaults );
|
49 |
|
50 |
+
$message = "{$context["object_type"]} {$context["object_name"]} {$context["action"]}";
|
51 |
|
52 |
+
SimpleLogger()->info( $message, $context );
|
53 |
}
|
54 |
|
55 |
/**
|
57 |
*
|
58 |
* @since 2.0.29
|
59 |
*
|
|
|
60 |
* Original description from wp_text_diff():
|
61 |
*
|
62 |
* Displays a human readable HTML representation of the difference between two strings.
|
83 |
* @param string|array $args Optional. Change 'title', 'title_left', and 'title_right' defaults. And leading_context_lines and trailing_context_lines.
|
84 |
* @return string Empty string if strings are equivalent or HTML with differences.
|
85 |
*/
|
86 |
+
function simple_history_text_diff( $left_string, $right_string, $args = null ) {
|
87 |
+
$defaults = array(
|
88 |
+
'title' => '',
|
89 |
+
'title_left' => '',
|
90 |
+
'title_right' => '',
|
91 |
+
'leading_context_lines' => 1,
|
92 |
+
'trailing_context_lines' => 1,
|
93 |
+
);
|
|
|
94 |
|
95 |
+
$args = wp_parse_args( $args, $defaults );
|
96 |
|
97 |
+
if ( ! class_exists( 'WP_Text_Diff_Renderer_Table' ) ) {
|
98 |
+
require ABSPATH . WPINC . '/wp-diff.php';
|
99 |
+
}
|
100 |
|
101 |
+
$left_string = normalize_whitespace( $left_string );
|
102 |
+
$right_string = normalize_whitespace( $right_string );
|
103 |
|
104 |
+
$left_lines = explode( "\n", $left_string );
|
105 |
+
$right_lines = explode( "\n", $right_string );
|
106 |
+
$text_diff = new Text_Diff( $left_lines, $right_lines );
|
107 |
|
108 |
+
$renderer = new WP_Text_Diff_Renderer_Table( $args );
|
109 |
+
$renderer->_leading_context_lines = $args['leading_context_lines'];
|
110 |
+
$renderer->_trailing_context_lines = $args['trailing_context_lines'];
|
111 |
|
112 |
+
$diff = $renderer->render( $text_diff );
|
113 |
|
114 |
+
if ( ! $diff ) {
|
115 |
+
return '';
|
116 |
+
}
|
117 |
|
118 |
+
$r = '';
|
119 |
|
120 |
+
$r .= "<div class='SimpleHistory__diff__contents' tabindex='0'>";
|
121 |
+
$r .= "<div class='SimpleHistory__diff__contentsInner'>";
|
122 |
|
123 |
+
$r .= "<table class='diff SimpleHistory__diff'>\n";
|
124 |
|
125 |
+
if ( ! empty( $args['show_split_view'] ) ) {
|
126 |
+
$r .=
|
127 |
+
"<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />";
|
128 |
+
} else {
|
129 |
+
$r .= "<col class='content' />";
|
130 |
+
}
|
131 |
|
132 |
+
if ( $args['title'] || $args['title_left'] || $args['title_right'] ) {
|
133 |
+
$r .= '<thead>';
|
134 |
+
}
|
135 |
+
if ( $args['title'] ) {
|
136 |
+
$r .= "<tr class='diff-title'><th colspan='4'>$args[title]</th></tr>\n";
|
137 |
+
}
|
138 |
+
if ( $args['title_left'] || $args['title_right'] ) {
|
139 |
+
$r .= "<tr class='diff-sub-title'>\n";
|
140 |
+
$r .= "\t<td></td><th>$args[title_left]</th>\n";
|
141 |
+
$r .= "\t<td></td><th>$args[title_right]</th>\n";
|
142 |
+
$r .= "</tr>\n";
|
143 |
+
}
|
144 |
+
if ( $args['title'] || $args['title_left'] || $args['title_right'] ) {
|
145 |
+
$r .= "</thead>\n";
|
146 |
+
}
|
147 |
|
148 |
+
$r .= "<tbody>\n$diff</div>\n</tbody>\n";
|
149 |
+
$r .= '</table>';
|
150 |
|
151 |
+
$r .= '</div>';
|
152 |
+
$r .= '</div>';
|
153 |
|
154 |
+
return $r;
|
155 |
}
|
156 |
|
157 |
/**
|
166 |
* $handler['callback'][1]
|
167 |
* );
|
168 |
*/
|
169 |
+
function sh_error_log() {
|
170 |
+
foreach ( func_get_args() as $var ) {
|
171 |
+
if ( is_bool( $var ) ) {
|
172 |
+
$bool_string = true === $var ? 'true' : 'false';
|
173 |
+
error_log( "$bool_string (boolean value)" );
|
174 |
+
} elseif ( is_null( $var ) ) {
|
175 |
+
error_log( 'null (null value)' );
|
176 |
+
} else {
|
177 |
+
error_log( print_r( $var, true ) );
|
178 |
+
}
|
179 |
+
}
|
|
|
180 |
}
|
181 |
|
182 |
/**
|
190 |
*
|
191 |
* @mixed Vars Variables to output.
|
192 |
*/
|
193 |
+
function sh_d() {
|
194 |
+
$output = '';
|
|
|
195 |
|
196 |
+
foreach ( func_get_args() as $var ) {
|
197 |
+
$loopOutput = '';
|
198 |
+
if ( is_bool( $var ) ) {
|
199 |
+
$bool_string = true === $var ? 'true' : 'false';
|
200 |
+
$loopOutput = "$bool_string (boolean value)";
|
201 |
+
} elseif ( is_null( $var ) ) {
|
202 |
+
$loopOutput = ( 'null (null value)' );
|
203 |
+
} else {
|
204 |
+
$loopOutput = print_r( $var, true );
|
205 |
+
}
|
206 |
|
207 |
+
if ( $loopOutput ) {
|
208 |
+
$output = $output . sprintf(
|
209 |
+
'
|
210 |
<pre>%1$s</pre>
|
211 |
',
|
212 |
+
esc_html( $loopOutput )
|
213 |
+
);
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
218 |
+
echo $output;
|
219 |
}
|
220 |
|
221 |
/**
|
235 |
* @param callable $callable The callable thing to check.
|
236 |
* @return string Name of callable.
|
237 |
*/
|
238 |
+
function sh_get_callable_name( $callable ) {
|
239 |
+
if ( is_string( $callable ) ) {
|
240 |
+
return trim( $callable );
|
241 |
+
} elseif ( is_array( $callable ) ) {
|
242 |
+
if ( is_object( $callable[0] ) ) {
|
243 |
+
return sprintf( '%s::%s', get_class( $callable[0] ), trim( $callable[1] ) );
|
244 |
+
} else {
|
245 |
+
return sprintf( '%s::%s', trim( $callable[0] ), trim( $callable[1] ) );
|
246 |
+
}
|
247 |
+
} elseif ( $callable instanceof Closure ) {
|
248 |
+
return 'closure';
|
249 |
+
} else {
|
250 |
+
return 'unknown';
|
251 |
+
}
|
|
|
252 |
}
|
253 |
|
254 |
/**
|
260 |
*
|
261 |
* @return string with words uppercased.
|
262 |
*/
|
263 |
+
function sh_ucwords( $str, $separator = ' ' ) {
|
264 |
+
$str = str_replace( $separator, ' ', $str );
|
265 |
+
$str = ucwords( strtolower( $str ) );
|
266 |
+
$str = str_replace( ' ', $separator, $str );
|
267 |
+
return $str;
|
|
|
268 |
}
|
inc/oldversions.php
CHANGED
@@ -2,42 +2,42 @@
|
|
2 |
/**
|
3 |
* Show an admin message if old PHP version.
|
4 |
*/
|
5 |
-
function simple_history_old_version_admin_notice()
|
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 |
}
|
2 |
/**
|
3 |
* Show an admin message if old PHP version.
|
4 |
*/
|
5 |
+
function simple_history_old_version_admin_notice() {
|
6 |
+
$ok_wp_version = version_compare( $GLOBALS['wp_version'], '5.2', '>=' );
|
7 |
+
$ok_php_version = version_compare( phpversion(), '5.6', '>=' );
|
8 |
+
?>
|
9 |
+
<div class="updated error">
|
10 |
+
<?php
|
11 |
+
if ( ! $ok_php_version ) {
|
12 |
+
echo '<p>';
|
13 |
+
printf(
|
14 |
+
/* translators: 1: PHP version */
|
15 |
+
esc_html(
|
16 |
+
__(
|
17 |
+
'Simple History is a great plugin, but to use it your server must have at least PHP 5.6 installed (you have version %s).',
|
18 |
+
'simple-history'
|
19 |
+
)
|
20 |
+
),
|
21 |
+
esc_html( phpversion() ) // 1
|
22 |
+
);
|
23 |
+
echo '</p>';
|
24 |
+
}
|
|
|
25 |
|
26 |
+
if ( ! $ok_wp_version ) {
|
27 |
+
echo '<p>';
|
28 |
+
printf(
|
29 |
+
/* translators: 1: WordPress version */
|
30 |
+
esc_html(
|
31 |
+
__(
|
32 |
+
'Simple History requires WordPress version 5.2 or higher (you have version %s).',
|
33 |
+
'simple-history'
|
34 |
+
)
|
35 |
+
),
|
36 |
+
esc_html( $GLOBALS['wp_version'] ) // 1
|
37 |
+
);
|
38 |
+
echo '</p>';
|
39 |
+
}
|
40 |
+
?>
|
41 |
+
</div>
|
42 |
+
<?php
|
43 |
}
|
index.php
CHANGED
@@ -6,11 +6,11 @@
|
|
6 |
* Text Domain: simple-history
|
7 |
* Domain Path: /languages
|
8 |
* Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
|
9 |
-
* Version:
|
10 |
* Author: Pär Thernström
|
11 |
* Author URI: http://simple-history.com/
|
12 |
* License: GPL2
|
13 |
-
|
14 |
*
|
15 |
* @package Simple History
|
16 |
*/
|
@@ -29,37 +29,37 @@
|
|
29 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
30 |
*/
|
31 |
|
32 |
-
if (!defined('WPINC')) {
|
33 |
-
|
34 |
}
|
35 |
|
36 |
// Plugin requires at least WordPress version "4.5.1", because usage of functions like wp_get_raw_referer.
|
37 |
// true if version ok, false if too old version.
|
38 |
-
$ok_wp_version = version_compare($GLOBALS['wp_version'], '5.2', '>=');
|
39 |
-
$ok_php_version = version_compare(phpversion(), '5.6', '>=');
|
40 |
|
41 |
-
if ($ok_php_version && $ok_wp_version) {
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
|
59 |
-
|
60 |
-
|
61 |
} else {
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
} // End if().
|
6 |
* Text Domain: simple-history
|
7 |
* Domain Path: /languages
|
8 |
* Description: Plugin that logs various things that occur in WordPress and then presents those events in a very nice GUI.
|
9 |
+
* Version: 3.0.0
|
10 |
* Author: Pär Thernström
|
11 |
* Author URI: http://simple-history.com/
|
12 |
* License: GPL2
|
13 |
+
|
14 |
*
|
15 |
* @package Simple History
|
16 |
*/
|
29 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
30 |
*/
|
31 |
|
32 |
+
if ( ! defined( 'WPINC' ) ) {
|
33 |
+
die();
|
34 |
}
|
35 |
|
36 |
// Plugin requires at least WordPress version "4.5.1", because usage of functions like wp_get_raw_referer.
|
37 |
// true if version ok, false if too old version.
|
38 |
+
$ok_wp_version = version_compare( $GLOBALS['wp_version'], '5.2', '>=' );
|
39 |
+
$ok_php_version = version_compare( phpversion(), '5.6', '>=' );
|
40 |
|
41 |
+
if ( $ok_php_version && $ok_wp_version ) {
|
42 |
+
/**
|
43 |
+
* Register function that is called when plugin is installed
|
44 |
+
*
|
45 |
+
* @TODO: make activation multi site aware, as in https://github.com/scribu/wp-proper-network-activation
|
46 |
+
* register_activation_hook( trailingslashit(WP_PLUGIN_DIR) . trailingslashit( plugin_basename(__DIR__) ) . "index.php" , array("SimpleHistory", "on_plugin_activate" ) );
|
47 |
+
*/
|
48 |
+
define( 'SIMPLE_HISTORY_VERSION', '3.0.0' );
|
49 |
+
define( 'SIMPLE_HISTORY_PATH', plugin_dir_path( __FILE__ ) );
|
50 |
+
define( 'SIMPLE_HISTORY_BASENAME', plugin_basename( __FILE__ ) );
|
51 |
+
define( 'SIMPLE_HISTORY_DIR_URL', plugin_dir_url( __FILE__ ) );
|
52 |
+
define( 'SIMPLE_HISTORY_FILE', __FILE__ );
|
53 |
|
54 |
+
/** Load required files */
|
55 |
+
require_once __DIR__ . '/inc/SimpleHistory.php';
|
56 |
+
require_once __DIR__ . '/inc/SimpleHistoryLogQuery.php';
|
57 |
+
require_once __DIR__ . '/inc/helpers.php';
|
58 |
|
59 |
+
/** Boot up */
|
60 |
+
SimpleHistory::get_instance();
|
61 |
} else {
|
62 |
+
// User is running to old version of php, add admin notice about that.
|
63 |
+
require_once __DIR__ . '/inc/oldversions.php';
|
64 |
+
add_action( 'admin_notices', 'simple_history_old_version_admin_notice' );
|
65 |
} // End if().
|
loggers/AvailableUpdatesLogger.php
CHANGED
@@ -6,303 +6,306 @@
|
|
6 |
* @package SimpleHistory
|
7 |
*/
|
8 |
|
9 |
-
if (! class_exists('AvailableUpdatesLogger')) {
|
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 |
}
|
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 |
+
public function getInfo() {
|
30 |
+
|
31 |
+
$arr_info = array(
|
32 |
+
'name' => 'AvailableUpdatesLogger',
|
33 |
+
'description' => 'Logs found updates to WordPress, plugins, and themes',
|
34 |
+
'capability' => 'manage_options',
|
35 |
+
'messages' => array(
|
36 |
+
'core_update_available' => __( 'Found an update to WordPress.', 'simple-history' ),
|
37 |
+
'plugin_update_available' => __( 'Found an update to plugin "{plugin_name}"', 'simple-history' ),
|
38 |
+
'theme_update_available' => __( 'Found an update to theme "{theme_name}"', 'simple-history' ),
|
39 |
+
),
|
40 |
+
'labels' => array(
|
41 |
+
'search' => array(
|
42 |
+
'label' => _x( 'WordPress and plugins updates found', 'Plugin logger: updates found', 'simple-history' ),
|
43 |
+
'label_all' => _x( 'All found updates', 'Plugin logger: updates found', 'simple-history' ),
|
44 |
+
'options' => array(
|
45 |
+
_x( 'WordPress updates found', 'Plugin logger: updates found', 'simple-history' ) => array(
|
46 |
+
'core_update_available',
|
47 |
+
),
|
48 |
+
_x( 'Plugin updates found', 'Plugin logger: updates found', 'simple-history' ) => array(
|
49 |
+
'plugin_update_available',
|
50 |
+
),
|
51 |
+
_x( 'Theme updates found', 'Plugin logger: updates found', 'simple-history' ) => array(
|
52 |
+
'theme_update_available',
|
53 |
+
),
|
54 |
+
),
|
55 |
+
), // search array.
|
56 |
+
), // labels.
|
57 |
+
);
|
58 |
+
|
59 |
+
return $arr_info;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Called when logger is loaded.
|
64 |
+
*/
|
65 |
+
public function loaded() {
|
66 |
+
|
67 |
+
// When WP is done checking for core updates it sets a site transient called "update_core"
|
68 |
+
// set_site_transient( 'update_core', null ); // Uncomment to test
|
69 |
+
add_action( 'set_site_transient_update_core', array( $this, 'on_setted_update_core_transient' ), 10, 1 );
|
70 |
+
|
71 |
+
// Dito for plugins
|
72 |
+
// set_site_transient( 'update_plugins', null ); // Uncomment to test
|
73 |
+
add_action( 'set_site_transient_update_plugins', array( $this, 'on_setted_update_plugins_transient' ), 10, 1 );
|
74 |
+
|
75 |
+
add_action( 'set_site_transient_update_themes', array( $this, 'on_setted_update_update_themes' ), 10, 1 );
|
76 |
+
}
|
77 |
+
|
78 |
+
public function on_setted_update_core_transient( $updates ) {
|
79 |
+
|
80 |
+
global $wp_version;
|
81 |
+
|
82 |
+
$last_version_checked = get_option( "simplehistory_{$this->slug}_wp_core_version_available" );
|
83 |
+
|
84 |
+
// During update of network sites this was not set, so make sure to check
|
85 |
+
if ( empty( $updates->updates[0]->current ) ) {
|
86 |
+
return;
|
87 |
+
}
|
88 |
+
|
89 |
+
$new_wp_core_version = $updates->updates[0]->current; // The new WP core version
|
90 |
+
|
91 |
+
// Some plugins can mess with version, so get fresh from the version file.
|
92 |
+
require_once ABSPATH . WPINC . '/version.php';
|
93 |
+
|
94 |
+
// If found version is same version as we have logged about before then don't continue
|
95 |
+
if ( $last_version_checked == $new_wp_core_version ) {
|
96 |
+
return;
|
97 |
+
}
|
98 |
+
|
99 |
+
// is WP core update available?
|
100 |
+
if ( 'upgrade' == $updates->updates[0]->response ) {
|
101 |
+
$this->noticeMessage(
|
102 |
+
'core_update_available',
|
103 |
+
array(
|
104 |
+
'wp_core_current_version' => $wp_version,
|
105 |
+
'wp_core_new_version' => $new_wp_core_version,
|
106 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
107 |
+
)
|
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 |
+
public function on_setted_update_plugins_transient( $updates ) {
|
121 |
+
|
122 |
+
if ( empty( $updates->response ) || ! is_array( $updates->response ) ) {
|
123 |
+
return;
|
124 |
+
}
|
125 |
+
|
126 |
+
// If we only want to notify about active plugins
|
127 |
+
/*
|
128 |
+
$active_plugins = get_option( 'active_plugins' );
|
129 |
+
$active_plugins = array_flip( $active_plugins ); // find which plugins are active
|
130 |
+
$plugins_need_update = array_intersect_key( $plugins_need_update, $active_plugins ); // only keep plugins that are active
|
131 |
+
*/
|
132 |
+
|
133 |
+
// update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
|
134 |
+
$option_key = "simplehistory_{$this->slug}_plugin_updates_available";
|
135 |
+
$checked_updates = get_option( $option_key );
|
136 |
+
|
137 |
+
if ( ! is_array( $checked_updates ) ) {
|
138 |
+
$checked_updates = array();
|
139 |
+
}
|
140 |
+
|
141 |
+
// File needed plugin API
|
142 |
+
if ( ! function_exists( 'get_plugin_data' ) ) {
|
143 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
144 |
+
}
|
145 |
+
|
146 |
+
// For each available update.
|
147 |
+
foreach ( $updates->response as $key => $data ) {
|
148 |
+
// Make sure plugin directory exists or get_plugin_data will
|
149 |
+
// give warning like
|
150 |
+
// "PHP Warning: fread() expects parameter 1 to be resource, boolean given in /wp/wp-includes/functions.php on line 4837"
|
151 |
+
$file = WP_PLUGIN_DIR . '/' . $key;
|
152 |
+
|
153 |
+
// Continue with next plugin if plugin file did not exist.
|
154 |
+
if ( ! file_exists( $file ) ) {
|
155 |
+
continue;
|
156 |
+
}
|
157 |
+
|
158 |
+
$fp = fopen( $file, 'r' );
|
159 |
+
|
160 |
+
// Continue with next plugin if plugin file could not be read.
|
161 |
+
if ( false === $fp ) {
|
162 |
+
continue;
|
163 |
+
}
|
164 |
+
|
165 |
+
$plugin_info = get_plugin_data( $file, true, false );
|
166 |
+
|
167 |
+
$plugin_new_version = isset( $data->new_version ) ? $data->new_version : '';
|
168 |
+
|
169 |
+
// Check if this plugin and this version has been checked/logged already.
|
170 |
+
if ( ! array_key_exists( $key, $checked_updates ) ) {
|
171 |
+
$checked_updates[ $key ] = array(
|
172 |
+
'checked_version' => null,
|
173 |
+
);
|
174 |
+
}
|
175 |
+
|
176 |
+
if ( $checked_updates[ $key ]['checked_version'] == $plugin_new_version ) {
|
177 |
+
// This version has been checked/logged already
|
178 |
+
continue;
|
179 |
+
}
|
180 |
+
|
181 |
+
$checked_updates[ $key ]['checked_version'] = $plugin_new_version;
|
182 |
+
|
183 |
+
$this->noticeMessage(
|
184 |
+
'plugin_update_available',
|
185 |
+
array(
|
186 |
+
'plugin_name' => isset( $plugin_info['Name'] ) ? $plugin_info['Name'] : '',
|
187 |
+
'plugin_current_version' => isset( $plugin_info['Version'] ) ? $plugin_info['Version'] : '',
|
188 |
+
'plugin_new_version' => $plugin_new_version,
|
189 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
190 |
+
// "plugin_info" => $plugin_info,
|
191 |
+
// "remote_plugin_info" => $remote_plugin_info,
|
192 |
+
// "active_plugins" => $active_plugins,
|
193 |
+
// "updates" => $updates
|
194 |
+
)
|
195 |
+
);
|
196 |
+
} // End foreach().
|
197 |
+
|
198 |
+
update_option( $option_key, $checked_updates );
|
199 |
+
}
|
200 |
+
|
201 |
+
public function on_setted_update_update_themes( $updates ) {
|
202 |
+
|
203 |
+
if ( empty( $updates->response ) || ! is_array( $updates->response ) ) {
|
204 |
+
return;
|
205 |
+
}
|
206 |
+
|
207 |
+
// update_option( "simplehistory_{$this->slug}_wp_core_version_available", $new_wp_core_version );
|
208 |
+
$option_key = "simplehistory_{$this->slug}_theme_updates_available";
|
209 |
+
$checked_updates = get_option( $option_key );
|
210 |
+
|
211 |
+
if ( ! is_array( $checked_updates ) ) {
|
212 |
+
$checked_updates = array();
|
213 |
+
}
|
214 |
+
|
215 |
+
// For each available update
|
216 |
+
foreach ( $updates->response as $key => $data ) {
|
217 |
+
$theme_info = wp_get_theme( $key );
|
218 |
+
|
219 |
+
// $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";
|
220 |
+
$settings['notified']['theme'][ $key ] = $data['new_version']; // set theme version we are notifying about
|
221 |
+
|
222 |
+
$theme_new_version = isset( $data['new_version'] ) ? $data['new_version'] : '';
|
223 |
+
|
224 |
+
// check if this plugin and this version has been checked/logged already
|
225 |
+
if ( ! array_key_exists( $key, $checked_updates ) ) {
|
226 |
+
$checked_updates[ $key ] = array(
|
227 |
+
'checked_version' => null,
|
228 |
+
);
|
229 |
+
}
|
230 |
+
|
231 |
+
if ( $checked_updates[ $key ]['checked_version'] == $theme_new_version ) {
|
232 |
+
// This version has been checked/logged already
|
233 |
+
continue;
|
234 |
+
}
|
235 |
+
|
236 |
+
$checked_updates[ $key ]['checked_version'] = $theme_new_version;
|
237 |
+
|
238 |
+
$this->noticeMessage(
|
239 |
+
'theme_update_available',
|
240 |
+
array(
|
241 |
+
'theme_name' => isset( $theme_info['Name'] ) ? $theme_info['Name'] : '',
|
242 |
+
'theme_current_version' => isset( $theme_info['Version'] ) ? $theme_info['Version'] : '',
|
243 |
+
'theme_new_version' => $theme_new_version,
|
244 |
+
'_initiator' => SimpleLoggerLogInitiators::WORDPRESS,
|
245 |
+
// "plugin_info" => $plugin_info,
|
246 |
+
// "remote_plugin_info" => $remote_plugin_info,
|
247 |
+
// "active_plugins" => $active_plugins,
|
248 |
+
// "updates" => $updates,
|
249 |
+
)
|
250 |
+
);
|
251 |
+
} // End foreach().
|
252 |
+
|
253 |
+
update_option( $option_key, $checked_updates );
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Append prev and current version of update object as details in the output
|
258 |
+
*/
|
259 |
+
public function getLogRowDetailsOutput( $row ) {
|
260 |
+
|
261 |
+
$output = '';
|
262 |
+
|
263 |
+
$current_version = null;
|
264 |
+
$new_version = null;
|
265 |
+
$context_message_key = isset( $row->context_message_key ) ? $row->context_message_key : null;
|
266 |
+
|
267 |
+
$context = isset( $row->context ) ? $row->context : array();
|
268 |
+
|
269 |
+
switch ( $context_message_key ) {
|
270 |
+
case 'core_update_available':
|
271 |
+
$current_version = isset( $context['wp_core_current_version'] ) ? $context['wp_core_current_version'] : null;
|
272 |
+
$new_version = isset( $context['wp_core_new_version'] ) ? $context['wp_core_new_version'] : null;
|
273 |
+
break;
|
274 |
+
|
275 |
+
case 'plugin_update_available':
|
276 |
+
$current_version = isset( $context['plugin_current_version'] ) ? $context['plugin_current_version'] : null;
|
277 |
+
$new_version = isset( $context['plugin_new_version'] ) ? $context['plugin_new_version'] : null;
|
278 |
+
break;
|
279 |
+
|
280 |
+
case 'theme_update_available':
|
281 |
+
$current_version = isset( $context['theme_current_version'] ) ? $context['theme_current_version'] : null;
|
282 |
+
$new_version = isset( $context['theme_new_version'] ) ? $context['theme_new_version'] : null;
|
283 |
+
break;
|
284 |
+
}
|
285 |
+
|
286 |
+
if ( $current_version && $new_version ) {
|
287 |
+
$output .= '<p>';
|
288 |
+
$output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
|
289 |
+
$output .= '<em>' . __( 'Available version', 'simple-history' ) . '</em> ' . esc_html( $new_version );
|
290 |
+
$output .= '</span> ';
|
291 |
+
|
292 |
+
$output .= '<span class="SimpleHistoryLogitem__inlineDivided">';
|
293 |
+
$output .= '<em>' . __( 'Installed version', 'simple-history' ) . '</em> ' . esc_html( $current_version );
|
294 |
+
$output .= '</span>';
|
295 |
+
|
296 |
+
$output .= '</p>';
|
297 |
+
|
298 |
+
// Add link to update-page, if user is allowed to that page.
|
299 |
+
$is_allowed_to_update_page = current_user_can( 'update_core' ) || current_user_can( 'update_themes' ) || current_user_can( 'update_plugins' );
|
300 |
+
|
301 |
+
if ( $is_allowed_to_update_page ) {
|
302 |
+
$output .= sprintf( '<p><a href="%1$s">', admin_url( 'update-core.php' ) );
|
303 |
+
$output .= __( 'View all updates', 'simple-history' );
|
304 |
+
$output .= '</a></p>';
|
305 |
+
}
|
306 |
+
}
|
307 |
+
|
308 |
+
return $output;
|
309 |
+
}
|
310 |
+
}
|
311 |
}
|
loggers/FileEditsLogger.php
CHANGED
@@ -3,252 +3,256 @@
|
|
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 |
}
|
3 |
/**
|
4 |
* Logs edits to theme or plugin files done from Appearance -> Editor or Plugins -> Editor
|
5 |
*/
|
6 |
+
class FileEditsLogger extends SimpleLogger {
|
7 |
+
public $slug = __CLASS__;
|
8 |
+
|
9 |
+
public function getInfo() {
|
10 |
+
|
11 |
+
$arr_info = array(
|
12 |
+
'name' => 'FileEditsLogger',
|
13 |
+
'description' => 'Logs edits to theme and plugin files',
|
14 |
+
'capability' => 'manage_options',
|
15 |
+
'messages' => array(
|
16 |
+
'theme_file_edited' => __( 'Edited file "{file_name}" in theme "{theme_name}"', 'simple-history' ),
|
17 |
+
'plugin_file_edited' => __( 'Edited file "{file_name}" in plugin "{plugin_name}"', 'simple-history' ),
|
18 |
+
),
|
19 |
+
'labels' => array(
|
20 |
+
'search' => array(
|
21 |
+
'label' => _x( 'Edited theme and plugin files', 'Plugin logger: file edits', 'simple-history' ),
|
22 |
+
'label_all' => _x( 'All file edits', 'Plugin logger: file edits', 'simple-history' ),
|
23 |
+
'options' => array(
|
24 |
+
_x( 'Edited theme files', 'Plugin logger: file edits', 'simple-history' ) => array(
|
25 |
+
'theme_file_edited',
|
26 |
+
),
|
27 |
+
_x( 'Edited plugin files', 'Plugin logger: file edits', 'simple-history' ) => array(
|
28 |
+
'plugin_file_edited',
|
29 |
+
),
|
30 |
+
),
|
31 |
+
), // search array
|
32 |
+
), // labels
|
33 |
+
);
|
34 |
+
|
35 |
+
return $arr_info;
|
36 |
+
}
|
37 |
+
|
38 |
+
public function loaded() {
|
39 |
+
add_action( 'load-theme-editor.php', array( $this, 'on_load_theme_editor' ), 10, 1 );
|
40 |
+
add_action( 'load-plugin-editor.php', array( $this, 'on_load_plugin_editor' ), 10, 1 );
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Called when /wp/wp-admin/plugin-editor.php is loaded
|
45 |
+
* Both using regular GET and during POST with updated file data
|
46 |
+
*
|
47 |
+
* todo:
|
48 |
+
* - log edits
|
49 |
+
* - log failed edits that result in error and plugin deactivation
|
50 |
+
*/
|
51 |
+
public function on_load_plugin_editor() {
|
52 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
53 |
+
if ( isset( $_POST ) && isset( $_POST['action'] ) ) {
|
54 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
55 |
+
$file = isset( $_POST['file'] ) ? $_POST['file'] : null;
|
56 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
57 |
+
$plugin_file = isset( $_POST['plugin'] ) ? $_POST['plugin'] : null;
|
58 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
59 |
+
$fileNewContents = isset( $_POST['newcontent'] ) ? wp_unslash( $_POST['newcontent'] ) : null;
|
60 |
+
|
61 |
+
// if 'phperror' is set then there was an error and an edit is done and wp tries to activate the plugin again
|
62 |
+
// $phperror = isset($_POST["phperror"]) ? $_POST["phperror"] : null;
|
63 |
+
// Get info about the edited plugin
|
64 |
+
$pluginInfo = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_file );
|
65 |
+
$pluginName = isset( $pluginInfo['Name'] ) ? $pluginInfo['Name'] : null;
|
66 |
+
$pluginVersion = isset( $pluginInfo['Version'] ) ? $pluginInfo['Version'] : null;
|
67 |
+
|
68 |
+
// Get contents before save
|
69 |
+
$fileContentsBeforeEdit = file_get_contents( WP_PLUGIN_DIR . '/' . $file );
|
70 |
+
|
71 |
+
$context = array(
|
72 |
+
'file_name' => $plugin_file,
|
73 |
+
'plugin_name' => $pluginName,
|
74 |
+
'plugin_version' => $pluginVersion,
|
75 |
+
'old_file_contents' => $fileContentsBeforeEdit,
|
76 |
+
'new_file_contents' => $fileNewContents,
|
77 |
+
'_occasionsID' => __CLASS__ . '/' . __FUNCTION__ . "/file-edit/$plugin_file/$file",
|
78 |
+
);
|
79 |
+
|
80 |
+
$loggerInstance = $this;
|
81 |
+
add_filter(
|
82 |
+
'wp_redirect',
|
83 |
+
function ( $location, $status ) use ( $context, $loggerInstance ) {
|
84 |
+
$locationParsed = parse_url( $location );
|
85 |
+
|
86 |
+
if ( $locationParsed === false || empty( $locationParsed['query'] ) ) {
|
87 |
+
return $location;
|
88 |
+
}
|
89 |
+
|
90 |
+
parse_str( $locationParsed['query'], $queryStringParsed );
|
91 |
+
// ddd($_POST, $context, $queryStringParsed, $location);
|
92 |
+
if ( empty( $queryStringParsed ) ) {
|
93 |
+
return $location;
|
94 |
+
}
|
95 |
+
|
96 |
+
// If query string "a=te" exists or "liveupdate=1" then plugin file was updated
|
97 |
+
$teIsSet = isset( $queryStringParsed['a'] ) && $queryStringParsed['a'] === 'te';
|
98 |
+
$liveUpdateIsSet = isset( $queryStringParsed['liveupdate'] ) && $queryStringParsed['liveupdate'] === '1';
|
99 |
+
if ( $teIsSet || $liveUpdateIsSet ) {
|
100 |
+
// File was updated
|
101 |
+
$loggerInstance->infoMessage( 'plugin_file_edited', $context );
|
102 |
+
}
|
103 |
+
|
104 |
+
return $location;
|
105 |
+
|
106 |
+
// location when successful edit to non-active plugin
|
107 |
+
// http://wp-playground.dev/wp/wp-admin/plugin-editor.php?file=akismet/akismet.php&plugin=akismet/akismet.php&a=te&scrollto=0
|
108 |
+
// locations when activated plugin edited successfully
|
109 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&plugin=akismet%2Fakismet.php&liveupdate=1&scrollto=0&networkwide&_wpnonce=b3f399fe94
|
110 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&phperror=1&_error_nonce=63511c266d
|
111 |
+
// http://wp-playground.dev/wp/wp-admin/plugin-editor.php?file=akismet/akismet.php&plugin=akismet/akismet.php&a=te&scrollto=0
|
112 |
+
// locations when editing active plugin and error occurs
|
113 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&plugin=akismet%2Fakismet.php&liveupdate=1&scrollto=0&networkwide&_wpnonce=b3f399fe94
|
114 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&phperror=1&_error_nonce=63511c266d
|
115 |
+
// locations when error edit is fixed and saved and plugin is activated again
|
116 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&plugin=akismet%2Fakismet.php&liveupdate=1&scrollto=0&networkwide&_wpnonce=b3f399fe94
|
117 |
+
// plugin-editor.php?file=akismet%2Fakismet.php&phperror=1&_error_nonce=63511c266d
|
118 |
+
// http://wp-playground.dev/wp/wp-admin/plugin-editor.php?file=akismet/akismet.php&plugin=akismet/akismet.php&a=te&scrollto=0
|
119 |
+
},
|
120 |
+
10,
|
121 |
+
2
|
122 |
+
);
|
123 |
+
}// End if().
|
124 |
+
/*
|
125 |
+
<?php if (isset($_GET['a'])) : ?>
|
126 |
+
<div id="message" class="updated notice is-dismissible"><p><?php _e('File edited successfully.') ?></p></div>
|
127 |
+
<?php elseif (isset($_GET['phperror'])) : ?>
|
128 |
+
<div id="message" class="updated"><p><?php _e('This plugin has been deactivated because your changes resulted in a <strong>fatal error</strong>.') ?></p>
|
129 |
+
*/
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Called when /wp/wp-admin/theme-editor.php is loaded
|
134 |
+
* Both using regular GET and during POST with updated file data
|
135 |
+
*
|
136 |
+
* When this action is fired we don't know if a file will be successfully saved or not.
|
137 |
+
* There are no filters/actions fired when the edit is saved. On the end wp_redirect() is
|
138 |
+
* called however and we know the location for the redirect and wp_redirect() has filters
|
139 |
+
* so we hook onto that to save the edit.
|
140 |
+
*/
|
141 |
+
public function on_load_theme_editor() {
|
142 |
+
// Only continue if method is post and action is update
|
143 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
144 |
+
if ( isset( $_POST ) && isset( $_POST['action'] ) && $_POST['action'] === 'update' ) {
|
145 |
+
/*
|
146 |
+
POST data is like
|
147 |
+
array(8)
|
148 |
+
'_wpnonce' => string(10) "9b5e46634f"
|
149 |
+
'_wp_http_referer' => string(88) "/wp/wp-admin/theme-editor.php?file=style.css&theme=twentyfifteen&scrollto=0&upda…"
|
150 |
+
'newcontent' => string(104366) "/* Theme Name: Twenty Fifteen Theme URI: https://wordpress.org/themes/twentyfift…"
|
151 |
+
'action' => string(6) "update"
|
152 |
+
'file' => string(9) "style.css"
|
153 |
+
'theme' => string(13) "twentyfifteen"
|
154 |
+
'scrollto' => string(3) "638"
|
155 |
+
'submit' => string(11) "Update File"
|
156 |
+
*/
|
157 |
+
|
158 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
159 |
+
$file = isset( $_POST['file'] ) ? $_POST['file'] : null;
|
160 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
161 |
+
$theme = isset( $_POST['theme'] ) ? $_POST['theme'] : null;
|
162 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
163 |
+
$fileNewContents = isset( $_POST['newcontent'] ) ? wp_unslash( $_POST['newcontent'] ) : null;
|
164 |
+
|
165 |
+
// Same code as in theme-editor.php
|
166 |
+
if ( $theme ) {
|
167 |
+
$stylesheet = $theme;
|
168 |
+
} else {
|
169 |
+
$stylesheet = get_stylesheet();
|
170 |
+
}
|
171 |
+
|
172 |
+
$theme = wp_get_theme( $stylesheet );
|
173 |
+
|
174 |
+
if ( ! is_a( $theme, 'WP_Theme' ) ) {
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
|
178 |
+
// Same code as in theme-editor.php
|
179 |
+
$relative_file = $file;
|
180 |
+
$file = $theme->get_stylesheet_directory() . '/' . $relative_file;
|
181 |
+
|
182 |
+
// Get file contents, so we have something to compare with later
|
183 |
+
$fileContentsBeforeEdit = file_get_contents( $file );
|
184 |
+
|
185 |
+
$context = array(
|
186 |
+
'theme_name' => $theme->name,
|
187 |
+
'theme_stylesheet_path' => $theme->get_stylesheet(),
|
188 |
+
'theme_stylesheet_dir' => $theme->get_stylesheet_directory(),
|
189 |
+
'file_name' => $relative_file,
|
190 |
+
'file_dir' => $file,
|
191 |
+
'old_file_contents' => $fileContentsBeforeEdit,
|
192 |
+
'new_file_contents' => $fileNewContents,
|
193 |
+
'_occasionsID' => __CLASS__ . '/' . __FUNCTION__ . "/file-edit/$file",
|
194 |
+
);
|
195 |
+
|
196 |
+
// Hook into wp_redirect
|
197 |
+
// This hook is only added when we know a POST is done from theme-editor.php
|
198 |
+
$loggerInstance = $this;
|
199 |
+
add_filter(
|
200 |
+
'wp_redirect',
|
201 |
+
function ( $location, $status ) use ( $context, $loggerInstance ) {
|
202 |
+
$locationParsed = parse_url( $location );
|
203 |
+
|
204 |
+
if ( $locationParsed === false || empty( $locationParsed['query'] ) ) {
|
205 |
+
return $location;
|
206 |
+
}
|
207 |
+
|
208 |
+
parse_str( $locationParsed['query'], $queryStringParsed );
|
209 |
+
|
210 |
+
if ( empty( $queryStringParsed ) ) {
|
211 |
+
return $location;
|
212 |
+
}
|
213 |
+
|
214 |
+
if ( isset( $queryStringParsed['updated'] ) && $queryStringParsed['updated'] ) {
|
215 |
+
// File was updated
|
216 |
+
$loggerInstance->infoMessage( 'theme_file_edited', $context );
|
217 |
+
}
|
218 |
+
|
219 |
+
return $location;
|
220 |
+
},
|
221 |
+
10,
|
222 |
+
2
|
223 |
+
); // add_filter
|
224 |
+
} // End if().
|
225 |
+
}
|
226 |
+
|
227 |
+
public function getLogRowDetailsOutput( $row ) {
|
228 |
+
|
229 |
+
$context = $row->context;
|
230 |
+
$message_key = isset( $context['_message_key'] ) ? $context['_message_key'] : null;
|
231 |
+
|
232 |
+
if ( ! $message_key ) {
|
233 |
+
return;
|
234 |
+
}
|
235 |
+
|
236 |
+
$out = '';
|
237 |
+
|
238 |
+
$diff_table_output = '';
|
239 |
+
|
240 |
+
if ( ! empty( $context['new_file_contents'] ) && ! empty( $context['old_file_contents'] ) ) {
|
241 |
+
if ( $context['new_file_contents'] !== $context['old_file_contents'] ) {
|
242 |
+
$diff_table_output .= sprintf(
|
243 |
+
'<tr><td>%1$s</td><td>%2$s</td></tr>',
|
244 |
+
__( 'File contents', 'simple-history' ),
|
245 |
+
simple_history_text_diff( $context['old_file_contents'], $context['new_file_contents'] )
|
246 |
+
);
|
247 |
+
}
|
248 |
+
}
|
249 |
+
|
250 |
+
if ( $diff_table_output ) {
|
251 |
+
$diff_table_output = '<table class="SimpleHistoryLogitem__keyValueTable">' . $diff_table_output . '</table>';
|
252 |
+
}
|
253 |
+
|
254 |
+
$out .= $diff_table_output;
|
255 |
+
|
256 |
+
return $out;
|
257 |
+
}
|
258 |
}
|
loggers/PluginEnableMediaReplaceLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Logs attachments updated with the great Enable Media Replace plugin
|
@@ -8,97 +8,99 @@ 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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
public $slug = __CLASS__;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Get array with information about this logger
|
17 |
+
*
|
18 |
+
* @return array
|
19 |
+
*/
|
20 |
+
public function getInfo() {
|
21 |
+
|
22 |
+
$arr_info = array(
|
23 |
+
'name' => _x( 'Enable Media Replace Logger', 'PluginEnableMediaReplaceLogger', 'simple-history' ),
|
24 |
+
'description' => _x( 'Logs media updates made with the Enable Media Replace Plugin', 'PluginEnableMediaReplaceLogger', 'simple-history' ),
|
25 |
+
'name_via' => _x( 'Using plugin Enable Media Replace', 'PluginUserSwitchingLogger', 'simple-history' ),
|
26 |
+
'capability' => 'upload_files',
|
27 |
+
'messages' => array(
|
28 |
+
'replaced_file' => _x( 'Replaced attachment "{prev_attachment_title}" with new attachment "{new_attachment_title}"', 'PluginEnableMediaReplaceLogger', 'simple-history' ),
|
29 |
+
),
|
30 |
+
);
|
31 |
+
|
32 |
+
return $arr_info;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function loaded() {
|
36 |
+
|
37 |
+
// Action that is called when Enable Media Replace loads it's admin options page (both when viewing and when posting new file to it)
|
38 |
+
add_action( 'load-media_page_enable-media-replace/enable-media-replace', array( $this, 'on_load_plugin_admin_page' ), 10, 1 );
|
39 |
+
}
|
40 |
+
|
41 |
+
public function on_load_plugin_admin_page() {
|
42 |
+
|
43 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
44 |
+
if ( empty( $_POST ) ) {
|
45 |
+
return;
|
46 |
+
}
|
47 |
+
|
48 |
+
if ( isset( $_GET['action'] ) && $_GET['action'] == 'media_replace_upload' ) {
|
49 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
50 |
+
$attachment_id = empty( $_POST['ID'] ) ? null : (int) $_POST['ID'];
|
51 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
52 |
+
$replace_type = empty( $_POST['replace_type'] ) ? null : sanitize_text_field( $_POST['replace_type'] );
|
53 |
+
$new_file = empty( $_FILES['userfile'] ) ? null : (array) $_FILES['userfile'];
|
54 |
+
|
55 |
+
$prev_attachment_post = get_post( $attachment_id );
|
56 |
+
|
57 |
+
if ( empty( $attachment_id ) || empty( $new_file ) || empty( $prev_attachment_post ) ) {
|
58 |
+
return;
|
59 |
+
}
|
60 |
+
|
61 |
+
/*
|
62 |
+
get {
|
63 |
+
"page": "enable-media-replace\/enable-media-replace.php",
|
64 |
+
"noheader": "true",
|
65 |
+
"action": "media_replace_upload",
|
66 |
+
"attachment_id": "64085",
|
67 |
+
"_wpnonce": "1089573e0c"
|
68 |
+
}
|
69 |
+
|
70 |
+
post {
|
71 |
+
"ID": "64085",
|
72 |
+
"replace_type": "replace"
|
73 |
+
}
|
74 |
+
|
75 |
+
files {
|
76 |
+
"userfile": {
|
77 |
+
"name": "earth-transparent.png",
|
78 |
+
"type": "image\/png",
|
79 |
+
"tmp_name": "\/Applications\/MAMP\/tmp\/php\/phpKA2XOo",
|
80 |
+
"error": 0,
|
81 |
+
"size": 4325729
|
82 |
+
}
|
83 |
+
}
|
84 |
+
*/
|
85 |
+
|
86 |
+
$this->infoMessage(
|
87 |
+
'replaced_file',
|
88 |
+
array(
|
89 |
+
'attachment_id' => $attachment_id,
|
90 |
+
'prev_attachment_title' => get_the_title( $prev_attachment_post ),
|
91 |
+
'new_attachment_title' => $new_file['name'],
|
92 |
+
'new_attachment_type' => $new_file['type'],
|
93 |
+
'new_attachment_size' => $new_file['size'],
|
94 |
+
'replace_type' => $replace_type,
|
95 |
+
/*
|
96 |
+
"get" => $_GET,
|
97 |
+
"post" => $_POST,
|
98 |
+
"files" => $_FILES,
|
99 |
+
"old_attachment_post" => $prev_attachment_post,
|
100 |
+
"old_attachment_meta" => $prev_attachment_meta
|
101 |
+
*/
|
102 |
+
)
|
103 |
+
);
|
104 |
+
}// End if().
|
105 |
+
}
|
106 |
}
|
loggers/PluginUserSwitchingLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Logs user switching from the great User Switching plugin
|
@@ -8,133 +8,128 @@ 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 |
-
'user_id' => $user_id,
|
136 |
-
'user_login' => $user->user_login,
|
137 |
-
)
|
138 |
-
);
|
139 |
-
}
|
140 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
public function getInfo() {
|
22 |
+
|
23 |
+
$arr_info = array(
|
24 |
+
'name' => _x( 'User Switching Logger', 'PluginUserSwitchingLogger', 'simple-history' ),
|
25 |
+
'description' => _x( 'Logs user switches', 'PluginUserSwitchingLogger', 'simple-history' ),
|
26 |
+
// Definition of via: by way of, through the medium or agency of; also : by means of
|
27 |
+
'name_via' => _x( 'Using plugin User Switching', 'PluginUserSwitchingLogger', 'simple-history' ),
|
28 |
+
'capability' => 'edit_users',
|
29 |
+
'messages' => array(
|
30 |
+
'switched_to_user' => _x( 'Switched to user "{user_login_to}" from user "{user_login_from}"', 'PluginUserSwitchingLogger', 'simple-history' ),
|
31 |
+
'switched_back_user' => _x( 'Switched back to user "{user_login_to}" from user "{user_login_from}"', 'PluginUserSwitchingLogger', 'simple-history' ),
|
32 |
+
'switched_back_themself' => _x( 'Switched back to user "{user_login_to}"', 'PluginUserSwitchingLogger', 'simple-history' ),
|
33 |
+
'switched_off_user' => _x( 'Switched off user "{user_login}"', 'PluginUserSwitchingLogger', 'simple-history' ),
|
34 |
+
),
|
35 |
+
);
|
36 |
+
|
37 |
+
return $arr_info;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function loaded() {
|
41 |
+
|
42 |
+
add_action( 'switch_to_user', array( $this, 'on_switch_to_user' ), 10, 2 );
|
43 |
+
add_action( 'switch_back_user', array( $this, 'on_switch_back_user' ), 10, 2 );
|
44 |
+
add_action( 'switch_off_user', array( $this, 'on_switch_off_user' ), 10, 1 );
|
45 |
+
}
|
46 |
+
|
47 |
+
public function on_switch_to_user( $user_id, $old_user_id ) {
|
48 |
+
|
49 |
+
$user_to = get_user_by( 'id', $user_id );
|
50 |
+
$user_from = get_user_by( 'id', $old_user_id );
|
51 |
+
|
52 |
+
if ( ! is_a( $user_to, 'WP_User' ) || ! is_a( $user_from, 'WP_User' ) ) {
|
53 |
+
return;
|
54 |
+
}
|
55 |
+
|
56 |
+
$this->infoMessage(
|
57 |
+
'switched_to_user',
|
58 |
+
array(
|
59 |
+
// It is the old user who initiates the switching
|
60 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
61 |
+
'_user_id' => $old_user_id,
|
62 |
+
'user_id' => $user_id,
|
63 |
+
'old_user_id' => $old_user_id,
|
64 |
+
'user_login_to' => $user_to->user_login,
|
65 |
+
'user_login_from' => $user_from->user_login,
|
66 |
+
)
|
67 |
+
);
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Function is called when a user switches back to their originating account.
|
72 |
+
* When you switch back after being logged off the
|
73 |
+
*
|
74 |
+
* Note: $old_user_id parameter is boolean false because there is no old user.
|
75 |
+
*
|
76 |
+
* @param int $user_id The ID of the user being switched back to.
|
77 |
+
* @param int|false $old_user_id The ID of the user being switched from, or false if the user is switching back
|
78 |
+
* after having been switched off.
|
79 |
+
*/
|
80 |
+
public function on_switch_back_user( $user_id, $old_user_id ) {
|
81 |
+
|
82 |
+
$user_to = get_user_by( 'id', $user_id );
|
83 |
+
|
84 |
+
$user_from = $old_user_id == false ? null : get_user_by( 'id', $old_user_id );
|
85 |
+
|
86 |
+
if ( ! is_a( $user_to, 'WP_User' ) ) {
|
87 |
+
return;
|
88 |
+
}
|
89 |
+
|
90 |
+
if ( $user_from ) {
|
91 |
+
// User switched back from another user
|
92 |
+
$this->infoMessage(
|
93 |
+
'switched_back_user',
|
94 |
+
array(
|
95 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
96 |
+
'_user_id' => $old_user_id,
|
97 |
+
'user_id' => $user_id,
|
98 |
+
'old_user_id' => $old_user_id,
|
99 |
+
'user_login_to' => $user_to->user_login,
|
100 |
+
'user_login_from' => $user_from->user_login,
|
101 |
+
)
|
102 |
+
);
|
103 |
+
} else {
|
104 |
+
// User switched back to themself (no prev user)
|
105 |
+
$this->infoMessage(
|
106 |
+
'switched_back_themself',
|
107 |
+
array(
|
108 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
109 |
+
'_user_id' => $user_id,
|
110 |
+
'user_login_to' => $user_to->user_login,
|
111 |
+
)
|
112 |
+
);
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
public function on_switch_off_user( $user_id ) {
|
117 |
+
|
118 |
+
$user = get_user_by( 'id', $user_id );
|
119 |
+
|
120 |
+
if ( ! is_a( $user, 'WP_User' ) ) {
|
121 |
+
return;
|
122 |
+
}
|
123 |
+
|
124 |
+
$this->infoMessage(
|
125 |
+
'switched_off_user',
|
126 |
+
array(
|
127 |
+
'_initiator' => SimpleLoggerLogInitiators::WP_USER,
|
128 |
+
'_user_id' => $user_id,
|
129 |
+
|
130 |
+
'user_id' => $user_id,
|
131 |
+
'user_login' => $user->user_login,
|
132 |
+
)
|
133 |
+
);
|
134 |
+
}
|
|
|
|
|
|
|
|
|
|
|
135 |
}
|
loggers/PluginWPCrontrolLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Logs cron event management from the WP Crontrol plugin
|
@@ -10,419 +10,412 @@ defined('ABSPATH') or die();
|
|
10 |
*
|
11 |
* @since x.x
|
12 |
*/
|
13 |
-
class PluginWPCrontrolLogger extends SimpleLogger
|
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 |
-
return '';
|
289 |
-
}
|
290 |
-
|
291 |
-
protected function cronEventDetailsOutput($row) {
|
292 |
-
$tmpl_row = '
|
293 |
<tr>
|
294 |
<td>%1$s</td>
|
295 |
<td>%2$s</td>
|
296 |
</tr>
|
297 |
';
|
298 |
-
|
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 |
<tr>
|
393 |
<td>%1$s</td>
|
394 |
<td>%2$s</td>
|
395 |
</tr>
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Logs cron event management from the WP Crontrol plugin
|
10 |
*
|
11 |
* @since x.x
|
12 |
*/
|
13 |
+
class PluginWPCrontrolLogger extends SimpleLogger {
|
14 |
+
|
15 |
+
|
16 |
+
public $slug = __CLASS__;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Get array with information about this logger
|
20 |
+
*
|
21 |
+
* @return array
|
22 |
+
*/
|
23 |
+
public function getInfo() {
|
24 |
+
|
25 |
+
$arr_info = array(
|
26 |
+
'name' => _x( 'WP Crontrol Logger', 'PluginWPCrontrolLogger', 'simple-history' ),
|
27 |
+
'description' => _x( 'Logs management of cron events', 'PluginWPCrontrolLogger', 'simple-history' ),
|
28 |
+
'name_via' => _x( 'Using plugin WP Crontrol', 'PluginWPCrontrolLogger', 'simple-history' ),
|
29 |
+
'capability' => 'manage_options',
|
30 |
+
'messages' => array(
|
31 |
+
'added_new_event' => _x( 'Added cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history' ),
|
32 |
+
'ran_event' => _x( 'Manually ran cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history' ),
|
33 |
+
'deleted_event' => _x( 'Deleted cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history' ),
|
34 |
+
'deleted_all_with_hook' => _x( 'Deleted all "{event_hook}" cron events', 'PluginWPCrontrolLogger', 'simple-history' ),
|
35 |
+
'edited_event' => _x( 'Edited cron event "{event_hook}"', 'PluginWPCrontrolLogger', 'simple-history' ),
|
36 |
+
'added_new_schedule' => _x( 'Added cron schedule "{schedule_name}"', 'PluginWPCrontrolLogger', 'simple-history' ),
|
37 |
+
'deleted_schedule' => _x( 'Deleted cron schedule "{schedule_name}"', 'PluginWPCrontrolLogger', 'simple-history' ),
|
38 |
+
),
|
39 |
+
);
|
40 |
+
|
41 |
+
return $arr_info;
|
42 |
+
}
|
43 |
+
|
44 |
+
public function loaded() {
|
45 |
+
|
46 |
+
add_action( 'crontrol/added_new_event', array( $this, 'added_new_event' ) );
|
47 |
+
add_action( 'crontrol/added_new_php_event', array( $this, 'added_new_event' ) );
|
48 |
+
add_action( 'crontrol/ran_event', array( $this, 'ran_event' ) );
|
49 |
+
add_action( 'crontrol/deleted_event', array( $this, 'deleted_event' ) );
|
50 |
+
add_action( 'crontrol/deleted_all_with_hook', array( $this, 'deleted_all_with_hook' ), 10, 2 );
|
51 |
+
add_action( 'crontrol/edited_event', array( $this, 'edited_event' ), 10, 2 );
|
52 |
+
add_action( 'crontrol/edited_php_event', array( $this, 'edited_event' ), 10, 2 );
|
53 |
+
add_action( 'crontrol/added_new_schedule', array( $this, 'added_new_schedule' ), 10, 3 );
|
54 |
+
add_action( 'crontrol/deleted_schedule', array( $this, 'deleted_schedule' ) );
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Fires after a new cron event is added.
|
59 |
+
*
|
60 |
+
* @param object $event {
|
61 |
+
* An object containing the event's data.
|
62 |
+
*
|
63 |
+
* @type string $hook Action hook to execute when the event is run.
|
64 |
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
|
65 |
+
* @type string|false $schedule How often the event should subsequently recur.
|
66 |
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
|
67 |
+
* @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
|
68 |
+
* }
|
69 |
+
*/
|
70 |
+
public function added_new_event( $event ) {
|
71 |
+
$context = array(
|
72 |
+
'event_hook' => $event->hook,
|
73 |
+
'event_timestamp' => $event->timestamp,
|
74 |
+
'event_args' => $event->args,
|
75 |
+
);
|
76 |
+
|
77 |
+
if ( $event->schedule ) {
|
78 |
+
$context['event_schedule_name'] = $event->schedule;
|
79 |
+
|
80 |
+
if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
|
81 |
+
$context['event_schedule_name'] = \Crontrol\Event\get_schedule_name( $event );
|
82 |
+
}
|
83 |
+
} else {
|
84 |
+
$context['event_schedule_name'] = _x( 'None', 'PluginWPCrontrolLogger', 'simple-history' );
|
85 |
+
}
|
86 |
+
|
87 |
+
$this->infoMessage(
|
88 |
+
'added_new_event',
|
89 |
+
$context
|
90 |
+
);
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Fires after a cron event is ran manually.
|
95 |
+
*
|
96 |
+
* @param object $event {
|
97 |
+
* An object containing the event's data.
|
98 |
+
*
|
99 |
+
* @type string $hook Action hook to execute when the event is run.
|
100 |
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
|
101 |
+
* @type string|false $schedule How often the event should subsequently recur.
|
102 |
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
|
103 |
+
* @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
|
104 |
+
* }
|
105 |
+
*/
|
106 |
+
public function ran_event( $event ) {
|
107 |
+
$context = array(
|
108 |
+
'event_hook' => $event->hook,
|
109 |
+
'event_args' => $event->args,
|
110 |
+
);
|
111 |
+
|
112 |
+
$this->infoMessage(
|
113 |
+
'ran_event',
|
114 |
+
$context
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Fires after a cron event is deleted.
|
120 |
+
*
|
121 |
+
* @param object $event {
|
122 |
+
* An object containing the event's data.
|
123 |
+
*
|
124 |
+
* @type string $hook Action hook to execute when the event is run.
|
125 |
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
|
126 |
+
* @type string|false $schedule How often the event should subsequently recur.
|
127 |
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
|
128 |
+
* @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
|
129 |
+
* }
|
130 |
+
*/
|
131 |
+
public function deleted_event( $event ) {
|
132 |
+
$context = array(
|
133 |
+
'event_hook' => $event->hook,
|
134 |
+
'event_timestamp' => $event->timestamp,
|
135 |
+
'event_args' => $event->args,
|
136 |
+
);
|
137 |
+
|
138 |
+
if ( $event->schedule ) {
|
139 |
+
$context['event_schedule_name'] = $event->schedule;
|
140 |
+
|
141 |
+
if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
|
142 |
+
$context['event_schedule_name'] = \Crontrol\Event\get_schedule_name( $event );
|
143 |
+
}
|
144 |
+
} else {
|
145 |
+
$context['event_schedule_name'] = _x( 'None', 'PluginWPCrontrolLogger', 'simple-history' );
|
146 |
+
}
|
147 |
+
|
148 |
+
$this->infoMessage(
|
149 |
+
'deleted_event',
|
150 |
+
$context
|
151 |
+
);
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Fires after all cron events with the given hook are deleted.
|
156 |
+
*
|
157 |
+
* @param string $hook The hook name.
|
158 |
+
* @param int $deleted The number of events that were deleted.
|
159 |
+
*/
|
160 |
+
public function deleted_all_with_hook( $hook, $deleted ) {
|
161 |
+
$context = array(
|
162 |
+
'event_hook' => $hook,
|
163 |
+
'events_deleted' => $deleted,
|
164 |
+
);
|
165 |
+
|
166 |
+
$this->infoMessage(
|
167 |
+
'deleted_all_with_hook',
|
168 |
+
$context
|
169 |
+
);
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Fires after a cron event is edited.
|
174 |
+
*
|
175 |
+
* @param object $event {
|
176 |
+
* An object containing the new event's data.
|
177 |
+
*
|
178 |
+
* @type string $hook Action hook to execute when the event is run.
|
179 |
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
|
180 |
+
* @type string|false $schedule How often the event should subsequently recur.
|
181 |
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
|
182 |
+
* @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
|
183 |
+
* }
|
184 |
+
* @param object $original {
|
185 |
+
* An object containing the original event's data.
|
186 |
+
*
|
187 |
+
* @type string $hook Action hook to execute when the event is run.
|
188 |
+
* @type int $timestamp Unix timestamp (UTC) for when to next run the event.
|
189 |
+
* @type string|false $schedule How often the event should subsequently recur.
|
190 |
+
* @type array $args Array containing each separate argument to pass to the hook's callback function.
|
191 |
+
* @type int $interval The interval time in seconds for the schedule. Only present for recurring events.
|
192 |
+
* }
|
193 |
+
*/
|
194 |
+
public function edited_event( $event, $original ) {
|
195 |
+
$context = array(
|
196 |
+
'event_hook' => $event->hook,
|
197 |
+
'event_timestamp' => $event->timestamp,
|
198 |
+
'event_args' => $event->args,
|
199 |
+
'event_original_hook' => $original->hook,
|
200 |
+
'event_original_timestamp' => $original->timestamp,
|
201 |
+
'event_original_args' => $original->args,
|
202 |
+
);
|
203 |
+
|
204 |
+
if ( $event->schedule ) {
|
205 |
+
$context['event_schedule_name'] = $event->schedule;
|
206 |
+
|
207 |
+
if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
|
208 |
+
$context['event_schedule_name'] = \Crontrol\Event\get_schedule_name( $event );
|
209 |
+
}
|
210 |
+
} else {
|
211 |
+
$context['event_schedule_name'] = _x( 'None', 'PluginWPCrontrolLogger', 'simple-history' );
|
212 |
+
}
|
213 |
+
|
214 |
+
if ( $original->schedule ) {
|
215 |
+
$context['event_original_schedule_name'] = $original->schedule;
|
216 |
+
|
217 |
+
if ( function_exists( '\Crontrol\Event\get_schedule_name' ) ) {
|
218 |
+
$context['event_original_schedule_name'] = \Crontrol\Event\get_schedule_name( $original );
|
219 |
+
}
|
220 |
+
} else {
|
221 |
+
$context['event_original_schedule_name'] = _x( 'None', 'PluginWPCrontrolLogger', 'simple-history' );
|
222 |
+
}
|
223 |
+
|
224 |
+
$this->infoMessage(
|
225 |
+
'edited_event',
|
226 |
+
$context
|
227 |
+
);
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Fires after a new cron schedule is added.
|
232 |
+
*
|
233 |
+
* @param string $name The internal name of the schedule.
|
234 |
+
* @param int $interval The interval between executions of the new schedule.
|
235 |
+
* @param string $display The display name of the schedule.
|
236 |
+
*/
|
237 |
+
public function added_new_schedule( $name, $interval, $display ) {
|
238 |
+
$context = array(
|
239 |
+
'schedule_name' => $name,
|
240 |
+
'schedule_interval' => $interval,
|
241 |
+
'schedule_display' => $display,
|
242 |
+
);
|
243 |
+
|
244 |
+
$this->infoMessage(
|
245 |
+
'added_new_schedule',
|
246 |
+
$context
|
247 |
+
);
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Fires after a cron schedule is deleted.
|
252 |
+
*
|
253 |
+
* @param string $name The internal name of the schedule.
|
254 |
+
*/
|
255 |
+
public function deleted_schedule( $name ) {
|
256 |
+
$context = array(
|
257 |
+
'schedule_name' => $name,
|
258 |
+
);
|
259 |
+
|
260 |
+
$this->infoMessage(
|
261 |
+
'deleted_schedule',
|
262 |
+
$context
|
263 |
+
);
|
264 |
+
}
|
265 |
+
|
266 |
+
public function getLogRowDetailsOutput( $row ) {
|
267 |
+
switch ( $row->context_message_key ) {
|
268 |
+
case 'added_new_event':
|
269 |
+
case 'ran_event':
|
270 |
+
case 'deleted_event':
|
271 |
+
case 'deleted_all_with_hook':
|
272 |
+
case 'edited_event':
|
273 |
+
return $this->cronEventDetailsOutput( $row );
|
274 |
+
break;
|
275 |
+
case 'added_new_schedule':
|
276 |
+
case 'deleted_schedule':
|
277 |
+
return $this->cronScheduleDetailsOutput( $row );
|
278 |
+
break;
|
279 |
+
}
|
280 |
+
|
281 |
+
return '';
|
282 |
+
}
|
283 |
+
|
284 |
+
protected function cronEventDetailsOutput( $row ) {
|
285 |
+
$tmpl_row = '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
<tr>
|
287 |
<td>%1$s</td>
|
288 |
<td>%2$s</td>
|
289 |
</tr>
|
290 |
';
|
291 |
+
$context = $row->context;
|
292 |
+
$output = '<table class="SimpleHistoryLogitem__keyValueTable">';
|
293 |
+
|
294 |
+
if ( isset( $context['event_original_hook'] ) && ( $context['event_original_hook'] !== $context['event_hook'] ) ) {
|
295 |
+
$key_text_diff = simple_history_text_diff(
|
296 |
+
$context['event_original_hook'],
|
297 |
+
$context['event_hook']
|
298 |
+
);
|
299 |
+
|
300 |
+
if ( $key_text_diff ) {
|
301 |
+
$output .= sprintf(
|
302 |
+
$tmpl_row,
|
303 |
+
_x( 'Hook', 'PluginWPCrontrolLogger', 'simple-history' ),
|
304 |
+
$key_text_diff
|
305 |
+
);
|
306 |
+
}
|
307 |
+
}
|
308 |
+
|
309 |
+
if ( isset( $context['event_original_args'] ) && ( $context['event_original_args'] !== $context['event_args'] ) ) {
|
310 |
+
$key_text_diff = simple_history_text_diff(
|
311 |
+
$context['event_original_args'],
|
312 |
+
$context['event_args']
|
313 |
+
);
|
314 |
+
|
315 |
+
if ( $key_text_diff ) {
|
316 |
+
$output .= sprintf(
|
317 |
+
$tmpl_row,
|
318 |
+
_x( 'Arguments', 'PluginWPCrontrolLogger', 'simple-history' ),
|
319 |
+
$key_text_diff
|
320 |
+
);
|
321 |
+
}
|
322 |
+
} else if ( isset( $context['event_args'] ) ) {
|
323 |
+
if ( '[]' !== $context['event_args'] ) {
|
324 |
+
$args = $context['event_args'];
|
325 |
+
} else {
|
326 |
+
$args = _x( 'None', 'PluginWPCrontrolLogger', 'simple-history' );
|
327 |
+
}
|
328 |
+
|
329 |
+
$output .= sprintf(
|
330 |
+
$tmpl_row,
|
331 |
+
_x( 'Arguments', 'PluginWPCrontrolLogger', 'simple-history' ),
|
332 |
+
esc_html( $args )
|
333 |
+
);
|
334 |
+
}
|
335 |
+
|
336 |
+
if ( isset( $context['event_original_timestamp'] ) && ( $context['event_original_timestamp'] !== $context['event_timestamp'] ) ) {
|
337 |
+
$key_text_diff = simple_history_text_diff(
|
338 |
+
gmdate( 'Y-m-d H:i:s', $context['event_original_timestamp'] ),
|
339 |
+
gmdate( 'Y-m-d H:i:s', $context['event_timestamp'] )
|
340 |
+
);
|
341 |
+
|
342 |
+
if ( $key_text_diff ) {
|
343 |
+
$output .= sprintf(
|
344 |
+
$tmpl_row,
|
345 |
+
_x( 'Next Run', 'PluginWPCrontrolLogger', 'simple-history' ),
|
346 |
+
$key_text_diff
|
347 |
+
);
|
348 |
+
}
|
349 |
+
} else if ( isset( $context['event_timestamp'] ) ) {
|
350 |
+
$output .= sprintf(
|
351 |
+
$tmpl_row,
|
352 |
+
_x( 'Next Run', 'PluginWPCrontrolLogger', 'simple-history' ),
|
353 |
+
esc_html( gmdate( 'Y-m-d H:i:s', $context['event_timestamp'] ) . ' UTC' )
|
354 |
+
);
|
355 |
+
}
|
356 |
+
|
357 |
+
if ( isset( $context['event_original_schedule_name'] ) && ( $context['event_original_schedule_name'] !== $context['event_schedule_name'] ) ) {
|
358 |
+
$key_text_diff = simple_history_text_diff(
|
359 |
+
$context['event_original_schedule_name'],
|
360 |
+
$context['event_schedule_name']
|
361 |
+
);
|
362 |
+
|
363 |
+
if ( $key_text_diff ) {
|
364 |
+
$output .= sprintf(
|
365 |
+
$tmpl_row,
|
366 |
+
_x( 'Recurrence', 'PluginWPCrontrolLogger', 'simple-history' ),
|
367 |
+
$key_text_diff
|
368 |
+
);
|
369 |
+
}
|
370 |
+
} else if ( isset( $context['event_schedule_name'] ) ) {
|
371 |
+
$output .= sprintf(
|
372 |
+
$tmpl_row,
|
373 |
+
_x( 'Recurrence', 'PluginWPCrontrolLogger', 'simple-history' ),
|
374 |
+
esc_html( $context['event_schedule_name'] )
|
375 |
+
);
|
376 |
+
}
|
377 |
+
|
378 |
+
$output .= '</table>';
|
379 |
+
|
380 |
+
return $output;
|
381 |
+
}
|
382 |
+
|
383 |
+
protected function cronScheduleDetailsOutput( $row ) {
|
384 |
+
$tmpl_row = '
|
385 |
<tr>
|
386 |
<td>%1$s</td>
|
387 |
<td>%2$s</td>
|
388 |
</tr>
|
389 |
';
|
390 |
+
$context = $row->context;
|
391 |
+
$output = '<table class="SimpleHistoryLogitem__keyValueTable">';
|
392 |
+
|
393 |
+
if ( isset( $context['schedule_name'] ) ) {
|
394 |
+
$output .= sprintf(
|
395 |
+
$tmpl_row,
|
396 |
+
_x( 'Name', 'PluginWPCrontrolLogger', 'simple-history' ),
|
397 |
+
esc_html( $context['schedule_name'] )
|
398 |
+
);
|
399 |
+
}
|
400 |
+
|
401 |
+
if ( isset( $context['schedule_interval'] ) ) {
|
402 |
+
$output .= sprintf(
|
403 |
+
$tmpl_row,
|
404 |
+
_x( 'Interval', 'PluginWPCrontrolLogger', 'simple-history' ),
|
405 |
+
esc_html( $context['schedule_interval'] )
|
406 |
+
);
|
407 |
+
}
|
408 |
+
|
409 |
+
if ( isset( $context['schedule_display'] ) ) {
|
410 |
+
$output .= sprintf(
|
411 |
+
$tmpl_row,
|
412 |
+
_x( 'Display Name', 'PluginWPCrontrolLogger', 'simple-history' ),
|
413 |
+
esc_html( $context['schedule_display'] )
|
414 |
+
);
|
415 |
+
}
|
416 |
+
|
417 |
+
$output .= '</table>';
|
418 |
+
|
419 |
+
return $output;
|
420 |
+
}
|
421 |
}
|
loggers/Plugin_ACF.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH') || die();
|
4 |
|
5 |
/**
|
6 |
* Logger for the Advanced Custom Fields (ACF) plugin
|
@@ -9,1074 +9,1072 @@ defined('ABSPATH') || die();
|
|
9 |
* @package SimpleHistory
|
10 |
* @since 2.21
|
11 |
*/
|
12 |
-
if (! class_exists('Plugin_ACF')) {
|
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 |
-
if (isset($context[ "acf_new_$acfKey" ]) && isset($context[ "acf_prev_$acfKey" ])) {
|
582 |
-
$diff_table_output .= sprintf(
|
583 |
-
'<tr>
|
584 |
<td>%1$s</td>
|
585 |
<td>
|
586 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
587 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
588 |
</td>
|
589 |
</tr>',
|
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 |
<td>%1$s</td>
|
624 |
<td>
|
625 |
%2$s
|
626 |
%3$s
|
627 |
</td>
|
628 |
</tr>',
|
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 |
<td>%1$s</td>
|
657 |
<td>%2$s</td>
|
658 |
</tr>',
|
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 |
<td>%1$s</td>
|
686 |
<td>%2$s</td>
|
687 |
</tr>',
|
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 |
%4$s
|
747 |
%3$s
|
748 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%1$s</ins>
|
749 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%2$s</del>
|
750 |
',
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
<td>%1$s</td>
|
765 |
<td>%2$s</td>
|
766 |
</tr>',
|
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 |
} // 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 |
+
$arr_info = array(
|
59 |
+
'name' => 'Plugin ACF',
|
60 |
+
'description' => _x( 'Logs ACF stuff', 'Logger: Plugin ACF', 'simple-history' ),
|
61 |
+
'name_via' => _x( 'Using plugin ACF', 'Logger: Plugin ACF', 'simple-history' ),
|
62 |
+
'capability' => 'manage_options',
|
63 |
+
);
|
64 |
+
|
65 |
+
return $arr_info;
|
66 |
+
}
|
67 |
+
|
68 |
+
private function isACFInstalled() {
|
69 |
+
return defined( 'ACF' ) && ACF;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Method called when logger is loaded.
|
74 |
+
*/
|
75 |
+
public function loaded() {
|
76 |
+
|
77 |
+
// Bail if no ACF found.
|
78 |
+
if ( ! $this->isACFInstalled() ) {
|
79 |
+
return;
|
80 |
+
}
|
81 |
+
|
82 |
+
// Remove ACF Fields from the post types that postlogger logs.
|
83 |
+
add_filter( 'simple_history/post_logger/skip_posttypes', array( $this, 'remove_acf_from_postlogger' ) );
|
84 |
+
|
85 |
+
// Get prev version of acf field group.
|
86 |
+
// This is called before transition_post_status.
|
87 |
+
add_filter( 'wp_insert_post_data', array( $this, 'on_wp_insert_post_data' ), 10, 2 );
|
88 |
+
|
89 |
+
// Store old and new field data when a post is saved.
|
90 |
+
add_action( 'transition_post_status', array( $this, 'on_transition_post_status' ), 5, 3 );
|
91 |
+
|
92 |
+
// Append ACF data to post context
|
93 |
+
add_filter( 'simple_history/post_logger/post_updated/context', array( $this, 'on_post_updated_context' ), 10, 2 );
|
94 |
+
|
95 |
+
// Add ACF diff data to activity feed detailed output.
|
96 |
+
add_filter( 'simple_history/post_logger/post_updated/diff_table_output', array( $this, 'on_diff_table_output_field_group' ), 10, 2 );
|
97 |
+
|
98 |
+
// Store prev ACF field values before new values are added.
|
99 |
+
// Called from filter admin_action_editpost that is fired at top of admin.php
|
100 |
+
add_action( 'admin_action_editpost', array( $this, 'on_admin_action_editpost' ) );
|
101 |
+
|
102 |
+
// Fired when ACF saves a post. Adds ACF context to logged row.
|
103 |
+
add_filter( 'acf/save_post', array( $this, 'on_acf_save_post' ), 50 );
|
104 |
+
|
105 |
+
// Fired after a log row is inserted. Add filter so field group save is is not logged again.
|
106 |
+
add_action( 'simple_history/log/inserted', array( $this, 'on_log_inserted' ), 10, 3 );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Fired after a log row is inserted.
|
111 |
+
*/
|
112 |
+
public function on_log_inserted( $context, $data_parent_row, $simple_history_instance ) {
|
113 |
+
$message_key = ! empty( $context['_message_key'] ) ? $context['_message_key'] : false;
|
114 |
+
$logger = ! empty( $data_parent_row['logger'] ) ? $data_parent_row['logger'] : false;
|
115 |
+
$post_id = ! empty( $context['post_id'] ) ? $context['post_id'] : false;
|
116 |
+
$post_type = ! empty( $context['post_type'] ) ? $context['post_type'] : false;
|
117 |
+
|
118 |
+
// Bail if not all required vars are set.
|
119 |
+
if ( ! $message_key || ! $logger || ! $post_id || ! $post_type ) {
|
120 |
+
return;
|
121 |
+
}
|
122 |
+
|
123 |
+
// Only act when logger was SimplePostLogger.
|
124 |
+
if ( $logger !== 'SimplePostLogger' ) {
|
125 |
+
return;
|
126 |
+
}
|
127 |
+
|
128 |
+
// Only act when the saved type was a ACF Field Group.
|
129 |
+
if ( $post_type !== 'acf-field-group' ) {
|
130 |
+
return;
|
131 |
+
}
|
132 |
+
|
133 |
+
// Ok, a row was inserted using the log function on SimplePostLogger,
|
134 |
+
// now ACF will call save_post again and trigger
|
135 |
+
// another log of the same row. To prevent this we
|
136 |
+
// now add a filter to prevent the next log.
|
137 |
+
add_filter( 'simple_history/post_logger/post_updated/ok_to_log', array( $this, 'prevent_second_acf_field_group_post_save_log' ), 10, 4 );
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Fired from SimpleLogger action 'simple_history/post_logger/post_updated/ok_to_log' and added only after
|
142 |
+
* a row already has been logged.
|
143 |
+
*
|
144 |
+
* This function checks if post type logged by SimplePostLogger is a ACF Field Group, and if it is
|
145 |
+
* then don't log that log. This way we prevent the post logger from logging the field group changes twice.
|
146 |
+
*/
|
147 |
+
public function prevent_second_acf_field_group_post_save_log( $ok_to_log, $new_status, $old_status, $post ) {
|
148 |
+
if ( isset( $post->post_type ) && $post->post_type === 'acf-field-group' ) {
|
149 |
+
$ok_to_log = false;
|
150 |
+
}
|
151 |
+
|
152 |
+
return $ok_to_log;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Append info about changes in ACF fields input,
|
157 |
+
* i.e. store all info we later use to show changes that a user has done.
|
158 |
+
*
|
159 |
+
* Called when ACF saves a post.
|
160 |
+
*
|
161 |
+
* @param mixed int $post_id ID of post that is being saved. string "option" or "options" when saving an options page.
|
162 |
+
*/
|
163 |
+
public function on_acf_save_post( $post_id ) {
|
164 |
+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
165 |
+
return;
|
166 |
+
}
|
167 |
+
|
168 |
+
// Only act when $post_id is numeric, can be "options" too when
|
169 |
+
// ACF saves an options page.
|
170 |
+
if ( ! is_numeric( $post_id ) ) {
|
171 |
+
return;
|
172 |
+
}
|
173 |
+
|
174 |
+
// Don't act on post revision.
|
175 |
+
if ( wp_is_post_revision( $post_id ) ) {
|
176 |
+
return;
|
177 |
+
}
|
178 |
+
|
179 |
+
/*
|
180 |
+
Meta values look like
|
181 |
+
[product_images_0_image] => 625
|
182 |
+
[_product_images_0_image] => field_59a091044812e
|
183 |
+
[product_images_0_image_caption] => Image row yes
|
184 |
+
[_product_images_0_image_caption] => field_59a0910f4812f
|
185 |
+
[product_images_0_image_related_0_related_name] => Related one
|
186 |
+
[_product_images_0_image_related_0_related_name] => field_59aaedd43ae11
|
187 |
+
[product_images_0_image_related_0_related_item_post] =>
|
188 |
+
[_product_images_0_image_related_0_related_item_post] => field_59aaede43ae12
|
189 |
+
[product_images_0_image_related_1_related_name] => Another related
|
190 |
+
[_product_images_0_image_related_1_related_name] => field_59aaedd43ae11
|
191 |
+
[product_images_0_image_related_1_related_item_post] =>
|
192 |
+
[_product_images_0_image_related_1_related_item_post] => field_59aaede43ae12
|
193 |
+
[product_images_0_image_related] => 2
|
194 |
+
[_product_images_0_image_related] => field_59aaedbc3ae10
|
195 |
+
[product_images_1_image] => 574
|
196 |
+
*/
|
197 |
+
$prev_post_meta = isset( $this->oldPostData['prev_post_meta'] ) ? $this->oldPostData['prev_post_meta'] : array();
|
198 |
+
|
199 |
+
$new_post_meta = get_post_custom( $post_id );
|
200 |
+
array_walk(
|
201 |
+
$new_post_meta,
|
202 |
+
function( &$value, $key ) {
|
203 |
+
$value = reset( $value );
|
204 |
+
}
|
205 |
+
);
|
206 |
+
|
207 |
+
// New and old post meta can contain different amount of keys,
|
208 |
+
// join them so we have the name of all post meta thaf have been added, removed, or modified.
|
209 |
+
$new_and_old_post_meta = array_merge( $prev_post_meta, $new_post_meta );
|
210 |
+
ksort( $new_and_old_post_meta, SORT_REGULAR );
|
211 |
+
|
212 |
+
// array1 - The array to compare from
|
213 |
+
// array2 - An array to compare against
|
214 |
+
// Returns an array containing all the values from array1 that are not present in any of the other arrays.
|
215 |
+
// Keep only ACF fields in prev and new post meta.
|
216 |
+
$prev_post_meta = $this->keep_only_acf_stuff_in_array( $prev_post_meta, $new_and_old_post_meta );
|
217 |
+
$new_post_meta = $this->keep_only_acf_stuff_in_array( $new_post_meta, $new_and_old_post_meta );
|
218 |
+
$new_and_old_post_meta_acf_fields = array_merge( $prev_post_meta, $new_post_meta );
|
219 |
+
|
220 |
+
// Map field name with fieldkey so we can get field objects when needed.
|
221 |
+
// Final array have values like:
|
222 |
+
// [product_images_0_image] => field_59a091044812e
|
223 |
+
// [product_images_0_image_caption] => field_59a0910f4812f
|
224 |
+
// [product_images_0_image_related_0_related_name] => field_59aaedd43ae11.
|
225 |
+
$fieldnames_to_field_keys = array();
|
226 |
+
foreach ( $new_and_old_post_meta_acf_fields as $meta_key => $meta_value ) {
|
227 |
+
// $key is like [product_images_0_image_related_1_related_name].
|
228 |
+
// Get ACF fieldkey for that value. Will be in $new_and_old_post_meta
|
229 |
+
// as the same as key but with underscore first
|
230 |
+
$meta_key_to_look_for = "_{$meta_key}";
|
231 |
+
if ( isset( $new_and_old_post_meta[ $meta_key_to_look_for ] ) ) {
|
232 |
+
$fieldnames_to_field_keys[ $meta_key ] = $new_and_old_post_meta[ $meta_key_to_look_for ];
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
// Compare old with new = get only changed, not added, deleted are here.
|
237 |
+
$post_meta_diff1 = array_diff_assoc( $prev_post_meta, $new_post_meta );
|
238 |
+
|
239 |
+
// Compare new with old = get an diff with added and changed stuff.
|
240 |
+
$post_meta_diff2 = array_diff_assoc( $new_post_meta, $prev_post_meta );
|
241 |
+
|
242 |
+
// Compare keys, gets added fields.
|
243 |
+
$post_meta_added_fields = array_diff( array_keys( $post_meta_diff2 ), array_keys( $post_meta_diff1 ) );
|
244 |
+
$post_meta_added_fields = array_values( $post_meta_added_fields );
|
245 |
+
|
246 |
+
// Keys that exist in diff1 but not in diff2 = deleted.
|
247 |
+
$post_meta_removed_fields = array_diff_assoc( array_keys( $post_meta_diff1 ), array_keys( $post_meta_diff2 ) );
|
248 |
+
$post_meta_removed_fields = array_values( $post_meta_removed_fields );
|
249 |
+
|
250 |
+
$post_meta_changed_fields = array_keys( $post_meta_diff1 );
|
251 |
+
|
252 |
+
/*
|
253 |
+
* value is changed: added to both diff and diff2
|
254 |
+
* value is added, like in repeater: added to diff2 (not to diff)
|
255 |
+
* $diff3: contains only added things.
|
256 |
+
* Compare old and new values
|
257 |
+
* Loop all keys in $new_and_old_post_meta
|
258 |
+
* But act only on those whose keys begins with "_" and where the value begins with "field_" and ends with alphanum.
|
259 |
+
*/
|
260 |
+
|
261 |
+
/*
|
262 |
+
* We have the diff, now add it to the context
|
263 |
+
* This is called after Simple History already has added its row
|
264 |
+
* So... we must add to the context late somehow
|
265 |
+
* Get the latest inserted row from the SimplePostLogger, check if that postID is
|
266 |
+
* same as the
|
267 |
+
*/
|
268 |
+
$post_logger = $this->simpleHistory->getInstantiatedLoggerBySlug( 'SimplePostLogger' );
|
269 |
+
|
270 |
+
// Save ACF diff if detected post here is same as the last one used in Postlogger.
|
271 |
+
if ( isset( $post_logger->lastInsertContext['post_id'] ) && $post_id === $post_logger->lastInsertContext['post_id'] ) {
|
272 |
+
$last_insert_id = $post_logger->lastInsertID;
|
273 |
+
|
274 |
+
// Append new info to the context of history item with id $post_logger->lastInsertID.
|
275 |
+
$acf_context = array();
|
276 |
+
$acf_context = $this->add_acf_context( $acf_context, 'added', $post_meta_added_fields, $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys );
|
277 |
+
$acf_context = $this->add_acf_context( $acf_context, 'changed', $post_meta_changed_fields, $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys );
|
278 |
+
$acf_context = $this->add_acf_context( $acf_context, 'removed', $post_meta_removed_fields, $prev_post_meta, $new_post_meta, $fieldnames_to_field_keys );
|
279 |
+
|
280 |
+
$post_logger->append_context( $last_insert_id, $acf_context );
|
281 |
+
|
282 |
+
// Prev and new post meta for testing.
|
283 |
+
/*
|
284 |
+
$post_logger->append_context(
|
285 |
+
$last_insert_id,
|
286 |
+
array(
|
287 |
+
'prev_post_meta' => $prev_post_meta,
|
288 |
+
)
|
289 |
+
);
|
290 |
+
$post_logger->append_context(
|
291 |
+
$last_insert_id,
|
292 |
+
array(
|
293 |
+
'new_post_meta' => $new_post_meta,
|
294 |
+
)
|
295 |
+
);
|
296 |
+
*/
|
297 |
+
} // End if().
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Add ACF context for added, removed, or changed fields.
|
302 |
+
*
|
303 |
+
* @param array $context Context.
|
304 |
+
* @param string $modify_type Type. added | removed | changed.
|
305 |
+
* @param array $relevant_acf_fields Fields.
|
306 |
+
* @param array $prev_post_meta Prev meta.
|
307 |
+
* @param array $new_post_meta New meta.
|
308 |
+
* @param array $fieldnames_to_field_keys Fieldnames to field keys mapping.
|
309 |
+
* @return array Modified context.
|
310 |
+
*/
|
311 |
+
public function add_acf_context( $context = array(), $modify_type = '', $relevant_acf_fields = array(), $prev_post_meta = array(), $new_post_meta = array(), $fieldnames_to_field_keys = array() ) {
|
312 |
+
|
313 |
+
if ( ! is_array( $context ) || empty( $modify_type ) || empty( $relevant_acf_fields ) ) {
|
314 |
+
return $context;
|
315 |
+
}
|
316 |
+
|
317 |
+
$loopnum = 0;
|
318 |
+
foreach ( $relevant_acf_fields as $field_slug ) {
|
319 |
+
/*
|
320 |
+
Store just the names to begin with
|
321 |
+
acf_field_added_0 = url.
|
322 |
+
acf_field_added_1 = first_name.
|
323 |
+
|
324 |
+
If field slug contains a number, like in "product_images_2_image"
|
325 |
+
that probably means that that field is a repeater with name "product_images"
|
326 |
+
with a sub field called "image" and that the image is the 2:nd among it's selected sub fields.
|
327 |
+
|
328 |
+
Example of how fields can look:
|
329 |
+
acf_field_added_0 product_images_2_image
|
330 |
+
acf_field_added_1 product_images_2_image_caption
|
331 |
+
acf_field_added_2 product_images_2_image_related
|
332 |
+
acf_field_changed_0 my_field_in_acf
|
333 |
+
acf_field_changed_1 product_images
|
334 |
+
acf_field_changed_2 price
|
335 |
+
acf_field_changed_3 description
|
336 |
+
*/
|
337 |
+
$context_key = "acf_field_{$modify_type}_{$loopnum}";
|
338 |
+
$context[ "{$context_key}/slug" ] = $field_slug;
|
339 |
+
|
340 |
+
/*
|
341 |
+
* Try to get som extra info, like display name and type for this field.
|
342 |
+
* For a nice context in the feed we want: parent field group name and type?
|
343 |
+
*/
|
344 |
+
if ( isset( $fieldnames_to_field_keys[ $field_slug ] ) ) {
|
345 |
+
$field_key = $fieldnames_to_field_keys[ $field_slug ];
|
346 |
+
$context[ "{$context_key}/key" ] = $field_key;
|
347 |
+
|
348 |
+
// Interesting stuff in field object:
|
349 |
+
// - Label = the human readable name of the field
|
350 |
+
// - Type = the type of the field
|
351 |
+
// - Parent = id of parent field post id.
|
352 |
+
$field_object = get_field_object( $field_key );
|
353 |
+
|
354 |
+
if ( is_array( $field_object ) ) {
|
355 |
+
$context[ "{$context_key}/label" ] = $field_object['label'];
|
356 |
+
if ( ! empty( $field_object['type'] ) ) {
|
357 |
+
$context[ "{$context_key}/type" ] = $field_object['type'];
|
358 |
+
}
|
359 |
+
|
360 |
+
// If no parent just continue to next field.
|
361 |
+
if ( empty( $field_object['parent'] ) ) {
|
362 |
+
continue;
|
363 |
+
}
|
364 |
+
|
365 |
+
// We have at least one parent, get them all, including the field group
|
366 |
+
// $context[ "{$context_key}/field_parent_object" ] = $parent_field;
|
367 |
+
$field_parents = array();
|
368 |
+
$field_field_group = null;
|
369 |
+
|
370 |
+
// Begin with the direct parent.
|
371 |
+
$parent_field = $field_object;
|
372 |
+
|
373 |
+
while ( ! empty( $parent_field['parent'] ) ) {
|
374 |
+
$parentFieldParent = $parent_field['parent'];
|
375 |
+
|
376 |
+
// acf-field | acf-field-group.
|
377 |
+
$parent_field_post_type = get_post_type( $parentFieldParent );
|
378 |
+
|
379 |
+
if ( false === $parent_field_post_type ) {
|
380 |
+
break;
|
381 |
+
}
|
382 |
+
|
383 |
+
if ( 'acf-field' === $parent_field_post_type ) {
|
384 |
+
// Field is when field is for example a sub field of a repeater.
|
385 |
+
if ( function_exists( 'acf_get_field' ) ) {
|
386 |
+
// Since ACF 5.7.10 the acf_get_field() function is available.
|
387 |
+
$parent_field = acf_get_field( $parentFieldParent );
|
388 |
+
} elseif ( function_exists( '_acf_get_field_by_id' ) ) {
|
389 |
+
// ACF function _acf_get_field_by_id() is available before ACF 5.7.10.
|
390 |
+
$parent_field = _acf_get_field_by_id( $parentFieldParent );
|
391 |
+
}
|
392 |
+
} elseif ( 'acf-field-group' === $parent_field_post_type ) {
|
393 |
+
$parent_field = acf_get_field_group( $parentFieldParent );
|
394 |
+
} else {
|
395 |
+
// Unknown post type.
|
396 |
+
break;
|
397 |
+
}
|
398 |
+
|
399 |
+
if ( false === $parent_field ) {
|
400 |
+
break;
|
401 |
+
}
|
402 |
+
|
403 |
+
if ( 'acf-field' === $parent_field_post_type ) {
|
404 |
+
$field_parents[] = $parent_field;
|
405 |
+
} elseif ( 'acf-field-group' === $parent_field_post_type ) {
|
406 |
+
$field_field_group = $parent_field;
|
407 |
+
} // End if().
|
408 |
+
} // End while().
|
409 |
+
|
410 |
+
$field_parents = array_reverse( $field_parents );
|
411 |
+
|
412 |
+
// Array with info about each parent.
|
413 |
+
$arr_field_path = array();
|
414 |
+
|
415 |
+
if ( ! empty( $field_field_group['title'] ) ) {
|
416 |
+
$arr_field_path[] = array(
|
417 |
+
'name' => $field_field_group['title'],
|
418 |
+
'type' => 'field_group',
|
419 |
+
);
|
420 |
+
}
|
421 |
+
|
422 |
+
foreach ( $field_parents as $one_field_parent ) {
|
423 |
+
$arr_field_path[] = array(
|
424 |
+
'name' => $one_field_parent['label'],
|
425 |
+
'type' => 'field',
|
426 |
+
'field_type' => $one_field_parent['type'],
|
427 |
+
);
|
428 |
+
}
|
429 |
+
|
430 |
+
if ( ! empty( $arr_field_path ) ) {
|
431 |
+
$path_loop_num = 0;
|
432 |
+
foreach ( $arr_field_path as $one_field_path ) {
|
433 |
+
$context[ "{$context_key}/path_{$path_loop_num}/name" ] = $one_field_path['name'];
|
434 |
+
$context[ "{$context_key}/path_{$path_loop_num}/type" ] = $one_field_path['type'];
|
435 |
+
if ( ! empty( $one_field_path['field_type'] ) ) {
|
436 |
+
$context[ "{$context_key}/path_{$path_loop_num}/field_type" ] = $one_field_path['field_type'];
|
437 |
+
}
|
438 |
+
$path_loop_num++;
|
439 |
+
}
|
440 |
+
}
|
441 |
+
|
442 |
+
// Add value of fields if they are not part of
|
443 |
+
// repeatable or flexible fields or similar.
|
444 |
+
// error_log( "Final parents" . print_r( $field_parents, 1 ) );
|
445 |
+
// error_log( "Final field group" . print_r( $field_field_group['title'], 1 ) );
|
446 |
+
// error_log( "context" . print_r( $context, 1 ) );
|
447 |
+
} // End if().
|
448 |
+
} // End if().
|
449 |
+
|
450 |
+
$loopnum++;
|
451 |
+
} // End foreach().
|
452 |
+
|
453 |
+
// error_log( "---------------------------" );
|
454 |
+
// error_log( "field_path_string: $field_path_string");
|
455 |
+
// error_log( "context" . print_r( $context, 1 ) );
|
456 |
+
return $context;
|
457 |
+
}
|
458 |
+
|
459 |
+
/**
|
460 |
+
* Clean array and keep only ACF related things.
|
461 |
+
*
|
462 |
+
* Remove
|
463 |
+
* - underscore fields
|
464 |
+
* - fields with value field_*
|
465 |
+
*
|
466 |
+
* Keep
|
467 |
+
* - vals that are acf
|
468 |
+
*
|
469 |
+
* @param array $arr Array.
|
470 |
+
* @param array $all_fields Array fields.
|
471 |
+
*/
|
472 |
+
public function keep_only_acf_stuff_in_array( $arr, $all_fields ) {
|
473 |
+
$new_arr = array();
|
474 |
+
|
475 |
+
foreach ( $arr as $key => $val ) {
|
476 |
+
// Don't keep keys that begin with underscore "_".
|
477 |
+
if ( strpos( $key, '_' ) === 0 ) {
|
478 |
+
continue;
|
479 |
+
}
|
480 |
+
|
481 |
+
// Don't keep keys that begin with "field_".
|
482 |
+
if ( strpos( $val, 'field_' ) === 0 ) {
|
483 |
+
continue;
|
484 |
+
}
|
485 |
+
|
486 |
+
// Don't keep fields that does not have a corresponding _field value.
|
487 |
+
// Each key has both the name, for example 'color' and another
|
488 |
+
// key called '_color'. We check that the underscore version exists
|
489 |
+
// and contains 'field_'. After this check only ACF fields should exist
|
490 |
+
// in the array..
|
491 |
+
if ( ! isset( $all_fields[ "_{$key}" ] ) ) {
|
492 |
+
continue;
|
493 |
+
}
|
494 |
+
|
495 |
+
if ( strpos( $all_fields[ "_{$key}" ], 'field_' ) !== 0 ) {
|
496 |
+
continue;
|
497 |
+
}
|
498 |
+
|
499 |
+
$new_arr[ $key ] = $val;
|
500 |
+
}
|
501 |
+
|
502 |
+
return $new_arr;
|
503 |
+
}
|
504 |
+
|
505 |
+
/**
|
506 |
+
* Store prev post meta when post is saved.
|
507 |
+
* Stores data in $this->oldPostData.
|
508 |
+
*/
|
509 |
+
public function on_admin_action_editpost() {
|
510 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
511 |
+
$post_ID = isset( $_POST['post_ID'] ) ? (int) $_POST['post_ID'] : 0;
|
512 |
+
|
513 |
+
if ( ! $post_ID ) {
|
514 |
+
return;
|
515 |
+
}
|
516 |
+
|
517 |
+
$prev_post = get_post( $post_ID );
|
518 |
+
|
519 |
+
if ( is_wp_error( $prev_post ) ) {
|
520 |
+
return;
|
521 |
+
}
|
522 |
+
|
523 |
+
$post_meta = get_post_custom( $post_ID );
|
524 |
+
|
525 |
+
// Meta is array of arrays, get first value of each array value.
|
526 |
+
array_walk(
|
527 |
+
$post_meta,
|
528 |
+
function( &$value, $key ) {
|
529 |
+
$value = reset( $value );
|
530 |
+
}
|
531 |
+
);
|
532 |
+
|
533 |
+
$this->oldPostData['prev_post_meta'] = $post_meta;
|
534 |
+
}
|
535 |
+
|
536 |
+
/**
|
537 |
+
* Called from PostLogger and its diff table output using filter 'simple_history/post_logger/post_updated/diff_table_output'.
|
538 |
+
* Diff table is generated only for post type 'acf-field-group'.
|
539 |
+
*
|
540 |
+
* @param string $diff_table_output
|
541 |
+
* @param array $context
|
542 |
+
* @return string
|
543 |
+
*/
|
544 |
+
public function on_diff_table_output_field_group( $diff_table_output, $context ) {
|
545 |
+
$post_type = ! empty( $context['post_type'] ) ? $context['post_type'] : false;
|
546 |
+
|
547 |
+
// Bail if not ACF Field Group.
|
548 |
+
if ( $post_type !== 'acf-field-group' ) {
|
549 |
+
return $diff_table_output;
|
550 |
+
}
|
551 |
+
|
552 |
+
// Field group fields to check for and output if found
|
553 |
+
$arrKeys = array(
|
554 |
+
'instruction_placement' => array(
|
555 |
+
'name' => _x( 'Instruction placement', 'Logger: Plugin ACF', 'simple-history' ),
|
556 |
+
),
|
557 |
+
'label_placement' => array(
|
558 |
+
'name' => _x( 'Label placement', 'Logger: Plugin ACF', 'simple-history' ),
|
559 |
+
),
|
560 |
+
'description' => array(
|
561 |
+
'name' => _x( 'Description', 'Logger: Plugin ACF', 'simple-history' ),
|
562 |
+
),
|
563 |
+
'menu_order' => array(
|
564 |
+
'name' => _x( 'Menu order', 'Logger: Plugin ACF', 'simple-history' ),
|
565 |
+
),
|
566 |
+
'position' => array(
|
567 |
+
'name' => _x( 'Position', 'Logger: Plugin ACF', 'simple-history' ),
|
568 |
+
),
|
569 |
+
'active' => array(
|
570 |
+
'name' => _x( 'Active', 'Logger: Plugin ACF', 'simple-history' ),
|
571 |
+
),
|
572 |
+
'style' => array(
|
573 |
+
'name' => _x( 'Style', 'Logger: Plugin ACF', 'simple-history' ),
|
574 |
+
),
|
575 |
+
);
|
576 |
+
|
577 |
+
foreach ( $arrKeys as $acfKey => $acfVals ) {
|
578 |
+
if ( isset( $context[ "acf_new_$acfKey" ] ) && isset( $context[ "acf_prev_$acfKey" ] ) ) {
|
579 |
+
$diff_table_output .= sprintf(
|
580 |
+
'<tr>
|
|
|
|
|
|
|
581 |
<td>%1$s</td>
|
582 |
<td>
|
583 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
584 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
585 |
</td>
|
586 |
</tr>',
|
587 |
+
$acfVals['name'],
|
588 |
+
esc_html( $context[ "acf_new_$acfKey" ] ),
|
589 |
+
esc_html( $context[ "acf_prev_$acfKey" ] )
|
590 |
+
);
|
591 |
+
}
|
592 |
+
}
|
593 |
+
|
594 |
+
// If only acf_hide_on_screen_removed exists nothing is outputed.
|
595 |
+
$acf_hide_on_screen_added = empty( $context['acf_hide_on_screen_added'] ) ? null : $context['acf_hide_on_screen_added'];
|
596 |
+
$acf_hide_on_screen_removed = empty( $context['acf_hide_on_screen_removed'] ) ? null : $context['acf_hide_on_screen_removed'];
|
597 |
+
|
598 |
+
if ( $acf_hide_on_screen_added || $acf_hide_on_screen_removed ) {
|
599 |
+
$strCheckedHideOnScreen = '';
|
600 |
+
$strUncheckedHideOnScreen = '';
|
601 |
+
|
602 |
+
if ( $acf_hide_on_screen_added ) {
|
603 |
+
$strCheckedHideOnScreen = sprintf(
|
604 |
+
'%1$s %2$s',
|
605 |
+
_x( 'Checked', 'Logger: Plugin ACF', 'simple-history' ), // 1
|
606 |
+
esc_html( $acf_hide_on_screen_added ) // 2
|
607 |
+
);
|
608 |
+
}
|
609 |
+
|
610 |
+
if ( $acf_hide_on_screen_removed ) {
|
611 |
+
$strUncheckedHideOnScreen = sprintf(
|
612 |
+
'%1$s %2$s',
|
613 |
+
_x( 'Unchecked', 'Logger: Plugin ACF', 'simple-history' ), // 1
|
614 |
+
esc_html( $acf_hide_on_screen_removed ) // 2
|
615 |
+
);
|
616 |
+
}
|
617 |
+
|
618 |
+
$diff_table_output .= sprintf(
|
619 |
+
'<tr>
|
620 |
<td>%1$s</td>
|
621 |
<td>
|
622 |
%2$s
|
623 |
%3$s
|
624 |
</td>
|
625 |
</tr>',
|
626 |
+
_x( 'Hide on screen', 'Logger: Plugin ACF', 'simple-history' ), // 1
|
627 |
+
$strCheckedHideOnScreen, // 2
|
628 |
+
$strUncheckedHideOnScreen // 3
|
629 |
+
);
|
630 |
+
}
|
631 |
+
|
632 |
+
// Check for deleted fields.
|
633 |
+
if ( isset( $context['acf_deleted_fields_0_key'] ) ) {
|
634 |
+
// 1 or more deleted fields exist in context.
|
635 |
+
$loopnum = 0;
|
636 |
+
$strDeletedFields = '';
|
637 |
+
|
638 |
+
while ( isset( $context[ "acf_deleted_fields_{$loopnum}_key" ] ) ) {
|
639 |
+
$strDeletedFields .= sprintf(
|
640 |
+
'%1$s (%3$s), ',
|
641 |
+
esc_html( $context[ "acf_deleted_fields_{$loopnum}_label" ] ),
|
642 |
+
esc_html( $context[ "acf_deleted_fields_{$loopnum}_name" ] ),
|
643 |
+
esc_html( $context[ "acf_deleted_fields_{$loopnum}_type" ] )
|
644 |
+
);
|
645 |
+
|
646 |
+
$loopnum++;
|
647 |
+
}
|
648 |
+
|
649 |
+
$strDeletedFields = trim( $strDeletedFields, ', ' );
|
650 |
+
|
651 |
+
$diff_table_output .= sprintf(
|
652 |
+
'<tr>
|
653 |
<td>%1$s</td>
|
654 |
<td>%2$s</td>
|
655 |
</tr>',
|
656 |
+
_nx( 'Deleted field', 'Deleted fields', $loopnum, 'Logger: Plugin ACF', 'simple-history' ), // 1
|
657 |
+
$strDeletedFields
|
658 |
+
);
|
659 |
+
} // if deleted fields
|
660 |
+
|
661 |
+
// Check for added fields
|
662 |
+
if ( isset( $context['acf_added_fields_0_key'] ) ) {
|
663 |
+
// 1 or more deleted fields exist in context
|
664 |
+
$loopnum = 0;
|
665 |
+
$strAddedFields = '';
|
666 |
+
|
667 |
+
while ( isset( $context[ "acf_added_fields_{$loopnum}_key" ] ) ) {
|
668 |
+
$strAddedFields .= sprintf(
|
669 |
+
'%1$s (%3$s), ',
|
670 |
+
esc_html( $context[ "acf_added_fields_{$loopnum}_label" ] ), // 1
|
671 |
+
esc_html( $context[ "acf_added_fields_{$loopnum}_name" ] ), // 2
|
672 |
+
esc_html( $context[ "acf_added_fields_{$loopnum}_type" ] ) // 3
|
673 |
+
);
|
674 |
+
|
675 |
+
$loopnum++;
|
676 |
+
}
|
677 |
+
|
678 |
+
$strAddedFields = trim( $strAddedFields, ', ' );
|
679 |
+
|
680 |
+
$diff_table_output .= sprintf(
|
681 |
+
'<tr>
|
682 |
<td>%1$s</td>
|
683 |
<td>%2$s</td>
|
684 |
</tr>',
|
685 |
+
_nx( 'Added field', 'Added fields', $loopnum, 'Logger: Plugin ACF', 'simple-history' ), // 1
|
686 |
+
$strAddedFields
|
687 |
+
);
|
688 |
+
} // if deleted fields
|
689 |
+
|
690 |
+
// Check for modified fields
|
691 |
+
if ( isset( $context['acf_modified_fields_0_ID_prev'] ) ) {
|
692 |
+
// 1 or more modifiedfields exist in context
|
693 |
+
$loopnum = 0;
|
694 |
+
$strModifiedFields = '';
|
695 |
+
$arrAddedFieldsKeysToCheck = array(
|
696 |
+
'name' => array(
|
697 |
+
'name' => _x( 'Name: ', 'Logger: Plugin ACF', 'simple-history' ),
|
698 |
+
),
|
699 |
+
'parent' => array(
|
700 |
+
'name' => _x( 'Parent: ', 'Logger: Plugin ACF', 'simple-history' ),
|
701 |
+
),
|
702 |
+
'key' => array(
|
703 |
+
'name' => _x( 'Key: ', 'Logger: Plugin ACF', 'simple-history' ),
|
704 |
+
),
|
705 |
+
'label' => array(
|
706 |
+
'name' => _x( 'Label: ', 'Logger: Plugin ACF', 'simple-history' ),
|
707 |
+
),
|
708 |
+
'type' => array(
|
709 |
+
'name' => _x( 'Type: ', 'Logger: Plugin ACF', 'simple-history' ),
|
710 |
+
),
|
711 |
+
);
|
712 |
+
|
713 |
+
while ( isset( $context[ "acf_modified_fields_{$loopnum}_name_prev" ] ) ) {
|
714 |
+
// One modified field, with one or more changed things
|
715 |
+
$strOneModifiedField = '';
|
716 |
+
|
717 |
+
// Add the field name manually, if it is not among the changed field,
|
718 |
+
// or we don't know what field the other changed values belongs to.
|
719 |
+
/*
|
720 |
+
if (empty($context["acf_modified_fields_{$loopnum}_name_new"])) {
|
721 |
+
$strOneModifiedField .= sprintf(
|
722 |
+
_x('Name: %1$s', 'Logger: Plugin ACF', 'simple-history'), // 1
|
723 |
+
esc_html($context["acf_modified_fields_{$loopnum}_name_prev"]) // 2
|
724 |
+
);
|
725 |
+
}
|
726 |
+
*/
|
727 |
+
|
728 |
+
// Add the label name manually, if it is not among the changed field,
|
729 |
+
// or we don't know what field the other changed values belongs to.
|
730 |
+
if ( empty( $context[ "acf_modified_fields_{$loopnum}_label_new" ] ) ) {
|
731 |
+
$strOneModifiedField .= sprintf(
|
732 |
+
_x( 'Label: %1$s', 'Logger: Plugin ACF', 'simple-history' ), // 1
|
733 |
+
esc_html( $context[ "acf_modified_fields_{$loopnum}_label_prev" ] ) // 2
|
734 |
+
);
|
735 |
+
}
|
736 |
+
|
737 |
+
// Check for other keys changed for this field
|
738 |
+
foreach ( $arrAddedFieldsKeysToCheck as $oneAddedFieldKeyToCheck => $oneAddedFieldKeyToCheckVals ) {
|
739 |
+
$newAndOldValsExists = isset( $context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_new" ] ) && isset( $context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_new" ] );
|
740 |
+
if ( $newAndOldValsExists ) {
|
741 |
+
$strOneModifiedField .= sprintf(
|
742 |
+
'
|
743 |
%4$s
|
744 |
%3$s
|
745 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%1$s</ins>
|
746 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%2$s</del>
|
747 |
',
|
748 |
+
esc_html( $context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_new" ] ), // 1
|
749 |
+
esc_html( $context[ "acf_modified_fields_{$loopnum}_{$oneAddedFieldKeyToCheck}_prev" ] ), // 2
|
750 |
+
esc_html( $oneAddedFieldKeyToCheckVals['name'] ), // 3
|
751 |
+
empty( $strOneModifiedField ) ? '' : '<br>' // 4 new line
|
752 |
+
);
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
$strOneModifiedField = trim( $strOneModifiedField, ", \n\r\t" );
|
757 |
+
|
758 |
+
if ( $strOneModifiedField ) {
|
759 |
+
$strModifiedFields .= sprintf(
|
760 |
+
'<tr>
|
761 |
<td>%1$s</td>
|
762 |
<td>%2$s</td>
|
763 |
</tr>',
|
764 |
+
_x( 'Modified field', 'Logger: Plugin ACF', 'simple-history' ), // 1
|
765 |
+
$strOneModifiedField
|
766 |
+
);
|
767 |
+
}
|
768 |
+
|
769 |
+
$loopnum++;
|
770 |
+
}
|
771 |
+
|
772 |
+
/*
|
773 |
+
if ($strModifiedFields) {
|
774 |
+
$strModifiedFields = sprintf(
|
775 |
+
'<tr>
|
776 |
+
<td>%1$s</td>
|
777 |
+
<td>%2$s</td>
|
778 |
+
</tr>',
|
779 |
+
_nx('Modified field', 'Modified fields', $loopnum, 'Logger: Plugin ACF', 'simple-history'), // 1
|
780 |
+
$strModifiedFields
|
781 |
+
) . $strModifiedFields;
|
782 |
+
}*/
|
783 |
+
|
784 |
+
$diff_table_output .= $strModifiedFields;
|
785 |
+
} // if deleted fields
|
786 |
+
|
787 |
+
return $diff_table_output;
|
788 |
+
}
|
789 |
+
|
790 |
+
/**
|
791 |
+
* Append ACF data to post context.
|
792 |
+
*
|
793 |
+
* Called via filter `simple_history/post_logger/post_updated/context`.
|
794 |
+
*
|
795 |
+
* @param array $context
|
796 |
+
* @param WP_Post $post
|
797 |
+
*/
|
798 |
+
public function on_post_updated_context( $context, $post ) {
|
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 |
+
if ( $old_value != $new_value ) {
|
947 |
+
$post_data_diff[ $key ] = array(
|
948 |
+
'old' => $old_value,
|
949 |
+
'new' => $new_value,
|
950 |
+
);
|
951 |
+
}
|
952 |
+
|
953 |
+
return $post_data_diff;
|
954 |
+
}
|
955 |
+
|
956 |
+
/**
|
957 |
+
* Store a version of the field group as it was before the save
|
958 |
+
* Called before field group post/values is added to db
|
959 |
+
*
|
960 |
+
* @param array $data Post data.
|
961 |
+
* @param array $postarr Post data.
|
962 |
+
*/
|
963 |
+
public function on_wp_insert_post_data( $data, $postarr ) {
|
964 |
+
|
965 |
+
// Only do this if ACF field group is being saved.
|
966 |
+
if ( $postarr['post_type'] !== 'acf-field-group' ) {
|
967 |
+
return $data;
|
968 |
+
}
|
969 |
+
|
970 |
+
if ( empty( $postarr['ID'] ) ) {
|
971 |
+
return $data;
|
972 |
+
}
|
973 |
+
|
974 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
975 |
+
if ( empty( $_POST['acf_field_group'] ) ) {
|
976 |
+
return $data;
|
977 |
+
}
|
978 |
+
|
979 |
+
$this->oldAndNewFieldGroupsAndFields['fieldGroup']['old'] = acf_get_field_group( $postarr['ID'] );
|
980 |
+
|
981 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
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 |
+
static $isCalled = false;
|
994 |
+
|
995 |
+
if ( $isCalled ) {
|
996 |
+
return;
|
997 |
+
}
|
998 |
+
|
999 |
+
$isCalled = true;
|
1000 |
+
|
1001 |
+
$post_id = $post->ID;
|
1002 |
+
|
1003 |
+
// do not act if this is an auto save routine
|
1004 |
+
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
1005 |
+
return;
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
// bail early if not acf-field-group
|
1009 |
+
if ( $post->post_type !== 'acf-field-group' ) {
|
1010 |
+
return;
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
// only save once! WordPress save's a revision as well.
|
1014 |
+
if ( wp_is_post_revision( $post_id ) ) {
|
1015 |
+
return;
|
1016 |
+
}
|
1017 |
+
|
1018 |
+
// Store info about fields that are going to be deleted
|
1019 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
1020 |
+
if ( ! empty( $_POST['_acf_delete_fields'] ) ) {
|
1021 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
1022 |
+
$deletedFieldsIDs = explode( '|', (string) $_POST['_acf_delete_fields'] );
|
1023 |
+
$deletedFieldsIDs = array_map( 'intval', $deletedFieldsIDs );
|
1024 |
+
|
1025 |
+
foreach ( $deletedFieldsIDs as $id ) {
|
1026 |
+
if ( ! $id ) {
|
1027 |
+
continue;
|
1028 |
+
}
|
1029 |
+
|
1030 |
+
$field_info = acf_get_field( $id );
|
1031 |
+
|
1032 |
+
if ( ! $field_info ) {
|
1033 |
+
continue;
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
$this->oldAndNewFieldGroupsAndFields['deletedFields'][ $id ] = $field_info;
|
1037 |
+
}
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
// Store info about added or modified fields
|
1041 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
1042 |
+
if ( ! empty( $_POST['acf_fields'] ) && is_array( $_POST['acf_fields'] ) ) {
|
1043 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
1044 |
+
foreach ( $_POST['acf_fields'] as $oneFieldAddedOrUpdated ) {
|
1045 |
+
if ( empty( $oneFieldAddedOrUpdated['ID'] ) ) {
|
1046 |
+
// New fields have no id
|
1047 |
+
// 'ID' => string(0) ""
|
1048 |
+
$this->oldAndNewFieldGroupsAndFields['addedFields'][] = $oneFieldAddedOrUpdated;
|
1049 |
+
} else {
|
1050 |
+
// Existing fields have an id
|
1051 |
+
// 'ID' => string(3) "383"
|
1052 |
+
$this->oldAndNewFieldGroupsAndFields['modifiedFields']['old'][ $oneFieldAddedOrUpdated['ID'] ] = acf_get_field( $oneFieldAddedOrUpdated['ID'] );
|
1053 |
+
|
1054 |
+
$this->oldAndNewFieldGroupsAndFields['modifiedFields']['new'][ $oneFieldAddedOrUpdated['ID'] ] = $oneFieldAddedOrUpdated;
|
1055 |
+
}
|
1056 |
+
}
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
// We don't do anything else here, but we make the actual logging
|
1060 |
+
// in filter 'acf/update_field_group' beacuse it's safer because
|
1061 |
+
// ACF has done it's validation and it's after ACF has saved the fields,
|
1062 |
+
// so less likely that we make some critical error
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
|
1066 |
+
/**
|
1067 |
+
* Add the post types that ACF uses for fields to the array of post types
|
1068 |
+
* that the default post logger should not log. If not each field will cause one
|
1069 |
+
* post update log message.
|
1070 |
+
*/
|
1071 |
+
public function remove_acf_from_postlogger( $skip_posttypes ) {
|
1072 |
+
array_push(
|
1073 |
+
$skip_posttypes,
|
1074 |
+
'acf-field'
|
1075 |
+
);
|
1076 |
+
|
1077 |
+
return $skip_posttypes;
|
1078 |
+
}
|
1079 |
+
}
|
1080 |
} // End if().
|
loggers/Plugin_BeaverBuilder.php
CHANGED
@@ -1,115 +1,112 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Logger for Beaver Builder
|
7 |
*/
|
8 |
-
if (!class_exists('Plugin_BeaverBuilder')) {
|
9 |
// phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
|
10 |
-
|
11 |
-
{
|
12 |
-
public $slug = __CLASS__;
|
13 |
|
14 |
-
|
15 |
-
{
|
16 |
-
$arr_info = array(
|
17 |
-
'name' => 'Plugin Beaver Builder',
|
18 |
-
'description' => _x(
|
19 |
-
'Logs various things in Beaver Builder',
|
20 |
-
'Logger: Plugin Beaver Builder',
|
21 |
-
'simple-history'
|
22 |
-
),
|
23 |
-
'name_via' => _x(
|
24 |
-
'Using plugin Beaver Builder',
|
25 |
-
'Logger: Plugin Beaver Builder',
|
26 |
-
'simple-history'
|
27 |
-
),
|
28 |
-
'capability' => 'manage_options',
|
29 |
-
'messages' => array(
|
30 |
-
'layout_saved' => __(
|
31 |
-
'Layout "{layout_name}" updated',
|
32 |
-
'simple-history'
|
33 |
-
),
|
34 |
-
'template_saved' => __(
|
35 |
-
'Template "{layout_name}" updated',
|
36 |
-
'simple-history'
|
37 |
-
),
|
38 |
-
'draft_saved' => __(
|
39 |
-
'Draft "{layout_name}" updated',
|
40 |
-
'simple-history'
|
41 |
-
),
|
42 |
-
'admin_saved' => __(
|
43 |
-
'Beaver Builder settings saved',
|
44 |
-
'simple-history'
|
45 |
-
)
|
46 |
-
)
|
47 |
-
);
|
48 |
|
49 |
-
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
-
|
53 |
-
|
54 |
-
if (!class_exists('FLBuilder')) {
|
55 |
-
return;
|
56 |
-
}
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
4
|
63 |
-
);
|
64 |
-
add_action(
|
65 |
-
'fl_builder_after_save_user_template',
|
66 |
-
array($this, 'saveTemplate'),
|
67 |
-
10,
|
68 |
-
1
|
69 |
-
);
|
70 |
-
add_action(
|
71 |
-
'fl_builder_after_save_draft',
|
72 |
-
array($this, 'saveDraft'),
|
73 |
-
10,
|
74 |
-
2
|
75 |
-
);
|
76 |
-
add_action('fl_builder_admin_settings_save', array(
|
77 |
-
$this,
|
78 |
-
'saveAdmin'
|
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 |
-
if ($publish) {
|
106 |
-
$this->noticeMessage('layout_saved', $context);
|
107 |
-
}
|
108 |
-
}
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Logger for Beaver Builder
|
7 |
*/
|
8 |
+
if ( ! class_exists( 'Plugin_BeaverBuilder' ) ) {
|
9 |
// phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
|
10 |
+
class Plugin_BeaverBuilder extends SimpleLogger {
|
|
|
|
|
11 |
|
12 |
+
public $slug = __CLASS__;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
+
public function getInfo() {
|
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 |
+
public function loaded() {
|
52 |
+
if ( ! class_exists( 'FLBuilder' ) ) {
|
53 |
+
return;
|
54 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
+
add_action(
|
57 |
+
'fl_builder_after_save_layout',
|
58 |
+
array( $this, 'saveLayout' ),
|
59 |
+
10,
|
60 |
+
4
|
61 |
+
);
|
62 |
+
add_action(
|
63 |
+
'fl_builder_after_save_user_template',
|
64 |
+
array( $this, 'saveTemplate' ),
|
65 |
+
10,
|
66 |
+
1
|
67 |
+
);
|
68 |
+
add_action(
|
69 |
+
'fl_builder_after_save_draft',
|
70 |
+
array( $this, 'saveDraft' ),
|
71 |
+
10,
|
72 |
+
2
|
73 |
+
);
|
74 |
+
add_action(
|
75 |
+
'fl_builder_admin_settings_save',
|
76 |
+
array(
|
77 |
+
$this,
|
78 |
+
'saveAdmin',
|
79 |
+
)
|
80 |
+
);
|
81 |
+
}
|
82 |
|
83 |
+
public function saveTemplate( $post_id ) {
|
84 |
+
$post = get_post( $post_id );
|
85 |
+
$context = array(
|
86 |
+
'layout_name' => $post->post_name,
|
87 |
+
);
|
88 |
+
$this->noticeMessage( 'template_saved', $context );
|
89 |
+
}
|
90 |
|
91 |
+
public function saveDraft( $post_id, $publish ) {
|
92 |
+
$context = array(
|
93 |
+
'layout_name' => $post_id,
|
94 |
+
);
|
95 |
+
$this->noticeMessage( 'draft_saved', $context );
|
96 |
+
}
|
|
|
|
|
|
|
|
|
97 |
|
98 |
+
public function saveLayout( $post_id, $publish, $data, $settings ) {
|
99 |
+
$post = get_post( $post_id );
|
100 |
+
$context = array(
|
101 |
+
'layout_name' => $post->post_name,
|
102 |
+
);
|
103 |
+
if ( $publish ) {
|
104 |
+
$this->noticeMessage( 'layout_saved', $context );
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
public function saveAdmin() {
|
109 |
+
$this->noticeMessage( 'admin_saved' );
|
110 |
+
}
|
111 |
+
}
|
112 |
} // End if().
|
loggers/Plugin_DuplicatePost.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* Logger for the Duplicate Post plugin
|
@@ -9,145 +9,141 @@ defined('ABSPATH') or die();
|
|
9 |
* @package SimpleHistory
|
10 |
* @since 2.13
|
11 |
*/
|
12 |
-
if (!class_exists('Plugin_DuplicatePost')) {
|
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 |
-
return $this->interpolate($message, $context, $row);
|
151 |
-
}
|
152 |
-
}
|
153 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
class Plugin_DuplicatePost extends SimpleLogger {
|
14 |
+
|
15 |
+
public $slug = __CLASS__;
|
16 |
+
|
17 |
+
public function getInfo() {
|
18 |
+
$arr_info = array(
|
19 |
+
'name' => 'Plugin Duplicate Posts',
|
20 |
+
'description' => _x(
|
21 |
+
'Logs posts and pages cloned using plugin Duplicate Post',
|
22 |
+
'Logger: Plugin Duplicate Post',
|
23 |
+
'simple-history'
|
24 |
+
),
|
25 |
+
'name_via' => _x( 'Using plugin Duplicate Posts', 'Logger: Plugin Duplicate Post', 'simple-history' ),
|
26 |
+
'capability' => 'manage_options',
|
27 |
+
'messages' => array(
|
28 |
+
'post_duplicated' => _x(
|
29 |
+
'Cloned "{duplicated_post_title}" to a new post',
|
30 |
+
'Logger: Plugin Duplicate Post',
|
31 |
+
'simple-history'
|
32 |
+
),
|
33 |
+
),
|
34 |
+
);
|
35 |
+
|
36 |
+
return $arr_info;
|
37 |
+
}
|
38 |
+
|
39 |
+
public function loaded() {
|
40 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
41 |
+
|
42 |
+
$isPluginActive = is_plugin_active( 'duplicate-post/duplicate-post.php' );
|
43 |
+
|
44 |
+
if ( ! $isPluginActive ) {
|
45 |
+
return;
|
46 |
+
}
|
47 |
+
|
48 |
+
// When a copy have been made of a post or page
|
49 |
+
// the action 'dp_duplicate_page' or 'dp_duplicate_post'
|
50 |
+
// is fired with args $new_post_id, $post, $status.
|
51 |
+
// We add actions with prio 20 so we probably run after
|
52 |
+
// the plugins own
|
53 |
+
add_action( 'dp_duplicate_post', array( $this, 'onDpDuplicatePost' ), 100, 3 );
|
54 |
+
add_action( 'dp_duplicate_page', array( $this, 'onDpDuplicatePost' ), 100, 3 );
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* A post or page was duplicated
|
59 |
+
*
|
60 |
+
* @param $new_post_id
|
61 |
+
* @param $post old post that a copy was made of
|
62 |
+
* @param $status
|
63 |
+
*/
|
64 |
+
public function onDpDuplicatePost( $newPostID, $post, $status ) {
|
65 |
+
$new_post = get_post( $newPostID );
|
66 |
+
|
67 |
+
$context = array(
|
68 |
+
'new_post_title' => $new_post->post_title,
|
69 |
+
'new_post_id' => $new_post->ID,
|
70 |
+
'duplicated_post_title' => $post->post_title,
|
71 |
+
'duplicated_post_id' => $post->ID,
|
72 |
+
// "duplicate_new_post_id" => $newPostID,
|
73 |
+
// "status" => $status
|
74 |
+
);
|
75 |
+
|
76 |
+
$this->infoMessage( 'post_duplicated', $context );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Modify plain output to include link to post
|
81 |
+
*/
|
82 |
+
public function getLogRowPlainTextOutput( $row ) {
|
83 |
+
$context = $row->context;
|
84 |
+
$new_post_id = isset( $context['new_post_id'] ) ? $context['new_post_id'] : null;
|
85 |
+
$duplicated_post_id = isset( $context['duplicated_post_id'] ) ? $context['duplicated_post_id'] : null;
|
86 |
+
$duplicated_post_title = isset( $context['duplicated_post_title'] )
|
87 |
+
? $context['duplicated_post_title']
|
88 |
+
: null;
|
89 |
+
$message_key = isset( $context['_message_key'] ) ? $context['_message_key'] : null;
|
90 |
+
|
91 |
+
$message = $row->message;
|
92 |
+
|
93 |
+
// Check if post still is available
|
94 |
+
// It will return a WP_Post Object if post still is in system
|
95 |
+
// If post is deleted from trash (not just moved there), then null is returned
|
96 |
+
$postDuplicated = get_post( $duplicated_post_id );
|
97 |
+
$post_is_available = is_a( $postDuplicated, 'WP_Post' );
|
98 |
+
|
99 |
+
// Try to get singular name
|
100 |
+
$post_type = isset( $postDuplicated->post_type ) ? $postDuplicated->post_type : '';
|
101 |
+
$post_type_obj = get_post_type_object( $post_type );
|
102 |
+
|
103 |
+
if ( ! is_null( $post_type_obj ) ) {
|
104 |
+
if ( ! empty( $post_type_obj->labels->singular_name ) ) {
|
105 |
+
$context['duplicated_post_post_type_singular_name'] = strtolower(
|
106 |
+
$post_type_obj->labels->singular_name
|
107 |
+
);
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
$context['duplicated_post_edit_link'] = get_edit_post_link( $duplicated_post_id );
|
112 |
+
$context['new_post_edit_link'] = get_edit_post_link( $new_post_id );
|
113 |
+
|
114 |
+
// If post is not available any longer then we can't link to it, so keep plain message then
|
115 |
+
// Also keep plain format if user is not allowed to edit post (edit link is empty)
|
116 |
+
if ( $post_is_available && $context['duplicated_post_edit_link'] ) {
|
117 |
+
$message = _x(
|
118 |
+
'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>',
|
119 |
+
'Logger: Plugin Duplicate Post',
|
120 |
+
'simple-history'
|
121 |
+
);
|
122 |
+
}
|
123 |
+
|
124 |
+
$context['new_post_edit_link'] = isset( $context['new_post_edit_link'] )
|
125 |
+
? esc_html( $context['new_post_edit_link'] )
|
126 |
+
: '';
|
127 |
+
|
128 |
+
$context['duplicated_post_edit_link'] = isset( $context['duplicated_post_edit_link'] )
|
129 |
+
? esc_html( $context['duplicated_post_edit_link'] )
|
130 |
+
: '';
|
131 |
+
|
132 |
+
$context['duplicated_post_title'] = isset( $context['duplicated_post_title'] )
|
133 |
+
? esc_html( $context['duplicated_post_title'] )
|
134 |
+
: '';
|
135 |
+
|
136 |
+
$context['duplicated_post_title'] = isset( $context['duplicated_post_title'] )
|
137 |
+
? esc_html( $context['duplicated_post_title'] )
|
138 |
+
: '';
|
139 |
+
|
140 |
+
$context['duplicated_post_post_type_singular_name'] = isset(
|
141 |
+
$context['duplicated_post_post_type_singular_name']
|
142 |
+
)
|
143 |
+
? esc_html( $context['duplicated_post_post_type_singular_name'] )
|
144 |
+
: '';
|
145 |
+
|
146 |
+
return $this->interpolate( $message, $context, $row );
|
147 |
+
}
|
148 |
+
}
|
|
|
|
|
|
|
|
|
149 |
} // End if().
|
loggers/Plugin_LimitLoginAttempts.php
CHANGED
@@ -1,231 +1,228 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
-
|
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 |
-
return $output;
|
229 |
-
}
|
230 |
-
}
|
231 |
} // End if().
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
class Plugin_LimitLoginAttempts extends SimpleLogger {
|
11 |
+
|
12 |
+
|
13 |
+
public $slug = __CLASS__;
|
14 |
+
|
15 |
+
public function getInfo() {
|
16 |
+
|
17 |
+
$arr_info = array(
|
18 |
+
'name' => 'Plugin Limit Login Attempts',
|
19 |
+
'description' => _x( 'Logs failed login attempts, lockouts, and configuration changes made in the plugin Limit Login Attempts', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
20 |
+
'name_via' => _x( 'Using plugin Limit Login Attempts', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
21 |
+
'capability' => 'manage_options',
|
22 |
+
'messages' => array(
|
23 |
+
// 'user_locked_out' => _x( 'User locked out', "Logger: Plugin Limit Login Attempts", "simple-history" ),
|
24 |
+
'failed_login_whitelisted' => _x( 'Failed login attempt from whitelisted IP', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
25 |
+
'failed_login' => _x( 'Was locked out because too many failed login attempts', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
26 |
+
'cleared_ip_log' => _x( 'Cleared IP log', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
27 |
+
'reseted_lockout_count' => _x( 'Reseted lockout count', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
28 |
+
'cleared_current_lockouts' => _x( 'Cleared current lockouts', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
29 |
+
'updated_options' => _x( 'Updated options', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
30 |
+
),
|
31 |
+
/*
|
32 |
+
"labels" => array(
|
33 |
+
"search" => array(
|
34 |
+
"label" => _x( "Limit Login Attempts", "Logger: Plugin Limit Login Attempts", "simple-history" ),
|
35 |
+
"options" => array(
|
36 |
+
_x( "xxxPages not found", "User logger: 404", "simple-history" ) => array(
|
37 |
+
"page_not_found",
|
38 |
+
),
|
39 |
+
),
|
40 |
+
), // end search
|
41 |
+
),*/ // end labels
|
42 |
+
);
|
43 |
+
|
44 |
+
return $arr_info;
|
45 |
+
}
|
46 |
+
|
47 |
+
public function loaded() {
|
48 |
+
|
49 |
+
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
50 |
+
|
51 |
+
$pluginFilePath = 'limit-login-attempts/limit-login-attempts.php';
|
52 |
+
$isPluginActive = is_plugin_active( $pluginFilePath );
|
53 |
+
|
54 |
+
// Only continue to add filters if plugin is active.
|
55 |
+
// This minimise the risk of plugin errors, because plugin
|
56 |
+
// has been forked to new versions.
|
57 |
+
if ( ! $isPluginActive ) {
|
58 |
+
return;
|
59 |
+
}
|
60 |
+
|
61 |
+
add_filter( 'pre_option_limit_login_lockouts_total', array( $this, 'on_option_limit_login_lockouts_total' ), 10, 1 );
|
62 |
+
|
63 |
+
add_action( 'load-settings_page_limit-login-attempts', array( $this, 'on_load_settings_page' ), 10, 1 );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Fired when plugin options screen is loaded
|
68 |
+
*/
|
69 |
+
public function on_load_settings_page( $a ) {
|
70 |
+
|
71 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
72 |
+
if ( $_POST && wp_verify_nonce( $_POST['_wpnonce'], 'limit-login-attempts-options' ) ) {
|
73 |
+
// Settings saved
|
74 |
+
if ( isset( $_POST['clear_log'] ) ) {
|
75 |
+
$this->noticeMessage( 'cleared_ip_log' );
|
76 |
+
}
|
77 |
+
|
78 |
+
if ( isset( $_POST['reset_total'] ) ) {
|
79 |
+
$this->noticeMessage( 'reseted_lockout_count' );
|
80 |
+
}
|
81 |
+
|
82 |
+
if ( isset( $_POST['reset_current'] ) ) {
|
83 |
+
$this->noticeMessage( 'cleared_current_lockouts' );
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( isset( $_POST['update_options'] ) ) {
|
87 |
+
$options = array(
|
88 |
+
'client_type' => sanitize_text_field( $_POST['client_type'] ),
|
89 |
+
'allowed_retries' => sanitize_text_field( $_POST['allowed_retries'] ),
|
90 |
+
'lockout_duration' => sanitize_text_field( $_POST['lockout_duration'] ) * 60,
|
91 |
+
'valid_duration' => sanitize_text_field( $_POST['valid_duration'] ) * 3600,
|
92 |
+
'allowed_lockouts' => sanitize_text_field( $_POST['allowed_lockouts'] ),
|
93 |
+
'long_duration' => sanitize_text_field( $_POST['long_duration'] ) * 3600,
|
94 |
+
'email_after' => sanitize_text_field( $_POST['email_after'] ),
|
95 |
+
'cookies' => ( isset( $_POST['cookies'] ) && $_POST['cookies'] == '1' ) ? 'yes' : 'no',
|
96 |
+
);
|
97 |
+
|
98 |
+
$v = array();
|
99 |
+
if ( isset( $_POST['lockout_notify_log'] ) ) {
|
100 |
+
$v[] = 'log';
|
101 |
+
}
|
102 |
+
if ( isset( $_POST['lockout_notify_email'] ) ) {
|
103 |
+
$v[] = 'email';
|
104 |
+
}
|
105 |
+
$lockout_notify = implode( ',', $v );
|
106 |
+
$options['lockout_notify'] = $lockout_notify;
|
107 |
+
|
108 |
+
$this->noticeMessage(
|
109 |
+
'updated_options',
|
110 |
+
array(
|
111 |
+
'options' => $options,
|
112 |
+
)
|
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 |
+
public function on_option_limit_login_lockouts_total( $value ) {
|
124 |
+
|
125 |
+
global $limit_login_just_lockedout;
|
126 |
+
|
127 |
+
if ( ! $limit_login_just_lockedout ) {
|
128 |
+
return $value;
|
129 |
+
}
|
130 |
+
|
131 |
+
$ip = limit_login_get_address();
|
132 |
+
$whitelisted = is_limit_login_ip_whitelisted( $ip );
|
133 |
+
|
134 |
+
$retries = get_option( 'limit_login_retries' );
|
135 |
+
if ( ! is_array( $retries ) ) {
|
136 |
+
$retries = array();
|
137 |
+
}
|
138 |
+
|
139 |
+
/* Format message. First current lockout duration */
|
140 |
+
$lockout_type = '';
|
141 |
+
if ( ! isset( $retries[ $ip ] ) ) {
|
142 |
+
/* longer lockout */
|
143 |
+
$lockout_type = 'longer';
|
144 |
+
$count = limit_login_option( 'allowed_retries' ) * limit_login_option( 'allowed_lockouts' );
|
145 |
+
$lockouts = limit_login_option( 'allowed_lockouts' );
|
146 |
+
$time = round( limit_login_option( 'long_duration' ) / 3600 );
|
147 |
+
// $when = sprintf( _n( '%d hour', '%d hours', $time, "Logger: Plugin Limit Login Attempts", 'limit-login-attempts' ), $time );
|
148 |
+
} else {
|
149 |
+
/* normal lockout */
|
150 |
+
$lockout_type = 'normal';
|
151 |
+
$count = $retries[ $ip ];
|
152 |
+
$lockouts = floor( $count / limit_login_option( 'allowed_retries' ) );
|
153 |
+
$time = round( limit_login_option( 'lockout_duration' ) / 60 );
|
154 |
+
// $when = sprintf( _n( '%d minute', '%d minutes', $time, 'limit-login-attempts' ), $time );
|
155 |
+
}
|
156 |
+
|
157 |
+
if ( $whitelisted ) {
|
158 |
+
// $subject = __( "Failed login attempts from whitelisted IP", 'limit-login-attempts' );
|
159 |
+
$message_key = 'failed_login_whitelisted';
|
160 |
+
} else {
|
161 |
+
// $subject = __( "Too many failed login attempts", 'limit-login-attempts' );
|
162 |
+
$message_key = 'failed_login';
|
163 |
+
}
|
164 |
+
|
165 |
+
$this->noticeMessage(
|
166 |
+
$message_key,
|
167 |
+
array(
|
168 |
+
'_initiator' => SimpleLoggerLogInitiators::WEB_USER,
|
169 |
+
'value' => $value,
|
170 |
+
'limit_login_just_lockedout' => $limit_login_just_lockedout,
|
171 |
+
// "retries" => $retries,
|
172 |
+
// "whitelisted" => $whitelisted, // bool, true | false
|
173 |
+
// "subject" => $subject,
|
174 |
+
// "message" => $message,
|
175 |
+
'count' => $count, // num of failed login attempts before block
|
176 |
+
'time' => $time, // duration in minutes for block
|
177 |
+
'lockouts' => $lockouts,
|
178 |
+
'ip' => $ip,
|
179 |
+
'lockout_type' => $lockout_type,
|
180 |
+
)
|
181 |
+
);
|
182 |
+
|
183 |
+
return $value;
|
184 |
+
}
|
185 |
+
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Add some extra info
|
189 |
+
*/
|
190 |
+
public function getLogRowDetailsOutput( $row ) {
|
191 |
+
|
192 |
+
$output = '';
|
193 |
+
|
194 |
+
$context = isset( $row->context ) ? $row->context : array();
|
195 |
+
|
196 |
+
$message_key = $row->context_message_key;
|
197 |
+
|
198 |
+
if ( 'failed_login' == $message_key ) {
|
199 |
+
$count = $context['count'];
|
200 |
+
$lockouts = $context['lockouts'];
|
201 |
+
$ip = $context['ip'];
|
202 |
+
// $whitelisted = $context["whitelisted"];
|
203 |
+
$lockout_type = $context['lockout_type'];
|
204 |
+
$time = $context['time'];
|
205 |
+
|
206 |
+
$output .= sprintf(
|
207 |
+
'<p>' . _x( '%1$d failed login attempts (%2$d lockout(s)) from IP: %3$s', 'Logger: Plugin Limit Login Attempts', 'simple-history' ) . '</p>',
|
208 |
+
$count, // 1
|
209 |
+
$lockouts, // 2
|
210 |
+
$ip // 3
|
211 |
+
);
|
212 |
+
|
213 |
+
if ( 'longer' == $lockout_type ) {
|
214 |
+
$when = sprintf( _nx( '%d hour', '%d hours', $time, 'Logger: Plugin Limit Login Attempts', 'simple-history' ), $time );
|
215 |
+
} elseif ( 'normal' == $lockout_type ) {
|
216 |
+
$when = sprintf( _nx( '%d minute', '%d minutes', $time, 'Logger: Plugin Limit Login Attempts', 'simple-history' ), $time );
|
217 |
+
}
|
218 |
+
|
219 |
+
$output .= '<p>' . sprintf(
|
220 |
+
_x( 'IP was blocked for %1$s', 'Logger: Plugin Limit Login Attempts', 'simple-history' ),
|
221 |
+
$when // 1
|
222 |
+
) . '</p>';
|
223 |
+
}
|
224 |
+
|
225 |
+
return $output;
|
226 |
+
}
|
227 |
+
}
|
|
|
|
|
|
|
228 |
} // End if().
|
loggers/Plugin_Redirection.php
CHANGED
@@ -1,410 +1,398 @@
|
|
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 |
-
|
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 |
-
public function getLogRowDetailsOutput($row)
|
365 |
-
{
|
366 |
-
$context = $row->context;
|
367 |
-
$message_key = $context['_message_key'];
|
368 |
-
|
369 |
-
$out = '';
|
370 |
-
|
371 |
-
if ('redirection_redirection_edited' === $message_key) {
|
372 |
-
if ($context['new_source_url'] !== $context['prev_source_url']) {
|
373 |
-
$diff_table_output = sprintf(
|
374 |
-
'<tr>
|
375 |
<td>%1$s</td>
|
376 |
<td>
|
377 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
378 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
379 |
</td>
|
380 |
</tr>',
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
|
386 |
-
|
387 |
-
|
388 |
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
<td>%1$s</td>
|
393 |
<td>
|
394 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
395 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
396 |
</td>
|
397 |
</tr>',
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
}
|
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 |
+
* Class to log things from the Redirection plugin.
|
12 |
+
*/
|
13 |
+
class Plugin_Redirection extends SimpleLogger {
|
14 |
+
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Logger slug.
|
18 |
+
*
|
19 |
+
* @var string
|
20 |
+
*/
|
21 |
+
public $slug = __CLASS__;
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Return info about logger.
|
25 |
+
*
|
26 |
+
* @return array Array with plugin info.
|
27 |
+
*/
|
28 |
+
public function getInfo() {
|
29 |
+
|
30 |
+
$arr_info = array(
|
31 |
+
'name' => 'Redirection',
|
32 |
+
'description' => _x( 'Text', 'Logger: Redirection', 'simple-history' ),
|
33 |
+
'name_via' => _x( 'In plugin Redirection', 'Logger: Redirection', 'simple-history' ),
|
34 |
+
'capability' => 'manage_options',
|
35 |
+
'messages' => array(
|
36 |
+
'redirection_redirection_added' => _x( 'Added a redirection for URL "{source_url}"', 'Logger: Redirection', 'simple-history' ),
|
37 |
+
'redirection_redirection_edited' => _x( 'Edited redirection for URL "{prev_source_url}"', 'Logger: Redirection', 'simple-history' ),
|
38 |
+
'redirection_redirection_enabled' => _x( 'Enabled redirection for {items_count} URL(s)', 'Logger: Redirection', 'simple-history' ),
|
39 |
+
'redirection_redirection_disabled' => _x( 'Disabled redirection for {items_count} URL(s)', 'Logger: Redirection', 'simple-history' ),
|
40 |
+
'redirection_redirection_deleted' => _x( 'Deleted redirection for {items_count} URL(s)', 'Logger: Redirection', 'simple-history' ),
|
41 |
+
'redirection_options_saved' => _x( 'Updated redirection options', 'Logger: Redirection', 'simple-history' ),
|
42 |
+
'redirection_options_removed_all' => _x( 'Removed all redirection options and deactivated plugin', 'Logger: Redirection', 'simple-history' ),
|
43 |
+
'redirection_group_added' => _x( 'Added redirection group "{group_name}"', 'Logger: Redirection', 'simple-history' ),
|
44 |
+
'redirection_group_enabled' => _x( 'Enabled {items_count} redirection group(s)', 'Logger: Redirection', 'simple-history' ),
|
45 |
+
'redirection_group_disabled' => _x( 'Disabled {items_count} redirection group(s)', 'Logger: Redirection', 'simple-history' ),
|
46 |
+
'redirection_group_deleted' => _x( 'Deleted {items_count} redirection group(s)', 'Logger: Redirection', 'simple-history' ),
|
47 |
+
),
|
48 |
+
|
49 |
+
/*
|
50 |
+
"labels" => array(
|
51 |
+
"search" => array(
|
52 |
+
"label" => _x("Plugin Redirection", "Logger: Redirection", "simple-history"),
|
53 |
+
"label_all" => _x("All posts & pages activity", "Logger: Redirection", "simple-history"),
|
54 |
+
"options" => array(
|
55 |
+
_x("Posts created", "Logger: Redirection", "simple-history") => array(
|
56 |
+
"post_created"
|
57 |
+
),
|
58 |
+
_x("Posts updated", "Logger: Redirection", "simple-history") => array(
|
59 |
+
"post_updated"
|
60 |
+
),
|
61 |
+
_x("Posts trashed", "Logger: Redirection", "simple-history") => array(
|
62 |
+
"post_trashed"
|
63 |
+
),
|
64 |
+
_x("Posts deleted", "Logger: Redirection", "simple-history") => array(
|
65 |
+
"post_deleted"
|
66 |
+
),
|
67 |
+
_x("Posts restored", "Logger: Redirection", "simple-history") => array(
|
68 |
+
"post_restored"
|
69 |
+
),
|
70 |
+
)
|
71 |
+
) // end search array
|
72 |
+
) // end labels
|
73 |
+
*/
|
74 |
+
);
|
75 |
+
|
76 |
+
return $arr_info;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Called when logger is loaded.
|
81 |
+
*/
|
82 |
+
public function loaded() {
|
83 |
+
// Redirection plugin uses the WP REST API, so catch when requests do the API is done.
|
84 |
+
// We use filter *_before_callbacks so we can access the old title
|
85 |
+
// of the Redirection object, i.e. before new values are saved.
|
86 |
+
add_filter( 'rest_request_before_callbacks', array( $this, 'on_rest_request_before_callbacks' ), 10, 3 );
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Fired when WP REST API call is done.
|
91 |
+
*
|
92 |
+
* @param WP_HTTP_Response $response Result to send to the client. Usually a WP_REST_Response.
|
93 |
+
* @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server).
|
94 |
+
* @param WP_REST_Request $request Request used to generate the response.
|
95 |
+
*
|
96 |
+
* @return WP_HTTP_Response $response
|
97 |
+
*/
|
98 |
+
public function on_rest_request_before_callbacks( $response, $handler, $request ) {
|
99 |
+
// Callback must be set.
|
100 |
+
if ( ! isset( $handler['callback'] ) ) {
|
101 |
+
return $response;
|
102 |
+
}
|
103 |
+
|
104 |
+
$callback = $handler['callback'];
|
105 |
+
|
106 |
+
$callable_name = sh_get_callable_name( $callback );
|
107 |
+
|
108 |
+
$ok_redirection_api_callable_names = array(
|
109 |
+
'Redirection_Api_Redirect::route_bulk',
|
110 |
+
'Redirection_Api_Redirect::route_create',
|
111 |
+
'Redirection_Api_Redirect::route_update',
|
112 |
+
'Redirection_Api_Group::route_create',
|
113 |
+
'Redirection_Api_Group::route_bulk',
|
114 |
+
'Redirection_Api_Settings::route_save_settings',
|
115 |
+
);
|
116 |
+
|
117 |
+
// Bail directly if this is not a Redirection API call.
|
118 |
+
if ( ! in_array( $callable_name, $ok_redirection_api_callable_names ) ) {
|
119 |
+
return $response;
|
120 |
+
}
|
121 |
+
|
122 |
+
if ( 'Redirection_Api_Redirect::route_create' === $callable_name ) {
|
123 |
+
$this->log_redirection_add( $request );
|
124 |
+
} elseif ( 'Redirection_Api_Redirect::route_update' === $callable_name ) {
|
125 |
+
$this->log_redirection_edit( $request );
|
126 |
+
} elseif ( 'Redirection_Api_Redirect::route_bulk' === $callable_name ) {
|
127 |
+
$bulk_action = $request->get_param( 'bulk' );
|
128 |
+
$bulk_items = $request->get_param( 'items' );
|
129 |
+
|
130 |
+
if ( ! is_array( $bulk_items ) ) {
|
131 |
+
$bulk_items = explode( ',', $bulk_items );
|
132 |
+
}
|
133 |
+
|
134 |
+
if ( is_array( $bulk_items ) ) {
|
135 |
+
$bulk_items = array_map( 'intval', $bulk_items );
|
136 |
+
}
|
137 |
+
|
138 |
+
if ( empty( $bulk_items ) ) {
|
139 |
+
return $response;
|
140 |
+
}
|
141 |
+
|
142 |
+
if ( 'enable' === $bulk_action ) {
|
143 |
+
$this->log_redirection_enable_or_disable( $request, $bulk_items );
|
144 |
+
} elseif ( 'disable' === $bulk_action ) {
|
145 |
+
$this->log_redirection_enable_or_disable( $request, $bulk_items );
|
146 |
+
} elseif ( 'delete' === $bulk_action ) {
|
147 |
+
$this->log_redirection_delete( $request, $bulk_items );
|
148 |
+
}
|
149 |
+
} elseif ( 'Redirection_Api_Group::route_create' === $callable_name ) {
|
150 |
+
$this->log_group_add( $request );
|
151 |
+
} elseif ( 'Redirection_Api_Group::route_bulk' === $callable_name ) {
|
152 |
+
$bulk_action = $request->get_param( 'bulk' );
|
153 |
+
|
154 |
+
$bulk_items = $request->get_param( 'items' );
|
155 |
+
$bulk_items = explode( ',', $bulk_items );
|
156 |
+
|
157 |
+
if ( is_array( $bulk_items ) ) {
|
158 |
+
$bulk_items = array_map( 'intval', $bulk_items );
|
159 |
+
}
|
160 |
+
|
161 |
+
if ( empty( $bulk_items ) ) {
|
162 |
+
return $response;
|
163 |
+
}
|
164 |
+
|
165 |
+
if ( 'enable' === $bulk_action ) {
|
166 |
+
$this->log_group_enable_or_disable( $request, $bulk_items );
|
167 |
+
} elseif ( 'disable' === $bulk_action ) {
|
168 |
+
$this->log_group_enable_or_disable( $request, $bulk_items );
|
169 |
+
} elseif ( 'delete' === $bulk_action ) {
|
170 |
+
$this->log_group_delete( $request, $bulk_items );
|
171 |
+
}
|
172 |
+
} elseif ( 'Redirection_Api_Settings::route_save_settings' == $callable_name ) {
|
173 |
+
$this->log_options_save( $request );
|
174 |
+
}
|
175 |
+
|
176 |
+
return $response;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Log when a Redirection group is deleted.
|
181 |
+
*
|
182 |
+
* @param object $req Request.
|
183 |
+
* @param array $bulk_items Array with item ids.
|
184 |
+
*/
|
185 |
+
public function log_group_delete( $req, $bulk_items ) {
|
186 |
+
$context = array(
|
187 |
+
'items' => $bulk_items,
|
188 |
+
'items_count' => count( $bulk_items ),
|
189 |
+
);
|
190 |
+
|
191 |
+
$this->infoMessage(
|
192 |
+
'redirection_group_deleted',
|
193 |
+
$context
|
194 |
+
);
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Log when a Redirection grouop is added
|
199 |
+
*
|
200 |
+
* @param WP_REST_Request $req Request.
|
201 |
+
*/
|
202 |
+
public function log_group_add( $req ) {
|
203 |
+
$group_name = $req->get_param( 'name' );
|
204 |
+
|
205 |
+
if ( ! $group_name ) {
|
206 |
+
return;
|
207 |
+
}
|
208 |
+
|
209 |
+
$context = array(
|
210 |
+
'group_name' => $group_name,
|
211 |
+
);
|
212 |
+
|
213 |
+
$this->infoMessage(
|
214 |
+
'redirection_group_added',
|
215 |
+
$context
|
216 |
+
);
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Log enabling and disabling of redirection groups.
|
221 |
+
*
|
222 |
+
* @param object $req Request.
|
223 |
+
* @param array $bulk_items Array with item ids.
|
224 |
+
*/
|
225 |
+
public function log_group_enable_or_disable( $req, $bulk_items ) {
|
226 |
+
$bulk_action = $req->get_param( 'bulk' );
|
227 |
+
|
228 |
+
$message_key = 'enable' === $bulk_action ? 'redirection_group_enabled' : 'redirection_group_disabled';
|
229 |
+
|
230 |
+
$context = array(
|
231 |
+
'items' => $bulk_items,
|
232 |
+
'items_count' => count( $bulk_items ),
|
233 |
+
);
|
234 |
+
|
235 |
+
$this->infoMessage(
|
236 |
+
$message_key,
|
237 |
+
$context
|
238 |
+
);
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Log when options are saved.
|
243 |
+
*
|
244 |
+
* @param object $req Request.
|
245 |
+
*/
|
246 |
+
protected function log_options_save( $req ) {
|
247 |
+
$this->infoMessage( 'redirection_options_saved' );
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Log the deletion of a redirection.
|
252 |
+
*
|
253 |
+
* @param object $req Request.
|
254 |
+
* @param array $bulk_items Array with item ids.
|
255 |
+
*/
|
256 |
+
protected function log_redirection_delete( $req, $bulk_items ) {
|
257 |
+
$context = array(
|
258 |
+
'items' => $bulk_items,
|
259 |
+
'items_count' => count( $bulk_items ),
|
260 |
+
);
|
261 |
+
|
262 |
+
$message_key = 'redirection_redirection_deleted';
|
263 |
+
|
264 |
+
$this->infoMessage(
|
265 |
+
$message_key,
|
266 |
+
$context
|
267 |
+
);
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Log enable or disable of items.
|
272 |
+
*
|
273 |
+
* @param Object $req Req.
|
274 |
+
* @param Array $bulk_items Array.
|
275 |
+
*/
|
276 |
+
protected function log_redirection_enable_or_disable( $req, $bulk_items ) {
|
277 |
+
$bulk_action = $req->get_param( 'bulk' );
|
278 |
+
|
279 |
+
$message_key = 'enable' === $bulk_action ? 'redirection_redirection_enabled' : 'redirection_redirection_disabled';
|
280 |
+
|
281 |
+
$context = array(
|
282 |
+
'items' => $bulk_items,
|
283 |
+
'items_count' => count( $bulk_items ),
|
284 |
+
);
|
285 |
+
|
286 |
+
$this->infoMessage(
|
287 |
+
$message_key,
|
288 |
+
$context
|
289 |
+
);
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Log when a Redirection is added.
|
294 |
+
*
|
295 |
+
* @param WP_REST_Request $req Request.
|
296 |
+
*/
|
297 |
+
protected function log_redirection_add( $req ) {
|
298 |
+
$action_data = $req->get_param( 'action_data' );
|
299 |
+
|
300 |
+
if ( ! $action_data || ! is_array( $action_data ) ) {
|
301 |
+
return false;
|
302 |
+
}
|
303 |
+
|
304 |
+
$context = array(
|
305 |
+
'source_url' => $req->get_param( 'url' ),
|
306 |
+
'target_url' => $action_data['url'],
|
307 |
+
);
|
308 |
+
|
309 |
+
$this->infoMessage( 'redirection_redirection_added', $context );
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Log when a Redirection is changed.
|
314 |
+
*
|
315 |
+
* @param WP_REST_Request $req Request.
|
316 |
+
*/
|
317 |
+
protected function log_redirection_edit( $req ) {
|
318 |
+
$action_data = $req->get_param( 'action_data' );
|
319 |
+
|
320 |
+
if ( ! $action_data || ! is_array( $action_data ) ) {
|
321 |
+
return false;
|
322 |
+
}
|
323 |
+
|
324 |
+
$message_key = 'redirection_redirection_edited';
|
325 |
+
|
326 |
+
$redirection_id = $req->get_param( 'id' );
|
327 |
+
|
328 |
+
$context = array(
|
329 |
+
'new_source_url' => $req->get_param( 'url' ),
|
330 |
+
'new_target' => $action_data,
|
331 |
+
'redirection_id' => $redirection_id,
|
332 |
+
);
|
333 |
+
|
334 |
+
// Get old values.
|
335 |
+
$redirection_item = Red_Item::get_by_id( $redirection_id );
|
336 |
+
|
337 |
+
if ( false !== $redirection_item ) {
|
338 |
+
$context['prev_source_url'] = $redirection_item->get_url();
|
339 |
+
$context['prev_target'] = maybe_unserialize( $redirection_item->get_action_data() );
|
340 |
+
}
|
341 |
+
|
342 |
+
$this->infoMessage(
|
343 |
+
$message_key,
|
344 |
+
$context
|
345 |
+
);
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Return more info about an logged redirection event.
|
350 |
+
*
|
351 |
+
* @param object $row Row with info.
|
352 |
+
*/
|
353 |
+
public function getLogRowDetailsOutput( $row ) {
|
354 |
+
$context = $row->context;
|
355 |
+
$message_key = $context['_message_key'];
|
356 |
+
|
357 |
+
$out = '';
|
358 |
+
|
359 |
+
if ( 'redirection_redirection_edited' === $message_key ) {
|
360 |
+
if ( $context['new_source_url'] !== $context['prev_source_url'] ) {
|
361 |
+
$diff_table_output = sprintf(
|
362 |
+
'<tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
<td>%1$s</td>
|
364 |
<td>
|
365 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
366 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
367 |
</td>
|
368 |
</tr>',
|
369 |
+
esc_html_x( 'Source URL', 'Logger: Redirection', 'simple-history' ), // 1
|
370 |
+
esc_html( $context['new_source_url'] ), // 2
|
371 |
+
esc_html( $context['prev_source_url'] ) // 3
|
372 |
+
);
|
373 |
|
374 |
+
$out .= '<table class="SimpleHistoryLogitem__keyValueTable">' . $diff_table_output . '</table>';
|
375 |
+
}
|
376 |
|
377 |
+
if ( $context['new_target'] !== $context['prev_target'] ) {
|
378 |
+
$diff_table_output = sprintf(
|
379 |
+
'<tr>
|
380 |
<td>%1$s</td>
|
381 |
<td>
|
382 |
<ins class="SimpleHistoryLogitem__keyValueTable__addedThing">%2$s</ins>
|
383 |
<del class="SimpleHistoryLogitem__keyValueTable__removedThing">%3$s</del>
|
384 |
</td>
|
385 |
</tr>',
|
386 |
+
esc_html_x( 'Target', 'Logger: Redirection', 'simple-history' ), // 1
|
387 |
+
esc_html( $context['new_target'] ), // 2
|
388 |
+
esc_html( $context['prev_target'] ) // 3
|
389 |
+
);
|
390 |
+
|
391 |
+
$out .= '<table class="SimpleHistoryLogitem__keyValueTable">' . $diff_table_output . '</table>';
|
392 |
+
}
|
393 |
+
}
|
394 |
+
|
395 |
+
return $out;
|
396 |
+
}
|
397 |
+
}
|
398 |
}
|
loggers/Plugin_UltimateMembers_Logger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
*
|
@@ -8,48 +8,48 @@ 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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
*
|
8 |
*
|
9 |
* @since 2.2
|
10 |
*/
|
11 |
+
class Plugin_UltimateMembers_Logger extends SimpleLogger {
|
12 |
+
|
13 |
+
public $slug = __CLASS__;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Get array with information about this logger
|
17 |
+
*
|
18 |
+
* @return array
|
19 |
+
*/
|
20 |
+
public function getInfo() {
|
21 |
+
$arr_info = array(
|
22 |
+
'name' => _x( 'Ultimate Members Logger', 'PluginUltimateMembersLogger', 'simple-history' ),
|
23 |
+
'description' => _x( 'Logs actions from the Ultimate Members plugin', 'PluginUltimateMembersLogger', 'simple-history' ),
|
24 |
+
'capability' => 'edit_users',
|
25 |
+
'messages' => array(
|
26 |
+
'logged_in' => _x( 'Logged in', 'PluginUltimateMembersLogger', 'simple-history' ),
|
27 |
+
),
|
28 |
+
);
|
29 |
+
|
30 |
+
return $arr_info;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function loaded() {
|
34 |
+
|
35 |
+
// Action that is called when Enable Media Replace loads it's admin options page (both when viewing and when posting new file to it)
|
36 |
+
add_action( 'um_on_login_before_redirect', array( $this, 'on_um_on_login_before_redirect' ), 10, 1 );
|
37 |
+
}
|
38 |
+
|
39 |
+
public function on_um_on_login_before_redirect( $user_id ) {
|
40 |
+
|
41 |
+
$this->infoMessage(
|
42 |
+
'logged_in',
|
43 |
+
array(
|
44 |
+
// "user_id" => $user_id,
|
45 |
+
/*
|
46 |
+
"get" => $_GET,
|
47 |
+
"post" => $_POST,
|
48 |
+
"files" => $_FILES,
|
49 |
+
"old_attachment_post" => $prev_attachment_post,
|
50 |
+
"old_attachment_meta" => $prev_attachment_meta
|
51 |
+
*/
|
52 |
+
)
|
53 |
+
);
|
54 |
+
}
|
55 |
}
|
loggers/SimpleCategoriesLogger.php
CHANGED
@@ -1,323 +1,314 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Logs changes to categories and tags and taxonomies
|
7 |
*/
|
8 |
+
class SimpleCategoriesLogger extends SimpleLogger {
|
9 |
+
|
10 |
+
public $slug = __CLASS__;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Get array with information about this logger
|
14 |
+
*
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
public function getInfo() {
|
18 |
+
|
19 |
+
$arr_info = array(
|
20 |
+
'name' => __( 'Categories Logger', 'simple-history' ),
|
21 |
+
'description' => 'Logs changes to categories, tags, and taxonomies',
|
22 |
+
'messages' => array(
|
23 |
+
'created_term' => __( 'Added term "{term_name}" in taxonomy "{term_taxonomy}"', 'simple-history' ),
|
24 |
+
'deleted_term' => __( 'Deleted term "{term_name}" from taxonomy "{term_taxonomy}"', 'simple-history' ),
|
25 |
+
'edited_term' => __( 'Edited term "{to_term_name}" in taxonomy "{to_term_taxonomy}"', 'simple-history' ),
|
26 |
+
),
|
27 |
+
'labels' => array(
|
28 |
+
'search' => array(
|
29 |
+
'label' => _x( 'Categories', 'Categories logger: search', 'simple-history' ),
|
30 |
+
'label_all' => _x( 'All category activity', 'Category logger: search', 'simple-history' ),
|
31 |
+
'options' => array(
|
32 |
+
_x( 'Term created', 'Category logger: search', 'simple-history' ) => array(
|
33 |
+
'created_term',
|
34 |
+
),
|
35 |
+
_x( 'Term deleted', 'Category logger: search', 'simple-history' ) => array(
|
36 |
+
'deleted_term',
|
37 |
+
),
|
38 |
+
_x( 'Term edited', 'Category logger: search', 'simple-history' ) => array(
|
39 |
+
'edited_term',
|
40 |
+
),
|
41 |
+
),
|
42 |
+
), // end search array
|
43 |
+
), // end labels
|
44 |
+
);
|
45 |
+
|
46 |
+
return $arr_info;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Called when the logger is loaded.
|
51 |
+
*/
|
52 |
+
public function loaded() {
|
53 |
+
// Fires after a new term is created, and after the term cache has been cleaned..
|
54 |
+
add_action( 'created_term', array( $this, 'on_created_term' ), 10, 3 );
|
55 |
+
|
56 |
+
// Hook to this filter to see if it will cause a hierarchy loop.
|
57 |
+
add_action( 'delete_term', array( $this, 'on_delete_term' ), 10, 4 );
|
58 |
+
|
59 |
+
// Filter the term parent.
|
60 |
+
add_action( 'wp_update_term_parent', array( $this, 'on_wp_update_term_parent' ), 10, 5 );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Filter the term parent.
|
65 |
+
* Only way for Simple History to get both old and new term name.
|
66 |
+
* For example 'edited_term' does not contain enough info to know what the term was called before the update.
|
67 |
+
*
|
68 |
+
* @param int $parent ID of the parent term.
|
69 |
+
* @param int $term_id Term ID.
|
70 |
+
* @param string $taxonomy Taxonomy slug.
|
71 |
+
* @param array $parsed_args An array of potentially altered update arguments for the given term.
|
72 |
+
* @param array $term_update_args An array of update arguments for the given term.
|
73 |
+
*/
|
74 |
+
public function on_wp_update_term_parent( $parent = null, $term_id = null, $taxonomy = null, $parsed_args = null, $term_update_args = null ) {
|
75 |
+
|
76 |
+
$term_before_edited = get_term_by( 'id', $term_id, $taxonomy );
|
77 |
+
|
78 |
+
if ( ! $term_before_edited || empty( $term_update_args ) ) {
|
79 |
+
return $parent;
|
80 |
+
}
|
81 |
+
|
82 |
+
$term_id = $term_before_edited->term_id;
|
83 |
+
|
84 |
+
$from_term_name = $term_before_edited->name;
|
85 |
+
$from_term_taxonomy = $term_before_edited->taxonomy;
|
86 |
+
$from_term_slug = $term_before_edited->slug;
|
87 |
+
$from_term_description = $term_before_edited->description;
|
88 |
+
|
89 |
+
$to_term_name = $term_update_args['name'];
|
90 |
+
$to_term_taxonomy = $term_update_args['taxonomy'];
|
91 |
+
$to_term_slug = $term_update_args['slug'];
|
92 |
+
$to_term_description = $term_update_args['description'];
|
93 |
+
|
94 |
+
$do_log_term = $this->ok_to_log_taxonomy( $from_term_taxonomy );
|
95 |
+
|
96 |
+
if ( ! $do_log_term ) {
|
97 |
+
return $parent;
|
98 |
+
}
|
99 |
+
|
100 |
+
$this->infoMessage(
|
101 |
+
'edited_term',
|
102 |
+
array(
|
103 |
+
'term_id' => $term_id,
|
104 |
+
'from_term_name' => $from_term_name,
|
105 |
+
'from_term_taxonomy' => $from_term_taxonomy,
|
106 |
+
'from_term_slug' => $from_term_slug,
|
107 |
+
'from_term_description' => $from_term_description,
|
108 |
+
'to_term_name' => $to_term_name,
|
109 |
+
'to_term_taxonomy' => $to_term_taxonomy,
|
110 |
+
'to_term_slug' => $to_term_slug,
|
111 |
+
'to_term_description' => $to_term_description,
|
112 |
+
)
|
113 |
+
);
|
114 |
+
|
115 |
+
return $parent;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Check if it's ok to log a taxonomy.
|
120 |
+
* We skip some taxonomies, for example Polylang translation terms that fill the log with
|
121 |
+
* messages like 'Edited term "pll_5a3643a142c80" in taxonomy "post_translations"' otherwise.
|
122 |
+
*
|
123 |
+
* @since 2.21
|
124 |
+
* @param string $from_term_taxonomy Slug of taxonomy.
|
125 |
+
* @return bool True or false.
|
126 |
+
*/
|
127 |
+
public function ok_to_log_taxonomy( $from_term_taxonomy = '' ) {
|
128 |
+
if ( empty( $from_term_taxonomy ) ) {
|
129 |
+
return false;
|
130 |
+
}
|
131 |
+
|
132 |
+
$skip_taxonomies = $this->get_skip_taxonomies();
|
133 |
+
|
134 |
+
$do_log = ! in_array( $from_term_taxonomy, $skip_taxonomies, true );
|
135 |
+
|
136 |
+
return $do_log;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Get taxonomies to skip.
|
141 |
+
*
|
142 |
+
* @since 2.21
|
143 |
+
* @return array Array with taxonomies.
|
144 |
+
*/
|
145 |
+
public function get_skip_taxonomies() {
|
146 |
+
|
147 |
+
$taxonomies_to_skip = array(
|
148 |
+
// Polylang taxonomies used to store translation mappings.
|
149 |
+
'post_translations',
|
150 |
+
'term_translations',
|
151 |
+
);
|
152 |
+
|
153 |
+
$taxonomies_to_skip = apply_filters( 'simple_history/categories_logger/skip_taxonomies', $taxonomies_to_skip );
|
154 |
+
|
155 |
+
return $taxonomies_to_skip;
|
156 |
+
}
|
157 |
+
|
158 |
+
/*
|
159 |
+
* Fires after a new term is created, and after the term cache has been cleaned.
|
160 |
+
*
|
161 |
+
* @since 2.3.0
|
162 |
+
*
|
163 |
+
* @param int $term_id Term ID.
|
164 |
+
* @param int $tt_id Term taxonomy ID.
|
165 |
+
* @param string $taxonomy Taxonomy slug.
|
166 |
+
*/
|
167 |
+
public function on_created_term( $term_id = null, $tt_id = null, $taxonomy = null ) {
|
168 |
+
|
169 |
+
$term = get_term_by( 'id', $term_id, $taxonomy );
|
170 |
+
|
171 |
+
if ( ! $term ) {
|
172 |
+
return;
|
173 |
+
}
|
174 |
+
|
175 |
+
$term_name = $term->name;
|
176 |
+
$term_taxonomy = $term->taxonomy;
|
177 |
+
$term_id = $term->term_id;
|
178 |
+
|
179 |
+
$do_log_term = $this->ok_to_log_taxonomy( $term_taxonomy );
|
180 |
+
|
181 |
+
if ( ! $do_log_term ) {
|
182 |
+
return;
|
183 |
+
}
|
184 |
+
|
185 |
+
$this->infoMessage(
|
186 |
+
'created_term',
|
187 |
+
array(
|
188 |
+
'term_id' => $term_id,
|
189 |
+
'term_name' => $term_name,
|
190 |
+
'term_taxonomy' => $term_taxonomy,
|
191 |
+
)
|
192 |
+
);
|
193 |
+
}
|
194 |
+
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Fires after a term is deleted from the database and the cache is cleaned.
|
198 |
+
*
|
199 |
+
* @param int $term Term ID.
|
200 |
+
* @param int $tt_id Term taxonomy ID.
|
201 |
+
* @param string $taxonomy Taxonomy slug.
|
202 |
+
* @param mixed $deleted_term Copy of the already-deleted term, in the form specified
|
203 |
+
* by the parent function. WP_Error otherwise.
|
204 |
+
*/
|
205 |
+
public function on_delete_term( $term = null, $tt_id = null, $taxonomy = null, $deleted_term = null ) {
|
206 |
+
|
207 |
+
if ( is_wp_error( $deleted_term ) ) {
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
|
211 |
+
$term_name = $deleted_term->name;
|
212 |
+
$term_taxonomy = $deleted_term->taxonomy;
|
213 |
+
$term_id = $deleted_term->term_id;
|
214 |
+
|
215 |
+
$do_log_term = $this->ok_to_log_taxonomy( $term_taxonomy );
|
216 |
+
|
217 |
+
if ( ! $do_log_term ) {
|
218 |
+
return;
|
219 |
+
}
|
220 |
+
|
221 |
+
$this->infoMessage(
|
222 |
+
'deleted_term',
|
223 |
+
array(
|
224 |
+
'term_id' => $term_id,
|
225 |
+
'term_name' => $term_name,
|
226 |
+
'term_taxonomy' => $term_taxonomy,
|
227 |
+
)
|
228 |
+
);
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Modify plain output to include link to term and taxonomy.
|
233 |
+
*
|
234 |
+
* @param object $row Row data.
|
235 |
+
*/
|
236 |
+
public function getLogRowPlainTextOutput( $row ) {
|
237 |
+
$context = $row->context;
|
238 |
+
$message_key = isset( $context['_message_key'] ) ? $context['_message_key'] : null;
|
239 |
+
|
240 |
+
// Default to original log message.
|
241 |
+
$message = $row->message;
|
242 |
+
|
243 |
+
// Get term that was created, edited, or removed.
|
244 |
+
$term_id = isset( $context['term_id'] ) ? (int) $context['term_id'] : null;
|
245 |
+
|
246 |
+
// Get taxonomy for term.
|
247 |
+
if ( 'created_term' === $message_key || 'deleted_term' === $message_key ) {
|
248 |
+
$term_taxonomy = isset( $context['term_taxonomy'] ) ? (string) $context['term_taxonomy'] : null;
|
249 |
+
} elseif ( 'edited_term' === $message_key ) {
|
250 |
+
$term_taxonomy = isset( $context['from_term_taxonomy'] ) ? (string) $context['from_term_taxonomy'] : null;
|
251 |
+
}
|
252 |
+
|
253 |
+
$tax_edit_link = add_query_arg(
|
254 |
+
array(
|
255 |
+
'taxonomy' => $term_taxonomy,
|
256 |
+
),
|
257 |
+
admin_url( 'term.php' )
|
258 |
+
);
|
259 |
+
|
260 |
+
$context['tax_edit_link'] = $tax_edit_link;
|
261 |
+
|
262 |
+
$term_object = get_term( $term_id, $term_taxonomy );
|
263 |
+
|
264 |
+
if ( is_wp_error( $term_object ) ) {
|
265 |
+
return $this->interpolate( $message, $context, $row );
|
266 |
+
}
|
267 |
+
|
268 |
+
$term_edit_link = isset( $term_object ) ? get_edit_tag_link( $term_id, $term_object->taxonomy ) : null;
|
269 |
+
$context['term_edit_link'] = $term_edit_link;
|
270 |
+
|
271 |
+
// Get taxonomy name to use in log but fall back to taxonomy slug if
|
272 |
+
// taxonomy has been deleted.
|
273 |
+
$context['termTaxonomySlugOrName'] = isset( $context['term_taxonomy'] ) ? $context['term_taxonomy'] : null;
|
274 |
+
$context['toTermTaxonomySlugOrName'] = isset( $context['to_term_taxonomy'] ) ? $context['to_term_taxonomy'] : null;
|
275 |
+
|
276 |
+
if ( isset( $context['term_taxonomy'] ) && $context['term_taxonomy'] ) {
|
277 |
+
$termTaxonomyObject = get_taxonomy( $context['term_taxonomy'] );
|
278 |
+
if ( is_a( $termTaxonomyObject, 'WP_Taxonomy' ) ) {
|
279 |
+
$termTaxonomyObjectLabels = get_taxonomy_labels( $termTaxonomyObject );
|
280 |
+
$context['termTaxonomySlugOrName'] = $termTaxonomyObjectLabels->singular_name;
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
if ( isset( $context['to_term_taxonomy'] ) && $context['to_term_taxonomy'] ) {
|
285 |
+
$termTaxonomyObject = get_taxonomy( $context['to_term_taxonomy'] );
|
286 |
+
if ( is_a( $termTaxonomyObject, 'WP_Taxonomy' ) ) {
|
287 |
+
$termTaxonomyObjectLabels = get_taxonomy_labels( $termTaxonomyObject );
|
288 |
+
$context['toTermTaxonomySlugOrName'] = $termTaxonomyObjectLabels->singular_name;
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
if ( 'created_term' === $message_key && ! empty( $term_edit_link ) && ! empty( $tax_edit_link ) ) {
|
293 |
+
$message = _x(
|
294 |
+
'Added term <a href="{term_edit_link}">"{term_name}"</a> in taxonomy <a href="{tax_edit_link}">"{termTaxonomySlugOrName}"</a>',
|
295 |
+
'Categories logger: detailed plain text output for created term',
|
296 |
+
'simple-history'
|
297 |
+
);
|
298 |
+
} elseif ( 'deleted_term' === $message_key && ! empty( $tax_edit_link ) ) {
|
299 |
+
$message = _x(
|
300 |
+
'Deleted term "{term_name}" from taxonomy <a href="{tax_edit_link}">"{termTaxonomySlugOrName}"</a>',
|
301 |
+
'Categories logger: detailed plain text output for deleted term',
|
302 |
+
'simple-history'
|
303 |
+
);
|
304 |
+
} elseif ( 'edited_term' === $message_key && ! empty( $term_edit_link ) && ! empty( $tax_edit_link ) ) {
|
305 |
+
$message = _x(
|
306 |
+
'Edited term <a href="{term_edit_link}">"{to_term_name}"</a> in taxonomy <a href="{tax_edit_link}">"{toTermTaxonomySlugOrName}"</a>',
|
307 |
+
'Categories logger: detailed plain text output for edited term',
|
308 |
+
'simple-history'
|
309 |
+
);
|
310 |
+
}
|
311 |
+
|
312 |
+
return $this->interpolate( $message, $context, $row );
|
313 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
}
|
loggers/SimpleCommentsLogger.php
CHANGED
@@ -1,52 +1,51 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
-
$where .= sprintf('
|
50 |
AND id NOT IN (
|
51 |
|
52 |
SELECT id
|
@@ -73,707 +72,702 @@ class SimpleCommentsLogger extends SimpleLogger
|
|
73 |
WHERE logger = "%3$s"
|
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 |
-
$output .= sprintf(
|
716 |
-
'
|
717 |
<tr>
|
718 |
<td>%1$s</td>
|
719 |
<td>%2$s</td>
|
720 |
</tr>
|
721 |
',
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
<tr>
|
744 |
<td></td>
|
745 |
<td><a href="%2$s">%1$s</a></td>
|
746 |
</tr>
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Logs things related to comments
|
7 |
*/
|
8 |
+
class SimpleCommentsLogger extends SimpleLogger {
|
9 |
+
|
10 |
+
public $slug = __CLASS__;
|
11 |
+
|
12 |
+
public function __construct( $sh ) {
|
13 |
+
parent::__construct( $sh );
|
14 |
+
|
15 |
+
// Add option to not show spam comments, because to much things getting logged
|
16 |
+
// add_filter("simple_history/log_query_sql_where", array($this, "maybe_modify_log_query_sql_where"));
|
17 |
+
add_filter( 'simple_history/log_query_inner_where', array( $this, 'maybe_modify_log_query_sql_where' ) );
|
18 |
+
add_filter( 'simple_history/quick_stats_where', array( $this, 'maybe_modify_log_query_sql_where' ) );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Modify sql query to exclude comments of type spam
|
23 |
+
*
|
24 |
+
* @param string $where sql query where
|
25 |
+
*/
|
26 |
+
public function maybe_modify_log_query_sql_where( $where ) {
|
27 |
+
|
28 |
+
// since 19 sept 2016 we do include spam, to skip the subquery
|
29 |
+
// spam comments should not be logged anyway since some time
|
30 |
+
$include_spam = true;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Filter option to include spam or not in the gui
|
34 |
+
* By default spam is not included, because it can fill the log
|
35 |
+
* with too much events
|
36 |
+
*
|
37 |
+
* @since 2.0
|
38 |
+
*
|
39 |
+
* @param bool $include_spam Default false
|
40 |
+
*/
|
41 |
+
$include_spam = apply_filters( 'simple_history/comments_logger/include_spam', $include_spam );
|
42 |
+
|
43 |
+
if ( $include_spam ) {
|
44 |
+
return $where;
|
45 |
+
}
|
46 |
+
|
47 |
+
$where .= sprintf(
|
48 |
+
'
|
|
|
49 |
AND id NOT IN (
|
50 |
|
51 |
SELECT id
|
72 |
WHERE logger = "%3$s"
|
73 |
|
74 |
)
|
75 |
+
',
|
76 |
+
$this->db_table,
|
77 |
+
$this->db_table_contexts,
|
78 |
+
$this->slug
|
79 |
+
);
|
80 |
+
|
81 |
+
// echo $where;
|
82 |
+
return $where;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Get array with information about this logger
|
87 |
+
*
|
88 |
+
* @return array
|
89 |
+
*/
|
90 |
+
public function getInfo() {
|
91 |
+
|
92 |
+
$arr_info = array(
|
93 |
+
'name' => 'Comments Logger',
|
94 |
+
'description' => 'Logs comments, and modifications to them',
|
95 |
+
'capability' => 'moderate_comments',
|
96 |
+
'messages' => array(
|
97 |
+
|
98 |
+
// Comments
|
99 |
+
'anon_comment_added' => _x(
|
100 |
+
'Added a comment to {comment_post_type} "{comment_post_title}"',
|
101 |
+
'A comment was added to the database by a non-logged in internet user',
|
102 |
+
'simple-history'
|
103 |
+
),
|
104 |
+
|
105 |
+
'user_comment_added' => _x(
|
106 |
+
'Added a comment to {comment_post_type} "{comment_post_title}"',
|
107 |
+
'A comment was added to the database by a logged in user',
|
108 |
+
'simple-history'
|
109 |
+
),
|
110 |
+
|
111 |
+
'comment_status_approve' => _x(
|
112 |
+
'Approved a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
113 |
+
'A comment was approved',
|
114 |
+
'simple-history'
|
115 |
+
),
|
116 |
+
|
117 |
+
'comment_status_hold' => _x(
|
118 |
+
'Unapproved a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
119 |
+
'A comment was was unapproved',
|
120 |
+
'simple-history'
|
121 |
+
),
|
122 |
+
|
123 |
+
'comment_status_spam' => _x(
|
124 |
+
'Marked a comment to post "{comment_post_title}" as spam',
|
125 |
+
'A comment was marked as spam',
|
126 |
+
'simple-history'
|
127 |
+
),
|
128 |
+
|
129 |
+
'comment_status_trash' => _x(
|
130 |
+
'Trashed a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
131 |
+
'A comment was marked moved to the trash',
|
132 |
+
'simple-history'
|
133 |
+
),
|
134 |
+
|
135 |
+
'comment_untrashed' => _x(
|
136 |
+
'Restored a comment to "{comment_post_title}" by {comment_author} ({comment_author_email}) from the trash',
|
137 |
+
'A comment was restored from the trash',
|
138 |
+
'simple-history'
|
139 |
+
),
|
140 |
+
|
141 |
+
'comment_deleted' => _x(
|
142 |
+
'Deleted a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
143 |
+
'A comment was deleted',
|
144 |
+
'simple-history'
|
145 |
+
),
|
146 |
+
|
147 |
+
'comment_edited' => _x(
|
148 |
+
'Edited a comment to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
149 |
+
'A comment was edited',
|
150 |
+
'simple-history'
|
151 |
+
),
|
152 |
+
|
153 |
+
// Trackbacks
|
154 |
+
'anon_trackback_added' => _x(
|
155 |
+
'Added a trackback to {comment_post_type} "{comment_post_title}"',
|
156 |
+
'A trackback was added to the database by a non-logged in internet user',
|
157 |
+
'simple-history'
|
158 |
+
),
|
159 |
+
|
160 |
+
'user_trackback_added' => _x(
|
161 |
+
'Added a trackback to {comment_post_type} "{comment_post_title}"',
|
162 |
+
'A trackback was added to the database by a logged in user',
|
163 |
+
'simple-history'
|
164 |
+
),
|
165 |
+
|
166 |
+
'trackback_status_approve' => _x(
|
167 |
+
'Approved a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
168 |
+
'A trackback was approved',
|
169 |
+
'simple-history'
|
170 |
+
),
|
171 |
+
|
172 |
+
'trackback_status_hold' => _x(
|
173 |
+
'Unapproved a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
174 |
+
'A trackback was was unapproved',
|
175 |
+
'simple-history'
|
176 |
+
),
|
177 |
+
|
178 |
+
'trackback_status_spam' => _x(
|
179 |
+
'Marked a trackback to post "{comment_post_title}" as spam',
|
180 |
+
'A trackback was marked as spam',
|
181 |
+
'simple-history'
|
182 |
+
),
|
183 |
+
|
184 |
+
'trackback_status_trash' => _x(
|
185 |
+
'Trashed a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
186 |
+
'A trackback was marked moved to the trash',
|
187 |
+
'simple-history'
|
188 |
+
),
|
189 |
+
|
190 |
+
'trackback_untrashed' => _x(
|
191 |
+
'Restored a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email}) from the trash',
|
192 |
+
'A trackback was restored from the trash',
|
193 |
+
'simple-history'
|
194 |
+
),
|
195 |
+
|
196 |
+
'trackback_deleted' => _x(
|
197 |
+
'Deleted a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
198 |
+
'A trackback was deleted',
|
199 |
+
'simple-history'
|
200 |
+
),
|
201 |
+
|
202 |
+
'trackback_edited' => _x(
|
203 |
+
'Edited a trackback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
204 |
+
'A trackback was edited',
|
205 |
+
'simple-history'
|
206 |
+
),
|
207 |
+
|
208 |
+
// Pingbacks
|
209 |
+
'anon_pingback_added' => _x(
|
210 |
+
'Added a pingback to {comment_post_type} "{comment_post_title}"',
|
211 |
+
'A trackback was added to the database by a non-logged in internet user',
|
212 |
+
'simple-history'
|
213 |
+
),
|
214 |
+
|
215 |
+
'user_pingback_added' => _x(
|
216 |
+
'Added a pingback to {comment_post_type} "{comment_post_title}"',
|
217 |
+
'A pingback was added to the database by a logged in user',
|
218 |
+
'simple-history'
|
219 |
+
),
|
220 |
+
|
221 |
+
'pingback_status_approve' => _x(
|
222 |
+
'Approved a pingback to "{comment_post_title}" by "{comment_author}"" ({comment_author_email})',
|
223 |
+
'A pingback was approved',
|
224 |
+
'simple-history'
|
225 |
+
),
|
226 |
+
|
227 |
+
'pingback_status_hold' => _x(
|
228 |
+
'Unapproved a pingback to "{comment_post_title}" by "{comment_author}" ({comment_author_email})',
|
229 |
+
'A pingback was was unapproved',
|
230 |
+
'simple-history'
|
231 |
+
),
|
232 |
+
|
233 |
+
'pingback_status_spam' => _x(
|
234 |
+
'Marked a pingback to post "{comment_post_title}" as spam',
|
235 |
+
'A pingback was marked as spam',
|
236 |
+
'simple-history'
|
237 |
+
),
|
238 |
+
|
239 |
+
'pingback_status_trash' => _x(
|
240 |
+
'Trashed a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
241 |
+
'A pingback was marked moved to the trash',
|
242 |
+
'simple-history'
|
243 |
+
),
|
244 |
+
|
245 |
+
'pingback_untrashed' => _x(
|
246 |
+
'Restored a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email}) from the trash',
|
247 |
+
'A pingback was restored from the trash',
|
248 |
+
'simple-history'
|
249 |
+
),
|
250 |
+
|
251 |
+
'pingback_deleted' => _x(
|
252 |
+
'Deleted a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
253 |
+
'A pingback was deleted',
|
254 |
+
'simple-history'
|
255 |
+
),
|
256 |
+
|
257 |
+
'pingback_edited' => _x(
|
258 |
+
'Edited a pingback to "{comment_post_title}" by {comment_author} ({comment_author_email})',
|
259 |
+
'A pingback was edited',
|
260 |
+
'simple-history'
|
261 |
+
),
|
262 |
+
|
263 |
+
), // end messages
|
264 |
+
|
265 |
+
'labels' => array(
|
266 |
+
|
267 |
+
'search' => array(
|
268 |
+
'label' => _x( 'Comments', 'Comments logger: search', 'simple-history' ),
|
269 |
+
'label_all' => _x( 'All comments activity', 'Comments logger: search', 'simple-history' ),
|
270 |
+
'options' => array(
|
271 |
+
_x( 'Added comments', 'Comments logger: search', 'simple-history' ) => array(
|
272 |
+
'anon_comment_added',
|
273 |
+
'user_comment_added',
|
274 |
+
'anon_trackback_added',
|
275 |
+
'user_trackback_added',
|
276 |
+
'anon_pingback_added',
|
277 |
+
'user_pingback_added',
|
278 |
+
),
|
279 |
+
_x( 'Edited comments', 'Comments logger: search', 'simple-history' ) => array(
|
280 |
+
'comment_edited',
|
281 |
+
'trackback_edited',
|
282 |
+
'pingback_edited',
|
283 |
+
),
|
284 |
+
_x( 'Approved comments', 'Comments logger: search', 'simple-history' ) => array(
|
285 |
+
'comment_status_approve',
|
286 |
+
'trackback_status_approve',
|
287 |
+
'pingback_status_approve',
|
288 |
+
),
|
289 |
+
_x( 'Held comments', 'Comments logger: search', 'simple-history' ) => array(
|
290 |
+
'comment_status_hold',
|
291 |
+
'trackback_status_hold',
|
292 |
+
'pingback_status_hold',
|
293 |
+
),
|
294 |
+
_x( 'Comments status changed to spam', 'Comments logger: search', 'simple-history' ) => array(
|
295 |
+
'comment_status_spam',
|
296 |
+
'trackback_status_spam',
|
297 |
+
'pingback_status_spam',
|
298 |
+
),
|
299 |
+
_x( 'Trashed comments', 'Comments logger: search', 'simple-history' ) => array(
|
300 |
+
'comment_status_trash',
|
301 |
+
'trackback_status_trash',
|
302 |
+
'pingback_status_trash',
|
303 |
+
),
|
304 |
+
_x( 'Untrashed comments', 'Comments logger: search', 'simple-history' ) => array(
|
305 |
+
'comment_untrashed',
|
306 |
+
'trackback_untrashed',
|
307 |
+
'pingback_untrashed',
|
308 |
+
),
|
309 |
+
_x( 'Deleted comments', 'Comments logger: search', 'simple-history' ) => array(
|
310 |
+
'comment_deleted',
|
311 |
+
'trackback_deleted',
|
312 |
+
'pingback_deleted',
|
313 |
+
),
|
314 |
+
),
|
315 |
+
), // end search
|
316 |
+
|
317 |
+
), // labels
|
318 |
+
|
319 |
+
);
|
320 |
+
|
321 |
+
return $arr_info;
|
322 |
+
}
|
323 |
+
|
324 |
+
public function loaded() {
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Fires immediately after a comment is inserted into the database.
|
328 |
+
*/
|
329 |
+
add_action( 'comment_post', array( $this, 'on_comment_post' ), 10, 2 );
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Fires after a comment status has been updated in the database.
|
333 |
+
* The hook also fires immediately before comment status transition hooks are fired.
|
334 |
+
*/
|
335 |
+
add_action( 'wp_set_comment_status', array( $this, 'on_wp_set_comment_status' ), 10, 2 );
|
336 |
+
|
337 |
+
/**
|
338 |
+
*Fires immediately after a comment is restored from the Trash.
|
339 |
+
*/
|
340 |
+
add_action( 'untrashed_comment', array( $this, 'on_untrashed_comment' ), 10, 1 );
|
341 |
+
|
342 |
+
/**
|
343 |
+
* Fires immediately before a comment is deleted from the database.
|
344 |
+
*/
|
345 |
+
add_action( 'delete_comment', array( $this, 'on_delete_comment' ), 10, 1 );
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Fires immediately after a comment is updated in the database.
|
349 |
+
* The hook also fires immediately before comment status transition hooks are fired.
|
350 |
+
*/
|
351 |
+
add_action( 'edit_comment', array( $this, 'on_edit_comment' ), 10, 1 );
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Get comments context
|
356 |
+
*
|
357 |
+
* @param int $comment_ID
|
358 |
+
* @return mixed array with context if comment found, false if comment not found
|
359 |
+
*/
|
360 |
+
public function get_context_for_comment( $comment_ID ) {
|
361 |
+
|
362 |
+
// get_comment passes comment_ID by reference, so it can be unset by that function
|
363 |
+
$comment_ID_original = $comment_ID;
|
364 |
+
$comment_data = get_comment( $comment_ID );
|
365 |
+
|
366 |
+
if ( is_null( $comment_data ) ) {
|
367 |
+
return false;
|
368 |
+
}
|
369 |
+
|
370 |
+
$comment_parent_post = get_post( $comment_data->comment_post_ID );
|
371 |
+
|
372 |
+
$context = array(
|
373 |
+
'comment_ID' => $comment_ID_original,
|
374 |
+
'comment_author' => $comment_data->comment_author,
|
375 |
+
'comment_author_email' => $comment_data->comment_author_email,
|
376 |
+
'comment_author_url' => $comment_data->comment_author_url,
|
377 |
+
'comment_author_IP' => $comment_data->comment_author_IP,
|
378 |
+
'comment_content' => $comment_data->comment_content,
|
379 |
+
'comment_approved' => $comment_data->comment_approved,
|
380 |
+
'comment_agent' => $comment_data->comment_agent,
|
381 |
+
'comment_type' => $comment_data->comment_type,
|
382 |
+
'comment_parent' => $comment_data->comment_parent,
|
383 |
+
'comment_post_ID' => $comment_data->comment_post_ID,
|
384 |
+
'comment_post_title' => $comment_parent_post->post_title,
|
385 |
+
'comment_post_type' => $comment_parent_post->post_type,
|
386 |
+
);
|
387 |
+
|
388 |
+
// Note: comment type is empty for normal comments
|
389 |
+
if ( empty( $context['comment_type'] ) ) {
|
390 |
+
$context['comment_type'] = 'comment';
|
391 |
+
}
|
392 |
+
|
393 |
+
return $context;
|
394 |
+
}
|
395 |
+
|
396 |
+
public function on_edit_comment( $comment_ID ) {
|
397 |
+
|
398 |
+
$context = $this->get_context_for_comment( $comment_ID );
|
399 |
+
if ( ! $context ) {
|
400 |
+
return;
|
401 |
+
}
|
402 |
+
|
403 |
+
$this->infoMessage(
|
404 |
+
"{$context["comment_type"]}_edited",
|
405 |
+
$context
|
406 |
+
);
|
407 |
+
}
|
408 |
+
|
409 |
+
public function on_delete_comment( $comment_ID ) {
|
410 |
+
|
411 |
+
$context = $this->get_context_for_comment( $comment_ID );
|
412 |
+
|
413 |
+
if ( ! $context ) {
|
414 |
+
return;
|
415 |
+
}
|
416 |
+
|
417 |
+
$comment_data = get_comment( $comment_ID );
|
418 |
+
|
419 |
+
// add occasions if comment was considered spam
|
420 |
+
// if not added, spam comments can easily flood the log
|
421 |
+
// Deletions of spam easiy flood log
|
422 |
+
if ( isset( $comment_data->comment_approved ) && 'spam' === $comment_data->comment_approved ) {
|
423 |
+
// since 2.5.5: don't log deletion of spam comments
|
424 |
+
return;
|
425 |
+
// $context["_occasionsID"] = __CLASS__ . '/' . __FUNCTION__ . "/anon_{$context["comment_type"]}_deleted/type:spam";
|
426 |
+
}
|
427 |
+
|
428 |
+
$this->infoMessage(
|
429 |
+
"{$context["comment_type"]}_deleted",
|
430 |
+
$context
|
431 |
+
);
|
432 |
+
}
|
433 |
+
|
434 |
+
public function on_untrashed_comment( $comment_ID ) {
|
435 |
+
|
436 |
+
$context = $this->get_context_for_comment( $comment_ID );
|
437 |
+
if ( ! $context ) {
|
438 |
+
return;
|
439 |
+
}
|
440 |
+
|
441 |
+
$this->infoMessage(
|
442 |
+
"{$context["comment_type"]}_untrashed",
|
443 |
+
$context
|
444 |
+
);
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* Fires after a comment status has been updated in the database.
|
449 |
+
* The hook also fires immediately before comment status transition hooks are fired.
|
450 |
+
*
|
451 |
+
* @param int $comment_id The comment ID.
|
452 |
+
* @param string|bool $comment_status The comment status. Possible values include 'hold',
|
453 |
+
* 'approve', 'spam', 'trash', or false.
|
454 |
+
* do_action( 'wp_set_comment_status', $comment_id, $comment_status );
|
455 |
+
*/
|
456 |
+
public function on_wp_set_comment_status( $comment_ID, $comment_status ) {
|
457 |
+
|
458 |
+
$context = $this->get_context_for_comment( $comment_ID );
|
459 |
+
|
460 |
+
if ( ! $context ) {
|
461 |
+
return;
|
462 |
+
}
|
463 |
+
|
464 |
+
/*
|
465 |
+
$comment_status:
|
466 |
+
approve
|
467 |
+
comment was approved
|
468 |
+
spam
|
469 |
+
comment was marked as spam
|
470 |
+
trash
|
471 |
+
comment was trashed
|
472 |
+
hold
|
473 |
+
comment was un-approved
|
474 |
+
*/
|
475 |
+
$message = "{$context["comment_type"]}_status_{$comment_status}";
|
476 |
+
|
477 |
+
$this->infoMessage(
|
478 |
+
$message,
|
479 |
+
$context
|
480 |
+
);
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Fires immediately after a comment is inserted into the database.
|
485 |
+
*/
|
486 |
+
public function on_comment_post( $comment_ID, $comment_approved ) {
|
487 |
+
|
488 |
+
$context = $this->get_context_for_comment( $comment_ID );
|
489 |
+
|
490 |
+
if ( ! $context ) {
|
491 |
+
return;
|
492 |
+
}
|
493 |
+
|
494 |
+
// since 2.5.5: no more logging of spam comments
|
495 |
+
if ( isset( $comment_approved ) && 'spam' === $comment_approved ) {
|
496 |
+
return;
|
497 |
+
}
|
498 |
+
|
499 |
+
$comment_data = get_comment( $comment_ID );
|
500 |
+
|
501 |
+
$message = '';
|
502 |
+
|
503 |
+
if ( $comment_data->user_id ) {
|
504 |
+
// comment was from a logged in user
|
505 |
+
$message = "user_{$context["comment_type"]}_added";
|
506 |
+
} else {
|
507 |
+
// comment was from a non-logged in user
|
508 |
+
$message = "anon_{$context["comment_type"]}_added";
|
509 |
+
$context['_initiator'] = SimpleLoggerLogInitiators::WEB_USER;
|
510 |
+
|
511 |
+
// add occasions if comment is considered spam
|
512 |
+
// if not added, spam comments can easily flood the log
|
513 |
+
if ( isset( $comment_data->comment_approved ) && 'spam' === $comment_data->comment_approved ) {
|
514 |
+
$context['_occasionsID'] = __CLASS__ . '/' . __FUNCTION__ . "/anon_{$context["comment_type"]}_added/type:spam";
|
515 |
+
}
|
516 |
+
}
|
517 |
+
|
518 |
+
$this->infoMessage(
|
519 |
+
$message,
|
520 |
+
$context
|
521 |
+
);
|
522 |
+
}
|
523 |
+
|
524 |
+
|
525 |
+
/**
|
526 |
+
* Modify plain output to inlcude link to post
|
527 |
+
* and link to comment
|
528 |
+
*
|
529 |
+
* @param object $row
|
530 |
+
*/
|
531 |
+
public function getLogRowPlainTextOutput( $row ) {
|
532 |
+
|
533 |
+
$message = $row->message;
|
534 |
+
$context = $row->context;
|
535 |
+
$message_key = $context['_message_key'];
|
536 |
+
|
537 |
+
// Message is untranslated here, so get translated text
|
538 |
+
// Can't call parent __FUNCTION__ because it will interpolate too, which we don't want
|
539 |
+
if ( ! empty( $message_key ) ) {
|
540 |
+
$message = $this->messages[ $message_key ]['translated_text'];
|
541 |
+
}
|
542 |
+
|
543 |
+
// Wrap links around {comment_post_title}
|
544 |
+
$comment_post_ID = isset( $context['comment_post_ID'] ) ? (int) $context['comment_post_ID'] : null;
|
545 |
+
if ( $comment_post_ID ) {
|
546 |
+
$edit_post_link = get_edit_post_link( $comment_post_ID );
|
547 |
+
|
548 |
+
if ( $edit_post_link ) {
|
549 |
+
$message = str_replace(
|
550 |
+
'"{comment_post_title}"',
|
551 |
+
"<a href='{$edit_post_link}'>\"{comment_post_title}\"</a>",
|
552 |
+
$message
|
553 |
+
);
|
554 |
+
}
|
555 |
+
}
|
556 |
+
|
557 |
+
return $this->interpolate( $message, $context, $row );
|
558 |
+
}
|
559 |
+
|
560 |
+
|
561 |
+
/**
|
562 |
+
* Get output for detailed log section
|
563 |
+
*/
|
564 |
+
public function getLogRowDetailsOutput( $row ) {
|
565 |
+
|
566 |
+
$context = $row->context;
|
567 |
+
$message_key = $context['_message_key'];
|
568 |
+
$output = '';
|
569 |
+
// print_r($row);exit;
|
570 |
+
/*
|
571 |
+
if ( 'spam' !== $commentdata['comment_approved'] ) { // If it's spam save it silently for later crunching
|
572 |
+
if ( '0' == $commentdata['comment_approved'] ) { // comment not spam, but not auto-approved
|
573 |
+
wp_notify_moderator( $comment_ID );
|
574 |
+
*/
|
575 |
+
/*
|
576 |
+
if ( isset( $context["comment_approved"] ) && $context["comment_approved"] == '0' ) {
|
577 |
+
$output .= "<br>comment was automatically approved";
|
578 |
+
} else {
|
579 |
+
$output .= "<br>comment was not automatically approved";
|
580 |
+
}*/
|
581 |
+
|
582 |
+
$comment_text = '';
|
583 |
+
if ( isset( $context['comment_content'] ) && $context['comment_content'] ) {
|
584 |
+
$comment_text = $context['comment_content'];
|
585 |
+
$comment_text = wp_trim_words( $comment_text, 20 );
|
586 |
+
$comment_text = wpautop( $comment_text );
|
587 |
+
}
|
588 |
+
|
589 |
+
// Keys to show
|
590 |
+
$arr_plugin_keys = array();
|
591 |
+
$comment_type = isset( $context['comment_type'] ) ? $context['comment_type'] : '';
|
592 |
+
|
593 |
+
switch ( $comment_type ) {
|
594 |
+
case 'trackback':
|
595 |
+
$arr_plugin_keys = array(
|
596 |
+
'trackback_status' => _x( 'Status', 'comments logger - detailed output comment status', 'simple-history' ),
|
597 |
+
// "trackback_type" => _x("Trackback type", "comments logger - detailed output comment type", "simple-history"),
|
598 |
+
'trackback_author' => _x( 'Name', 'comments logger - detailed output author', 'simple-history' ),
|
599 |
+
'trackback_author_email' => _x( 'Email', 'comments logger - detailed output email', 'simple-history' ),
|
600 |
+
'trackback_content' => _x( 'Content', 'comments logger - detailed output content', 'simple-history' ),
|
601 |
+
);
|
602 |
+
|
603 |
+
break;
|
604 |
+
case 'pingback':
|
605 |
+
$arr_plugin_keys = array(
|
606 |
+
'pingback_status' => _x( 'Status', 'comments logger - detailed output comment status', 'simple-history' ),
|
607 |
+
// "pingback_type" => _x("Pingback type", "comments logger - detailed output comment type", "simple-history"),
|
608 |
+
'pingback_author' => _x( 'Name', 'comments logger - detailed output author', 'simple-history' ),
|
609 |
+
'pingback_author_email' => _x( 'Email', 'comments logger - detailed output email', 'simple-history' ),
|
610 |
+
'pingback_content' => _x( 'Content', 'comments logger - detailed output content', 'simple-history' ),
|
611 |
+
|
612 |
+
);
|
613 |
+
|
614 |
+
break;
|
615 |
+
case 'comment':
|
616 |
+
default:
|
617 |
+
$arr_plugin_keys = array(
|
618 |
+
'comment_status' => _x( 'Status', 'comments logger - detailed output comment status', 'simple-history' ),
|
619 |
+
// "comment_type" => _x("Comment type", "comments logger - detailed output comment type", "simple-history"),
|
620 |
+
'comment_author' => _x( 'Name', 'comments logger - detailed output author', 'simple-history' ),
|
621 |
+
'comment_author_email' => _x( 'Email', 'comments logger - detailed output email', 'simple-history' ),
|
622 |
+
'comment_content' => _x( 'Comment', 'comments logger - detailed output content', 'simple-history' ),
|
623 |
+
);
|
624 |
+
|
625 |
+
break;
|
626 |
+
|
627 |
+
// "comment_author_url" => _x("Author URL", "comments logger - detailed output author", "simple-history"),
|
628 |
+
// "comment_author_IP" => _x("IP number", "comments logger - detailed output IP", "simple-history"),
|
629 |
+
}// End switch().
|
630 |
+
|
631 |
+
$arr_plugin_keys = apply_filters( 'simple_history/comments_logger/row_details_plugin_info_keys', $arr_plugin_keys );
|
632 |
+
|
633 |
+
// Start output of plugin meta data table
|
634 |
+
$output .= "<table class='SimpleHistoryLogitem__keyValueTable'>";
|
635 |
+
|
636 |
+
foreach ( $arr_plugin_keys as $key => $desc ) {
|
637 |
+
switch ( $key ) {
|
638 |
+
case 'comment_content':
|
639 |
+
case 'trackback_content':
|
640 |
+
case 'pingback_content':
|
641 |
+
$desc_output = $comment_text;
|
642 |
+
break;
|
643 |
+
|
644 |
+
case 'comment_author':
|
645 |
+
case 'trackback_author':
|
646 |
+
case 'pingback_author':
|
647 |
+
$desc_output = '';
|
648 |
+
|
649 |
+
if ( isset( $context[ $key ] ) ) {
|
650 |
+
$desc_output .= esc_html( $context[ $key ] );
|
651 |
+
}
|
652 |
+
|
653 |
+
/*
|
654 |
+
if ( isset( $context["comment_author_email"] ) ) {
|
655 |
+
|
656 |
+
$gravatar_email = $context["comment_author_email"];
|
657 |
+
$avatar = $this->simpleHistory->get_avatar( $gravatar_email, 14, "blank" );
|
658 |
+
$desc_output .= "<span class='SimpleCommentsLogger__gravatar'>{$avatar}</span>";
|
659 |
+
|
660 |
+
}
|
661 |
+
*/
|
662 |
+
|
663 |
+
break;
|
664 |
+
|
665 |
+
case 'comment_status':
|
666 |
+
case 'trackback_status':
|
667 |
+
case 'pingback_status':
|
668 |
+
if ( isset( $context['comment_approved'] ) ) {
|
669 |
+
if ( $context['comment_approved'] === 'spam' ) {
|
670 |
+
$desc_output = __( 'Spam', 'simple-history' );
|
671 |
+
} elseif ( $context['comment_approved'] == 1 ) {
|
672 |
+
$desc_output = __( 'Approved', 'simple-history' );
|
673 |
+
} elseif ( $context['comment_approved'] == 0 ) {
|
674 |
+
$desc_output = __( 'Pending', 'simple-history' );
|
675 |
+
}
|
676 |
+
}
|
677 |
+
|
678 |
+
break;
|
679 |
+
|
680 |
+
case 'comment_type':
|
681 |
+
case 'trackback_type':
|
682 |
+
case 'pingback_type':
|
683 |
+
if ( isset( $context['comment_type'] ) ) {
|
684 |
+
if ( $context['comment_type'] === 'trackback' ) {
|
685 |
+
$desc_output = __( 'Trackback', 'simple-history' );
|
686 |
+
} elseif ( $context['comment_type'] === 'pingback' ) {
|
687 |
+
$desc_output = __( 'Pingback', 'simple-history' );
|
688 |
+
} elseif ( $context['comment_type'] === 'comment' ) {
|
689 |
+
$desc_output = __( 'Comment', 'simple-history' );
|
690 |
+
} else {
|
691 |
+
$desc_output = '';
|
692 |
+
}
|
693 |
+
}
|
694 |
+
|
695 |
+
break;
|
696 |
+
|
697 |
+
default:
|
698 |
+
if ( isset( $context[ $key ] ) ) {
|
699 |
+
$desc_output = esc_html( $context[ $key ] );
|
700 |
+
}
|
701 |
+
|
702 |
+
break;
|
703 |
+
}// End switch().
|
704 |
+
|
705 |
+
// Skip empty rows
|
706 |
+
if ( empty( $desc_output ) ) {
|
707 |
+
continue;
|
708 |
+
}
|
709 |
+
|
710 |
+
$output .= sprintf(
|
711 |
+
'
|
|
|
|
|
|
|
|
|
712 |
<tr>
|
713 |
<td>%1$s</td>
|
714 |
<td>%2$s</td>
|
715 |
</tr>
|
716 |
',
|
717 |
+
esc_html( $desc ),
|
718 |
+
$desc_output
|
719 |
+
);
|
720 |
+
}// End foreach().
|
721 |
+
|
722 |
+
// Add link to edit comment
|
723 |
+
$comment_ID = isset( $context['comment_ID'] ) && is_numeric( $context['comment_ID'] ) ? (int) $context['comment_ID'] : false;
|
724 |
+
|
725 |
+
if ( $comment_ID ) {
|
726 |
+
$comment = get_comment( $comment_ID );
|
727 |
+
|
728 |
+
if ( $comment ) {
|
729 |
+
// http://site.local/wp/wp-admin/comment.php?action=editcomment&c=
|
730 |
+
$edit_comment_link = get_edit_comment_link( $comment_ID );
|
731 |
+
|
732 |
+
// Edit link sometimes does not contain comment ID
|
733 |
+
// Probably because comment has been removed or something
|
734 |
+
// So only continue if link does not end with "=""
|
735 |
+
if ( $edit_comment_link && $edit_comment_link[ strlen( $edit_comment_link ) - 1 ] !== '=' ) {
|
736 |
+
$output .= sprintf(
|
737 |
+
'
|
738 |
<tr>
|
739 |
<td></td>
|
740 |
<td><a href="%2$s">%1$s</a></td>
|
741 |
</tr>
|
742 |
',
|
743 |
+
_x( 'View/Edit', 'comments logger - edit comment', 'simple-history' ),
|
744 |
+
$edit_comment_link
|
745 |
+
);
|
746 |
+
}
|
747 |
+
}
|
748 |
+
} // End if().
|
749 |
+
|
750 |
+
// End table
|
751 |
+
$output .= '</table>';
|
752 |
+
|
753 |
+
return $output;
|
754 |
+
}
|
755 |
+
|
756 |
+
public function adminCSS() {
|
757 |
+
?>
|
758 |
+
<style>
|
759 |
+
.SimpleCommentsLogger__gravatar {
|
760 |
+
line-height: 1;
|
761 |
+
border-radius: 50%;
|
762 |
+
overflow: hidden;
|
763 |
+
margin-right: .5em;
|
764 |
+
margin-left: .5em;
|
765 |
+
display: inline-block;
|
766 |
+
}
|
767 |
+
.SimpleCommentsLogger__gravatar img {
|
768 |
+
display: block;
|
769 |
+
}
|
770 |
+
</style>
|
771 |
+
<?php
|
772 |
+
}
|
|
|
773 |
}
|
loggers/SimpleCoreUpdatesLogger.php
CHANGED
@@ -1,116 +1,111 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
-
'prev_version' => $old_wp_version,
|
112 |
-
'new_version' => $new_wp_version,
|
113 |
-
)
|
114 |
-
);
|
115 |
-
}
|
116 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || 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 |
+
add_action( '_core_updated_successfully', array( $this, 'on_core_updated' ) );
|
16 |
+
add_action( 'update_feedback', array( $this, 'on_update_feedback' ) );
|
17 |
+
|
18 |
+
// Can't log db updates at the moment, because loaded() is not called yet when the action fires
|
19 |
+
// add_action( 'wp_upgrade', array( $this, "on_wp_upgrade" ), 10, 2 );
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Fires after a site is fully upgraded.
|
24 |
+
* The database, that is.
|
25 |
+
*
|
26 |
+
* @param int $wp_db_version The new $wp_db_version.
|
27 |
+
* @param int $wp_current_db_version The old (current) $wp_db_version.
|
28 |
+
*/
|
29 |
+
public function on_wp_upgrade( $wp_db_version, $wp_current_db_version ) {
|
30 |
+
|
31 |
+
$this->debugMessage(
|
32 |
+
'core_db_version_updated',
|
33 |
+
array(
|
34 |
+
'new_version' => $wp_db_version,
|
35 |
+
'prev_version' => $wp_current_db_version,
|
36 |
+
)
|
37 |
+
);
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* We need to store the WordPress version we are updating from.
|
42 |
+
* 'update_feedback' is a suitable filter.
|
43 |
+
*/
|
44 |
+
public function on_update_feedback() {
|
45 |
+
|
46 |
+
if ( ! empty( $GLOBALS['wp_version'] ) && ! isset( $GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ] ) ) {
|
47 |
+
$GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ] = $GLOBALS['wp_version'];
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Get array with information about this logger
|
53 |
+
*
|
54 |
+
* @return array
|
55 |
+
*/
|
56 |
+
public function getInfo() {
|
57 |
+
|
58 |
+
$arr_info = array(
|
59 |
+
'name' => 'Core Updates Logger',
|
60 |
+
'description' => 'Logs the update of WordPress (manual and automatic updates)',
|
61 |
+
'capability' => 'update_core',
|
62 |
+
'messages' => array(
|
63 |
+
'core_updated' => __( 'Updated WordPress to {new_version} from {prev_version}', 'simple-history' ),
|
64 |
+
'core_auto_updated' => __( 'WordPress auto-updated to {new_version} from {prev_version}', 'simple-history' ),
|
65 |
+
'core_db_version_updated' => __( 'WordPress database version updated to {new_version} from {prev_version}', 'simple-history' ),
|
66 |
+
),
|
67 |
+
'labels' => array(
|
68 |
+
'search' => array(
|
69 |
+
'label' => _x( 'WordPress Core', 'User logger: search', 'simple-history' ),
|
70 |
+
'options' => array(
|
71 |
+
_x( 'WordPress core updates', 'User logger: search', 'simple-history' ) => array(
|
72 |
+
'core_updated',
|
73 |
+
'core_auto_updated',
|
74 |
+
),
|
75 |
+
),
|
76 |
+
), // end search array
|
77 |
+
), // end labels
|
78 |
+
);
|
79 |
+
|
80 |
+
return $arr_info;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Called when WordPress is updated
|
85 |
+
*
|
86 |
+
* @param string $new_wp_version
|
87 |
+
*/
|
88 |
+
public function on_core_updated( $new_wp_version ) {
|
89 |
+
|
90 |
+
$old_wp_version = empty( $GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ] ) ? $GLOBALS['wp_version'] : $GLOBALS[ 'simple_history_' . $this->slug . '_wp_version' ];
|
91 |
+
|
92 |
+
$auto_update = true;
|
93 |
+
if ( $GLOBALS['pagenow'] == 'update-core.php' ) {
|
94 |
+
$auto_update = false;
|
95 |
+
}
|
96 |
+
|
97 |
+
if ( $auto_update ) {
|
98 |
+
$message = 'core_auto_updated';
|
99 |
+
} else {
|
100 |
+
$message = 'core_updated';
|
101 |
+
}
|
102 |
+
|
103 |
+
$this->noticeMessage(
|
104 |
+
$message,
|
105 |
+
array(
|
106 |
+
'prev_version' => $old_wp_version,
|
107 |
+
'new_version' => $new_wp_version,
|
108 |
+
)
|
109 |
+
);
|
110 |
+
}
|
|
|
|
|
|
|
|
|
|
|
111 |
}
|
loggers/SimpleExportLogger.php
CHANGED
@@ -1,56 +1,53 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
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 |
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* Logs WordPress exports
|
7 |
*/
|
8 |
+
class SimpleExportLogger extends SimpleLogger {
|
9 |
+
|
10 |
+
public $slug = __CLASS__;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Get array with information about this logger
|
14 |
+
*
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
public function getInfo() {
|
18 |
+
$arr_info = array(
|
19 |
+
'name' => __( 'Export Logger', 'simple-history' ),
|
20 |
+
'description' => __( 'Logs updates to WordPress export', 'simple-history' ),
|
21 |
+
'capability' => 'export',
|
22 |
+
'messages' => array(
|
23 |
+
'created_export' => __( 'Created XML export', 'simple-history' ),
|
24 |
+
),
|
25 |
+
'labels' => array(
|
26 |
+
'search' => array(
|
27 |
+
'label' => _x( 'Export', 'Export logger: search', 'simple-history' ),
|
28 |
+
'options' => array(
|
29 |
+
_x( 'Created exports', 'Export logger: search', 'simple-history' ) => array(
|
30 |
+
'created_export',
|
31 |
+
),
|
32 |
+
),
|
33 |
+
), // end search array
|
34 |
+
), // end labels
|
35 |
+
);
|
36 |
+
|
37 |
+
return $arr_info;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function loaded() {
|
41 |
+
|
42 |
+
add_action( 'export_wp', array( $this, 'on_export_wp' ), 10, 1 );
|
43 |
+
}
|
44 |
+
|
45 |
+
public function on_export_wp( $args ) {
|
46 |
+
$this->infoMessage(
|
47 |
+
'created_export',
|
48 |
+
array(
|
49 |
+
'args' => $this->simpleHistory->json_encode( $args ),
|
50 |
+
)
|
51 |
+
);
|
52 |
+
}
|
|
|
|
|
|
|
53 |
}
|
loggers/SimpleLegacyLogger.php
DELETED
@@ -1,104 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
defined('ABSPATH') or die();
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Logger for events stored earlier than v2
|
7 |
-
* and for events added via simple_history_add
|
8 |
-
*
|
9 |
-
* @since 2.0
|
10 |
-
*/
|
11 |
-
class SimpleLegacyLogger extends SimpleLogger
|
12 |
-
{
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Unique slug for this logger
|
16 |
-
* Will be saved in DB and used to associate each log row with its logger
|
17 |
-
*/
|
18 |
-
public $slug = 'SimpleLegacyLogger';
|
19 |
-
|
20 |
-
public function __construct()
|
21 |
-
{
|
22 |
-
|
23 |
-
// $this->info(__CLASS__ . " construct()");
|
24 |
-
}
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Get array with information about this logger
|
28 |
-
*
|
29 |
-
* @return array
|
30 |
-
*/
|
31 |
-
public function getInfo()
|
32 |
-
{
|
33 |
-
|
34 |
-
$arr_info = array(
|
35 |
-
'name' => 'Legacy Logger',
|
36 |
-
'description' => 'Formats old events',
|
37 |
-
'capability' => 'edit_pages',
|
38 |
-
'messages' => array(),
|
39 |
-
/*
|
40 |
-
"labels" => array(
|
41 |
-
"search" => array(
|
42 |
-
"label" => _x("Export", "Export logger: search", "simple-history"),
|
43 |
-
"options" => array(
|
44 |
-
_x("Exports created", "Core updates logger: search", "simple-history") => array(
|
45 |
-
"created_export"
|
46 |
-
),
|
47 |
-
)
|
48 |
-
) // end search array
|
49 |
-
) // end labels
|
50 |
-
*/
|
51 |
-
|
52 |
-
);
|
53 |
-
|
54 |
-
return $arr_info;
|
55 |
-
}
|
56 |
-
|
57 |
-
public function getLogRowPlainTextOutput($row)
|
58 |
-
{
|
59 |
-
|
60 |
-
$message = $row->message;
|
61 |
-
$context = $row->context;
|
62 |
-
|
63 |
-
$out = '';
|
64 |
-
|
65 |
-
global $wpdb;
|
66 |
-
|
67 |
-
// Get old columns for this event
|
68 |
-
$sql = sprintf(
|
69 |
-
'
|
70 |
-
SELECT * FROM %1$s
|
71 |
-
WHERE id = %2$d
|
72 |
-
',
|
73 |
-
$wpdb->prefix . SimpleHistory::DBTABLE,
|
74 |
-
$row->id
|
75 |
-
);
|
76 |
-
|
77 |
-
$one_item = $wpdb->get_row($sql);
|
78 |
-
|
79 |
-
// $out .= print_r($row, true);
|
80 |
-
// Code mostly from version 1.x
|
81 |
-
$object_type = ucwords($one_item->object_type);
|
82 |
-
$object_name = esc_html($one_item->object_name);
|
83 |
-
$user = get_user_by('id', $one_item->user_id);
|
84 |
-
$user_nicename = esc_html(@$user->user_nicename);
|
85 |
-
$user_email = esc_html(@$user->user_email);
|
86 |
-
$description = '';
|
87 |
-
|
88 |
-
if ($user_nicename) {
|
89 |
-
$description .= sprintf(__('By %s', 'simple-history'), $user_nicename);
|
90 |
-
}
|
91 |
-
|
92 |
-
if (isset($one_item->occasions)) {
|
93 |
-
$description .= sprintf(__('%d occasions', 'simple-history'), sizeof($one_item->occasions));
|
94 |
-
}
|
95 |
-
|
96 |
-
$item_title = esc_html($object_type) . ' "' . esc_html($object_name) . "\" {$one_item->action}";
|
97 |
-
$item_title = html_entity_decode($item_title, ENT_COMPAT, 'UTF-8');
|
98 |
-
|
99 |
-
$out .= "$item_title";
|
100 |
-
$out .= "<br>$description";
|
101 |
-
|
102 |
-
return $out;
|
103 |
-
}
|
104 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
loggers/SimpleLogger.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
defined('ABSPATH')
|
4 |
|
5 |
/**
|
6 |
* A PSR-3 inspired logger class
|
@@ -10,1726 +10,1690 @@ defined('ABSPATH') or die();
|
|
10 |
*
|
11 |
* @link https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md PSR-3 specification
|
12 |
*/
|
13 |
-
class SimpleLogger
|
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 |
-
if ($use_you && $is_current_user) {
|
245 |
-
$tmpl_initiator_html = '
|
246 |
<a href="%6$s" class="SimpleHistoryLogitem__headerUserProfileLink">
|
247 |
<strong class="SimpleHistoryLogitem__inlineDivided">%5$s</strong>
|
248 |
</a>
|
249 |
';
|
250 |
-
|
251 |
-
|
252 |
<a href="%6$s" class="SimpleHistoryLogitem__headerUserProfileLink">
|
253 |
<strong class="SimpleHistoryLogitem__inlineDivided">%3$s</strong>
|
254 |
<span class="SimpleHistoryLogitem__inlineDivided SimpleHistoryLogitem__headerEmail">%2$s</span>
|
255 |
</a>
|
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 |
-
$ip_address_html = $this->getLogRowHeaderIPAddressOutput($row);
|
667 |
-
|
668 |
-
// Template to combine header parts.
|
669 |
-
$template = '
|
670 |
%1$s
|
671 |
%2$s
|
672 |
%3$s
|
673 |
%4$s
|
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 |
-
* thumbnail of that image can bo outputed here
|
839 |
-
*
|
840 |
-
* @param object $row
|
841 |
-
* @return string HTML-formatted output
|
842 |
-
*/
|
843 |
-
public function getLogRowDetailsOutput($row)
|
844 |
-
{
|
845 |
-
$html = '';
|
846 |
-
|
847 |
-
/**
|
848 |
-
* Filter generated output for details
|
849 |
-
*
|
850 |
-
* @since 2.0
|
851 |
-
*
|
852 |
-
* @param string $html
|
853 |
-
* @param object $row Log row
|
854 |
-
*/
|
855 |
-
$html = apply_filters('simple_history/row_details_output', $html, $row);
|
856 |
-
|
857 |
-
return $html;
|
858 |
-
}
|
859 |
-
|
860 |
-
/**
|
861 |
-
* System is unusable.
|
862 |
-
*
|
863 |
-
* @param string $message
|
864 |
-
* @param array $context
|
865 |
-
* @return null
|
866 |
-
*/
|
867 |
-
public function emergency($message, array $context = array())
|
868 |
-
{
|
869 |
-
return $this->log(SimpleLoggerLogLevels::EMERGENCY, $message, $context);
|
870 |
-
}
|
871 |
-
|
872 |
-
/**
|
873 |
-
* System is unusable.
|
874 |
-
*
|
875 |
-
* @param string $message key from getInfo messages array
|
876 |
-
* @param array $context
|
877 |
-
* @return null
|
878 |
-
*/
|
879 |
-
public function emergencyMessage($message, array $context = array())
|
880 |
-
{
|
881 |
-
return $this->logByMessageKey(
|
882 |
-
SimpleLoggerLogLevels::EMERGENCY,
|
883 |
-
$message,
|
884 |
-
$context
|
885 |
-
);
|
886 |
-
}
|
887 |
-
|
888 |
-
/**
|
889 |
-
* Log with message
|
890 |
-
* Called from infoMessage(), errorMessage(), and so on
|
891 |
-
*
|
892 |
-
* Call like this:
|
893 |
-
*
|
894 |
-
* return $this->logByMessageKey(SimpleLoggerLogLevels::EMERGENCY, $message, $context);
|
895 |
-
*/
|
896 |
-
private function logByMessageKey(
|
897 |
-
$SimpleLoggerLogLevelsLevel,
|
898 |
-
$messageKey,
|
899 |
-
$context
|
900 |
-
) {
|
901 |
-
// When logging by message then the key must exist
|
902 |
-
if (!isset($this->messages[$messageKey]['untranslated_text'])) {
|
903 |
-
return;
|
904 |
-
}
|
905 |
-
|
906 |
-
/**
|
907 |
-
* Filter so plugins etc. can shortut logging
|
908 |
-
*
|
909 |
-
* @since 2.0.20
|
910 |
-
*
|
911 |
-
* @param true yes, we default to do the logging
|
912 |
-
* @param string logger slug
|
913 |
-
* @param string messageKey
|
914 |
-
* @param string log level
|
915 |
-
* @param array context
|
916 |
-
* @return bool false to abort logging
|
917 |
-
*/
|
918 |
-
$doLog = apply_filters(
|
919 |
-
'simple_history/simple_logger/log_message_key',
|
920 |
-
true,
|
921 |
-
$this->slug,
|
922 |
-
$messageKey,
|
923 |
-
$SimpleLoggerLogLevelsLevel,
|
924 |
-
$context
|
925 |
-
);
|
926 |
-
|
927 |
-
if (!$doLog) {
|
928 |
-
return;
|
929 |
-
}
|
930 |
-
|
931 |
-
$context['_message_key'] = $messageKey;
|
932 |
-
$message = $this->messages[$messageKey]['untranslated_text'];
|
933 |
-
|
934 |
-
$this->log($SimpleLoggerLogLevelsLevel, $message, $context);
|
935 |
-
}
|
936 |
-
|
937 |
-
/**
|
938 |
-
* Action must be taken immediately.
|
939 |
-
*
|
940 |
-
* @param string $message
|
941 |
-
* @param array $context
|
942 |
-
* @return null
|
943 |
-
*/
|
944 |
-
public function alert($message, array $context = array())
|
945 |
-
{
|
946 |
-
return $this->log(SimpleLoggerLogLevels::ALERT, $message, $context);
|
947 |
-
}
|
948 |
-
|
949 |
-
/**
|
950 |
-
* Action must be taken immediately.
|
951 |
-
*
|
952 |
-
* @param string $message key from getInfo messages array
|
953 |
-
* @param array $context
|
954 |
-
* @return null
|
955 |
-
*/
|
956 |
-
public function alertMessage($message, array $context = array())
|
957 |
-
{
|
958 |
-
return $this->logByMessageKey(
|
959 |
-
SimpleLoggerLogLevels::ALERT,
|
960 |
-
$message,
|
961 |
-
$context
|
962 |
-
);
|
963 |
-
}
|
964 |
-
|
965 |
-
/**
|
966 |
-
* Critical conditions.
|
967 |
-
*
|
968 |
-
* Example: Application component unavailable, unexpected exception.
|
969 |
-
*
|
970 |
-
* @param string $message
|
971 |
-
* @param array $context
|
972 |
-
* @return null
|
973 |
-
*/
|
974 |
-
public function critical($message, array $context = array())
|
975 |
-
{
|
976 |
-
return $this->log(SimpleLoggerLogLevels::CRITICAL, $message, $context);
|
977 |
-
}
|
978 |
-
|
979 |
-
/**
|
980 |
-
* Critical conditions.
|
981 |
-
*
|
982 |
-
* @param string $message key from getInfo messages array
|
983 |
-
* @param array $context
|
984 |
-
* @return null
|
985 |
-
*/
|
986 |
-
public function criticalMessage($message, array $context = array())
|
987 |
-
{
|
988 |
-
if (!isset($this->messages[$message]['untranslated_text'])) {
|
989 |
-
return;
|
990 |
-
}
|
991 |
-
|
992 |
-
$context['_message_key'] = $message;
|
993 |
-
$message = $this->messages[$message]['untranslated_text'];
|
994 |
-
|
995 |
-
$this->log(SimpleLoggerLogLevels::CRITICAL, $message, $context);
|
996 |
-
}
|
997 |
-
|
998 |
-
/**
|
999 |
-
* Runtime errors that do not require immediate action but should typically
|
1000 |
-
* be logged and monitored.
|
1001 |
-
*
|
1002 |
-
* @param string $message
|
1003 |
-
* @param array $context
|
1004 |
-
* @return null
|
1005 |
-
*/
|
1006 |
-
public function error($message, array $context = array())
|
1007 |
-
{
|
1008 |
-
return $this->log(SimpleLoggerLogLevels::ERROR, $message, $context);
|
1009 |
-
}
|
1010 |
-
|
1011 |
-
/**
|
1012 |
-
* Runtime errors that do not require immediate action but should typically
|
1013 |
-
* be logged and monitored.
|
1014 |
-
*
|
1015 |
-
* @param string $message key from getInfo messages array
|
1016 |
-
* @param array $context
|
1017 |
-
* @return null
|
1018 |
-
*/
|
1019 |
-
public function errorMessage($message, array $context = array())
|
1020 |
-
{
|
1021 |
-
return $this->logByMessageKey(
|
1022 |
-
SimpleLoggerLogLevels::ERROR,
|
1023 |
-
$message,
|
1024 |
-
$context
|
1025 |
-
);
|
1026 |
-
}
|
1027 |
-
|
1028 |
-
/**
|
1029 |
-
* Exceptional occurrences that are not errors.
|
1030 |
-
*
|
1031 |
-
* Example: Use of deprecated APIs, poor use of an API, undesirable things
|
1032 |
-
* that are not necessarily wrong.
|
1033 |
-
*
|
1034 |
-
* @param string $message
|
1035 |
-
* @param array $context
|
1036 |
-
* @return null
|
1037 |
-
*/
|
1038 |
-
public function warning($message, array $context = array())
|
1039 |
-
{
|
1040 |
-
return $this->log(SimpleLoggerLogLevels::WARNING, $message, $context);
|
1041 |
-
}
|
1042 |
-
|
1043 |
-
/**
|
1044 |
-
* Exceptional occurrences that are not errors.
|
1045 |
-
*
|
1046 |
-
* @param string $message key from getInfo messages array
|
1047 |
-
* @param array $context
|
1048 |
-
* @return null
|
1049 |
-
*/
|
1050 |
-
public function warningMessage($message, array $context = array())
|
1051 |
-
{
|
1052 |
-
return $this->logByMessageKey(
|
1053 |
-
SimpleLoggerLogLevels::WARNING,
|
1054 |
-
$message,
|
1055 |
-
$context
|
1056 |
-
);
|
1057 |
-
}
|
1058 |
-
|
1059 |
-
/**
|
1060 |
-
* Normal but significant events.
|
1061 |
-
*
|
1062 |
-
* @param string $message
|
1063 |
-
* @param array $context
|
1064 |
-
* @return null
|
1065 |
-
*/
|
1066 |
-
public function notice($message, array $context = array())
|
1067 |
-
{
|
1068 |
-
return $this->log(SimpleLoggerLogLevels::NOTICE, $message, $context);
|
1069 |
-
}
|
1070 |
-
|
1071 |
-
/**
|
1072 |
-
* Normal but significant events.
|
1073 |
-
*
|
1074 |
-
* @param string $message key from getInfo messages array
|
1075 |
-
* @param array $context
|
1076 |
-
* @return null
|
1077 |
-
*/
|
1078 |
-
public function noticeMessage($message, array $context = array())
|
1079 |
-
{
|
1080 |
-
return $this->logByMessageKey(
|
1081 |
-
SimpleLoggerLogLevels::NOTICE,
|
1082 |
-
$message,
|
1083 |
-
$context
|
1084 |
-
);
|
1085 |
-
}
|
1086 |
-
|
1087 |
-
/**
|
1088 |
-
* Interesting events.
|
1089 |
-
*
|
1090 |
-
* Example: User logs in, SQL logs.
|
1091 |
-
*
|
1092 |
-
* @param string $message
|
1093 |
-
* @param array $context
|
1094 |
-
* @return null
|
1095 |
-
*/
|
1096 |
-
public function info($message, array $context = array())
|
1097 |
-
{
|
1098 |
-
return $this->log(SimpleLoggerLogLevels::INFO, $message, $context);
|
1099 |
-
}
|
1100 |
-
|
1101 |
-
/**
|
1102 |
-
* Interesting events.
|
1103 |
-
*
|
1104 |
-
* Example: User logs in, SQL logs.
|
1105 |
-
*
|
1106 |
-
* @param string $message key from getInfo messages array
|
1107 |
-
* @param array $context
|
1108 |
-
* @return null
|
1109 |
-
*/
|
1110 |
-
public function infoMessage($message, array $context = array())
|
1111 |
-
{
|
1112 |
-
return $this->logByMessageKey(
|
1113 |
-
SimpleLoggerLogLevels::INFO,
|
1114 |
-
$message,
|
1115 |
-
$context
|
1116 |
-
);
|
1117 |
-
}
|
1118 |
-
|
1119 |
-
/**
|
1120 |
-
* Detailed debug information.
|
1121 |
-
*
|
1122 |
-
* @param string $message
|
1123 |
-
* @param array $context
|
1124 |
-
* @return null
|
1125 |
-
*/
|
1126 |
-
public function debug($message, array $context = array())
|
1127 |
-
{
|
1128 |
-
return $this->log(SimpleLoggerLogLevels::DEBUG, $message, $context);
|
1129 |
-
}
|
1130 |
-
|
1131 |
-
/**
|
1132 |
-
* Detailed debug information.
|
1133 |
-
*
|
1134 |
-
* @param string $message key from getInfo messages array
|
1135 |
-
* @param array $context
|
1136 |
-
* @return null
|
1137 |
-
*/
|
1138 |
-
public function debugMessage($message, array $context = array())
|
1139 |
-
{
|
1140 |
-
return $this->logByMessageKey(
|
1141 |
-
SimpleLoggerLogLevels::DEBUG,
|
1142 |
-
$message,
|
1143 |
-
$context
|
1144 |
-
);
|
1145 |
-
}
|
1146 |
-
|
1147 |
-
/**
|
1148 |
-
* Logs with an arbitrary level.
|
1149 |
-
*
|
1150 |
-
* @param mixed $level The log level. Default "info".
|
1151 |
-
* @param string $message The log message. Default "".
|
1152 |
-
* @param array $context The log context. Default empty array.
|
1153 |
-
* @return class SimpleLogger instance
|
1154 |
-
*/
|
1155 |
-
public function log($level = 'info', $message = '', $context = array())
|
1156 |
-
{
|
1157 |
-
global $wpdb;
|
1158 |
-
|
1159 |
-
// Check that passed args are of correct types.
|
1160 |
-
if (!is_string($level) || !is_string($message)) {
|
1161 |
-
return $this;
|
1162 |
-
}
|
1163 |
-
|
1164 |
-
// Context must be array, but can be passed as null and so on.
|
1165 |
-
if (!is_array($context)) {
|
1166 |
-
$context = array();
|
1167 |
-
}
|
1168 |
-
|
1169 |
-
// Don't go on if message is empty.
|
1170 |
-
if (empty($message)) {
|
1171 |
-
return $this;
|
1172 |
-
}
|
1173 |
-
|
1174 |
-
/**
|
1175 |
-
* Filter that makes it possible to shortcut this log.
|
1176 |
-
* Return bool false to cancel.
|
1177 |
-
*
|
1178 |
-
* @since 2.3.1
|
1179 |
-
*/
|
1180 |
-
$do_log = apply_filters(
|
1181 |
-
'simple_history/log/do_log',
|
1182 |
-
true,
|
1183 |
-
$level,
|
1184 |
-
$message,
|
1185 |
-
$context,
|
1186 |
-
$this
|
1187 |
-
);
|
1188 |
-
if (false === $do_log) {
|
1189 |
-
return $this;
|
1190 |
-
}
|
1191 |
-
|
1192 |
-
/**
|
1193 |
-
* Easy shortcut method to disable logging of messages from
|
1194 |
-
* a specific logger.
|
1195 |
-
*
|
1196 |
-
* Example filter name:
|
1197 |
-
* simple_history/log/do_log/SimpleUserLogger
|
1198 |
-
* simple_history/log/do_log/SimplePostLogger
|
1199 |
-
*
|
1200 |
-
* Example to disable logging of any user login/logout/failed login activity:
|
1201 |
-
* add_filter('simple_history/log/do_log/SimpleUserLogger', '__return_false')
|
1202 |
-
*
|
1203 |
-
* @since 2.nn
|
1204 |
-
*/
|
1205 |
-
$do_log = apply_filters(
|
1206 |
-
"simple_history/log/do_log/{$this->slug}",
|
1207 |
-
true
|
1208 |
-
);
|
1209 |
-
if (false === $do_log) {
|
1210 |
-
return $this;
|
1211 |
-
}
|
1212 |
-
|
1213 |
-
/**
|
1214 |
-
* Easy shortcut method to disable logging of messages from
|
1215 |
-
* a specific logger and message.
|
1216 |
-
*
|
1217 |
-
* Example filter name:
|
1218 |
-
* simple_history/log/do_log/SimpleUserLogger/user_logged_in
|
1219 |
-
* simple_history/log/do_log/SimplePostLogger/post_updated
|
1220 |
-
*
|
1221 |
-
* @since 2.nn
|
1222 |
-
*/
|
1223 |
-
$message_key = isset($context['_message_key'])
|
1224 |
-
? $context['_message_key']
|
1225 |
-
: null;
|
1226 |
-
$do_log = apply_filters(
|
1227 |
-
"simple_history/log/do_log/{$this->slug}/{$message_key}",
|
1228 |
-
true
|
1229 |
-
);
|
1230 |
-
if (false === $do_log) {
|
1231 |
-
return $this;
|
1232 |
-
}
|
1233 |
-
|
1234 |
-
// Check if $message is a translated message, and if so then fetch original
|
1235 |
-
$sh_latest_translations =
|
1236 |
-
$this->simpleHistory->gettextLatestTranslations;
|
1237 |
-
|
1238 |
-
if (!empty($sh_latest_translations)) {
|
1239 |
-
if (isset($sh_latest_translations[$message])) {
|
1240 |
-
// Translation of this phrase was found, so use original phrase instead of translated one
|
1241 |
-
// Store textdomain since it's required to translate
|
1242 |
-
$context['_gettext_domain'] =
|
1243 |
-
$sh_latest_translations[$message]['domain'];
|
1244 |
-
|
1245 |
-
// These are good to keep when debugging
|
1246 |
-
// $context["_gettext_org_message"] = $sh_latest_translations[$message]["text"];
|
1247 |
-
// $context["_gettext_translated_message"] = $sh_latest_translations[$message]["translation"];
|
1248 |
-
$message = $sh_latest_translations[$message]['text'];
|
1249 |
-
}
|
1250 |
-
}
|
1251 |
-
|
1252 |
-
/**
|
1253 |
-
* Filter arguments passed to log funtion
|
1254 |
-
*
|
1255 |
-
* @since 2.0
|
1256 |
-
*
|
1257 |
-
* @param string $level
|
1258 |
-
* @param string $message
|
1259 |
-
* @param array $context
|
1260 |
-
* @param object SimpleLogger object
|
1261 |
-
*/
|
1262 |
-
apply_filters(
|
1263 |
-
'simple_history/log_arguments',
|
1264 |
-
$level,
|
1265 |
-
$message,
|
1266 |
-
$context,
|
1267 |
-
$this
|
1268 |
-
);
|
1269 |
-
$context = apply_filters(
|
1270 |
-
'simple_history/log_argument/context',
|
1271 |
-
$context,
|
1272 |
-
$level,
|
1273 |
-
$message,
|
1274 |
-
$this
|
1275 |
-
);
|
1276 |
-
$level = apply_filters(
|
1277 |
-
'simple_history/log_argument/level',
|
1278 |
-
$level,
|
1279 |
-
$context,
|
1280 |
-
$message,
|
1281 |
-
$this
|
1282 |
-
);
|
1283 |
-
$message = apply_filters(
|
1284 |
-
'simple_history/log_argument/message',
|
1285 |
-
$message,
|
1286 |
-
$level,
|
1287 |
-
$context,
|
1288 |
-
$this
|
1289 |
-
);
|
1290 |
-
|
1291 |
-
/*
|
1292 |
-
Store date as GMT date, i.e. not local date/time
|
1293 |
-
* Some info here:
|
1294 |
-
* http://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/
|
1295 |
-
*/
|
1296 |
-
$localtime = current_time('mysql', 1);
|
1297 |
-
|
1298 |
-
$db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
1299 |
-
|
1300 |
-
/**
|
1301 |
-
* Filter db table used for simple history events
|
1302 |
-
*
|
1303 |
-
* @since 2.0
|
1304 |
-
*
|
1305 |
-
* @param string $db_table
|
1306 |
-
*/
|
1307 |
-
$db_table = apply_filters('simple_history/db_table', $db_table);
|
1308 |
-
|
1309 |
-
$data = array(
|
1310 |
-
'logger' => $this->slug,
|
1311 |
-
'level' => $level,
|
1312 |
-
'date' => $localtime,
|
1313 |
-
'message' => $message
|
1314 |
-
);
|
1315 |
-
|
1316 |
-
// Allow date to be overriden.
|
1317 |
-
// Date must be in format 'Y-m-d H:i:s'.
|
1318 |
-
if (isset($context['_date'])) {
|
1319 |
-
$data['date'] = $context['_date'];
|
1320 |
-
unset($context['_date']);
|
1321 |
-
}
|
1322 |
-
|
1323 |
-
// Add occasions id.
|
1324 |
-
$occasions_id = null;
|
1325 |
-
if (isset($context['_occasionsID'])) {
|
1326 |
-
// Minimize risk of similar loggers logging same messages and such and resulting in same occasions id
|
1327 |
-
// by always adding logger slug.
|
1328 |
-
$occasions_data = array(
|
1329 |
-
'_occasionsID' => $context['_occasionsID'],
|
1330 |
-
'_loggerSlug' => $this->slug
|
1331 |
-
);
|
1332 |
-
$occasions_id = md5(json_encode($occasions_data));
|
1333 |
-
unset($context['_occasionsID']);
|
1334 |
-
} else {
|
1335 |
-
// No occasions id specified, create one bases on the data array.
|
1336 |
-
$occasions_data = $data + $context;
|
1337 |
-
|
1338 |
-
// Don't include date in context data.
|
1339 |
-
unset($occasions_data['date']);
|
1340 |
-
|
1341 |
-
$occasions_id = md5(json_encode($occasions_data));
|
1342 |
-
}
|
1343 |
-
|
1344 |
-
$data['occasionsID'] = $occasions_id;
|
1345 |
-
|
1346 |
-
// Log initiator, defaults to current user if exists, or other if not user exist
|
1347 |
-
if (isset($context['_initiator'])) {
|
1348 |
-
// Manually set in context
|
1349 |
-
$data['initiator'] = $context['_initiator'];
|
1350 |
-
unset($context['_initiator']);
|
1351 |
-
} else {
|
1352 |
-
// No initiator set, try to determine
|
1353 |
-
// Default to other
|
1354 |
-
$data['initiator'] = SimpleLoggerLogInitiators::OTHER;
|
1355 |
-
|
1356 |
-
// Check if user is responsible.
|
1357 |
-
if (function_exists('wp_get_current_user')) {
|
1358 |
-
$current_user = wp_get_current_user();
|
1359 |
-
|
1360 |
-
if (isset($current_user->ID) && $current_user->ID) {
|
1361 |
-
$data['initiator'] = SimpleLoggerLogInitiators::WP_USER;
|
1362 |
-
$context['_user_id'] = $current_user->ID;
|
1363 |
-
$context['_user_login'] = $current_user->user_login;
|
1364 |
-
$context['_user_email'] = $current_user->user_email;
|
1365 |
-
}
|
1366 |
-
}
|
1367 |
-
|
1368 |
-
// If cron then set WordPress as responsible
|
1369 |
-
if (defined('DOING_CRON') && DOING_CRON) {
|
1370 |
-
// Seems to be wp cron running and doing this.
|
1371 |
-
$data['initiator'] = SimpleLoggerLogInitiators::WORDPRESS;
|
1372 |
-
$context['_wp_cron_running'] = true;
|
1373 |
-
|
1374 |
-
// To aid debugging we log the current filter and a list of all filters.
|
1375 |
-
global $wp_current_filter;
|
1376 |
-
$context['_wp_cron_current_filter'] = current_filter();
|
1377 |
-
}
|
1378 |
-
|
1379 |
-
// If running as CLI and WP_CLI_PHP_USED is set then it is WP CLI that is doing it
|
1380 |
-
// How to log this? Is this a user, is it WordPress, or what?
|
1381 |
-
// I'm thinking:
|
1382 |
-
// - it is a user that is manually doing this, on purpose, with intent, so not auto wordpress
|
1383 |
-
// - it is a specific user, but we don't know who
|
1384 |
-
// - sounds like a special case, set initiator to wp_cli
|
1385 |
-
// Can be used by plugins/themes to check if WP-CLI is running or not
|
1386 |
-
if (defined('WP_CLI') && WP_CLI) {
|
1387 |
-
$data['initiator'] = SimpleLoggerLogInitiators::WP_CLI;
|
1388 |
-
}
|
1389 |
-
} // End if().
|
1390 |
-
|
1391 |
-
// Detect XML-RPC calls and append to context, if not already there.
|
1392 |
-
if (
|
1393 |
-
defined('XMLRPC_REQUEST') &&
|
1394 |
-
XMLRPC_REQUEST &&
|
1395 |
-
!isset($context['_xmlrpc_request'])
|
1396 |
-
) {
|
1397 |
-
$context['_xmlrpc_request'] = true;
|
1398 |
-
}
|
1399 |
-
|
1400 |
-
// Detect REST calls and append to context, if not already there.
|
1401 |
-
$isRestApiRequest =
|
1402 |
-
(defined('REST_API_REQUEST') && REST_API_REQUEST) ||
|
1403 |
-
(defined('REST_REQUEST') && REST_REQUEST);
|
1404 |
-
if ($isRestApiRequest) {
|
1405 |
-
$context['_rest_api_request'] = true;
|
1406 |
-
}
|
1407 |
-
|
1408 |
-
// Trim message.
|
1409 |
-
$data['message'] = trim($data['message']);
|
1410 |
-
|
1411 |
-
/**
|
1412 |
-
* Filter data to be saved to db.
|
1413 |
-
*
|
1414 |
-
* @since 2.0
|
1415 |
-
*
|
1416 |
-
* @param array $data
|
1417 |
-
*/
|
1418 |
-
$data = apply_filters('simple_history/log_insert_data', $data);
|
1419 |
-
|
1420 |
-
// Insert data into db.
|
1421 |
-
$result = $wpdb->insert($db_table, $data);
|
1422 |
-
|
1423 |
-
$data_parent_row = null;
|
1424 |
-
|
1425 |
-
// Only save context if able to store row.
|
1426 |
-
if (false === $result) {
|
1427 |
-
$history_inserted_id = null;
|
1428 |
-
} else {
|
1429 |
-
$history_inserted_id = $wpdb->insert_id;
|
1430 |
-
|
1431 |
-
$db_table_contexts =
|
1432 |
-
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
1433 |
-
|
1434 |
-
/**
|
1435 |
-
* Filter table name for contexts.
|
1436 |
-
*
|
1437 |
-
* @since 2.0
|
1438 |
-
*
|
1439 |
-
* @param string $db_table_contexts
|
1440 |
-
*/
|
1441 |
-
$db_table_contexts = apply_filters(
|
1442 |
-
'simple_history/logger_db_table_contexts',
|
1443 |
-
$db_table_contexts
|
1444 |
-
);
|
1445 |
-
|
1446 |
-
if (!is_array($context)) {
|
1447 |
-
$context = array();
|
1448 |
-
}
|
1449 |
-
|
1450 |
-
// Append user id to context, if not already added.
|
1451 |
-
if (!isset($context['_user_id'])) {
|
1452 |
-
// wp_get_current_user is not available early.
|
1453 |
-
// http://codex.wordpress.org/Function_Reference/wp_get_current_user
|
1454 |
-
// https://core.trac.wordpress.org/ticket/14024
|
1455 |
-
if (function_exists('wp_get_current_user')) {
|
1456 |
-
$current_user = wp_get_current_user();
|
1457 |
-
|
1458 |
-
if (isset($current_user->ID) && $current_user->ID) {
|
1459 |
-
$context['_user_id'] = $current_user->ID;
|
1460 |
-
$context['_user_login'] = $current_user->user_login;
|
1461 |
-
$context['_user_email'] = $current_user->user_email;
|
1462 |
-
}
|
1463 |
-
}
|
1464 |
-
}
|
1465 |
-
|
1466 |
-
// Add remote addr to context.
|
1467 |
-
if (!isset($context['_server_remote_addr'])) {
|
1468 |
-
$remote_addr = empty($_SERVER['REMOTE_ADDR'])
|
1469 |
-
? ''
|
1470 |
-
: wp_unslash($_SERVER['REMOTE_ADDR']);
|
1471 |
-
|
1472 |
-
/**
|
1473 |
-
* Filter to control if ip addresses should be anonymized or not.
|
1474 |
-
*
|
1475 |
-
* @since 2.22
|
1476 |
-
*
|
1477 |
-
* @param bool true to anonymize ip address, false to keep original ip address.
|
1478 |
-
* @return bool
|
1479 |
-
*/
|
1480 |
-
$anonymize_ip_address = apply_filters(
|
1481 |
-
'simple_history/privacy/anonymize_ip_address',
|
1482 |
-
true
|
1483 |
-
);
|
1484 |
-
|
1485 |
-
if (
|
1486 |
-
$anonymize_ip_address &&
|
1487 |
-
function_exists('wp_privacy_anonymize_ip')
|
1488 |
-
) {
|
1489 |
-
$remote_addr = wp_privacy_anonymize_ip($remote_addr);
|
1490 |
-
}
|
1491 |
-
|
1492 |
-
$context['_server_remote_addr'] = $remote_addr;
|
1493 |
-
|
1494 |
-
// If web server is behind a load balancer then the ip address will always be the same
|
1495 |
-
// See bug report: https://wordpress.org/support/topic/use-x-forwarded-for-http-header-when-logging-remote_addr?replies=1#post-6422981
|
1496 |
-
// Note that the x-forwarded-for header can contain multiple ips, comma separated
|
1497 |
-
// Also note that the header can be faked
|
1498 |
-
// Ref: http://stackoverflow.com/questions/753645/how-do-i-get-the-correct-ip-from-http-x-forwarded-for-if-it-contains-multiple-ip
|
1499 |
-
// Ref: http://blackbe.lt/advanced-method-to-obtain-the-client-ip-in-php/
|
1500 |
-
// Check for IP in lots of headers
|
1501 |
-
// Based on code found here:
|
1502 |
-
// http://blackbe.lt/advanced-method-to-obtain-the-client-ip-in-php/
|
1503 |
-
$ip_keys = $this->get_ip_number_header_keys();
|
1504 |
-
|
1505 |
-
foreach ($ip_keys as $key) {
|
1506 |
-
if (array_key_exists($key, $_SERVER) === true) {
|
1507 |
-
// Loop through all IPs.
|
1508 |
-
$ip_loop_num = 0;
|
1509 |
-
foreach (explode(',', $_SERVER[$key]) as $ip) {
|
1510 |
-
// trim for safety measures.
|
1511 |
-
$ip = trim($ip);
|
1512 |
-
|
1513 |
-
// attempt to validate IP.
|
1514 |
-
if ($this->validate_ip($ip)) {
|
1515 |
-
// valid, add to context, with loop index appended so we can store many IPs.
|
1516 |
-
$key_lower = strtolower($key);
|
1517 |
-
|
1518 |
-
if (
|
1519 |
-
$anonymize_ip_address &&
|
1520 |
-
function_exists('wp_privacy_anonymize_ip')
|
1521 |
-
) {
|
1522 |
-
$ip = wp_privacy_anonymize_ip($ip);
|
1523 |
-
}
|
1524 |
-
|
1525 |
-
$context[
|
1526 |
-
"_server_{$key_lower}_{$ip_loop_num}"
|
1527 |
-
] = $ip;
|
1528 |
-
}
|
1529 |
-
|
1530 |
-
$ip_loop_num++;
|
1531 |
-
}
|
1532 |
-
}
|
1533 |
-
}
|
1534 |
-
} // End if().
|
1535 |
-
|
1536 |
-
// Append http referer.
|
1537 |
-
if (
|
1538 |
-
!isset($context['_server_http_referer']) &&
|
1539 |
-
isset($_SERVER['HTTP_REFERER'])
|
1540 |
-
) {
|
1541 |
-
$context['_server_http_referer'] = $_SERVER['HTTP_REFERER'];
|
1542 |
-
}
|
1543 |
-
|
1544 |
-
/**
|
1545 |
-
* Filter the context to store for this event/row
|
1546 |
-
*
|
1547 |
-
* @since 2.0.29
|
1548 |
-
*
|
1549 |
-
* @param array $context Array with all context data to store. Modify and return this.
|
1550 |
-
* @param array $data Array with data used for parent row.
|
1551 |
-
* @param array $this Reference to this logger instance.
|
1552 |
-
*/
|
1553 |
-
$context = apply_filters(
|
1554 |
-
'simple_history/log_insert_context',
|
1555 |
-
$context,
|
1556 |
-
$data,
|
1557 |
-
$this
|
1558 |
-
);
|
1559 |
-
$data_parent_row = $data;
|
1560 |
-
|
1561 |
-
// Insert all context values into db.
|
1562 |
-
$this->append_context($history_inserted_id, $context);
|
1563 |
-
} // End if().
|
1564 |
-
|
1565 |
-
$this->lastInsertID = $history_inserted_id;
|
1566 |
-
$this->lastInsertContext = $context;
|
1567 |
-
|
1568 |
-
$this->simpleHistory->get_cache_incrementor(true);
|
1569 |
-
|
1570 |
-
/**
|
1571 |
-
* Action that is called after an event has been logged
|
1572 |
-
*
|
1573 |
-
* @since 2.5.1
|
1574 |
-
*
|
1575 |
-
* @param array $context Array with all context data that was used to log event.
|
1576 |
-
* @param array $data Array with data used for parent row.
|
1577 |
-
* @param array $this Reference to this logger instance
|
1578 |
-
*/
|
1579 |
-
do_action(
|
1580 |
-
'simple_history/log/inserted',
|
1581 |
-
$context,
|
1582 |
-
$data_parent_row,
|
1583 |
-
$this
|
1584 |
-
);
|
1585 |
-
|
1586 |
-
// Return $this so we can chain methods.
|
1587 |
-
return $this;
|
1588 |
-
}
|
1589 |
-
|
1590 |
-
/**
|
1591 |
-
* Append new info to the context of history item with id $post_logger->lastInsertID.
|
1592 |
-
*
|
1593 |
-
* @param int $history_id The id of the history row to add context to.
|
1594 |
-
* @param array $context Context to append to existing context for the row.
|
1595 |
-
* @return bool True if context was added, false if not (beacuse row_id or context is empty).
|
1596 |
-
*/
|
1597 |
-
public function append_context($history_id, $context)
|
1598 |
-
{
|
1599 |
-
if (empty($history_id) || empty($context)) {
|
1600 |
-
return false;
|
1601 |
-
}
|
1602 |
-
|
1603 |
-
global $wpdb;
|
1604 |
-
|
1605 |
-
$db_table_contexts = $wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
1606 |
-
|
1607 |
-
foreach ($context as $key => $value) {
|
1608 |
-
// Everything except strings should be json_encoded, ie. arrays and objects.
|
1609 |
-
if (!is_string($value)) {
|
1610 |
-
$value = simpleHistory::json_encode($value);
|
1611 |
-
}
|
1612 |
-
|
1613 |
-
$data = array(
|
1614 |
-
'history_id' => $history_id,
|
1615 |
-
'key' => $key,
|
1616 |
-
'value' => $value
|
1617 |
-
);
|
1618 |
-
|
1619 |
-
$wpdb->insert($db_table_contexts, $data);
|
1620 |
-
}
|
1621 |
-
|
1622 |
-
return true;
|
1623 |
-
}
|
1624 |
-
|
1625 |
-
/**
|
1626 |
-
* Returns array with headers that may contain user IP
|
1627 |
-
*
|
1628 |
-
* @since 2.0.29
|
1629 |
-
*/
|
1630 |
-
public function get_ip_number_header_keys()
|
1631 |
-
{
|
1632 |
-
$arr = array(
|
1633 |
-
'HTTP_CLIENT_IP',
|
1634 |
-
'HTTP_X_FORWARDED_FOR',
|
1635 |
-
'HTTP_X_FORWARDED',
|
1636 |
-
'HTTP_X_CLUSTER_CLIENT_IP',
|
1637 |
-
'HTTP_FORWARDED_FOR',
|
1638 |
-
'HTTP_FORWARDED'
|
1639 |
-
);
|
1640 |
-
|
1641 |
-
return $arr;
|
1642 |
-
}
|
1643 |
-
|
1644 |
-
/**
|
1645 |
-
* Returns additional headers with ip number from context
|
1646 |
-
*
|
1647 |
-
* @since 2.0.29
|
1648 |
-
* @param object $row Row with info.
|
1649 |
-
* @return array Headers
|
1650 |
-
*/
|
1651 |
-
public function get_event_ip_number_headers($row)
|
1652 |
-
{
|
1653 |
-
$ip_keys = $this->get_ip_number_header_keys();
|
1654 |
-
$arr_found_additional_ip_headers = array();
|
1655 |
-
$context = $row->context;
|
1656 |
-
|
1657 |
-
foreach ($ip_keys as $one_ip_header_key) {
|
1658 |
-
$one_ip_header_key_lower = strtolower($one_ip_header_key);
|
1659 |
-
|
1660 |
-
foreach ($context as $context_key => $context_val) {
|
1661 |
-
// $key_check_for = "_server_" . strtolower($one_ip_header_key) . "_0";
|
1662 |
-
$match = preg_match(
|
1663 |
-
"/^_server_{$one_ip_header_key_lower}_[\d+]/",
|
1664 |
-
$context_key,
|
1665 |
-
$matches
|
1666 |
-
);
|
1667 |
-
if ($match) {
|
1668 |
-
$arr_found_additional_ip_headers[
|
1669 |
-
$context_key
|
1670 |
-
] = $context_val;
|
1671 |
-
}
|
1672 |
-
}
|
1673 |
-
} // End foreach().
|
1674 |
-
|
1675 |
-
return $arr_found_additional_ip_headers;
|
1676 |
-
}
|
1677 |
-
|
1678 |
-
/**
|
1679 |
-
* Ensures an ip address is both a valid IP and does not fall within
|
1680 |
-
* a private network range.
|
1681 |
-
*
|
1682 |
-
* @param string $ip IP number.
|
1683 |
-
* @return bool
|
1684 |
-
*/
|
1685 |
-
public function validate_ip($ip)
|
1686 |
-
{
|
1687 |
-
if (
|
1688 |
-
filter_var(
|
1689 |
-
$ip,
|
1690 |
-
FILTER_VALIDATE_IP,
|
1691 |
-
FILTER_FLAG_IPV4 |
|
1692 |
-
FILTER_FLAG_NO_PRIV_RANGE |
|
1693 |
-
FILTER_FLAG_NO_RES_RANGE
|
1694 |
-
) === false
|
1695 |
-
) {
|
1696 |
-
return false;
|
1697 |
-
}
|
1698 |
-
|
1699 |
-
return true;
|
1700 |
-
}
|
1701 |
-
|
1702 |
-
/**
|
1703 |
-
* Override this to add CSS in <head> for your logger.
|
1704 |
-
* The CSS that you output will only be outputed
|
1705 |
-
* on pages where Simple History is used.
|
1706 |
-
*/
|
1707 |
-
public function adminCSS()
|
1708 |
-
{
|
1709 |
-
/*
|
1710 |
-
?>
|
1711 |
-
<style>
|
1712 |
-
body {
|
1713 |
-
border: 2px solid red;
|
1714 |
-
}
|
1715 |
-
</style>
|
1716 |
-
<?php
|
1717 |
-
*/
|
1718 |
-
}
|
1719 |
-
|
1720 |
-
/**
|
1721 |
-
* Override this to add JavaScript in the footer for your logger.
|
1722 |
-
* The JS that you output will only be outputed
|
1723 |
-
* on pages where Simple History is used.
|
1724 |
-
*/
|
1725 |
-
public function adminJS()
|
1726 |
-
{
|
1727 |
-
/*
|
1728 |
-
?>
|
1729 |
-
<script>
|
1730 |
-
console.log("This is outputed in the footer");
|
1731 |
-
</script>
|
1732 |
-
<?php
|
1733 |
-
*/
|
1734 |
-
}
|
1 |
<?php
|
2 |
|
3 |
+
defined( 'ABSPATH' ) || die();
|
4 |
|
5 |
/**
|
6 |
* A PSR-3 inspired logger class
|
10 |
*
|
11 |
* @link https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md PSR-3 specification
|
12 |
*/
|
13 |
+
class SimpleLogger {
|
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 = __CLASS__;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Will contain the untranslated messages from getInfo()
|
23 |
+
*
|
24 |
+
* By adding your messages here they will be stored both translated and non-translated
|
25 |
+
* You then log something like this:
|
26 |
+
* <code>
|
27 |
+
* $this->info( $this->messages["POST_UPDATED"] );
|
28 |
+
* </code>
|
29 |
+
* or with the shortcut
|
30 |
+
* <code>
|
31 |
+
* $this->infoMessage("POST_UPDATED");
|
32 |
+
* </code>
|
33 |
+
* which results in the original, untranslated, string being added to the log and database
|
34 |
+
* the translated string are then only used when showing the log in the GUI
|
35 |
+
*/
|
36 |
+
public $messages;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* ID of last inserted row
|
40 |
+
*
|
41 |
+
* @var int $lastInsertID Database row primary key.
|
42 |
+
*/
|
43 |
+
public $lastInsertID;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Context of last inserted row.
|
47 |
+
*
|
48 |
+
* @var int $lastInsertContext Context used for the last insert.
|
49 |
+
* @since 2.2x
|
50 |
+
*/
|
51 |
+
public $lastInsertContext;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Simple History instance.
|
55 |
+
*
|
56 |
+
* @var object $simpleHistory Simple history instance.
|
57 |
+
*/
|
58 |
+
public $simpleHistory;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Constructor. Remember to call this as parent constructor if making a childlogger
|
62 |
+
*
|
63 |
+
* @param $simpleHistory history class objectinstance
|
64 |
+
*/
|
65 |
+
public function __construct( $simpleHistory = null ) {
|
66 |
+
global $wpdb;
|
67 |
+
|
68 |
+
$this->db_table = $wpdb->prefix . SimpleHistory::DBTABLE;
|
69 |
+
$this->db_table_contexts =
|
70 |
+
$wpdb->prefix . SimpleHistory::DBTABLE_CONTEXTS;
|
71 |
+
|
72 |
+
$this->simpleHistory = $simpleHistory;
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Method that is called automagically when logger is loaded by Simple History
|
77 |
+
* Add your init stuff here
|
78 |
+
*/
|
79 |
+
public function loaded() {
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Get array with information about this logger.
|
84 |
+
*
|
85 |
+
* @return array
|
86 |
+
*/
|
87 |
+
public function getInfo() {
|
88 |
+
$arr_info = array(
|
89 |
+
// The logger slug. Defaulting to the class name is nice and logical I think.
|
90 |
+
'slug' => __CLASS__,
|
91 |
+
|
92 |
+
// Shown on the info-tab in settings, use these fields to tell
|
93 |
+
// an admin what your logger is used for.
|
94 |
+
'name' => 'SimpleLogger',
|
95 |
+
'description' => 'The built in logger for Simple History',
|
96 |
+
|
97 |
+
// Capability required to view log entries from this logger
|
98 |
+
'capability' => 'edit_pages',
|
99 |
+
'messages' => array(
|
100 |
+
// No pre-defined variants
|
101 |
+
// when adding messages __() or _x() must be used
|
102 |
+
),
|
103 |
+
);
|
104 |
+
|
105 |
+
return $arr_info;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Return single array entry from the array in getInfo()
|
110 |
+
* Returns the value of the key if value exists, or null
|
111 |
+
*
|
112 |
+
* @since 2.5.4
|
113 |
+
* @return Mixed
|
114 |
+
*/
|
115 |
+
public function getInfoValueByKey( $key ) {
|
116 |
+
$arr_info = $this->getInfo();
|
117 |
+
|
118 |
+
return isset( $arr_info[ $key ] ) ? $arr_info[ $key ] : null;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Returns the capability required to read log rows from this logger
|
123 |
+
*
|
124 |
+
* @return $string capability
|
125 |
+
*/
|
126 |
+
public function getCapability() {
|
127 |
+
$arr_info = $this->getInfo();
|
128 |
+
|
129 |
+
$capability = 'manage_options';
|
130 |
+
|
131 |
+
if ( ! empty( $arr_info['capability'] ) ) {
|
132 |
+
$capability = $arr_info['capability'];
|
133 |
+
}
|
134 |
+
|
135 |
+
return $capability;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Interpolates context values into the message placeholders.
|
140 |
+
*
|
141 |
+
* @param string $message
|
142 |
+
* @param array $context
|
143 |
+
* @param array $row Currently not always passed, because loggers need to be updated to support this...
|
144 |
+
*/
|
145 |
+
public function interpolate( $message, $context = array(), $row = null ) {
|
146 |
+
if ( ! is_array( $context ) ) {
|
147 |
+
return $message;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Filter the context used to create the message from the message template
|
152 |
+
*
|
153 |
+
* @since 2.2.4
|
154 |
+
*/
|
155 |
+
$context = apply_filters(
|
156 |
+
'simple_history/logger/interpolate/context',
|
157 |
+
$context,
|
158 |
+
$message,
|
159 |
+
$row
|
160 |
+
);
|
161 |
+
|
162 |
+
// Build a replacement array with braces around the context keys
|
163 |
+
$replace = array();
|
164 |
+
foreach ( $context as $key => $val ) {
|
165 |
+
// Both key and val must be strings or number (for vals)
|
166 |
+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
|
167 |
+
if ( is_string( $key ) || is_numeric( $key ) ) {
|
168 |
+
// key ok
|
169 |
+
}
|
170 |
+
|
171 |
+
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf
|
172 |
+
if ( is_string( $val ) || is_numeric( $val ) ) {
|
173 |
+
// val ok
|
174 |
+
} else {
|
175 |
+
// not a value we can replace
|
176 |
+
continue;
|
177 |
+
}
|
178 |
+
|
179 |
+
$replace[ '{' . $key . '}' ] = $val;
|
180 |
+
}
|
181 |
+
|
182 |
+
// Interpolate replacement values into the message and return
|
183 |
+
return strtr( $message, $replace );
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* @param object $row
|
188 |
+
* @return string HTML
|
189 |
+
*/
|
190 |
+
public function getLogRowHeaderInitiatorOutput( $row ) {
|
191 |
+
$initiator_html = '';
|
192 |
+
$initiator = $row->initiator;
|
193 |
+
$context = $row->context;
|
194 |
+
|
195 |
+
switch ( $initiator ) {
|
196 |
+
case 'wp':
|
197 |
+
$initiator_html .=
|
198 |
+
'<strong class="SimpleHistoryLogitem__inlineDivided">WordPress</strong> ';
|
199 |
+
break;
|
200 |
+
|
201 |
+
case 'wp_cli':
|
202 |
+
$initiator_html .=
|
203 |
+
'<strong class="SimpleHistoryLogitem__inlineDivided">WP-CLI</strong> ';
|
204 |
+
break;
|
205 |
+
|
206 |
+
// wp_user = wordpress uses, but user may have been deleted since log entry was added
|
207 |
+
case 'wp_user':
|
208 |
+
$user_id = isset( $row->context['_user_id'] )
|
209 |
+
? $row->context['_user_id']
|
210 |
+
: null;
|
211 |
+
|
212 |
+
$user = get_user_by( 'id', $user_id );
|
213 |
+
if ( $user_id > 0 && ( $user ) ) {
|
214 |
+
// Sender is user and user still exists.
|
215 |
+
$is_current_user =
|
216 |
+
get_current_user_id() == $user_id ? true : false;
|
217 |
+
|
218 |
+
// get user role, as done in user-edit.php
|
219 |
+
$wp_roles = $GLOBALS['wp_roles'];
|
220 |
+
$user_roles = array_intersect(
|
221 |
+
array_values( (array) $user->roles ),
|
222 |
+
array_keys( (array) $wp_roles->roles )
|
223 |
+
);
|
224 |
+
$user_role = array_shift( $user_roles );
|
225 |
+
|
226 |
+
$user_display_name = $user->display_name;
|
227 |
+
|
228 |
+
/*
|
229 |
+
* If user who logged this is the currently logged in user
|
230 |
+
* skip name and email and use just "You"
|
231 |
+
*
|
232 |
+
* @param bool If you should be used
|
233 |
+
* @since 2.1
|
234 |
+
*/
|
235 |
+
$use_you = apply_filters(
|
236 |
+
'simple_history/header_initiator_use_you',
|
237 |
+
true
|
238 |
+
);
|
239 |
+
|
240 |
+
if ( $use_you && $is_current_user ) {
|
241 |
+
$tmpl_initiator_html = '
|
|
|
|
|
|
|
|
|
242 |
<a href="%6$s" class="SimpleHistoryLogitem__headerUserProfileLink">
|
243 |
<strong class="SimpleHistoryLogitem__inlineDivided">%5$s</strong>
|
244 |
</a>
|
245 |
';
|
246 |
+
} else {
|
247 |
+
$tmpl_initiator_html = '
|
248 |
<a href="%6$s" class="SimpleHistoryLogitem__headerUserProfileLink">
|
249 |
<strong class="SimpleHistoryLogitem__inlineDivided">%3$s</strong>
|
250 |
<span class="SimpleHistoryLogitem__inlineDivided SimpleHistoryLogitem__headerEmail">%2$s</span>
|
251 |
</a>
|
252 |
';
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Filter the format for the user output
|
257 |
+
*
|
258 |
+
* @since 2.0
|
259 |
+
*
|
260 |
+
* @param string $format.
|
261 |
+
*/
|
262 |
+
$tmpl_initiator_html = apply_filters(
|
263 |
+
'simple_history/header_initiator_html_existing_user',
|
264 |
+
$tmpl_initiator_html
|
265 |
+
);
|
266 |
+
|
267 |
+
$initiator_html .= sprintf(
|
268 |
+
$tmpl_initiator_html,
|
269 |
+
esc_html( $user->user_login ), // 1
|
270 |
+
esc_html( $user->user_email ), // 2
|
271 |
+
esc_html( $user_display_name ), // 3
|
272 |
+
$user_role, // 4
|
273 |
+
_x(
|
274 |
+
'You',
|
275 |
+
'header output when initiator is the currently logged in user',
|
276 |
+
'simple-history'
|
277 |
+
), // 5
|
278 |
+
get_edit_user_link( $user_id ) // 6
|
279 |
+
);
|
280 |
+
} elseif ( $user_id > 0 ) {
|
281 |
+
// Sender was a user, but user is deleted now
|
282 |
+
// output all info we have
|
283 |
+
// _user_id
|
284 |
+
// _username
|
285 |
+
// _user_login
|
286 |
+
// _user_email
|
287 |
+
$initiator_html .= sprintf(
|
288 |
+
'<strong class="SimpleHistoryLogitem__inlineDivided">' .
|
289 |
+
__(
|
290 |
+
'Deleted user (had id %1$s, email %2$s, login %3$s)',
|
291 |
+
'simple-history'
|
292 |
+
) .
|
293 |
+
'</strong>',
|
294 |
+
esc_html( $context['_user_id'] ), // 1
|
295 |
+
esc_html( $context['_user_email'] ), // 2
|
296 |
+
esc_html( $context['_user_login'] ) // 3
|
297 |
+
);
|
298 |
+
} // End if().
|
299 |
+
|
300 |
+
break;
|
301 |
+
|
302 |
+
case 'web_user':
|
303 |
+
/*
|
304 |
+
Note: server_remote_addr may not show visiting/attacking ip, if server is behind...stuff..
|
305 |
+
Can be behind varnish cache, or browser can for example use compression in chrome mobile
|
306 |
+
then the real ip is behind _server_http_x_forwarded_for_0 or similar
|
307 |
+
_server_remote_addr 66.249.81.222
|
308 |
+
_server_http_x_forwarded_for_0 5.35.187.212
|
309 |
+
*/
|
310 |
+
|
311 |
+
// Check if additional IP addresses are stored, from http_x_forwarded_for and so on.
|
312 |
+
$arr_found_additional_ip_headers = $this->get_event_ip_number_headers(
|
313 |
+
$row
|
314 |
+
);
|
315 |
+
|
316 |
+
$initiator_html .=
|
317 |
+
"<strong class='SimpleHistoryLogitem__inlineDivided'>" .
|
318 |
+
__( 'Anonymous web user', 'simple-history' ) .
|
319 |
+
'</strong> ';
|
320 |
+
|
321 |
+
break;
|
322 |
+
|
323 |
+
case 'other':
|
324 |
+
$initiator_html .=
|
325 |
+
"<strong class='SimpleHistoryLogitem__inlineDivided'>" .
|
326 |
+
_x(
|
327 |
+
'Other',
|
328 |
+
'Event header output, when initiator is unknown',
|
329 |
+
'simple-history'
|
330 |
+
) .
|
331 |
+
'</strong>';
|
332 |
+
break;
|
333 |
+
|
334 |
+
// no initiator
|
335 |
+
case null:
|
336 |
+
// $initiator_html .= "<strong class='SimpleHistoryLogitem__inlineDivided'>Null</strong>";
|
337 |
+
break;
|
338 |
+
|
339 |
+
default:
|
340 |
+
$initiator_html .=
|
341 |
+
"<strong class='SimpleHistoryLogitem__inlineDivided'>" .
|
342 |
+
esc_html( $initiator ) .
|
343 |
+
'</strong>';
|
344 |
+
} // End switch().
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Filter generated html for the initiator row header html
|
348 |
+
*
|
349 |
+
* @since 2.0
|
350 |
+
*
|
351 |
+
* @param string $initiator_html
|
352 |
+
* @param object $row Log row
|
353 |
+
*/
|
354 |
+
$initiator_html = apply_filters(
|
355 |
+
'simple_history/row_header_initiator_output',
|
356 |
+
$initiator_html,
|
357 |
+
$row
|
358 |
+
);
|
359 |
+
|
360 |
+
return $initiator_html;
|
361 |
+
}
|
362 |
+
|
363 |
+
public function getLogRowHeaderDateOutput( $row ) {
|
364 |
+
// HTML for date
|
365 |
+
// Date (should...) always exist
|
366 |
+
// http://developers.whatwg.org/text-level-semantics.html#the-time-element
|
367 |
+
$date_html = '';
|
368 |
+
$str_when = '';
|
369 |
+
|
370 |
+
// $row->date is in GMT
|
371 |
+
$date_datetime = new DateTime( $row->date, new DateTimeZone( 'GMT' ) );
|
372 |
+
|
373 |
+
// Current datetime in GMT
|
374 |
+
$time_current = strtotime( current_time( 'mysql', 1 ) );
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Filter how many seconds as most that can pass since an
|
378 |
+
* event occured to show "nn minutes ago" (human diff time-format) instead of exact date
|
379 |
+
*
|
380 |
+
* @since 2.0
|
381 |
+
*
|
382 |
+
* @param int $time_ago_max_time Seconds
|
383 |
+
*/
|
384 |
+
$time_ago_max_time = DAY_IN_SECONDS * 2;
|
385 |
+
$time_ago_max_time = apply_filters(
|
386 |
+
'simple_history/header_time_ago_max_time',
|
387 |
+
$time_ago_max_time
|
388 |
+
);
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Filter how many seconds as most that can pass since an
|
392 |
+
* event occured to show "just now" instead of exact date
|
393 |
+
*
|
394 |
+
* @since 2.0
|
395 |
+
*
|
396 |
+
* @param int $time_ago_max_time Seconds
|
397 |
+
*/
|
398 |
+
$time_ago_just_now_max_time = 30;
|
399 |
+
$time_ago_just_now_max_time = apply_filters(
|
400 |
+
'simple_history/header_just_now_max_time',
|
401 |
+
$time_ago_just_now_max_time
|
402 |
+
);
|
403 |
+
|
404 |
+
$date_format = get_option( 'date_format' );
|
405 |
+
$time_format = get_option( 'time_format' );
|
406 |
+
$date_and_time_format = $date_format . ' - ' . $time_format;
|
407 |
+
|
408 |
+
// Show local time as hours an minutes when event is recent.
|
409 |
+
$local_date_format = $time_format;
|
410 |
+
|
411 |
+
// Show local time as date and hours when event is a bit older.
|
412 |
+
if (
|
413 |
+
$time_current - HOUR_IN_SECONDS * 6 >
|
414 |
+
$date_datetime->getTimestamp()
|
415 |
+
) {
|
416 |
+
$local_date_format = $date_and_time_format;
|
417 |
+
}
|
418 |
+
|
419 |
+
if (
|
420 |
+
$time_current - $date_datetime->getTimestamp() <=
|
421 |
+
$time_ago_just_now_max_time
|
422 |
+
) {
|
423 |
+
// Show "just now" if event is very recent.
|
424 |
+
$str_when = __( 'Just now', 'simple-history' );
|
425 |
+
} elseif (
|
426 |
+
$time_current - $date_datetime->getTimestamp() >
|
427 |
+
$time_ago_max_time
|
428 |
+
) {
|
429 |
+
/* Translators: Date format for log row header, see http://php.net/date */
|
430 |
+
$datef = __( 'M j, Y \a\t G:i', 'simple-history' );
|
431 |
+
$str_when = date_i18n(
|
432 |
+
$datef,
|
433 |
+
strtotime( get_date_from_gmt( $row->date ) )
|
434 |
+
);
|
435 |
+
} else {
|
436 |
+
// Show "nn minutes ago" when event is xx seconds ago or earlier
|
437 |
+
$date_human_time_diff = human_time_diff(
|
438 |
+
$date_datetime->getTimestamp(),
|
439 |
+
$time_current
|
440 |
+
);
|
441 |
+
/* Translators: 1: last modified date and time in human time diff-format */
|
442 |
+
$str_when = sprintf(
|
443 |
+
__( '%1$s ago', 'simple-history' ),
|
444 |
+
$date_human_time_diff
|
445 |
+
);
|
446 |
+
}
|
447 |
+
|
448 |
+
$item_permalink = admin_url( apply_filters( 'simple_history/admin_location', 'index' ) . '.php?page=simple_history_page' );
|
449 |
+
if ( ! empty( $row->id ) ) {
|
450 |
+
$item_permalink .= "#item/{$row->id}";
|
451 |
+
}
|
452 |
+
|
453 |
+
// Datetime attribute on <time> element.
|
454 |
+
$str_datetime_title = sprintf(
|
455 |
+
__( '%1$s local time %3$s (%2$s GMT time)', 'simple-history' ),
|
456 |
+
get_date_from_gmt(
|
457 |
+
$date_datetime->format( 'Y-m-d H:i:s' ),
|
458 |
+
$date_and_time_format
|
459 |
+
), // 1 local time
|
460 |
+
$date_datetime->format( $date_and_time_format ), // GMT time
|
461 |
+
PHP_EOL // 3, new line
|
462 |
+
);
|
463 |
+
|
464 |
+
// Time and date before live updated relative date.
|
465 |
+
$str_datetime_local = sprintf(
|
466 |
+
'%1$s',
|
467 |
+
get_date_from_gmt(
|
468 |
+
$date_datetime->format( 'Y-m-d H:i:s' ),
|
469 |
+
$local_date_format
|
470 |
+
) // 1 local time
|
471 |
+
);
|
472 |
+
|
473 |
+
// HTML for whole span with date info.
|
474 |
+
$date_html =
|
475 |
+
"<span class='SimpleHistoryLogitem__permalink SimpleHistoryLogitem__when SimpleHistoryLogitem__inlineDivided'>";
|
476 |
+
$date_html .= "<a class='' href='{$item_permalink}'>";
|
477 |
+
$date_html .= sprintf(
|
478 |
+
'<span title="%1$s">%4$s (<time datetime="%3$s" class="SimpleHistoryLogitem__when__liveRelative">%2$s</time>)</span>',
|
479 |
+
esc_attr( $str_datetime_title ), // 1 datetime attribute
|
480 |
+
esc_html( $str_when ), // 2 date text, visible in log, but overridden by JS relative date script.
|
481 |
+
$date_datetime->format( DateTime::RFC3339 ), // 3
|
482 |
+
esc_html( $str_datetime_local ) // 4
|
483 |
+
);
|
484 |
+
$date_html .= '</a>';
|
485 |
+
$date_html .= '</span>';
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Filter the output of the date section of the header.
|
489 |
+
*
|
490 |
+
* @since 2.5.1
|
491 |
+
*
|
492 |
+
* @param string $date_html
|
493 |
+
* @param object $row
|
494 |
+
*/
|
495 |
+
$date_html = apply_filters(
|
496 |
+
'simple_history/row_header_date_output',
|
497 |
+
$date_html,
|
498 |
+
$row
|
499 |
+
);
|
500 |
+
|
501 |
+
return $date_html;
|
502 |
+
}
|
503 |
+
|
504 |
+
public function getLogRowHeaderUsingPluginOutput( $row ) {
|
505 |
+
// Logger "via" info in header, i.e. output some extra
|
506 |
+
// info next to the time to make it more clear what plugin etc.
|
507 |
+
// that "caused" this event
|
508 |
+
$via_html = '';
|
509 |
+
$logger_name_via = $this->getInfoValueByKey( 'name_via' );
|
510 |
+
|
511 |
+
if ( $logger_name_via ) {
|
512 |
+
$via_html =
|
513 |
+
"<span class='SimpleHistoryLogitem__inlineDivided SimpleHistoryLogitem__via'>";
|
514 |
+
$via_html .= $logger_name_via;
|
515 |
+
$via_html .= '</span>';
|
516 |
+
}
|
517 |
+
|
518 |
+
return $via_html;
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Context for IP Addresses can contain multiple entries.
|
523 |
+
*
|
524 |
+
* - "_server_remote_addr" with value for example "172.17.0.0" is the main entry.
|
525 |
+
* It usually contains the IP address of the visitor.
|
526 |
+
*
|
527 |
+
* - Then zero or one or multiple entries can exist if web server is for example behind proxy.
|
528 |
+
* Entries that can exist are the one with keys is get_ip_number_header_keys(),
|
529 |
+
* Also each key can exist multiple times.
|
530 |
+
* Final key name will be like "_server_http_x_forwarded_for_0", "_server_http_x_forwarded_for_1" and so on.
|
531 |
+
*
|
532 |
+
* @param mixed $row
|
533 |
+
* @return string
|
534 |
+
*/
|
535 |
+
public function getLogRowHeaderIPAddressOutput( $row ) {
|
536 |
+
|
537 |
+
/**
|
538 |
+
* Filter if IP Address should be added to header row.
|
539 |
+
*
|
540 |
+
* @since 2.x
|
541 |
+
*
|
542 |
+
* @param bool True to show IP address, false to hide it. Defaults to false.
|
543 |
+
* @param object $row Row data
|
544 |
+
*/
|
545 |
+
$show_ip_address = apply_filters(
|
546 |
+
'simple_history/row_header_output/display_ip_address',
|
547 |
+
false,
|
548 |
+
$row
|
549 |
+
);
|
550 |
+
|
551 |
+
if ( ! $show_ip_address ) {
|
552 |
+
return '';
|
553 |
+
}
|
554 |
+
|
555 |
+
$context = $row->context;
|
556 |
+
$html = "<span class='SimpleHistoryLogitem__inlineDivided SimpleHistoryLogitem__anonUserWithIp'>";
|
557 |
+
|
558 |
+
$arr_ip_addresses = array();
|
559 |
+
|
560 |
+
// Look for additional ip addresses.
|
561 |
+
$arr_found_additional_ip_headers = $this->get_event_ip_number_headers( $row );
|
562 |
+
|
563 |
+
$arr_ip_addresses = array_merge(
|
564 |
+
// Remote addr always exists.
|
565 |
+
array( '_server_remote_addr' => $context['_server_remote_addr'] ),
|
566 |
+
$arr_found_additional_ip_headers
|
567 |
+
);
|
568 |
+
|
569 |
+
// if ( count( $arr_found_additional_ip_headers ) ) {
|
570 |
+
// $iplookup_link = sprintf('https://ipinfo.io/%1$s', esc_attr($context["_server_remote_addr"]));
|
571 |
+
// $ip_numbers_joined = wp_sprintf_l('%l', array("_server_remote_addr" => $context["_server_remote_addr"]) + $arr_found_additional_ip_headers);
|
572 |
+
/*
|
573 |
+
$html .= sprintf(
|
574 |
+
__('Anonymous user with multiple IP addresses detected: %1$s', "simple-history"),
|
575 |
+
"<a target='_blank' href={$iplookup_link} class='SimpleHistoryLogitem__anonUserWithIp__theIp'>" . esc_html( $ip_numbers_joined ) . "</a>"
|
576 |
+
);*/
|
577 |
+
|
578 |
+
/*
|
579 |
+
print_r($arr_found_additional_ip_headers);
|
580 |
+
Array
|
581 |
+
(
|
582 |
+
[_server_http_x_forwarded_for_0] => 5.35.187.212
|
583 |
+
[_server_http_x_forwarded_for_1] => 83.251.97.21
|
584 |
+
)
|
585 |
+
*/
|
586 |
+
|
587 |
+
// } else {
|
588 |
+
|
589 |
+
$first_ip_address = reset( $arr_ip_addresses );
|
590 |
+
|
591 |
+
// Output single or plural text.
|
592 |
+
if ( count( $arr_ip_addresses ) === 1 ) {
|
593 |
+
// Single ip address
|
594 |
+
$iplookup_link = sprintf(
|
595 |
+
'https://ipinfo.io/%1$s',
|
596 |
+
esc_attr( $first_ip_address )
|
597 |
+
);
|
598 |
+
|
599 |
+
$html .= sprintf(
|
600 |
+
__( 'IP Address %1$s', 'simple-history' ),
|
601 |
+
"<a target='_blank' href='{$iplookup_link}' class='SimpleHistoryLogitem__anonUserWithIp__theIp' data-ip-address='" . esc_attr( $first_ip_address ) . "'>" .
|
602 |
+
esc_html( $first_ip_address ) .
|
603 |
+
'</a>'
|
604 |
+
);
|
605 |
+
} elseif ( count( $arr_ip_addresses ) > 1 ) {
|
606 |
+
$ip_addresses_html = '';
|
607 |
+
|
608 |
+
foreach ( $arr_ip_addresses as $ip_address_header => $ip_address ) {
|
609 |
+
$iplookup_link = sprintf(
|
610 |
+
'https://ipinfo.io/%1$s',
|
611 |
+
esc_attr( $ip_address )
|
612 |
+
);
|
613 |
+
|
614 |
+
$ip_addresses_html .= sprintf(
|
615 |
+
'<a target="_blank" href="%3$s" class="SimpleHistoryLogitem__anonUserWithIp__theIp" data-ip-address="%4$s">%1$s</a>, ',
|
616 |
+
esc_html( $ip_address ), // 1
|
617 |
+
esc_html( $ip_address_header ), // 2
|
618 |
+
$iplookup_link, // 3
|
619 |
+
esc_attr( $ip_address ) // 4
|
620 |
+
);
|
621 |
+
}
|
622 |
+
|
623 |
+
// Remove trailing comma.
|
624 |
+
$ip_addresses_html = rtrim( $ip_addresses_html, ', ' );
|
625 |
+
|
626 |
+
$html .= sprintf(
|
627 |
+
__( 'IP Addresses %1$s', 'simple-history' ),
|
628 |
+
$ip_addresses_html
|
629 |
+
);
|
630 |
+
}
|
631 |
+
|
632 |
+
// } // multiple ip
|
633 |
+
$html .= '</span> ';
|
634 |
+
|
635 |
+
// $initiator_html .= "<strong>" . __("<br><br>Unknown user from {$context["_server_remote_addr"]}") . "</strong>";
|
636 |
+
// $initiator_html .= "<strong>" . __("<br><br>{$context["_server_remote_addr"]}") . "</strong>";
|
637 |
+
// $initiator_html .= "<strong>" . __("<br><br>User from IP {$context["_server_remote_addr"]}") . "</strong>";
|
638 |
+
// $initiator_html .= "<strong>" . __("<br><br>Non-logged in user from IP {$context["_server_remote_addr"]}") . "</strong>";
|
639 |
+
// } // End if().
|
640 |
+
return $html;
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Returns header output for a log row.
|
645 |
+
*
|
646 |
+
* Format should be common for all log rows and should be like:
|
647 |
+
* Username (user role) · Date · IP Address · Via plugin abc
|
648 |
+
* I.e.:
|
649 |
+
* Initiator * Date/time * IP Address * Via logger
|
650 |
+
*
|
651 |
+
* @param object $row Row data
|
652 |
+
* @return string HTML
|
653 |
+
*/
|
654 |
+
public function getLogRowHeaderOutput( $row ) {
|
655 |
+
$initiator_html = $this->getLogRowHeaderInitiatorOutput( $row );
|
656 |
+
$date_html = $this->getLogRowHeaderDateOutput( $row );
|
657 |
+
$via_html = $this->getLogRowHeaderUsingPluginOutput( $row );
|
658 |
+
$ip_address_html = $this->getLogRowHeaderIPAddressOutput( $row );
|
659 |
+
|
660 |
+
// Template to combine header parts.
|
661 |
+
$template = '
|
|
|
|
|
|
|
|
|
662 |
%1$s
|
663 |
%2$s
|
664 |
%3$s
|
665 |
%4$s
|
666 |
';
|
667 |
|
668 |
+
/**
|
669 |
+
* Filter template used to glue together markup the log row header.
|
670 |
+
*
|
671 |
+
* @since 2.0
|
672 |
+
*
|
673 |
+
* @param string $template
|
674 |
+
* @param object $row Log row
|
675 |
+
*/
|
676 |
+
$template = apply_filters(
|
677 |
+
'simple_history/row_header_output/template',
|
678 |
+
$template,
|
679 |
+
$row
|
680 |
+
);
|
681 |
+
|
682 |
+
// Glue together final result.
|
683 |
+
$html = sprintf(
|
684 |
+
$template,
|
685 |
+
$initiator_html, // 1
|
686 |
+
$date_html, // 2
|
687 |
+
$via_html, // 3
|
688 |
+
$ip_address_html // 4
|
689 |
+
);
|
690 |
+
|
691 |
+
/**
|
692 |
+
* Filter generated html for the log row header.
|
693 |
+
*
|
694 |
+
* @since 2.0
|
695 |
+
*
|
696 |
+
* @param string $html
|
697 |
+
* @param object $row Log row
|
698 |
+
*/
|
699 |
+
$html = apply_filters( 'simple_history/row_header_output', $html, $row );
|
700 |
+
|
701 |
+
return $html;
|
702 |
+
}
|
703 |
+
|
704 |
+
/**
|
705 |
+
* Returns the plain text version of this entry
|
706 |
+
* Used in for example CSV-exports.
|
707 |
+
* Defaults to log message with context interpolated.
|
708 |
+
* Keep format as plain and simple as possible.
|
709 |
+
* Links are ok, for example to link to users or posts.
|
710 |
+
* Tags will be stripped when text is used for CSV-exports and so on.
|
711 |
+
* Keep it on a single line. No <p> or <br> and so on.
|
712 |
+
*
|
713 |
+
* Example output:
|
714 |
+
* Edited post "About the company"
|
715 |
+
*
|
716 |
+
* Message should sound like it's coming from the user.
|
717 |
+
* Image that the name of the user is added in front of the text:
|
718 |
+
* Jessie James: Edited post "About the company"
|
719 |
+
*/
|
720 |
+
public function getLogRowPlainTextOutput( $row ) {
|
721 |
+
$message = $row->message;
|
722 |
+
$message_key = isset( $row->context['_message_key'] )
|
723 |
+
? $row->context['_message_key']
|
724 |
+
: null;
|
725 |
+
|
726 |
+
// Message is translated here, but translation must be added in
|
727 |
+
// plain text before
|
728 |
+
if ( empty( $message_key ) ) {
|
729 |
+
// Message key did not exist, so check if we should translate using textdomain
|
730 |
+
if ( ! empty( $row->context['_gettext_domain'] ) ) {
|
731 |
+
// phpcs:ignore WordPress.WP.I18n.NonSingularStringLiteralDomain, WordPress.WP.I18n.NonSingularStringLiteralText
|
732 |
+
$message = __( $message, $row->context['_gettext_domain'] );
|
733 |
+
}
|
734 |
+
} else {
|
735 |
+
// Check that messages does exist
|
736 |
+
// If we for example disable a Logger we may have references
|
737 |
+
// to message keys that are unavailable. If so then fallback to message.
|
738 |
+
if ( isset( $this->messages[ $message_key ]['translated_text'] ) ) {
|
739 |
+
$message = $this->messages[ $message_key ]['translated_text'];
|
740 |
+
} else { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedElse
|
741 |
+
// Not message exists for message key. Just keep using message.
|
742 |
+
}
|
743 |
+
}
|
744 |
+
|
745 |
+
$html = $this->interpolate( $message, $row->context, $row );
|
746 |
+
|
747 |
+
// All messages are escaped by default.
|
748 |
+
// If you need unescaped output override this method
|
749 |
+
// in your own logger
|
750 |
+
$html = esc_html( $html );
|
751 |
+
|
752 |
+
/**
|
753 |
+
* Filter generated output for plain text output
|
754 |
+
*
|
755 |
+
* @since 2.0
|
756 |
+
*
|
757 |
+
* @param string $html
|
758 |
+
* @param object $row Log row
|
759 |
+
*/
|
760 |
+
$html = apply_filters(
|
761 |
+
'simple_history/row_plain_text_output',
|
762 |
+
$html,
|
763 |
+
$row
|
764 |
+
);
|
765 |
+
|
766 |
+
return $html;
|
767 |
+
}
|
768 |
+
|
769 |
+
/**
|
770 |
+
* Get output for image
|
771 |
+
* Image can be for example gravar if sender is user,
|
772 |
+
* or other images if sender i system, wordpress, and so on
|
773 |
+
*/
|
774 |
+
public function getLogRowSenderImageOutput( $row ) {
|
775 |
+
$sender_image_html = '';
|
776 |
+
$sender_image_size = 32;
|
777 |
+
|
778 |
+
$initiator = $row->initiator;
|
779 |
+
|
780 |
+
switch ( $initiator ) {
|
781 |
+
// wp_user = wordpress uses, but user may have been deleted since log entry was added
|
782 |
+
case 'wp_user':
|
783 |
+
$user_id = isset( $row->context['_user_id'] )
|
784 |
+
? $row->context['_user_id']
|
785 |
+
: null;
|
786 |
+
|
787 |
+
$user = get_user_by( 'id', $user_id );
|
788 |
+
if ( $user_id > 0 && ( $user ) ) {
|
789 |
+
// Sender was user
|
790 |
+
$sender_image_html = $this->simpleHistory->get_avatar(
|
791 |
+
$user->user_email,
|
792 |
+
$sender_image_size
|
793 |
+
);
|
794 |
+
} elseif ( $user_id > 0 ) {
|
795 |
+
// Sender was a user, but user is deleted now
|
796 |
+
$sender_image_html = $this->simpleHistory->get_avatar(
|
797 |
+
'',
|
798 |
+
$sender_image_size
|
799 |
+
);
|
800 |
+
} else {
|
801 |
+
$sender_image_html = $this->simpleHistory->get_avatar(
|
802 |
+
'',
|
803 |
+
$sender_image_size
|
804 |
+
);
|
805 |
+
}
|
806 |
+
|
807 |
+
break;
|
808 |
+
}
|
809 |
+
|
810 |
+
/**
|
811 |
+
* Filter generated output for row image (sender image)
|
812 |
+
*
|
813 |
+
* @since 2.0
|
814 |
+
*
|
815 |
+
* @param string $sender_image_html
|
816 |
+
* @param object $row Log row
|
817 |
+
*/
|
818 |
+
$sender_image_html = apply_filters(
|
819 |
+
'simple_history/row_sender_image_output',
|
820 |
+
$sender_image_html,
|
821 |
+
$row
|
822 |
+
);
|
823 |
+
|
824 |
+
return $sender_image_html;
|
825 |
+
}
|
826 |
+
|
827 |
+
/**
|
828 |
+
* Use this method to output detailed output for a log row
|
829 |
+
* Example usage is if a user has uploaded an
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|