Documentation · Technical Documentation

Architecture Overview

This document describes the high-level architecture of the ADP Car Market Hub WordPress plugin: how the source tree is organised, which classes carry the main responsibilities, and how the major features are wired together at runtime.

When to use this document

Read this document if you need to:

  • Get an overview of the plugin's PHP code base before diving into a specific subsystem.
  • Understand which class is responsible for a given feature.
  • Plan a customisation, integration or code review.

For step-by-step bootstrap order, see Plugin Bootstrap And Lifecycle. For storage details, see Data Model and Database Schema.

Overview

The plugin is implemented in PHP and follows standard WordPress plugin conventions. It uses:

  • A single root file (adp-car-market-hub.php) that defines plugin constants, registers an autoloader and hooks bootstrap callbacks.
  • A AS24CI\ PHP namespace for all classes.
  • The WordPress core APIs for custom post types, taxonomies, options, WP-Cron, REST API, AJAX handlers and dbDelta-managed custom tables.
  • A central AS24CI\Plugin singleton that wires every feature together on the plugins_loaded action.

Top-level directory layout

The repository is organised as follows (only directories relevant to the runtime architecture are listed):

  • adp-car-market-hub.php — main plugin file. Defines constants, registers the autoloader, loads the text domain, registers activation/deactivation hooks, registers custom WP-Cron intervals and bootstraps the AS24CI\Plugin singleton on plugins_loaded.
  • includes/ — shared and frontend PHP classes, one class per file. File names follow the pattern class-as24ci-<name>.php and resolve to the AS24CI\<Name> class via the autoloader.
  • includes/admin/ — admin-only PHP classes (settings tabs, list-table helpers, dashboard widgets). Resolved by the same autoloader as a fallback when a class is not found under includes/.
  • src/Core/Helpers.php — shared procedural helpers loaded unconditionally from the main plugin file.
  • templates/ — frontend templates and template parts that can be overridden by themes.
  • assets/ — admin and frontend CSS, JavaScript and images.
  • languages/ — translation files; the text domain is adp-car-market-hub.
  • uninstall.php — runs when the plugin is deleted from WordPress and removes plugin options and (optionally) imported content.

Autoloader

adp-car-market-hub.php registers a small PSR-4-compatible autoloader for the AS24CI\ prefix. Class names are converted to the file naming convention class-as24ci-<lower-case-name-with-dashes>.php. The autoloader looks first in includes/ and then in includes/admin/, which lets shared and admin-only classes share a single namespace.

Core classes and their responsibilities

The following classes form the backbone of the plugin. Names are written in their fully-qualified form (AS24CI\<Class>).

Bootstrap and shared services

  • AS24CI\Plugin — Singleton entry point. Constructs the shared service instances (Logger, Client, Image_Importer, Vehicle_Repository, Importer, Scheduler), wires all WordPress hooks for the active feature set and exposes the static activate() / deactivate() / init() callbacks.
  • AS24CI\Logger — Lightweight logger used across the plugin for importer and scheduler messages.
  • AS24CI\Options — Centralised registry of option keys exposed as class constants (e.g. Options::DB_VERSION, Options::DEFAULT_CURRENCY, Options::AUTO_IMPORT_ENABLED). The uninstall.php script uses Options::get_all_keys() to clean up options on plugin removal.

Data and storage

  • AS24CI\CPT — Registers the as24ci_car custom post type with custom capability mapping (as24ci_car / as24ci_cars) and the combined "AutoScout24 API Import" metabox.
  • AS24CI\Taxonomies — Registers the 15 vehicle attribute taxonomies attached to as24ci_car (make, model, body type, fuel type, transmission, drive, condition, exterior/interior colour, emission standard, energy label, vehicle category, warranty type, warranty details, cylinder arrangement).
  • AS24CI\Leads_CPT — Registers the as24ci_lead custom post type used to store contact-form submissions, with status constants for new, contacted, closed and spam.
  • AS24CI\Vehicle_Repository — Repository for the dedicated custom table {$wpdb->prefix}as24_vehicles that holds vehicle field data (instead of wp_postmeta). Provides schema management (maybe_create_table()), CRUD helpers, and filter/order whitelists used by find().
  • AS24CI\Vehicle_Field_Resolver — Centralised reader that resolves vehicle fields by combining repository data with manual overrides. Wired during Plugin construction via Vehicle_Field_Resolver::set_repository().
  • AS24CI\Vehicle_Deleter — Single, idempotent cleanup path used whenever a vehicle is permanently deleted (native WP delete, importer full-sync delete, bulk action). Wired during Plugin construction.

