From 25b6bf055629d66b06b064a8cf09080f164e2c6d Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+studip@gmail.com> Date: Tue, 14 Nov 2023 14:11:05 +0000 Subject: [PATCH] add faculty and sub-institutes relationship to institutes route, fixes #3458 Closes #3458 Merge request studip/studip!2359 --- .../Routes/Institutes/InstitutesIndex.php | 34 +++++- .../Routes/Institutes/InstitutesShow.php | 2 + lib/classes/JsonApi/Schemas/Institute.php | 105 +++++++++++++++--- 3 files changed, 124 insertions(+), 17 deletions(-) diff --git a/lib/classes/JsonApi/Routes/Institutes/InstitutesIndex.php b/lib/classes/JsonApi/Routes/Institutes/InstitutesIndex.php index d7ef8de3c67..6eef1b63ccd 100644 --- a/lib/classes/JsonApi/Routes/Institutes/InstitutesIndex.php +++ b/lib/classes/JsonApi/Routes/Institutes/InstitutesIndex.php @@ -10,17 +10,45 @@ use JsonApi\Schemas\Institute as InstituteSchema; class InstitutesIndex extends JsonApiController { protected $allowedIncludePaths = [ + InstituteSchema::REL_FACULTY, InstituteSchema::REL_STATUS_GROUPS, + InstituteSchema::REL_SUB_INSTITUTES, ]; + protected $allowedFilteringParameters = ['is-faculty']; + protected $allowedPagingParameters = ['offset', 'limit']; public function __invoke(Request $request, Response $response, $args) { - list($offset, $limit) = $this->getOffsetAndLimit(); - $institutes = \Institute::findBySql('1 ORDER BY Name LIMIT ? OFFSET ?', [$limit, $offset]); - $total = \Institute::countBySql(); + [$offset, $limit] = $this->getOffsetAndLimit(); + + $filters = $this->getFilters(); + + if (!isset($filters['is-faculty'])) { + $condition = '1'; + } elseif ($filters['is-faculty']) { + $condition = 'fakultaets_id = Institut_id'; + } else { + $condition = 'fakultaets_id != Institut_id'; + } + + $institutes = \Institute::findBySql("{$condition} ORDER BY Name LIMIT ? OFFSET ?", [$limit, $offset]); + $total = \Institute::countBySql($condition); return $this->getPaginatedContentResponse($institutes, $total); } + + private function getFilters() + { + $filtering = $this->getQueryParameters()->getFilteringParameters() ?? []; + + $filters = []; + + if (isset($filtering['is-faculty'])) { + $filters['is-faculty'] = (bool) $filtering['is-faculty']; + } + + return $filters; + } } diff --git a/lib/classes/JsonApi/Routes/Institutes/InstitutesShow.php b/lib/classes/JsonApi/Routes/Institutes/InstitutesShow.php index 4847982c2d3..5ef3b5a8d02 100644 --- a/lib/classes/JsonApi/Routes/Institutes/InstitutesShow.php +++ b/lib/classes/JsonApi/Routes/Institutes/InstitutesShow.php @@ -15,7 +15,9 @@ use JsonApi\Schemas\Institute as InstituteSchema; class InstitutesShow extends JsonApiController { protected $allowedIncludePaths = [ + InstituteSchema::REL_FACULTY, InstituteSchema::REL_STATUS_GROUPS, + InstituteSchema::REL_SUB_INSTITUTES, ]; /** diff --git a/lib/classes/JsonApi/Schemas/Institute.php b/lib/classes/JsonApi/Schemas/Institute.php index c1775b1646d..13e061a2d11 100644 --- a/lib/classes/JsonApi/Schemas/Institute.php +++ b/lib/classes/JsonApi/Schemas/Institute.php @@ -10,48 +10,56 @@ class Institute extends SchemaProvider const TYPE = 'institutes'; const REL_BLUBBER = 'blubber-threads'; + const REL_FACULTY = 'faculty'; const REL_FILES = 'file-refs'; const REL_FOLDERS = 'folders'; const REL_MEMBERSHIPS = 'memberships'; const REL_STATUS_GROUPS = 'status-groups'; + const REL_SUB_INSTITUTES = 'sub-institutes'; + /** + * @param \Institute $institute + */ public function getId($institute): ?string { return $institute->id; } + /** + * @param \Institute $institute + */ public function getAttributes($institute, ContextInterface $context): iterable { return [ - 'name' => (string) $institute['Name'], - 'city' => $institute['Plz'], - 'street' => $institute['Strasse'], - 'phone' => $institute['telefon'], - 'fax' => $institute['fax'], - 'url' => $institute['url'], - 'mkdate' => date('c', $institute['mkdate']), - 'chdate' => date('c', $institute['chdate']), + 'name' => (string) $institute->name, + 'city' => $institute->plz, + 'street' => $institute->strasse, + 'phone' => $institute->telefon, + 'fax' => $institute->fax, + 'url' => $institute->url, + 'is-faculty' => $institute->is_fak, + 'mkdate' => date('c', $institute->mkdate), + 'chdate' => date('c', $institute->chdate), ]; } /** + * @param \Institute $resource * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function getRelationships($resource, ContextInterface $context): iterable { $relationships = []; - $filesLink = $this->getRelationshipRelatedLink($resource, self::REL_FILES); $relationships[self::REL_FILES] = [ self::RELATIONSHIP_LINKS => [ - Link::RELATED => $filesLink, + Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FILES), ], ]; - $foldersLink = $this->getRelationshipRelatedLink($resource, self::REL_FOLDERS); $relationships[self::REL_FOLDERS] = [ self::RELATIONSHIP_LINKS => [ - Link::RELATED => $foldersLink, + Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FOLDERS), ], ]; @@ -73,6 +81,60 @@ class Institute extends SchemaProvider $this->shouldInclude($context, self::REL_STATUS_GROUPS) ); + if (!$resource->is_fak) { + $relationships = $this->addFacultyRelationship( + $relationships, + $resource, + $this->shouldInclude($context, self::REL_FACULTY) + ); + } + + $relationships = $this->addSubInstitutesRelationship( + $relationships, + $resource, + $this->shouldInclude($context, self::REL_SUB_INSTITUTES) + ); + + return $relationships; + } + + private function addFacultyRelationship(array $relationships, \Institute $resource, bool $includeData): array + { + $relation = [ + self::RELATIONSHIP_LINKS => [ + Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_FACULTY), + ], + ]; + + if ($includeData) { + $relation[self::RELATIONSHIP_DATA] = $resource->faculty; + } else { + $relation[self::RELATIONSHIP_DATA] = \Institute::build(['id' => $resource->faculty->id]); + } + + $relationships[self::REL_FACULTY] = $relation; + + return $relationships; + } + + private function addSubInstitutesRelationship(array $relationships, \Institute $resource, bool $includeData): array + { + $relation = [ + self::RELATIONSHIP_LINKS => [ + Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_SUB_INSTITUTES), + ], + ]; + + if ($includeData) { + $relation[self::RELATIONSHIP_DATA] = $resource->sub_institutes; + } else { + $relation[self::RELATIONSHIP_DATA] = $resource->sub_institutes->map(function (\Institute $institute): \Institute { + return \Institute::build(['id' => $institute->id]); + }); + } + + $relationships[self::REL_SUB_INSTITUTES] = $relation; + return $relationships; } @@ -86,11 +148,26 @@ class Institute extends SchemaProvider Link::RELATED => $this->getRelationshipRelatedLink($resource, self::REL_STATUS_GROUPS), ] ]; + if ($includeData) { - $related = $resource->status_groups; - $relation[self::RELATIONSHIP_DATA] = $related; + $relation[self::RELATIONSHIP_DATA] = $resource->status_groups; } return array_merge($relationships, [self::REL_STATUS_GROUPS => $relation]); } + + public function hasResourceMeta($resource): bool + { + return true; + } + + /** + * @param \Institute $resource + */ + public function getResourceMeta($resource) + { + return [ + 'sub-institutes-count' => count($resource->sub_institutes), + ]; + } } -- GitLab