diff options
| author | Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de> | 2024-01-23 07:41:52 +0000 |
|---|---|---|
| committer | Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de> | 2024-01-23 07:41:52 +0000 |
| commit | 1728bc517691b3d0dde5ccdf0c0631ff1b855b6d (patch) | |
| tree | f3ad972dc584dc70c4817405d616558cc1a55061 /lib/classes/JsonApi | |
| parent | 9750421a650a4e4980a1286212661a87eb92905b (diff) | |
Courseware Aufgaben erweitern (StEP3286)
Merge request studip/studip!2445
Diffstat (limited to 'lib/classes/JsonApi')
11 files changed, 432 insertions, 64 deletions
diff --git a/lib/classes/JsonApi/RouteMap.php b/lib/classes/JsonApi/RouteMap.php index d4d5bbb..4f44165 100644 --- a/lib/classes/JsonApi/RouteMap.php +++ b/lib/classes/JsonApi/RouteMap.php @@ -501,6 +501,13 @@ class RouteMap $group->get('/courseware-task-groups/{id}', Routes\Courseware\TaskGroupsShow::class); $group->post('/courseware-task-groups', Routes\Courseware\TaskGroupsCreate::class); + $group->patch('/courseware-task-groups/{id}', Routes\Courseware\TaskGroupsUpdate::class); + $group->delete('/courseware-task-groups/{id}', Routes\Courseware\TaskGroupsDelete::class); + $this->addRelationship( + $group, + '/courseware-task-groups/{id}/relationships/solvers', + Routes\Courseware\Rel\SolversOfTaskGroup::class + ); $group->get('/courseware-task-feedback/{id}', Routes\Courseware\TaskFeedbackShow::class); $group->post('/courseware-task-feedback', Routes\Courseware\TaskFeedbackCreate::class); diff --git a/lib/classes/JsonApi/Routes/Courseware/Authority.php b/lib/classes/JsonApi/Routes/Courseware/Authority.php index 88eb3df..2acf83e 100644 --- a/lib/classes/JsonApi/Routes/Courseware/Authority.php +++ b/lib/classes/JsonApi/Routes/Courseware/Authority.php @@ -23,7 +23,13 @@ use User; use Course; /** + * @SuppressWarnings(PHPMD.CamelCaseParameterName) + * @SuppressWarnings(PHPMD.CamelCaseVariableName) + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings(PHPMD.ExcessivePublicCount) + * @SuppressWarnings(PHPMD.StaticAccess) + * @SuppressWarnings(PHPMD.Superglobals) * @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.TooManyPublicMethods) */ @@ -306,6 +312,16 @@ class Authority return $resource['lecturer_id'] === $user->id; } + public static function canUpdateTaskGroup(User $user, TaskGroup $resource): bool + { + return self::canCreateTasks($user, $resource->target); + } + + public static function canDeleteTaskGroup(User $user, TaskGroup $resource): bool + { + return self::canUpdateTaskGroup($user, $resource); + } + public static function canShowTask(User $user, Task $resource): bool { return self::canUpdateTask($user, $resource); @@ -332,6 +348,11 @@ class Authority return self::canCreateTasks($user, $resource->structural_element) && !$resource->userIsASolver($user); } + public static function canRenewTask(User $user, Task $resource): bool + { + return self::canDeleteTask($user, $resource); + } + public static function canCreateTaskFeedback(User $user, Task $resource): bool { return self::canCreateTasks($user, $resource->structural_element); @@ -352,7 +373,6 @@ class Authority return self::canCreateTaskFeedback($user, $resource); } - public static function canIndexStructuralElementComments(User $user, StructuralElement $resource) { return self::canShowStructuralElement($user, $resource); @@ -407,7 +427,8 @@ class Authority public static function canShowStructuralElementFeedback(User $user, StructuralElementFeedback $resource) { - return $resource->user_id === $user->id || self::canUpdateStructuralElement($user, $resource->structural_element); + return $resource->user_id === $user->id || + self::canUpdateStructuralElement($user, $resource->structural_element); } public static function canDeleteStructuralElementFeedback(User $user, StructuralElementFeedback $resource) @@ -415,7 +436,6 @@ class Authority return self::canUpdateStructuralElementFeedback($user, $resource); } - public static function canShowTemplate(User $user, Template $resource) { // templates are for everybody, aren't they? @@ -430,7 +450,7 @@ class Authority public static function canCreateTemplate(User $user) { - return $GLOBALS['perm']->have_perm('admin'); + return $GLOBALS['perm']->have_perm('admin', $user->id); } public static function canUpdateTemplate(User $user, Template $resource) @@ -490,7 +510,7 @@ class Authority if ($user->id === $range->id) { return true; } - return $GLOBALS['perm']->have_studip_perm('tutor', $range->id ,$user->id); + return $GLOBALS['perm']->have_studip_perm('tutor', $range->id, $user->id); } public static function canSortUnit(User $user, \Range $range): bool @@ -518,7 +538,6 @@ class Authority return $request_user->id === $user->id; } - public static function canShowClipboard(User $user, Clipboard $resource): bool { return $resource->user_id === $user->id; @@ -541,7 +560,7 @@ class Authority } else { $structural_element = $resource->getStructuralElement(); } - + return $structural_element->canEdit($user); } diff --git a/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php b/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php new file mode 100644 index 0000000..2ab5ffa --- /dev/null +++ b/lib/classes/JsonApi/Routes/Courseware/Rel/SolversOfTaskGroup.php @@ -0,0 +1,207 @@ +<?php + +namespace JsonApi\Routes\Courseware\Rel; + +use Courseware\StructuralElement; +use Courseware\Task; +use Courseware\TaskGroup; +use JsonApi\Errors\RecordNotFoundException; +use JsonApi\Errors\UnprocessableEntityException; +use JsonApi\Routes\Courseware\Authority; +use JsonApi\Routes\RelationshipsController; +use JsonApi\Schemas\Courseware\TaskGroup as TaskGroupSchema; +use JsonApi\Schemas\StatusGroup as StatusGroupSchema; +use JsonApi\Schemas\User as UserSchema; +use Psr\Http\Message\ServerRequestInterface as Request; +use Statusgruppen; +use User; + +/** + * @SuppressWarnings(PHPMD.LongVariable) + * @SuppressWarnings(PHPMD.StaticAccess) + */ +class SolversOfTaskGroup extends RelationshipsController +{ + protected $allowedPagingParameters = ['offset', 'limit']; + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function fetchRelationship(Request $request, $related) + { + $solvers = $related->getSolvers(); + $total = count($solvers); + + return $this->getPaginatedIdentifiersResponse(array_slice($solvers, ...$this->getOffsetAndLimit()), $total); + } + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function addToRelationship(Request $request, $related) + { + $this->createTaskFor( + $related, + array_filter($this->validateSolvers($related, $this->validate($request)), function ($solver) use ( + $related + ) { + return !$related->findTaskBySolver($solver); + }) + ); + + return $this->getCodeResponse(204); + } + + protected function findRelated(array $args) + { + $related = TaskGroup::find($args['id']); + if (!$related) { + throw new RecordNotFoundException(); + } + + return $related; + } + + protected function authorize(Request $request, $resource) + { + switch ($request->getMethod()) { + case 'GET': + return Authority::canShowTaskGroup($this->getUser($request), $resource); + case 'POST': + return Authority::canUpdateTaskGroup($this->getUser($request), $resource); + + default: + return false; + } + } + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function getRelationshipSelfLink($resource, $schema, $userData) + { + return $schema->getRelationshipSelfLink($resource, TaskGroupSchema::REL_SOLVERS); + } + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + protected function getRelationshipRelatedLink($resource, $schema, $userData) + { + return $schema->getRelationshipRelatedLink($resource, TaskGroupSchema::REL_SOLVERS); + } + + protected function validateResourceDocument($json, $data) + { + if (!self::arrayHas($json, 'data')) { + return 'Missing `data` member at document´s top level.'; + } + + $data = self::arrayGet($json, 'data'); + + if (!is_array($data)) { + return 'Document´s `data` must be an array.'; + } + + foreach ($data as $item) { + if (!in_array(self::arrayGet($item, 'type'), [UserSchema::TYPE, StatusGroupSchema::TYPE])) { + return 'Wrong `type` in document´s `data`.'; + } + + if (!self::arrayGet($item, 'id')) { + return 'Missing `id` of document´s `data`.'; + } + } + } + + private function validateSolvers(TaskGroup $taskGroup, iterable $json): iterable + { + if (!$taskGroup->course) { + return []; + } + $solvers = []; + foreach ($json['data'] as $item) { + $solver = $this->findSolver($item); + if (!$solver) { + throw new RecordNotFoundException(); + } + if (!$this->validateSolver($taskGroup, $solver)) { + throw new UnprocessableEntityException(); + } + $solvers[] = $solver; + } + return $solvers; + } + + /** + * @return Statusgruppen|User|null + */ + private function findSolver($json) + { + switch ($json['type']) { + case 'status-groups': + return Statusgruppen::find($json['id']); + case 'users': + return User::find($json['id']); + } + return null; + } + + /** + * @param Statusgruppen|User $solver + * + * @SuppressWarnings(PHPMD.Superglobals) + */ + private function validateSolver(TaskGroup $taskGroup, $solver): bool + { + if ($solver instanceof User) { + return $GLOBALS['perm']->have_studip_perm('autor', $taskGroup->course->id, $solver->id); + } + if ($solver instanceof Statusgruppen) { + return $taskGroup->course->id === $solver->range_id; + } + + return false; + } + + /** + * @param array<User|Statusgruppen> $solvers + */ + private function createTaskFor(TaskGroup $taskGroup, $solvers): void + { + $template = $this->getTaskTemplate($taskGroup); + if (!$template) { + throw new RuntimeException(); + } + + foreach ($solvers as $solver) { + $task = Task::build([ + 'task_group_id' => $taskGroup->id, + 'solver_id' => $solver->id, + 'solver_type' => $this->getSolverType($solver), + ]); + + $taskElement = $template->copy($taskGroup->lecturer, $taskGroup->target, 'task'); + $taskElement->title = $taskGroup->title; + $taskElement->store(); + + $task['structural_element_id'] = $taskElement->id; + $task->store(); + } + } + + private function getTaskTemplate(TaskGroup $taskGroup): StructuralElement + { + return StructuralElement::find($taskGroup->task_template_id); + } + + /** + * @param User|Statusgruppen $solver + */ + private function getSolverType($solver): string + { + $solverTypes = [\User::class => 'autor', \Statusgruppen::class => 'group']; + + return $solverTypes[get_class($solver)]; + } +} diff --git a/lib/classes/JsonApi/Routes/Courseware/TaskGroupsCreate.php b/lib/classes/JsonApi/Routes/Courseware/TaskGroupsCreate.php index 28c4e9c..f7357a4 100644 --- a/lib/classes/JsonApi/Routes/Courseware/TaskGroupsCreate.php +++ b/lib/classes/JsonApi/Routes/Courseware/TaskGroupsCreate.php @@ -65,14 +65,20 @@ class TaskGroupsCreate extends JsonApiController if (!self::arrayHas($json, 'data.attributes.title')) { return 'Missing `title` attribute.'; } - if (!self::arrayHas($json, 'data.attributes.submission-date')) { - return 'Missing `submission-date` attribute.'; + if (!self::arrayHas($json, 'data.attributes.start-date')) { + return 'Missing `start-date` attribute.'; } - $submissionDate = self::arrayGet($json, 'data.attributes.submission-date'); - if (!self::isValidTimestamp($submissionDate)) { - return '`submission-date` is not an ISO 8601 timestamp.'; + $startDate = self::arrayGet($json, 'data.attributes.start-date'); + if (!self::isValidTimestamp($startDate)) { + return '`start-date` is not an ISO 8601 timestamp.'; + } + if (!self::arrayHas($json, 'data.attributes.end-date')) { + return 'Missing `end-date` attribute.'; + } + $endDate = self::arrayGet($json, 'data.attributes.end-date'); + if (!self::isValidTimestamp($endDate)) { + return '`end-date` is not an ISO 8601 timestamp.'; } - if (!self::arrayHas($json, 'data.relationships.target')) { return 'Missing `target` relationship.'; } @@ -165,8 +171,8 @@ class TaskGroupsCreate extends JsonApiController $target = $this->getTargetFromJson($json); $solverMayAddBlocks = self::arrayGet($json, 'data.attributes.solver-may-add-blocks', ''); - $submissionDate = self::arrayGet($json, 'data.attributes.submission-date', ''); - $submissionDate = self::fromISO8601($submissionDate); + $startDate = self::fromISO8601(self::arrayGet($json, 'data.attributes.start-date', '')); + $endDate = self::fromISO8601(self::arrayGet($json, 'data.attributes.end-date', '')); $title = self::arrayGet($json, 'data.attributes.title', ''); /** @var TaskGroup $taskGroup */ @@ -177,6 +183,8 @@ class TaskGroupsCreate extends JsonApiController 'task_template_id' => $taskTemplate->getId(), 'solver_may_add_blocks' => $solverMayAddBlocks, 'title' => $title, + 'start_date' => $startDate->getTimestamp(), + 'end_date' => $endDate->getTimestamp(), ]); foreach ($solvers as $solver) { @@ -184,7 +192,6 @@ class TaskGroupsCreate extends JsonApiController 'task_group_id' => $taskGroup->getId(), 'solver_id' => $solver->getId(), 'solver_type' => $this->getSolverType($solver), - 'submission_date' => $submissionDate->getTimestamp(), ]); // copy task template diff --git a/lib/classes/JsonApi/Routes/Courseware/TaskGroupsDelete.php b/lib/classes/JsonApi/Routes/Courseware/TaskGroupsDelete.php new file mode 100644 index 0000000..2faf778 --- /dev/null +++ b/lib/classes/JsonApi/Routes/Courseware/TaskGroupsDelete.php @@ -0,0 +1,38 @@ +<?php + +namespace JsonApi\Routes\Courseware; + +use Courseware\TaskGroup; +use JsonApi\Errors\AuthorizationFailedException; +use JsonApi\Errors\RecordNotFoundException; +use JsonApi\JsonApiController; +use Psr\Http\Message\ResponseInterface as Response; +use Psr\Http\Message\ServerRequestInterface as Request; + +/** + * Delete one TaskGroup. + */ +class TaskGroupsDelete extends JsonApiController +{ + /** + * @param array $args + * @return Response + * + * @SuppressWarnings(PHPMD.StaticAccess) + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke(Request $request, Response $response, $args) + { + /** @var ?TaskGroup $resource */ + $resource = TaskGroup::find($args['id']); + if (!$resource) { + throw new RecordNotFoundException(); + } + if (!Authority::canDeleteTaskGroup($this->getUser($request), $resource)) { + throw new AuthorizationFailedException(); + } + $resource->delete(); + + return $this->getCodeResponse(204); + } +} diff --git a/lib/classes/JsonApi/Routes/Courseware/TaskGroupsUpdate.php b/lib/classes/JsonApi/Routes/Courseware/TaskGroupsUpdate.php new file mode 100644 index 0000000..8662b71 --- /dev/null +++ b/lib/classes/JsonApi/Routes/Courseware/TaskGroupsUpdate.php @@ -0,0 +1,99 @@ +<?php + +namespace JsonApi\Routes\Courseware; + +use Courseware\TaskGroup; +use JsonApi\Errors\AuthorizationFailedException; +use JsonApi\Errors\RecordNotFoundException; +use JsonApi\JsonApiController; +use JsonApi\Routes\TimestampTrait; +use JsonApi\Routes\ValidationTrait; +use JsonApi\Schemas\Courseware\TaskGroup as TaskGroupSchema; +use Psr\Http\Message\ResponseInterface as Response; +use Psr\Http\Message\ServerRequestInterface as Request; +use User; + +/** + * Updates one TaskGroup. + * + * @SuppressWarnings(PHPMD.StaticAccess) + */ +class TaskGroupsUpdate extends JsonApiController +{ + use TimestampTrait; + use ValidationTrait; + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @param array $args + * @return Response + */ + public function __invoke(Request $request, Response $response, $args) + { + /** @var ?\Courseware\TaskGroup $resource */ + $resource = TaskGroup::find($args['id']); + if (!$resource) { + throw new RecordNotFoundException(); + } + $json = $this->validate($request, $resource); + $user = $this->getUser($request); + if (!Authority::canUpdateTaskGroup($user, $resource)) { + throw new AuthorizationFailedException(); + } + + $process = $this->update($resource, $json); + + return $this->getContentResponse($process); + } + + /** + * @SuppressWarnings(PHPMD.UnusedFormalParameters) + * + * @param array $json + * @param mixed $data + * + * @return string|void + */ + protected function validateResourceDocument($json, $data) + { + if (!self::arrayHas($json, 'data')) { + return 'Missing `data` member at document´s top level.'; + } + if (TaskGroupSchema::TYPE !== self::arrayGet($json, 'data.type')) { + return 'Invalid `type` of document´s `data`.'; + } + + if (!self::arrayHas($json, 'data.attributes.start-date')) { + return 'Missing `start-date` attribute.'; + } + $startDate = self::arrayGet($json, 'data.attributes.start-date'); + if (!self::isValidTimestamp($startDate)) { + return '`start-date` is not an ISO 8601 timestamp.'; + } + + if (!self::arrayHas($json, 'data.attributes.end-date')) { + return 'Missing `end-date` attribute.'; + } + $endDate = self::arrayGet($json, 'data.attributes.end-date'); + if (!self::isValidTimestamp($endDate)) { + return '`end-date` is not an ISO 8601 timestamp.'; + } + + if (self::fromISO8601($startDate) > self::fromISO8601($endDate)) { + return '`start-date` is later than `end-date`'; + } + } + + private function update(TaskGroup $taskGroup, array $json): TaskGroup + { + $startDate = self::fromISO8601(self::arrayGet($json, 'data.attributes.start-date')); + $endDate = self::fromISO8601(self::arrayGet($json, 'data.attributes.end-date')); + + $taskGroup->start_date = $startDate->getTimestamp(); + $taskGroup->end_date = $endDate->getTimestamp(); + + $taskGroup->store(); + + return $taskGroup; + } +} diff --git a/lib/classes/JsonApi/Routes/Courseware/TasksIndex.php b/lib/classes/JsonApi/Routes/Courseware/TasksIndex.php index f0b2ce9..26a021c 100644 --- a/lib/classes/JsonApi/Routes/Courseware/TasksIndex.php +++ b/lib/classes/JsonApi/Routes/Courseware/TasksIndex.php @@ -77,9 +77,10 @@ class TasksIndex extends JsonApiController } } - private function findTasksByCourse(\Course $course): \SimpleCollection + private function findTasksByCourse(\Course $course, bool $showNotYetActive = true): \SimpleCollection { - $taskGroups = TaskGroup::findBySQL('seminar_id = ?', [$course->getId()]); + $whereClause = $showNotYetActive ? 'seminar_id = ?' : 'start_date <= UNIX_TIMESTAMP() AND seminar_id = ?'; + $taskGroups = TaskGroup::findBySQL($whereClause, [$course->getId()]); $tasks = []; foreach ($taskGroups as $taskGroup) { @@ -98,7 +99,7 @@ class TasksIndex extends JsonApiController }) ->pluck('id'); - return $this->findTasksByCourse($course)->filter(function ($task) use ($user, $groupIds) { + return $this->findTasksByCourse($course, false)->filter(function ($task) use ($user, $groupIds) { return ('autor' === $task['solver_type'] && $task['solver_id'] === $user->getId()) || ('group' === $task['solver_type'] && in_array($task['solver_id'], $groupIds)); }); diff --git a/lib/classes/JsonApi/Routes/Courseware/TasksUpdate.php b/lib/classes/JsonApi/Routes/Courseware/TasksUpdate.php index 3728dba..33b51ad 100644 --- a/lib/classes/JsonApi/Routes/Courseware/TasksUpdate.php +++ b/lib/classes/JsonApi/Routes/Courseware/TasksUpdate.php @@ -13,6 +13,8 @@ use Psr\Http\Message\ServerRequestInterface as Request; /** * Update one Task. + * + * @SuppressWarnings(PHPMD.StaticAccess) */ class TasksUpdate extends JsonApiController { @@ -32,7 +34,8 @@ class TasksUpdate extends JsonApiController throw new RecordNotFoundException(); } $json = $this->validate($request, $resource); - if (!Authority::canUpdateTask($user = $this->getUser($request), $resource)) { + $user = $this->getUser($request); + if (!Authority::canUpdateTask($user, $resource)) { throw new AuthorizationFailedException(); } $resource = $this->updateTask($user, $resource, $json); @@ -66,53 +69,35 @@ class TasksUpdate extends JsonApiController private function updateTask(\User $user, Task $resource, array $json): Task { - if (Authority::canDeleteTask($user, $resource)) { - if (self::arrayHas($json, 'data.attributes.renewal')) { - $newRenewalState = self::arrayGet($json, 'data.attributes.renewal'); - if ('declined' === $newRenewalState) { - $resource->renewal = $newRenewalState; - } - if ('granted' === $newRenewalState && self::arrayHas($json, 'data.attributes.renewal-date')) { - $renewalDate = self::arrayGet($json, 'data.attributes.renewal-date', ''); - $renewalDate = self::fromISO8601($renewalDate); + if (Authority::canRenewTask($user, $resource)) { + return $this->renewTask($resource, $json); + } - $resource->renewal = $newRenewalState; - $resource->renewal_date = $renewalDate->getTimestamp(); - } - } - } else { - if (self::arrayHas($json, 'data.attributes.submitted')) { - $newSubmittedState = self::arrayGet($json, 'data.attributes.submitted'); - if ($this->canSubmit($resource, $newSubmittedState)) { - $resource->submitted = $newSubmittedState; - if ('pending' === $resource->renewal) { - $resource->renewal = ''; - } - } - } - if (self::arrayHas($json, 'data.attributes.renewal')) { - $newRenewalState = self::arrayGet($json, 'data.attributes.renewal'); - if ('pending' === $newRenewalState) { - $resource->renewal = $newRenewalState; - } - } + if (self::arrayGet($json, 'data.attributes.submitted') === true && $resource->canSubmit()) { + $resource->submitTask(); } - $resource->store(); + if (self::arrayGet($json, 'data.attributes.renewal') === 'pending') { + $resource->requestRenewal(); + } return $resource; } - private function canSubmit(Task $resource, string $newSubmittedState): bool + private function renewTask(Task $resource, array $json): Task { - $now = time(); - if (1 === (int) $resource->submitted || !$newSubmittedState) { - return false; - } - if ('granted' === $resource->renewal) { - return $now <= $resource->renewal_date; - } else { - return $now <= $resource->submission_date; + switch (self::arrayGet($json, 'data.attributes.renewal')) { + case 'declined': + $resource->declineRenewalRequest(); + break; + + case 'granted': + $resource->grantRenewalRequest( + self::fromISO8601(self::arrayGet($json, 'data.attributes.renewal-date')) + ); + break; } + + return $resource; } } diff --git a/lib/classes/JsonApi/SchemaMap.php b/lib/classes/JsonApi/SchemaMap.php index dd74bc9..71aadf7 100644 --- a/lib/classes/JsonApi/SchemaMap.php +++ b/lib/classes/JsonApi/SchemaMap.php @@ -59,17 +59,17 @@ class SchemaMap \Courseware\Clipboard::class => Schemas\Courseware\Clipboard::class, \Courseware\Container::class => Schemas\Courseware\Container::class, \Courseware\Instance::class => Schemas\Courseware\Instance::class, + \Courseware\PublicLink::class => Schemas\Courseware\PublicLink::class, \Courseware\StructuralElement::class => Schemas\Courseware\StructuralElement::class, \Courseware\StructuralElementComment::class => Schemas\Courseware\StructuralElementComment::class, \Courseware\StructuralElementFeedback::class => Schemas\Courseware\StructuralElementFeedback::class, - \Courseware\Unit::class => Schemas\Courseware\Unit::class, - \Courseware\UserDataField::class => Schemas\Courseware\UserDataField::class, - \Courseware\UserProgress::class => Schemas\Courseware\UserProgress::class, \Courseware\Task::class => Schemas\Courseware\Task::class, - \Courseware\TaskGroup::class => Schemas\Courseware\TaskGroup::class, \Courseware\TaskFeedback::class => Schemas\Courseware\TaskFeedback::class, + \Courseware\TaskGroup::class => Schemas\Courseware\TaskGroup::class, \Courseware\Template::class => Schemas\Courseware\Template::class, - \Courseware\PublicLink::class => Schemas\Courseware\PublicLink::class, + \Courseware\Unit::class => Schemas\Courseware\Unit::class, + \Courseware\UserDataField::class => Schemas\Courseware\UserDataField::class, + \Courseware\UserProgress::class => Schemas\Courseware\UserProgress::class, ]; } } diff --git a/lib/classes/JsonApi/Schemas/Courseware/Task.php b/lib/classes/JsonApi/Schemas/Courseware/Task.php index a0605e6..81c7a0d 100644 --- a/lib/classes/JsonApi/Schemas/Courseware/Task.php +++ b/lib/classes/JsonApi/Schemas/Courseware/Task.php @@ -2,6 +2,8 @@ namespace JsonApi\Schemas\Courseware; +use Courseware\Task as TaskModel; +use JsonApi\Routes\Courseware\Authority as CoursewareAuthority; use JsonApi\Schemas\SchemaProvider; use Neomerx\JsonApi\Contracts\Schema\ContextInterface; use Neomerx\JsonApi\Schema\Link; diff --git a/lib/classes/JsonApi/Schemas/Courseware/TaskGroup.php b/lib/classes/JsonApi/Schemas/Courseware/TaskGroup.php index 12dbc6c..c950671 100644 --- a/lib/classes/JsonApi/Schemas/Courseware/TaskGroup.php +++ b/lib/classes/JsonApi/Schemas/Courseware/TaskGroup.php @@ -3,6 +3,7 @@ namespace JsonApi\Schemas\Courseware; use Courseware\StructuralElement; +use Courseware\TaskGroup as TaskGroupModel; use JsonApi\Schemas\SchemaProvider; use Neomerx\JsonApi\Contracts\Schema\ContextInterface; use Neomerx\JsonApi\Schema\Identifier; @@ -35,6 +36,8 @@ class TaskGroup extends SchemaProvider return [ 'solver-may-add-blocks' => (bool) $resource['solver_may_add_blocks'], 'title' => (string) $resource->title, + 'start-date' => date('c', $resource['start_date']), + 'end-date' => date('c', $resource['end_date']), 'mkdate' => date('c', $resource['mkdate']), 'chdate' => date('c', $resource['chdate']), ]; |
