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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
<?php
namespace RESTAPI\Routes;
/**
* @author <mlunzena@uos.de>
* @license GPL 2 or later
* @deprecated Since Stud.IP 5.0. Will be removed in Stud.IP 6.0.
*
* @condition course_id ^[a-f0-9]{1,32}$
* @condition user_id ^[a-f0-9]{1,32}$
*/
class Course extends \RESTAPI\RouteMap
{
public function before()
{
require_once 'User.php';
}
/**
* Lists all courses of a user including the semesters in which
* that course is active.
* Optionally filtered by a URL parameter 'semester'.
*
* @get /user/:user_id/courses
*/
public function getUserCourses($user_id)
{
if (($GLOBALS['user']->id !== $user_id) && !$GLOBALS['perm']->have_perm("root")) {
$this->error(401);
}
// setting up semester to filter by
$semester = null;
$semester_id = \Request::get('semester');
if ($semester_id) {
$semester = \Semester::find($semester_id);
if (!$semester) {
$this->error(400, "Semester not found.");
}
}
$memberships = $this->findMembershipsByUserId($user_id, $semester);
$total = count($memberships);
$memberships = $memberships->limit($this->offset, $this->limit);
$memberships_json = $this->membershipsToJSON($memberships);
$this->etag(md5(serialize($memberships_json)));
return $this->paginated(
$memberships_json,
$total,
compact('user_id'),
['semester' => $semester_id]
);
}
/**
* Show a single course
*
* @get /course/:course_id
*/
public function getCourse($course_id)
{
if (!$course = \Course::find($course_id)) {
$this->notFound("Course not found");
}
$course = $this->requireCourse($course_id);
$this->lastmodified($course->chdate);
$course_json = $this->courseToJSON($course);
$this->etag(md5(serialize($course_json)));
return $course_json;
}
/**
* List all members of a course.
* Optionally filtered by a URL parameter 'status'.
*
* @get /course/:course_id/members
*/
public function getMembers($course_id)
{
$status_filter = \Request::get('status');
if ($status_filter && !in_array($status_filter, words("user autor tutor dozent"))) {
$this->error(400, "Status may be one of: user, autor, tutor, dozent");
}
$course = $this->requireCourse($course_id);
$members = $course->members;
if ($status_filter) {
$members = $members->findBy('status', $status_filter);
}
$total = count($members);
$members = $members->limit($this->offset, $this->limit);
$members_json = $this->membersToJSON($course, $members);
$this->etag(md5(serialize($members_json)));
return $this->paginated(
$members_json,
$total,
compact('course_id'),
['status' => $status_filter]
);
}
/**
* Get the root file folder of a course.
*
* @get /course/:course_id/top_folder
*/
public function getTopFolder($course_id)
{
$top_folder = \Folder::findTopFolder($this->requireCourse($course_id)->id);
if (!$top_folder) {
$this->notFound("No folder found for course with id {$course_id}!");
}
return (new FileSystem())->getFolder($top_folder->id);
}
/**************************************************/
/* PRIVATE HELPER METHODS */
/**************************************************/
private function findMembershipsByUserId($user_id, $semester)
{
$memberships = \SimpleORMapCollection::createFromArray(
\CourseMember::findBySQL('user_id = ? ORDER BY mkdate ASC', [$user_id])
);
// filter by semester
if ($semester) {
$memberships = $memberships->filter(function ($m) use ($semester) {
return $m->course->isInSemester($semester);
});
}
return $memberships;
}
private function membershipsToJSON($memberships)
{
$json = [];
foreach ($memberships as $membership) {
$course_json = $this->courseToJSON($course = $membership->course);
$json[$this->urlf("/course/%s", [$course->id])] = $course_json;
}
return $json;
}
private function courseToJSON($course)
{
$json = [];
$json['course_id'] = $course->id;
$json['number'] = $course->VeranstaltungsNummer;
$json['title'] = (string) $course->Name;
$json['subtitle'] = (string) $course->Untertitel;
$json['type'] = $course->status;
$json['description'] = (string) $course->Beschreibung;
$json['location'] = (string) $course->Ort;
// lecturers
foreach ($course->getMembersWithStatus('dozent') as $lecturer) {
$url = $this->urlf('/user/%s', [htmlReady($lecturer->user_id)]);
$json['lecturers'][$url] = User::getMiniUser($this, $lecturer->user);
}
// other members
foreach (words("user autor tutor dozent") as $status) {
$json['members'][$status] = $this->urlf('/course/%s/members?status=%s', [$course->id, $status]);
$json['members'][$status . '_count'] = $course->countMembersWithStatus($status);
}
foreach (words("start_semester end_semester") as $key) {
$json[$key] = $course->$key ? $this->urlf('/semester/%s', [htmlReady($course->$key->id)]) : null;
}
$activated = array_map('get_class', $course->getActivatedTools());
$json['modules'] = [];
foreach (['forum' => 'forum_categories',
'documents' => 'top_folder',
'wiki' => 'wiki'] as $module => $uri)
{
if (in_array('Core' . ucfirst($module), $activated)) {
$json['modules'][$module] = $this->urlf('/course/%s/%s', [htmlReady($course->id), $uri]);
}
}
// Add group if current user is member of the group
$json['group'] = null;
$member = \CourseMember::find([$course->id, $GLOBALS['user']->id]);
if ($member) {
$json['group'] = (int) $member->gruppe;
}
return $json;
}
private function requireCourse($id)
{
if (!$course = \Course::find($id)) {
$this->notFound("Course not found");
}
//This route is used in the room management system.
//Therefore, we need not only to check if the user is in the course,
//but also, if the user is a global resource admin. In the latter case,
//access shall also be granted.
if (!$GLOBALS['perm']->have_studip_perm('user', $id, $GLOBALS['user']->id)
&& !\ResourceManager::userHasGlobalPermission(\User::findCurrent(), 'admin')) {
$this->error(401);
}
return $course;
}
private function membersToJSON($course, $members)
{
$json = [];
foreach ($members as $member) {
$url = $this->urlf('/user/%s', [$member->user_id]);
$avatar = \Avatar::getAvatar($member->user_id);
$json[$url] = [
'member' => User::getMiniUser($this, $member->user),
'status' => $member->status
];
}
return $json;
}
}
|