request = $request; } /** * Disable redirect-to-base when tunnel param is present so RequestPreprocessor skips the block. * * @param BaseUrlChecker $subject * @return array|null [false] to disable, null to proceed */ public function beforeIsEnabled(BaseUrlChecker $subject): ?array { if ($this->request instanceof Http && $this->hasTunnelStore($this->request)) { return [false]; } return null; } /** * If tunnel store indicator is present, treat URL as valid (skip redirect). * * @param BaseUrlChecker $subject * @param callable $proceed * @param array $uri * @param Http $request * @return bool */ public function aroundExecute(BaseUrlChecker $subject, callable $proceed, $uri, $request): bool { if ($request instanceof Http && $this->hasTunnelStore($request)) { return true; } return $proceed($uri, $request); } private function hasTunnelStore(Http $request): bool { $value = $request->getParam(self::QUERY_PARAM_STORE); if ($value !== null && $value !== '' && trim((string) $value) !== '') { return true; } if (method_exists($request, 'getQueryValue')) { $value = $request->getQueryValue(self::QUERY_PARAM_STORE); if ($value !== null && $value !== '' && trim((string) $value) !== '') { return true; } } $uri = $request->getRequestUri(); if ($uri !== null && str_contains((string) $uri, self::QUERY_PARAM_STORE . '=')) { return true; } $value = $request->getServer(self::SERVER_HEADER); if ($value !== null && $value !== '' && trim((string) $value) !== '') { return true; } // Fallback: superglobals (e.g. if request was built before query string was available) return $this->hasTunnelStoreFromSuperglobals(); } private function hasTunnelStoreFromSuperglobals(): bool { if (!empty($_GET[self::QUERY_PARAM_STORE]) && trim((string) $_GET[self::QUERY_PARAM_STORE]) !== '') { return true; } $uri = $_SERVER['REQUEST_URI'] ?? ''; if ($uri !== '' && str_contains($uri, self::QUERY_PARAM_STORE . '=')) { return true; } $h = $_SERVER[self::SERVER_HEADER] ?? ''; return $h !== '' && trim((string) $h) !== ''; } }