Select Git revision
FileRefsOfFilesShow.php
Forked from
Stud.IP / Stud.IP
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
TaskGroupsCreate.php 7.05 KiB
<?php
namespace JsonApi\Routes\Courseware;
use Courseware\StructuralElement;
use Courseware\Task;
use Courseware\TaskGroup;
use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\JsonApiController;
use JsonApi\Routes\TimestampTrait;
use JsonApi\Routes\ValidationTrait;
use JsonApi\Schemas\Courseware\StructuralElement as StructuralElementSchema;
use JsonApi\Schemas\Courseware\TaskGroup as TaskGroupSchema;
use JsonApi\Schemas\StatusGroup as StatusGroupSchema;
use JsonApi\Schemas\User as UserSchema;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
/**
* Create a TaskGroup.
*/
class TaskGroupsCreate extends JsonApiController
{
use TimestampTrait;
use ValidationTrait;
/**
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @param array $args
*
* @return Response
*/
public function __invoke(Request $request, Response $response, $args)
{
$json = $this->validate($request);
$structuralElement = $this->getTargetFromJson($json);
if (!Authority::canCreateTasks($user = $this->getUser($request), $structuralElement)) {
throw new AuthorizationFailedException();
}
$taskGroup = $this->createTaskGroup($user, $json);
return $this->getCreatedResponse($taskGroup);
}
/**
* @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 'Wrong `type` member of document´s `data`.';
}
if (self::arrayHas($json, 'data.id')) {
return 'New document must not have an `id`.';
}
if (!self::arrayHas($json, 'data.attributes.title')) {
return 'Missing `title` attribute.';
}
if (!self::arrayHas($json, 'data.attributes.submission-date')) {
return 'Missing `submission-date` attribute.';
} $submissionDate = self::arrayGet($json, 'data.attributes.submission-date');
if (!self::isValidTimestamp($submissionDate)) {
return '`submission-date` is not an ISO 8601 timestamp.';
}
if (!self::arrayHas($json, 'data.relationships.target')) {
return 'Missing `target` relationship.';
}
if (!self::arrayHas($json, 'data.relationships.task-template')) {
return 'Missing `task-template` relationship.';
}
if (!self::arrayHas($json, 'data.relationships.solvers')) {
return 'Missing `solvers` relationship.';
}
if (!$this->validateSolvers($json)) {
return 'Invalid `solvers` relationship.';
}
if (!$this->getTargetFromJson($json)) {
return 'Invalid `target` relationship.';
}
if (!$this->getTaskTemplateFromJson($json)) {
return 'Invalid `task-template` relationship.';
}
}
private function validateSolvers(array $json): bool
{
if (!self::arrayHas($json, 'data.relationships.solvers.data')) {
return false;
}
$data = self::arrayGet($json, 'data.relationships.solvers.data');
if (!is_array($data) || !count($data)) {
return false;
}
foreach ($data as $resourceIdentifier) {
if (
!(
$this->validateResourceObject($resourceIdentifier, '', UserSchema::TYPE) ||
$this->validateResourceObject($resourceIdentifier, '', StatusGroupSchema::TYPE)
)
) {
return false;
}
}
return true;
}
private function getSolversFromJson(array $json): iterable
{
if (!self::arrayHas($json, 'data.relationships.solvers.data')) {
return [];
}
$solvers = [];
$mapping = [UserSchema::TYPE => \User::class, StatusGroupSchema::TYPE => \Statusgruppen::class];
foreach (self::arrayGet($json, 'data.relationships.solvers.data') as $resourceIdentifier) {
$solvers[] = $mapping[$resourceIdentifier['type']]::find($resourceIdentifier['id']);
}
return $solvers;
}
private function getTargetFromJson(array $json): ?StructuralElement
{ if (!$this->validateResourceObject($json, 'data.relationships.target', StructuralElementSchema::TYPE)) {
return null;
}
$resourceId = self::arrayGet($json, 'data.relationships.target.data.id');
return StructuralElement::find($resourceId);
}
private function getTaskTemplateFromJson(array $json): ?StructuralElement
{
if (!$this->validateResourceObject($json, 'data.relationships.task-template', StructuralElementSchema::TYPE)) {
return null;
}
$resourceId = self::arrayGet($json, 'data.relationships.task-template.data.id');
return StructuralElement::find($resourceId);
}
private function createTaskGroup(\User $lecturer, array $json): TaskGroup
{
$tasks = [];
$solvers = $this->getSolversFromJson($json);
$taskTemplate = $this->getTaskTemplateFromJson($json);
$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);
$title = self::arrayGet($json, 'data.attributes.title', '');
/** @var TaskGroup $taskGroup */
$taskGroup = TaskGroup::create([
'seminar_id' => $target['range_id'],
'lecturer_id' => $lecturer->getId(),
'target_id' => $target->getId(),
'task_template_id' => $taskTemplate->getId(),
'solver_may_add_blocks' => $solverMayAddBlocks,
'title' => $title,
]);
foreach ($solvers as $solver) {
$task = Task::build([
'task_group_id' => $taskGroup->getId(),
'solver_id' => $solver->getId(),
'solver_type' => $this->getSolverType($solver),
'submission_date' => $submissionDate->getTimestamp(),
]);
// copy task template
$taskElement = $taskTemplate->copy($lecturer, $target);
$taskElement->title = $title;
$taskElement->purpose = 'task';
$taskElement->store();
//update task with element id
$task['structural_element_id'] = $taskElement->id;
$task->store();
}
return $taskGroup;
}
/**
* @param \User|\Statusgruppen $solver
*/
private function getSolverType($solver): string
{
$solverTypes = [\User::class => 'autor', \Statusgruppen::class => 'group'];
return $solverTypes[get_class($solver)];
}
}