WP Manifestindependent plugin directory
manifest / performance / probe-site-doctor

Probe Site Doctor

Probe Site Doctor analyzes a WordPress site across performance, database, configuration, plugin/theme, technical SEO and developer checks, and produces an actionable WordPress website health, performance and diagnostics reports.

by Djouonang Landry · github.com/landrydjouonang-hue/probe-site-doctor

★ 0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/landrydjouonang-hue/probe-site-doctor/archive/refs/heads/main.zip

Probe Site Doctor

Probe Site Doctor

WordPress health, performance & developer diagnostics.
49 read-only checks · printable health report · per-page speed causes · Core Web Vitals from real visitors

Version WordPress PHP License Dependencies

Probe Site Doctor analyzes a WordPress site across performance, database, configuration, plugin/theme, technical SEO and developer checks, and produces an actionable health report: a 0–100 score, findings ranked by severity, and a concrete recommendation for each finding. It then tells you what is making a given page slow, and — if you switch it on — what real visitors' browsers measured.

Everything it does is read-only. It never changes your site, never installs an update, never deletes a row, and never contacts a third party.

Author: Djouonang Landry · License: GPL-2.0-or-later · Requires WordPress 6.4+, PHP 8.0+

Scope — what it is and what it is not

It is It is not
A diagnostic tool for performance, database health, configuration, maintenance status and technical SEO settings A malware scanner, file-integrity monitor, firewall or vulnerability database
Read-only: a scan never changes the site A replacement for a dedicated security product
Includes a few basic hardening checks (e.g. debug output, public debug logs, outdated PHP) Proof that a site is secure. A high score does not mean that.

This scope statement is shown on the dashboard itself.

Features (v0.9.0)

  • Modular diagnostic engine with a public check interface and registration hooks
  • Four severity levels: Good, Information, Warning, Critical
  • Six categories: Performance, Database, Configuration, Plugins & Themes, SEO (Technical), Developer
  • Stored scan history with automatic retention (20 completed scans by default)
  • Dashboard: health score, score trend, per-area scores, severity filter, per-finding details
  • Website Health Report: a printable report with an overall diagnostic summary, priority recommendations and six sections (Performance, Database, Plugins & Themes, Configuration, Security Indicators, SEO). Generated on demand from any stored scan, printable straight to PDF, and downloadable as one self-contained HTML file
  • Scans run one check per REST request, with a progress bar and no PHP timeouts. The form falls back to a single request when JavaScript is off.
  • REST API (probe-site-doctor/v1), custom capabilities, multisite-aware uninstall
  • 49 checks: performance (Phase 2), database (Phase 3), plugin/theme/version (Phase 4), configuration indicators (Phase 5), technical SEO (Phase 6) and developer diagnostics (Phase 8)
  • Developer screen: the full system report — environment, active theme, active plugins, PHP extensions, PHP and WordPress memory limits, cron, REST availability, debug settings, database details and defined constants — with a copy/download diagnostic report (Markdown or JSON) for support tickets
  • Page Speed screen: analyse any page on the site and get a prioritised list of what is making it slow, with a concrete fix for each cause
  • Core Web Vitals from real visitors (optional, off by default): LCP, INP, CLS, FCP and TTFB collected first-party from visitors' browsers, summarised as 75th percentiles per page and device
  • Prioritised update recommendations for WordPress, plugins, themes and PHP. Site Doctor never installs updates and never contacts WordPress.org; it reads the update data WordPress already has.
  • Database findings show Finding · Estimated impact · Recommended action · Optional manual cleanup. Nothing is ever deleted automatically; see docs/CLEANUP-POLICY.md

Built-in checks

"How" shows how each check gets its evidence. Server means it reads settings, files, the database or PHP state. Loopback means the server requests its own public homepage as an anonymous visitor and analyses the response.

