=== Clean unused shortcodes ===
Contributors: amrelarabi
Donate link: https://www.paypal.com/paypalme/amrelarabi
Tags: shortcode, clean, admin, tools, ui
Requires at least: 5.8
Tested up to: 6.9.4
Requires PHP: 7.4
Stable tag: 2.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Scan your site for orphaned shortcodes and remove them safely from post content and excerpts.

== Description ==

**Clean unused shortcodes** helps you find and remove shortcode tags left behind by old plugins, themes, or page builders — without hunting through posts one by one.

The tool lives under **Tools → Clean unused shortcodes**. Choose which public post types to scan, review the results, preview changes, then clean individual shortcodes or run a bulk cleanup.

= Highlights =

* **Scan by post type** — posts, pages, and other public types (media/attachments excluded).
* **Three result tabs** — unused (unregistered) shortcodes, used (registered and found), and registered but unused.
* **Content and excerpts** — scans both fields and shows where each shortcode appears.
* **Batched operations** — scan and clean large sites in chunks with a progress bar and cancel option.
* **Incremental scan** — optionally rescan only posts modified since the last run.
* **Dry-run preview** — see before/after snippets per post before saving.
* **Protected shortcodes** — allowlist tags you never want removed (e.g. `caption`, `embed`).
* **Skip on clean all** — exclude specific shortcodes from bulk cleanup.
* **Gutenberg-aware** — removes empty `wp:shortcode` blocks after the inner shortcode is stripped.
* **Hyphenated names** — detects shortcodes like `[my-slider]` as well as `[gallery]`.

= Who is this for? =

* Sites that deactivated plugins but still have `[shortcode]` tags in content.
* Editors who want a clear list of where each tag appears before deleting.
* Administrators cleaning up legacy content on staging before going live.

Always **back up your database** (or test on staging) before running bulk clean operations.

== Installation ==

1. Install the plugin through **Plugins → Add New** in WordPress, or upload the `clean-unused-shortcodes` folder to `/wp-content/plugins/`.
2. Activate **Clean unused shortcodes** through the **Plugins** screen.
3. Go to **Tools → Clean unused shortcodes**.
4. (Optional) Set **Protected shortcodes** — one name per line.
5. Select post types, click **Scan shortcodes**, then preview or clean as needed.

== Frequently Asked Questions ==

= What is an "unused" shortcode? =

A shortcode tag found in your scanned content that is **not** currently registered in WordPress (not in the global `$shortcode_tags` list) and is not on your protected list.

= Will this remove active plugin shortcodes? =

No. Registered shortcodes are listed under **Used** or **Registered but unused** and are not removed by the clean actions. Only unregistered (orphaned) tags in the **Unused** tab are removed.

= Does it work with the block editor? =

Yes. Shortcodes inside the **Shortcode** block (`wp:shortcode`) are scanned. After cleaning, empty block wrappers are removed so you do not get blank Shortcode blocks in the editor.

= Can I undo a clean? =

There is no built-in undo. Use a backup or revision restore if you need to roll back. Use **Preview** before cleaning to review changes.

= Does it scan custom post types? =

Yes. All public post types are available in the selector (attachments are excluded).

== Screenshots ==

1. Tools screen with post type selection, scan progress, and results tabs.
2. Unused shortcodes table with locations, skip option, preview, and clean actions.
3. Dry-run preview modal showing before and after content.

== Changelog ==

= 2.1.0 =
* Rebuilt admin tools UI (reliable vanilla JS; no React dependency on the tools screen).
* Post type multiselect — scan posts, pages, and other public types.
* **Batched scan and clean** with progress bar and cancel for large sites.
* **Incremental scan** — optionally rescan only posts changed since the last run.
* **Dry-run preview** with per-post before/after snippets (content and excerpt).
* **Protected shortcodes** allowlist and per-shortcode **skip on clean all**.
* Result tabs: unused, used, and **registered but unused**.
* Scan **excerpts**; show whether each hit is in content or excerpt.
* Detect **hyphenated** shortcode names (e.g. `my-slider`).
* Remove empty Gutenberg **Shortcode** (`wp:shortcode`) blocks after cleaning.
* Improved security (capability checks, nonces; no unauthenticated AJAX).

= 2.0.1 =
* Update author name.
* Tested with WordPress 6.9.4.

= 2.0.0 =
* Complete plugin rewrite using React for the admin UI.
* Preview unused and used shortcodes; location list with edit/view links.
* Clean All for unused shortcodes.

= 1.0.4 =
* Updated admin UI.
* Fixed white screen on the tools page.

= 1.0.3 =
* Tested with WordPress 6.1.1.

= 1.0.2 =
* Updated plugin description.

= 1.0.1 =
* Updated donate link.

= 1.0.0 =
* First release.

== Upgrade Notice ==

= 2.1.0 =
Major update after 2.0.1: batched scan/clean, dry-run preview, protected shortcodes, excerpt scanning, registered-but-unused tab, and Gutenberg-aware cleanup. Back up your database before bulk cleaning.

= 2.0.1 =
Maintenance release. Tested with WordPress 6.9.4.
