=== Technical Site Auditor ===
Contributors: pihlfelt
Tags: seo, audit, performance, security, optimization
Requires at least: 5.8
Tested up to: 7.1
Stable tag: 3.3.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Technical SEO, performance, security and database audit for WordPress, with manual guidance for every issue and one-click fixes you can undo.

== Description ==

Technical Site Auditor scans your WordPress site the way visitors and search engines see it and reports technical problems in SEO, performance, security, accessibility, database health, e-mail deliverability and WooCommerce store setup. Every issue explains what was found, why it matters and how to fix it step by step. The free version fixes everything except search visibility and WooCommerce: 67 one-click fixes, every one of them undoable.

A scan only reads. Nothing on your site changes until you apply a fix, and every fix records what it changed so you can undo it under Fixes → Applied & history.

The free version runs 251 checks in 26 groups, plus up to 6 page-builder checks when Elementor or Divi is installed and 12 WooCommerce store-setup checks when WooCommerce is active. Premium adds the search-visibility and WooCommerce fixes, 41 WooCommerce catalogue and store-operations checks, automation (scheduled scans, regression monitoring, scheduled maintenance, plugin-status alerts), backups and the Redirect, Meta and Breadcrumbs tools.

= Key Features =

**Scanning and reporting**
* Scans your pages over HTTP in batches, up to 5,000 URLs per scan by default (filterable); site-wide facts such as robots.txt, sitemaps, headers and the database are checked once per scan
* Problems that come from your theme and repeat on most pages are reported once for the whole site, with sample pages
* Scan completeness: how many pages could not be read and why, so a clean result never hides pages that were never checked
* Issues by page or by check, with Open, "Fix active, still detected", Ignored and Resolved tabs and filters for severity, category, fix type and text
* "Re-check this URL" verifies one page without a full scan; ignore a check everywhere or mark issues as resolved
* New-since-last-scan markers with the date each issue was first seen, a site health score on the Overview, and CSV export of the filtered list

**Content and SEO**
* Titles, meta descriptions, headings, thin content, duplicate titles and descriptions across the whole site
* Open Graph and Twitter Card tags, social image size, Schema.org structured data
* Canonical tags (including canonicals that point to a redirect or a noindexed page), noindex on important pages, X-Robots-Tag headers, robots meta conflicts, hreflang
* robots.txt rules and syntax, XML sitemap contents and size limits, published pages missing from the sitemap, plain permalinks
* Indexable internal search results, a duplicate author archive on single-author sites, classic themes without title-tag support
* Broken internal links, links through redirects, orphan pages, redirect chains and loops; external links checked with retries so a slow or bot-blocking site is "could not be verified", not broken
* Sample content left published, links to development hosts, dead goo.gl links

**Performance**
* Images: dimensions, lazy loading, srcset, alt text, WebP/AVIF delivery, priority hints for the largest image
* Render-blocking CSS and JavaScript, file counts, cache busting, page size, DOM size, speculative loading
* Fonts (font-display, preconnect, Google Fonts), iframes (lazy loading, titles, dimensions)
* Server: PHP support status by date, compression, HTTP/2, TLS version, certificate validity and expiry, object cache, OPcache

**Security**
* HTTPS, HTTP-to-HTTPS and www redirects, HSTS strength, mixed content on HTTPS pages
* HTTP security headers verified with real requests
* Downloadable sensitive files (.env, .git, wp-config.php backups, database dumps, phpinfo, Adminer), confirmed by their content
* Missing or default authentication salts, PHP errors shown to visitors, XML-RPC, user enumeration, the file editor, debug.log exposure, directory listing, PHP execution in uploads, wp-config.php permissions, open registration with an elevated role

**Accessibility, database and hygiene**
* Form labels, alt text on linked images, empty buttons and links, skip links, zoom blocked by the viewport tag, iframe titles, the page language
* Autoloaded options, revisions, spam, trash, expired transients, orphaned metadata and cron events, table engine, fragmentation, utf8mb4, Action Scheduler bloat
* Plugins and the active theme (and its parent) closed or removed on WordPress.org, abandoned, untested or with pending updates, and a "changed since last time" panel

**AI visibility and e-mail deliverability**
* Which AI crawlers your robots.txt allows, blocks or does not mention, and whether an llms.txt file exists
* SPF and DMARC records present and valid, a mail server (MX) for the sending domain, a DKIM key at common selectors, and "WordPress could not send email" when the last e-mail failed
* Send test e-mail (Settings → Advanced): whether wp_mail() succeeded, the error, the From address and whether PHP mail() or SMTP was used

**WooCommerce**
* Free, when WooCommerce is active: cart, checkout and account pages set up, not cached and not indexable; terms and privacy pages; payment method; tax; REST and Store API exposure; the legacy API; webhooks over plain HTTP; checkout over HTTPS
* Premium: products, variations, shipping, stock, reviews, cart fragments, sessions, Action Scheduler failures, a payment method in test mode on the live site, pending database updates, outdated template overrides, order e-mails switched off, HPOS compatibility mode, missing tax rates, large logs and product images without alt text

= One-click fixes in the free version =

The free version fixes everything except search visibility and WooCommerce. Its 67 fixes each record what they change and can be undone under Fixes → Applied & history:

* **Security hardening and headers:** security headers, HSTS, upgrade-insecure-requests, deprecated headers, PHP execution in uploads, sensitive files, install.php, directory listing and debug.log. .htaccess changes are backed up, the site is tested after the change and the change is rolled back if it breaks the site; on nginx the fix says why it cannot be applied
* **More security:** XML-RPC, the file editor, version disclosure, user enumeration, PHP errors, a safe default role, rel="noopener", readme.html, minor core auto-updates, Application Passwords, pingbacks, a REST API login requirement, a redirect to HTTPS and the main host, wp-config.php permissions
* **Database cleanups with 30-day restore:** revisions, spam, trash, expired transients, orphaned metadata and cron events, auto-drafts and Action Scheduler history are saved before deletion and can be restored for 30 days. Plus autoloaded options, MyISAM to InnoDB, utf8mb4, table optimisation and a revision limit
* **Performance:** emoji scripts, oEmbed discovery, head clutter, jQuery Migrate, deferred JavaScript, font-display and preconnect, lazy-loaded iframes, comment-reply.js only where needed, speculative loading, WebP for new uploads, GZIP, browser caching, Elementor and Divi optimisations
* **Cleanup, content and accessibility:** comments, dashboard widgets, the admin bar, unused widgets, the welcome panel, update notices; http:// URLs rewritten to https:// in the database (serialization-safe), staging URLs, mailto: links, sample content, self-pingbacks, the HTML lang attribute and a skip link

= Free vs Premium =

**Every check is free except the WooCommerce catalogue checks, and every fix is free except the SEO/search-visibility and WooCommerce fixes.** Premium adds those, plus automation, backups and the Redirect, Meta and Breadcrumbs tools.

**Free Version**
* 251 checks in 26 groups (plus page-builder checks), including WooCommerce store setup and e-mail deliverability, and a test e-mail
* Fix guidance for every issue and 67 one-click fixes with undo
* Up to 5,000 URLs per scan, scan completeness, re-check, ignore and resolve, health score, new-since-last-scan markers, CSV export

**Premium Version**
* Everything in the free version, plus SEO and search-visibility fixes: search engine indexing, post-name permalinks, attachment pages, canonical tags on archives, noindex for empty archives and internal search results, the core sitemap, the sitemap line in robots.txt, an llms.txt generator, an AI crawler block list, redirect chains and rules, content links through redirects, the author archive redirect and title-tag support
* 41 more WooCommerce checks and 12 WooCommerce fixes
* Presets (Minimal, Balanced, Performance) that apply a curated set of fixes in one go
* Regression monitoring: new, resolved and returned issues since the previous scan, issue history and a health score trend
* Scheduled scans with an HTML e-mail report, optionally only when new problems appear
* Scheduled maintenance: the database cleanups you choose run on a schedule, each run undoable for 30 days
* E-mail alerts when an installed plugin is closed, removed or abandoned on WordPress.org
* Backups of the database, themes and plugins with a safe, atomic restore (uploads and wp-config.php are not included)
* Tools: Redirect Manager, Meta Title/Description Manager, Breadcrumbs
* Undo never requires an active licence

= Integrations =

Technical Site Auditor recognises popular plugins and adjusts its checks to them: Yoast SEO, Rank Math, All in One SEO, SEOPress, The SEO Framework, WooCommerce, Elementor, Divi, WPBakery, and caching, image optimisation, security, backup, forms, analytics, multilingual and redirect plugins (Help → Integrations lists them all and shows which are active on your site).

== Installation ==

1. Upload the plugin files to `/wp-content/plugins/technical-site-auditor/` directory, or install the plugin through the WordPress plugins screen.
2. Activate the plugin through the 'Plugins' screen in WordPress.
3. Go to Site Auditor → Issues in the admin menu and click "Run scan".

== Frequently Asked Questions ==

= Does a scan change my site? =

No. A scan only reads your pages and settings. Changes happen only when you apply a fix, and each fix can be undone under Fixes → Applied & history.

= Is there a limit on how many URLs I can scan? =

Up to 5,000 URLs per scan by default, in both versions. Developers can raise or lower the limit with the `wtsa_max_discovered_urls` filter. Large sites are scanned in batches, and the scan tells you if the limit cut the URL list short.

= Do I need a license key for the free version? =

No, the free version works without a license key. You only need a license key for the premium version.

= What is the difference between the free and the premium version? =

The free version fixes everything except search visibility and WooCommerce; Premium adds those plus automation. In detail: every check is free except the WooCommerce catalogue and performance checks, and every one-click fix is free - security hardening and headers, database cleanups with 30-day restore, performance, cleanup, content and accessibility - except the SEO and search-visibility fixes (indexing, permalinks, canonical and noindex tags, sitemaps, robots.txt, llms.txt, AI crawlers, redirects) and the WooCommerce fixes. Premium also adds scheduled scans, regression monitoring, scheduled maintenance, plugin-status alerts, presets, backups and the Redirect, Meta and Breadcrumbs tools.

= Which fixes are free? =