Category Check ID How
Performance Page cache (cache signals + server response time) performance.page-cache Loopback
Performance Persistent object cache performance.object-cache Server
Performance PHP OPcache performance.opcache Server
Performance Large images (media library) performance.large-images Server
Performance Image optimization indicators performance.image-optimization Server
Performance Script and style loading (render-blocking) performance.render-blocking-assets Loopback
Performance Excessive asset loading performance.asset-weight Loopback
Database Query indicators (round trip, typical query, SAVEQUERIES) database.query-performance Server
Database Database size (and growth since previous scan) database.size Server
Database Large tables (log/session/stats detection) database.large-tables Server
Database Table storage engines database.tables Server
Database Autoloaded options database.autoloaded-options Server
Database Post revisions database.revisions Server
Database Transients database.transients Server
Database Post meta volume database.postmeta Server
Database Orphaned metadata indicators database.orphaned-meta Server
Database Trash, spam and auto-drafts database.bloat Server
Configuration WordPress core version (and automatic security releases) configuration.wordpress-version Server
Configuration File editing settings configuration.file-editing Server
Configuration HTTPS configuration configuration.https Loopback
Configuration Administrator account indicators configuration.admin-accounts Server
Configuration XML-RPC status configuration.xmlrpc Loopback
Configuration REST API exposure indicators configuration.rest-api Loopback
Configuration WordPress version visibility configuration.version-visibility Loopback
Configuration Security-related configuration indicators configuration.security-indicators Loopback
Configuration PHP version (support and speed) configuration.php-version Server
Configuration Debug settings configuration.debug-mode Server
Plugins & Themes Outdated plugins extensions.outdated-plugins Server
Plugins & Themes Outdated themes extensions.outdated-themes Server
Plugins & Themes Inactive plugins extensions.inactive-plugins Server
Plugins & Themes Inactive themes extensions.inactive-themes Server
Plugins & Themes Plugin compatibility indicators extensions.compatibility Server
SEO Search engine visibility seo.search-visibility Server
SEO Permalink structure seo.permalink-structure Server
SEO Indexing configuration indicators seo.indexing Loopback
SEO Sitemap availability seo.sitemap Loopback
SEO Page titles seo.page-titles Loopback
SEO Meta descriptions seo.meta-descriptions Loopback
SEO Image alt text seo.image-alt-text Loopback
SEO Broken internal links seo.internal-links Loopback
Developer Environment information developer.environment Server
Developer Active theme and plugins developer.active-components Server
Developer PHP extensions developer.php-extensions Server
Developer PHP memory limit developer.memory-limit Server
Developer WordPress memory limit developer.wp-memory-limit Server
Developer Cron status developer.cron Server
Developer REST API status developer.rest-api Loopback
Developer Debug log developer.debug-log Server
Developer Database configuration developer.database-configuration Server

The WordPress and PHP version checks are listed under Configuration because they cover support status as well as speed. Both include performance guidance.

Three kinds of performance data, kept apart

Source What it tells you Where
Server-side analysis (always available) What the server sends and the work the page gives a browser: response time, HTML and asset weight, render-blocking files, images, third-party domains, caching and compression headers. This is where the causes are, and every cause comes with a fix. Scan findings, Page Speed screen
Field data from real browsers (optional, off by default) What visitors actually experienced: LCP, INP, CLS, FCP, TTFB as 75th percentiles per page and device. Page Speed screen
Lab tools (external, your choice) A controlled test in Google's browser with a full audit trail. Site Doctor links to PageSpeed Insights for the page you are looking at; it never sends your URLs anywhere itself. Link on the Page Speed screen

A server-side number is never presented as a page-load time, and the field data section says plainly that it needs traffic before it means anything.

Server-side diagnostics vs. frontend performance

The scan itself runs on the web server, so its findings do not measure browser page-load performance. Scan findings never report LCP, INP or CLS — those come only from the field-data collector described below — and their figures are not page-load times:

  • Server response time (page cache check) is the time the server takes to answer a request from itself. It excludes visitor network latency, image and script downloads, and rendering.
  • Asset checks read the homepage HTML. They count files, identify render-blocking markup, and add up the on-disk size of local files before compression. Third-party files and assets that JavaScript loads later are not measured.
  • Image checks inspect the media library. Whether a large image actually reaches visitors depends on the theme and the content.

