Skip to content
cromstelit edited this page Oct 14, 2026 · 2 revisions

Welcome to the smart-domain-mapping-system wiki!

Generated from repository analysis (v1.1.1, tag 719c8a2). PHP / WordPress plugin (wordpress-plugin).


1. Project Overview

Field Value
Name Smart Domain Mapping System
Package citgroup/smart-domain-mapping-system
Version v1.1.1 (domain-mapping-system.php header + DMS_VERSION)
Type wordpress-plugin
License GPL-2.0-or-later
Tech stack PHP 7.4+, WordPress Multisite (WP_MULTISITE), jQuery (admin), Composer (dev), PHPUnit (tests)
Key dependencies wordpress-plugin (runtime); phpunit/phpunit (tests); wpcs (coding standards); composer.phar (vendor/bin/phpunit, vendor/bin/phpcs)

Purpose: Multisite custom domain mapping using wp_sitemeta, with DNS verification, SSL lifecycle tracking (hosting site provider, avoids ACME cost), audit logging, REST API endpoints, WP-CLI commands (dms verify), and health-check retention.


2. Architecture

flowchart TB
    subgraph WP["WordPress Multisite"]
        WPCore["WP Core"] --> PluginRoot["domain-mapping-system.php"]
    end

    PluginRoot --> Autoload["dms_autoload()"]
    PluginRoot --> CLI["WP-CLI class-cli.php (eager)"]
    PluginRoot --> PublicRedirect["public/redirect-helpers.php"]

    Autoload --> CoreModule["includes/core/"]
    Autoload --> AdminModule["includes/admin/"]
    Autoload --> RestModule["includes/rest/"]
    Autoload --> SSLModule["includes/ssl/"]
    Autoload --> VerificationModule["includes/verification/"]
    Autoload --> CLIClass["includes/cli/class-cli.php"]

    CoreModule --> DBTables["class-db-tables.php"]
    CoreModule --> PluginInit["class-domain-mapping-system.php (DMS_Plugin)"]
    CoreModule --> LogEngine["class-logging.php"]
    CoreModule --> MappingEngine["class-mapping-engine.php"]
    CoreModule --> Migration["class-migration.php"]

    AdminModule --> SettingsClass["class-settings.php (DMS_Settings)"]

    RestModule --> RestAPI["class-rest-api.php"]

    SSLModule --> SSLInterface["class-ssl-provider-interface.php"]
    SSLModule --> SSLNone["class-ssl-provider-none.php (hosting-site, provider=hosting, no ACME)"]
    SSLModule --> SSLAcme["class-ssl-provider-acme.php"]
    SSLModule --> SSLMgr["class-ssl-manager.php"]
    SSLModule --> SSLProviders["class-ssl-providers.php"]

    VerificationModule --> DNSVerify["class-dns-verification.php"]
    VerificationModule --> HealthCheck["class-health-check.php"]

    SettingsClass --> SettingsUI["admin/views/settings.php"]
    SettingsClass --> MappingsUI["admin/views/network-mappings.php"]
    SettingsClass --> LogsUI["admin/views/logs.php"]
    SettingsClass --> AdminAssets["admin/css/admin.css + admin/js/admin.js"]

    PluginInit --> InitMapping["DMS_Mapping_Engine"]
    PluginInit --> InitSettings["DMS_Settings"]
Loading

Key design choices (from docs/DECISIONS.md):

  • Explicit class-to-file autoloader (dms_autoload) — names don't match file names (e.g., DMS_Settings lives in includes/admin/class-settings.php).
  • WP-CLI (DMS_CLI_Command) eagerly loaded (self-registering); all others lazy-loaded.
  • SSL provider: provider='hosting' (hosting-site TLS, avoids ACME third-party cost). Not claimed production-ready for live TLS verification.

3. Project Structure

