Skip to content

Commit

Permalink
feat: Added PathResolverInterface::resolvePath $allowNonReachableNode…
Browse files Browse the repository at this point in the history
…s arg to restrict path resolution to reachable node-types
  • Loading branch information
ambroisemaupate committed Sep 15, 2022
1 parent eca47b8 commit d78754d
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 44 deletions.
7 changes: 6 additions & 1 deletion src/Api/Controller/GetWebResponseByPathController.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ protected function normalizeResourcePath(string $path): ?PersistableInterface
* Serve any PersistableInterface Resource by implementing
* your PathResolver and tagging it "roadiz_core.path_resolver"
*/
$resourceInfo = $this->pathResolver->resolvePath($path, ['html', 'json'], true);
$resourceInfo = $this->pathResolver->resolvePath(
$path,
['html', 'json'],
true,
false
);
$resource = $resourceInfo->getResource();

/*
Expand Down
65 changes: 37 additions & 28 deletions src/Repository/NodeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ protected function filterByTag(array &$criteria, QueryBuilder $qb)
* * key => array('>', $value)
* * key => array('BETWEEN', $value, $value)
* * key => array('LIKE', $value)
* * key => array('NOT IN', $array)
* * key => array('NOT IN', $array)
* * key => 'NOT NULL'
*
* You can filter with translations relation, examples:
Expand Down Expand Up @@ -250,8 +250,8 @@ protected function applyTranslationByTag(
*
* @param array $criteria
* @param array|null $orderBy
* @param integer|null $limit
* @param integer|null $offset
* @param int|null $limit
* @param int|null $offset
* @param TranslationInterface|null $translation
* @return array
*/
Expand Down Expand Up @@ -298,8 +298,8 @@ public function findByWithTranslation(
*
* @param array $criteria
* @param array|null $orderBy
* @param integer|null $limit
* @param integer|null $offset
* @param int|null $limit
* @param int|null $offset
* @param TranslationInterface|null $translation
* @return array|Paginator
*/
Expand Down Expand Up @@ -348,8 +348,8 @@ public function findBy(
*
* @param array $criteria
* @param array|null $orderBy
* @param integer|null $limit
* @param integer|null $offset
* @param int|null $limit
* @param int|null $offset
* @param TranslationInterface|null $translation
* @return QueryBuilder
*/
Expand Down Expand Up @@ -410,7 +410,7 @@ protected function getContextualQueryWithTranslation(
public function findOneByWithTranslation(
array $criteria,
TranslationInterface $translation = null
) {
): ?Node {
return $this->findOneBy(
$criteria,
null,
Expand All @@ -430,7 +430,7 @@ public function findOneBy(
array $criteria,
array $orderBy = null,
TranslationInterface $translation = null
) {
): ?Node {
$qb = $this->getContextualQueryWithTranslation(
$criteria,
$orderBy,
Expand Down Expand Up @@ -460,7 +460,7 @@ public function findOneBy(
public function findWithTranslation(
$nodeId,
TranslationInterface $translation
) {
): ?Node {
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', static::NODESSOURCES_ALIAS)
Expand All @@ -484,7 +484,7 @@ public function findWithTranslation(
*/
public function findWithDefaultTranslation(
$nodeId
) {
): ?Node {
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', static::NODESSOURCES_ALIAS)
Expand All @@ -509,12 +509,12 @@ public function findWithDefaultTranslation(
*
* @return null|Node
* @throws NonUniqueResultException
* @deprecated Use findOneByIdentifier
* @deprecated Use findNodeTypeNameAndSourceIdByIdentifier
*/
public function findByNodeNameWithTranslation(
$nodeName,
TranslationInterface $translation
) {
): ?Node {
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', static::NODESSOURCES_ALIAS)
Expand All @@ -533,16 +533,18 @@ public function findByNodeNameWithTranslation(
/**
* Find one node using its nodeName and a translation, or a unique URL alias.
*
* @param string $identifier
* @param string $identifier
* @param TranslationInterface|null $translation
* @param bool $availableTranslation
*
* @param bool $availableTranslation
* @param bool $allowNonReachableNodes
* @return array|null Array with node-type "name" and node-source "id"
* @throws NonUniqueResultException
*/
public function findNodeTypeNameAndSourceIdByIdentifier(
string $identifier,
?TranslationInterface $translation,
bool $availableTranslation = false
bool $availableTranslation = false,
bool $allowNonReachableNodes = true
): ?array {
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('nt.name, ns.id')
Expand All @@ -562,6 +564,11 @@ public function findNodeTypeNameAndSourceIdByIdentifier(
->setMaxResults(1)
->setCacheable(true);

if (!$allowNonReachableNodes) {
$qb->andWhere($qb->expr()->eq('nt.reachable', ':reachable'))
->setParameter('reachable', true);
}

if ($availableTranslation) {
$qb->andWhere($qb->expr()->eq('t.available', ':available'))
->setParameter('available', true);
Expand All @@ -581,11 +588,11 @@ public function findNodeTypeNameAndSourceIdByIdentifier(
*
* @return null|Node
* @throws NonUniqueResultException
* @deprecated Use findOneByIdentifier
* @deprecated Use findNodeTypeNameAndSourceIdByIdentifier
*/
public function findByNodeNameWithDefaultTranslation(
$nodeName
) {
): ?Node {
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', static::NODESSOURCES_ALIAS)
Expand All @@ -607,10 +614,11 @@ public function findByNodeNameWithDefaultTranslation(
*
* @param TranslationInterface|null $translation
* @return null|Node
* @throws NonUniqueResultException
*/
public function findHomeWithTranslation(
TranslationInterface $translation = null
) {
): ?Node {
if (null === $translation) {
return $this->findHomeWithDefaultTranslation();
}
Expand All @@ -634,8 +642,9 @@ public function findHomeWithTranslation(
* Find the Home node with the default translation.
*
* @return null|Node
* @throws NonUniqueResultException
*/
public function findHomeWithDefaultTranslation()
public function findHomeWithDefaultTranslation(): ?Node
{
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns')
Expand All @@ -661,7 +670,7 @@ public function findHomeWithDefaultTranslation()
public function findByParentWithTranslation(
TranslationInterface $translation,
Node $parent = null
) {
): array {
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns, ua')
->innerJoin('n.nodeSources', static::NODESSOURCES_ALIAS)
Expand All @@ -687,7 +696,7 @@ public function findByParentWithTranslation(
* @param Node|null $parent
* @return Node[]
*/
public function findByParentWithDefaultTranslation(Node $parent = null)
public function findByParentWithDefaultTranslation(Node $parent = null): array
{
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns')
Expand Down Expand Up @@ -715,7 +724,7 @@ public function findByParentWithDefaultTranslation(Node $parent = null)
* @return null|Node
* @throws NonUniqueResultException
*/
public function findOneWithAliasAndAvailableTranslation(string $urlAliasAlias)
public function findOneWithAliasAndAvailableTranslation(string $urlAliasAlias): ?Node
{
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns, t, uas')
Expand All @@ -740,7 +749,7 @@ public function findOneWithAliasAndAvailableTranslation(string $urlAliasAlias)
* @return null|Node
* @throws NonUniqueResultException
*/
public function findOneWithAlias($urlAliasAlias)
public function findOneWithAlias($urlAliasAlias): ?Node
{
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select('n, ns, t, uas')
Expand All @@ -763,7 +772,7 @@ public function findOneWithAlias($urlAliasAlias)
* @return bool
* @throws NonUniqueResultException|\Doctrine\ORM\NoResultException
*/
public function exists($nodeName)
public function exists($nodeName): bool
{
$qb = $this->createQueryBuilder(static::NODE_ALIAS);
$qb->select($qb->expr()->countDistinct('n.nodeName'))
Expand Down Expand Up @@ -918,8 +927,8 @@ public function findAllOffspringIdByNode(Node $node)
* @param Node $node
* @param array $criteria
* @param array|null $orderBy
* @param int $limit
* @param int $offset
* @param int|null $limit
* @param int|null $offset
* @param TranslationInterface|null $translation
* @return array|null
*/
Expand Down
5 changes: 3 additions & 2 deletions src/Routing/ChainResourcePathResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ public function addPathResolver(PathResolverInterface $pathResolver): ChainResou
public function resolvePath(
string $path,
array $supportedFormatExtensions = ['html'],
bool $allowRootPaths = false
bool $allowRootPaths = false,
bool $allowNonReachableNodes = true
): ResourceInfo {
if (count($this->pathResolvers) === 0) {
throw new ResourceNotFoundException('No PathResolverInterface was registered to resolve path');
}
foreach ($this->pathResolvers as $pathResolver) {
try {
return $pathResolver->resolvePath($path, $supportedFormatExtensions, $allowRootPaths);
return $pathResolver->resolvePath($path, $supportedFormatExtensions, $allowRootPaths, $allowNonReachableNodes);
} catch (ResourceNotFoundException $exception) {
// Do nothing to allow other resolver to work.
}
Expand Down
5 changes: 4 additions & 1 deletion src/Routing/NodeUrlMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ protected function getNodeRouteHelper(NodesSources $nodeSource, ?Theme $theme):
*/
public function matchNode(string $decodedUrl, ?Theme $theme): array
{
$resourceInfo = $this->pathResolver->resolvePath($decodedUrl, $this->getSupportedFormatExtensions());
$resourceInfo = $this->pathResolver->resolvePath(
$decodedUrl,
$this->getSupportedFormatExtensions()
);
$nodeSource = $resourceInfo->getResource();

if ($nodeSource instanceof NodesSources && !$nodeSource->getNode()->isHome()) {
Expand Down
22 changes: 12 additions & 10 deletions src/Routing/NodesSourcesPathResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,13 @@ public function __construct(
}

/**
* @param string $path
* @param array $supportedFormatExtensions
* @param bool $allowRootPaths Allow resolving / and /en, /fr paths to home pages
* @return ResourceInfo
* @inheritDoc
*/
public function resolvePath(
string $path,
array $supportedFormatExtensions = ['html'],
bool $allowRootPaths = false
bool $allowRootPaths = false,
bool $allowNonReachableNodes = true
): ResourceInfo {
$resourceInfo = new ResourceInfo();
$tokens = $this->tokenizePath($path);
Expand Down Expand Up @@ -105,7 +103,7 @@ public function resolvePath(
* Try with URL Aliases OR nodeName
*/
$this->stopwatch->start('parseFromIdentifier');
$nodeSource = $this->parseFromIdentifier($tokens, $translation);
$nodeSource = $this->parseFromIdentifier($tokens, $translation, $allowNonReachableNodes);
$this->stopwatch->stop('parseFromIdentifier');
}

Expand Down Expand Up @@ -206,11 +204,14 @@ private function parseTranslation(array &$tokens = []): ?TranslationInterface
/**
* @param array<string> $tokens
* @param TranslationInterface|null $translation
*
* @param bool $allowNonReachableNodes
* @return NodesSources|null
*/
private function parseFromIdentifier(array &$tokens, ?TranslationInterface $translation = null): ?NodesSources
{
private function parseFromIdentifier(
array &$tokens,
?TranslationInterface $translation = null,
bool $allowNonReachableNodes = true
): ?NodesSources {
if (!empty($tokens[0])) {
/*
* If the only url token is not for language
Expand All @@ -223,7 +224,8 @@ private function parseFromIdentifier(array &$tokens, ?TranslationInterface $tran
->findNodeTypeNameAndSourceIdByIdentifier(
$identifier,
$translation,
!$this->previewResolver->isPreview()
!$this->previewResolver->isPreview(),
$allowNonReachableNodes
);
if (null !== $array) {
/** @var NodesSources|null $nodeSource */
Expand Down
4 changes: 3 additions & 1 deletion src/Routing/PathResolverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ interface PathResolverInterface
* @param string $path
* @param array<string> $supportedFormatExtensions
* @param bool $allowRootPaths Allow resolving / and /en, /fr paths to home pages
* @param bool $allowNonReachableNodes Allow resolving non-reachable nodes
* @return ResourceInfo
*/
public function resolvePath(
string $path,
array $supportedFormatExtensions = ['html'],
bool $allowRootPaths = false
bool $allowRootPaths = false,
bool $allowNonReachableNodes = true
): ResourceInfo;
}
3 changes: 2 additions & 1 deletion src/Routing/RedirectionPathResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public function __construct(ManagerRegistry $managerRegistry)
public function resolvePath(
string $path,
array $supportedFormatExtensions = ['html'],
bool $allowRootPaths = false
bool $allowRootPaths = false,
bool $allowNonReachableNodes = true
): ResourceInfo {
$redirection = $this->managerRegistry
->getRepository(Redirection::class)
Expand Down

0 comments on commit d78754d

Please sign in to comment.