Skip to content

Commit

Permalink
Add sortBys to the DimensionContentQueryEnhancer (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
Prokyonn authored Aug 7, 2024
1 parent 0f2d107 commit 8ab47bd
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 10 deletions.
19 changes: 17 additions & 2 deletions Content/Infrastructure/Doctrine/DimensionContentQueryEnhancer.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,26 @@ class DimensionContentQueryEnhancer
* templateKeys?: string[],
* loadGhost?: bool,
* } $filters
* @param array{
* title?: 'asc'|'desc',
* authored?: 'asc'|'desc',
* workflowPublished?: 'asc'|'desc',
* } $sortBys
*/
public function addFilters(
QueryBuilder $queryBuilder,
string $contentRichEntityAlias,
string $dimensionContentClassName,
array $filters
array $filters,
array $sortBys
): void {
$effectiveAttributes = $dimensionContentClassName::getEffectiveDimensionAttributes($filters);

$queryBuilder->leftJoin(
$dimensionContentClassName,
'filterDimensionContent',
Join::WITH,
'filterDimensionContent.' . $contentRichEntityAlias . ' = ' . $contentRichEntityAlias . ''
'filterDimensionContent.' . $contentRichEntityAlias . ' = ' . $contentRichEntityAlias
);

foreach ($effectiveAttributes as $key => $value) {
Expand Down Expand Up @@ -182,6 +188,15 @@ public function addFilters(
->setParameter('templateKeys', $templateKeys);
}
}

// Sort by
foreach ($sortBys as $field => $order) {
if (!\in_array($field, ['title', 'authored', 'workflowPublished'], true)) {
continue;
}

$queryBuilder->addOrderBy('filterDimensionContent.' . $field, $order);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public function countBy(array $filters = []): int
* @param array{
* id?: 'asc'|'desc',
* title?: 'asc'|'desc',
* } $sortBy
* } $sortBys
* @param array{
* example_admin?: bool,
* example_website?: bool,
Expand All @@ -216,9 +216,9 @@ public function countBy(array $filters = []): int
*
* @return \Generator<Example>
*/
public function findBy(array $filters = [], array $sortBy = [], array $selects = []): \Generator
public function findBy(array $filters = [], array $sortBys = [], array $selects = []): \Generator
{
$queryBuilder = $this->createQueryBuilder($filters, $sortBy, $selects);
$queryBuilder = $this->createQueryBuilder($filters, $sortBys, $selects);

// TODO optimize hydration with toIterable()
/** @var iterable<Example> $examples */
Expand Down Expand Up @@ -258,14 +258,14 @@ public function remove(Example $example): void
* @param array{
* id?: 'asc'|'desc',
* title?: 'asc'|'desc',
* } $sortBy
* } $sortBys
* @param array{
* example_admin?: bool,
* example_website?: bool,
* with-example-content?: bool|array<string, mixed>,
* } $selects
*/
private function createQueryBuilder(array $filters, array $sortBy = [], array $selects = []): QueryBuilder
private function createQueryBuilder(array $filters, array $sortBys = [], array $selects = []): QueryBuilder
{
foreach ($selects as $selectGroup => $value) {
if (!$value) {
Expand Down Expand Up @@ -307,13 +307,18 @@ private function createQueryBuilder(array $filters, array $sortBy = [], array $s
$queryBuilder->setFirstResult($offset);
}

if (\array_key_exists('locale', $filters) // should also work with locale = null
&& \array_key_exists('stage', $filters)) {
if ((
\array_key_exists('locale', $filters) // should also work with locale = null
&& \array_key_exists('stage', $filters)
)
|| ([] === $filters && [] !== $sortBys) // if no filters are set, but sortBy is set
) {
$this->dimensionContentQueryEnhancer->addFilters(
$queryBuilder,
'example',
ExampleDimensionContent::class,
$filters
$filters,
$sortBys
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Sulu\Bundle\ContentBundle\Tests\Functional\Content\Infrastructure\Doctrine;

use Sulu\Bundle\ContentBundle\Content\Application\ContentManager\ContentManagerInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollection;
use Sulu\Bundle\ContentBundle\Content\Infrastructure\Doctrine\DimensionContentQueryEnhancer;
use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent;
Expand All @@ -35,9 +36,12 @@ class DimensionContentQueryEnhancerTest extends SuluTestCase
*/
private $exampleRepository;

private ContentManagerInterface $contentManager;

protected function setUp(): void
{
$this->exampleRepository = static::getContainer()->get('example_test.example_repository');
$this->contentManager = static::getContainer()->get('sulu_content.content_manager');
}

public function testNullDimensionAttribute(): void
Expand Down Expand Up @@ -395,4 +399,195 @@ public function testFilterTemplateKeys(): void
'templateKeys' => ['a', 'c'],
]));
}

public function testSortByInvalidField(): void
{
static::purgeDatabase();

$example = static::createExample();
$example2 = static::createExample();
$example3 = static::createExample();
static::createExampleContent($example, ['title' => 'Example A', 'templateKey' => 'a']);
static::createExampleContent($example2, ['title' => 'Example B', 'templateKey' => 'b']);
static::createExampleContent($example3, ['title' => 'Example C', 'templateKey' => 'c']);
static::getEntityManager()->flush();
static::getEntityManager()->clear();

$unsortedResult = \iterator_to_array($this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
]
));

foreach ($this->exampleRepository->findBy(['locale' => 'en', 'stage' => 'draft'], ['invalid' => 'asc']) as $key => $example) {
self::assertSame($unsortedResult[$key]->getId(), $example->getId());
}

foreach ($this->exampleRepository->findBy(['locale' => 'en', 'stage' => 'draft'], ['invalid' => 'desc']) as $key => $example) {
self::assertSame($unsortedResult[$key]->getId(), $example->getId());
}
}

public function testSortByTitle(): void
{
static::purgeDatabase();

$example = static::createExample();
$example2 = static::createExample();
$example3 = static::createExample();
static::createExampleContent($example, ['templateData' => ['title' => 'Example A'], 'templateKey' => 'a']);
static::createExampleContent($example2, ['templateData' => ['title' => 'Example B'], 'templateKey' => 'b']);
static::createExampleContent($example3, ['templateData' => ['title' => 'Example C'], 'templateKey' => 'c']);
static::getEntityManager()->flush();
static::getEntityManager()->clear();

$result = \iterator_to_array(
$this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
],
[
'title' => 'asc',
]
)
);
$this->assertCount(3, $result);
$this->assertSame('Example A', $this->contentManager->resolve($result[0], ['locale' => 'en', 'stage' => 'draft'])->getTemplateData()['title']);
$this->assertSame('Example B', $this->contentManager->resolve($result[1], ['locale' => 'en', 'stage' => 'draft'])->getTemplateData()['title']);
$this->assertSame('Example C', $this->contentManager->resolve($result[2], ['locale' => 'en', 'stage' => 'draft'])->getTemplateData()['title']);

$result = \iterator_to_array(
$this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
],
[
'title' => 'desc',
]
)
);
$this->assertCount(3, $result);
$this->assertSame('Example C', $this->contentManager->resolve($result[0], ['locale' => 'en', 'stage' => 'draft'])->getTemplateData()['title']);
$this->assertSame('Example B', $this->contentManager->resolve($result[1], ['locale' => 'en', 'stage' => 'draft'])->getTemplateData()['title']);
$this->assertSame('Example A', $this->contentManager->resolve($result[2], ['locale' => 'en', 'stage' => 'draft'])->getTemplateData()['title']);
}

