aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/JsonApi/Routes/Courseware/StructuralElementsCreate.php
blob: 8f1c8bd84432a4e1845fd5873f82bc524110e4fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php

namespace JsonApi\Routes\Courseware;

use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\JsonApiController;
use JsonApi\Routes\ValidationTrait;
use JsonApi\Schemas\Courseware\StructuralElement as StructuralElementSchema;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Studip\Activity\Activity;

/**
 * Create a block in a container.
 */
class StructuralElementsCreate extends JsonApiController
{
    use ValidationTrait;

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function __invoke(Request $request, Response $response, $args)
    {
        $json = $this->validate($request);
        $parent = $this->getParentFromJson($json);
        if (!Authority::canCreateStructuralElement($user = $this->getUser($request), $parent)) {
            throw new AuthorizationFailedException();
        }
        $struct = $this->createStructuralElement($user, $json, $parent);

        return $this->getCreatedResponse($struct);
    }

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameters)
     */
    protected function validateResourceDocument($json, $data)
    {
        if (!self::arrayHas($json, 'data')) {
            return 'Missing `data` member at document“s top level.';
        }
        if (StructuralElementSchema::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.relationships.parent')) {
            return 'Missing `parent` relationship.';
        }
        if (!$this->getParentFromJson($json)) {
            return 'Invalid `parent` relationship.';
        }
    }

    private function getParentFromJson($json)
    {
        if (!$this->validateResourceObject($json, 'data.relationships.parent', StructuralElementSchema::TYPE)) {
            return null;
        }
        $parentId = self::arrayGet($json, 'data.relationships.parent.data.id');

        return \Courseware\StructuralElement::find($parentId);
    }

    private function createStructuralElement(\User $user, array $json, \Courseware\StructuralElement $parent)
    {
        $struct = \Courseware\StructuralElement::build([
            'parent_id' => $parent->id,
            'range_id' => $parent->range_id,
            'range_type' => $parent->range_type,
            'owner_id' => $user->id,
            'editor_id' => $user->id,
            'edit_blocker_id' => '',
            'title' => self::arrayGet($json, 'data.attributes.title', ''),
            'purpose' => self::arrayGet($json, 'data.attributes.purpose', 'content'),
            'payload' => self::arrayGet($json, 'data.attributes.payload', ''),
            'position' => $parent->countChildren()
        ]);

        $struct->store();
        $template = \Courseware\Template::find(self::arrayGet($json, 'data.templateId'));

        if ($template) {
            $structure = json_decode($template->structure, true);

            foreach($structure['containers'] as $container) {

                $new_container = \Courseware\Container::build([
                    'structural_element_id' => $struct->id,
                    'owner_id' => $user->id,
                    'editor_id' => $user->id,
                    'edit_blocker_id' => '',
                    'position' => $struct->countContainers(),
                    'container_type' => $container['attributes']['container-type'],
                    'payload' => json_encode($container['attributes']['payload']),
                ]);

                $new_container->store();
                $blockMap = [];
                foreach($container['blocks'] as $block) {
                    $new_block = \Courseware\Block::build([
                        'container_id'    => $new_container->id,
                        'owner_id'        => $user->id,
                        'editor_id'       => $user->id,
                        'position'        => $new_container->countBlocks(),
                        'block_type'      => $block['attributes']['block-type'],
                        'payload'         => json_encode($block['attributes']['payload']),
                        'visible'         => 1,
                    ]);

                    $new_block->store();
                    $blockMap[$block['id']] = $new_block->id;
                }
                $new_container['payload'] = $new_container->type->copyPayload($blockMap);
                $new_container->store();
            }
        }

        return $struct;
    }
}