From a12dcc9192e4827b226815c6edb921e616aca601 Mon Sep 17 00:00:00 2001 From: Joshua Gigg Date: Sun, 6 Sep 2020 15:14:07 +0100 Subject: [PATCH 1/5] Package List Search Signed-off-by: Joshua Gigg --- src/Query/User/PackageQuery.php | 5 +++ .../User/PackageQuery/DbalPackageQuery.php | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/Query/User/PackageQuery.php b/src/Query/User/PackageQuery.php index 0fea4d70..9da651dc 100644 --- a/src/Query/User/PackageQuery.php +++ b/src/Query/User/PackageQuery.php @@ -22,6 +22,11 @@ public function findAll(string $organizationId, Filter $filter): array; public function count(string $organizationId, Filter $filter): int; + /** + * @return Package[] + */ + public function find(string $organizationId, string $searchString, int $limit = 20, int $offset = 0): array; + /** * @return PackageName[] */ diff --git a/src/Query/User/PackageQuery/DbalPackageQuery.php b/src/Query/User/PackageQuery/DbalPackageQuery.php index c1dcaa22..a33c495b 100644 --- a/src/Query/User/PackageQuery/DbalPackageQuery.php +++ b/src/Query/User/PackageQuery/DbalPackageQuery.php @@ -73,6 +73,42 @@ function (array $data): Package { ); } + /** + * @return Package[] + */ + public function find(string $organizationId, string $searchString, int $limit = 20, int $offset = 0): array + { + return array_map(function (array $data): Package { + return $this->hydratePackage($data); + }, $this->connection->fetchAll( + 'SELECT + id, + organization_id, + type, + repository_url, + name, + latest_released_version, + latest_release_date, + description, + last_sync_at, + last_sync_error, + webhook_created_at, + last_scan_date, + last_scan_status, + last_scan_result + FROM organization_package + WHERE organization_id = :organization_id + AND name LIKE :search + GROUP BY id + ORDER BY name ASC + LIMIT :limit OFFSET :offset', [ + ':organization_id' => $organizationId, + ':search' => '%' . $searchString . '%', + ':limit' => $limit, + ':offset' => $offset, + ])); + } + /** * @return PackageName[] */ From f53a0a74ba4b4e4fbe4aff57dbfcb7de14642dbd Mon Sep 17 00:00:00 2001 From: Joshua Gigg Date: Tue, 8 Sep 2020 13:29:04 +0100 Subject: [PATCH 2/5] Replace all pagination with Filter classes Continuation of #259 --- .../Admin/OrganizationController.php | 6 ++- src/Controller/Admin/ProxyController.php | 6 ++- src/Controller/Admin/UserController.php | 6 ++- .../Organization/MembersController.php | 11 +++- src/Controller/OrganizationController.php | 17 ++++-- src/Query/Admin/OrganizationQuery.php | 3 +- .../DbalOrganizationQuery.php | 7 +-- src/Query/Admin/UserQuery.php | 3 +- src/Query/Admin/UserQuery/DbalUserQuery.php | 7 +-- src/Query/Filter.php | 30 ++--------- src/Query/User/OrganizationQuery.php | 7 +-- .../DbalOrganizationQuery.php | 19 +++---- src/Query/User/PackageQuery.php | 6 +-- .../User/PackageQuery/DbalPackageQuery.php | 13 +++-- src/Query/User/PackageQuery/Filter.php | 52 +++++++++++++++++++ templates/component/pagination.html.twig | 14 ++--- templates/organization/packages.html.twig | 2 +- .../AcceptInvitationHandlerTest.php | 5 +- .../Organization/GenerateTokenHandlerTest.php | 3 +- .../Organization/InviteUserHandlerTest.php | 3 +- .../Security/ScanPackageHandlerTest.php | 2 +- .../Security/SendScanResultHandlerTest.php | 2 +- 22 files changed, 146 insertions(+), 78 deletions(-) create mode 100644 src/Query/User/PackageQuery/Filter.php diff --git a/src/Controller/Admin/OrganizationController.php b/src/Controller/Admin/OrganizationController.php index 0b74055a..338ff6e3 100644 --- a/src/Controller/Admin/OrganizationController.php +++ b/src/Controller/Admin/OrganizationController.php @@ -6,6 +6,7 @@ use Buddy\Repman\Message\Organization\RemoveOrganization; use Buddy\Repman\Query\Admin\OrganizationQuery; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Organization; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; @@ -26,9 +27,12 @@ public function __construct(OrganizationQuery $organizationQuery) */ public function list(Request $request): Response { + $filter = Filter::fromRequest($request); + return $this->render('admin/organization/list.html.twig', [ - 'organizations' => $this->organizationQuery->findAll(20, (int) $request->get('offset', 0)), + 'organizations' => $this->organizationQuery->findAll($filter), 'count' => $this->organizationQuery->count(), + 'filter' => $filter, ]); } diff --git a/src/Controller/Admin/ProxyController.php b/src/Controller/Admin/ProxyController.php index 4cbce81b..11b40cab 100644 --- a/src/Controller/Admin/ProxyController.php +++ b/src/Controller/Admin/ProxyController.php @@ -6,6 +6,7 @@ use Buddy\Repman\Message\Proxy\RemoveDist; use Buddy\Repman\Query\Admin\Proxy\DownloadsQuery; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Service\Proxy; use Buddy\Repman\Service\Proxy\ProxyRegister; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -30,15 +31,18 @@ public function __construct(ProxyRegister $register, DownloadsQuery $downloadsQu */ public function list(string $proxy, Request $request): Response { + $filter = Filter::fromRequest($request); + $packages = $this->register->getByHost($proxy)->syncedPackages(); $count = $packages->length(); - $packages = $packages->drop((int) $request->get('offset', 0))->take(20)->iterator()->toArray(); + $packages = $packages->drop($filter->getOffset())->take($filter->getLimit())->iterator()->toArray(); return $this->render('admin/proxy/dist.html.twig', [ 'proxy' => $proxy, 'packages' => $packages, 'downloads' => $this->downloadsQuery->findByNames($packages), 'count' => $count, + 'filter' => $filter, ]); } diff --git a/src/Controller/Admin/UserController.php b/src/Controller/Admin/UserController.php index ab0f1d67..e96de931 100644 --- a/src/Controller/Admin/UserController.php +++ b/src/Controller/Admin/UserController.php @@ -10,6 +10,7 @@ use Buddy\Repman\Message\User\EnableUser; use Buddy\Repman\Query\Admin\Model\User; use Buddy\Repman\Query\Admin\UserQuery; +use Buddy\Repman\Query\Filter; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -29,9 +30,12 @@ public function __construct(UserQuery $userQuery) */ public function list(Request $request): Response { + $filter = Filter::fromRequest($request); + return $this->render('admin/user/list.html.twig', [ - 'users' => $this->userQuery->findAll(20, (int) $request->get('offset', 0)), + 'users' => $this->userQuery->findAll($filter), 'count' => $this->userQuery->count(), + 'filter' => $filter, ]); } diff --git a/src/Controller/Organization/MembersController.php b/src/Controller/Organization/MembersController.php index 6e1ee9a8..88aa798e 100644 --- a/src/Controller/Organization/MembersController.php +++ b/src/Controller/Organization/MembersController.php @@ -11,6 +11,7 @@ use Buddy\Repman\Message\Organization\Member\InviteUser; use Buddy\Repman\Message\Organization\Member\RemoveInvitation; use Buddy\Repman\Message\Organization\Member\RemoveMember; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Organization; use Buddy\Repman\Query\User\Model\Organization\Member; use Buddy\Repman\Query\User\OrganizationQuery; @@ -39,11 +40,14 @@ public function __construct(OrganizationQuery $organizations, TokenStorageInterf */ public function listMembers(Organization $organization, Request $request): Response { + $filter = Filter::fromRequest($request); + return $this->render('organization/member/members.html.twig', [ 'organization' => $organization, - 'members' => $this->organizations->findAllMembers($organization->id(), 20, (int) $request->get('offset', 0)), + 'members' => $this->organizations->findAllMembers($organization->id(), $filter), 'count' => $this->organizations->membersCount($organization->id()), 'invitations' => $this->organizations->invitationsCount($organization->id()), + 'filter' => $filter, ]); } @@ -102,10 +106,13 @@ public function invite(Organization $organization, Request $request): Response */ public function listInvitations(Organization $organization, Request $request): Response { + $filter = Filter::fromRequest($request); + return $this->render('organization/member/invitations.html.twig', [ 'organization' => $organization, - 'invitations' => $this->organizations->findAllInvitations($organization->id(), 20, (int) $request->get('offset', 0)), + 'invitations' => $this->organizations->findAllInvitations($organization->id(), $filter), 'count' => $this->organizations->invitationsCount($organization->id()), + 'filter' => $filter, ]); } diff --git a/src/Controller/OrganizationController.php b/src/Controller/OrganizationController.php index 5178059a..272928ea 100644 --- a/src/Controller/OrganizationController.php +++ b/src/Controller/OrganizationController.php @@ -24,12 +24,12 @@ use Buddy\Repman\Message\Organization\RemoveToken; use Buddy\Repman\Message\Organization\SynchronizePackage; use Buddy\Repman\Message\Security\ScanPackage; -use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs\Day; use Buddy\Repman\Query\User\Model\Organization; use Buddy\Repman\Query\User\Model\Package; use Buddy\Repman\Query\User\OrganizationQuery; use Buddy\Repman\Query\User\PackageQuery; +use Buddy\Repman\Query\User\PackageQuery\Filter; use Buddy\Repman\Security\Model\User; use Buddy\Repman\Service\ExceptionHandler; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; @@ -121,11 +121,14 @@ public function removePackage(Organization $organization, Package $package): Res */ public function packageDetails(Organization $organization, Package $package, Request $request): Response { + $filter = \Buddy\Repman\Query\Filter::fromRequest($request); + return $this->render('organization/package/details.html.twig', [ 'organization' => $organization, 'package' => $package, + 'filter' => $filter, 'count' => $this->packageQuery->versionCount($package->id()), - 'versions' => $this->packageQuery->getVersions($package->id(), 20, (int) $request->get('offset', 0)), + 'versions' => $this->packageQuery->getVersions($package->id(), $filter), ]); } @@ -217,10 +220,13 @@ public function generateToken(Organization $organization, Request $request): Res */ public function tokens(Organization $organization, Request $request): Response { + $filter = \Buddy\Repman\Query\Filter::fromRequest($request); + return $this->render('organization/tokens.html.twig', [ - 'tokens' => $this->organizationQuery->findAllTokens($organization->id(), 20, (int) $request->get('offset', 0)), + 'tokens' => $this->organizationQuery->findAllTokens($organization->id(), $filter), 'count' => $this->organizationQuery->tokenCount($organization->id()), 'organization' => $organization, + 'filter' => $filter, ]); } @@ -338,10 +344,13 @@ public function scanPackage(Organization $organization, Package $package): Respo */ public function packageScanResults(Organization $organization, Package $package, Request $request): Response { + $filter = \Buddy\Repman\Query\Filter::fromRequest($request); + return $this->render('organization/package/scanResults.html.twig', [ 'organization' => $organization, 'package' => $package, - 'results' => $this->packageQuery->getScanResults($package->id(), 20, (int) $request->get('offset', 0)), + 'filter' => $filter, + 'results' => $this->packageQuery->getScanResults($package->id(), $filter), 'count' => $this->packageQuery->getScanResultsCount($package->id()), ]); } diff --git a/src/Query/Admin/OrganizationQuery.php b/src/Query/Admin/OrganizationQuery.php index 6cc4c475..acc6c345 100644 --- a/src/Query/Admin/OrganizationQuery.php +++ b/src/Query/Admin/OrganizationQuery.php @@ -5,6 +5,7 @@ namespace Buddy\Repman\Query\Admin; use Buddy\Repman\Query\Admin\Model\Organization; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; interface OrganizationQuery @@ -12,7 +13,7 @@ interface OrganizationQuery /** * @return Organization[] */ - public function findAll(int $limit = 20, int $offset = 0): array; + public function findAll(Filter $filter): array; public function count(): int; diff --git a/src/Query/Admin/OrganizationQuery/DbalOrganizationQuery.php b/src/Query/Admin/OrganizationQuery/DbalOrganizationQuery.php index b1861b01..4aa895ac 100644 --- a/src/Query/Admin/OrganizationQuery/DbalOrganizationQuery.php +++ b/src/Query/Admin/OrganizationQuery/DbalOrganizationQuery.php @@ -6,6 +6,7 @@ use Buddy\Repman\Query\Admin\Model\Organization; use Buddy\Repman\Query\Admin\OrganizationQuery; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; use Doctrine\DBAL\Connection; @@ -21,7 +22,7 @@ public function __construct(Connection $connection) /** * @return Organization[] */ - public function findAll(int $limit = 20, int $offset = 0): array + public function findAll(Filter $filter): array { return array_map(function (array $data): Organization { return $this->hydrateOrganization($data); @@ -33,8 +34,8 @@ public function findAll(int $limit = 20, int $offset = 0): array ORDER BY o.alias LIMIT :limit OFFSET :offset', [ - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ]) ); } diff --git a/src/Query/Admin/UserQuery.php b/src/Query/Admin/UserQuery.php index 8990e3a9..3b91886b 100644 --- a/src/Query/Admin/UserQuery.php +++ b/src/Query/Admin/UserQuery.php @@ -5,6 +5,7 @@ namespace Buddy\Repman\Query\Admin; use Buddy\Repman\Query\Admin\Model\User; +use Buddy\Repman\Query\Filter; use Munus\Control\Option; interface UserQuery @@ -12,7 +13,7 @@ interface UserQuery /** * @return User[] */ - public function findAll(int $limit = 20, int $offset = 0): array; + public function findAll(Filter $filter): array; /** * @return Option diff --git a/src/Query/Admin/UserQuery/DbalUserQuery.php b/src/Query/Admin/UserQuery/DbalUserQuery.php index 1af64267..c4964029 100644 --- a/src/Query/Admin/UserQuery/DbalUserQuery.php +++ b/src/Query/Admin/UserQuery/DbalUserQuery.php @@ -6,6 +6,7 @@ use Buddy\Repman\Query\Admin\Model\User; use Buddy\Repman\Query\Admin\UserQuery; +use Buddy\Repman\Query\Filter; use Doctrine\DBAL\Connection; use Munus\Control\Option; @@ -18,13 +19,13 @@ public function __construct(Connection $connection) $this->connection = $connection; } - public function findAll(int $limit = 20, int $offset = 0): array + public function findAll(Filter $filter): array { return array_map(function (array $data): User { return $this->hydrateUser($data); }, $this->connection->fetchAll('SELECT id, email, status, roles FROM "user" ORDER BY email LIMIT :limit OFFSET :offset', [ - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ])); } diff --git a/src/Query/Filter.php b/src/Query/Filter.php index 43b75280..227dbc0a 100644 --- a/src/Query/Filter.php +++ b/src/Query/Filter.php @@ -6,13 +6,12 @@ use Symfony\Component\HttpFoundation\Request; -final class Filter +class Filter { private int $offset = 0; private int $limit = 20; - private ?string $searchTerm; - public function __construct(int $offset = 0, int $limit = 20, ?string $searchTerm = null) + public function __construct(int $offset = 0, int $limit = 20) { if ($offset >= 0) { $this->offset = $offset; @@ -25,8 +24,6 @@ public function __construct(int $offset = 0, int $limit = 20, ?string $searchTer if ($this->limit > 100) { $this->limit = 100; } - - $this->searchTerm = $searchTerm; } public function getOffset(): int @@ -39,39 +36,22 @@ public function getLimit(): int return $this->limit; } - public function getSearchTerm(): ?string - { - return $this->searchTerm; - } - - public function hasSearchTerm(): bool - { - return $this->searchTerm !== null; - } - /** * @return array */ public function getQueryStringParams(): array { - $params = [ + return [ 'offset' => (string) $this->getOffset(), 'limit' => (string) $this->getLimit(), ]; - - if ($this->hasSearchTerm()) { - $params['search'] = (string) $this->getSearchTerm(); - } - - return $params; } - public static function fromRequest(Request $request): Filter + public static function fromRequest(Request $request): self { return new self( (int) $request->get('offset', 0), - (int) $request->get('limit', 20), - $request->get('search', null) + (int) $request->get('limit', 20) ); } } diff --git a/src/Query/User/OrganizationQuery.php b/src/Query/User/OrganizationQuery.php index 5ba0297f..711e405a 100644 --- a/src/Query/User/OrganizationQuery.php +++ b/src/Query/User/OrganizationQuery.php @@ -4,6 +4,7 @@ namespace Buddy\Repman\Query\User; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; use Buddy\Repman\Query\User\Model\Organization; use Buddy\Repman\Query\User\Model\Organization\Invitation; @@ -26,7 +27,7 @@ public function getByInvitation(string $token, string $email): Option; /** * @return Token[] */ - public function findAllTokens(string $organizationId, int $limit = 20, int $offset = 0): array; + public function findAllTokens(string $organizationId, Filter $filter): array; public function tokenCount(string $organizationId): int; @@ -35,7 +36,7 @@ public function getInstalls(string $organizationId, int $lastDays = 30): Install /** * @return Member[] */ - public function findAllMembers(string $organizationId, int $limit = 20, int $offset = 0): array; + public function findAllMembers(string $organizationId, Filter $filter): array; public function membersCount(string $organizationId): int; @@ -44,7 +45,7 @@ public function isMember(string $organizationId, string $email): bool; /** * @return Invitation[] */ - public function findAllInvitations(string $organizationId, int $limit = 20, int $offset = 0): array; + public function findAllInvitations(string $organizationId, Filter $filter): array; public function invitationsCount(string $organizationId): int; diff --git a/src/Query/User/OrganizationQuery/DbalOrganizationQuery.php b/src/Query/User/OrganizationQuery/DbalOrganizationQuery.php index 3c9934f4..60253d03 100644 --- a/src/Query/User/OrganizationQuery/DbalOrganizationQuery.php +++ b/src/Query/User/OrganizationQuery/DbalOrganizationQuery.php @@ -4,6 +4,7 @@ namespace Buddy\Repman\Query\User\OrganizationQuery; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; use Buddy\Repman\Query\User\Model\Organization; use Buddy\Repman\Query\User\Model\Organization\Invitation; @@ -62,7 +63,7 @@ public function getByInvitation(string $token, string $email): Option /** * @return Token[] */ - public function findAllTokens(string $organizationId, int $limit = 20, int $offset = 0): array + public function findAllTokens(string $organizationId, Filter $filter): array { return array_map(function (array $data): Token { return new Token( @@ -78,8 +79,8 @@ public function findAllTokens(string $organizationId, int $limit = 20, int $offs ORDER BY UPPER(name) ASC LIMIT :limit OFFSET :offset', [ ':id' => $organizationId, - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ])); } @@ -109,7 +110,7 @@ public function getInstalls(string $organizationId, int $lastDays = 30): Install ); } - public function findAllInvitations(string $organizationId, int $limit = 20, int $offset = 0): array + public function findAllInvitations(string $organizationId, Filter $filter): array { return array_map(function (array $row): Invitation { return new Invitation( @@ -124,8 +125,8 @@ public function findAllInvitations(string $organizationId, int $limit = 20, int ORDER BY email ASC LIMIT :limit OFFSET :offset', [ ':id' => $organizationId, - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ])); } @@ -142,7 +143,7 @@ public function invitationsCount(string $organizationId): int /** * @return Member[] */ - public function findAllMembers(string $organizationId, int $limit = 20, int $offset = 0): array + public function findAllMembers(string $organizationId, Filter $filter): array { return array_map(function (array $row): Member { return new Member( @@ -158,8 +159,8 @@ public function findAllMembers(string $organizationId, int $limit = 20, int $off ORDER BY u.email ASC LIMIT :limit OFFSET :offset', [ ':id' => $organizationId, - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ])); } diff --git a/src/Query/User/PackageQuery.php b/src/Query/User/PackageQuery.php index 9da651dc..bab4311d 100644 --- a/src/Query/User/PackageQuery.php +++ b/src/Query/User/PackageQuery.php @@ -4,13 +4,13 @@ namespace Buddy\Repman\Query\User; -use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; use Buddy\Repman\Query\User\Model\Package; use Buddy\Repman\Query\User\Model\PackageName; use Buddy\Repman\Query\User\Model\ScanResult; use Buddy\Repman\Query\User\Model\Version; use Buddy\Repman\Query\User\Model\WebhookRequest; +use Buddy\Repman\Query\User\PackageQuery\Filter; use Munus\Control\Option; interface PackageQuery @@ -42,7 +42,7 @@ public function versionCount(string $packageId): int; /** * @return Version[] */ - public function getVersions(string $packageId, int $limit = 20, int $offset = 0): array; + public function getVersions(string $packageId, \Buddy\Repman\Query\Filter $filter): array; public function getInstalls(string $packageId, int $lastDays = 30, ?string $version = null): Installs; @@ -59,7 +59,7 @@ public function findRecentWebhookRequests(string $packageId): array; /** * @return ScanResult[] */ - public function getScanResults(string $packageId, int $limit = 20, int $offset = 0): array; + public function getScanResults(string $packageId, \Buddy\Repman\Query\Filter $filter): array; public function getScanResultsCount(string $packageId): int; diff --git a/src/Query/User/PackageQuery/DbalPackageQuery.php b/src/Query/User/PackageQuery/DbalPackageQuery.php index a33c495b..add1e1e6 100644 --- a/src/Query/User/PackageQuery/DbalPackageQuery.php +++ b/src/Query/User/PackageQuery/DbalPackageQuery.php @@ -5,7 +5,6 @@ namespace Buddy\Repman\Query\User\PackageQuery; use Buddy\Repman\Entity\Organization\Package\Version as VersionEntity; -use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; use Buddy\Repman\Query\User\Model\Package; use Buddy\Repman\Query\User\Model\PackageName; @@ -180,7 +179,7 @@ public function versionCount(string $packageId): int /** * @return Version[] */ - public function getVersions(string $packageId, int $limit = 20, int $offset = 0): array + public function getVersions(string $packageId, \Buddy\Repman\Query\Filter $filter): array { return array_map(function (array $data): Version { return new Version( @@ -201,8 +200,8 @@ public function getVersions(string $packageId, int $limit = 20, int $offset = 0) ORDER BY date DESC LIMIT :limit OFFSET :offset', [ ':package_id' => $packageId, - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ])); } @@ -252,7 +251,7 @@ public function findRecentWebhookRequests(string $packageId): array /** * @return ScanResult[] */ - public function getScanResults(string $packageId, int $limit = 20, int $offset = 0): array + public function getScanResults(string $packageId, \Buddy\Repman\Query\Filter $filter): array { return array_map(function (array $data): ScanResult { return new ScanResult( @@ -272,8 +271,8 @@ public function getScanResults(string $packageId, int $limit = 20, int $offset = ORDER BY date DESC LIMIT :limit OFFSET :offset', [ ':package_id' => $packageId, - ':limit' => $limit, - ':offset' => $offset, + ':limit' => $filter->getLimit(), + ':offset' => $filter->getOffset(), ])); } diff --git a/src/Query/User/PackageQuery/Filter.php b/src/Query/User/PackageQuery/Filter.php new file mode 100644 index 00000000..55977a62 --- /dev/null +++ b/src/Query/User/PackageQuery/Filter.php @@ -0,0 +1,52 @@ +searchTerm = $searchTerm; + } + + public function getSearchTerm(): ?string + { + return $this->searchTerm; + } + + public function hasSearchTerm(): bool + { + return $this->searchTerm !== null; + } + + public function getQueryStringParams(): array + { + $params = \Buddy\Repman\Query\Filter::getQueryStringParams(); + + if ($this->hasSearchTerm()) { + $params['search'] = (string) $this->getSearchTerm(); + } + + return $params; + } + + public static function fromRequest(Request $request): self + { + return new self( + (int) $request->get('offset', 0), + (int) $request->get('limit', 20), + $request->get('search', null) + ); + } +} diff --git a/templates/component/pagination.html.twig b/templates/component/pagination.html.twig index a31f0c85..a15099cf 100644 --- a/templates/component/pagination.html.twig +++ b/templates/component/pagination.html.twig @@ -1,14 +1,14 @@ -{% set offset = offset | default(20) %} -{% set currentOffset = currentOffset | default(app.request.query.get('offset', 0)) %} +{% set limit = filter.limit %} +{% set currentOffset = filter.offset %} {% if count > 0 and currentOffset <= count %}
-

