From 7d952692d2f1e5df82b745f1d143e42249e258a0 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Sat, 23 Dec 2023 23:45:52 +0900 Subject: [PATCH 1/7] =?UTF-8?q?chore:=20=F0=9F=A4=96=20update=20composer.(?= =?UTF-8?q?json|lock)=20of=20demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo/composer.json | 8 +------ demo/composer.lock | 58 ++++++++-------------------------------------- 2 files changed, 11 insertions(+), 55 deletions(-) diff --git a/demo/composer.json b/demo/composer.json index 7d9cf53..4e04d14 100644 --- a/demo/composer.json +++ b/demo/composer.json @@ -24,16 +24,10 @@ "symfony/twig-bundle": "7.0.*", "symfony/validator": "7.0.*", "symfony/yaml": "7.0.*", - "ttskch/paginator-bundle": "dev-feat/refactor", + "ttskch/paginator-bundle": "^6.0", "twig/extra-bundle": "^2.12|^3.0", "twig/twig": "^2.12|^3.0" }, - "repositories": { - "ttskch/paginator-bundle": { - "type": "vcs", - "url": "https://github.com/ttskch/TtskchPaginatorBundle" - } - }, "config": { "allow-plugins": { "php-http/discovery": true, diff --git a/demo/composer.lock b/demo/composer.lock index 48e7b42..5fb6071 100644 --- a/demo/composer.lock +++ b/demo/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b30335884393bdb3a97601947b74b2d8", + "content-hash": "30e7b45a82c54e1acff3d08bd057581e", "packages": [ { "name": "cakephp/chronos", @@ -5067,16 +5067,16 @@ }, { "name": "ttskch/paginator-bundle", - "version": "dev-feat/refactor", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/ttskch/TtskchPaginatorBundle.git", - "reference": "d44c3588c560e1348d4af18aab5434a68ccb4297" + "reference": "46e3ef726e4c422dae112f0c3467571d1dcf78ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ttskch/TtskchPaginatorBundle/zipball/d44c3588c560e1348d4af18aab5434a68ccb4297", - "reference": "d44c3588c560e1348d4af18aab5434a68ccb4297", + "url": "https://api.github.com/repos/ttskch/TtskchPaginatorBundle/zipball/46e3ef726e4c422dae112f0c3467571d1dcf78ac", + "reference": "46e3ef726e4c422dae112f0c3467571d1dcf78ac", "shasum": "" }, "require": { @@ -5111,43 +5111,7 @@ "Ttskch\\PaginatorBundle\\": "src/" } }, - "autoload-dev": { - "psr-4": { - "Ttskch\\PaginatorBundle\\Tests\\": "tests/" - } - }, - "scripts": { - "post-install-cmd": [ - "@composer bin all install" - ], - "post-update-cmd": [ - "@composer bin all install" - ], - "cs": [ - "vendor-bin/tools/vendor/bin/php-cs-fixer fix --config .php-cs-fixer.dist.php --dry-run --diff -v" - ], - "cs:fix": [ - "vendor-bin/tools/vendor/bin/php-cs-fixer fix --config .php-cs-fixer.dist.php" - ], - "sa": [ - "@php -d memory_limit=-1 vendor-bin/tools/vendor/bin/phpstan analyse" - ], - "sa:clear": [ - "vendor-bin/tools/vendor/bin/phpstan clear-result-cache" - ], - "test": [ - "@php -d memory_limit=-1 vendor/bin/phpunit" - ], - "tests": [ - "@cs", - "@test", - "@sa" - ], - "tests:bc": [ - "@cs", - "@test" - ] - }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -5162,10 +5126,10 @@ "symfony" ], "support": { - "source": "https://github.com/ttskch/TtskchPaginatorBundle/tree/feat/refactor", - "issues": "https://github.com/ttskch/TtskchPaginatorBundle/issues" + "issues": "https://github.com/ttskch/TtskchPaginatorBundle/issues", + "source": "https://github.com/ttskch/TtskchPaginatorBundle/tree/6.0.0" }, - "time": "2023-12-23T14:35:38+00:00" + "time": "2023-12-23T14:43:06+00:00" }, { "name": "twig/extra-bundle", @@ -6651,9 +6615,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "ttskch/paginator-bundle": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From d91bd8dbb8d245e10392b96e9cd6d33f9c4cedd0 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Sun, 24 Dec 2023 00:24:49 +0900 Subject: [PATCH 2/7] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20fix=20sample?= =?UTF-8?q?=20code=20in=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d09f6d2..ec31da5 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,9 @@ public function index(FooRepository $fooRepository, Paginator $paginator): Respo - - - + + + @@ -109,9 +109,9 @@ Just do like as following. {# ... #} - - - + + + @@ -376,9 +376,9 @@ public function index(FooRepository $fooRepository, Paginator $paginator): Respo
{{ ttskch_paginator_sortable('id') }}{{ ttskch_paginator_sortable('name') }}{{ ttskch_paginator_sortable('email') }}{{ ttskch_paginator_sortable('id', 'Id') }}{{ ttskch_paginator_sortable('name', 'Name') }}{{ ttskch_paginator_sortable('email', 'Email') }}
{{ ttskch_paginator_sortable('id') }}{{ ttskch_paginator_sortable('name') }}{{ ttskch_paginator_sortable('email') }}{{ ttskch_paginator_sortable('id', 'Id') }}{{ ttskch_paginator_sortable('name', 'Name') }}{{ ttskch_paginator_sortable('email', 'Email') }} {{ ttskch_paginator_sortable('bar.id', 'Bar') }} {{ ttskch_paginator_sortable('bar.baz.id', 'Baz') }}
- - - + + + From 0778a0d969de168e699bdded54d22191748b1e26 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Sun, 24 Dec 2023 00:58:07 +0900 Subject: [PATCH 3/7] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20improve=20samp?= =?UTF-8?q?le=20code=20in=20readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 136 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index ec31da5..64c634c 100644 --- a/README.md +++ b/README.md @@ -311,33 +311,45 @@ class FooSearchType extends AbstractType ```php // FooRepository.php +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; use Ttskch\PaginatorBundle\Counter\Doctrine\ORM\QueryBuilderCounter; use Ttskch\PaginatorBundle\Slicer\Doctrine\ORM\QueryBuilderSlicer; -public function sliceByCriteria(FooCriteria $criteria): \Traversable -{ - $qb = $this->createQueryBuilderFromCriteria($criteria); - $slicer = new QueryBuilderSlicer($qb); - - return $slicer->slice($criteria); -} - -public function countByCriteria(FooCriteria $criteria): int +/** + * @extends ServiceEntityRepository + */ +class FooRepository extends ServiceEntityRepository { - $qb = $this->createQueryBuilderFromCriteria($criteria); - $counter = new QueryBuilderCounter($qb); - - return $counter->count($criteria); -} + // ... -private function createQueryBuilderFromCriteria(FooCriteria $criteria): QueryBuilder -{ - return $this->createQueryBuilder('f') - ->orWhere('f.name like :query') - ->orWhere('f.email like :query') - ->setParameter('query', '%'.str_replace('%', '\%', $criteria->query).'%') - ; + /** + * @return \Traversable + */ + public function sliceByCriteria(FooCriteria $criteria): \Traversable + { + $qb = $this->createQueryBuilderFromCriteria($criteria); + $slicer = new QueryBuilderSlicer($qb); + + return $slicer->slice($criteria); + } + + public function countByCriteria(FooCriteria $criteria): int + { + $qb = $this->createQueryBuilderFromCriteria($criteria); + $counter = new QueryBuilderCounter($qb); + + return $counter->count($criteria); + } + + private function createQueryBuilderFromCriteria(FooCriteria $criteria): QueryBuilder + { + return $this->createQueryBuilder('f') + ->orWhere('f.name like :query') + ->orWhere('f.email like :query') + ->setParameter('query', '%'.str_replace('%', '\%', $criteria->query).'%') + ; + } } ``` @@ -353,11 +365,11 @@ use Ttskch\PaginatorBundle\Paginator; public function index(FooRepository $fooRepository, Paginator $paginator): Response { $paginator->initialize( - \Closure::fromCallable([$fooRepository, 'sliceByCriteria']), - \Closure::fromCallable([$fooRepository, 'countByCriteria']), - // or if PHP >= 8.1 - // $fooRepository->sliceByCriteria(...), - // $fooRepository->countByCriteria(...), + $fooRepository->sliceByCriteria(...), + $fooRepository->countByCriteria(...), + // or if PHP < 8.1 + // \Closure::fromCallable([$fooRepository, 'sliceByCriteria']), + // \Closure::fromCallable([$fooRepository, 'countByCriteria']), new FooCriteria('id'), ); @@ -400,37 +412,49 @@ public function index(FooRepository $fooRepository, Paginator $paginator): Respo ```php // FooRepository.php +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\QueryBuilder; use Ttskch\PaginatorBundle\Counter\Doctrine\ORM\QueryBuilderCounter; use Ttskch\PaginatorBundle\Slicer\Doctrine\ORM\QueryBuilderSlicer; -public function sliceByCriteria(FooCriteria $criteria): \Traversable -{ - $qb = $this->createQueryBuilderFromCriteria($criteria); - $slicer = new QueryBuilderSlicer($qb, alreadyJoined: true); // **PAY ATTENTION HERE** - - return $slicer->slice($criteria); -} - -public function countByCriteria(FooCriteria $criteria): int +/** + * @extends ServiceEntityRepository + */ +class FooRepository extends ServiceEntityRepository { - $qb = $this->createQueryBuilderFromCriteria($criteria); - $counter = new QueryBuilderCounter($qb); - - return $counter->count($criteria); -} + // ... -private function createQueryBuilderFromCriteria(FooCriteria $criteria): QueryBuilder -{ - return $this->createQueryBuilder('f') - ->leftJoin('f.bar', 'bar') - ->leftJoin('bar.baz', 'baz') - ->orWhere('f.name like :query') - ->orWhere('f.email like :query') - ->orWhere('bar.name like :query') - ->orWhere('baz.name like :query') - ->setParameter('query', '%'.str_replace('%', '\%', $criteria->query).'%') - ; + /** + * @return \Traversable + */ + public function sliceByCriteria(FooCriteria $criteria): \Traversable + { + $qb = $this->createQueryBuilderFromCriteria($criteria); + $slicer = new QueryBuilderSlicer($qb, alreadyJoined: true); // **PAY ATTENTION HERE** + + return $slicer->slice($criteria); + } + + public function countByCriteria(FooCriteria $criteria): int + { + $qb = $this->createQueryBuilderFromCriteria($criteria); + $counter = new QueryBuilderCounter($qb); + + return $counter->count($criteria); + } + + private function createQueryBuilderFromCriteria(FooCriteria $criteria): QueryBuilder + { + return $this->createQueryBuilder('f') + ->leftJoin('f.bar', 'bar') + ->leftJoin('bar.baz', 'baz') + ->orWhere('f.name like :query') + ->orWhere('f.email like :query') + ->orWhere('bar.name like :query') + ->orWhere('baz.name like :query') + ->setParameter('query', '%'.str_replace('%', '\%', $criteria->query).'%') + ; + } } ``` @@ -446,11 +470,11 @@ use Ttskch\PaginatorBundle\Paginator; public function index(FooRepository $fooRepository, Paginator $paginator): Response { $paginator->initialize( - \Closure::fromCallable([$fooRepository, 'sliceByCriteria']), - \Closure::fromCallable([$fooRepository, 'countByCriteria']), - // or if PHP >= 8.1 - // $fooRepository->sliceByCriteria(...), - // $fooRepository->countByCriteria(...), + $fooRepository->sliceByCriteria(...), + $fooRepository->countByCriteria(...), + // or if PHP < 8.1 + // \Closure::fromCallable([$fooRepository, 'sliceByCriteria']), + // \Closure::fromCallable([$fooRepository, 'countByCriteria']), new FooCriteria('f.id') ); From 672594039e72b5cfeac55e7b2d084070c519542f Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Wed, 27 Dec 2023 12:41:56 +0900 Subject: [PATCH 4/7] =?UTF-8?q?chore:=20=F0=9F=A4=96=20remove=20unnecessar?= =?UTF-8?q?y=20dev-dependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 5 +---- tests/Functional/WebTestCase.php | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/composer.json b/composer.json index cecb824..128adfa 100644 --- a/composer.json +++ b/composer.json @@ -4,8 +4,6 @@ "keywords": ["symfony", "pager", "pagination", "paginator", "sortable", "customizable", "searchable"], "type": "symfony-bundle", "license": "MIT", - "minimum-stability": "dev", - "prefer-stable": true, "autoload": { "psr-4": { "Ttskch\\PaginatorBundle\\": "src/" @@ -34,8 +32,7 @@ "symfony/http-kernel": "^5.0|^6.0|^7.0", "symfony/phpunit-bridge": "^7.0", "symfony/twig-bundle": "^5.0|^6.0|^7.0", - "symfony/yaml": "^5.0|^6.0|^7.0", - "t4web/composer-lock-parser": "dev-master" + "symfony/yaml": "^5.0|^6.0|^7.0" }, "config": { "allow-plugins": { diff --git a/tests/Functional/WebTestCase.php b/tests/Functional/WebTestCase.php index 0c667ae..1d45ab3 100644 --- a/tests/Functional/WebTestCase.php +++ b/tests/Functional/WebTestCase.php @@ -4,7 +4,6 @@ namespace Ttskch\PaginatorBundle\Tests\Functional; -use ComposerLockParser\ComposerInfo; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; /** @@ -27,16 +26,22 @@ protected static function getKernelClass(): string private static function getFrameworkBundleVersionId(): int { - $composerInfo = new ComposerInfo(__DIR__.'/../../composer.lock'); - $package = $composerInfo->getPackages()->getByName('symfony/framework-bundle'); - $version = ltrim($package->getVersion(), 'v'); + /** @var array{packages-dev: array} $lock */ + $lock = json_decode(strval(file_get_contents(__DIR__.'/../../composer.lock')), true, flags: JSON_THROW_ON_ERROR); + foreach ($lock['packages-dev'] as $package) { + if ('symfony/framework-bundle' === $package['name']) { + $version = ltrim($package['version'], 'v'); - if (false === preg_match('/^\d+\.\d+\.\d+$/', $version)) { - throw new \RuntimeException('Only can test with stable version of "symfony/framework-bundle".'); - } + if (false === preg_match('/^\d+\.\d+\.\d+$/', $version)) { + throw new \RuntimeException('Only can test with stable version of "symfony/framework-bundle".'); + } + + [$major, $minor, $patch] = explode('.', $version); - [$major, $minor, $patch] = explode('.', $version); + return intval(sprintf('%d%02d%02d', $major, $minor, $patch)); + } + } - return intval(sprintf('%d%02d%02d', $major, $minor, $patch)); + throw new \RuntimeException('"symfony/framework-bundle" is not installed.'); } } From c1b093d25f7bbb1deea071d424434418596b2899 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Wed, 27 Dec 2023 15:26:48 +0900 Subject: [PATCH 5/7] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20fix=20php-cs-f?= =?UTF-8?q?ixer=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Functional/TestKernelForFrameworkLowerThan50100.php | 2 +- tests/Functional/TestKernelForFrameworkLowerThan50400.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Functional/TestKernelForFrameworkLowerThan50100.php b/tests/Functional/TestKernelForFrameworkLowerThan50100.php index ba0d3e3..5f4ca0c 100644 --- a/tests/Functional/TestKernelForFrameworkLowerThan50100.php +++ b/tests/Functional/TestKernelForFrameworkLowerThan50100.php @@ -14,7 +14,7 @@ use Ttskch\PaginatorBundle\TtskchPaginatorBundle; /** - * @see \Ttskch\PaginatorBundle\Tests\Functional\WebTestCase::getKernelClass() + * @see WebTestCase::getKernelClass() * @see https://zenn.dev/ttskch/articles/f9701ccf95d7c7 * @see https://symfony.com/doc/current/configuration/micro_kernel_trait.html */ diff --git a/tests/Functional/TestKernelForFrameworkLowerThan50400.php b/tests/Functional/TestKernelForFrameworkLowerThan50400.php index 617da82..004c4f0 100644 --- a/tests/Functional/TestKernelForFrameworkLowerThan50400.php +++ b/tests/Functional/TestKernelForFrameworkLowerThan50400.php @@ -13,7 +13,7 @@ use Ttskch\PaginatorBundle\TtskchPaginatorBundle; /** - * @see \Ttskch\PaginatorBundle\Tests\Functional\WebTestCase::getKernelClass() + * @see WebTestCase::getKernelClass() * @see https://zenn.dev/ttskch/articles/f9701ccf95d7c7 * @see https://symfony.com/doc/current/configuration/micro_kernel_trait.html */ From e4be765fcf596007267cba0b19c5049400700e43 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Tue, 6 Feb 2024 12:53:18 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20enable=20to=20contro?= =?UTF-8?q?l=20fetchJoinCollection=20argument=20for=20Doctrine=20Paginator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Slicer/Doctrine/ORM/QueryBuilderSlicer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Slicer/Doctrine/ORM/QueryBuilderSlicer.php b/src/Slicer/Doctrine/ORM/QueryBuilderSlicer.php index dd34e61..8ef91ac 100644 --- a/src/Slicer/Doctrine/ORM/QueryBuilderSlicer.php +++ b/src/Slicer/Doctrine/ORM/QueryBuilderSlicer.php @@ -33,13 +33,13 @@ public function __construct( /** * @return \Traversable */ - public function slice(CriteriaInterface $criteria): \Traversable + public function slice(CriteriaInterface $criteria, bool $fetchJoinCollection = true): \Traversable { $this->sortByCriteria($criteria, $this->alreadyJoined); // @see https://stackoverflow.com/questions/50199102/setmaxresults-does-not-works-fine-when-doctrine-query-has-join/50203939#answer-50203939 /** @var Paginator $paginator */ - $paginator = new Paginator($this->qb, true); + $paginator = new Paginator($this->qb, $fetchJoinCollection); $paginator->getQuery() ->setFirstResult($criteria->getLimit() * ($criteria->getPage() - 1)) From 66086fd43a8c83537f09c6e6d96df6f9fb17d125 Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Tue, 6 Feb 2024 13:05:43 +0900 Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20fix=20cs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Exception/UninitializedCriteriaException.php | 2 +- src/Exception/UninitializedPaginatorException.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Exception/UninitializedCriteriaException.php b/src/Exception/UninitializedCriteriaException.php index d22e0eb..3ab79b5 100644 --- a/src/Exception/UninitializedCriteriaException.php +++ b/src/Exception/UninitializedCriteriaException.php @@ -8,7 +8,7 @@ class UninitializedCriteriaException extends \LogicException { - public function __construct(CriteriaInterface $criteria, int $code = 0, \Throwable $previous = null) + public function __construct(CriteriaInterface $criteria, int $code = 0, ?\Throwable $previous = null) { parent::__construct(sprintf('The class "%s" must not be used before initialization.', $criteria::class), $code, $previous); } diff --git a/src/Exception/UninitializedPaginatorException.php b/src/Exception/UninitializedPaginatorException.php index 22b5cda..562f212 100644 --- a/src/Exception/UninitializedPaginatorException.php +++ b/src/Exception/UninitializedPaginatorException.php @@ -8,7 +8,7 @@ class UninitializedPaginatorException extends \LogicException { - public function __construct(int $code = 0, \Throwable $previous = null) + public function __construct(int $code = 0, ?\Throwable $previous = null) { parent::__construct(sprintf('The class "%s" must not be used before initialization.', Paginator::class), $code, $previous); }
{{ ttskch_paginator_sortable('id') }}{{ ttskch_paginator_sortable('name') }}{{ ttskch_paginator_sortable('email') }}{{ ttskch_paginator_sortable('id', 'Id') }}{{ ttskch_paginator_sortable('name', 'Name') }}{{ ttskch_paginator_sortable('email', 'Email') }}