Skip to content

Commit

Permalink
Merge branch 'hotfix/v2.1.18'
Browse files Browse the repository at this point in the history
  • Loading branch information
ambroisemaupate committed Jun 23, 2023
2 parents 0bfc469 + 5156b7e commit 22ed7f5
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 110 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## [v2.1.18](https://github.com/roadiz/core-bundle-dev-app/compare/v2.1.17...v2.1.18) (2023-06-23)


### Bug Fixes

* Fixed and refactored SQL search query building on Repository and Paginator levels ([b5d320b](https://github.com/roadiz/core-bundle-dev-app/commit/b5d320b49f28ff167e6a4482090fc743bd46c186))

## [v2.1.17](https://github.com/roadiz/core-bundle-dev-app/compare/v2.1.16...v2.1.17) (2023-06-20)


Expand Down
2 changes: 1 addition & 1 deletion lib/RoadizCoreBundle/config/services.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
parameters:
roadiz_core.cms_version: '2.1.17'
roadiz_core.cms_version: '2.1.18'
roadiz_core.cms_version_prefix: 'main'
env(APP_NAMESPACE): "roadiz"
env(APP_VERSION): "0.1.0"
Expand Down
10 changes: 0 additions & 10 deletions lib/RoadizCoreBundle/src/DataCollector/RequestDataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,6 @@ public static function getTemplate(): ?string
return '@RoadizCore/DataCollector/request.html.twig';
}

public function getMethod()
{
return $this->data['method'];
}

public function getAcceptableContentTypes()
{
return $this->data['acceptable_content_types'];
}

/**
* {@inheritdoc}
*/
Expand Down
47 changes: 26 additions & 21 deletions lib/RoadizCoreBundle/src/ListManager/Paginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace RZ\Roadiz\CoreBundle\ListManager;

use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\QueryBuilder;
Expand Down Expand Up @@ -96,19 +97,19 @@ public function setDisplayingAllNodesStatuses(bool $displayAllNodesStatuses)
}

/**
* @return string
* @return string|null
*/
public function getSearchPattern()
public function getSearchPattern(): ?string
{
return $this->searchPattern;
}

