diff --git a/app/helpers/Recodex/RecodexApiHelper.php b/app/helpers/Recodex/RecodexApiHelper.php index 6057ee9..e83da5b 100644 --- a/app/helpers/Recodex/RecodexApiHelper.php +++ b/app/helpers/Recodex/RecodexApiHelper.php @@ -503,4 +503,18 @@ public function createTermGroup(string $instanceId, string $parentGroupId, strin return null; } + + /** + * Set or unset archived flag of a group. + * @param string $groupId ReCodEx ID of a group which is being updated + * @param bool $archived true to set archived flag, false to unset + */ + public function setGroupArchivedFlag(string $groupId, bool $archived): void + { + Debugger::log( + "ReCodEx::setGroupArchivedFlag('$groupId', " . ($archived ? 'true' : 'false') . ")", + Debugger::INFO + ); + $this->post("groups/$groupId/archived", [], ['value' => $archived]); + } } diff --git a/app/presenters/GroupsPresenter.php b/app/presenters/GroupsPresenter.php index deff7c0..4fd9590 100644 --- a/app/presenters/GroupsPresenter.php +++ b/app/presenters/GroupsPresenter.php @@ -5,6 +5,7 @@ use App\Exceptions\BadRequestException; use App\Exceptions\ForbiddenRequestException; use App\Exceptions\NotFoundException; +use App\Exceptions\RecodexApiException; use App\Helpers\RecodexGroup; use App\Model\Entity\SisScheduleEvent; use App\Model\Repository\SisScheduleEvents; @@ -401,4 +402,35 @@ public function actionRemoveAttribute(string $id) $this->recodexApi->removeAttribute($id, $key, $value); $this->sendSuccessResponse("OK"); } + + public function checkSetArchived() + { + if (!$this->groupAcl->canSetArchived()) { + throw new ForbiddenRequestException("You do not have permissions to set archived flag."); + } + } + + /** + * Proxy to ReCodEx that sets or unsets the 'archived' flag of a group. + * @POST + * @Param(type="query", name="id", validation="string:1..", + * description="ReCodEx ID of a group for which the archived flag will be set or unset.") + * @Param(type="post", name="value", validation="bool", + * description="Boolean value indicating whether the group should be archived or not.") + */ + public function actionSetArchived(string $id) + { + $archived = $this->getRequest()->getPost('value'); + if (!is_bool($archived)) { + throw new BadRequestException("Missing or invalid 'value' parameter (expected boolean)."); + } + + try { + $this->recodexApi->setGroupArchivedFlag($id, $archived); + } catch (RecodexApiException $e) { + throw new BadRequestException("Failed to set archived flag for group $id: " . $e->getMessage()); + } + + $this->sendSuccessResponse("OK"); + } } diff --git a/app/router/RouterFactory.php b/app/router/RouterFactory.php index 96f1fb0..b69682a 100644 --- a/app/router/RouterFactory.php +++ b/app/router/RouterFactory.php @@ -83,6 +83,7 @@ private static function createGroupsRoutes(string $prefix): RouteList $router[] = new PostRoute("$prefix//add-attribute", "Groups:addAttribute"); $router[] = new PostRoute("$prefix//remove-attribute", "Groups:removeAttribute"); $router[] = new PostRoute("$prefix//create-term/", "Groups:createTerm"); + $router[] = new PostRoute("$prefix//archived", "Groups:setArchived"); return $router; } } diff --git a/app/security/ACL/IGroupPermissions.php b/app/security/ACL/IGroupPermissions.php index 8bd7a96..8c34c49 100644 --- a/app/security/ACL/IGroupPermissions.php +++ b/app/security/ACL/IGroupPermissions.php @@ -13,4 +13,6 @@ public function canViewTeacher(): bool; public function canEditRawAttributes(): bool; public function canCreateTermGroup(): bool; + + public function canSetArchived(): bool; } diff --git a/tests/Presenters/GroupsPresenter.phpt b/tests/Presenters/GroupsPresenter.phpt index 63356cd..7462e15 100644 --- a/tests/Presenters/GroupsPresenter.phpt +++ b/tests/Presenters/GroupsPresenter.phpt @@ -1114,6 +1114,30 @@ class TestGroupsPresenter extends Tester\TestCase ); }, BadRequestException::class); } + + public function testSetArchivedFlag() + { + PresenterTestHelper::loginDefaultAdmin($this->container); + + $this->client->shouldReceive("post")->with('groups/g1/archived', Mockery::any()) + ->andReturn(new Response(200, ['Content-Type' => 'application/json'], json_encode([ + 'success' => true, + 'code' => 200, + 'payload' => [ + self::group('g1', null, 'Root', true, ['foo' => ['bar', 'baz']]), + ] + ]))); + + $payload = PresenterTestHelper::performPresenterRequest( + $this->presenter, + 'Groups', + 'POST', + ['action' => 'setArchived', 'id' => 'g1'], + ['value' => true] + ); + + Assert::equal("OK", $payload); + } } Debugger::$logDirectory = __DIR__ . '/../../log';