Each finding shows a Server-side or Server loopback badge. To measure real frontend performance, use PageSpeed Insights, Lighthouse or browser developer tools.

Site Doctor reads the update data WordPress has already collected (the update_plugins, update_themes and update_core transients). It does not contact WordPress.org, does not trigger an update check, and never installs or activates anything.

Findings contribute prioritised recommendations, collected on the dashboard:

Priority Meaning
High Security/maintenance release, or a patch/minor update of a component in use
Medium Major version of a component in use (test on staging), or an unsupported PHP branch
Blocked The update needs a newer PHP or WordPress version first
Low Update for an inactive plugin or theme (deleting is usually better)

Each finding also includes manual update steps and copyable WP-CLI commands. Only you run them.

Configuration indicators, not a security audit

The Configuration checks read settings: debug output, file editing, HTTPS, administrator accounts, XML-RPC, REST exposure, version visibility, security keys, file permissions and similar. Every such finding says so in plain words, and a clean result does not mean the site is secure.

Not checked at all: malware, modified core or plugin files, known vulnerabilities in installed code, intrusions, password strength, two-factor authentication, certificate chains and TLS versions, and whether PHP files in the uploads folder can be executed (testing that would require uploading a file). Use a dedicated security product and an SSL testing service for those.

Non-invasive by design: server-side checks read constants, options and file metadata. Probe-based checks make anonymous GET requests to the site's own endpoints (xmlrpc.php, the REST root and users endpoint, readme.html, the uploads folder). No POST, no authentication, no XML-RPC method call, nothing uploaded.

Nothing is changed: fixes appear as How to change this manually, with wp-config.php, PHP or server snippets you apply yourself. Site Doctor registers no filter that alters XML-RPC, REST or registration behaviour.

Weighting is deliberately honest: obscurity-level items (version visibility, the default wp_ table prefix, display names) are Information with Low impact and say that hiding them protects little. Only real exposure is Critical — plain HTTP in production, placeholder security keys, a world-writable wp-config.php, new registrations becoming administrators, or PHP errors shown to visitors.

Technical SEO, not an SEO platform

The SEO checks cover what a diagnostic tool can verify on the server: whether published content has titles, whether descriptions exist where a supported plugin stores them, whether internal links resolve, whether images carry alt text, whether indexing is allowed, and whether a sitemap responds.

Not covered: content quality, keyword research, rankings, search volume, backlinks, competitors, and whether pages are actually indexed (that needs Google Search Console). Site Doctor does not write meta tags or edit content — keep using Yoast, Rank Math, SEOPress or similar for that, and Site Doctor reads their per-page descriptions when they store them in post meta.

Scanning is deliberately bounded: content scans stop after a few hundred published items, and broken-link verification makes only a small number of requests. Findings say how much was examined and what was left unverified, so the numbers are never presented as a full crawl.

Developer diagnostics

Site Doctor → Developer is the screen to open when you have inherited someone else's WordPress install. It reads, live:

