Implements the site-level request-aware base:
- keep canonical (request-independent) base eager in the Site constructor,
resolved with RequestWrapper(null) so ip() no longer throws
- resolve the request-aware base lazily in getBase() against a request
published by the SiteResolver middleware via CurrentRequestHolder
- site identification (SiteMatcher) uses getCanonicalBase(), so routing
stays request-independent
Per-language variants, backend/CLI holder population and a SiteInterface
compat path are deliberately out of scope; see SIZING.md.
See https://forge.typo3.org/issues/106696
Signed-off-by: Sebastian Mendel <info@sebastianmendel.de>
Note
Sizing sketch only — NOT for merge, and not how TYPO3 Core is contributed (that goes through Gerrit). This exists to make the size of a correct request-time base-variant fix for forge #106696 tangible — the "big" alternative to the naive one-liner (CybotTM/typo3#1) and to the docs PR (TYPO3-Documentation/TYPO3CMS-Reference-CoreApi#6651).
Why the naive fix cannot work (recap)
Base variants are resolved in the request-less
Siteconstructor, reached from theSiteResolvermiddleware before$GLOBALS['TYPO3_REQUEST']is ever assigned (that happens only in the innermostfrontend/Http/RequestHandler::handle()). Soip()silently returnsfalse. A correct fix must make the base request-scoped at read time, which changes the lifecycle ofSiteandSiteLanguage.What this branch implements
The new infrastructure a request-time fix needs:
CurrentRequestHolder(new, ~50 LOC): a process-wide, request-scoped holder, external toSite(which is serialized into the runtime cache, so a live request must never live on it), withwithRequest()save/restore for sub-requests.Services.yaml: registers it (public, shared).SiteResolvermiddleware: populates the holder with the request — which at that point already carriesnormalizedParams/ the client IP — and restores it viatry/finally.These compile but intentionally do nothing on their own: the holder is populated and never read, because the large consuming surgery is not applied (it is the risky part being sized).
What a correct fix additionally needs (NOT in this branch — the sized surgery)
See
SIZING.mdfor the file-by-file breakdown. In short:Site.php(stop eager resolve, lazygetBase(), ~100–150 LOC),SiteLanguage.php(lazy base, ~40–70 LOC),SiteMatchercanonical-base carve-out so identification stays request-independent while presentation becomes request-aware, backendSiteResolver+ adminpanel preview holder population, and real FE-request functional tests (~200–320 LOC).Size bands
≈ 10–15× the naive fix's LOC, main-only, with real BC / site-identity / cache-coherence risk across TypoLink, redirects, hreflang and CSP — for a capability the ecosystem already covers via a custom
ExpressionLanguageProvider(b13/host-variants).Verdict
NO-GO on a core code fix as the primary answer. Ship the docs PR (#6651), delegate request/host-dependent bases to the provider pattern, and only build this out if the maintainers explicitly mandate request-dependent base variants in core.