public function testSortByAuthored(): void
{
static::purgeDatabase();

$example = static::createExample();
$example2 = static::createExample();
$example3 = static::createExample();
static::createExampleContent($example, ['templateData' => ['title' => 'Example A'], 'authored' => new \DateTimeImmutable('2020-01-01')]);
static::createExampleContent($example2, ['templateData' => ['title' => 'Example B'], 'authored' => new \DateTimeImmutable('2020-03-01')]);
static::createExampleContent($example3, ['templateData' => ['title' => 'Example C'], 'authored' => new \DateTimeImmutable('2020-02-01')]);
static::getEntityManager()->flush();
static::getEntityManager()->clear();

$result = \iterator_to_array(
$this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
],
[
'authored' => 'desc',
]
)
);
$this->assertCount(3, $result);
/** @var ExampleDimensionContent $exampleDimensionContent */
$exampleDimensionContent = $this->contentManager->resolve($result[0], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-03-01', $exampleDimensionContent->getAuthored()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent2 */
$exampleDimensionContent2 = $this->contentManager->resolve($result[1], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-02-01', $exampleDimensionContent2->getAuthored()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent3 */
$exampleDimensionContent3 = $this->contentManager->resolve($result[2], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-01-01', $exampleDimensionContent3->getAuthored()?->format('Y-m-d'));

$result = \iterator_to_array(
$this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
],
[
'authored' => 'asc',
]
)
);
$this->assertCount(3, $result);
/** @var ExampleDimensionContent $exampleDimensionContent */
$exampleDimensionContent = $this->contentManager->resolve($result[0], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-01-01', $exampleDimensionContent->getAuthored()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent2 */
$exampleDimensionContent2 = $this->contentManager->resolve($result[1], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-02-01', $exampleDimensionContent2->getAuthored()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent3 */
$exampleDimensionContent3 = $this->contentManager->resolve($result[2], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-03-01', $exampleDimensionContent3->getAuthored()?->format('Y-m-d'));
}

public function testSortByWorkflowPublished(): void
{
static::purgeDatabase();

$example = static::createExample();
$example2 = static::createExample();
$example3 = static::createExample();
static::createExampleContent($example, ['templateData' => ['title' => 'Example A'], 'workflowPublished' => new \DateTimeImmutable('2020-01-01')]);
static::createExampleContent($example2, ['templateData' => ['title' => 'Example B'], 'workflowPublished' => new \DateTimeImmutable('2020-03-01')]);
static::createExampleContent($example3, ['templateData' => ['title' => 'Example C'], 'workflowPublished' => new \DateTimeImmutable('2020-02-01')]);
static::getEntityManager()->flush();
static::getEntityManager()->clear();

$result = \iterator_to_array(
$this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
],
[
'workflowPublished' => 'desc',
]
)
);
$this->assertCount(3, $result);
/** @var ExampleDimensionContent $exampleDimensionContent */
$exampleDimensionContent = $this->contentManager->resolve($result[0], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-03-01', $exampleDimensionContent->getWorkflowPublished()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent2 */
$exampleDimensionContent2 = $this->contentManager->resolve($result[1], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-02-01', $exampleDimensionContent2->getWorkflowPublished()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent3 */
$exampleDimensionContent3 = $this->contentManager->resolve($result[2], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-01-01', $exampleDimensionContent3->getWorkflowPublished()?->format('Y-m-d'));

$result = \iterator_to_array(
$this->exampleRepository->findBy(
[
'locale' => 'en',
'stage' => 'draft',
],
[
'workflowPublished' => 'asc',
]
)
);
$this->assertCount(3, $result);
/** @var ExampleDimensionContent $exampleDimensionContent */
$exampleDimensionContent = $this->contentManager->resolve($result[0], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-01-01', $exampleDimensionContent->getWorkflowPublished()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent2 */
$exampleDimensionContent2 = $this->contentManager->resolve($result[1], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-02-01', $exampleDimensionContent2->getWorkflowPublished()?->format('Y-m-d'));
/** @var ExampleDimensionContent $exampleDimensionContent3 */
$exampleDimensionContent3 = $this->contentManager->resolve($result[2], ['locale' => 'en', 'stage' => 'draft']);
$this->assertSame('2020-03-01', $exampleDimensionContent3->getWorkflowPublished()?->format('Y-m-d'));
}
}
9 changes: 9 additions & 0 deletions Tests/Functional/Traits/CreateExampleTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use Doctrine\ORM\EntityManagerInterface;
use Sulu\Bundle\CategoryBundle\Entity\CategoryInterface;
use Sulu\Bundle\ContactBundle\Entity\ContactInterface;
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example;
use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent;
Expand All @@ -40,6 +41,10 @@ public function createExample(): Example
* templateData?: mixed[],
* excerptCategories?: CategoryInterface[],
* excerptTags?: TagInterface[],
* author?: ?ContactInterface,
* authored?: ?\DateTimeImmutable,
* workflowPlace?: ?string,
* workflowPublished?: ?\DateTimeImmutable,
* } $data
*/
public function createExampleContent(Example $example, array $data = []): void
Expand All @@ -56,6 +61,10 @@ public function createExampleContent(Example $example, array $data = []): void
$localizedDimensionContent = $example->createDimensionContent();
$localizedDimensionContent->setLocale($locale);
$localizedDimensionContent->setStage($stage);
$localizedDimensionContent->setAuthor($data['author'] ?? null);
$localizedDimensionContent->setAuthored($data['authored'] ?? null);
$localizedDimensionContent->setWorkflowPlace($data['workflowPlace'] ?? null);
$localizedDimensionContent->setWorkflowPublished($data['workflowPublished'] ?? null);

$templateKey = $data['templateKey'] ?? null;
if ($templateKey) {
Expand Down

0 comments on commit 8ab47bd

Please sign in to comment.