Group Contents
Environment WordPress and PHP versions, SAPI, server software, OS, database server, URLs, environment type, locale, timezone, permalinks, paths, uploads writability, cache drop-ins
Active theme Name, version, author, stylesheet/template, child and parent theme, block theme, required WP/PHP, available update
Active plugins Every active plugin with version, author, available update, network scope and auto-update state — plus must-use plugins and drop-ins, the code that loads outside the plugin list
PHP extensions All loaded extensions, and the status of each required and recommended one, with the image library in use
PHP configuration memory_limit, execution time, input vars, upload limits, display_errors, error_log, OPcache, cURL/OpenSSL versions, disabled functions
WordPress memory limit WP_MEMORY_LIMIT, WP_MAX_MEMORY_LIMIT, the limit PHP is running under, current and peak usage
Cron status DISABLE_WP_CRON / ALTERNATE_WP_CRON, event and hook counts, next event, overdue events, missing core events, duplicated hooks, registered schedules
REST API status The REST root and a core route requested anonymously, namespaces advertised, response time
Debug information WP_DEBUG, WP_DEBUG_LOG, WP_DEBUG_DISPLAY, SCRIPT_DEBUG, SAVEQUERIES, fatal error handler, log path, size, last write, whether it sits in the web root
Database information Server and client versions, charset and collation, prefix, table count and size, the ten largest tables, tables not on utf8mb4, max_allowed_packet, buffer pool, sql_mode
Defined constants A whitelist of configuration constants

Never collected: authentication keys and salts, the database password, and the contents of the debug log (only its size and timestamp). Only whitelisted constants are reported, and anything whose name ends in KEY, SALT, PASSWORD, SECRET or TOKEN is refused even if it is whitelisted.

Nine of these areas are also scan checks (developer.*), so they appear in the health report with a severity, an impact and manual instructions: PHP extensions, PHP memory limit, WordPress memory limit, cron, REST availability, the debug log, database configuration, the environment declaration and the active-component inventory.

Exportable diagnostic reports

The Developer screen offers the whole system report — plus the findings of the latest scan that still need attention — as:

  • Copy to clipboard for pasting into a ticket or a chat,
  • Download .md (probe-site-doctor-diagnostics-<host>-<date>.md), a Markdown document with tables,
  • Download .json for tooling.

Both downloads are capability-checked and nonce-protected, write no file on the server and send nothing anywhere. Filters: probesd_system_info, probesd_system_report_markdown, probesd_system_report_data.

Page speed: what is making a page slow

Site Doctor → Page Speed analyses one page at a time — the home page, blog index, latest post/page/product, or any URL on this site. It fetches the page twice as an anonymous visitor (to see whether a cache answers) and reads up to three of its asset files for caching and compression headers. Then it reports:

  • What the server sends: first and repeat response time, cache indicators, HTML and local asset weight, file counts, render-blocking files.
  • What is making this page slow: a prioritised list of causes. Each one names what was measured, which Core Web Vital it typically affects, and how to improve it — slow server response, no page cache, no compression, render-blocking CSS/JS, heavy JavaScript, inline bloat, heavy or oversized images, missing image dimensions, a lazy-loaded hero image, no modern image formats, missing lazy loading, third-party domains without preconnect, assets served without caching headers, a large DOM, and heavy embeds.
  • Heaviest files on the page and the third-party domains it references.

Limits, stated on the screen: sizes are on-disk sizes of local files before compression, third-party files are never requested, and assets that JavaScript adds later are invisible to a server-side fetch.

Core Web Vitals from real visitors

This is the only part of Site Doctor that measures what visitors experience, because it is the only part that runs in their browsers.

When an administrator enables it, a ~3 KB first-party script runs on public pages, reads the browser's own performance entries (largest-contentful-paint, layout-shift, event timing, paint timing and navigation timing) and sends them back to this site once, when the page is hidden. The Page Speed screen then shows 75th-percentile LCP, INP, CLS, FCP and TTFB — for the analysed page, for the whole site, and split by mobile and desktop viewports — each rated against Google's thresholds.

Privacy and honesty, by design:

  • Off by default. It adds a script to the public site, so enabling it is a decision for the site owner (manage_options), not for the plugin.
  • First-party only. Data goes to this site's own REST route. No third-party service, no CDN, no analytics vendor.
  • No visitor identity. Stored rows contain a path, a device class (mobile/desktop by viewport width), a metric and a value. No IP address, no user agent, no cookie, nothing in the visitor's browser.
  • Logged-in users are excluded, because their pages carry the admin bar and are rarely cached.
  • Bounded. Sampling percentage and a retention window (default 30 days) are configurable; old rows are deleted automatically, and there is a one-click "delete all collected field data".
  • The collector route only exists while it is enabled, accepts same-origin requests only, validates and range-checks every value, and is rate limited per address.
  • Field data needs traffic. Fewer than about 30 samples is an indication, not a measurement — and the screen says so.