\Domain Mapping System\
├── .github/                 # CI (ci.yml, codeql.yml, release.yml), dependabot.yml
├── admin/
│   ├── css/admin.css
│   ├── js/admin.js          # AJAX submit handlers (add/delete/enable/primary/verify)
│   └── views/
│       ├── logs.php         # Audit log table render
│       ├── network-mappings.php  # Domain mapping list + add form
│       └── settings.php     # Settings form (default redirect, SSL provider, retention)
├── assets/                  # Banner/icons (not shipped in ZIP; generated via bin/generate-assets.py)
├── bin/
│   ├── build-zip.ps1        # Packages tracked files only (git ls-files); excludes tests/docs/vendor
│   ├── bump-version.ps1     # Updates version header + readme.txt stable tag
│   ├── generate-assets.py   # Programmatic asset generation
│   └── install-wp-tests.sh  # WP test bootstrap
├── database/
│   ├── schema.md            # Schema derived from class-db-tables.php
│   └── migrations/
│       └── 1_initial.php     # dbDelta reference; reversible
├── docs/
│   ├── API.md               # REST endpoints reference
│   ├── ARCHITECTURE.md      # Structure, autoloader, security, DB notes
│   ├── CHANGELOG.md         # v1.0.0 / v1.1.0 / v1.1.1 history
│   ├── DECISIONS.md         # Structure choices, SSL hosting-site, grouping
│   ├── IMPLEMENTATION_PLAN.md # Audit phases, criteria, evidence
│   ├── MEMORY.md            # Constraints, known gaps, version tags
│   ├── RELEASE_PROCESS.md   # Build/release verification checklist
│   ├── SECURITY_AUDIT.md    # Security rules audit
│   ├── TESTING_STRATEGY.md  # Coverage, CI approach, unverified assumptions
│   └── TODO.md              # Completed + blocked (honest reporting)
├── includes/
│   ├── admin/
│   │   └── class-settings.php  # DMS_Settings (init, register_settings, sanitize_options, enqueue_admin_assets, add_menu, save_settings, add_mapping, render_settings)
│   ├── cli/
│   │   └── class-cli.php       # WP-CLI command (dms verify)
│   ├── core/
│   │   ├── class-db-tables.php    # Schema creation (mappings + logs tables)
│   │   ├── class-domain-mapping-system.php  # DMS_Plugin (bootstrap)
│   │   ├── class-logging.php     # Audit log writes + health-check purge
│   │   ├── class-mapping-engine.php  # Mapping list/add/update/delete
│   │   └── class-migration.php   # Migration runner (dbDelta)
│   ├── rest/
│   │   └── class-rest-api.php     # REST endpoints (post/create, patch/update, delete, verify, primary)
│   ├── ssl/
│   │   ├── class-ssl-provider-interface.php
│   │   ├── class-ssl-provider-none.php  # provider='hosting'
│   │   ├── class-ssl-provider-acme.php
│   │   ├── class-ssl-manager.php
│   │   └── class-ssl-providers.php
│   └── verification/
│       ├── class-dns-verification.php
│       └── class-health-check.php
├── languages/                 # POT template (domain-mapping-system.pot)
├── public/
│   └── redirect-helpers.php   # Public-facing redirect helpers
├── domain-mapping-system.php # Plugin header + autoloader + bootstrap
├── readme.txt                 # WordPress directory format (Stable tag, changelog)
├── README.md                  # Root documentation (allowed by .gitignore exception)
├── CONTRIBUTING.md            # Community contribution rules (root)
├── SECURITY.md                 # Security disclosure (root)
└── uninstall.php              # Uninstall cleanup

Excluded from ZIP (git ls-files exclusions): tests/, docs/, assets/ (generated), vendor/, .github/, .gitignore, .gitattributes, composer.*, .phpcs.xml.dist, .gitkeep.


4. Core Components

4.1 Plugin Bootstrap (domain-mapping-system.php)

  • Defines DMS_VERSION.
  • Defines DMS_PLUGIN_FILE (absolute plugin file path) for plugin_dir_url().
  • Defines ABSPATH guard (if ( ! defined( 'ABSPATH' ) ) exit;).
  • Registers dms_autoload() via spl_autoload_register().
  • Includes public/redirect-helpers.php eagerly (public redirect logic).
  • Initializes DMS_Plugin::get_instance().

4.2 Autoloader (dms_autoload)

