Use cases and output profiles
This document matches the current PHP layer: Use_Case, Use_Case_Registry, Use_Case_Storage, and built-in implementations such as Sidebar_Image_Use_Case and Open_Graph_Image_Use_Case.
Terminology
Section titled “Terminology”| Term | Meaning |
|---|---|
| Use-case spec | Advisory dimensions (recommended_settings()), settings schema, and mapping sources for the editor. |
| Open Graph request context | Internal bucket in Open_Graph_Image_Use_Case for eligibility: singular, front_page, or non_singular — not a separate PHP “source context” API. |
Field values at render time come from the post (or preview) passed to Field_Resolver::collect_raw(); Open Graph settings (post types, front page, archives) live in the assignment settings object.
Layers
Section titled “Layers”- Use case — Defines schema, mapping sources, and
init()hooks (for examplewp_head, generation filters). - Registry — Stores registered types (slug → label, class, …) and boots active classes from the loader manifest option when
coverkit_initruns. - Storage — Reads/writes per-template assignments in post meta and rebuilds the loader manifest when that meta changes.
- Renderer —
Renderer::generate( string $generation_key, $template_id, ?int $post_id = null, array $options = array() )loads a template, applies field data, and runs the generator. Field wiring is in block attributes /{field}placeholders. Assignments live in template post meta_coverkit_use_cases(Use_Case_Storage::META_KEY).
Boot order
Section titled “Boot order”plugins_loadedpriority1:init()constructsUse_Case_Registry(constructorrequire_once’sincludes/use-cases/bootstrap.php, which schedulescoverkit_register_use_case()oncoverkit_initat priority5only; it does not register immediately).initpriority15:fire_coverkit_init()runsdo_action( 'coverkit_init' ).coverkit_initpriority5: built-in and plugin code callcoverkit_register_use_case()so types exist before boot.coverkit_initpriority10:Use_Case_Registry::boot()reads the optionUse_Case_Registry::LOADER_MANIFEST_OPTION(coverkit_active_use_case_classes, slug → FQCN), instantiates each class once, and callsUse_Case::maybe_init()(which runsinit()).- When template meta
_coverkit_use_caseschanges,Use_Case_Storage::rebuild_loader_manifest()rescans templates and rewritescoverkit_active_use_case_classes.
Open Graph output is registered from Open_Graph_Image_Use_Case::init() (wp_head), not from the registry class.
| Path | Role |
|---|---|
includes/class-coverkit-use-case.php | Abstract Use_Case. |
includes/class-coverkit-use-case-registry.php | Use_Case_Registry singleton; type registration + manifest boot + reset() for tests. |
includes/class-coverkit-use-case-storage.php | Canonical _coverkit_use_cases meta, sanitization, loader manifest rebuild. |
includes/use-cases/class-coverkit-*-use-case.php | Concrete use cases; autoload: CoverKit\Foo_Bar_Use_Case → includes/use-cases/class-coverkit-foo-bar-use-case.php. |
Autoload rule: in coverkit.php, CoverKit\Use_Cases\Foo_Bar_Use_Case → includes/use-cases/class-coverkit-foo-bar-use-case.php.
Registering a custom use case
Section titled “Registering a custom use case”Register on coverkit_init at priority less than 10 so the slug exists before Use_Case_Registry::boot() runs.
add_action( 'coverkit_init', static function (): void { \CoverKit\coverkit_register_use_case( 'my_packaging', array( 'label' => __( 'Packaging shot', 'my-plugin' ), 'description' => __( 'Square catalog image from product data.', 'my-plugin' ), 'class' => \MyPlugin\Packaging_Use_Case::class, ) ); }, 5);Extending Use_Case
Section titled “Extending Use_Case”namespace MyPlugin;
use CoverKit\Use_Case;
final class Packaging_Use_Case extends Use_Case {
/** * @return array<string, mixed> */ protected static function recommended_settings(): array { return array( 'dimensions' => array( 'width' => 1080, 'height' => 1080 ), 'formats' => array( 'jpg', 'webp' ), ); }
/** * @return array<string, array<string, mixed>> */ protected static function use_case_settings_schema(): array { return array( 'format' => array( 'type' => 'string', 'label' => __( 'Format', 'my-plugin' ), 'control' => 'select', 'default' => 'jpg', 'options' => array( 'jpg' => __( 'JPG', 'my-plugin' ) ), ), ); }
/** * @return array<string, array<string, mixed>> */ protected static function use_case_mapping_sources(): array { return array( 'post_title' => array( 'required' => true ), 'site_logo' => array( 'recommended' => true ), ); }
protected function init(): void { // Optional: \add_action(), \add_filter(), … }}The slug returned by get_slug() comes from the registry entry for your class (the $slug argument to coverkit_register_use_case()).
Mapping source catalog (editor field picker)
Section titled “Mapping source catalog (editor field picker)”Use_Case::get_mapping_sources() builds the list of mappable data sources for the block editor.
- Base catalog —
Use_Case::default_mapping_sources()holds shared built-ins (post fields, site fields, featured image, taxonomies, etc.). Entries are not markedrequiredhere so each use case controls requirements. - Per-class delta — Override
use_case_mapping_sources()so entries shallow-merge onto an existing id: for each key,array_merge( base[id], delta[id] )so the delta overrides individual keys (for examplerequired,recommended,label) while keeping base keys such asformatterwhen the delta omits them. - First-party prune —
Use_Case::filter_declared_mapping_sources( $sources )runs next (default: no-op). Subclasses override it to drop keys from the merged list without registering a WordPress filter when a use case needs a shorter picker. - Public extension — unchanged:
coverkit_use_case_mapping_sourcesandcoverkit_use_case_{$slug}_mapping_sourcesstill wrap the result for third-party plugins.
Resolver keys should match Field_Resolver::collect_builtin_raw(); use a 'field' entry in the source definition when the mapping id differs from the resolver key.
Built-in use cases
Section titled “Built-in use cases”Sidebar image (sidebar_image)
Section titled “Sidebar image (sidebar_image)”- Class:
CoverKit\Use_Cases\Sidebar_Image_Use_Case. - Recommended: 300×600, formats aligned with the sidebar preview consumer.
Open Graph image (opengraph)
Section titled “Open Graph image (opengraph)”- Class:
CoverKit\Use_Cases\Open_Graph_Image_Use_Case(file:class-coverkit-open-graph-image-use-case.php). Slug must stay aligned with REST andRenderercallers using theopengraphgeneration key. - Recommended: 1200×630 (
1.91:1), formats includepng,jpg,jpeg,gif,webp. - Mapping delta:
post_titlerequired;post_excerpt,author,site_logo,featured_imagerecommended. - Runtime: On
wp_head, prints oneog:imageblock for the first eligible published template in ascending ID order. Eligibility uses assignment settings: non-emptypost_typelist for singular views,apply_front_pagefor the front page,apply_non_singularfor archives/search (see class docblocks). Image URL uses the REST shapecoverkit/v1/opengraph/{template_id}/{post_id}.{ext}. - Extensibility:
coverkit_opengraph_meta_enabled,coverkit_opengraph_request_post_id,coverkit_opengraph_template_id. Third-party SEO plugin integration is deferred and should be added only inside this class when implemented (seeinit()docblock).
Template meta: _coverkit_use_cases
Section titled “Template meta: _coverkit_use_cases”Per template, post meta _coverkit_use_cases (Use_Case_Storage::META_KEY) is an object map: use case id → assignment (active, settings, mappings, …). When assignments change, Use_Case_Storage::rebuild_loader_manifest() rebuilds coverkit_active_use_case_classes so the registry can boot each active use case class once per request.
Optional summary meta _coverkit_active_use_cases (Use_Case_Storage::SUMMARY_META_KEY) stores a slug list for editor/debug reads.
tests/php/UseCaseRegistryTest.php— registry registration, boot from manifest,reset()behavior.tests/php/UseCaseSettingsSchemaTest.php— settings schema filters and sanitization paths.tests/php/SidebarImageUseCaseTest.php— sidebar mapping delta and schema.tests/php/OpenGraphImageUseCaseTest.php— Open Graph slug/schema/mapping,coverkit_pre_generateslug guard, and template eligibility (reflection on private helper + stubbed post meta).
Related
Section titled “Related”- php-backend.md — class-level index and field pipeline.
- hooks-and-extension-points.md — mapping, settings, and generation filters.