Filter: probesd_web_vitals_enabled. REST: POST probe-site-doctor/v1/vitals (public while enabled), GET probe-site-doctor/v1/vitals (capability-checked).

Website Health Report

Site Doctor → Health Report turns a completed scan into a report meant to be read, printed or handed to a client. Administrators generate it on demand: the screen opens with the latest scan, and any stored scan can be selected from the picker. Scan History offers Printable report and Download on every completed scan.

The report contains:

  1. Header — site name and URL, scan date, generation date, who requested it, scan reference, plugin version and environment type.
  2. Overall diagnostic summary — score and band, a one-sentence verdict, severity counts, how many checks were scored, movement since the previous scan, how the score is calculated, and what it does not mean.
  3. Priority recommendations — critical findings first, then warnings, each with its section, recommended action and estimated impact.
  4. Section summaries — score, severity counts and a plain-language assessment per section.
  5. Seven sections — Performance, Database, Plugins & Themes, Configuration, Security Indicators, SEO (Technical), Developer. Each one repeats its own scope, then lists its findings with severity, explanation, estimated impact, recommended action and manual steps, followed by a compact table of checks that passed and of checks that could not be evaluated.
  6. Environment at scan time and a footer that repeats the score disclaimer.

The Configuration category is split for the report: the security-related indicators (debug output, file editing, HTTPS, administrator accounts, XML-RPC, REST exposure, version visibility, security keys) form the Security Indicators section, while the PHP and WordPress version checks stay under Configuration. Both the section list and the mapping are filterable: probesd_report_sections, probesd_report_section_for_check.

Printing and PDF. Print / Save as PDF prints the same document; the browser's own "Save as PDF" destination produces the PDF. Each section starts on a new page, findings and tables are kept whole where possible, and the admin menu and toolbar are excluded from the printout. No PDF engine is bundled — that would add a heavy dependency for something every browser already does.

Download. Download HTML sends one self-contained file (site-health-report-<host>-<date>-<scan>.html) with its stylesheet inline and no external references, so it can be archived, emailed or printed later. The download is capability-checked and nonce-protected, writes nothing, and leaves no file on the server. Filter: probesd_report_export_html.

The report is read-only in every sense: it renders a stored scan and never runs a check or changes a setting.

Health score

Each completed result counts as Good = 100, Warning = 50, Critical = 0, and the score is their average. Information results, failed checks and skipped checks are neutral and are left out. Bands: ≥ 80 Healthy, ≥ 50 Needs attention, below 50 Needs urgent attention. Filter: probesd_health_score.

The score is not a security guarantee and not a certification. It summarises only the checks in the report: Site Doctor does not scan for malware, modified files, known vulnerabilities or intrusions, and it cannot measure what visitors experience in a browser. A high score means these checks passed, nothing more. That sentence (Score::disclaimer()) is printed next to the score on the dashboard, in the report summary and in the report footer.

Capabilities

Capability Grants Default
probesd_view_reports Dashboard, history, read reports, generate and download the health report, Developer and Page Speed screens, export diagnostics Administrator
probesd_run_scans Start scans, delete reports Administrator
probesd_run_cleanup Confirm future cleanup operations (none exist yet; typed confirmation always required) Administrator

Enabling the field-data collector, changing its sampling/retention or deleting the collected data requires manage_options, because it changes what runs on the public site.

Extending

See docs/WRITING-CHECKS.md. In short:

add_action( 'probesd_register_checks', function ( $registry ) {
    $registry->register( new My_Plugin\Checks\My_Check() );
} );

More docs: docs/ARCHITECTURE.md, docs/DATABASE.md, docs/CLEANUP-POLICY.md.