/**
* @param string $searchPattern
* @param string|null $searchPattern
*
* @return $this
*/
public function setSearchPattern($searchPattern)
public function setSearchPattern(?string $searchPattern)
{
$this->searchPattern = $searchPattern;

Expand All @@ -135,8 +136,9 @@ public function getTotalCount(): int
/*
* Use QueryBuilder for non-roadiz entities
*/
$qb = $this->getSearchQueryBuilder();
$qb->select($qb->expr()->countDistinct('o'));
$alias = 'o';
$qb = $this->getSearchQueryBuilder($alias);
$qb->select($qb->expr()->countDistinct($alias));
try {
return (int)$qb->getQuery()->getSingleScalarResult();
} catch (NoResultException | NonUniqueResultException $e) {
Expand All @@ -163,7 +165,7 @@ public function getPageCount(): int
/**
* Return entities filtered for current page.
*
* @param array $order
* @param array $order
* @param int $page
*
* @return array|\Doctrine\ORM\Tools\Pagination\Paginator
Expand All @@ -186,10 +188,10 @@ public function findByAtPage(array $order = [], int $page = 1)
/**
* Use a search query to paginate instead of a findBy.
*
* @param array $order
* @param array $order
* @param int $page
*
* @return array
* @return array|\Doctrine\ORM\Tools\Pagination\Paginator
*/
public function searchByAtPage(array $order = [], int $page = 1)
{
Expand All @@ -207,12 +209,13 @@ public function searchByAtPage(array $order = [], int $page = 1)
/*
* Use QueryBuilder for non-roadiz entities
*/
$qb = $this->getSearchQueryBuilder();
$alias = 'o';
$qb = $this->getSearchQueryBuilder($alias);
$qb->setMaxResults($this->getItemsPerPage())
->setFirstResult($this->getItemsPerPage() * ($page - 1));

foreach ($order as $key => $value) {
$qb->addOrderBy('o.' . $key, $value);
$qb->addOrderBy($alias . '.' . $key, $value);
}

return $qb->getQuery()->getResult();
Expand All @@ -223,7 +226,7 @@ public function searchByAtPage(array $order = [], int $page = 1)
*
* @return $this
*/
public function setItemsPerPage(int $itemsPerPage)
public function setItemsPerPage(int $itemsPerPage): self
{
$this->itemsPerPage = $itemsPerPage;

Expand All @@ -237,29 +240,31 @@ public function getItemsPerPage(): int
return $this->itemsPerPage;
}

protected function getSearchQueryBuilder(): QueryBuilder
protected function getSearchQueryBuilder(string $alias): QueryBuilder
{
$searchableFields = $this->getSearchableFields();
if (count($searchableFields) === 0) {
throw new \RuntimeException('Entity has no searchable field.');
}
$qb = $this->getRepository()->createQueryBuilder('o');
$qb = $this->getRepository()->createQueryBuilder($alias);
$orX = [];
foreach ($this->getSearchableFields() as $field) {
$orX[] = $qb->expr()->like('o.' . $field, $qb->expr()->literal('%' . $this->searchPattern . '%'));
$orX[] = $qb->expr()->like(
'LOWER(' . $alias . '.' . $field . ')',
$qb->expr()->literal('%' . mb_strtolower($this->searchPattern) . '%')
);
}
$qb->andWhere($qb->expr()->orX(...$orX));
return $qb;
}

protected function getSearchableFields(): array
{
return array_filter(
['name', 'title', 'slug'],
function (string $fieldName) {
return $this->em->getClassMetadata($this->entityName)->hasField($fieldName);
}
);
$metadata = $this->em->getClassMetadata($this->entityName);
if (!($metadata instanceof ClassMetadataInfo)) {
throw new \RuntimeException('Entity has no metadata.');
}
return EntityRepository::getSearchableColumnsNames($metadata);
}

/**
Expand Down
12 changes: 4 additions & 8 deletions lib/RoadizCoreBundle/src/Repository/DocumentRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,11 @@ protected function createSearchBy(
*/
$qb->leftJoin($alias . '.documentTranslations', 'dt');
$criteriaFields = [];
$metadata = $this->_em->getClassMetadata(DocumentTranslation::class);
$cols = $metadata->getColumnNames();
foreach ($cols as $col) {
$field = $metadata->getFieldName($col);
$type = $metadata->getTypeOfField($field);
if (in_array($type, $this->searchableTypes)) {
$criteriaFields[$field] = '%' . strip_tags((string) $pattern) . '%';
}

foreach (self::getSearchableColumnsNames($this->_em->getClassMetadata(DocumentTranslation::class)) as $field) {
$criteriaFields[$field] = '%' . strip_tags(mb_strtolower($pattern)) . '%';
}

foreach ($criteriaFields as $key => $value) {
$fullKey = sprintf('LOWER(%s)', 'dt.' . $key);
$qb->orWhere($qb->expr()->like($fullKey, $qb->expr()->literal($value)));
Expand Down
67 changes: 40 additions & 27 deletions lib/RoadizCoreBundle/src/Repository/EntityRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query;
Expand Down Expand Up @@ -75,14 +76,6 @@ public function __construct(
*/
public const NODETYPE_ALIAS = 'nt';

/**
* Doctrine column types that can be search
* with LIKE feature.
*
* @var array
*/
protected array $searchableTypes = ['string', 'text'];

/**
* @param QueryBuilder $qb
* @param class-string $entityClass
Expand All @@ -97,7 +90,7 @@ protected function dispatchQueryBuilderEvent(QueryBuilder $qb, string $entityCla
* @param string $property
* @param mixed $value
*
* @return object|QueryBuilderBuildEvent
* @return QueryBuilderBuildEvent
*/
protected function dispatchQueryBuilderBuildEvent(QueryBuilder $qb, string $property, mixed $value): object
{
Expand All @@ -113,7 +106,7 @@ protected function dispatchQueryBuilderBuildEvent(QueryBuilder $qb, string $prop
/**
* @param Query $query
*
* @return object|QueryEvent
* @return QueryEvent
*/
protected function dispatchQueryEvent(Query $query): object
{
Expand All @@ -128,7 +121,7 @@ protected function dispatchQueryEvent(Query $query): object
* @param string $property
* @param mixed $value
*
* @return object|QueryBuilderApplyEvent
* @return QueryBuilderApplyEvent
*/
protected function dispatchQueryBuilderApplyEvent(QueryBuilder $qb, string $property, mixed $value): object
{
Expand Down Expand Up @@ -234,6 +227,40 @@ public function countBy(mixed $criteria): int
return 0;
}

/**
* @param ClassMetadataInfo $metadata
* @return array
*/
public static function getSearchableColumnsNames(ClassMetadataInfo $metadata): array
{
/*
* Get fields needed for a search query
*/
$criteriaFields = [];
$cols = $metadata->getColumnNames();
foreach ($cols as $col) {
$field = $metadata->getFieldName($col);
$type = $metadata->getTypeOfField($field);
if (
in_array($type, ['string', 'text']) &&
!in_array($field, [
'color',
'folder',
'childrenOrder',
'childrenOrderDirection',
'password',
'salt',
'token',
'confirmationToken'
])
) {
$criteriaFields[] = $field;
}
}

return $criteriaFields;
}

/**
* Create a LIKE comparison with entity texts colunms.
*
Expand All @@ -247,23 +274,9 @@ protected function classicLikeComparison(
QueryBuilder $qb,
string $alias = EntityRepository::DEFAULT_ALIAS
): QueryBuilder {
/*
* Get fields needed for a search query
*/
$metadata = $this->_em->getClassMetadata($this->getEntityName());
$criteriaFields = [];
$cols = $metadata->getColumnNames();
foreach ($cols as $col) {
$field = $metadata->getFieldName($col);
$type = $metadata->getTypeOfField($field);
if (
in_array($type, $this->searchableTypes) &&
$field != 'folder' &&
$field != 'childrenOrder' &&
$field != 'childrenOrderDirection'
) {
$criteriaFields[$field] = '%' . strip_tags((string) $pattern) . '%';
}
foreach (static::getSearchableColumnsNames($this->getClassMetadata()) as $field) {
$criteriaFields[$field] = '%' . strip_tags(mb_strtolower($pattern)) . '%';
}

foreach ($criteriaFields as $key => $value) {
Expand Down
16 changes: 5 additions & 11 deletions lib/RoadizCoreBundle/src/Repository/FolderRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,18 @@ protected function createSearchBy(
* Search in translations
*/
$qb->leftJoin('obj.translatedFolders', 'tf');

$criteriaFields = [];
$metadata = $this->_em->getClassMetadata(FolderTranslation::class);
$cols = $metadata->getColumnNames();
foreach ($cols as $col) {
$field = $metadata->getFieldName($col);
$type = $metadata->getTypeOfField($field);
if (in_array($type, $this->searchableTypes)) {
$criteriaFields[$field] = '%' . strip_tags((string) $pattern) . '%';
}
foreach (self::getSearchableColumnsNames($this->_em->getClassMetadata(FolderTranslation::class)) as $field) {
$criteriaFields[$field] = '%' . strip_tags(mb_strtolower($pattern)) . '%';
}

foreach ($criteriaFields as $key => $value) {
$fullKey = sprintf('LOWER(%s)', 'tf.' . $key);
$qb->orWhere($qb->expr()->like($fullKey, $qb->expr()->literal($value)));
}

$qb = $this->prepareComparisons($criteria, $qb, $alias);

return $qb;
return $this->prepareComparisons($criteria, $qb, $alias);
}

/**
Expand Down
10 changes: 2 additions & 8 deletions lib/RoadizCoreBundle/src/Repository/NodeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -1001,14 +1001,8 @@ protected function createSearchBy(
*/
$qb->innerJoin($alias . '.nodeSources', self::NODESSOURCES_ALIAS);
$criteriaFields = [];
$metadatas = $this->_em->getClassMetadata(NodesSources::class);
$cols = $metadatas->getColumnNames();
foreach ($cols as $col) {
$field = $metadatas->getFieldName($col);
$type = $metadatas->getTypeOfField($field);
if (in_array($type, $this->searchableTypes)) {
$criteriaFields[$field] = '%' . strip_tags((string) $pattern) . '%';
}
foreach (self::getSearchableColumnsNames($this->_em->getClassMetadata(NodesSources::class)) as $field) {
$criteriaFields[$field] = '%' . strip_tags(mb_strtolower($pattern)) . '%';
}
foreach ($criteriaFields as $key => $value) {
$fullKey = sprintf('LOWER(%s)', self::NODESSOURCES_ALIAS . '.' . $key);
Expand Down
16 changes: 3 additions & 13 deletions lib/RoadizCoreBundle/src/Repository/PrefixAwareRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
use RZ\Roadiz\CoreBundle\Doctrine\ORM\SimpleQueryBuilder;
use RZ\Roadiz\CoreBundle\Entity\FolderTranslation;

/**
* Class PrefixAwareRepository for defining join-queries prefixes.
Expand Down Expand Up @@ -314,20 +315,9 @@ protected function classicLikeComparison(
/*
* Get fields needed for a search query
*/
$metadatas = $this->_em->getClassMetadata($this->getEntityName());
$criteriaFields = [];
$cols = $metadatas->getColumnNames();
foreach ($cols as $col) {
$field = $metadatas->getFieldName($col);
$type = $metadatas->getTypeOfField($field);
if (
in_array($type, $this->searchableTypes) &&
$field != 'folder' &&
$field != 'childrenOrder' &&
$field != 'childrenOrderDirection'
) {
$criteriaFields[$field] = '%' . strip_tags((string) $pattern) . '%';
}
foreach (static::getSearchableColumnsNames($this->getClassMetadata()) as $field) {
$criteriaFields[$field] = '%' . strip_tags(mb_strtolower($pattern)) . '%';
}

foreach ($criteriaFields as $key => $value) {
Expand Down
Loading

0 comments on commit 22ed7f5

Please sign in to comment.