*/ protected array $arguments; /** * Route arguments mapped by static mappers * "static" means the provided values in a URI maps to a finite number of values * (routeArguments - "arguments mapped by non static mapper") * * @var array */ protected array $staticArguments; /** * Route arguments, that have an infinite number of possible values * AND query string arguments. These arguments require a cHash. * * @var array */ protected array $dynamicArguments; /** * Arguments defined in and mapped by a route enhancer * * @var array */ protected array $routeArguments; /** * Query arguments in the generated URI * * @var array */ protected array $queryArguments = []; public function __construct(int $pageId, string $pageType, array $routeArguments, array $staticArguments = [], array $remainingArguments = []) { $this->pageId = $pageId; $this->pageType = $pageType; $this->routeArguments = $this->sort($routeArguments); $this->staticArguments = $this->sort($staticArguments); $this->arguments = $this->routeArguments; $this->updateDynamicArguments(); if (!empty($remainingArguments)) { $this->updateQueryArguments($remainingArguments); } } public function areDirty(): bool { return $this->dirty; } /** * @return array */ public function getRouteArguments(): array { return $this->routeArguments; } public function getPageId(): int { return $this->pageId; } public function getPageType(): string { return $this->pageType; } /** * @return string|array|null */ public function get(string $name): mixed { return $this->arguments[$name] ?? null; } /** * @return array */ public function getArguments(): array { return $this->arguments; } /** * @return array */ public function getStaticArguments(): array { return $this->staticArguments; } /** * @return array */ public function getDynamicArguments(): array { return $this->dynamicArguments; } /** * @return array */ public function getQueryArguments(): array { return $this->queryArguments; } /** * @param array $queryArguments */ protected function updateQueryArguments(array $queryArguments) { $queryArguments = $this->sort($queryArguments); if ($this->queryArguments === $queryArguments) { return; } // in case query arguments would override route arguments, // the state is considered as dirty (since it's not distinct) // thus, route arguments take precedence over query arguments $additionalQueryArguments = $this->diff($queryArguments, $this->routeArguments); $dirty = $additionalQueryArguments !== $queryArguments; $this->dirty = $this->dirty || $dirty; $this->queryArguments = $queryArguments; $this->arguments = array_replace_recursive($this->arguments, $additionalQueryArguments); $this->updateDynamicArguments(); } /** * Updates dynamic arguments based on definitions for static arguments. */ protected function updateDynamicArguments(): void { $this->dynamicArguments = $this->diff( $this->arguments, $this->staticArguments ); } /** * Cleans empty array recursively. * * @param array $array */ protected function clean(array $array): array { foreach ($array as $key => &$item) { if (!is_array($item)) { continue; } if (!empty($item)) { $item = $this->clean($item); } if (empty($item)) { unset($array[$key]); } } return $array; } /** * Sorts array keys recursively. * * @param array $array */ protected function sort(array $array): array { $array = $this->clean($array); ArrayUtility::naturalKeySortRecursive($array); return $array; } /** * Removes keys that are defined in $second from $first recursively. * * @param array $first * @param array $second */ protected function diff(array $first, array $second): array { return ArrayUtility::arrayDiffKeyRecursive($first, $second); } public function offsetExists(mixed $offset): bool { return $offset === 'pageId' || $offset === 'pageType' || isset($this->arguments[$offset]); } /** * @return int|string|array|null */ public function offsetGet(mixed $offset): mixed { if ($offset === 'pageId') { return $this->getPageId(); } if ($offset === 'pageType') { return $this->getPageType(); } return $this->arguments[$offset] ?? null; } public function offsetSet(mixed $offset, mixed $value): void { throw new \InvalidArgumentException('PageArguments cannot be modified.', 1538152266); } public function offsetUnset(mixed $offset): void { throw new \InvalidArgumentException('PageArguments cannot be modified.', 1538152269); } }