Hook Reference
Dino Discover exposes a few dozen named hooks in 0.1.0 — a mix of
filters (used to substitute behaviour) and actions (fired at
observability points). This page covers the load-bearing ones grouped
by purpose. For an exhaustive callsite-by-callsite enumeration the
authoritative answer is always grep:
grep -rn 'apply_filters\|do_action' includes/ | grep dino_discover_For the architectural picture of how these hooks fit into the systems map, see Architecture.
Engine swap filters
Section titled “Engine swap filters”The four filters that replace engine implementations site-wide. Each expects an instance of the corresponding interface as the return value.
| Filter | Replaces | Default |
|---|---|---|
dino_discover_question_engine | QuestionEngineInterface | RulesQuestionEngine |
dino_discover_recommendation_engine | RecommendationEngineInterface | UpvoteRecommendationEngine |
dino_discover_coverage_engine | CoverageEngineInterface | CoverageCalculator |
dino_discover_statistics_engine | StatisticsInterface | PointEstimateStatistics |
add_filter( 'dino_discover_recommendation_engine', function( $default ) { return new \MyAgency\EmbeddingRecommendationEngine();} );Each filter runs at container-bind time, so it’s called once per request lifecycle, not per call.
Per-call result filters
Section titled “Per-call result filters”Filters that run on engine output. Cheaper than swapping the whole engine when you only want to tweak the result.
dino_discover_next_question
Section titled “dino_discover_next_question”Fires every time the question engine returns a next-node decision. Lets you override the routing per call.
- File:
includes/Engine/RulesQuestionEngine.php:497 - Args:
(NextNodeDecision $decision, AnswerHistory $history, QuizContext $context) - Returns: the (possibly-modified)
NextNodeDecision.
dino_discover_recommendation_results
Section titled “dino_discover_recommendation_results”The last word on the recommendation. Re-rank, suppress, or inject items here.
- File:
includes/Engine/UpvoteRecommendationEngine.php:156 - Args:
(RecommendationSet $set, QuizContext $context, AnswerHistory $history) - Returns: the (possibly-modified)
RecommendationSet.
add_filter( 'dino_discover_recommendation_results', function( $set ) { // Drop any product tagged 'discontinued'. $items = array_filter( $set->items(), function( $item ) { return ! has_term( 'discontinued', 'product_tag', $item->product_id() ); } ); return $set->with_items( array_values( $items ) );}, 10 );Lifecycle actions
Section titled “Lifecycle actions”Observability points fired at key moments. Subscribe to integrate with external systems.
dino_discover_quiz_published
Section titled “dino_discover_quiz_published”Fires after a successful publish, after the snapshot row is written
and dd_quizzes.published_snapshot_id is flipped.
- File:
includes/Snapshot/Snapshotter.php:341 - Args:
(int $quiz_id, int $snapshot_id)
Use it to invalidate caches, notify Slack, kick off a CDN purge.
dino_discover_draft_replaced
Section titled “dino_discover_draft_replaced”Fires after a snapshot is restored to draft (the inverse of publish).
- File:
includes/Snapshot/Snapshotter.php:392 - Args:
(int $quiz_id, int $snapshot_id)
dino_discover_quiz_started
Section titled “dino_discover_quiz_started”Fires server-side when a new session row is created (the start of a shopper’s run through a quiz).
- File:
includes/API/StorefrontController.php(create_session) - Args:
(int $session_id, array $payload)
dino_discover_question_answered
Section titled “dino_discover_question_answered”Fires once per answer_given event after the row lands in
dd_events_scratch.
- File:
includes/API/StorefrontController.php(events ingest) - Args:
(int $session_id, array $event_payload)
dino_discover_quiz_completed
Section titled “dino_discover_quiz_completed”Fires once per quiz_completed event.
- File:
includes/API/StorefrontController.php(events ingest) - Args:
(int $session_id, array $event_payload)
dino_discover_quiz_abandoned
Section titled “dino_discover_quiz_abandoned”Fires once per quiz_abandoned event.
- File:
includes/API/StorefrontController.php(events ingest) - Args:
(int $session_id, array $event_payload)
dino_discover_recommendation_clicked
Section titled “dino_discover_recommendation_clicked”Fires once per recommendation_clicked event.
- File:
includes/API/StorefrontController.php(events ingest) - Args:
(int $session_id, array $event_payload)
dino_discover_lead_captured
Section titled “dino_discover_lead_captured”Fires after a lead row is inserted, before any integration push is queued.
- File:
includes/API/StorefrontController.php:641 - Args:
(int $lead_id, int $session_id, string $email)
Note: the email passed here is the plaintext email submitted by
the shopper. The row in dd_leads stores both the plaintext email
column (for CSV export and outbound integrations) and an HMAC-SHA256
email_hash column (for dedupe lookups).
dino_discover_order_attributed
Section titled “dino_discover_order_attributed”Fires after the AttributionLinker attributes a completed WooCommerce
order back to a quiz session within the attribution window.
- File:
includes/Engine/Analytics/AttributionLinker.php:239 - Args:
(int $order_id, array $payload)where$payloadcarriessession_id,quiz_id,snapshot_id,variant_id,product_id,revenue_cents(all ints).
dino_discover_draft_preview_accessed
Section titled “dino_discover_draft_preview_accessed”Fires every time the admin draft-preview tab loads. The default
listener (DraftPreviewAuditLogger) writes an audit entry to the WP
error log.
- File:
includes/Storefront/DraftPreviewPage.php:204 - Args:
(array $payload)— keys includeresult,user_id,ip,quiz_id,quiz_slug,timestamp, plus optionalreasonandroutediscriminator.
dino_discover_token_unresolved
Section titled “dino_discover_token_unresolved”Fires when a {token} in a template can’t be resolved.
- File:
includes/Engine/TokenResolver.php:242 - Args:
(string $token, string $template)
dino_discover_question_engine_removed_answer_fallback
Section titled “dino_discover_question_engine_removed_answer_fallback”Fires when the question engine encounters an answer that’s been removed from the snapshot since the session started — the snapshot-aware recovery path.
- File:
includes/Engine/RulesQuestionEngine.php:124 - Args:
(int $current_id, array $answer_ids)
dino_discover_term_exceeds_cap
Section titled “dino_discover_term_exceeds_cap”Fires when a target tag/category expansion exceeds the per-target product cap.
- File:
includes/Engine/Cache/TargetExpansionCache.php:141 - Args:
(int $id, int $total, string $type)
Capability filters
Section titled “Capability filters”dino_discover_capability
Section titled “dino_discover_capability”Override the admin capability gate.
- File:
includes/Support/Cap.php:29 - Default:
'manage_dino_discover' - Args:
(string $capability)
dino_discover_capability_roles
Section titled “dino_discover_capability_roles”The roles to grant the admin capability to at activation.
- File:
includes/Activator.php:247 - Default:
[ 'administrator', 'shop_manager' ] - Args:
(array $roles)
Storefront / cart filters
Section titled “Storefront / cart filters”dino_discover_cart_adder
Section titled “dino_discover_cart_adder”Swap the implementation of CartAdderInterface used by the
bulk-add endpoint and per-card add-to-cart.
- File:
includes/Plugin.php:437 - Default:
WooCartAdder
Question types & integrations registries
Section titled “Question types & integrations registries”dino_discover_register_question_types
Section titled “dino_discover_register_question_types”Register a custom question type. The filter is called by the
QuestionType\Registry at boot.
- File:
includes/Engine/QuestionType/Registry.php:62 - Args:
(array $descriptors)— append your descriptor to the array and return it.
dino_discover_register_integrations
Section titled “dino_discover_register_integrations”Register a custom Connect-tab integration.
- File:
includes/Integrations/Registry.php
Integration fallback keys
Section titled “Integration fallback keys”dino_discover_klaviyo_fallback_api_key
Section titled “dino_discover_klaviyo_fallback_api_key”Site-wide Klaviyo API key for environments that source secrets from
outside wp_options.
- File:
includes/Integrations/Klaviyo/KlaviyoPusher.php:619
dino_discover_mailchimp_fallback_api_key
Section titled “dino_discover_mailchimp_fallback_api_key”Same pattern for Mailchimp.
- File:
includes/Integrations/Mailchimp/MailchimpPusher.php:629
REST tuning
Section titled “REST tuning”dino_discover_rate_limit
Section titled “dino_discover_rate_limit”Tune the per-route rate limit. Default is 60 requests/minute.
- File:
includes/API/RateLimiter.php:79
dino_discover_client_ip
Section titled “dino_discover_client_ip”Override how the client IP is derived. Useful behind a CDN that
sets CF-Connecting-IP, X-Forwarded-For, etc.
- File:
includes/API/RateLimiter.php:158
Analytics tuning
Section titled “Analytics tuning”dino_discover_attribution_window_days
Section titled “dino_discover_attribution_window_days”Override the attribution window (default 30 days; clamped to 0–365).
- File:
includes/Engine/Analytics/AttributionLinker.php:184
dino_discover_statistics_rate_metrics
Section titled “dino_discover_statistics_rate_metrics”Customise the list of metrics treated as rate-style for confidence interval computation.
- File:
includes/Engine/Statistics/PointEstimateStatistics.php:192
Storefront template filter
Section titled “Storefront template filter”dino_discover_template_path
Section titled “dino_discover_template_path”Override the resolved template path before the loader requires it. The default loader looks up theme overrides, falls back to plugin templates; this filter is the last hop.
- File:
includes/Storefront/TemplateLoader.php(constantFILTER_TEMPLATE_PATH)
Storefront template actions
Section titled “Storefront template actions”Both actions fire from templates/quiz-results.php around the results
panel render. Use them to inject markup before or after the panel
without overriding the template.
dino_discover_before_results
Section titled “dino_discover_before_results”Fires immediately before the results panel renders.
- File:
templates/quiz-results.php:53 - Args:
(array $args)
dino_discover_after_results
Section titled “dino_discover_after_results”Fires immediately after the results panel renders.
- File:
templates/quiz-results.php:131 - Args:
(array $args)
Docs URL overrides
Section titled “Docs URL overrides”For agencies that want to host their own docs or customise the in-product help links:
| Filter | Overrides |
|---|---|
dino_discover_docs_base_url | The docs base URL for in-app links. |
dino_discover_docs_url | The Onboarding tips link. |
dino_discover_methodology_url | The analytics-methodology link. |
Licence URL overrides
Section titled “Licence URL overrides”| Filter | Overrides |
|---|---|
dino_discover_licence_url | The licence server URL. |
dino_discover_licence_server | The licence server implementation (LicenceServerInterface). |
What’s documented in v1 but not yet emitted
Section titled “What’s documented in v1 but not yet emitted”- The per-quiz
_for_quizvariants of the engine filters (e.g.dino_discover_recommendation_engine_for_quiz) are named in the design doc, but no callsite exists inincludes/today; only the global single-arg filters fire. dino_discover_question_seenanddino_discover_recommendation_shownare documented as scratch-only telemetry events (per theLIFECYCLE_ACTIONSdocblock inStorefrontController) — they are validevent_typevalues but intentionally do not surface as actions in 0.1.0.
Note that 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 do fire in 0.1.0 — see the
sections above for callsites.
Verifying what’s live
Section titled “Verifying what’s live”The authoritative answer to “is hook X emitted” is grep:
grep -rn 'dino_discover_X' includes/The result will show every apply_filters and do_action call site
for the hook in the current build.
What’s next
Section titled “What’s next”- Engine Interfaces — the contracts the swap-filters substitute.
- REST API Reference — the endpoints that fire many of these hooks.
- Architecture — where each hook sits in the systems map.
- Lead Capture Panel — the
merchant-facing surface for
lead_captured.