=== SEO Inspector ===
Contributors: manishn
Tags: seo, seo audit, seo checker, seo health, meta description, broken links, yoast, rank math, woocommerce
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.0
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Instantly find and fix SEO issues across your entire WordPress website. Works alongside Yoast, Rank Math, AIOSEO & SEOPress.

== Description ==

**SEO Inspector** is a production-quality SEO Health Scanner that audits your entire WordPress website for SEO issues. Unlike traditional SEO plugins, it works **alongside** your existing SEO plugin (Yoast, Rank Math, AIOSEO, SEOPress) and focuses purely on finding and surfacing SEO problems.

Think of it as a **professional SEO audit tool built right into your WordPress dashboard**.

### 🔍 20+ SEO Checks

* **Missing SEO Title** (Critical)
* **Missing Meta Description** (Critical)
* **Broken Internal Links** (Critical)
* **Missing H1 Tag** (High)
* **Multiple H1 Tags** (High)
* **Duplicate Post Titles** (High)
* **Duplicate Slugs** (High)
* **Images Missing ALT Text** (High)
* **Broken Images** (High)
* **Noindex Pages** (High)
* **SEO Title Too Short** (Medium)
* **SEO Title Too Long** (Medium)
* **Meta Description Too Short** (Medium)
* **Missing Featured Image** (Medium)
* **No Internal Links** (Medium)
* **Orphan Posts** (Medium)
* **Missing Canonical URL** (Medium)
* **Meta Description Too Long** (Low)
* **No External Links** (Low)
* **URL Too Long** (Low)
* **No Categories Assigned** (Low)
* **No Tags Assigned** (Low)
* **Images Missing Width/Height** (Low)

### ⚡ Key Features

* **SEO Health Score (0–100)** — Instantly see the overall SEO health of your site
* **Works with your SEO plugin** — Reads SEO titles/descriptions from Yoast, Rank Math, AIOSEO, SEOPress
* **Batch AJAX scanning** — Scans 100 posts per request, never freezes the browser
* **Beautiful modern dashboard** — Stats cards, progress ring, Chart.js pie & bar charts
* **Issues table** — Searchable, sortable, filterable, paginated issues list
* **Severity levels** — Critical, High, Medium, Low with color-coding
* **Bulk actions** — Ignore, Mark Fixed, Reopen issues in bulk
* **CSV export** — Export all issues for external reporting
* **Scheduled scans** — Daily, weekly, or monthly via WP-Cron
* **HTML email reports** — Beautiful email reports after each scheduled scan
* **WooCommerce support** — Scans product post types
* **Custom post types** — Fully configurable which post types to scan
* **Multisite compatible** — Full support for WordPress Multisite networks
* **Dark mode compatible** — Follows system/WordPress dark mode preferences
* **Developer-friendly** — Rich set of hooks and filters for extensibility

== Installation ==

= From the WordPress admin =

1. Navigate to **Plugins > Add New**.
2. Search for **"SEO Inspector"**.
3. Click **Install Now**, then **Activate**.
4. Navigate to **SEO Inspector > Dashboard** in the admin menu.
5. Click **Run SEO Scan** to perform your first scan.

= Manual Installation =

1. Download the plugin `.zip` file.
2. Navigate to **Plugins > Add New > Upload Plugin**.
3. Upload the `.zip` file and click **Install Now**.
4. Click **Activate Plugin**.

= Requirements =

* WordPress 6.0 or higher
* PHP 8.0 or higher
* MySQL 5.7 / MariaDB 10.3 or higher

== Frequently Asked Questions ==

= Does this replace my existing SEO plugin? =

No. SEO Inspector is a **health scanner**, not an SEO plugin. It is designed to work **alongside** Yoast SEO, Rank Math, All In One SEO, SEOPress, or any other SEO plugin. It reads SEO data from whichever plugin you have installed.

= Will scanning large sites slow down my website? =

No. Scanning is performed via AJAX in batches of 100 posts, only when you manually click "Run SEO Scan" or when a scheduled cron job runs. It never scans on regular page loads.

= What SEO plugins does it integrate with? =

It automatically detects and reads SEO metadata from:
- **Yoast SEO**
- **Rank Math**
- **All In One SEO (AIOSEO)**
- **SEOPress**

If none are installed, it falls back to the WordPress post title.

= Does it support WooCommerce? =

Yes. SEO Inspector can scan WooCommerce product post types. You can enable/disable product scanning in **Settings**.

= How is the SEO Health Score calculated? =

The score (0–100) is calculated by deducting points for open issues based on their severity:
- Critical: -10 points each
- High: -5 points each
- Medium: -2 points each
- Low: -1 point each

The total is then normalized to a 0–100 scale based on the number of posts scanned.

= Can I ignore false positives? =

Yes. You can ignore individual issues or use bulk actions to ignore multiple issues at once. Ignored issues are hidden from the open issues view but can be reviewed under the "Ignored" filter.

= Is it multisite compatible? =

