Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Overhaul Routing #2693

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions Neos.Flow/Classes/Mvc/Routing/Dto/UriConstraints.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,22 +284,6 @@ public function withPathSuffix(string $pathSuffix, bool $prepend = false): self
return new static($newConstraints);
}

/**
* Returns the URI path constraint, which consists of the path and query string parts, or NULL if none was set
*
* @return string|null
* @deprecated With Flow 7.0, use toUri()->getPath() and/or toUri()->getQuery() instead. @see toUri()
*/
public function getPathConstraint(): ?string
{
$pathPart = $this->constraints[self::CONSTRAINT_PATH] ?? null;
$queryPart = $this->constraints[self::CONSTRAINT_QUERY_STRING] ?? null;
if ($pathPart === null && $queryPart === null) {
return null;
}
return $pathPart . ($queryPart ? '?' . $queryPart : '');
}

/**
* Applies all constraints of this instance to the given $templateUri and returns a new UriInterface instance
* satisfying all of the constraints (see example above)
Expand Down
119 changes: 33 additions & 86 deletions Neos.Flow/Classes/Mvc/Routing/RouterCachingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* source code.
*/

use Neos\Cache\Exception as CacheException;
use Neos\Flow\Annotations as Flow;
use Neos\Cache\CacheAwareInterface;
use Neos\Cache\Frontend\VariableFrontend;
Expand All @@ -22,7 +23,6 @@
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Utility\Arrays;
use Neos\Flow\Validation\Validator\UuidValidator;
use Psr\Log\LoggerInterface;

/**
Expand All @@ -33,26 +33,26 @@
class RouterCachingService
{
/**
* @var VariableFrontend
* @Flow\Inject
* @var VariableFrontend
*/
protected $routeCache;

/**
* @var VariableFrontend
* @Flow\Inject
* @var VariableFrontend
*/
protected $resolveCache;

/**
* @var PersistenceManagerInterface
* @Flow\Inject
* @var PersistenceManagerInterface
*/
protected $persistenceManager;

/**
* @var LoggerInterface
* @Flow\Inject(name="Neos.Flow:SystemLogger")
* @var LoggerInterface
*/
protected $logger;

Expand All @@ -69,17 +69,9 @@ class RouterCachingService
protected $routingSettings;

/**
* @param LoggerInterface $logger
*/
public function injectLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}

