configuration = $configuration; } /** * {@inheritdoc} */ public function buildResult(Route $route, array $results, array $remainingQueryParameters = []): PageArguments { // determine those parameters that have been processed $parameters = array_intersect_key( $results, array_flip($route->compile()->getPathVariables()) ); // strip of those that where not processed (internals like _route, etc.) $internals = array_diff_key($results, $parameters); $matchedVariableNames = array_keys($parameters); $staticMappers = $route->filterAspects([StaticMappableAspectInterface::class], $matchedVariableNames); $dynamicCandidates = array_diff_key($parameters, $staticMappers, $route->getOption('_static') ?? []); // all route arguments $routeArguments = $this->inflateParameters($parameters, $internals); // dynamic arguments, that don't have a static mapper $dynamicArguments = $this->inflateParameters($dynamicCandidates); // route arguments, that don't appear in dynamic arguments $staticArguments = ArrayUtility::arrayDiffKeyRecursive($routeArguments, $dynamicArguments); $page = $route->getOption('_page'); $pageId = (int)(isset($page['t3ver_oid']) && $page['t3ver_oid'] > 0 ? $page['t3ver_oid'] : $page['uid']); $pageId = (int)($page['l10n_parent'] > 0 ? $page['l10n_parent'] : $pageId); // See PageSlugCandidateProvider where this is added. if ($page['MPvar'] ?? '') { $routeArguments['MP'] = $page['MPvar']; } $type = $this->resolveType($route, $remainingQueryParameters); return new PageArguments($pageId, $type, $routeArguments, $staticArguments, $remainingQueryParameters); } /** * {@inheritdoc} */ public function enhanceForMatching(RouteCollection $collection): void { /** @var Route $defaultPageRoute */ $defaultPageRoute = $collection->get('default'); $variant = $this->getVariant($defaultPageRoute, $this->configuration); $collection->add('enhancer_' . spl_object_hash($variant), $variant); } /** * Builds a variant of a route based on the given configuration. */ protected function getVariant(Route $defaultPageRoute, array $configuration): Route { $arguments = $configuration['_arguments'] ?? []; unset($configuration['_arguments']); $variableProcessor = $this->getVariableProcessor(); $routePath = $this->modifyRoutePath($configuration['routePath']); $routePath = $variableProcessor->deflateRoutePath($routePath, null, $arguments); $variant = clone $defaultPageRoute; $variant->setPath(rtrim($variant->getPath(), '/') . '/' . ltrim($routePath, '/')); $variant->addOptions(['_enhancer' => $this, '_arguments' => $arguments]); $defaults = $variableProcessor->deflateKeys($this->configuration['defaults'] ?? [], null, $arguments); // only keep `defaults` that are actually used in `routePath` $variant->setDefaults($this->filterValuesByPathVariables($variant, $defaults)); $this->applyRouteAspects($variant, $this->aspects); $this->applyRequirements($variant, $this->configuration['requirements'] ?? []); $this->applyStaticVariables($variant, $this->configuration['static'] ?? []); return $variant; } /** * {@inheritdoc} */ public function enhanceForGeneration(RouteCollection $collection, array $parameters): void { /** @var Route $defaultPageRoute */ $defaultPageRoute = $collection->get('default'); $variant = $this->getVariant($defaultPageRoute, $this->configuration); $compiledRoute = $variant->compile(); // contains all given parameters, even if not used as variables in route $deflatedParameters = $this->getVariableProcessor()->deflateParameters($parameters, $variant->getArguments()); $variables = array_flip($compiledRoute->getPathVariables()); $mergedParams = array_replace($variant->getDefaults(), $deflatedParameters); // all params must be given, otherwise we exclude this variant if ($variables === [] || array_diff_key($variables, $mergedParams) !== []) { return; } $variant->addOptions(['deflatedParameters' => $deflatedParameters]); $collection->add('enhancer_' . spl_object_hash($variant), $variant); } public function inflateParameters(array $parameters, array $internals = []): array { return $this->getVariableProcessor()->inflateParameters($parameters, $internals); } }