Yes. The plugin creates a database table per site in the network. On uninstall, all data is cleaned up for all sites in the network.

= Does it send data externally? =

No. All scanning happens on your server. No data is sent to external servers.

= How do I enable email reports? =

Go to **SEO Inspector > Settings > Email Reports**, enable the option, enter the recipient email address, and set a scan schedule. Reports will be sent automatically after each scheduled scan.

= Can I export my results? =

Yes. Go to **SEO Inspector > Issues** and click **Export CSV**, or go to **SEO Inspector > Tools** and use the Export Scan Results button.

= How do I extend the plugin? =

See the **Hooks & Filters** section below for the full list of available actions and filters.

== Screenshots ==

1. **Dashboard** — Stats cards, SEO Health Score ring, Chart.js charts, and recent issues.
2. **Run SEO Scan** — Large scan button with live progress bar and batch status.
3. **Issues Table** — Searchable, sortable, filterable issues table with bulk actions.
4. **Issue Detail Modal** — Problem description, why it matters, and recommendation.
5. **Settings Page** — Full configuration with toggle switches.
6. **Tools Page** — Cache management, database reset, CSV export, system info.
7. **About Page** — Feature list, checks performed, developer hooks.

== Changelog ==

= 1.0.0 =
* Initial release.
* 20+ SEO health checks.
* SEO Health Score (0–100).
* AJAX batch scanning engine.
* Yoast SEO, Rank Math, AIOSEO, SEOPress integration.
* WooCommerce and custom post type support.
* Issues table with search, sort, filter, bulk actions, pagination.
* Issue detail modal with problem, impact, and recommendation.
* CSV export.
* WP-Cron scheduled scans (daily/weekly/monthly).
* Beautiful HTML email reports.
* Dark mode compatible admin UI.
* Chart.js pie and bar charts.
* Multisite support.
* Full extensibility via hooks and filters.

== Upgrade Notice ==

= 1.0.0 =
Initial release.

== Hooks & Filters ==

=== Filters ===

**`seoinspector_seo_title`**
Filter the SEO title retrieved for a post.

    add_filter( 'seoinspector_seo_title', function( $title, $post_id, $plugin ) {
        // Customize the SEO title.
        return $title;
    }, 10, 3 );

**`seoinspector_seo_description`**
Filter the SEO meta description retrieved for a post.

    add_filter( 'seoinspector_seo_description', function( $desc, $post_id, $plugin ) {
        return $desc;
    }, 10, 3 );

**`seoinspector_post_issues`**
Filter the complete list of issues found for a post. Add or remove custom checks.

    add_filter( 'seoinspector_post_issues', function( $issues, $post ) {
        // Add a custom check.
        if ( strlen( $post->post_content ) < 300 ) {
            $issues[] = array(
                'post_id'    => $post->ID,
                'post_type'  => $post->post_type,
                'issue_type' => 'content_too_short',
                'severity'   => 'medium',
                'status'     => 'open',
                'details'    => array( 'length' => strlen( $post->post_content ) ),
            );
        }
        return $issues;
    }, 10, 2 );

**`seoinspector_scan_query_args`**
Filter the WP_Query arguments used to get posts for scanning.

    add_filter( 'seoinspector_scan_query_args', function( $args ) {
        // Only scan posts modified in the last 30 days.
        $args['date_query'] = array(
            array( 'column' => 'post_modified', 'after' => '30 days ago' ),
        );
        return $args;
    } );

**`seoinspector_available_post_types`**
Filter the list of post types available for scanning in Settings.

    add_filter( 'seoinspector_available_post_types', function( $types ) {
        $types['portfolio'] = 'Portfolio';
        return $types;
    } );

**`seoinspector_seo_score`**
Filter the calculated SEO health score.

    add_filter( 'seoinspector_seo_score', function( $score, $total_posts, $stats ) {
        return min( 100, $score );
    }, 10, 3 );

**`seoinspector_is_noindex`**
Filter whether a post is noindex.

    add_filter( 'seoinspector_is_noindex', function( $noindex, $post_id, $plugin ) {
        return $noindex;
    }, 10, 3 );

**`seoinspector_canonical_url`**
Filter the canonical URL for a post.

=== Actions ===

**`seoinspector_post_scanned`**
Fires after a single post has been scanned.

    add_action( 'seoinspector_post_scanned', function( $post_id, $issues ) {
        // Do something after each post is scanned.
    }, 10, 2 );

**`seoinspector_scan_completed`**
Fires when a full AJAX scan is completed.

    add_action( 'seoinspector_scan_completed', function( $total, $score, $duration ) {
        error_log( "SEO scan complete: {$total} posts, score {$score}, {$duration}s" );
    }, 10, 3 );

**`seoinspector_scheduled_scan_completed`**
Fires when a cron-scheduled scan is completed.

== Privacy Policy ==

SEO Inspector does not collect or transmit any personal data. All processing happens on your server. No data is sent to external servers.