/**
* @return void
* @throws CacheException
*/
public function initializeObject()
public function initializeObject(): void
{
// flush routing caches if in Development context & routing settings changed
if ($this->objectManager->getContext()->isDevelopment() && $this->routeCache->get('routingSettings') !== $this->routingSettings) {
Expand All @@ -91,7 +83,6 @@ public function initializeObject()
/**
* Checks the cache for the given RouteContext and returns the result or false if no matching ache entry was found
*
* @param RouteContext $routeContext
* @return array|boolean the cached route values or false if no cache entry was found
*/
public function getCachedMatchResults(RouteContext $routeContext)
Expand All @@ -107,18 +98,14 @@ public function getCachedMatchResults(RouteContext $routeContext)
/**
* Stores the $matchResults in the cache
*
* @param RouteContext $routeContext
* @param array $matchResults
* @param RouteTags|null $matchedTags
* @return void
* @throws CacheException
*/
public function storeMatchResults(RouteContext $routeContext, array $matchResults, RouteTags $matchedTags = null)
public function storeMatchResults(RouteContext $routeContext, array $matchResults, RouteTags $matchedTags = null): void
{
if ($this->containsObject($matchResults)) {
return;
}

$tags = $this->generateRouteTags(RequestInformationHelper::getRelativeRequestPath($routeContext->getHttpRequest()), $matchResults);
$tags = $this->generateRouteTagsFromUriPath(RequestInformationHelper::getRelativeRequestPath($routeContext->getHttpRequest()));
if ($matchedTags !== null) {
$tags = array_unique(array_merge($matchedTags->getTags(), $tags));
}
Expand All @@ -128,8 +115,7 @@ public function storeMatchResults(RouteContext $routeContext, array $matchResult
/**
* Checks the cache for the given ResolveContext and returns the cached UriConstraints if a cache entry is found
*
* @param ResolveContext $resolveContext
* @return UriConstraints|boolean the cached URI or false if no cache entry was found
* @return UriConstraints|bool the cached URI or false if no cache entry was found
*/
public function getCachedResolvedUriConstraints(ResolveContext $resolveContext)
{
Expand All @@ -142,77 +128,65 @@ public function getCachedResolvedUriConstraints(ResolveContext $resolveContext)

/**
* Stores the resolved UriConstraints in the cache together with the $routeValues
*
* @param ResolveContext $resolveContext
* @param UriConstraints $uriConstraints
* @param RouteTags|null $resolvedTags
* @return void
* @throws CacheException
*/
public function storeResolvedUriConstraints(ResolveContext $resolveContext, UriConstraints $uriConstraints, RouteTags $resolvedTags = null)
public function storeResolvedUriConstraints(ResolveContext $resolveContext, UriConstraints $uriConstraints, RouteTags $resolvedTags = null): void
{
$routeValues = $this->convertObjectsToHashes($resolveContext->getRouteValues());
if ($routeValues === null) {
return;
}

$cacheIdentifier = $this->buildResolveCacheIdentifier($resolveContext, $routeValues);
$tags = $this->generateRouteTags((string)$uriConstraints->toUri(), $routeValues);
$tags = $this->generateRouteTagsFromUriPath((string)$uriConstraints->toUri());
if ($resolvedTags !== null) {
$tags = array_unique(array_merge($resolvedTags->getTags(), $tags));
}
$this->resolveCache->set($cacheIdentifier, $uriConstraints, $tags);
}

/**
* @param string $uriPath
* @param array $routeValues
* @return array
*/
protected function generateRouteTags($uriPath, $routeValues)
private function generateRouteTagsFromUriPath(string $uriPath): array
{
$uriPath = trim($uriPath, '/');
$tags = $this->extractUuids($routeValues);
$tags = [];
$path = '';
$uriPath = explode('/', $uriPath);
foreach ($uriPath as $uriPathSegment) {
foreach (explode('/', trim($uriPath, '/')) as $uriPathSegment) {
$path .= '/' . $uriPathSegment;
$path = trim($path, '/');
$tags[] = md5($path);
}

return $tags;
}

/**
* @deprecated with Flow 8.0 - This method is no longer used! It is just kept in order to keep AOP aspects from failing
*/
protected function generateRouteTags($uriPath, $routeValues)
{
return [];
}

/**
* Flushes 'route' and 'resolve' caches.
*
* @return void
*/
public function flushCaches()
public function flushCaches(): void
{
$this->routeCache->flush();
$this->resolveCache->flush();
}

/**
* Flushes 'findMatchResults' and 'resolve' caches for the given $tag
*
* @param string $tag
* @return void
*/
public function flushCachesByTag($tag)
public function flushCachesByTag(string $tag): void
{
$this->routeCache->flushByTag($tag);
$this->resolveCache->flushByTag($tag);
}

/**
* Flushes 'findMatchResults' caches that are tagged with the given $uriPath
*
* @param string $uriPath
* @return void
*/
public function flushCachesForUriPath($uriPath)
public function flushCachesForUriPath(string $uriPath): void
{
$uriPathTag = md5(trim($uriPath, '/'));
$this->flushCachesByTag($uriPathTag);
Expand All @@ -221,10 +195,9 @@ public function flushCachesForUriPath($uriPath)
/**
* Checks if the given subject contains an object
*
* @param mixed $subject
* @return boolean true if $subject contains an object, otherwise false
* @return bool true if $subject contains an object, otherwise false
*/
protected function containsObject($subject)
private function containsObject($subject): bool
{
if (is_object($subject)) {
return true;
Expand All @@ -244,9 +217,9 @@ protected function containsObject($subject)
* Recursively converts objects in an array to their identifiers
*
* @param array $routeValues the array to be processed
* @return array the modified array or NULL if $routeValues contain an object and its identifier could not be determined
* @return array|null the modified array or NULL if $routeValues contain an object and its identifier could not be determined
*/
protected function convertObjectsToHashes(array $routeValues)
private function convertObjectsToHashes(array $routeValues): ?array
{
foreach ($routeValues as &$value) {
if (is_object($value)) {
Expand All @@ -271,37 +244,11 @@ protected function convertObjectsToHashes(array $routeValues)

/**
* Generates the Resolve cache identifier for the given Request
*
* @param ResolveContext $resolveContext
* @param array $routeValues
* @return string
*/
protected function buildResolveCacheIdentifier(ResolveContext $resolveContext, array $routeValues)
private function buildResolveCacheIdentifier(ResolveContext $resolveContext, array $routeValues): string
{
Arrays::sortKeysRecursively($routeValues);

return md5(sprintf('abs:%s|prefix:%s|routeValues:%s', $resolveContext->isForceAbsoluteUri() ? 1 : 0, $resolveContext->getUriPathPrefix(), trim(http_build_query($routeValues), '/')));
}

/**
* Helper method to generate tags by taking all UUIDs contained
* in the given $routeValues or $matchResults
*
* @param array $values
* @return array
*/
protected function extractUuids(array $values)
{
$uuids = [];
foreach ($values as $value) {
if (is_string($value)) {
if (preg_match(UuidValidator::PATTERN_MATCH_UUID, $value) !== 0) {
$uuids[] = $value;
}
} elseif (is_array($value)) {
$uuids = array_merge($uuids, $this->extractUuids($value));
}
}
return $uuids;
}
}
6 changes: 3 additions & 3 deletions Neos.Flow/Tests/Unit/Mvc/Routing/RouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -919,8 +919,8 @@ public function resolvesAppendsDefaultValuesOfOptionalUriPartsToResolvedUriPathC
$this->routeValues = ['baz' => 'bazValue'];

$this->resolveRouteValues($this->routeValues);
$expectedResult = 'foo/barDefaultValue/bazvalue';
$actualResult = $this->route->getResolvedUriConstraints()->getPathConstraint();
$expectedResult = '/foo/barDefaultValue/bazvalue';
$actualResult = $this->route->getResolvedUriConstraints()->toUri()->getPath();
self::assertSame($expectedResult, $actualResult);
}

Expand Down Expand Up @@ -973,7 +973,7 @@ public function resolvedUriConstraintsIsEmptyAfterUnsuccessfulResolve()

$this->routeValues = ['differentKey' => 'value1'];
self::assertFalse($this->resolveRouteValues($this->routeValues));
self::assertNull($this->route->getResolvedUriConstraints()->getPathConstraint());
self::assertSame('/', $this->route->getResolvedUriConstraints()->toUri()->getPath());
}

/**
Expand Down
Loading
Loading