Architecture¶
Domain Short URL extends the base Short URL module through service decoration. Each decorated service wraps the original and adds domain-aware behavior while delegating non-domain operations to the inner service.
Decorated services¶
DomainAwareShortUrlManager¶
Decorates ShortUrlManager. Overrides:
buildFullUrl()— uses the assigned domain's hostname and path prefix instead of the current request's hostsyncRedirects()— setsdomain_idon all created redirect entities to scope them to the correct domainresolveNodeBySlug()— queries for nodes matching both the slug and the active domain, falling back to a global lookupgetUrlOptions()— injects the domain entity into the options array for outbound path processing
DomainAwareSlugGenerator¶
Decorates SlugGenerator. Adds:
generateAutoIncrementForDomain(string $domain_id)— generates a domain-scoped sequential slug using a per-domain State API counter whencounter_scopeisper_domain
Base36 generation delegates directly to the inner generator since random slugs don't need domain scoping.
DomainAwareVisitMiddleware¶
Replaces the base ShortUrlVisitMiddleware via a service provider
(DomainShorturlServiceProvider). Extends the base middleware to:
- Read the
X-Shorturl-DomainIdresponse header and includedomain_idin the visit record - Strip the header before the response reaches the client
Data flow¶
Visit tracking¶
- A redirect response is generated by the Domain Redirect module.
DomainShortUrlEntityHooks::redirectResponseAlter()stamps theX-Shorturl-DomainIdheader from the redirect'sdomain_idfield.DomainAwareVisitMiddleware::buildVisitFields()reads the header and addsdomain_idto the visit row.- The header is stripped before sending to the client.
Slug generation (auto-increment)¶
- User creates a short URL node with a domain selected.
ShortUrlEntityHooks::nodePresave()runs first and generates a global slug.DomainShortUrlEntityHooks::nodePresave()runs after (viaOrderAfterattribute), detects the domain, and replaces the slug with a domain-scoped counter value.- The node title is set to
{slug} @ {domain_label}.
Hook implementations¶
| Class | Hooks |
|---|---|
DomainShortUrlEntityHooks |
node_presave, redirect_response_alter |
DomainShortUrlFormHooks |
form_node_shorturl_form_alter, form_node_shorturl_edit_form_alter |
DomainShortUrlViewsHooks |
views_data_alter |
Database additions¶
The shorturl_visits table gains a domain_id column
(VARCHAR 255, indexed) added during module installation and
removed on uninstall.