From 21a0e7551ae4e39a55fe02b48876183a69edbeef Mon Sep 17 00:00:00 2001 From: Julian Date: Mon, 8 Jan 2024 17:30:25 +0100 Subject: [PATCH] Add sort order to project search --- config.yaml | 2 +- lib/Api/APIKeysApi.php | 12 ++-- lib/Api/PermissionsApi.php | 20 +++--- lib/Api/ProjectsApi.php | 43 ++++++++----- lib/Client/HangarAPIClient.php | 3 +- .../ProjectSearch/ProjectSearchOptions.php | 61 +++++++++++++++---- .../ProjectSearch/ProjectSortOrder.php | 9 +++ lib/Configuration.php | 4 +- test/Client/ClientTest.php | 46 ++++++++++++++ 9 files changed, 155 insertions(+), 45 deletions(-) create mode 100644 lib/Client/Options/ProjectSearch/ProjectSortOrder.php diff --git a/config.yaml b/config.yaml index d519245..de0afc2 100644 --- a/config.yaml +++ b/config.yaml @@ -1,5 +1,5 @@ invokerPackage: Aternos\HangarApi -artifactVersion: 3.1.1 +artifactVersion: 3.2.0 generatorName: php outputDir: . sourceFolder: src diff --git a/lib/Api/APIKeysApi.php b/lib/Api/APIKeysApi.php index 4754160..b358052 100644 --- a/lib/Api/APIKeysApi.php +++ b/lib/Api/APIKeysApi.php @@ -198,7 +198,7 @@ public function createKeyWithHttpInfo($create_api_key_form, string $contentType } switch($statusCode) { - case 201: + case 403: if ('string' === '\SplFileObject') { $content = $response->getBody(); //stream goes to serializer } else { @@ -225,7 +225,7 @@ public function createKeyWithHttpInfo($create_api_key_form, string $contentType $response->getStatusCode(), $response->getHeaders() ]; - case 403: + case 401: if ('string' === '\SplFileObject') { $content = $response->getBody(); //stream goes to serializer } else { @@ -252,7 +252,7 @@ public function createKeyWithHttpInfo($create_api_key_form, string $contentType $response->getStatusCode(), $response->getHeaders() ]; - case 401: + case 201: if ('string' === '\SplFileObject') { $content = $response->getBody(); //stream goes to serializer } else { @@ -311,7 +311,7 @@ public function createKeyWithHttpInfo($create_api_key_form, string $contentType } catch (ApiException $e) { switch ($e->getCode()) { - case 201: + case 403: $data = ObjectSerializer::deserialize( $e->getResponseBody(), 'string', @@ -319,7 +319,7 @@ public function createKeyWithHttpInfo($create_api_key_form, string $contentType ); $e->setResponseObject($data); break; - case 403: + case 401: $data = ObjectSerializer::deserialize( $e->getResponseBody(), 'string', @@ -327,7 +327,7 @@ public function createKeyWithHttpInfo($create_api_key_form, string $contentType ); $e->setResponseObject($data); break; - case 401: + case 201: $data = ObjectSerializer::deserialize( $e->getResponseBody(), 'string', diff --git a/lib/Api/PermissionsApi.php b/lib/Api/PermissionsApi.php index a529f37..563c0e5 100644 --- a/lib/Api/PermissionsApi.php +++ b/lib/Api/PermissionsApi.php @@ -552,8 +552,8 @@ public function hasAllRequest($permissions, $slug = null, $organization = null, * Checks whether you have at least one of the provided permissions * * @param \Aternos\HangarApi\Model\NamedPermission[] $permissions The permissions to check (required) - * @param string $slug The slug of the project to check permissions in. Must not be used together with `organizationName` (optional) - * @param string $organization The organization to check permissions in. Must not be used together with `projectOwner` and `projectSlug` (optional) + * @param string $slug The slug of the project to check permissions in. Must not be used together with `organization` (optional) + * @param string $organization The organization to check permissions in. Must not be used together with `slug` (optional) * @param string $contentType The value for the Content-Type header. Check self::contentTypes['hasAny'] to see the possible values for this operation * * @throws \Aternos\HangarApi\ApiException on non-2xx response or if the response body is not in the expected format @@ -572,8 +572,8 @@ public function hasAny($permissions, $slug = null, $organization = null, string * Checks whether you have at least one of the provided permissions * * @param \Aternos\HangarApi\Model\NamedPermission[] $permissions The permissions to check (required) - * @param string $slug The slug of the project to check permissions in. Must not be used together with `organizationName` (optional) - * @param string $organization The organization to check permissions in. Must not be used together with `projectOwner` and `projectSlug` (optional) + * @param string $slug The slug of the project to check permissions in. Must not be used together with `organization` (optional) + * @param string $organization The organization to check permissions in. Must not be used together with `slug` (optional) * @param string $contentType The value for the Content-Type header. Check self::contentTypes['hasAny'] to see the possible values for this operation * * @throws \Aternos\HangarApi\ApiException on non-2xx response or if the response body is not in the expected format @@ -768,8 +768,8 @@ public function hasAnyWithHttpInfo($permissions, $slug = null, $organization = n * Checks whether you have at least one of the provided permissions * * @param \Aternos\HangarApi\Model\NamedPermission[] $permissions The permissions to check (required) - * @param string $slug The slug of the project to check permissions in. Must not be used together with `organizationName` (optional) - * @param string $organization The organization to check permissions in. Must not be used together with `projectOwner` and `projectSlug` (optional) + * @param string $slug The slug of the project to check permissions in. Must not be used together with `organization` (optional) + * @param string $organization The organization to check permissions in. Must not be used together with `slug` (optional) * @param string $contentType The value for the Content-Type header. Check self::contentTypes['hasAny'] to see the possible values for this operation * * @throws \InvalidArgumentException @@ -791,8 +791,8 @@ function ($response) { * Checks whether you have at least one of the provided permissions * * @param \Aternos\HangarApi\Model\NamedPermission[] $permissions The permissions to check (required) - * @param string $slug The slug of the project to check permissions in. Must not be used together with `organizationName` (optional) - * @param string $organization The organization to check permissions in. Must not be used together with `projectOwner` and `projectSlug` (optional) + * @param string $slug The slug of the project to check permissions in. Must not be used together with `organization` (optional) + * @param string $organization The organization to check permissions in. Must not be used together with `slug` (optional) * @param string $contentType The value for the Content-Type header. Check self::contentTypes['hasAny'] to see the possible values for this operation * * @throws \InvalidArgumentException @@ -843,8 +843,8 @@ function ($exception) { * Create request for operation 'hasAny' * * @param \Aternos\HangarApi\Model\NamedPermission[] $permissions The permissions to check (required) - * @param string $slug The slug of the project to check permissions in. Must not be used together with `organizationName` (optional) - * @param string $organization The organization to check permissions in. Must not be used together with `projectOwner` and `projectSlug` (optional) + * @param string $slug The slug of the project to check permissions in. Must not be used together with `organization` (optional) + * @param string $organization The organization to check permissions in. Must not be used together with `slug` (optional) * @param string $contentType The value for the Content-Type header. Check self::contentTypes['hasAny'] to see the possible values for this operation * * @throws \InvalidArgumentException diff --git a/lib/Api/ProjectsApi.php b/lib/Api/ProjectsApi.php index 09b826d..e1b6904 100644 --- a/lib/Api/ProjectsApi.php +++ b/lib/Api/ProjectsApi.php @@ -1735,7 +1735,8 @@ public function getProjectWatchersRequest($slug, $pagination, string $contentTyp * @param string $category A category to filter for (optional) * @param string $platform A platform to filter for (optional) * @param string $owner The author of the project (optional) - * @param string $q The query to use when searching (optional) + * @param string $q Deprecated: Use 'query' instead (optional) (deprecated) + * @param string $query The query to use when searching (optional) * @param string $license A license to filter for (optional) * @param string $version A Minecraft version to filter for (optional) * @param string $tag A tag to filter for (optional) @@ -1745,9 +1746,9 @@ public function getProjectWatchersRequest($slug, $pagination, string $contentTyp * @throws \InvalidArgumentException * @return \Aternos\HangarApi\Model\PaginatedResultProject|\Aternos\HangarApi\Model\PaginatedResultProject|\Aternos\HangarApi\Model\PaginatedResultProject */ - public function getProjects($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) + public function getProjects($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $query = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) { - list($response) = $this->getProjectsWithHttpInfo($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $license, $version, $tag, $contentType); + list($response) = $this->getProjectsWithHttpInfo($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $query, $license, $version, $tag, $contentType); return $response; } @@ -1762,7 +1763,8 @@ public function getProjects($pagination, $prioritize_exact_match = true, $sort = * @param string $category A category to filter for (optional) * @param string $platform A platform to filter for (optional) * @param string $owner The author of the project (optional) - * @param string $q The query to use when searching (optional) + * @param string $q Deprecated: Use 'query' instead (optional) (deprecated) + * @param string $query The query to use when searching (optional) * @param string $license A license to filter for (optional) * @param string $version A Minecraft version to filter for (optional) * @param string $tag A tag to filter for (optional) @@ -1772,9 +1774,9 @@ public function getProjects($pagination, $prioritize_exact_match = true, $sort = * @throws \InvalidArgumentException * @return array of \Aternos\HangarApi\Model\PaginatedResultProject|\Aternos\HangarApi\Model\PaginatedResultProject|\Aternos\HangarApi\Model\PaginatedResultProject, HTTP status code, HTTP response headers (array of strings) */ - public function getProjectsWithHttpInfo($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) + public function getProjectsWithHttpInfo($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $query = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) { - $request = $this->getProjectsRequest($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $license, $version, $tag, $contentType); + $request = $this->getProjectsRequest($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $query, $license, $version, $tag, $contentType); try { $options = $this->createHttpClientOption(); @@ -1965,7 +1967,8 @@ public function getProjectsWithHttpInfo($pagination, $prioritize_exact_match = t * @param string $category A category to filter for (optional) * @param string $platform A platform to filter for (optional) * @param string $owner The author of the project (optional) - * @param string $q The query to use when searching (optional) + * @param string $q Deprecated: Use 'query' instead (optional) (deprecated) + * @param string $query The query to use when searching (optional) * @param string $license A license to filter for (optional) * @param string $version A Minecraft version to filter for (optional) * @param string $tag A tag to filter for (optional) @@ -1974,9 +1977,9 @@ public function getProjectsWithHttpInfo($pagination, $prioritize_exact_match = t * @throws \InvalidArgumentException * @return \GuzzleHttp\Promise\PromiseInterface */ - public function getProjectsAsync($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) + public function getProjectsAsync($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $query = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) { - return $this->getProjectsAsyncWithHttpInfo($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $license, $version, $tag, $contentType) + return $this->getProjectsAsyncWithHttpInfo($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $query, $license, $version, $tag, $contentType) ->then( function ($response) { return $response[0]; @@ -1995,7 +1998,8 @@ function ($response) { * @param string $category A category to filter for (optional) * @param string $platform A platform to filter for (optional) * @param string $owner The author of the project (optional) - * @param string $q The query to use when searching (optional) + * @param string $q Deprecated: Use 'query' instead (optional) (deprecated) + * @param string $query The query to use when searching (optional) * @param string $license A license to filter for (optional) * @param string $version A Minecraft version to filter for (optional) * @param string $tag A tag to filter for (optional) @@ -2004,10 +2008,10 @@ function ($response) { * @throws \InvalidArgumentException * @return \GuzzleHttp\Promise\PromiseInterface */ - public function getProjectsAsyncWithHttpInfo($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) + public function getProjectsAsyncWithHttpInfo($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $query = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) { $returnType = '\Aternos\HangarApi\Model\PaginatedResultProject'; - $request = $this->getProjectsRequest($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $license, $version, $tag, $contentType); + $request = $this->getProjectsRequest($pagination, $prioritize_exact_match, $sort, $category, $platform, $owner, $q, $query, $license, $version, $tag, $contentType); return $this->client ->sendAsync($request, $this->createHttpClientOption()) @@ -2054,7 +2058,8 @@ function ($exception) { * @param string $category A category to filter for (optional) * @param string $platform A platform to filter for (optional) * @param string $owner The author of the project (optional) - * @param string $q The query to use when searching (optional) + * @param string $q Deprecated: Use 'query' instead (optional) (deprecated) + * @param string $query The query to use when searching (optional) * @param string $license A license to filter for (optional) * @param string $version A Minecraft version to filter for (optional) * @param string $tag A tag to filter for (optional) @@ -2063,7 +2068,7 @@ function ($exception) { * @throws \InvalidArgumentException * @return \GuzzleHttp\Psr7\Request */ - public function getProjectsRequest($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) + public function getProjectsRequest($pagination, $prioritize_exact_match = true, $sort = null, $category = null, $platform = null, $owner = null, $q = null, $query = null, $license = null, $version = null, $tag = null, string $contentType = self::contentTypes['getProjects'][0]) { // verify the required parameter 'pagination' is set @@ -2083,6 +2088,7 @@ public function getProjectsRequest($pagination, $prioritize_exact_match = true, + $resourcePath = '/api/v1/projects'; $formParams = []; $queryParams = []; @@ -2154,6 +2160,15 @@ public function getProjectsRequest($pagination, $prioritize_exact_match = true, false // required ) ?? []); // query params + $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( + $query, + 'query', // param base name + 'string', // openApiType + 'form', // style + true, // explode + false // required + ) ?? []); + // query params $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue( $license, 'license', // param base name diff --git a/lib/Client/HangarAPIClient.php b/lib/Client/HangarAPIClient.php index 7a5e814..d0cc5a7 100644 --- a/lib/Client/HangarAPIClient.php +++ b/lib/Client/HangarAPIClient.php @@ -189,10 +189,11 @@ public function getProjects(ProjectSearchOptions $options = new ProjectSearchOpt $result = $this->projects->getProjects($options->getPagination(), $options->isPrioritizeExactMatch(), - $options->getSortField()?->value, + $options->getSortParameter(), $options->getCategory()?->value, $options->getPlatform()?->value, $options->getOwner(), + null, $options->getQuery(), $options->getLicense(), $options->getVersion(), diff --git a/lib/Client/Options/ProjectSearch/ProjectSearchOptions.php b/lib/Client/Options/ProjectSearch/ProjectSearchOptions.php index e7ab553..2394f83 100644 --- a/lib/Client/Options/ProjectSearch/ProjectSearchOptions.php +++ b/lib/Client/Options/ProjectSearch/ProjectSearchOptions.php @@ -17,6 +17,7 @@ class ProjectSearchOptions protected RequestPagination $pagination; protected bool $prioritizeExactMatch = true; protected ?ProjectSortField $sortField = null; + protected ProjectSortOrder $sortOrder = ProjectSortOrder::ASC; protected ?ProjectCategory $category = null; protected ?Platform $platform = null; protected ?string $owner = null; @@ -60,7 +61,7 @@ public function getOffset(): int /** * @param int $offset - * @return static + * @return $this */ public function setOffset(int $offset): static { @@ -78,7 +79,7 @@ public function getLimit(): int /** * @param int $limit - * @return static + * @return $this */ public function setLimit(int $limit): static { @@ -96,7 +97,7 @@ public function isPrioritizeExactMatch(): bool /** * @param bool $prioritizeExactMatch - * @return static + * @return $this */ public function setPrioritizeExactMatch(bool $prioritizeExactMatch): static { @@ -114,7 +115,7 @@ public function getSortField(): ?ProjectSortField /** * @param ProjectSortField|null $sort - * @return static + * @return $this */ public function setSortField(?ProjectSortField $sort): static { @@ -122,6 +123,44 @@ public function setSortField(?ProjectSortField $sort): static return $this; } + /** + * @return ProjectSortOrder + */ + public function getSortOrder(): ProjectSortOrder + { + return $this->sortOrder; + } + + /** + * @param ProjectSortOrder $sortOrder + * @return $this + */ + public function setSortOrder(ProjectSortOrder $sortOrder): static + { + $this->sortOrder = $sortOrder; + return $this; + } + + /** + * Get the sort parameter for the API request + * + * Returns the sort field value with a minus sign in front if the sort order is descending. + * If no sort field is set, null is returned. + * @return string|null + */ + public function getSortParameter(): ?string + { + if ($this->sortField === null) { + return null; + } + + if ($this->sortOrder === ProjectSortOrder::DESC) { + return '-' . $this->sortField->value; + } + + return $this->sortField->value; + } + /** * @return ProjectCategory|null */ @@ -132,7 +171,7 @@ public function getCategory(): ?ProjectCategory /** * @param ProjectCategory|null $category - * @return static + * @return $this */ public function setCategory(?ProjectCategory $category): static { @@ -150,7 +189,7 @@ public function getPlatform(): ?Platform /** * @param Platform|null $platform - * @return static + * @return $this */ public function setPlatform(?Platform $platform): static { @@ -168,7 +207,7 @@ public function getOwner(): ?string /** * @param string|null $owner - * @return static + * @return $this */ public function setOwner(?string $owner): static { @@ -186,7 +225,7 @@ public function getQuery(): ?string /** * @param string|null $query - * @return static + * @return $this */ public function setQuery(?string $query): static { @@ -204,7 +243,7 @@ public function getLicense(): ?string /** * @param string|null $license - * @return static + * @return $this */ public function setLicense(?string $license): static { @@ -222,7 +261,7 @@ public function getVersion(): ?string /** * @param string|null $version - * @return static + * @return $this */ public function setVersion(?string $version): static { @@ -240,7 +279,7 @@ public function getTag(): ?string /** * @param string|null $tag - * @return static + * @return $this */ public function setTag(?string $tag): static { diff --git a/lib/Client/Options/ProjectSearch/ProjectSortOrder.php b/lib/Client/Options/ProjectSearch/ProjectSortOrder.php new file mode 100644 index 0000000..ced6091 --- /dev/null +++ b/lib/Client/Options/ProjectSearch/ProjectSortOrder.php @@ -0,0 +1,9 @@ +getTempFolderPath() . PHP_EOL; return $report; diff --git a/test/Client/ClientTest.php b/test/Client/ClientTest.php index c02d85f..b587423 100644 --- a/test/Client/ClientTest.php +++ b/test/Client/ClientTest.php @@ -7,6 +7,8 @@ use Aternos\HangarApi\Client\List\ResultList; use Aternos\HangarApi\Client\Options\ProjectCategory; use Aternos\HangarApi\Client\Options\ProjectSearch\ProjectSearchOptions; +use Aternos\HangarApi\Client\Options\ProjectSearch\ProjectSortField; +use Aternos\HangarApi\Client\Options\ProjectSearch\ProjectSortOrder; use Aternos\HangarApi\Model\ProjectNamespace; use Aternos\HangarApi\Model\RequestPagination; use PHPUnit\Framework\TestCase; @@ -229,6 +231,50 @@ public function testGetProjectsByOwner() $this->assertNull($projectList); } + /** + * Test case for getProjects sorting by the shortest duration since the last update + * @throws ApiException + */ + public function testGetRecentlyUpdatedProjects() + { + $options = new ProjectSearchOptions(); + $options->setLimit(10); + $options->setSortField(ProjectSortField::UPDATED); + $options->setSortOrder(ProjectSortOrder::DESC); + $projectList = $this->apiClient->getProjects($options); + $this->assertValidResultList($projectList); + + $lastUpdated = time(); + foreach ($projectList as $project) { + $this->assertValidProject($project); + $updated = $project->getData()->getLastUpdated()->getTimestamp(); + $this->assertLessThanOrEqual($lastUpdated, $updated); + $lastUpdated = $updated; + } + } + + /** + * Test case for getProjects sorting by the longest duration since the last update + * @throws ApiException + */ + public function testGetNotRecentlyUpdatedProjects() + { + $options = new ProjectSearchOptions(); + $options->setLimit(10); + $options->setSortField(ProjectSortField::UPDATED); + $options->setSortOrder(ProjectSortOrder::ASC); + $projectList = $this->apiClient->getProjects($options); + $this->assertValidResultList($projectList); + + $lastUpdated = 0; + foreach ($projectList as $project) { + $this->assertValidProject($project); + $updated = $project->getData()->getLastUpdated()->getTimestamp(); + $this->assertGreaterThanOrEqual($lastUpdated, $updated); + $lastUpdated = $updated; + } + } + /** * Test case for getProject * @throws ApiException