Skip to content

Commit

Permalink
feat: Optimize dynamic nodes-sources path resolver (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
ambroisemaupate authored Jan 28, 2025
1 parent 94573ef commit 0020b0b
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 267 deletions.
126 changes: 0 additions & 126 deletions lib/RoadizCoreBundle/src/Repository/NodeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\Expr;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
Expand Down Expand Up @@ -617,131 +616,6 @@ public function findByNodeNameWithTranslation(
return $qb->getQuery()->getOneOrNullResult();
}

/**
* Find one node using its nodeName and a translation, or a unique URL alias.
*
* @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 $allowNonReachableNodes = true,
): ?array {
$qb = $this->createQueryBuilder(self::NODE_ALIAS);
$qb->select('nt.name, ns.id')
->innerJoin('n.nodeSources', self::NODESSOURCES_ALIAS)
->innerJoin('n.nodeType', self::NODETYPE_ALIAS)
->innerJoin('ns.translation', self::TRANSLATION_ALIAS)
->leftJoin('ns.urlAliases', 'uas')
->andWhere($qb->expr()->orX(
$qb->expr()->eq('uas.alias', ':identifier'),
$qb->expr()->andX(
$qb->expr()->eq('n.nodeName', ':identifier'),
$qb->expr()->eq('t.id', ':translation')
)
))
->setParameter('identifier', $identifier)
->setParameter('translation', $translation)
->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);
}

$this->alterQueryBuilderWithAuthorizationChecker($qb);
$query = $qb->getQuery();
$query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
$query->setHydrationMode(Query::HYDRATE_ARRAY);

return $query->getOneOrNullResult();
}

/**
* Find one Node with its nodeName and the default translation.
*
* @throws NonUniqueResultException
*
* @deprecated Use findNodeTypeNameAndSourceIdByIdentifier
*/
public function findByNodeNameWithDefaultTranslation(
string $nodeName,
): ?Node {
$qb = $this->createQueryBuilder(self::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', self::NODESSOURCES_ALIAS)
->innerJoin('ns.translation', self::TRANSLATION_ALIAS)
->andWhere($qb->expr()->eq('n.nodeName', ':nodeName'))
->andWhere($qb->expr()->eq('t.defaultTranslation', ':defaultTranslation'))
->setMaxResults(1)
->setParameter('nodeName', $nodeName)
->setParameter('defaultTranslation', true)
->setCacheable(true);

$this->alterQueryBuilderWithAuthorizationChecker($qb);

return $qb->getQuery()->getOneOrNullResult();
}

/**
* Find the Home node with a given translation.
*
* @throws NonUniqueResultException
*/
public function findHomeWithTranslation(
?TranslationInterface $translation = null,
): ?Node {
if (null === $translation) {
return $this->findHomeWithDefaultTranslation();
}

$qb = $this->createQueryBuilder(self::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', self::NODESSOURCES_ALIAS)
->andWhere($qb->expr()->eq('n.home', ':home'))
->andWhere($qb->expr()->eq('ns.translation', ':translation'))
->setMaxResults(1)
->setParameter('home', true)
->setParameter('translation', $translation)
->setCacheable(true);

$this->alterQueryBuilderWithAuthorizationChecker($qb);

return $qb->getQuery()->getOneOrNullResult();
}

/**
* Find the Home node with the default translation.
*
* @throws NonUniqueResultException
*/
public function findHomeWithDefaultTranslation(): ?Node
{
$qb = $this->createQueryBuilder(self::NODE_ALIAS);
$qb->select('n, ns')
->innerJoin('n.nodeSources', self::NODESSOURCES_ALIAS)
->innerJoin('ns.translation', self::TRANSLATION_ALIAS)
->andWhere($qb->expr()->eq('n.home', ':home'))
->andWhere($qb->expr()->eq('t.defaultTranslation', ':defaultTranslation'))
->setMaxResults(1)
->setParameter('home', true)
->setParameter('defaultTranslation', true)
->setCacheable(true);

$this->alterQueryBuilderWithAuthorizationChecker($qb);

return $qb->getQuery()->getOneOrNullResult();
}

public function findByParentWithTranslation(
TranslationInterface $translation,
?Node $parent = null,
Expand Down
69 changes: 37 additions & 32 deletions lib/RoadizCoreBundle/src/Repository/NodesSourcesRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Persistence\ManagerRegistry;
use RZ\Roadiz\Contracts\NodeType\NodeTypeFieldInterface;
use RZ\Roadiz\Core\AbstractEntities\TranslationInterface;
use RZ\Roadiz\CoreBundle\Doctrine\Event\QueryBuilder\QueryBuilderNodesSourcesApplyEvent;
use RZ\Roadiz\CoreBundle\Doctrine\Event\QueryBuilder\QueryBuilderNodesSourcesBuildEvent;
Expand Down Expand Up @@ -179,6 +178,40 @@ protected function applyFilterByCriteria(array &$criteria, QueryBuilder $qb): vo
}
}

public function findOneByIdentifierAndTranslation(
string $identifier,
?TranslationInterface $translation,
bool $availableTranslation = false,
): ?NodesSources {
$qb = $this->createQueryBuilder(self::NODESSOURCES_ALIAS);
$qb->select([self::NODESSOURCES_ALIAS, static::NODE_ALIAS, 'ua'])
->innerJoin(self::NODESSOURCES_ALIAS.'.node', self::NODE_ALIAS)
->innerJoin(self::NODESSOURCES_ALIAS.'.translation', self::TRANSLATION_ALIAS)
->leftJoin(self::NODESSOURCES_ALIAS.'.urlAliases', 'ua')
->andWhere($qb->expr()->orX(
$qb->expr()->eq('ua.alias', ':identifier'),
$qb->expr()->andX(
$qb->expr()->eq(self::NODE_ALIAS.'.nodeName', ':identifier'),
$qb->expr()->eq(self::TRANSLATION_ALIAS.'.id', ':translation')
)
))
->setParameter('identifier', $identifier)
->setParameter('translation', $translation)
->setMaxResults(1)
->setCacheable(true);

if ($availableTranslation) {
$qb->andWhere($qb->expr()->eq(self::TRANSLATION_ALIAS.'.available', ':available'))
->setParameter('available', true);
}

$this->alterQueryBuilderWithAuthorizationChecker($qb);
$query = $qb->getQuery();
$query->setCacheable(true);

return $query->getOneOrNullResult();
}

public function alterQueryBuilderWithAuthorizationChecker(
QueryBuilder $qb,
string $prefix = EntityRepository::NODESSOURCES_ALIAS,
Expand Down Expand Up @@ -476,8 +509,7 @@ public function findByTextQuery(
array $additionalCriteria = [],
) {
$qb = $this->createQueryBuilder(static::NODESSOURCES_ALIAS);
$qb->addSelect(static::NODE_ALIAS)
->addSelect('ua')
$qb->select([static::NODESSOURCES_ALIAS, static::NODE_ALIAS, 'ua'])
->leftJoin(static::NODESSOURCES_ALIAS.'.urlAliases', 'ua')
->andWhere($qb->expr()->orX(
$qb->expr()->like(static::NODESSOURCES_ALIAS.'.title', ':query'),
Expand Down Expand Up @@ -651,39 +683,12 @@ public function searchBy(
return parent::searchBy($pattern, $criteria, $orders, $limit, $offset, static::NODESSOURCES_ALIAS);
}

/**
* @deprecated Use findByNodesSourcesAndFieldNameAndTranslation instead
*/
public function findByNodesSourcesAndFieldAndTranslation(
NodesSources $nodesSources,
NodeTypeFieldInterface $field,
): ?array {
$qb = $this->createQueryBuilder(static::NODESSOURCES_ALIAS);
$qb->select('ns, n, ua')
->innerJoin('ns.node', static::NODE_ALIAS)
->leftJoin('ns.urlAliases', 'ua')
->innerJoin('n.aNodes', 'ntn')
->andWhere($qb->expr()->eq('ntn.fieldName', ':fieldName'))
->andWhere($qb->expr()->eq('ntn.nodeA', ':nodeA'))
->andWhere($qb->expr()->eq('ns.translation', ':translation'))
->addOrderBy('ntn.position', 'ASC')
->setCacheable(true);

$this->alterQueryBuilderWithAuthorizationChecker($qb);

$qb->setParameter('fieldName', $field->getName())
->setParameter('nodeA', $nodesSources->getNode())
->setParameter('translation', $nodesSources->getTranslation());

return $qb->getQuery()->getResult();
}

public function findByNodesSourcesAndFieldNameAndTranslation(
NodesSources $nodesSources,
string $fieldName,
): ?array {
$qb = $this->createQueryBuilder(static::NODESSOURCES_ALIAS);
$qb->select('ns, n, ua')
$qb->select([static::NODESSOURCES_ALIAS, static::NODE_ALIAS, 'ua'])
->innerJoin('ns.node', static::NODE_ALIAS)
->leftJoin('ns.urlAliases', 'ua')
->innerJoin('n.aNodes', 'ntn')
Expand All @@ -705,7 +710,7 @@ public function findByNodesSourcesAndFieldNameAndTranslation(
public function findByNode(Node $node): array
{
$qb = $this->createQueryBuilder(static::NODESSOURCES_ALIAS);
$qb->select('ns, n, ua')
$qb->select([static::NODESSOURCES_ALIAS, static::NODE_ALIAS, 'ua'])
->innerJoin('ns.node', static::NODE_ALIAS)
->innerJoin('ns.translation', static::TRANSLATION_ALIAS)
->leftJoin('ns.urlAliases', 'ua')
Expand Down
Loading

0 comments on commit 0020b0b

Please sign in to comment.