Import pipeline

  • AS24CI\Client — HTTP client for the AutoScout24 API. Handles authentication and request execution.
  • AS24CI\Mapper — Maps incoming AutoScout24 listing payloads to the internal field shape used by the repository and writes the _as24ci_listing_id postmeta for backwards compatibility.
  • AS24CI\Importer — Coordinates per-listing import: fetches data via Client, transforms it via Mapper, persists vehicles via the repository and tracks change detection through the _as24ci_content_hash and _as24ci_images_hash postmeta keys.
  • AS24CI\Image_Importer — Downloads and attaches vehicle images, optionally converting them to WebP. Stores attachment IDs in the _as24ci_image_ids postmeta.
  • AS24CI\Scheduler — Owns the WP-Cron hooks as24ci_scheduled_import and as24ci_image_queue_process, the run-lock transients (as24ci_cron_import_running, as24ci_image_queue_running) and the manual Batch-Wizard queue transient as24ci_batch_queue. The same run_import() flow is used by WP-Cron, the REST cron endpoint and the admin "Run now" button.
  • AS24CI\Cron_Endpoint — REST endpoint that allows external servers to trigger imports through a token-secured URL.

Frontend, SEO and integrations

  • AS24CI\Templates — Routes vehicle archive and single templates through the plugin's template loader, enabling theme overrides.
  • AS24CI\Assets — Registers and enqueues admin and frontend CSS and JavaScript bundles.
  • AS24CI\Archive_Filters — Renders the archive filter UI and applies query modifications based on user selections.
  • AS24CI\Schema — Adds Schema.org structured data and Open Graph / Twitter Card meta tags to single vehicle pages. Optional, gated by Options::FEATURE_SCHEMA.
  • AS24CI\Sitemap — Integrates vehicles into the WordPress core sitemap and is compatible with Yoast and Rank Math. Optional, gated by Options::FEATURE_SITEMAP.
  • AS24CI\Social_Share, AS24CI\Pdf_Datasheet, AS24CI\Favorites, AS24CI\Compare, AS24CI\Export, AS24CI\Bulk_Actions, AS24CI\Financing_Calculator, AS24CI\Test_Drive, AS24CI\Search_Agent — Optional features that each register their own hooks. Most are gated by an Options::FEATURE_* toggle (see seed_safe_defaults() in AS24CI\Plugin for the defaults shipped on a fresh install).
  • AS24CI\Webhooks — Outgoing webhooks for CRM and integration use cases.
  • AS24CI\Rest_Api — Public REST API for vehicle listings, gated by Options::REST_API_ENABLED.
  • AS24CI\Analytics — Page-view, filter and lead tracking. Owns the {$wpdb->prefix}as24ci_analytics table and the as24ci_daily_cleanup retention cron.
  • AS24CI\Ai_Assistant — Generates AI descriptions, SEO metadata and equipment highlights using the managed Google Gemini configuration exposed by AS24CI\Ai_Config. The customer Gemini key is delivered server-to-server by the API Platform and stored encrypted via AS24CI\Ai_Credential_Manager; no provider, model or API key is selectable in the admin UI.
  • AS24CI\Data_Quality_Scanner — Optional taxonomy-typo detector that uses the AI integration.
  • AS24CI\Pricing_Engine — Daily pricing analysis that runs on the as24ci_pricing_analysis_cron hook.
  • AS24CI\Locations, AS24CI\Seller_Profile_Fields — Dealership locations, opening hours and seller-profile metadata.
  • AS24CI\Team / AS24CI\Admin_Team — CMH Team: dealership sales contacts that do not require WordPress user accounts. Storage is option-based (no custom table or CPT); contacts are kept in Options::TEAM_MEMBERS and related option keys, mirroring the Locations pattern. Admin_Team registers a dedicated top-level admin menu.
  • AS24CI\License_Manager, AS24CI\License_Client, AS24CI\License_Refresh_Signal, AS24CI\License_Signal_Secret — ADP Car Market Hub API Platform license / managed-access layer. License_Manager owns the daily re-validation cron (as24ci_license_refresh), feature-rights storage, operational/AI write-path gating and admin notices. License_Refresh_Signal exposes the inbound POST /as24ci/v1/license-refresh-signal endpoint.
  • AS24CI\Ai_Credential_Manager — Stores and decrypts the customer Gemini credential delivered by the API Platform.
  • Content Studio (AS24CI\Content_Studio_*, e.g. Content_Studio_Repository, Content_Studio_Options, Content_Studio_Admin_Worker, Admin_Tab_Content_Studio) — A largely self-contained module that generates marketing content from existing vehicle data. It owns its own tables (as24ci_content_studio_jobs, as24ci_content_studio_assets), its own as24ci_content_studio_* options and a background worker, and is bootstrapped from the main plugin file rather than the Admin router. It reads existing vehicle/import data read-only.