Explicit class-to-file map (file names don't match class names):

$map = array(
    'DMS_Plugin' => 'includes/core/class-domain-mapping-system.php',
    'DMS_Settings' => 'includes/admin/class-settings.php',
    'DMS_SSL_Manager' => 'includes/ssl/class-ssl-manager.php',
    'DMS_SSL_Provider_Interface' => 'includes/ssl/class-ssl-provider-interface.php',
    'DMS_SSL_Provider_None' => 'includes/ssl/class-ssl-provider-none.php',
    'DMS_SSL_Provider_ACME' => 'includes/ssl/class-ssl-provider-acme.php',
    // ... additional 14 classes mapped
);

CLI (DMS_CLI_Command) eagerly loaded; all others lazy-loaded.

4.3 Core Module (includes/core/)

Class File Responsibility
DMS_Plugin class-domain-mapping-system.php Singleton; hooks init, starts Mapping_Engine + Settings.
DMS_Mapping_Engine class-mapping-engine.php List, add, update, delete, set-primary mappings.
DMS_Logging class-logging.php Audit log writes (DMS_TABLE_LOGS); health-check purge.
DMS_Settings class-settings.php Settings registration (dm_options); sanitize (sanitize_options); admin UI (add_menu, render_settings).
DMS_Health_Check class-health-check.php Daily purge of audit entries exceeding retention (audit_retention_days).
DMS_Migration class-migration.php Migration runner; uses dbDelta() reference from class-db-tables.php.
DMS_DB_Tables class-db-tables.php Schema creation (mappings + logs tables); defines DMS_TABLE_MAPPINGS, DMS_TABLE_LOGS.

4.4 SSL Module (includes/ssl/)

  • DMS_SSL_Provider_Interface: contract (issue_certificate(), renew_certificate()).
  • DMS_SSL_Provider_None: provider='hosting' (hosting-site TLS; avoids ACME third-party cost). Records pending (issue) and issued (renew) in DMS_SSL_Manager.
  • DMS_SSL_Provider_ACME: ACME / Let's Encrypt provider.
  • DMS_SSL_Manager: manages certificate lifecycle tracking per blog/domain.
  • DMS_SSL_Providers: registry/discovery.

Note: hosting SSL provider does NOT claim production-ready status for hosting-level TLS verification; requires live hosting environment verification (see docs/TODO.md).

4.5 REST Module (includes/rest/)

DMS_REST_API registers endpoints (network admin scope):

  • POST / action=dm_rest_create_mapping
  • PATCH / action=dm_rest_patch_mapping
  • DELETE / action=dm_rest_delete_mapping
  • POST / action=dm_rest_set_primary
  • POST / action=dm_rest_verify_mapping

AJAX uses wp_create_nonce('dm_nonce_action'); REST uses standard WP REST nonce (rest_nonce).

4.6 Verification Module (includes/verification/)

  • DMS_DNS_Verification: checks published challenge (HTTP/ACME-style) or TXT record.
  • DMS_Health_Check: daily purge (respects audit_retention_days; 0 = keep forever; clamped to 3650 max, 0 min).

5. Data Flow

sequenceDiagram
    participant User as Network Admin
    participant Browser as Browser / WP Admin
    participant WP as WP Multisite
    participant Plugin as DMS Plugin (bootstrap)
    participant MappingEngine as DMS_Mapping_Engine
    participant Settings as DMS_Settings
    participant RestAPI as REST API
    participant DB as wp_sitemeta / DB Tables
    participant SSLMgr as DMS_SSL_Manager

    User->>Browser: Load admin page (settings / mappings / logs)
    Browser->>WP: network_admin_url()
    WP->>Plugin: init hooks (mapping + settings)
    Plugin->>MappingEngine: init()
    Plugin->>Settings: init() (enqueue admin assets)
    Settings->>Browser: admin/css/admin.css + admin/js/admin.js + wp_localize_script(dmAdmin)

    User->>Browser: Submit form (add mapping / save settings)
    Browser->>WP: POST (form action or AJAX)
    WP->>RestAPI: action=dm_rest_create_mapping (nonce verified)
    RestAPI->>MappingEngine: add/update/delete logic
    MappingEngine->>DB: INSERT / UPDATE wp_sitemeta mappings table
    MappingEngine->>SSLMgr: record_certificate(blog_id, domain, 'hosting', 'pending')

    User->>Browser: Click Verify
    Browser->>WP: POST action=dm_rest_verify_mapping
    WP->>RestAPI: verify endpoint
    RestAPI->>MappingEngine: verify mapping
    MappingEngine->>DB: UPDATE verified status
    DB->>MappingEngine: confirmation
    RestAPI->>Browser: JSON response (verified / unverified / error)

    User->>Browser: Click Delete
    Browser->>WP: POST action=dm_rest_delete_mapping (nonce + confirm)
    WP->>RestAPI: delete endpoint
    RestAPI->>MappingEngine: delete mapping
    MappingEngine->>DB: DELETE row
    DB->>MappingEngine: confirmation
    RestAPI->>Browser: JSON response
Loading

6. Data Model

6.1 Database Tables (from database/schema.md + includes/core/class-db-tables.php)

erDiagram
    MAPPINGS ||--|{ LOGS : generates
    MAPPINGS {
        int id PK
        int blog_id FK
        string domain UK
        int active BOOL
        int verified BOOL
        int primary BOOL
        datetime created_at
    }
    LOGS {
        int id PK
        int blog_id FK
        string domain
        int user_id
        string action
        string context
        datetime created_at
    }
    WP_SITEMETA ||--o{ MAPPINGS : stores_mapping_options
    WP_SITEMETA {
        int meta_id PK
        int site_id FK
        string meta_key
        longtext meta_value
    }
Loading

6.2 Option Schema (dm_options in wp_sitemeta)

// Default (from DMS_Settings::register_settings)
array(
    'default_redirect' => '301',      // Choices: 301, 302
    'ssl_provider'     => 'none',     // Choices: none, acme, hosting
    'audit_retention_days' => '180',  // Int: 0 = forever; max 3650; min 0
)

Sanitization (sanitize_options):

  • default_redirect: must be 301 or 302; else 301.
  • ssl_provider: must be none, acme, or hosting; else none.
  • audit_retention_days: absint(); clamped min(3650); 0 preserved (forever).

7. API Reference

7.1 REST Endpoints (includes/rest/class-rest-api.php + docs/API.md)

Endpoint (action) Method Auth Description
dm_rest_create_mapping POST dm_nonce_action + manage_network Add mapping; records SSL 'pending'.
dm_rest_patch_mapping PATCH nonce + capability Update active (enable/disable).
dm_rest_delete_mapping DELETE nonce + manage_network Delete mapping by id.
dm_rest_set_primary POST nonce + manage_network Set primary=1; updates wp_blogs.domain.
dm_rest_verify_mapping POST nonce + manage_network Run verification (challenge/TXT); updates verified.

7.2 WP-CLI (bin/, .github/workflows/release.yml)

  • wp dms verify (from includes/cli/class-cli.php): trigger verification for a domain.
  • Build/release: pwsh bin/build-zip.ps1 [version]; pwsh bin/bump-version.ps1 x.y.z; .github/workflows/release.yml triggers on v* tags.

7.3 Public Functions / Hooks (public/redirect-helpers.php)

Public redirect helpers (included eagerly in plugin bootstrap) provide redirect logic for mapped domains.


8. Configuration

8.1 Plugin Header (domain-mapping-system.php)

/*
Plugin Name: Smart Domain Mapping System
Version: 1.1.1
Stable tag: 1.1.1
*/

DMS_VERSION = 1.1.1 (must match header + readme.txt Stable tag).

8.2 .phpcs.xml.dist

Explicit source targets: includes/, admin/, public/, tests/. Excludes vendor/, node_modules/, _build/. Standard: WordPress coding standards (wpcs).

8.3 .gitignore Exceptions

  • Tracks: README.md, CONTRIBUTING.md, SECURITY.md (root docs allowed).
  • Ignores: other .md (e.g., planning docs like Domain Mapping System - PRD.md excluded from ZIP by .gitignore rules; not a release issue).
  • .gitkeep stripped by build script (Get-ChildItem -Filter '.gitkeep' | Remove-Item).

9. Getting Started

9.1 Install (WordPress Multisite)

# Clone / download plugin to wp-content/plugins/smart-domain-mapping-system/
# Or install from release ZIP

# Activate network-wide (network admin -> Plugins)
# Configure settings at Network Admin -> Domain Mapping -> Settings

9.2 Configure SSL Provider

Settings (dm_options):

  • None: no SSL tracking.
  • ACME / Let's Encrypt: third-party ACME CA.
  • Hosting Site (no ACME): uses the server's existing SSL certificate (hosting-level TLS); avoids ACME interaction cost; integration verification requires live hosting environment (docs/TODO.md).

9.3 Basic Mapping Flow

  1. Network Admin -> Domain Mapping -> Add New Mapping (Blog ID, Domain, Make Primary).
  2. Click Verify to run dm_rest_verify_mapping.
  3. Confirm verification result (challenge / TXT / failure message) in admin/js/admin.js status region (#dm-add-status, #dm-table-status).
  4. Audit entries record in DMS_TABLE_LOGS (action = verify / add / delete / etc.).
  5. Health check (DMS_Health_Check) runs daily; purges entries older than audit_retention_days.

10. Development Guide

10.1 Run Tests

# Requires WP test library (WP_MULTISITE=1); not executable locally without WP_TESTS_DIR
php vendor/bin/phpunit -c phpunit.xml.dist --testsuite dms

# PHP syntax checks (all .php files in repo)
find . -name '*.php' -not -path './vendor/*' -not -path './_build/*' -exec php -l {} \;

10.2 Lint / Coding Standards

# PHPCS (explicit source targets; 0 errors / 0 warnings required for release)
php vendor/bin/phpcs --standard=.phpcs.xml.dist

# JS syntax check
node --check admin/js/admin.js

10.3 Build Release

pwsh bin/build-zip.ps1 1.1.1
# Produces: smart-domain-mapping-system-1.1.1.zip (28 tracked entries, no tests/docs/vendor)

# POT translation template
mkdir -p languages
wp i18n make-pot . languages/domain-mapping-system.pot \
  --exclude=vendor,node_modules,_build,tests,bin,assets,docs,.github \
  --domain=domain-mapping-system \
  --package-name="Smart Domain Mapping System"

10.4 Verification (Pre-Release Checklist — from docs/RELEASE_PROCESS.md)

  • php -l clean on all .php files.
  • node --check admin/js/admin.js passes.
  • php vendor/bin/phpcs --standard=.phpcs.xml.dist reports 0 errors / 0 warnings.
  • composer validate passes.
  • docs/TODO.md updated; docs/MEMORY.md reflects current state; docs/CHANGELOG.md has entry.
  • .gitignore excludes planning docs properly; README.md, CONTRIBUTING.md, SECURITY.md tracked.
  • ZIP clean (28 entries, no .github/, tests/, docs/, vendor/, .md planning docs, .gitkeep).
  • Stable tag in readme.txt, header version (Version:), DMS_VERSION, tag name (v1.1.1) all match.
  • Release notes reference version and assets correctly.

10.5 Unverified Integration Gaps (Honest — from docs/TESTING_STRATEGY.md)

These are NOT production-ready without passing corresponding integration tests:

  • Multisite routing integration (WP_MULTISITE=1 live environment required).
  • Live DNS verification (needs real domain + authoritative DNS server).
  • SSL lifecycle: hosting-level TLS verification (needs live hosting environment; provider='hosting' records pending/issued but cannot verify certificate presence without server-level inspection).
  • Full security auth-flow integration (needs live multisite + REST nonce + capability enforcement against real manage_network users).
  • DB rollback/reversibility (dbDelta creates tables; rollback not exercised against live DB).
  • Performance/load benchmark (not required by audit checklist).

Appendix A — Class Index

Class File Singleton? Key Methods
DMS_Plugin core/class-domain-mapping-system.php Yes (get_instance) init()
DMS_Mapping_Engine core/class-mapping-engine.php Yes init(), list_mappings()
DMS_Settings admin/class-settings.php Yes init(), sanitize_options(), register_settings(), add_menu(), render_settings()
DMS_Logging core/class-logging.php Yes log(), health-check purge
DMS_Health_Check verification/class-health-check.php Yes run() (daily)
DMS_DNS_Verification verification/class-dns-verification.php — Verification logic
DMS_REST_API rest/class-rest-api.php — Endpoint registration
DMS_SSL_Manager ssl/class-ssl-manager.php Yes record_certificate()
DMS_SSL_Provider_None ssl/class-ssl-provider-none.php — issue_certificate(), renew_certificate() (provider='hosting')
DMS_CLI_Command cli/class-cli.php — WP-CLI command (dms verify)

Document generated from repository state at v1.1.1 (719c8a2). All paths, links, and structure verified against actual repository contents. No false production-readiness claims included; unverified external-infrastructure gaps documented honestly (docs/TODO.md, docs/TESTING_STRATEGY.md).