Showing {{ currentOffset + 1 }} to {{ min(currentOffset + offset, count) }} of {{ count }} entries

- {% if count > offset %} +

Showing {{ currentOffset + 1 }} to {{ min(currentOffset + limit, count) }} of {{ count }} entries

+ {% if count > limit %}
    - {% for i in 0..(count/offset) %} -
  • - {{ i+1 }} + {% for i in 0..(count/limit) %} +
  • + {{ i+1 }}
  • {% endfor %}
diff --git a/templates/organization/packages.html.twig b/templates/organization/packages.html.twig index aa7225e6..44c3deea 100644 --- a/templates/organization/packages.html.twig +++ b/templates/organization/packages.html.twig @@ -168,7 +168,7 @@ {% endfor %} - {% include 'component/pagination.html.twig' with {'currentOffset': filter.offset, 'path_name': 'organization_packages', 'path_params': filter.getQueryStringParams()|merge({'organization': organization.alias}), offset: filter.limit} %} + {% include 'component/pagination.html.twig' with {'path_name': 'organization_packages', 'path_params': {'organization': organization.alias}} %}
{% endblock %} diff --git a/tests/Integration/MessageHandler/Organization/AcceptInvitationHandlerTest.php b/tests/Integration/MessageHandler/Organization/AcceptInvitationHandlerTest.php index 857384e8..6e7302c0 100644 --- a/tests/Integration/MessageHandler/Organization/AcceptInvitationHandlerTest.php +++ b/tests/Integration/MessageHandler/Organization/AcceptInvitationHandlerTest.php @@ -6,6 +6,7 @@ use Buddy\Repman\Entity\Organization\Member as DomainMember; use Buddy\Repman\Message\Organization\Member\AcceptInvitation; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Organization; use Buddy\Repman\Query\User\Model\Organization\Member; use Buddy\Repman\Query\User\OrganizationQuery\DbalOrganizationQuery; @@ -24,7 +25,7 @@ public function testAcceptInvitation(): void /** @var DbalOrganizationQuery $query */ $query = $this->container()->get(DbalOrganizationQuery::class); self::assertEquals(0, $query->invitationsCount($organizationId)); - self::assertEquals([], $query->findAllInvitations($organizationId)); + self::assertEquals([], $query->findAllInvitations($organizationId, new Filter())); /** @var Organization $organization */ $organization = $query->getByAlias('repman')->get(); @@ -35,6 +36,6 @@ public function testAcceptInvitation(): void self::assertEquals([ new Member($ownerId, $ownerEmail, DomainMember::ROLE_OWNER), new Member($invitedId, $invitedEmail, DomainMember::ROLE_MEMBER), - ], $query->findAllMembers($organizationId)); + ], $query->findAllMembers($organizationId, new Filter())); } } diff --git a/tests/Integration/MessageHandler/Organization/GenerateTokenHandlerTest.php b/tests/Integration/MessageHandler/Organization/GenerateTokenHandlerTest.php index c67c15bd..1c41b7be 100644 --- a/tests/Integration/MessageHandler/Organization/GenerateTokenHandlerTest.php +++ b/tests/Integration/MessageHandler/Organization/GenerateTokenHandlerTest.php @@ -7,6 +7,7 @@ use Buddy\Repman\Message\Organization\CreateOrganization; use Buddy\Repman\Message\Organization\GenerateToken; use Buddy\Repman\Message\User\CreateUser; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\OrganizationQuery\DbalOrganizationQuery; use Buddy\Repman\Service\Organization\TokenGenerator; use Buddy\Repman\Tests\Integration\IntegrationTestCase; @@ -22,7 +23,7 @@ public function testAddToken(): void // when $this->dispatchMessage(new GenerateToken($orgId, 'prod')); // then - $tokens = $this->container()->get(DbalOrganizationQuery::class)->findAllTokens($orgId); + $tokens = $this->container()->get(DbalOrganizationQuery::class)->findAllTokens($orgId, new Filter()); self::assertCount(1, $tokens); self::assertEquals('random-string', $tokens[0]->value()); self::assertEquals('prod', $tokens[0]->name()); diff --git a/tests/Integration/MessageHandler/Organization/InviteUserHandlerTest.php b/tests/Integration/MessageHandler/Organization/InviteUserHandlerTest.php index db890944..f8003bec 100644 --- a/tests/Integration/MessageHandler/Organization/InviteUserHandlerTest.php +++ b/tests/Integration/MessageHandler/Organization/InviteUserHandlerTest.php @@ -6,6 +6,7 @@ use Buddy\Repman\Entity\Organization\Member; use Buddy\Repman\Message\Organization\Member\InviteUser; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Organization\Invitation; use Buddy\Repman\Query\User\OrganizationQuery\DbalOrganizationQuery; use Buddy\Repman\Tests\Integration\IntegrationTestCase; @@ -21,6 +22,6 @@ public function testInviteUser(): void /** @var DbalOrganizationQuery $query */ $query = $this->container()->get(DbalOrganizationQuery::class); self::assertEquals(1, $query->invitationsCount($organizationId)); - self::assertEquals([new Invitation('some@repman.io', Member::ROLE_MEMBER, $token)], $query->findAllInvitations($organizationId)); + self::assertEquals([new Invitation('some@repman.io', Member::ROLE_MEMBER, $token)], $query->findAllInvitations($organizationId, new Filter())); } } diff --git a/tests/Integration/MessageHandler/Security/ScanPackageHandlerTest.php b/tests/Integration/MessageHandler/Security/ScanPackageHandlerTest.php index 658acf5e..14bcb69d 100644 --- a/tests/Integration/MessageHandler/Security/ScanPackageHandlerTest.php +++ b/tests/Integration/MessageHandler/Security/ScanPackageHandlerTest.php @@ -6,8 +6,8 @@ use Buddy\Repman\Message\Security\ScanPackage; use Buddy\Repman\MessageHandler\Security\ScanPackageHandler; -use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\PackageQuery; +use Buddy\Repman\Query\User\PackageQuery\Filter; use Buddy\Repman\Tests\Integration\IntegrationTestCase; final class ScanPackageHandlerTest extends IntegrationTestCase diff --git a/tests/Integration/MessageHandler/Security/SendScanResultHandlerTest.php b/tests/Integration/MessageHandler/Security/SendScanResultHandlerTest.php index 8d35999d..83d84716 100644 --- a/tests/Integration/MessageHandler/Security/SendScanResultHandlerTest.php +++ b/tests/Integration/MessageHandler/Security/SendScanResultHandlerTest.php @@ -6,8 +6,8 @@ use Buddy\Repman\Message\Security\SendScanResult; use Buddy\Repman\MessageHandler\Security\SendScanResultHandler; -use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\PackageQuery; +use Buddy\Repman\Query\User\PackageQuery\Filter; use Buddy\Repman\Tests\Integration\IntegrationTestCase; final class SendScanResultHandlerTest extends IntegrationTestCase From db19628d6b6f1d12efbc0df9b74b6b1a4978f327 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kondas Date: Wed, 9 Sep 2020 08:03:00 +0200 Subject: [PATCH 3/5] Fix code style --- src/Query/User/PackageQuery/DbalPackageQuery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Query/User/PackageQuery/DbalPackageQuery.php b/src/Query/User/PackageQuery/DbalPackageQuery.php index add1e1e6..2838c7dd 100644 --- a/src/Query/User/PackageQuery/DbalPackageQuery.php +++ b/src/Query/User/PackageQuery/DbalPackageQuery.php @@ -102,7 +102,7 @@ public function find(string $organizationId, string $searchString, int $limit = ORDER BY name ASC LIMIT :limit OFFSET :offset', [ ':organization_id' => $organizationId, - ':search' => '%' . $searchString . '%', + ':search' => '%'.$searchString.'%', ':limit' => $limit, ':offset' => $offset, ])); From 303cce0e2453e05d75d3b2b9ee3089fd8c63eb6d Mon Sep 17 00:00:00 2001 From: Joshua Gigg Date: Wed, 9 Sep 2020 08:21:27 +0100 Subject: [PATCH 4/5] Fix suggestions & PHPStan --- src/Controller/OrganizationController.php | 13 +++---- .../PrivatePackageDownloadFixtures.php | 3 +- src/DataFixtures/TokenFixtures.php | 3 +- src/Query/User/PackageQuery.php | 16 ++++----- .../User/PackageQuery/DbalPackageQuery.php | 36 ------------------- src/Query/User/PackageQuery/Filter.php | 5 +-- 6 files changed, 18 insertions(+), 58 deletions(-) diff --git a/src/Controller/OrganizationController.php b/src/Controller/OrganizationController.php index 272928ea..c2d2f173 100644 --- a/src/Controller/OrganizationController.php +++ b/src/Controller/OrganizationController.php @@ -24,12 +24,13 @@ use Buddy\Repman\Message\Organization\RemoveToken; use Buddy\Repman\Message\Organization\SynchronizePackage; use Buddy\Repman\Message\Security\ScanPackage; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs\Day; use Buddy\Repman\Query\User\Model\Organization; use Buddy\Repman\Query\User\Model\Package; use Buddy\Repman\Query\User\OrganizationQuery; use Buddy\Repman\Query\User\PackageQuery; -use Buddy\Repman\Query\User\PackageQuery\Filter; +use Buddy\Repman\Query\User\PackageQuery\Filter as PackageFilter; use Buddy\Repman\Security\Model\User; use Buddy\Repman\Service\ExceptionHandler; use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; @@ -69,7 +70,7 @@ public function overview(Organization $organization): Response */ public function packages(Organization $organization, Request $request): Response { - $filter = Filter::fromRequest($request); + $filter = PackageFilter::fromRequest($request); $count = $this->packageQuery->count($organization->id(), $filter); @@ -121,7 +122,7 @@ public function removePackage(Organization $organization, Package $package): Res */ public function packageDetails(Organization $organization, Package $package, Request $request): Response { - $filter = \Buddy\Repman\Query\Filter::fromRequest($request); + $filter = Filter::fromRequest($request); return $this->render('organization/package/details.html.twig', [ 'organization' => $organization, @@ -220,7 +221,7 @@ public function generateToken(Organization $organization, Request $request): Res */ public function tokens(Organization $organization, Request $request): Response { - $filter = \Buddy\Repman\Query\Filter::fromRequest($request); + $filter = Filter::fromRequest($request); return $this->render('organization/tokens.html.twig', [ 'tokens' => $this->organizationQuery->findAllTokens($organization->id(), $filter), @@ -344,7 +345,7 @@ public function scanPackage(Organization $organization, Package $package): Respo */ public function packageScanResults(Organization $organization, Package $package, Request $request): Response { - $filter = \Buddy\Repman\Query\Filter::fromRequest($request); + $filter = Filter::fromRequest($request); return $this->render('organization/package/scanResults.html.twig', [ 'organization' => $organization, @@ -382,6 +383,6 @@ private function hasNoPackages(Organization $organization): bool return $user instanceof User && $organization->isOwner($user->id()) && - $this->packageQuery->count($organization->id(), (new Filter())) === 0; + $this->packageQuery->count($organization->id(), new PackageFilter()) === 0; } } diff --git a/src/DataFixtures/PrivatePackageDownloadFixtures.php b/src/DataFixtures/PrivatePackageDownloadFixtures.php index 1acc0321..ea1d8909 100644 --- a/src/DataFixtures/PrivatePackageDownloadFixtures.php +++ b/src/DataFixtures/PrivatePackageDownloadFixtures.php @@ -6,6 +6,7 @@ use Buddy\Repman\Entity\Organization\Package\Download; use Buddy\Repman\Query\Admin\OrganizationQuery; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\PackageName; use Buddy\Repman\Query\User\PackageQuery; use Doctrine\Bundle\FixturesBundle\Fixture; @@ -39,7 +40,7 @@ public function __construct(OrganizationQuery $organizations, PackageQuery $pack public function load(ObjectManager $manager): void { $this->em->getConfiguration()->setSQLLogger(null); - foreach ($this->organizations->findAll(9999) as $organization) { + foreach ($this->organizations->findAll(new Filter(0, 100)) as $organization) { foreach ($this->packages->getAllNames($organization->id()) as $package) { $this->loadDownloads($package); } diff --git a/src/DataFixtures/TokenFixtures.php b/src/DataFixtures/TokenFixtures.php index 9a9dd29c..3ace02e5 100644 --- a/src/DataFixtures/TokenFixtures.php +++ b/src/DataFixtures/TokenFixtures.php @@ -8,6 +8,7 @@ use Buddy\Repman\Message\Organization\GenerateToken; use Buddy\Repman\Query\Admin\Model\Organization; use Buddy\Repman\Query\Admin\OrganizationQuery; +use Buddy\Repman\Query\Filter; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\ORM\EntityManagerInterface; use Doctrine\Persistence\ObjectManager; @@ -44,7 +45,7 @@ public function load(ObjectManager $manager): void $progress->start(); $this->em->getConfiguration()->setSQLLogger(null); - foreach ($this->organizations->findAll(9999) as $organization) { + foreach ($this->organizations->findAll(new Filter(0, 100)) as $organization) { $this->generateTokens($organization); $progress->advance(); } diff --git a/src/Query/User/PackageQuery.php b/src/Query/User/PackageQuery.php index bab4311d..916a9344 100644 --- a/src/Query/User/PackageQuery.php +++ b/src/Query/User/PackageQuery.php @@ -4,13 +4,14 @@ namespace Buddy\Repman\Query\User; +use Buddy\Repman\Query\Filter; use Buddy\Repman\Query\User\Model\Installs; use Buddy\Repman\Query\User\Model\Package; use Buddy\Repman\Query\User\Model\PackageName; use Buddy\Repman\Query\User\Model\ScanResult; use Buddy\Repman\Query\User\Model\Version; use Buddy\Repman\Query\User\Model\WebhookRequest; -use Buddy\Repman\Query\User\PackageQuery\Filter; +use Buddy\Repman\Query\User\PackageQuery\Filter as PackageFilter; use Munus\Control\Option; interface PackageQuery @@ -18,14 +19,9 @@ interface PackageQuery /** * @return Package[] */ - public function findAll(string $organizationId, Filter $filter): array; + public function findAll(string $organizationId, PackageFilter $filter): array; - public function count(string $organizationId, Filter $filter): int; - - /** - * @return Package[] - */ - public function find(string $organizationId, string $searchString, int $limit = 20, int $offset = 0): array; + public function count(string $organizationId, PackageFilter $filter): int; /** * @return PackageName[] @@ -42,7 +38,7 @@ public function versionCount(string $packageId): int; /** * @return Version[] */ - public function getVersions(string $packageId, \Buddy\Repman\Query\Filter $filter): array; + public function getVersions(string $packageId, Filter $filter): array; public function getInstalls(string $packageId, int $lastDays = 30, ?string $version = null): Installs; @@ -59,7 +55,7 @@ public function findRecentWebhookRequests(string $packageId): array; /** * @return ScanResult[] */ - public function getScanResults(string $packageId, \Buddy\Repman\Query\Filter $filter): array; + public function getScanResults(string $packageId, Filter $filter): array; public function getScanResultsCount(string $packageId): int; diff --git a/src/Query/User/PackageQuery/DbalPackageQuery.php b/src/Query/User/PackageQuery/DbalPackageQuery.php index 2838c7dd..da33c9ea 100644 --- a/src/Query/User/PackageQuery/DbalPackageQuery.php +++ b/src/Query/User/PackageQuery/DbalPackageQuery.php @@ -72,42 +72,6 @@ function (array $data): Package { ); } - /** - * @return Package[] - */ - public function find(string $organizationId, string $searchString, int $limit = 20, int $offset = 0): array - { - return array_map(function (array $data): Package { - return $this->hydratePackage($data); - }, $this->connection->fetchAll( - 'SELECT - id, - organization_id, - type, - repository_url, - name, - latest_released_version, - latest_release_date, - description, - last_sync_at, - last_sync_error, - webhook_created_at, - last_scan_date, - last_scan_status, - last_scan_result - FROM organization_package - WHERE organization_id = :organization_id - AND name LIKE :search - GROUP BY id - ORDER BY name ASC - LIMIT :limit OFFSET :offset', [ - ':organization_id' => $organizationId, - ':search' => '%'.$searchString.'%', - ':limit' => $limit, - ':offset' => $offset, - ])); - } - /** * @return PackageName[] */ diff --git a/src/Query/User/PackageQuery/Filter.php b/src/Query/User/PackageQuery/Filter.php index 55977a62..259909d4 100644 --- a/src/Query/User/PackageQuery/Filter.php +++ b/src/Query/User/PackageQuery/Filter.php @@ -1,9 +1,6 @@ hasSearchTerm()) { $params['search'] = (string) $this->getSearchTerm(); From c732f0c67b814708c3bf3af4a2bd196c058cb746 Mon Sep 17 00:00:00 2001 From: Joshua Gigg Date: Wed, 9 Sep 2020 08:49:57 +0100 Subject: [PATCH 5/5] Import Filter as an Alias --- src/Query/User/PackageQuery/DbalPackageQuery.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Query/User/PackageQuery/DbalPackageQuery.php b/src/Query/User/PackageQuery/DbalPackageQuery.php index da33c9ea..be616432 100644 --- a/src/Query/User/PackageQuery/DbalPackageQuery.php +++ b/src/Query/User/PackageQuery/DbalPackageQuery.php @@ -5,6 +5,7 @@ namespace Buddy\Repman\Query\User\PackageQuery; use Buddy\Repman\Entity\Organization\Package\Version as VersionEntity; +use Buddy\Repman\Query\Filter as BaseFilter; use Buddy\Repman\Query\User\Model\Installs; use Buddy\Repman\Query\User\Model\Package; use Buddy\Repman\Query\User\Model\PackageName; @@ -143,7 +144,7 @@ public function versionCount(string $packageId): int /** * @return Version[] */ - public function getVersions(string $packageId, \Buddy\Repman\Query\Filter $filter): array + public function getVersions(string $packageId, BaseFilter $filter): array { return array_map(function (array $data): Version { return new Version( @@ -215,7 +216,7 @@ public function findRecentWebhookRequests(string $packageId): array /** * @return ScanResult[] */ - public function getScanResults(string $packageId, \Buddy\Repman\Query\Filter $filter): array + public function getScanResults(string $packageId, BaseFilter $filter): array { return array_map(function (array $data): ScanResult { return new ScanResult(