aboutsummaryrefslogtreecommitdiff
path: root/lib/classes/JsonApi/Routes/Schedule/UserScheduleShow.php
blob: b96a29093c025929bf0f8c046f60e7f45f088c24 (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
<?php

namespace JsonApi\Routes\Schedule;

use JsonApi\Errors\AuthorizationFailedException;
use JsonApi\Errors\RecordNotFoundException;
use JsonApi\JsonApiController;
use \ScheduleEntry;
use JsonApi\Routes\Users\Authority;
use Neomerx\JsonApi\Schema\Link;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

/**
 * Zeige den Stundenplan eines Nutzers.
 */
class UserScheduleShow extends JsonApiController
{
    protected $allowedFilteringParameters = ['timestamp'];

    protected $allowedIncludePaths = ['owner'];

    /**
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function __invoke(Request $request, Response $response, $args)
    {
        if (!$otherUser = \User::find($args['id'])) {
            throw new RecordNotFoundException('Could not find user.');
        }

        if (!Authority::canEditUser($this->getUser($request), $otherUser)) {
            throw new AuthorizationFailedException();
        }

        $filtering = $this->getQueryParameters()->getFilteringParameters();
        $semester = isset($filtering['timestamp'])
                  ? \Semester::findByTimestamp((int) $filtering['timestamp'])
                  : \Semester::findCurrent();

        if (!$semester) {
            throw new RecordNotFoundException('Could not find semester.');
        }

        return $this->getContentResponse(
            array_merge(
                ScheduleEntry::findByUser_id($otherUser->id),
                $this->getCycles($otherUser, $semester)
            ),
            200,
            [Link::SELF => $this->getSelfLink($otherUser, $semester)],
            $this->getMeta($semester)
        );
    }

    private function getCycles(\User $user, \Semester $semester): array
    {
        // get all virtually added seminars
        $stmt = \DBManager::get()->prepare(
            'SELECT c.`course_id` FROM `schedule_courses` as c
             LEFT JOIN `seminare` ON `seminare`.`seminar_id` = c.`course_id`
             JOIN `semester_courses` ON `seminare`.`seminar_id` = `semester_courses`.`course_id`
             WHERE user_id = :user_id AND semester_id = :semester_id'
        );
        $stmt->execute(['user_id' => $user->id, 'semester_id' => $semester->id]);
        $ids = $stmt->fetchFirst();

        // fetch seminar-entries
        $stmt = \DBManager::get()->prepare('
            SELECT s.seminar_id
            FROM seminar_user as su
                LEFT JOIN seminare as s USING (seminar_id)
                LEFT JOIN semester_courses ON (s.Seminar_id = semester_courses.course_id)
            WHERE su.user_id = :userid
                AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id)
        ');
        $stmt->execute([
            'userid' => $user->id,
            'semester_id' => $semester->id,
        ]);

        return array_reduce(
            array_unique(array_merge($ids, $stmt->fetchFirst())),
            function ($cycles, $seminarId) {
                return array_merge(
                    $cycles,
                    array_filter(
                        \Course::find($seminarId)->cycles->getArrayCopy(),
                        function ($cycle) {
                            return $cycle['is_visible'];
                        }
                    )
                );
            },
            []
        );
    }

    private function getSelfLink(\User $user, \Semester $semester): Link
    {
        $routeParser = $this->app->getRouteCollector()->getRouteParser();
        $url = $routeParser->urlFor('get-schedule', ['id' => $user->id], ['filter[timestamp]' => $semester->beginn]);

        return new Link(false, $url, false);
    }

    private function getMeta(\Semester $semester): array
    {
        $routeParser = $this->app->getRouteCollector()->getRouteParser();
        $url = $routeParser->urlFor('get-semester', ['id' => $semester->id]);

        return [ 'semester' => $url ];
    }
}