All of them except two categories. The 67 free one-click fixes cover security hardening and headers (including .htaccess changes with a site test and automatic rollback), database cleanups whose deleted rows can be restored for 30 days, performance, cleanup, content rewrites and accessibility. The SEO and search-visibility fixes (indexing, permalinks, canonical and noindex tags, sitemaps, robots.txt, llms.txt, AI crawlers, redirects, title tags) and the WooCommerce fixes are premium. In the free version those issues show their step-by-step "How to fix" instructions instead of a Fix button. A few fixes that change something visible (for example the permalink structure or product reviews) ask you to confirm before they run.

= Does it test e-mail delivery? =

Partly, and honestly. Every scan checks the DNS of your sending domain (SPF, DMARC, a mail server for bounces and replies, and a DKIM key at the common selectors), and reports when the last e-mail WordPress tried to send failed. Under Settings → Advanced, "Send test e-mail" sends one message to the address you type and shows whether WordPress handed it over, the error if not, the From address and name used, and whether PHP mail() or SMTP was used. Neither can see whether the message lands in the inbox or in spam; for that, check the test message itself. The DKIM check is a heuristic: a key under an unusual selector is not found, so it is only a notice.

= Can it block AI crawlers? =

The free version reports which AI crawlers (GPTBot, ClaudeBot, Google-Extended and others) your robots.txt allows, blocks or does not mention. In the premium version you tick the crawlers to keep out under Settings → Advanced; saving adds a two-line group for each ticked crawler (for example "User-agent: GPTBot" followed by "Disallow: /") to the robots.txt WordPress generates, recorded as a fix with undo, and unticking everything removes the groups again. Crawlers you leave unticked follow your normal rules. robots.txt is a request, not a lock: well-behaved crawlers honour it, others may not. A physical robots.txt file on the server cannot be changed this way, and the setting says so.

= Are backups safe? =

Backups (premium) are stored in wp-content/tsa-backups with 32-character random file names and are only offered for download to administrators, through WordPress. The folder is protected with .htaccess and web.config files; nginx ignores those, so on nginx the Backups screen shows the one-line rule to add to the server configuration (location ^~ /wp-content/tsa-backups/ { deny all; }). A restore first creates a restore point, refuses damaged or truncated backups and archives with unsafe file names before anything is changed, runs only the kind of statements a backup made by this plugin contains, and swaps the database in as the last step. Backups cover the database, themes and plugins - not uploads or wp-config.php - and are kept on the same server, so keep a copy elsewhere too.

= Will the plugin slow down my site? =

Scanning only runs when you start it (or on a schedule, premium). For visitors the plugin loads nothing except the small hooks of the fixes you switched on (and, in the premium version, the modules you enabled).

= Can I undo a fix? =

Yes. Every fix records what it changed, and you undo it under Fixes → Applied & history. Database cleanups (spam, trash, revisions, transients, orphaned metadata and others) save the deleted rows first, so they can be restored for 30 days - in the free version too. If a cleanup reaches the backup size limit, it stops and leaves the remaining rows untouched; running it again continues. Three cleanups cannot be undone, and say so: optimizing database tables (the rows stay the same), and, in the premium version, deleting expired WooCommerce sessions and deleting WooCommerce logs older than 30 days (both ask for confirmation first). Undo never requires an active licence.

= Why does an issue still show after I applied its fix? =

Results come from the last scan. Use "Re-check this URL" on the issue or run a new scan, and clear page caches first. If the scan still finds the problem, the issue moves to "Fix active, still detected": the fix is on, but something else on your site (the theme, another plugin, the server) still produces the problem.

= What is llms.txt, and do I need one? =

llms.txt is a young, community-proposed convention (llmstxt.org): a Markdown file in your site root that gives AI assistants a curated summary of your most important pages. Major search engines have said they do not use it, and not having one is not a problem. The check only reports whether a file exists. The premium version can generate one from your site title, tagline and key pages, leaving out password-protected and noindexed pages; any existing file is backed up first and the change can be undone.

= What does the plugin and theme hygiene check do? =

It looks up your installed plugins, your active theme and its parent theme in the WordPress.org directory and reports which ones have been closed or removed, which have not been updated in years and which have pending updates; for plugins it also reports which are untested with recent WordPress versions or conflict with your PHP/WordPress version. Only plugins and themes that WordPress.org serves updates for are looked up; premium or custom ones are never sent. The check never deactivates or deletes anything.

= Does it work with page builders? =

The plugin detects Elementor, Divi and WPBakery, and includes dedicated checks for Elementor and Divi.

= Is WooCommerce supported? =

Yes. The free version checks the store setup and security: cart, checkout and account pages, terms and privacy pages, payment method, tax, page caching and indexing of the cart and checkout, REST API and Store API exposure, the legacy REST API, webhooks and checkout HTTPS. The premium version adds 41 checks for the catalogue, performance and store operations (test-mode payment methods, pending database updates, outdated templates, order e-mails, tax rates, logs and more), plus 12 WooCommerce fixes. The link checker never follows add-to-cart, cart-removal or logout links, so a scan does not put products in a cart.

== Screenshots ==

1. Overview with the site health score, scan status and top issues
2. Issues list with tabs, filters and "How to fix"
3. Settings page for scanning, checks and thresholds
4. Scan progress with the completeness report
5. Fixes page with recommended fixes and undo
6. Redirect Manager (Premium)
7. Meta Manager (Premium)

== External Services ==

