=== Missing Page Logs & Redirects ===
Contributors: designnoted
Tags: 404, redirect, permalink, broken links
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.4.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Log every WordPress 404, redirect confident permalink matches, and learn from administrator reviews. No external service.

== Description ==

Missing Page Logs & Redirects stores one row per normalized URL path, with a hit counter and first/last seen timestamps. Every genuine WordPress 404 with a valid request URI increments the counter before the redirect decision; the row retains the latest request details and outcome. Its deterministic matching combines slug, token, path, title, and WordPress context signals. Administrator-approved examples can guide similar requests; blocked examples keep a normal 404 response.

* Missing Page Logs & Redirects > 404 Log: filter requests, inspect scoring, and open Create rule for a source URL.
* Missing Page Logs & Redirects > Rules: change destinations, switch positive/blocked rules, or delete a rule.
* Expand Automatic redirect settings in the log to change the default 0.82 confidence threshold.
* Normal redirects use HTTP 301 and need a 0.08 winner margin. Exact learned rules and a unique old slug bypass the margin.
* Posts, pages and public custom post types are supported. Private, draft, password-protected content, revisions and attachments are excluded.
* Create rule opens a separate form. Creating or editing rules does not change the log counter or snapshot.
* No cloud service, external AI, API key, IP-address logging, or frontend HTTP lookup.

== Installation ==

1. Copy the missing-page-logs-redirects directory to wp-content/plugins/.
2. Activate Missing Page Logs & Redirects for the site. On multisite, activate individually rather than network-wide.
3. Wait for background indexing to complete. The log shows an indexing notice until it is ready.
4. Visit Missing Page Logs & Redirects > 404 Log to review incoming requests.

The content index uses WordPress cron, 200 posts per batch. Sites with DISABLE_WP_CRON must run their normal system cron. A CLI operator can run pending batches with `wp cron event run smart404_index_batch` until the indexing notice disappears.

== Frequently Asked Questions ==

= Does it aggregate or sample events? =
Yes. Repeat requests atomically increase the counter on a single physical record. Case, slash and query-string variants share the normalized path; no separate per-hit records are stored. Web-server/CDN errors that never reach WordPress cannot be logged. The plugin avoids redirects if logging fails.

= What is a blocked event? =
A learned rule suppressed automatic redirection. The response remains HTTP 404, never HTTP 403.

= Can I enter a custom internal URL? =
Yes: an existing public post/page/CPT permalink, homepage, public taxonomy archive or post-type archive. Destinations must be verifiable locally. External hosts, authentication paths, arbitrary unknown endpoints and routing query strings are rejected. Plain ?p= / ?page_id= destinations are canonicalized. Tracking parameters are not copied from requests.

= How are unsafe requests handled? =
Requests with malformed URIs are not logged or redirected. Other genuine 404 events are still recorded, but non-GET/HEAD requests, admin/login/REST/AJAX/cron endpoints, feeds, embeds and unsupported paginated paths are not automatically redirected. Normal canonical redirects for successful requests stay enabled. Missing Page Logs & Redirects owns canonical/old-slug guessing only for the 404 it is handling.

= Are redirects always certain? =
No. A bounded shortlist is scored, and ambiguous matches remain 404s. Similar rules also need a clear winner. An invalid or unpublished exact rule destination fails closed; it does not fall back to a different guess. A duplicated historical slug does not bypass ambiguity protection.

= What data is retained? =
Per normalized path: total hits, first and last seen times, and the latest request URI/query string, referrer, user agent, decision and score. Previous per-hit details are not retained. URLs and headers can contain personal data. Access requires manage_options. Version 2 retains events indefinitely and does not automatically delete data on deactivation or plugin deletion. Site operators should include these tables in their retention and backup practices. Rules and grouped logs are independent.

== Changelog ==

= 2.4.0 =
* Rename to Missing Page Logs & Redirects with matching plugin slug and text domain.
* Correct the WordPress.org contributor login.
* Validate and sanitize request URIs before persistence or matching; reject malformed targets without redirecting.
* Verify text-domain metadata before creating release archives.

= 2.3.0 =
* Rename the plugin and public slugs to Backtrack 404 (backtrack-404), preserving existing logs, rules and settings.

= 2.2.0 =
* Rename the plugin and public slugs to Route Rescue 404 (route-rescue-404), preserving existing logs, rules and settings.

= 2.1.1 =
* Prepare database identifiers and values consistently, including atomic counters and log migration.
* Sanitize request metadata and admin filters; clarify translator placeholders.
* Search destinations by title, partial path or full URL.
* Ship only production files in the installable ZIP.

= 2.1.0 =
* One database row per normalized URL, atomic hit counters, first/last seen and latest outcome.
* Existing logs are consolidated with counts and rule references preserved.
* Separate Create rule screen and single log table.

= 2.0.0 =
* Complete per-event logging, bounded indexed matching, native/old-slug integration, confidence and ambiguity protection.
* Separate rule creation, fuzzy positive/negative learned rules, rules management, settings and responsive admin screens.
