From 9e546434bf88e6166cb7e957865c3c9fc6af84bd Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Tue, 25 Mar 2025 09:30:12 +0500 Subject: [PATCH 1/7] =?UTF-8?q?tests:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Repository/CommentRepository.php | 7 +++++-- tests/Repository/PostRepository.php | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/Repository/CommentRepository.php b/tests/Repository/CommentRepository.php index c592a7f..f691197 100644 --- a/tests/Repository/CommentRepository.php +++ b/tests/Repository/CommentRepository.php @@ -5,12 +5,15 @@ declare(strict_types=1); namespace IQDEV\Tests\Packages\DoctrineHttpFilter\Repository; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; -use IQDEV\Packages\DoctrineHttpFilter\HttpFilterEntityRepository; +use IQDEV\Packages\DoctrineHttpFilter\HttpFilterTrait; use IQDEV\Tests\Packages\DoctrineHttpFilter\Entity\Comment; -class CommentRepository extends HttpFilterEntityRepository +class CommentRepository extends EntityRepository { + use HttpFilterTrait; + public function __construct(EntityManagerInterface $em) { parent::__construct($em, new ClassMetadata(Comment::class)); diff --git a/tests/Repository/PostRepository.php b/tests/Repository/PostRepository.php index 3e1c377..7cd7910 100644 --- a/tests/Repository/PostRepository.php +++ b/tests/Repository/PostRepository.php @@ -5,12 +5,15 @@ declare(strict_types=1); namespace IQDEV\Tests\Packages\DoctrineHttpFilter\Repository; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; -use IQDEV\Packages\DoctrineHttpFilter\HttpFilterEntityRepository; +use IQDEV\Packages\DoctrineHttpFilter\HttpFilterTrait; use IQDEV\Tests\Packages\DoctrineHttpFilter\Entity\Post; -class PostRepository extends HttpFilterEntityRepository +class PostRepository extends EntityRepository { + use HttpFilterTrait; + public function __construct(EntityManagerInterface $em) { parent::__construct($em, new ClassMetadata(Post::class)); -- GitLab From 25a0aaa6858fb6792ac6cf5de5da76062e479acd Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Tue, 25 Mar 2025 11:04:05 +0500 Subject: [PATCH 2/7] =?UTF-8?q?fix:=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82=D1=80?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=BC=D0=B1=D0=B8?= =?UTF-8?q?=D0=BD=D0=B0=D1=86=D0=B8=D0=B9=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Filter/Date.php | 2 +- src/Filter/DateRange.php | 2 +- src/Filter/ILike.php | 2 +- src/Filter/In.php | 2 +- src/Filter/Like.php | 2 +- src/Filter/Range.php | 2 +- src/Filter/Where.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Filter/Date.php b/src/Filter/Date.php index 1a81eb5..7d54ba5 100644 --- a/src/Filter/Date.php +++ b/src/Filter/Date.php @@ -19,7 +19,7 @@ final class Date extends HttpFilter return $queryBuilder; } - $queryBuilder->where( + $queryBuilder->andWhere( $this->getColumn() . ' BETWEEN :dateStart AND :dateEnd', ); diff --git a/src/Filter/DateRange.php b/src/Filter/DateRange.php index 6456257..78a0af0 100644 --- a/src/Filter/DateRange.php +++ b/src/Filter/DateRange.php @@ -27,7 +27,7 @@ final class DateRange extends HttpFilter } if ($fromDate) { - $queryBuilder->where($this->getColumn() . ' >= :fromDate') + $queryBuilder->andWhere($this->getColumn() . ' >= :fromDate') ->setParameter('fromDate', $fromDate->setTime(0, 0, 0)); } diff --git a/src/Filter/ILike.php b/src/Filter/ILike.php index 2fe7a3e..a49fb34 100644 --- a/src/Filter/ILike.php +++ b/src/Filter/ILike.php @@ -11,7 +11,7 @@ final class ILike extends HttpFilter { public function addToQuery(QueryBuilder $queryBuilder): QueryBuilder { - $queryBuilder->where( + $queryBuilder->andWhere( $this->getColumn() . ' ILIKE \'%' . $this->getHttpValue() . '%\'', ); diff --git a/src/Filter/In.php b/src/Filter/In.php index 946e38f..8a90d2d 100644 --- a/src/Filter/In.php +++ b/src/Filter/In.php @@ -18,7 +18,7 @@ final class In extends HttpFilter $values = array_map(fn($value) => '\'' . $value . '\'', $this->getHttpValue()); $stringValues = implode(',', $values); - $queryBuilder->where( + $queryBuilder->andWhere( $this->getColumn() . ' IN (' . $stringValues . ')', ); diff --git a/src/Filter/Like.php b/src/Filter/Like.php index 30dd2ce..a5dc19a 100644 --- a/src/Filter/Like.php +++ b/src/Filter/Like.php @@ -15,7 +15,7 @@ final class Like extends HttpFilter return $queryBuilder; } - $queryBuilder->where( + $queryBuilder->andWhere( $this->getColumn() . ' LIKE :' . $this->getParameterKey(), ); diff --git a/src/Filter/Range.php b/src/Filter/Range.php index 8711c7d..ad5977c 100644 --- a/src/Filter/Range.php +++ b/src/Filter/Range.php @@ -17,7 +17,7 @@ final class Range extends HttpFilter } if (isset($this->getHttpValue()['min'])) { - $queryBuilder->where( + $queryBuilder->andWhere( $this->getColumn() . ' >= ' . $this->getHttpValue()['min'], ); } diff --git a/src/Filter/Where.php b/src/Filter/Where.php index 8a6a807..d7ad73e 100644 --- a/src/Filter/Where.php +++ b/src/Filter/Where.php @@ -15,7 +15,7 @@ final class Where extends HttpFilter return $queryBuilder; } - $queryBuilder->where( + $queryBuilder->andWhere( $this->getColumn() . ' = :' . $this->getParameterKey(), ); -- GitLab From 5e844378843ed9211b6d48a61a85767af0b5c977 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Tue, 25 Mar 2025 15:50:46 +0500 Subject: [PATCH 3/7] =?UTF-8?q?tests:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=BC=D0=B1=D0=B8?= =?UTF-8?q?=D0=BD=D0=B0=D1=86=D0=B8=D0=B9=20=D1=84=D0=B8=D0=BB=D1=8C=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/FilterByMultipleFiltersTest.php | 162 ++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 tests/FilterByMultipleFiltersTest.php diff --git a/tests/FilterByMultipleFiltersTest.php b/tests/FilterByMultipleFiltersTest.php new file mode 100644 index 0000000..7c84bca --- /dev/null +++ b/tests/FilterByMultipleFiltersTest.php @@ -0,0 +1,162 @@ +em->getRepository(Post::class); + + $firstName = 'Видеопредставление'; + $firstDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 12:00:00'); + $secondName = 'Видеомагнитофон'; + $secondDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-05 14:00:00'); + + $post = new Post( + $firstName, + $this->faker->text(), + $this->faker->boolean(), + $firstDate, + ); + + $post2 = new Post( + $secondName, + $this->faker->text(), + $this->faker->boolean(), + $secondDate, + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $subtitle = 'Видео'; + $firstDateWithDay = $firstDate->add(new DateInterval('P1D')); + $result = $postRepository->createQueryByFilter([ + 'createdAt' => DateRange::class, + 'title' => Like::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'title' => $subtitle, + 'createdAt' => [ + 'from' => $firstDate->format('Y-m-d'), + 'to' => $firstDateWithDay->format('Y-m-d'), + ], + ], + ])) + ->getQuery() + ->getResult(); + + $this->assertNotEmpty($result); + $this->assertCount(1, $result); + } + + public function testFilterByMultipleFiltersDateAndIn(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $firstName = 'Спорт'; + $firstDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 12:00:00'); + $secondName = 'Наука'; + $secondDate = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 14:00:00'); + + $post = new Post( + $firstName, + $this->faker->text(), + $this->faker->boolean(), + $firstDate, + ); + + $post2 = new Post( + $secondName, + $this->faker->text(), + $this->faker->boolean(), + $secondDate, + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $inValues = ['Спорт', 'Бизнес', 'Кулинария']; + $result = $postRepository->createQueryByFilter([ + 'createdAt' => Date::class, + 'title' => In::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'title' => $inValues, + 'createdAt' => $firstDate->format('Y-m-d'), + ], + ])) + ->getQuery() + ->getResult(); + + $this->assertNotEmpty($result); + $this->assertCount(1, $result); + } + + public function testFilterByMultipleFiltersRangeAndWhere(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $firstCountOfViews = 20; + $secondCountOfViews = 40; + + $post = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + DateTimeImmutable::createFromInterface($this->faker->dateTime()), + countOfViews: $firstCountOfViews, + ); + + $post2 = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + DateTimeImmutable::createFromInterface($this->faker->dateTime()), + countOfViews: $secondCountOfViews, + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $minValue = 30; + $name = 'Not found'; + $result = $postRepository->createQueryByFilter([ + 'title' => Where::class, + 'countOfViews' => Range::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'title' => $name, + 'createdAt' => [ + 'min' => $minValue, + ] + ], + ])) + ->getQuery() + ->getResult(); + + $this->assertEmpty($result); + } +} -- GitLab From ca8d9f7bc159f3a820621705102451d6f90824b5 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 27 Mar 2025 13:07:17 +0500 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20=D1=81=D0=BE=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HttpFilterEntityRepository.php | 16 +++++++++ src/HttpFilterTrait.php | 13 ++++++++ src/HttpSort.php | 53 ++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 src/HttpSort.php diff --git a/src/HttpFilterEntityRepository.php b/src/HttpFilterEntityRepository.php index fb0108c..23d844b 100644 --- a/src/HttpFilterEntityRepository.php +++ b/src/HttpFilterEntityRepository.php @@ -29,4 +29,20 @@ class HttpFilterEntityRepository extends EntityRepository implements QueryFilter return $queryBuilder; } + + public function createQueryForSort( + string $field, + string $tableAlias, + Request $request, + ?QueryBuilder $queryBuilder = null + ): QueryBuilder { + if ($queryBuilder === null) { + $queryBuilder = $this->createQueryBuilder($tableAlias); + } + + $sort = new HttpSort($tableAlias, $field, $request); + $sort->addToQuery($queryBuilder); + + return $queryBuilder; + } } diff --git a/src/HttpFilterTrait.php b/src/HttpFilterTrait.php index 373eb5d..fd1fab7 100644 --- a/src/HttpFilterTrait.php +++ b/src/HttpFilterTrait.php @@ -28,5 +28,18 @@ trait HttpFilterTrait return $this->repository->createQueryByFilter($filters, $this->getAliasTableForFilter(), $request); } + final public function createQueryForSort(Request $request, ?QueryBuilder $queryBuilder = null): QueryBuilder + { + if (! isset($this->repository)) { + $this->repository = new HttpFilterEntityRepository( + $this->getEntityManager(), + new ClassMetadata($this->getClassName()) + ); + } + $field = array_key_first($request->query->getIterator()[HttpSort::REQUEST_SORT_KEY]); + + return $this->repository->createQueryForSort($field, $this->getAliasTableForFilter(), $request, $queryBuilder); + } + abstract public function getAliasTableForFilter(): string; } diff --git a/src/HttpSort.php b/src/HttpSort.php new file mode 100644 index 0000000..1df58ce --- /dev/null +++ b/src/HttpSort.php @@ -0,0 +1,53 @@ +request = $request ?? Request::createFromGlobals(); + } + + protected function getColumn(): string + { + return $this->tableAlias . '.' . $this->field; + } + + protected function getHttpValue(): mixed + { + $filter = $this + ->request + ->query + ->getIterator()[static::REQUEST_SORT_KEY] ?? null; + + if ($filter === null) { + return null; + } + + return $filter[$this->field] ?? null; + } + + public function addToQuery(QueryBuilder $queryBuilder): QueryBuilder + { + if (in_array($this->getHttpValue(), self::SORT_DIRECTIONS, true)) { + $queryBuilder->orderBy($this->getColumn(), $this->getHttpValue()); + } + + return $queryBuilder; + } +} -- GitLab From f26abc89d67070bbd56876214c0725a06e4d228b Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Thu, 27 Mar 2025 13:08:28 +0500 Subject: [PATCH 5/7] =?UTF-8?q?tests:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D1=8B=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/HttpSortTest.php | 168 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 tests/HttpSortTest.php diff --git a/tests/HttpSortTest.php b/tests/HttpSortTest.php new file mode 100644 index 0000000..484b730 --- /dev/null +++ b/tests/HttpSortTest.php @@ -0,0 +1,168 @@ +em->getRepository(Post::class); + + $title = 'Видеопредставление'; + $title2 = 'Видео'; + $countOfViews = 12; + $countOfViews2 = 22; + + $post = new Post( + $title, + $this->faker->text(), + $this->faker->boolean(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + countOfViews: $countOfViews + ); + + $post2 = new Post( + $title2, + $this->faker->text(), + $this->faker->boolean(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + countOfViews: $countOfViews2 + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $result = $postRepository->createQueryByFilter([ + 'title' => Like::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'title' => $title2, + ], + ])); + + $result = $postRepository->createQueryForSort( + new Request([ + HttpSort::REQUEST_SORT_KEY => [ + 'countOfViews' => 'DESC', + ], + ]), + $result + ) + ->getQuery() + ->getResult(); + + $this->assertSame($countOfViews, $result[1]->countOfViews); + $this->assertCount(2, $result); + } + + public function testStringSortWithFilter(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $title = 'Видеопредставление'; + $title2 = 'Дорога'; + + $post = new Post( + $title, + $this->faker->text(), + $this->faker->boolean(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + ); + + $post2 = new Post( + $title2, + $this->faker->text(), + $this->faker->boolean(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $result = $postRepository->createQueryByFilter([ + 'title' => Like::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'title' => $title2, + ], + ])); + + $result = $postRepository->createQueryForSort( + new Request([ + HttpSort::REQUEST_SORT_KEY => [ + 'title' => 'ASC', + ], + ]), + $result + ) + ->getQuery() + ->getResult(); + + $this->assertSame($title2, $result[0]->title); + $this->assertCount(1, $result); + } + + public function testDateSortWithFilter(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $title = 'Видеопредставление'; + $title2 = 'Видео'; + $date = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-01 12:00:00'); + $date2 = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2020-01-05 19:30:00'); + + $post = new Post( + $title, + $this->faker->text(), + $this->faker->boolean(), + $date + ); + + $post2 = new Post( + $title2, + $this->faker->text(), + $this->faker->boolean(), + $date2 + ); + + $this->em->persist($post); + $this->em->persist($post2); + $this->em->flush(); + + $result = $postRepository->createQueryByFilter([ + 'title' => Like::class, + ], new Request([ + HttpFilter::REQUEST_FILTER_KEY => [ + 'title' => $title2, + ], + ])); + + $result = $postRepository->createQueryForSort( + new Request([ + HttpSort::REQUEST_SORT_KEY => [ + 'createdAt' => 'DESC', + ], + ]), + $result + ) + ->getQuery() + ->getResult(); + + $this->assertSame($date2, $result[0]->createdAt); + $this->assertCount(2, $result); + } +} -- GitLab From 0f630d6503d072d223b0e1a93ea0cf35752f0221 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Mon, 31 Mar 2025 11:58:42 +0500 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE?= =?UTF-8?q?=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D1=81=D0=BE=D1=80=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=81?= =?UTF-8?q?=D0=BC=D0=B5=D0=B6=D0=BD=D0=BE=D0=B9=20=D1=82=D0=B0=D0=B1=D0=BB?= =?UTF-8?q?=D0=B8=D1=86=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/HttpSort.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/HttpSort.php b/src/HttpSort.php index 1df58ce..a9ebc20 100644 --- a/src/HttpSort.php +++ b/src/HttpSort.php @@ -44,8 +44,9 @@ class HttpSort public function addToQuery(QueryBuilder $queryBuilder): QueryBuilder { + $orderColumns = str_contains($this->field, '.') ? $this->field : $this->getColumn(); if (in_array($this->getHttpValue(), self::SORT_DIRECTIONS, true)) { - $queryBuilder->orderBy($this->getColumn(), $this->getHttpValue()); + $queryBuilder->orderBy($orderColumns, $this->getHttpValue()); } return $queryBuilder; -- GitLab From 83d8c786b2f6b077aa0c533b24df877006250913 Mon Sep 17 00:00:00 2001 From: "a.shamavov" Date: Mon, 31 Mar 2025 11:59:26 +0500 Subject: [PATCH 7/7] =?UTF-8?q?tests:=20=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=20=D1=82=D0=B5=D1=81=D1=82=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D1=80=D1=82=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=81=D0=BC=D0=B5=D0=B6?= =?UTF-8?q?=D0=BD=D1=8B=D0=BC=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B0?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/HttpSortTest.php | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tests/HttpSortTest.php b/tests/HttpSortTest.php index 484b730..d0d4737 100644 --- a/tests/HttpSortTest.php +++ b/tests/HttpSortTest.php @@ -4,9 +4,11 @@ declare(strict_types=1); namespace IQDEV\Tests\Packages\DoctrineHttpFilter; +use Doctrine\ORM\AbstractQuery; use IQDEV\Packages\DoctrineHttpFilter\Filter\Like; use IQDEV\Packages\DoctrineHttpFilter\HttpFilter; use IQDEV\Packages\DoctrineHttpFilter\HttpSort; +use IQDEV\Tests\Packages\DoctrineHttpFilter\Entity\Comment; use IQDEV\Tests\Packages\DoctrineHttpFilter\Entity\Post; use IQDEV\Tests\Packages\DoctrineHttpFilter\Repository\PostRepository; use Symfony\Component\HttpFoundation\Request; @@ -165,4 +167,59 @@ class HttpSortTest extends TestCase $this->assertSame($date2, $result[0]->createdAt); $this->assertCount(2, $result); } + + public function testSortWithJoinTable(): void + { + /** @var PostRepository $postRepository */ + $postRepository = $this->em->getRepository(Post::class); + + $author1 = 'Александр'; + $author2 = 'Яков'; + + $post = new Post( + $this->faker->name(), + $this->faker->text(), + $this->faker->boolean(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + ); + + $comment1 = new Comment( + $author1, + $this->faker->text(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + $post + ); + $comment2 = new Comment( + $author1, + $this->faker->text(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + $post + ); + $comment3 = new Comment( + $author2, + $this->faker->text(), + \DateTimeImmutable::createFromInterface($this->faker->dateTime()), + $post + ); + + $this->em->persist($post); + $this->em->persist($comment1); + $this->em->persist($comment2); + $this->em->persist($comment3); + $this->em->flush(); + + $result = $postRepository->createQueryForSort( + new Request([ + HttpSort::REQUEST_SORT_KEY => [ + 'c.author' => 'DESC', + ], + ]) + ) + ->leftJoin(Comment::class, 'c') + ->select('p', 'c.author') + ->getQuery() + ->getResult(AbstractQuery::HYDRATE_ARRAY); + + $this->assertSame($author2, $result[0]['author']); + } } -- GitLab