PluginProbe
404 Solution / 4.1.19
404 Solution v4.1.19
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / README.md

README.md in 404 Solution 4.1.19, at README.md

646 lines 52.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 # 404 Solution #
2
3 Automatically redirect 404 errors to the right page using a 7-engine matching pipeline and spell-checking algorithm. Zero configuration required.
4
5 ## Description ##
6
7 Stop losing visitors and search rankings to broken links. **404 Solution automatically redirects 404s to the right page** — not just your homepage — using a 7-engine matching pipeline that includes a spell-checking algorithm to find what visitors actually typed.
8
9 **Example:** A visitor hits `/prodcut/awesome-item` (typo). Most 404 redirect plugins send them to your homepage. 404 Solution's spell-checker finds `/product/awesome-item` and redirects them there automatically.
10
11 ### Why 404 Solution Is Different ###
12
13 Most redirect plugins fall into two categories: tools that require you to manually write every rule, or tools that blindly send every 404 to your homepage. 404 Solution does neither.
14
15 * **A spell-checking algorithm that actually matches typos.** Using Levenshtein distance and N-gram scoring, 404 Solution catches `/prodcut/`, `/categroy/`, and `/wooocmmerce/` and finds the real destination — something no other free plugin does.
16 * **7 matching engines, in sequence.** Slug match > URL fix > Title keywords > Category/tag paths > Content search > Spelling similarity > Archive fallback. The first engine with a confident match wins.
17 * **Automatic, from day one.** Install and activate. 404 Solution starts capturing and redirecting immediately. You can tune it; you don't have to.
18 * **Redirect management when you need it.** Full manual redirect editor, regex support, bulk actions, and CSV/JSON import compatible with Redirection's export format.
19 * **Debug mode that shows its work.** Enable debug logging and see exactly which engine chose a redirect and why — a level of transparency no competing plugin offers.
20 * **Built for real-world hosting.** Self-healing database tables, auto-recovery from corruption, automatic log trimming, and zero wp-admin-wide banners.
21 * **Ships with extras most plugins sell separately.** HTTP 410 Gone, 307/308/451 status codes, Google Search Console integration, REST API, WP-CLI support, email digest reports, and security probe detection — all free.
22
23 ### Unlike plugins that blindly redirect to your homepage ###
24
25 A 404-to-homepage redirect tells Google your broken URL is the same page as your homepage. That creates a soft 404 — a page Google may index as duplicate content, eroding crawl budget and ranking over time.
26
27 404 Solution redirects to the *correct* destination, or returns a proper 410 Gone when content is permanently removed. Both outcomes are better for search engines and for visitors.
28
29 ### How It Works ###
30
31 1. A visitor reaches a URL that returns a 404.
32 2. 404 Solution runs the URL through its 7-engine pipeline.
33 3. Each engine tries to find a confident match above its score threshold.
34 4. The first engine to find a match wins. The visitor is redirected to the correct page.
35 5. The redirect is logged. You can review, edit, or delete it from the dashboard.
36
37 The whole process adds no perceptible latency for visitors on non-404 pages. The matching pipeline only runs when a genuine 404 occurs.
38
39 ### Key Features ###
40
41 **Intelligent Automatic Matching**
42
43 * 7-engine matching pipeline (slug, URL fix, title, category/tag, content, spelling, archive)
44 * Levenshtein distance + N-gram scoring catches genuine typos
45 * Per-engine confidence thresholds — tune aggressiveness per engine
46 * Conditional engine groups — override the matching strategy for specific URL patterns
47 * Slug-change auto-detection — redirects created automatically when you rename a post
48 * Trash/deletion monitoring — redirect created automatically when a post is deleted
49
50 **Redirect Management**
51
52 * Manual redirect editor with bulk actions
53 * Full regular expression support
54 * CSV and JSON import/export (compatible with Redirection plugin format)
55 * .htaccess and Nginx server-level export
56 * Per-post and per-term exclusion via meta box
57 * HTTP status codes: 301, 302, 307 (method-preserving temporary), 308 (method-preserving permanent), 410 Gone, 451 Unavailable For Legal Reasons, and Meta Refresh
58 * GDPR-compliant: IP addresses are hashed before storage — never written to disk in plain text
59
60 **404 Monitoring and Logging**
61
62 * Captures every 404 hit with referrer, user agent, and timestamp
63 * Automatic log trimming with configurable disk usage limits
64 * Security monitoring — flags vulnerability scanner probes (.env, /wp-config.php, phpMyAdmin, etc.)
65
66 **Reporting and Diagnostics**
67
68 * Stats dashboard with traffic trend charts (404s, redirects, captures over time)
69 * Email digest reports
70 * Debug logging — see which engine fired and why
71 * Google Search Console integration — import crawl errors and push fixes
72 * Internal link scanner to find broken links before visitors do
73
74 **Developer and Integrator Tools**
75
76 * REST API for redirect management
77 * WP-CLI subcommands (list, create, delete, import, export)
78 * Scheduled maintenance cron
79 * Full WordPress Multisite support
80
81 **Compatibility**
82
83 * WooCommerce (products, variations, categories, custom URLs)
84 * Yoast SEO, Rank Math
85 * WPML, Polylang, TranslatePress
86 * Easy Digital Downloads
87 * All custom post types and custom taxonomies
88
89 ### Perfect For ###
90
91 * **eCommerce sites** (WooCommerce, EDD) with changing product URLs
92 * **Content sites** with evolving permalink structures
93 * **Migrated sites** where old URLs need to map to new content
94 * **Large sites** with thousands of pages where manual redirects are impractical
95
96 ## Installation ##
97
98 1. Unzip the files and upload the contents to `/wp-content/plugins/`.
99 2. Activate the plugin.
100 3. Use the `Settings -> 404 Solution` options page to set the options.
101
102 ## Frequently Asked Questions ##
103
104 ### How is this different from the Redirection plugin? ###
105
106 Redirection is a manual redirect manager — you write the rules, it applies them. That is useful when you know in advance which URLs will break. 404 Solution handles the URLs you don't know about: it automatically finds the right destination using a 7-engine matching pipeline and a spell-checking algorithm.
107
108 **Example:** If a visitor types `/prodcut/awesome-item`, Redirection does nothing unless you manually created that specific rule. 404 Solution finds `/product/awesome-item` automatically.
109
110 The two plugins are complementary. Many sites run both: Redirection for planned migrations and 404 Solution for everything else.
111
112 ### How is this different from 404 to 301? ###
113
114 404 to 301 redirects ALL 404 errors to one fixed destination (usually the homepage). 404 Solution finds the actual page the visitor was looking for. Sending visitors to your homepage is poor UX and can create soft 404 problems in Google Search Console.
115
116 ### How is this different from WP 404 Auto Redirect to Similar Post? ###
117
118 WP 404 Auto Redirect uses keyword matching, which works when the URL contains recognizable words from a post title. It fails on character-level typos — a URL like `/prodcut/` has no keyword that matches "product."
119
120 404 Solution adds Levenshtein spell-checking, which catches transpositions and typos regardless of whether the keywords match. It also includes: full 404 logging, manual redirect management, CSV import/export, 410/451 status codes, GDPR IP hashing, debug logging, REST API, and WP-CLI support.
121
122 ### What HTTP status codes are supported? ###
123
124 **301** (permanent redirect), **302** (temporary redirect), **307** (temporary, method-preserving), **308** (permanent, method-preserving), **410 Gone** (correct response for permanently deleted content — better for SEO than a 301 to homepage), **451 Unavailable For Legal Reasons**, and **Meta Refresh** (client-side HTML redirect).
125
126 Using 410 instead of redirecting deleted content to your homepage produces better results in Google Search Console and prevents soft-404 indexing.
127
128 ### Will this slow down my site? ###
129
130 No. The matching pipeline only runs when a genuine 404 occurs — normal page loads are unaffected. For large sites, 404 Solution uses N-gram indexing and caching tables to keep matching fast. Once a redirect is established, subsequent hits are served from the redirect table directly, bypassing the pipeline.
131
132 ### Does it work with WooCommerce? ###
133
134 Yes. 404 Solution indexes WooCommerce products, product variations, product categories, and tags. When a product URL changes or a product is deleted, the appropriate redirect is created automatically.
135
136 ### What happens when a redirect destination is deleted? ###
137
138 404 Solution detects when a destination post is trashed or deleted and flags the redirect. Redirects pointing to deleted content are highlighted in the redirect table so nothing slips through unnoticed. The daily maintenance cron automatically removes orphaned auto-redirects.
139
140 ### Can I import redirects from another plugin? ###
141
142 Yes. 404 Solution imports CSV and JSON in the Redirection plugin's export format. It can also directly import from Rank Math, Yoast SEO, AIOSEO, and Safe Redirect Manager's database tables from the Tools tab.
143
144 ### Is it GDPR compliant? ###
145
146 Yes. IP addresses are hashed using a one-way algorithm before storage — the original IP is never written to disk. Log retention limits are configurable. No data is transmitted to external servers.
147
148 ### Does it support regex? ###
149
150 Yes. Manual redirect rules support full regular expression syntax for source URLs.
151
152 ### Does it work with WPML, Polylang, or TranslatePress? ###
153
154 Yes. 404 Solution detects the active language from the multilingual plugin's API and resolves redirect destinations to the correct translated version automatically.
155
156 ### Can I use WP-CLI to manage redirects? ###
157
158 Yes. 404 Solution includes WP-CLI subcommands for listing, creating, deleting, importing, and exporting redirects — useful for scripted migrations and DevOps workflows.
159
160 ### Does it work after a site migration? ###
161
162 Yes. 404 Solution is ideal for site migrations: slug-change auto-detection, URL typo correction (strips `.html`, `.php`, `.asp`), hierarchical category path resolution, and regex redirects for bulk pattern changes.
163
164 ### Can I redirect all 404s to a specific page? ###
165
166 Yes. Go to **Settings > 404 Solution > Redirect all unhandled 404s to** and select your preferred fallback page.
167
168 ### How do I manage log files and disk usage? ###
169
170 Log cleanup is automatic. Configure maximum log size under **Options > General Settings > Maximum log disk usage**. You can also manually clear logs from the Logs page.
171
172 ### Can I exclude certain URLs from being processed? ###
173
174 Yes. Use **Options > Advanced Settings > Files and Folders Ignore Strings** to add paths to ignore. Per-post and per-term exclusion is also available via the edit screen checkbox.
175
176 ### How do I exclude a specific post or page? ###
177
178 Edit the post/page and check the "Exclude from 404 Solution redirects" checkbox in the sidebar. Category and tag terms can also be excluded via term meta on the edit screen.
179
180 ### Have you written any other programs? ###
181
182 Check out [](https://www.ajexperience.com/AJ Experience](https://www.ajexperience.com/](https://www.ajexperience.com/) for other useful tools and resources.
183
184 ## Screenshots ##
185
186 1. **Redirect Dashboard** — Active redirects with status code badges (301, 302, 307, 308, 410, 451) and match confidence scores. Sort, search, and bulk-edit without leaving the page.
187 ![1. Redirect Dashboard](https://plugins.svn.wordpress.org/404-solution/trunk/assets/screenshot-1.jpg)
188
189 2. **Stats and Trends** — Traffic trend charts plotting 404 hits, redirects, and captures over time. See which URLs break most often.
190 ![2. Stats and Trends](https://plugins.svn.wordpress.org/404-solution/trunk/assets/screenshot-2.jpg)
191
192 3. **Debug Mode** — Enable debug logging to see exactly which of the 7 engines fired, what score it assigned, and why it chose that destination.
193 ![3. Debug Mode](https://plugins.svn.wordpress.org/404-solution/trunk/assets/screenshot-3.jpg)
194
195 4. **Captured 404s** — Every 404 logged with URL, referrer, user agent, and timestamp. Create a redirect for any row with one click.
196 ![4. Captured 404s](https://plugins.svn.wordpress.org/404-solution/trunk/assets/screenshot-4.jpg)
197
198 5. **Settings Page** — Enable/disable individual matching engines, set per-engine confidence thresholds, configure fallback behavior.
199 ![5. Settings Page](https://plugins.svn.wordpress.org/404-solution/trunk/assets/screenshot-5.jpg)
200
201 6. **Email Digest** — Weekly email digest with top 404 URLs and hit counts.
202 ![6. Email Digest](https://plugins.svn.wordpress.org/404-solution/trunk/assets/screenshot-6.jpg)
203
204 ## Changelog ##
205
206 ## Version 4.1.19 (May 17, 2026) ##
207
208 **New Features**
209
210 * Regex redirects are now auto-detected. When you save or import a redirect that contains regex characters (wildcards, brackets, pipes), the plugin automatically marks it as a regex redirect and applies the correct syntax. No need to manually check the "Treat as regex" box. An admin notice confirms the auto-promotion with Edit and Undo links.
211 * Debug logs now automatically redact sensitive server details (database name, table prefix, filesystem paths) so logs can be shared safely without manual editing.
212
213 **Bug Fixes**
214
215 * Fixed the Confidence dropdown filter on admin tables only working on the initial page load. Changing the filter and then navigating pages or waiting for the background refresh would reset it to "All", showing every row.
216 * Fixed invalid regex patterns in CSV imports crashing the import. Invalid patterns are now validated during import and suppressed at runtime instead of causing errors.
217 * Fixed the repair-and-retry path continuing to report an error after the repair succeeded. The error is now cleared immediately after a successful repair.
218 * Fixed a potential SQL ambiguity error in log queries on sites with certain JOIN configurations.
219 * Fixed all 6 scheduled tasks not being removed when the plugin is deactivated. Previously some cron hooks were left behind and would trigger errors until manually cleared.
220 * Fixed the "Undo" link on regex auto-promotion notices not reverting the URL on the next page load. The original URL is now correctly restored along with the Manual status.
221 * Fixed a rare race on shared hosting where a dropped database connection during the admin table rebuild could let a second worker drop the rebuild's working table out from under the first, producing "Table doesn't exist" or "Can't find .frm file" errors. The rebuild now releases its database lock between each step so a dropped connection loses at most one step of progress instead of the entire 11-step run.
222
223 **Improvements**
224
225 * Bulk CSV and WP-CLI imports are significantly faster. A 10,000-row import that previously issued ~60,000 extra cache-invalidation queries now batches them into a single invalidation at the end.
226 * Admin tables now update immediately after any change, including changes made via WP-CLI, the REST API, or cross-plugin imports, instead of showing stale data until the next cache rebuild.
227 * The admin settings page now validates URL length and rejects negative numeric values, preventing misconfigured redirects.
228
229 **Internationalization**
230
231 * Added translations for 6 new strings in all 12 language files.
232
233 ## Version 4.1.18 (May 13, 2026) ##
234
235 **Bug Fixes**
236
237 * Fixed the admin table cache rebuild getting stuck on the same step after a dropped database connection. The rebuild now auto-resumes from where it stopped on the next request, instead of retrying the same failing query forever.
238 * Fixed admin actions that hit an expired session nonce showing a generic "security check failed" error. The session is now silently refreshed and the action retried, so the expiry is invisible to the administrator.
239 * Fixed transient invalid AJAX responses on admin tables producing "undefined" errors. The admin pages now validate the response shape before reading it and surface a clear error instead.
240 * Fixed the "missing database table" admin notice being cleared by the next successful query in the same request, so the admin never saw it. The generic auto-clear now skips the missing-table notice; that notice is cleared only by the dedicated repair-success path.
241
242 **Improvements**
243
244 * Captured 404s and Page Redirects admin tables load noticeably faster on large sites. The total log-count query is now cached on the maximum log id (avoiding a full log-table scan on every page load), log queries no longer sort by non-indexed columns, the Most Unused Redirects report reads from the pre-aggregated hits rollup instead of scanning raw logs, and the dashboard activity trend is cached between admin page loads.
245 * When WordPress cron is broken and the log hits rollup falls behind, the plugin now surfaces an admin notice on its own pages explaining how to fix it, instead of silently letting the admin tables show stale numbers.
246
247 **Internationalization**
248
249 * Added translations for 13 admin strings that were previously displayed in English even on non-English sites.
250
251 ## Version 4.1.17 (May 10, 2026) ##
252
253 **Bug Fixes**
254
255 * Fixed repeated "Access denied" errors and silently-stuck Captured 404s and Page Redirects pages on shared and managed hosting environments where certain database privileges are restricted. The rebuild now skips the affected step and continues, instead of retrying the same denied operation on every cron run and emailing the site administrator.
256 * Fixed the rebuild silently never starting on managed or sharded MySQL services (such as PlanetScale and Vitess) that do not support standard MySQL named locks. The plugin now uses an alternate locking mechanism on these hosts.
257 * Fixed the rebuild getting permanently stuck after a previous run was interrupted (for example, by a server restart mid-rebuild). The plugin now detects and cleans up leftover state at the start of the next rebuild so it can complete normally.
258 * Fixed the rebuild silently waiting forever when WordPress scheduled tasks (cron) are disabled and no external cron is configured. The plugin now shows a clear admin notice with guidance on how to resolve it.
259 * Improved compatibility with multisite networks during long-running rebuilds that span multiple background tasks.
260 * Improved compatibility with persistent object caches (Redis, Memcached) so that rebuild progress is reliably saved even when the cache layer is briefly inconsistent.
261 * Improved compatibility with HyperDB, LudicrousDB, and other custom database drop-ins.
262
263 **Improvements**
264
265 * The plugin now self-detects unusual PHP and database hosting limits (memory limit, time limit, strict SQL modes, query packet size) at the start of each rebuild and adapts to work within them, instead of failing on restrictive hosts.
266
267 ## Version 4.1.16 (May 8, 2026) ##
268
269 **Bug Fixes**
270
271 * Fixed the Captured 404s and Page Redirects admin pages getting stuck on "Creating build buffer (1/11)" forever on hosts with the standard 30-second PHP execution limit (the default on most shared hosting). The cache rebuild was yielding before inserting any rows because it was reserving more PHP time than the request actually had, so each rebuild request returned without making progress. The first batch of every rebuild step now always runs, so the rebuild reliably moves forward on a typical 30-second host.
272 * Fixed Captured 404s and Page Redirects admin pages still failing to load when the database killed a single rebuild step (max statement time exceeded, lost connection, lock timeout): the entire rebuild used to give up, but it now resumes on the next request from where it left off, at every step.
273 * Fixed brief network blips and intermittent 5xx responses during a long rebuild causing the admin page to show "Could not finish refreshing data" instead of continuing to wait. Transient errors are now treated as a no-progress tick and the page keeps polling.
274 * Fixed the rebuild getting stuck retrying the same single-statement step (index build, hit-count update, or sort-index step) when the host's database statement timeout was shorter than that step needed to complete. Those steps used to retry with the same too-tight timeout forever; now the per-query timeout is extended for the retry so the step can finish.
275
276 **Improvements**
277
278 * The admin-table rebuild now adapts its batch size to the host. If a batch is killed by the database, the next attempt uses a smaller batch, and the smaller size is remembered for the rest of the rebuild so slow shared hosts converge on a size they can actually finish.
279 * Per-query timeouts during the rebuild are now sized to the host's own statement timeout (MariaDB max_statement_time / MySQL max_execution_time), so a kill produces a clean classifiable error the rebuild can resume from rather than a dropped connection.
280
281 ## Version 4.1.15 (May 6, 2026) ##
282
283 **Bug Fixes**
284
285 * Fixed a plugin load fatal on PHP 7.4 to 8.1 hosts that was introduced in 4.1.14. A constant inside a trait (added with the staged view rebuild) is only valid in PHP 8.2 and later; the declared minimum is PHP 7.4, so this restores compatibility for all supported PHP versions.
286
287 ## Version 4.1.14 (May 6, 2026) ##
288
289 **Bug Fixes**
290
291 * Fixed Captured 404s and Page Redirects admin tables getting stuck or returning "Could not load table data" on very large sites while the table cache was being rebuilt. The rebuild now resumes in small background steps and the admin screen keeps polling progress until the data is ready.
292 * Fixed a race where an admin table could retry too soon after a background rebuild started, causing repeated loading failures instead of waiting for the rebuilt data.
293
294 **Improvements**
295
296 * The Captured 404s and Page Redirects admin tables now use a staged cache rebuild that splits expensive destination, status, and hit-count work into bounded batches. Large sites should see more reliable table loading without long-running AJAX requests.
297 * Added clearer in-page progress handling while the admin table cache is warming, so administrators can tell the plugin is still working instead of seeing a static loading state.
298
299 ## Version 4.1.13 (May 2, 2026) ##
300
301 **Bug Fixes**
302
303 * Fixed "Could not load table data" timeouts on the Captured 404s and Page Redirects admin tables. On sites with a large WordPress posts table, the count query now skips unrelated JOINs when no search filter is active, and admin table caches are warmed in the background across multiple short requests instead of one long one — so the tables reliably load even when individual queries are slow.
304
305 **Improvements**
306
307 * The plugin admin footer now includes a collapsible Debug Info section showing per-stage AJAX timings, errors, and database query timings for the Captured 404s and Page Redirects views. When reporting a slow or stuck admin table, you can copy this directly without opening browser developer tools.
308 * SQL errors are now recorded before any automatic recovery (table repair, retry with a relaxed collation) runs, so the original cause of a failing query stays visible in the support log instead of being overwritten by the recovery attempt's own messages.
309
310 ## Version 4.1.12 (May 1, 2026) ##
311
312 **Bug Fixes**
313
314 * Fixed Captured 404s and Page Redirects table AJAX requests timing out while background log-cache maintenance was running. Maintenance that is triggered by an AJAX table load now runs through scheduled background tasks instead of shutdown work tied to the same HTTP request.
315 * Fixed debug-log setup failing on sites with negative or fractional WordPress timezone offsets.
316 * Fixed diagnostic logging paths that could throw while trying to report another error, which could hide the original problem behind a secondary logging failure.
317
318 ## Version 4.1.11 (May 1, 2026) ##
319
320 **Bug Fixes**
321
322 * Fixed loss of captured-404 history when the database performed automatic repair of a crashed log table. The plugin previously dropped and recreated the affected table after repeated repair failures, destroying logged hits in the process. It now leaves the table alone if repair cannot succeed, preserving your captured-404 history.
323 * Fixed loss of log data during repair of damaged plugin tables that were missing their primary key column. This was the underlying cause of the log-history loss reported during the 4.1.6 to 4.1.7 upgrade. The repair now preserves all existing rows instead of recreating the table from scratch.
324 * Fixed timeouts during the nightly log-cache rebuild on sites with aggressive log retention. The rebuild now reliably completes within shared-host time limits.
325
326 **Improvements**
327
328 * The Captured 404s list and other admin views that read log data now load substantially faster on sites with large log tables. A new indexed column replaces a slower per-row computation; existing sites are updated in the background during nightly maintenance and speed up over time.
329
330 ## Version 4.1.10 (Apr 30, 2026) ##
331
332 **Bug Fixes**
333
334 * Fixed disk-full, read-only, and crashed-table conditions encountered during log flush and N-gram cron scheduling escalating to error level and triggering developer email reports. These hosting conditions are now classified as warnings — the plugin already degrades past them — so they no longer spam the admin's inbox.
335 * Fixed admin AJAX error notices showing only generic HTTP/textStatus information when a paginated admin view timed out or returned a 500. The notice now includes the elapsed request time, the server-side processing stage that was in flight when the failure occurred, and the redacted SQL of the failing query when available, so the cause is identifiable without a server log dump.
336 * Fixed a parse-time fatal on PHP 7.4 through 8.1 caused by two trait-level constants introduced with the canonical-URL backfill work. The constants are now declared on the using class so the trait file parses cleanly on every supported PHP version.
337
338 **Improvements**
339
340 * The Page Redirects and Captured 404s admin views are now significantly faster on installs with very large redirects tables. Each redirect now stores a precomputed canonical URL that is indexed and JOINed against the hits rollup, eliminating the per-row CONCAT/TRIM evaluation that could time out the admin AJAX request on sites with hundreds of thousands of captured rows. The column is backfilled in chunks during the upgrade and the nightly maintenance cron, so large sites converge across cron ticks without blocking any single request.
341 * The daily cron that flags dead-destination redirects now scales with URL count rather than raw log-row count. The query now JOINs against the precomputed `logs_hits` rollup with a new `failed_hits` column, completing in milliseconds even on sites with millions of log rows where it previously timed out.
342 * The admin AJAX timeout for explicit user actions (sorting, filtering, pagination) was raised from 15 seconds to 45 seconds. Background detect-only refreshes still use the tight 15-second budget, so the longer timeout only applies when the admin is actively waiting.
343 * Several catch blocks across the plugin that previously swallowed exceptions silently now emit a warning breadcrumb to the support log, so unexpected failure paths are visible in support bundles instead of vanishing.
344
345 ## Version 4.1.9 (Apr 29, 2026) ##
346
347 **Bug Fixes**
348
349 * Fixed potential over-deletion of log history during the daily cron cleanup. The destructive DELETE was sized using an approximate row count from MySQL metadata, which can drift by orders of magnitude on InnoDB. The cron now gates the delete on an exact byte-size check before deciding what to remove.
350 * Fixed captured-URL counts undercounting when the same URL was logged with and without leading or trailing slashes (e.g. `/foo`, `foo`, `/foo/`). URL variants now collapse to a single canonical row in the hits rollup, restoring slash-tolerant matching that regressed in 4.1.7.
351 * Fixed Email Digest dropping captured URLs that had zero recent hits. The "Top Captured 404s" section now lists captured rows with no hits as well as those with hits, matching the on-screen behavior.
352 * Fixed Email Digest rendering a misleading "No captured 404s in this period" notice while the hits rollup was being rebuilt. The digest now ships with an explicit "Top URLs unavailable: log rollup is being rebuilt" message instead.
353 * Fixed the high-impact captured-count cache holding a value of zero for 24 hours when the rollup was unavailable or the query errored. The result is now cached only on a successful query, so the count recovers on the next page load.
354 * Fixed the Stats trend chart cache being polluted with empty results when the trend query errored or timed out.
355 * Fixed admin search inputs on Page Redirects and Captured 404s rendering a stray "O"-shaped SVG glyph above the search box.
356 * Fixed the health bar "unavailable" indicator rendering as a transparent dot during rollup rebuild — it now displays as a muted gray dot to communicate the transient state.
357 * Fixed every frontend 404 falling through to the theme 404 page on installs where the database upgrade could not complete (corrupted DDL files, opcache divergence, restrictive shared hosting). The redirect lookup now falls back to a schema-tolerant query against the existing redirects table, so manual redirects keep firing while the upgrade is stuck. Trade-off: scheduled redirects briefly stop honoring their start/end windows during the degraded window.
358 * Fixed asynchronous page suggestions failing to surface for long or low-overlap 404 URLs. The async worker now prioritizes recall over worst-case latency, since it already runs out-of-band and is rate-limited.
359 * Fixed admin tables remaining stuck on "Loading…" indefinitely when the AJAX request to fetch table data hangs (for example, while the plugin is recreating a missing database table on the slow path). The AJAX call now has a 15-second client-side timeout, the retry/fallback path replaces the loading rows with a clear error message instead of just stripping the placeholder attribute, and AJAX errors render a non-blocking admin notice instead of a native browser `alert()` dialog.
360
361 **Improvements**
362
363 * The Captured 404s and Page Redirects admin tables now render quickly even on sites with millions of log rows. The high-impact captured count, the per-row hit population query, the Email Digest top-captured query, and the Stats trend chart now all read from the pre-aggregated `logs_hits` rollup table, eliminating multi-second full-log scans that could time out behind Cloudflare and other reverse proxies.
364 * Health bar AJAX is now decoupled from pagination — the redirects table renders immediately while the health bar hydrates in a separate request, so a slow rollup query no longer blocks first paint.
365 * The daily cron now reads log row counts from MySQL `information_schema` metadata instead of running a full index scan on every nightly tick.
366 * Permalink keyword cron updates are now issued as a single bulk SQL query instead of up to 500 single-row UPDATEs per cycle, sharply reducing database load on busy sites.
367 * The anonymous suggestion-compute endpoint now enforces a per-IP rate limit and rejects unauthorized requests before any plugin classes are loaded.
368
369 ## Version 4.1.8 (Apr 28, 2026) ##
370
371 **Bug Fixes**
372
373 * Fixed a critical 4.1.7 regression where the `wp_abj404_logs_hits` cache table was dropped during the 4.1.6 → 4.1.7 upgrade and never recreated. Affected sites saw "Table doesn't exist" errors flooding the debug log and triggering email reports. Sites that already upgraded to 4.1.7 will have the table automatically recreated when they upgrade to 4.1.8 — the cache repopulates on the next scheduled rebuild. The destructive table-recreation step that caused this regression has been hardened to require positive evidence before dropping any table.
374 * Fixed `mysqli_num_fields()` TypeError on PHP 8.1+ MariaDB sites caused by the new query timeout wrapper (4.1.7) being passed to `wpdb::get_results()` for non-SELECT queries. INSERT/UPDATE/DELETE/DDL queries now route through `wpdb::query()` so the wrapper no longer confuses WordPress's query classifier.
375 * Fixed view-cache table self-repair only running on the upgrade path. Activation, scheduled cron runs, and upgrade now all repair a stripped view-cache table before any further table maintenance, so broken installs heal themselves regardless of how the plugin loads.
376 * Fixed spurious "Table doesn't exist" debug-log noise and a stale `.notice-error` admin banner during fresh installs. Pre-create maintenance queries are now silent when their target tables don't yet exist.
377
378 **Improvements**
379
380 * Collation mismatches between database tables are now repaired automatically and silently. Previously these surfaced as admin notices; the plugin now runs collation correction on detection (rate-limited to once per hour), retries the original query, and only logs at debug level — no user action required.
381
382 ## Version 4.1.7 (Apr 25, 2026) ##
383
384 **Bug Fixes**
385
386 * Fixed HTTP 524 timeout error on the Captured 404s admin tab for sites behind Cloudflare or other reverse proxies. The hits table rebuild query (which joins the logs table with redirects) is now split into a fast chunked pre-aggregation that scales to millions of log rows.
387 * Fixed AJAX responses not being flushed before shutdown hooks, which could cause proxy timeouts even when the response data was ready.
388 * Fixed ANALYZE TABLE running on every Settings page load, causing unnecessary database overhead.
389
390 **Improvements**
391
392 * All database queries now have automatic execution time limits (not just SELECT queries). INSERT...SELECT, UPDATE, DELETE, and DDL queries are also protected on MariaDB; INSERT...SELECT is also protected on MySQL.
393
394 ## Version 4.1.6 (Apr 23, 2026) ##
395
396 **New Features**
397
398 * Automatic query timeout — all SELECT queries now include a server-side execution time limit, preventing runaway queries from locking the database on shared hosting.
399 * WordPress URL-guess fallback — when no matching engine finds a redirect, the plugin now tries WordPress's built-in URL guessing as a last-resort redirect before returning a 404.
400
401 **Improvements**
402
403 * Admin pages now load instantly — all heavy database queries on the Redirects, Captured 404s, Logs, and Settings pages are deferred to AJAX, eliminating blocking page loads on large sites.
404 * Optimized three slow view queries that could cause timeouts on sites with large redirect and log tables.
405
406 **Bug Fixes**
407
408 * Fixed AJAX error state leaving placeholder loading attributes on admin tables, preventing interaction until page reload.
409 * Fixed duplicate bottom table separator appearing after AJAX table hydration.
410 * Fixed Logs page not loading via AJAX due to missing `.perpage` class on the per-page select element.
411 * Fixed stray search filter and unwanted top pagination placeholders appearing on admin pages.
412 * Fixed SQL query referencing a non-existent column in the logs-hits join query.
413
414 ## Version 4.1.5 (Apr 22, 2026) ##
415
416 **New Features**
417
418 * Simple mode Phase 3 — streamlined UI with contextual guidance, suggested destinations for captured 404s, and auto-created redirects for first-time users. Hides advanced columns and options in Simple mode for a cleaner experience.
419 * Centralized Google OAuth — one-click Google Search Console connection via a Cloudflare Worker relay, replacing the manual client-ID setup.
420
421 **Bug Fixes**
422
423 * Fixed "Illegal mix of collations" errors when WordPress core tables use `utf8mb3` and plugin tables use `utf8mb4`. Core columns are now wrapped with `CONVERT(...USING utf8mb4)` before applying `COLLATE`.
424 * Fixed collation mismatch in `getPublishedImageIDs` query when comparing term names across tables with different collations.
425 * Fixed `opcache_invalidate()` emitting a PHP warning on hosts that restrict the function via `disable_functions` (e.g. some WP Engine/Flywheel configurations).
426 * Fixed potential out-of-memory crash when the `logs_hits` fallback query ran without a row limit — now capped at 5,000 rows.
427 * Fixed four small correctness issues in redirect filtering, view queries, settings save, and redirect-table rendering.
428
429 **Improvements**
430
431 * Hardened admin page rendering against out-of-memory errors, corrupted options, and hook failures — the plugin now always shows its admin menu even when dependencies fail, and catches fatal errors with a shutdown handler fallback.
432 * Migrated four redirect query methods to the centralized `queryAndGetResults()` handler for consistent error handling and retry logic.
433
434 **Internationalization**
435
436 * Added Simple mode Phase 3 strings to all 17 locale PO files.
437 * Added missing admin error message translations across all locale PO files.
438
439 ## Version 4.1.4 (Apr 20, 2026) ##
440
441 **Bug Fixes**
442
443 * Fixed "Illegal mix of collations" errors on spell-checker and permalink-cache queries when plugin tables and WordPress core tables use different collations (e.g. `utf8mb4_unicode_520_ci` vs `utf8mb4_unicode_ci`). Extended the `COLLATE` protection pattern to `updatePermalinkCache.sql`, `getPublishedPagesAndPostsIDs.sql`, and `getIDsNeededForPermalinkCache.sql`.
444 * Fixed redirect edit form rejecting type=0 (Default 404 Page) with "Data not formatted properly" error. The validation was unable to distinguish "no type provided" from "type is 0" after int-casting.
445 * Fixed plugin tables not being detected after a hosting migration or `$table_prefix` change in `wp-config.php`. The daily maintenance cron now triggers prefix adoption so orphaned tables are auto-recovered without requiring a manual deactivate/reactivate cycle.
446 * Fixed transient PHP fatal errors during plugin upgrades on hosts with aggressive opcache settings (WP Engine, Flywheel, etc.) caused by stale bytecode from the previous version. Critical class files are now invalidated via `opcache_invalidate()` at the start of the upgrade.
447
448 **Improvements**
449
450 * The daily maintenance cron now checks and converts table engines back to InnoDB, fixing persistent MyISAM reversions caused by hosting environments that reset the storage engine between plugin upgrades.
451
452 ## Version 4.1.3 (Apr 17, 2026) ##
453
454 **Bug Fixes**
455
456 * Fixed spell checker throwing `get_object_vars()` TypeError on PHP 8+ when `get_term()` returns a non-object value (e.g. from a corrupted object cache). The tag and category matching branches now use `is_object()` guards before accessing term properties.
457 * Fixed Google Search Console integration returning HTTP 400 errors — the API does not support `groupType: 'or'` in dimension filter groups. Each URL is now queried individually.
458
459 ## Version 4.1.2 (Apr 16, 2026) ##
460
461 **Bug Fixes**
462
463 * Fixed spell checker consuming ~61MB of memory on large sites — restructured the algorithm to use ~16KB regardless of site size.
464 * Fixed a race condition in the `start_ts` column migration that could cause errors when multiple processes triggered the upgrade simultaneously.
465 * Fixed HOME type pages displaying the wrong title in the suggestion results.
466 * Fixed admin settings page showing a blank page instead of a visible error when the current user lacks the required permission.
467
468 **Improvements**
469
470 * Added all SQL files to the boot integrity check, ensuring corrupted or missing schema files are detected during plugin startup.
471
472 ## Version 4.1.1 (Apr 9, 2026) ##
473
474 **Bug Fixes**
475
476 * Fixed statistics page showing all zeros even when the logs page had data. Three separate bugs combined to cause this: the trend chart SQL was comparing `dest_url IS NULL` instead of `dest_url = '404'` (never matching real 404 entries); the stats dashboard returned an empty placeholder on first load instead of computing real data; and `getStatsCount()` threw an exception on empty query results, causing cascading failures that zeroed out all stats.
477
478 **New Features**
479
480 * Added heartbeat debug log emails for opted-in sites. Sites with the "send error logs" option enabled now have a 1-in-100 daily chance of sending their full debug zip even when no errors are detected, confirming the error-reporting pipeline is working. Subject line reads "heartbeat" instead of "error" for easy filtering.
481
482 ## Version 4.1.0 (Apr 4, 2026) ##
483
484 **New Features**
485
486 * Added built-in 404 suggestion page with one-click setup — selecting "Suggest similar pages" automatically creates a page with the `[abj404_solution_page_suggestions]` shortcode. No manual page creation or shortcode knowledge required.
487 * Simplified 404 behavior setting with visual tile picker — choose between "Suggest similar pages" (recommended), "Redirect to homepage", "Custom page", or "Theme default 404" with a single click.
488 * Block editor notice when editing the system suggestion page — warns editors that the page is managed by 404 Solution to prevent accidental shortcode removal.
489
490 **Bug Fixes**
491
492 * Fixed infrastructure database errors (disk full, read-only, crashed tables, connection lost) being logged at ERROR level from direct query call sites, triggering unnecessary developer email reports. All 17 direct-$wpdb error sites now use centralized infrastructure error classification and log as WARN.
493 * Fixed multisite cross-prefix missing-table errors being logged at ERROR level — when wp-cron references another subsite's table, the error is now correctly classified as WARN since it's not actionable from the current site's context.
494 * Fixed N-gram index creation failing when expected columns were missing from the logs table — now guards against missing columns before attempting index creation.
495 * Fixed N-gram cache rebuild progress exceeding 100% in some edge cases.
496 * Fixed "required" attribute remaining on custom page picker input when switching away from "Custom page" behavior tile.
497 * Improved prefix mismatch diagnostic message to distinguish multisite installations (normal cross-subsite references) from single-site prefix mismatches (wp-config.php issue).
498
499 ## Version 4.0.4 (Mar 29, 2026) ##
500
501 **Bug Fixes**
502
503 * Fixed multisite activation/upgrade skipping orphaned table adoption — batch methods now run adoption after table creation, ensuring migrated data is recovered on multisite networks.
504 * Fixed DDL schema comparison failing on MariaDB servers that use `COLLATE=utf8mb4_unicode_ci` (equals sign) instead of MySQL's `COLLATE utf8mb4_unicode_ci` (space), causing unnecessary schema rebuild loops.
505 * Fixed `doEmptyTrash()` executing an empty SQL query when called with an unrecognized sub-page parameter — now early-returns after logging the error.
506 * Fixed logs URL filter failing when `logsid` was passed as a non-string type, causing a type error in `sanitizeForSQL()`.
507 * Fixed invalid UTF-8 byte sequences in captured URLs corrupting log INSERT queries — added `mb_convert_encoding()` sanitization at the log entry boundary.
508 * Fixed DDL normalization not stripping `DEFAULT NULL` (which is implicit for nullable columns), causing infinite schema diff loops on some MySQL versions.
509 * Fixed orphaned table adoption running on every page load instead of once — adopted prefixes are now recorded in `wp_options` to prevent re-detection.
510 * Fixed table adoption running before target tables existed — adoption now executes after `runInitialCreateTables()`.
511
512 **Internationalization**
513
514 * Completed translations for all 204 pending strings across 12 languages.
515 * Added proper `_n()` plural forms for redirect count strings.
516 * Fixed culturally inappropriate translations and religious idioms in warning messages.
517 * Fixed fuzzy flags, broken format specifiers, and missing slug translations in PO files.
518
519 ## Version 4.0.3 (Mar 28, 2026) ##
520
521 **Bug Fixes**
522
523 * Fixed filter bar inputs and selects overflowing below their container's bottom border due to WordPress admin styles setting an inflated line-height on form controls.
524 * Fixed Logs tab URL search input being too narrow — it now dynamically grows to fill available space.
525 * Fixed database error notices not appearing on the plugin admin page when a table is missing or cannot be created.
526
527 ## Version 4.0.2 (Mar 28, 2026) ##
528
529 **New Features**
530
531 * Orphaned table adoption — automatically detects and recovers plugin data left behind by site migrations or table prefix changes. Uses slug-matching verification to confirm data ownership before adopting.
532 * Graceful admin screen when plugin files are missing or corrupt — instead of a white screen, shows a diagnostic page listing missing files with reinstall instructions (Error 18).
533 * Improved pipeline trace display with color-coded status badges for easier log reading.
534
535 **Bug Fixes**
536
537 * Fixed table prefix normalization — centralized 15+ direct `$wpdb->prefix` usages to go through the lowercased prefix helper, preventing "Table doesn't exist" errors on case-sensitive MySQL servers after table rename.
538 * Fixed `renameAbj404TablesToLowerCase()` running unnecessarily on MySQL servers with `lower_case_table_names >= 1` (where MySQL already handles table name casing).
539 * Fixed orphaned redirect cleanup failing on sites with non-default database table prefixes.
540 * Fixed N-gram cache race condition where concurrent TRUNCATE and INSERT operations could corrupt the spelling cache.
541 * Fixed timezone handling — replaced `date_default_timezone_set()` with WordPress `wp_date()` for timezone-safe date formatting.
542 * Fixed ErrorHandler switch statement bug that could route errors to the wrong handler.
543 * Fixed `deleteSpecifiedRedirects` type filter not correctly constraining purge operations.
544 * Fixed DDL schema comparison incorrectly flagging non-zero quoted integer defaults (e.g. `DEFAULT '1'` vs `DEFAULT 1`) as schema differences.
545
546 **Security**
547
548 * Added defense-in-depth guard that prevents schema migrations from accidentally dropping all columns from a table.
549
550 **Internal**
551
552 * Column-matched INSERT for table adoption — uses `SHOW COLUMNS` and `array_intersect` to handle schema drift between plugin versions when adopting data from old-prefix tables.
553 * Major codebase refactoring: consolidated duplicated DataAccess patterns, unified AJAX security boilerplate into a shared trait, extracted shared helpers for multisite batch processing and DDL normalization.
554 * Replaced `$_REQUEST[ABJ404_PP]` message bus with a typed `RequestContext` object.
555 * Removed dead code: unused settings method, stale DDL builders, and redundant index verification logic.
556
557 ## Version 4.0.1 (Mar 25, 2026) ##
558
559 **Bug Fixes**
560
561 * Fixed perpetual "still differences" schema errors on the engine_profiles table caused by MySQL quoting numeric defaults differently than the goal DDL (e.g. `default '1'` vs `default 1`).
562 * Fixed missing-table auto-repair flooding admins with error emails even when repair succeeded. Now only sends an email if repair actually fails.
563 * Fixed blank screen after dismissing the review notice.
564 * Fixed GSC integration sending unbounded API requests — added URL cap, corrected chunk size, and added a circuit-breaker.
565 * Fixed full-table scan in log ID/URL query by adding LIMIT 500.
566 * Fixed PHP 8.4 deprecation warning in CSV export (`fputcsv()` missing `$escape` parameter).
567 * Removed dead PDF email attachment feature.
568 * Fixed Logs table layout — long URLs no longer overflow into adjacent columns, and the Date column is no longer truncated.
569 * Fixed redirect not firing on WordPress 6.9+ when `class-wp-font-face.php` sends output before headers.
570
571 **Improvements**
572
573 * Added pipeline trace for per-request detail logging in the Logs tab — click the arrow on any log row to see every step of the redirect decision process.
574
575 ## Version 4.0.0 (Mar 24, 2026) ##
576
577 **New Features**
578
579 * Conditional engine groups (engine profiles) — override the matching strategy for specific URL patterns.
580 * Google Search Console integration with guided setup wizard — import crawl errors and push fixes.
581 * Email digest reports — weekly summary of top 404s and redirect activity.
582 * REST API for redirect management.
583 * WP-CLI overhaul — list, create, delete, import, export, and test subcommands.
584 * Cross-plugin importer — import redirects from Rank Math, Yoast SEO, AIOSEO, and Safe Redirect Manager with a preview step.
585 * HTTP 410 Gone, 451 Unavailable For Legal Reasons, 307/308, and Meta Refresh redirect types.
586 * Match confidence column, filter, and stats card — see how confident the engine was for each redirect.
587 * Auto-redirect when published posts are trashed or permanently deleted.
588 * Trend analytics dashboard — traffic trend charts plotting 404s, redirects, and captures over time.
589 * Server config export for nginx, Cloudflare Worker, Netlify, and Vercel.
590 * Stale cache detection and dead destination suspension.
591 * Send Feedback link on the plugins page.
592
593 **Bug Fixes**
594
595 * Fixed mass redirect deletion deleting ALL redirects when threshold was empty.
596 * Fixed category/tag type constants being swapped — category redirects pointed to tags and vice versa.
597 * Fixed CSV export/import round-trip losing redirect codes (always stored as 301).
598 * Fixed Redirection-format export hardcoding 301, losing actual redirect codes.
599 * Fixed regex redirects ignoring per-redirect code and always using the global default.
600 * Fixed AMP stripping corrupting multibyte URLs.
601 * Fixed spell checker byte/character mismatch on multibyte strings.
602 * Fixed log hits stripping valid multibyte Unicode from URLs.
603 * Fixed spelling cache returning wrong data type, breaking suggestions.
604 * Fixed database error storms flooding site admin emails.
605
606 ## Version 3.3.7 (Mar 20, 2026) ##
607 * Improvement: The plugin now automatically repairs corrupted plugin tables (MySQL errno 1034 "Incorrect key file") and retries the failed operation, so transient disk-level corruption no longer causes user-visible errors.
608 * Improvement: The activity log table is now stored on InnoDB, eliminating the "table is full" (errno 1114) failure mode that affected MyISAM tables. If the log table fills up, the plugin automatically trims the oldest 1,000 entries to free space and retries.
609 * Improvement: Admin notices for database problems now only appear on the plugin's own settings page rather than on every WordPress admin screen.
610 * Fix: Corrected a latent PHP error in the "Incorrect key file" recovery path that would have triggered a fatal error instead of attempting repair.
611
612 ## Version 3.3.6 (Mar 20, 2026) ##
613 * Fix: Prevented a spurious database error during schema upgrades where a comment in an internal SQL file was mistakenly interpreted as a column definition, causing a malformed ALTER TABLE statement to be logged. No data was affected.
614
615 ## Version 3.3.5 (Mar 20, 2026) ##
616 * Improvement: Large source files refactored into focused trait files — no functional changes, but the codebase is easier to navigate and maintain.
617 * Improvement: Strict type checking (PHPStan level 9) enforced throughout the codebase, catching and fixing potential type-mismatch errors before they could affect users.
618
619 ## Version 3.3.4 (Mar 19, 2026) ##
620 * FIX: Fixed an upgrade bug introduced in 3.3.3 that accidentally cleared the admin page view cache. No redirect data was affected — the cache rebuilds automatically on the next page load.
621 * FIX: Schema comparison now refuses to drop columns when the target schema parses to zero columns, preventing a whole class of accidental data-wipe bugs.
622 * FIX: One-time repair detects and drops any `view_cache` table left in a stripped state by the 3.3.3 bug, so it is cleanly recreated on the next plugin load.
623
624 ## Version 3.3.3 (Mar 19, 2026) ##
625 * Fix: Uninstaller no longer produces a PHPStan type error when `$wpdb->get_results()` returns null on edge-case database configurations.
626 * Improvement: Plugin table cleanup on blog deletion, uninstall, and collation repair now uses dynamic discovery, ensuring any future tables are automatically included.
627
628 ## Version 3.3.1 (Mar 18, 2026) ##
629 * Fix: Resolved "Table wp_abj404_view_cache doesn't exist" errors on some v3.3.0 upgrades where the cache table was not created.
630 * Fix: Reduced debug log noise when WP_DEBUG is enabled.
631 * Fix: Orphaned-redirect cleanup cron no longer triggers errors on sites with incomplete database installs.
632 * Fix: Plugin upgrades no longer perform unnecessary database ALTER TABLE operations.
633 * Fix: Bot requests with malformed character encodings no longer cause database errors.
634
635 ## Version 3.3.0 (Mar 15, 2026) ##
636 * Add: 7-engine matching pipeline — slug matching, URL typo correction, title keywords, category/tag path matching, content keywords, spelling similarity, and archive fallback.
637 * Add: Title keyword matching engine — finds posts whose title words appear in the broken URL, with fuzzy Levenshtein scoring for near-matches.
638 * Add: Content keyword matching engine — searches post body text when title and slug matching fail.
639 * Add: Category/tag matching engine — resolves hierarchical paths like `/shop/electronics` to the right taxonomy term or finds posts within a category.
640 * Add: URL typo correction engine — strips `.html`, `.php`, `.asp` and other file extensions, plus trailing punctuation from copy-paste errors.
641 * Add: Post type archive fallback engine — redirects to archive pages when no single-post match is found.
642 * Add: Per-engine score thresholds — fine-tune how aggressive each matching strategy is (Advanced Settings).
643 * Add: Per-post and per-term exclusion — exclude individual posts, pages, or taxonomy terms from automatic redirects via edit screen checkbox.
644 * Add: Orphaned redirect cleanup — daily cron automatically removes auto-redirects whose destination post was deleted or unpublished.
645 * Improvement: WordPress.org discoverability — updated plugin description, tags, and FAQ for better search visibility.
646