This plugin connects to the following external services. Requests happen only while a scan or a re-check runs (including scheduled scans in the premium version), and when you apply certain fixes. Every outgoing request is made by your own server through the WordPress HTTP API, which identifies itself with WordPress's standard user agent (your WordPress version and site address) unless stated otherwise.

= WordPress.org API =

The System Health checks use the official WordPress.org API.

**What it does:**
* Tests whether your server can reach api.wordpress.org, which WordPress needs for updates (core/version-check)
* Verifies that core WordPress files have not been modified (core/checksums)
* Looks up your active theme and, for a child theme, its parent theme in the theme directory (themes/info) to see whether it has been closed or not updated for years

**Data sent:**
* Your WordPress version number and site locale (language setting), for the core file checksums
* The directory slug of the active theme and its parent theme, for the theme lookup. Only themes that WordPress.org already serves updates for on your site are looked up

**When data is sent:**
* Only during a scan, when the System Health check is enabled. Theme lookups are cached for up to 24 hours, and at most 2 are made per scan.

**Service provider:** WordPress.org
* [Terms of Service](https://wordpress.org/about/domains/)
* [Privacy Policy](https://wordpress.org/about/privacy/)

= WordPress.org Plugin Directory API =

When the Plugin Hygiene check is enabled, the plugin queries the official WordPress.org plugin information API (api.wordpress.org/plugins/info/1.2/) for installed plugins.

**What it does:**
* Checks whether installed plugins are still listed in the WordPress.org directory or have been closed
* Checks when each plugin was last updated and which WordPress version it was tested with
* Checks each plugin's declared minimum PHP and WordPress requirements

**Data sent:**
* The directory slug (folder name) of each plugin. No license information is transmitted.

**When data is sent:**
* Only during a scan when the Plugin Hygiene check is enabled. Only plugins that WordPress.org already serves updates for on your site are looked up; plugins that declare their own update source (Update URI header) and premium or custom plugins are never sent. Responses are cached for up to 24 hours, and at most 30 lookups are made per scan.

**Service provider:** WordPress.org
* [Terms of Service](https://wordpress.org/about/domains/)
* [Privacy Policy](https://wordpress.org/about/privacy/)

= Public DNS lookups =

When the System Health check is enabled, the plugin performs DNS lookups for your own site's domain and the domain WordPress sends e-mail from: TXT records for SPF and DMARC (the _dmarc subdomain), MX records (with an A/AAAA fallback) to see whether the domain can receive bounces and replies, and DKIM TXT records at about 30 common selectors (selector._domainkey.domain). These are standard DNS queries made by your server's resolver; nothing is transmitted beyond the domain names being looked up. Results are cached for up to 12 hours, and the checks are skipped for local and development domains.

= Test e-mail =

"Send test e-mail" (Settings → Advanced) sends one message through your site's own mail setup (wp_mail(), and whatever SMTP or e-mail service plugin you use) to the address you type in, only when you click the button (at most one every 30 seconds). The plugin stores the time, whether it was sent, the mailer and the From address, but not the recipient or the subject.

= Requests to your own site and to linked pages =

During a scan, the plugin makes HTTP requests to your own site: its pages, robots.txt, sitemaps, a few probe URLs (for example /favicon.ico or files that should not be public) and one or two images and CSS/JavaScript files your pages load, which may be served by your CDN. When the External Links check is enabled, it also requests external URLs linked from your content to verify they still work (at most 10 links per page, results cached for up to 24 hours); these requests use the user agent "Mozilla/5.0 (compatible; WTSA Link Checker/1.0)". Some fixes make a test request to your own site after a change (for example, to confirm a .htaccess rule did not break the site). No personal user data is transmitted.

= Premium version only: pihlfelt.se =

The premium version contacts pihlfelt.se to activate and check your licence and to deliver plugin updates. The free version from WordPress.org never contacts pihlfelt.se.

== Changelog ==

= 3.3.0 =
The biggest release so far. Every check, every fix and every help text was reviewed against WordPress 7.1, WooCommerce and current PHP, with one rule: rather fewer checks and fixes that are right than more that are wrong. The result is a free version with 67 one-click fixes, 298 checks with fix guidance for each, scans that are more accurate and harder to break, and a Premium version that watches your site between scans.

**What's new**

* 67 one-click fixes in the free version, each with undo - every fix except search visibility and WooCommerce: security hardening and headers (.htaccess changes with a site test and automatic rollback), database cleanups whose deleted rows can be restored for 30 days, performance, cleanup, content rewrites (http:// URLs, staging URLs, e-mail links, sample content) and accessibility
* Fix guidance for every issue. Each check has its own "How to fix" instructions, and issue details list the actual products, URLs, images or files found instead of just a count
* 298 checks (268 in 3.2), 257 of them free: 61 issue types are new or replace an older one and 27 were retired. New are, among others: publicly downloadable sensitive files (.env, .git, wp-config.php backups, database dumps, phpinfo, Adminer, confirmed by their content), missing or default authentication salts, PHP errors shown to visitors, missing HTTP-to-HTTPS or www redirects, weak HSTS, mixed content on HTTPS pages, invalid SPF/DMARC records, invalid SSL certificates, duplicate titles and meta descriptions across the site, sitemap URLs that redirect or fail, published pages missing from the sitemap, robots.txt without a Sitemap line, plain permalinks, undersized social sharing images, sample content left published, links to development hosts, dead goo.gl links, tables not on utf8mb4, zoom blocked by the viewport tag, conflicting image priority hints, speculative loading turned off, a very large DOM and 404 pages that fail with a server error
* WooCommerce store-setup checks are now free (12 checks when WooCommerce is active): cart, checkout and account pages set up, not served from a page cache and not indexable; terms and privacy pages; payment methods, shipping, tax, e-mail sender, currency, permalinks and the REST API; the checkout and account pages served over HTTPS
* E-mail deliverability: a sending domain without a mail server (MX) for bounces and replies, no DKIM key at the common selectors, and "WordPress could not send email" when the last e-mail failed. "Send test e-mail" under Settings → Advanced shows whether wp_mail() succeeded, the error, the From address and name used, and whether PHP mail() or SMTP was used
* SEO checks: an X-Robots-Tag noindex header on a live site, robots meta tag and header in conflict, a canonical pointing to a redirect or to a noindexed page, indexable internal search results, a duplicate author archive, oversized sitemaps and a theme without title-tag support
* Theme hygiene: the active theme and its parent are checked like plugins - closed or removed on WordPress.org, abandoned, update pending, or a child theme whose parent is missing
* Scan completeness: the Overview, the Issues page and (Premium) the scan e-mail say how many pages could not be read and why, so a clean result never hides pages that were never checked
* "Re-check this URL" verifies one page or one site-wide check without a full scan. "Fix active, still detected" shows an issue a switched-on fix cannot solve on your site in its own tab instead of hiding it. "Ignore this check everywhere", a health score on the Overview, a "new" marker and first-seen date for each issue, and a "changed since last time" panel for plugin and theme hygiene
* Problems that repeat on most pages because they come from the theme (header, footer, menus) are reported once for the whole site, with sample pages, instead of once per page
* New fixes: block sensitive files, redirect to HTTPS and the main host, remove deprecated security headers, fix wp-config.php permissions, clean up Action Scheduler, convert tables to utf8mb4, replace staging URLs, fix the HTML lang attribute, add a skip link, set the default role, hide PHP errors and restore speculative loading
* Fixes that change something visible ask you to confirm first, with a dialog that says what will change: search engine indexing on a staging site, post-name permalinks, product reviews, hiding out-of-stock products and Redirects-module rules. After a fix is applied or undone the page cache is purged (WP Rocket, LiteSpeed Cache, W3 Total Cache, WP Super Cache, WP Fastest Cache, Cache Enabler, Autoptimize, SiteGround Optimizer, WP Engine, Kinsta, Breeze, Hummingbird, Comet Cache, Swift Performance and the core object cache)
* Settings → Advanced lets you choose whether "Disable XML-RPC" blocks the endpoint completely or only its login methods, the HSTS max-age and includeSubDomains, and the scripts "Defer JavaScript" never defers
* Free vs Premium is now one rule: every check is free except the WooCommerce catalogue checks, and every fix is free except the SEO/search-visibility and WooCommerce fixes. Premium adds those, plus automation (scheduled scans and maintenance, e-mail reports), backups, the Redirects, Meta tags and Breadcrumbs tools and presets. The last menu entry shows exactly what Premium adds

**New in Premium**

* Regression monitoring: what is new, resolved or came back since the previous scan, issue history and a health score trend. The scan e-mail is an HTML report and can be limited to new problems
* Scheduled maintenance: chosen database cleanups run on a schedule, each run backed up and undoable for 30 days, with a summary e-mail
* AI crawler policy: a block checklist under Settings → Advanced. Ticking crawlers and saving switches the "Manage AI crawlers" fix on (with undo); each blocked crawler gets its own robots.txt rule
* New SEO fixes: post-name permalinks (tested after the change and rolled back if posts stop loading), noindex for internal search results, redirect the single-author archive, title-tag support, add the sitemap to robots.txt, noindex cart, checkout and account pages, and Redirects-module rules (302 to 301, or switch off a rule that leads to a missing page)
* New WooCommerce checks and fixes: a payment method in test mode on the live site, a pending WooCommerce database update, outdated template overrides, order e-mails switched off, HPOS compatibility mode still syncing, missing tax rates, product images without alt text; fixes to clean expired sessions, clean old logs and remove WooCommerce block styles where they are not used
* The Breadcrumbs block is a real block editor block with a live preview and a separator setting

**Improved**

* New menu: Overview, Issues, Fixes, Tools (Premium), Settings and Help. The Optimize page and the old Fixes screen are one Fixes page with Recommended, All fixes and Applied & history tabs. Old bookmarks and e-mail links still work
* Undo lives in one place, Fixes → Applied & history, and never requires an active licence. Three fixes cannot be undone and say so: optimize database tables, clean expired WooCommerce sessions and clean old WooCommerce logs (Premium)
* Severity review: 24 checks changed severity. SEO length checks that fired on every site without an SEO plugin are now notices, a missing H1 is a warning instead of critical, and a plugin closed on WordPress.org is critical only when it was closed for a security issue
* The Issues page no longer keeps a check filter you did not choose; active filters are shown as chips you can remove one by one. The CSV export follows the current filter and is translatable
* "Enable automatic updates" enables minor (security) core updates only, never major ones, no longer edits wp-config.php, and explains when a constant or another plugin blocks updates. The three user-enumeration fixes are one "Block user enumeration" fix, and "Hide WordPress version" covers what "Remove generator" did; existing settings carry over
* Database cleanups that reach the backup size limit stop and leave the remaining rows untouched instead of continuing without a backup; running the cleanup again continues
* When a licence expires, what is already switched on keeps running - modules, applied fixes, scheduled scans, e-mails and scheduled maintenance. An active licence is needed to apply new Premium fixes and presets, change module, notification or maintenance settings, and for updates and support (Premium)
* "HPOS not enabled" is a warning and is detected through WooCommerce's own API; the "No SMTP or email service detected" hint is labelled as a heuristic and disappears once a test e-mail shows SMTP in use; the SPF guidance lists the real includes of common providers
* The backup type formerly called "Full Backup" is now "Database, themes and plugins" (Premium) - it never included uploads or wp-config.php, and the screen now says so

**More accurate, sturdier scans**

* A failing check is caught, logged and skipped so the scan always finishes - including on servers that send a header twice (Plesk, W3 Total Cache) and when an external site is slow
* The scanner never triggers side effects: add-to-cart, cart, logout, reply and nonce links are no longer requested, so a scan of a WooCommerce store no longer creates carts or tracking events
* Far fewer false alarms. HTTPS, XML-RPC, REST API, loopback, feed, RSD and shortlink checks now test the site's real address and real responses, so restrictions set by this plugin or a security plugin are recognised. Memory and execution-time checks read the server's limits, not the scanner's. robots.txt rules for AI crawlers are no longer reported as blocking search engines, and unknown directives such as Cloudflare's Content-Signal are a notice. WooCommerce cart, checkout and account pages are no longer reported as important pages with noindex. Block library CSS and global styles checks no longer fire on every WordPress 6.9+ site, "404 page returns 200" is no longer triggered by firewalls or maintenance mode, the favicon check can fire again, external links that answer 429/503 or block bots are "could not be verified" notices instead of broken links, PHP support is judged from the official end-of-life dates, and the accessibility checks honour aria-label, aria-labelledby and title, skip hidden fields and find the skip links of block themes

**Fixes that do what they say**

* Every fix was verified to change what it promises and to undo exactly that. "Deactivate" and "Reset" (Premium) only revert what the plugin itself changed, so a store's own WooCommerce settings are left alone. "Enable search engine indexing" can no longer hide a site, "Disable oEmbed" keeps the block editor's Embed block, "Defer JavaScript" uses WordPress's script loading strategy so dependent inline scripts keep working, the Permissions-Policy no longer blocks geolocation and payment features, lazy-loaded iframes leave the first one alone as WordPress does, and the llms.txt generator (Premium) excludes password-protected, noindexed, cart and checkout pages
* .htaccess changes in wp-admin, wp-content and uploads use the same safe writer as the root file (backup, atomic write, site test with rollback), and undo removes only the plugin's own block - never an old copy of the whole file
* Clean expired transients works on sites with an object cache; clean revisions no longer deletes other users' autosaves and respects WP_POST_REVISIONS; the redirect chain fix (Premium) now updates the Redirects module and Redirection plugin rules
* The free version's admin scripts no longer crash, so a running scan resumes after a page reload

**Backups you can rely on (Premium)**

* A restore now always builds its restore point before anything is changed, and stops if it cannot. "Database, themes and plugins" restores the database too, swapped in as the last step, and you stay logged in afterwards
* A backup is only marked complete when every byte was written: a full disk or a write error stops it with a clear message and removes the partial file, and damaged or truncated backups are refused before anything changes. TIMESTAMP values are correct on servers not set to UTC, the list of backups is no longer part of a backup, and stalled backups and abandoned restores are cleaned up after 24 hours
* Theme and plugin restores check permissions and disk space first, refuse archives with paths outside the theme and plugin folders, replace files atomically and remove files added since the backup. Backups and restores do several seconds of work per request and finish much faster
* Security: a restore runs only the statements a backup made by this plugin contains, so a tampered backup file cannot change live tables. Backup file names end in 32 random characters, refused downloads return 403/404, and on nginx the Backups screen shows the server rule that blocks the backup folder

**Removed**

* Fixes that did nothing on current WordPress or WooCommerce versions, or did harm: Optimize Heartbeat (the default is already 60 seconds), Disable WooCommerce Marketing Hub (retired in WooCommerce 11.1), Disable password strength meter (removed WooCommerce's only password check), Add HTML lang (replaced by "Fix the HTML lang attribute"), Optimize global styles (broke layouts on classic themes), Conditional block CSS (WordPress 6.9 does it itself), Disable cart fragments for guests (broke the cart widget), Disable Dashicons on the frontend (removed stylesheets that depend on it), the duplicate mixed-content fix, and three toggles that were never real fixes (frontend heartbeat, the comments menu and the admin footer text)
* Checks for preferences and defaults that fired on every site (welcome panel, dashboard widgets, admin bar, unused widgets, Application Passwords, autosave interval, heartbeat interval), duplicate checks that reported the same problem twice, and checks that could never be true (security headers summary, rel="next/prev" pagination, utf8mb4 support)
* The quick backup and the backup recommendation banner (Premium); use Tools → Backups

= 3.2.1 =
A maintenance release that makes site backups and restores more robust in less common hosting setups (Premium feature).

* Fixed: Backing up a very large database could fail during the final compression step on servers with a low PHP memory limit - compression now streams to disk instead of loading the whole dump into memory
* Fixed: On servers where several WordPress installs share one database, a database backup could include tables belonging to a neighboring install, and certain circumstances could then cause the restore of such a backup to be declined - table selection is now strict
* Fixed: Database exports now write rows in an explicit, stable order, ruling out rare situations where a row could be missed or duplicated in the backup file
* Improved: Restores now keep foreign key checks disabled for the entire import, so custom tables with foreign key constraints restore reliably
* Improved: Backups and restores now check available disk space before starting and stop with a clear message instead of failing partway through
* Improved: Database backups now record the site's actual database character set instead of assuming utf8mb4

= 3.2.0 =
A feature release focused on making cleanups reversible, keeping the plugin off your front end, and adding checks people actually asked for. Tested with WordPress 7.1 and PHP 8.4.

**New**

* Added: Database cleanups can now be undone. Spam, trash, revisions, transients, orphaned metadata, auto-drafts and removed scheduled events are backed up row by row before deletion and can be restored from the Fixes page for 30 days (very large runs that exceed the backup limit are reported honestly as permanent)
* Added: The plugin no longer loads its admin and scanning code on visitor requests. A normal page view now loads only the handful of files belonging to the fixes you actually switched on, which cut what the plugin contributes to a front-end request by around 97%
* Added: Plugin Hygiene check - finds installed plugins that have been closed or removed from WordPress.org, abandoned for years, untested with recent WordPress versions, overdue for updates, or in conflict with your PHP/WordPress version
* Added: Email alerts when an installed plugin's status changes - closed, removed or newly abandoned - so you hear about it without watching the report (Premium, and switchable under Settings)
* Added: AI Visibility check - see which AI crawlers your robots.txt allows, blocks or does not mention, plus an optional llms.txt generator
* Added: Security checks for open registration with elevated default roles, PHP execution in the uploads directory and wp-config.php file permissions
* Added: Search engine indexing check - catches the "Discourage search engines" setting left on after launch, with a one-click fix
* Added: Email deliverability check (SPF and DMARC DNS records)
* Added: WooCommerce REST API security - unauthenticated API access, the legacy REST API, unused write-capable API keys and webhooks delivering over plain http
* Added: Schema checks for duplicate markup from two sources, missing product identifiers and broken @id references
* Added: Duplicate sitemap detection when an SEO plugin and the WordPress core sitemap both respond
* Added: Action Scheduler bloat check for large stores
* Added: New one-click fixes - block PHP execution in uploads, enable indexing, disable the duplicate core sitemap, disable attachment pages, limit future post revisions, and a CSP upgrade-insecure-requests header
* Added: Setting for excluding specific script handles from the defer fix
* Added: Deactivating the plugin now tells you plainly what stays behind - applied fixes, .htaccess rules and wp-config changes are not undone by deactivating - and the plugin says so again if you reactivate it
* Added: Translation template (.pot), so the plugin can now be translated

**Improved**

* Improved: The Optimize page and the Fixes page are now two views of one system rather than two implementations, so a fix behaves, reports and undoes the same way whichever page you use
* Improved: New checks are enabled automatically when updating, without overriding your existing choices
* Improved: Orphan page detection now runs as a proper pass at the end of a scan instead of guessing while the scan is still going, and says plainly when part of the site could not be inspected
* Improved: Fewer false alarms. Accessibility, parked-domain, security-header, image-format and compression checks were each reporting problems that were not there - on Bootstrap markup, on filenames that merely contained a domain name, on cached responses, and on servers whose answers were read too strictly
* Improved: Checks that cannot be certain from a page scan now say so instead of asserting a cause, and report what was actually measured
* Improved: Scan progress shows the number of queued URLs from the start and explains the pause while the site-wide checks (DNS, plugin directory, sitemap, server headers) run, instead of sitting on "Initializing..."
* Improved: A clear notice if the plugin's database tables are missing, instead of features quietly failing

**Fixed**

* Fixed: Several optimizations reported themselves as active without taking effect, among them four security ones. They now apply as described
* Fixed: The HSTS and PHP-version header fixes could end up sending their header twice, in one case replacing a stronger policy already set by your host with a weaker one
* Fixed: Undo and deactivate no longer report success when there was nothing to undo them with, and a cleanup that has run no longer hides the issues it cleaned from later scans
* Fixed: A PHP deprecation notice that appeared above some of the plugin's screens on PHP 8.1 and newer, and those screens now carry a proper browser title
* Fixed: Alignment of the controls on the Issues screen's filter bar
* Fixed: Deleting the plugin with "delete data" enabled now removes every option it created

**Security**

* Security: Hardened the database search-and-replace behind the mixed-content fix so that serialized data cannot be corrupted, with the result verified before anything is written

= 3.1.0 =
A major reliability and quality release. We went through every check, fix and help text in the plugin and tightened the whole codebase.

* Added: Six additional checkers are now active - 404 page, accessibility, external links, fonts, iframes and pagination
* Improved: Checks now verify your site's actual state instead of settings, which removes a large number of false positives across the security, performance and page-builder checks
* Improved: Word counting now handles Swedish and other non-English languages correctly
* Improved: Recommendations brought up to current best practice, and checks updated for WordPress 6.6+ and current PHP versions
* Improved: All .htaccess fixes are written safely - Apache 2.4 compatible, verified after every change, with automatic backup and rollback
* Improved: Hardened backup system with protected storage on all server types; database restore is now atomic, so an interrupted restore can no longer harm your database
* Improved: More reliable auto-fixes - one setting per fix everywhere, clear "cannot be undone" warnings before database cleanups (which can now be re-run), and heavy operations run in batches on large sites
* Improved: Safer defaults - HSTS starts conservatively, and the REST API restriction keeps contact forms and WooCommerce guest checkout working
* Improved: Admin UI polish - better error handling during scans, working issue filters, accurate counts and consistent free/premium information
* Fixed: The iframe lazy-loading fix could blank post content on some PHP versions
* Fixed: The mixed content fix now safely updates post content only, with per-post backups
* Fixed: Premium updates from pihlfelt.se did not work due to an incorrect update endpoint
* Removed: A few obsolete toggles that no longer provide value on modern WordPress
* Code: General cleanup - removed unused and legacy code, tightened output escaping and export handling

= 3.0.2 =
* Added: Server Environment section in Settings showing PHP max_execution_time, memory_limit, and PHP version
* Added: Recommended batch_size and request_timeout based on server configuration
* Added: One-click "Apply" buttons for recommended scanner settings
* Added: New issue "Page HTML is large/too large" for bloated pages (Divi/Elementor detection)
* Added: New issue "Email link missing mailto:" for malformed email links
* Fixed: Undefined variable $failed_count PHP warning in scan view
* Fixed: rtrim() null parameter deprecation warning (PHP 8.1+ compatibility)
* Fixed: Email addresses without mailto: incorrectly reported as broken internal links
* Fixed: Scanner hanging on problematic pages (now auto-skips after 2 failed attempts)
* Improved: Reduced external link checks from 25 to 10 per page for faster scanning
* Improved: Batched database operations for better performance
* Improved: Faster retry delays when processing slow pages
* Improved: Large pages (>3MB) skip DOM parsing but still report size issues
* Improved: Clearer progress messages during scan

= 3.0.1 =
* Fixed: Database tables created with incorrect prefix preventing scans from working
* Fixed: Duplicate issues appearing multiple times for the same URL
* Fixed: Scanner analyzing error pages (429/5xx) instead of actual content
* Fixed: Progress bar not updating during scan (polling improvements)
* Fixed: Polling continuing after server errors, causing rate limiting
* Improved: Sequential polling to prevent overwhelming the server
* Improved: Added delay between URL requests to avoid rate limiting
* Improved: Reduced default batch size from 50 to 10 for better compatibility
* Improved: Immediate stop on 429/500 errors with user-friendly message

= 3.0.0 =
* Major: Unified Optimizer system for all optimizations
* Added: Auto-marking of issues as fixed when optimizations are activated
* Added: Automatic reopening of issues when optimizations are deactivated
* Added: Full backup system for database, themes, plugins, and full site backups
* Added: Chunked backup processing to handle large sites without timeouts
* Improved: Fix History now syncs correctly with actual optimization state
* Improved: Categories hide properly when requirements are not met
* Improved: WooCommerce category shows "WooCommerce required" notice
* Fixed: Empty category display for premium-only features
* Fixed: Various CSS styling issues
* Removed: Legacy optimization systems

= 1.0.7 =
* Added: Comprehensive issue details for 50+ more issue types
* Added: Fix guidance for accessibility issues (form labels, skip links, tabindex)
* Added: Safe .htaccess auto-fix system (Premium) with automatic backup and rollback
* Improved: Redirect chain display shows hop count and source plugin
* Improved: Security header issues show recommended values
* Improved: Database autoload issues show largest offending options

= 1.0.6 =
* Changed: "How to fix" now uses expandable button like "Why does this matter?"
* Fixed: Empty issue detail boxes no longer show
* Improved: Issue details now show WHAT was found, not just counts
* Improved: Database issues more human-readable

= 1.0.5 =
* Added: Complete fix guidance for all issue types
* Added: Knowledge base explanations with "Why this matters?", impact, and how to fix
* Fixed: "Manual" badge now always shows step-by-step guidance

= 1.0.0 - 1.0.4 =
* Initial releases: core audit engine, issue knowledge base, robots.txt refinements, duplicate detection improvements

== Upgrade Notice ==

= 3.3.0 =
Every check and fix reviewed: 67 one-click fixes with undo in the free version (everything except search visibility and WooCommerce), fix guidance for every issue, e-mail deliverability checks and a test e-mail, fewer false alarms, scan completeness and a new menu. Premium: safer backup restores.

= 3.2.1 =
More robust backups and restores: streamed compression for large databases, stricter table selection on shared databases, and disk space checks. Recommended for all Premium users.

= 3.2.0 =
Database cleanups can now be undone for 30 days, plus new plugin hygiene, AI visibility, security and WooCommerce API checks.

= 3.1.0 =
Major reliability and quality release — more accurate checks, safer fixes and a hardened backup system. Updating is strongly recommended.
