For Developers
This is the developer entry point for Dino Discover. If you’re implementing a quiz on a client site and need to swap the recommendation engine, override the storefront templates, or hook custom analytics into the lead pipeline — start here.
The plugin is built to be extended without forking. The four engine interfaces, the ~55-route REST API, the roughly thirty named hooks, and the WordPress-native template override pattern are the supported surfaces.
Start here
Section titled “Start here”- Architecture — the high-level systems map: container, engines, repositories, REST controllers, cron jobs.
- Engine Interfaces — the four PHP contracts (Question, Recommendation, Coverage, Statistics) that let you replace the brain of the plugin without rewiring the surface.
Reference
Section titled “Reference”- REST API Reference — the admin and storefront endpoints, grouped by controller, with capability and rate-limit notes.
- Hook Reference — every
dino_discover_*action and filter, with the file:line where it fires.
Key design contracts
Section titled “Key design contracts”A few invariants worth knowing before you start extending:
- Published-only storefront. Storefront endpoints accept only
published snapshots. A custom PHPStan rule
(
PublishedSnapshotOnlyRule) fails the build if any public route reads draft state. The single exception is the admin draft-preview tab, which is admin-session-gated and nonce-protected. - HPOS-compatible. Every order read goes through
wc_get_orders(). Another PHPStan rule (NoLegacyOrderTableReadRule) refuses code paths that open the legacy posts table for orders. - PHP 8.1 floor. The codebase uses enums, readonly value objects, and native union types. PHPStan is pinned to PHP 8.1 so 8.2+ syntax surfaces as an error locally.
- Two-tier engine filters. Every engine binding takes a global
filter (
dino_discover_<name>_engine) — see Engine Interfaces. - Filterable defaults. Settings keys are settable through the
admin UI, but every default is also reachable through a PHP filter,
so you can override from
wp-config.phpor an mu-plugin.
Composer autoload
Section titled “Composer autoload”The plugin uses Composer PSR-4:
"autoload": { "psr-4": { "DinoDiscover\\": "includes/" }}Every class in includes/ is available under the DinoDiscover\
namespace. The container (PHP-DI 7) wires the dependencies; if you’re
adding a new service that other code depends on, register it through
the container, not as a global.
The codebase by layer
Section titled “The codebase by layer”| Layer | Lives in | Role |
|---|---|---|
| Admin SPA | src/admin/ | React (@wordpress/element). Builder, Dashboard, Coverage, Settings. |
| Storefront bundle | src/storefront/ | Preact (preact/compat alias). Quiz, results, lead capture. |
| REST API | includes/API/ | Controllers under dino-discover/v1. |
| Engines | includes/Engine/ | Question, Recommendation, Coverage, Statistics. |
| Repositories | includes/Repository/ | Database access (one repo per domain). |
| Cron | includes/Cron/ | Event flush, rollup, prune, coverage refresh. |
| Snapshot | includes/Snapshot/ | Publish, restore, hydrate. |
| Settings | includes/Settings/ | Typed schema + store. |
| Storefront | includes/Storefront/ | Renderer, asset loader, shortcode, templates. |
| Integrations | includes/Integrations/ | Klaviyo, Mailchimp, Webhook. |
| Privacy | includes/Privacy/ | GDPR exporter / eraser. |
| Variant | includes/Variant/ | A/B variant assignor + linker. |
| Licence | includes/Licence/ | Licence client (forward-wired for 1.0). |
| Support | includes/Support/ | Capability, crypto, hash, cron helpers. |
| PHPStan | includes/PHPStan/ | Custom rules (TR-1, HPOS, crypto ownership). |
Where to read first if you’re …
Section titled “Where to read first if you’re …”- Swapping the recommendation engine — Engine Interfaces § Recommendation.
- Integrating with an external CRM — Hook Reference §
dino_discover_lead_capturedaction and the integrations registry filter. - Building a custom analytics pipeline — Hook Reference §
lifecycle actions (note: most lifecycle actions ship in 0.1.0;
some are documented for the v1 contract but not yet emitted —
watch the relevant
do_actionsite before you depend on it). - Overriding a storefront template — Embedding the Quiz § Templates and styling.
What’s not yet shipped
Section titled “What’s not yet shipped”Per the Beta gap list, a few developer-facing surfaces are wired in the design but not yet emitted in 0.1.0:
- Per-quiz
_for_quizfilter variants — the design names them (e.g.dino_discover_recommendation_engine_for_quiz) but no callsite exists inincludes/today; only the site-wide single-arg filters fire.
Most lifecycle actions catalogued in the technical design do fire
in 0.1.0: dino_discover_quiz_started,
dino_discover_question_answered, dino_discover_quiz_completed,
dino_discover_quiz_abandoned, dino_discover_recommendation_clicked,
dino_discover_lead_captured, dino_discover_order_attributed,
dino_discover_before_results, and dino_discover_after_results —
see Hook Reference for callsites. The full
inventory lives in includes/ — grep for apply_filters and
do_action to confirm anything specific.
What’s next
Section titled “What’s next”- Architecture — the systems map.
- Engine Interfaces — the four contracts.
- REST API Reference — the endpoint catalogue.
- Hook Reference — the full actions/filters list.