=== Link Status Scanner by Beplus ===
Contributors: rimbeplus
Tags: broken links, link checker, seo, link monitoring, broken link
Requires at least: 6.0
Tested up to: 7.0
Stable tag: 1.2.0
Requires PHP: 8.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Automatically detects broken and redirected links in posts, pages, custom fields, menus, and widgets — with scheduled scanning and email notifications.

== Description ==

Link Status Scanner by Beplus scans all your published content for broken links, redirects, and unreachable URLs. It runs in the background using WordPress Cron so your site performance is never impacted.

= Key Features =

* Automatic background scanning — Uses WP-Cron to scan posts and check links on a schedule you control.
* Multi-source scanning — Detects broken links in post content (`<a href>`), broken images (`<img src>`), Gutenberg block attributes (embed, button, image, file blocks), ACF custom fields, navigation menus, and widget areas.
* Link type badges — Every link is tagged by type (Anchor, Image, Block, ACF, Menu, Widget) so you know exactly where a broken URL came from.
* Broken link report — A clean admin table listing every broken link: URL, type, HTTP status code, the source it was found in, and when it was last checked.
* Status filters — Quickly filter links by All, Broken, Redirect, OK, Unchecked, or Ignored.
* Bulk actions — Re-check, ignore, or delete multiple links at once.
* Inline link replace — Swap any broken URL directly from the admin table without editing the post manually.
* Export CSV — Export your link data to a CSV file, filtered by status and link type, from the Export tab.
* Real-time progress — Scan and check operations show a live progress bar so you always know how far along the process is.
* Email notifications — Get a digest email listing new broken links after each cron check run.
* Configurable settings — Set check frequency (daily/weekly/monthly), request timeout, links per cron run, and excluded URL patterns.
* Dashboard widget — A quick summary of total, broken, redirect, and OK links on your WordPress dashboard.
* Scan on save — Newly published or updated posts are scanned immediately when saved.

= How It Works =

1. When a post is published or updated, Link Status Scanner extracts all URLs from the content — anchors, images, Gutenberg block attributes, and ACF fields — and stores them in the database.
2. A scheduled cron job also scans navigation menus and widget areas.
3. A second cron job checks each stored URL by making an HTTP HEAD request and recording the response code.
4. Broken links (4xx, 5xx, connection errors) are flagged in the admin report with their link type badge.
5. If email notifications are enabled, you receive a digest email listing newly broken links after each check run.

= Privacy =

Link Status Scanner by Beplus sends HTTP requests to external URLs in order to check their status. No personal data is collected or shared.

== Installation ==

1. Upload the `beplus-link-status-scanner` folder to `/wp-content/plugins/`.
2. Activate the plugin through the **Plugins** menu in WordPress.
3. Go to **Settings > Link Status Scanner** to view the broken links report.
4. Click **Scan Posts Now** to run an immediate scan, then **Check Links Now** to check their HTTP status.

== Frequently Asked Questions ==

= Does this plugin slow down my site? =

No. All scanning and HTTP checking happens through WP-Cron, which runs in the background. The only admin-side actions are when you manually trigger a scan or re-check.

= What types of links are scanned? =

The plugin scans `<a href>` anchors, `<img src>` images, Gutenberg block attributes (embed URL, button URL, image link, file link), ACF custom fields (URL, link, image, and file field types), navigation menus, and classic/block widget areas. `mailto:`, `tel:`, `javascript:`, and anchor-only `#` links are automatically skipped.

= Can I exclude certain domains or URLs? =

Yes. Go to the Settings tab and add URL patterns (one per line) to the Excluded URL Patterns field. Any link containing that pattern will be skipped.

= Why does WP-Cron not run on schedule? =

WP-Cron triggers on page loads. On low-traffic sites it may not run on time. For reliable scheduling, disable WP-Cron and add a real system cron job:
`*/5 * * * * curl -s https://yoursite.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1`

= What does "Redirect" status mean? =

A redirect (301, 302, 307, 308) means the URL has moved. The link still works but you may want to update it to the final destination for SEO.

= Does the plugin work with ACF? =

Yes. If Advanced Custom Fields is active, the scanner reads URL, link, image, and file field types. ACF is not required — the scanner simply skips ACF fields when ACF is not installed.

= Can I export the results? =

Yes. The Export tab lets you download a CSV file of all tracked links. You can filter by status (Broken, Redirect, OK, etc.) and by link type (Anchor, Image, Block, ACF, Menu, Widget) before exporting.

== Screenshots ==

1. Admin report table showing broken and redirected links with type badges, status filters, and bulk actions.
2. Export broken links to CSV with filtering by status and link type.

== Changelog ==

= 1.2.0 =
* New: Multi-source scanning — broken images (`<img src>`), Gutenberg block URLs (embed, button, image, file blocks), ACF custom fields, navigation menus, and widget areas are now scanned in addition to post content anchors.
* New: Link type column — every link in the report table is tagged with a color-coded badge (Anchor, Image, Block, ACF, Menu, Widget).
* New: Export CSV tab — export all tracked links to a CSV file, with filters by status and link type. File includes UTF-8 BOM for Excel compatibility.
* Improvement: Scan and check operations now show a real-time progress bar.

= 1.1.0 =
* New: Inline replace link — click "Replace" on any link row to swap the URL directly from the admin table without editing the post manually.
* The replacement updates both the database record and the actual post content.
* Status is automatically reset to "Unchecked" after replacement so the new URL gets verified on the next check.

= 1.0.0 =
* Initial release.
* Automatic post scanning on save and via WP-Cron.
* Admin report with WP_List_Table, status filters, and bulk actions.
* Settings page (frequency, timeout, links per run, excluded patterns, email notifications).
* Dashboard widget.
* Email digest notification for new broken links.

== Upgrade Notice ==

= 1.2.0 =
This update automatically upgrades the database to add a new `link_type` column. No manual steps required. After upgrading, run a fresh scan from the Broken Links tab to populate link types for existing records.

= 1.0.0 =
Initial release — no upgrade steps required.
