=== Settings Undo – Settings History, Rollback & Restore Options ===
Contributors: dotance
Tags: undo, rollback, settings, restore, history
Requires at least: 5.9
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Every settings change is recorded. See who changed what, compare old vs new, and undo it in one click. Works with any plugin or theme.

== Description ==

WordPress keeps revisions for posts and pages. It keeps nothing for settings. Save the wrong value on a plugin's options screen, or watch a colleague change something on Friday evening, and there is no history to go back to.

Settings Undo is that history. It records every real change to the options table made by a logged-in user – in WordPress itself, in any plugin, in any theme – and puts a timeline under **Tools → Settings Undo** with an Undo button on every entry.

**What you see for each change**

* Who made it, and when
* Which plugin, theme or WordPress core wrote it
* Which screen it came from – "Settings › Reading", a plugin's admin page, the Customizer, a REST route
* The value before and after, as a key-level diff for arrays (added, removed and changed keys) or side by side for simple values

**Undo**

* Undo one option, or every option a single save touched, in one click
* The undo itself is recorded, so it can be undone too
* Options that could lock you out – site URL, home URL, active plugins, theme, user roles – ask you to type the option name before they are restored

**Designed to be quiet**

A settings log is only useful if it is readable, so the plugin does not record everything. Transients, cron state, rewrite rules, update-check timestamps, cache keys and plugin version bumps are ignored. One settings form save that writes twelve options is one card in the timeline, not twelve. Changes made by cron, WP-CLI or anonymous requests are off by default and can be switched on.

**Safe by default**

* Only administrators (`manage_options`) can view the timeline or undo anything
* Values under keys that look like passwords, tokens or API keys are masked in the display; the stored value is intact, so an undo still works
* Old rows are pruned daily by age and by row count, both configurable
* Deleting the plugin keeps the history unless you tick "delete data on uninstall"

**For developers**

* `settings_undo_ignored_options` – filter an array of option names or `*` globs to ignore
* `settings_undo_max_value_size` – filter the byte cap above which a value is logged but not stored (default 512 KB)

Not in this version: multisite network options, WP-CLI commands, restore-to-a-point-in-time, and post content (WordPress revisions already cover that).

== Installation ==

1. Upload the `settings-undo` folder to `/wp-content/plugins/`, or install it from the Plugins screen.
2. Activate it. The history table is created on activation.
3. Go to **Tools → Settings Undo**. Save any settings page and it will appear there.

== Frequently Asked Questions ==

= Does it slow the site down? =

No. Nothing runs on the front end for visitors. Recording happens only when an option actually changes, and only after a cheap check that the option is not on the ignore list. Reading the timeline is one query per page.

= Why does a change I made not appear? =

Either the option is on the ignore list (transients, cron, caches, version numbers and similar noise), or the value was written by a background process – cron, WP-CLI or an anonymous request – which is not recorded unless you switch that on under Settings.

= Can I undo activating or deactivating a plugin? =

The `active_plugins` option is recorded and can be restored, with a typed confirmation. Note that restoring the list does not run a plugin's own activation or deactivation routines; proper activate/deactivate handling is planned for a later version.

= Where is the data stored? =

In one table, `{prefix}settings_undo_log`. Uninstalling the plugin leaves it in place unless "delete data on uninstall" is enabled.

= Is the diff available for every change? =

Values larger than 512 KB (serialised) are logged as "too large to store": you can see that the option changed, who changed it and when, but not the values, and they cannot be undone. The cap can be raised with the `settings_undo_max_value_size` filter.

== Screenshots ==

1. The timeline: one card per save, with who, when, which plugin, and which screen.
2. Inside a change set: every option the save touched, with Diff and Undo per row.
3. A key-level diff of an array option, collapsed to the keys that changed.
4. Undoing a protected option asks you to type its name.
5. The result after an undo; the undo is recorded as its own entry.
6. Settings: retention, background changes, masking, uninstall.

== Changelog ==

= 1.0.0 =
* First release: records add, update and delete of any option by a logged-in user; groups a request's writes into one change set; timeline with source, user, date and option filters; key-level diffs; undo one entry or a whole change set; typed confirmation for protected options; masking of secret-looking keys; daily pruning by age and row count.

== Upgrade Notice ==

= 1.0.0 =
First release.