Admin UI

  • AS24CI\Admin — Top-level admin controller, instantiated only when is_admin() is true. Internally composes tab classes from includes/admin/ (importer, settings, mapping, design, layout manager, leads, AI Assistant, system status, etc.).
  • AS24CI\Dashboard_Widget — Optional WordPress dashboard widget, gated by Options::FEATURE_DASHBOARD_WIDGET.

Feature toggles and "safe first setup"

Most non-essential features are conditionally registered in AS24CI\Plugin::register_hooks() based on options whose constants are defined on AS24CI\Options (for example FEATURE_SCHEMA, FEATURE_SITEMAP, FEATURE_FAVORITES, FEATURE_COMPARE, FEATURE_PDF_DATASHEET, REST_API_ENABLED, AI_ASSISTANT_ENABLED, ANALYTICS_ENABLED, TEST_DRIVE_ENABLED).

On a fresh install the plugin seeds conservative defaults via AS24CI\Plugin::seed_safe_defaults(). Privacy-relevant, external or batch features default to off; frontend-friendly features (sitemap, schema, favorites, compare, financing calculator, dashboard widget, export, lazy loading, layout manager) default to on. Existing installations are never overwritten because the seeder uses add_option().

Storage layout (high level)

The plugin uses three storage layers:

  1. Custom database tables managed via dbDelta: - {$wpdb->prefix}as24_vehicles — vehicle field data, owned by AS24CI\Vehicle_Repository. - {$wpdb->prefix}as24ci_analytics — analytics events, owned by AS24CI\Analytics. - {$wpdb->prefix}as24ci_search_agents — search-alert subscriptions, owned by AS24CI\Search_Agent. - {$wpdb->prefix}as24ci_content_studio_jobs and {$wpdb->prefix}as24ci_content_studio_assets — Content Studio jobs and generated assets, owned by AS24CI\Content_Studio_Repository.
  2. WordPress posts and postmeta: - as24ci_car posts back the WordPress permalinks, taxonomies and templates for each vehicle. A small set of postmeta keys remains in wp_postmeta for backwards compatibility (for example _as24ci_listing_id, _as24ci_content_hash, _as24ci_images_hash, _as24ci_image_ids, _as24ci_manual_image_ids). - as24ci_lead posts store contact-form submissions with status stored in _as24ci_lead_status.
  3. wp_options — All user-configurable settings. Keys are defined as constants on AS24CI\Options (and, for Content Studio, on AS24CI\Content_Studio_Options). Schema versions for the custom tables are also stored as options (as24ci_db_version, as24ci_vehicles_db_version, as24ci_search_agent_db_version, as24ci_content_studio_db_version). CMH Team contacts are also stored in options (as24ci_team_*).

For column-level details, see Database Schema. For the logical entity model and how postmeta and the custom table interact, see Data Model.

Runtime flow at a glance

A typical request goes through the following stages (simplified):

  1. WordPress loads adp-car-market-hub.php, which defines plugin constants, registers the autoloader and adds custom WP-Cron intervals.
  2. On plugins_loaded (priority 1) the text domain is loaded.
  3. On plugins_loaded (default priority) AS24CI\Plugin::init() runs, instantiates the singleton and registers all hooks for active features.
  4. Feature classes register their own hooks on init, rest_api_init, wp_ajax_*, wp_footer, etc.
  5. Subsequent activity (a cron run, a REST request, a frontend page view) is handled by the registered hooks.

Operational notes

  • The plugin assumes the WordPress and PHP versions declared in the plugin header (Requires at least: 6.2, Requires PHP: 8.1). Lower versions are not supported.
  • Most subsystems use wpdb directly only when dbDelta cannot express the required schema or query. Direct queries are limited to the repository, analytics, search-agent and uninstall code.
  • The architecture deliberately keeps frontend rendering separate from data import. The importer never renders templates; the templates never trigger network requests to AutoScout24.
  • The plugin adds a "Settings" link to its row on the WordPress Plugins screen via the plugin_action_links_<basename> filter.

Troubleshooting

  • A feature does not seem to register. Check the corresponding Options::FEATURE_* toggle. The register_hooks() method in AS24CI\Plugin skips disabled features.
  • A class is not found. Verify the file naming convention (class-as24ci-<lower-dashed-name>.php) and that the file lives in includes/ or includes/admin/. The autoloader only searches these two directories.
  • An admin-only class is referenced from the frontend. Admin classes are loaded on demand by the autoloader, but they may rely on admin-only globals or capabilities. Verify behaviour in the current plugin version before depending on it.