1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* For licensing terms, see /license.txt*/ |
4
|
|
|
|
5
|
|
|
use Chamilo\CoreBundle\Entity\AccessUrlRelSession; |
6
|
|
|
use Chamilo\CoreBundle\Entity\Course; |
7
|
|
|
use Chamilo\CoreBundle\Entity\CourseRelUser; |
8
|
|
|
use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField; |
9
|
|
|
use Chamilo\CoreBundle\Entity\SequenceResource; |
10
|
|
|
use Chamilo\CoreBundle\Entity\User; |
11
|
|
|
use Chamilo\CoreBundle\Framework\Container; |
12
|
|
|
use Chamilo\CoreBundle\Repository\SequenceResourceRepository; |
13
|
|
|
use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder; |
14
|
|
|
use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer; |
15
|
|
|
use Chamilo\CourseBundle\Entity\CGroup; |
16
|
|
|
use ChamiloSession as Session; |
17
|
|
|
use Doctrine\Common\Collections\Criteria; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Class CourseManager. |
21
|
|
|
* |
22
|
|
|
* This is the course library for Chamilo. |
23
|
|
|
* |
24
|
|
|
* All main course functions should be placed here. |
25
|
|
|
* |
26
|
|
|
* There are probably some places left with the wrong code. |
27
|
|
|
*/ |
28
|
|
|
class CourseManager |
29
|
|
|
{ |
30
|
|
|
public const MAX_COURSE_LENGTH_CODE = 40; |
31
|
|
|
/** This constant is used to show separate user names in the course |
32
|
|
|
* list (userportal), footer, etc */ |
33
|
|
|
public const USER_SEPARATOR = ' |'; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Creates a course. |
37
|
|
|
* |
38
|
|
|
* @param array $params Columns in the main.course table. |
39
|
|
|
* @param int $authorId Optional. |
40
|
|
|
* @param int $accessUrlId Optional. |
41
|
|
|
* |
42
|
|
|
* @return Course|null |
43
|
|
|
*/ |
44
|
|
|
public static function create_course($params, $authorId = 0, $accessUrlId = 0) |
45
|
|
|
{ |
46
|
|
|
//global $_configuration; |
47
|
|
|
|
48
|
|
|
// Check portal limits |
49
|
|
|
$accessUrlId = !empty($accessUrlId) ? (int) $accessUrlId : api_get_current_access_url_id(); |
50
|
|
|
$authorId = empty($authorId) ? api_get_user_id() : (int) $authorId; |
51
|
|
|
|
52
|
|
|
// @todo Check that this was move inside the CourseListener in a pre persist throw an Exception |
53
|
|
|
/*if (isset($_configuration[$accessUrlId]) && is_array($_configuration[$accessUrlId])) { |
54
|
|
|
$return = self::checkCreateCourseAccessUrlParam( |
55
|
|
|
$_configuration, |
56
|
|
|
$accessUrlId, |
57
|
|
|
'hosting_limit_courses', |
58
|
|
|
'PortalCoursesLimitReached' |
59
|
|
|
); |
60
|
|
|
if (false != $return) { |
61
|
|
|
return $return; |
62
|
|
|
} |
63
|
|
|
$return = self::checkCreateCourseAccessUrlParam( |
64
|
|
|
$_configuration, |
65
|
|
|
$accessUrlId, |
66
|
|
|
'hosting_limit_active_courses', |
67
|
|
|
'PortalActiveCoursesLimitReached' |
68
|
|
|
); |
69
|
|
|
if (false != $return) { |
70
|
|
|
return $return; |
71
|
|
|
} |
72
|
|
|
}*/ |
73
|
|
|
|
74
|
|
|
if (empty($params['title'])) { |
75
|
|
|
return false; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
if (empty($params['wanted_code'])) { |
79
|
|
|
$params['wanted_code'] = $params['title']; |
80
|
|
|
// Check whether the requested course code has already been occupied. |
81
|
|
|
$substring = api_substr($params['title'], 0, self::MAX_COURSE_LENGTH_CODE); |
82
|
|
|
if (false === $substring || empty($substring)) { |
83
|
|
|
return false; |
84
|
|
|
} else { |
85
|
|
|
$params['wanted_code'] = self::generate_course_code($substring); |
86
|
|
|
} |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
// Create the course keys |
90
|
|
|
$keys = AddCourse::define_course_keys($params['wanted_code']); |
91
|
|
|
$params['exemplary_content'] = isset($params['exemplary_content']) ? $params['exemplary_content'] : false; |
92
|
|
|
|
93
|
|
|
if (count($keys)) { |
94
|
|
|
$params['code'] = $keys['currentCourseCode']; |
95
|
|
|
$params['visual_code'] = $keys['currentCourseId']; |
96
|
|
|
$params['directory'] = $keys['currentCourseRepository']; |
97
|
|
|
$courseInfo = api_get_course_info($params['code']); |
98
|
|
|
if (empty($courseInfo)) { |
99
|
|
|
$course = AddCourse::register_course($params, $accessUrlId); |
100
|
|
|
if (null !== $course) { |
101
|
|
|
self::fillCourse($course, $params, $authorId); |
102
|
|
|
|
103
|
|
|
return $course; |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
return null; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Returns all the information of a given course code. |
113
|
|
|
* |
114
|
|
|
* @param string $course_code , the course code |
115
|
|
|
* |
116
|
|
|
* @return array with all the fields of the course table |
117
|
|
|
* |
118
|
|
|
* @deprecated Use api_get_course_info() instead |
119
|
|
|
* |
120
|
|
|
* @author Patrick Cool <[email protected]>, Ghent University |
121
|
|
|
* @assert ('') === false |
122
|
|
|
*/ |
123
|
|
|
public static function get_course_information($course_code) |
124
|
|
|
{ |
125
|
|
|
return Database::fetch_array( |
126
|
|
|
Database::query( |
127
|
|
|
"SELECT *, id as real_id FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." |
128
|
|
|
WHERE code = '".Database::escape_string($course_code)."'" |
129
|
|
|
), |
130
|
|
|
'ASSOC' |
131
|
|
|
); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Returns a list of courses. Should work with quickform syntax. |
136
|
|
|
* |
137
|
|
|
* @param int $from Offset (from the 7th = '6'). Optional. |
138
|
|
|
* @param int $howmany Number of results we want. Optional. |
139
|
|
|
* @param string $orderby The column we want to order it by. Optional, defaults to first column. |
140
|
|
|
* @param string $orderdirection The direction of the order (ASC or DESC). Optional, defaults to ASC. |
141
|
|
|
* @param int $visibility the visibility of the course, or all by default |
142
|
|
|
* @param string $startwith If defined, only return results for which the course *title* begins with this |
143
|
|
|
* string |
144
|
|
|
* @param string $urlId The Access URL ID, if using multiple URLs |
145
|
|
|
* @param bool $alsoSearchCode An extension option to indicate that we also want to search for course codes |
146
|
|
|
* (not *only* titles) |
147
|
|
|
* @param array $conditionsLike |
148
|
|
|
* @param array $onlyThisCourseList |
149
|
|
|
* |
150
|
|
|
* @return array |
151
|
|
|
*/ |
152
|
|
|
public static function get_courses_list( |
153
|
|
|
$from = 0, |
154
|
|
|
$howmany = 0, |
155
|
|
|
$orderby = 'title', |
156
|
|
|
$orderdirection = 'ASC', |
157
|
|
|
$visibility = -1, |
158
|
|
|
$startwith = '', |
159
|
|
|
$urlId = null, |
160
|
|
|
$alsoSearchCode = false, |
161
|
|
|
$conditionsLike = [], |
162
|
|
|
$onlyThisCourseList = [] |
163
|
|
|
) { |
164
|
|
|
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE); |
165
|
|
|
$sql = "SELECT course.*, course.id as real_id |
166
|
|
|
FROM $courseTable course "; |
167
|
|
|
|
168
|
|
|
if (!empty($urlId)) { |
169
|
|
|
$table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
170
|
|
|
$sql .= " INNER JOIN $table url ON (url.c_id = course.id) "; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
|
174
|
|
|
$visibility = (int) $visibility; |
175
|
|
|
|
176
|
|
|
if (!empty($startwith)) { |
177
|
|
|
$sql .= "WHERE (title LIKE '".Database::escape_string($startwith)."%' "; |
178
|
|
|
if ($alsoSearchCode) { |
179
|
|
|
$sql .= "OR code LIKE '".Database::escape_string($startwith)."%' "; |
180
|
|
|
} |
181
|
|
|
$sql .= ') '; |
182
|
|
|
if (-1 !== $visibility) { |
183
|
|
|
$sql .= " AND visibility = $visibility "; |
184
|
|
|
} |
185
|
|
|
} else { |
186
|
|
|
$sql .= 'WHERE 1 '; |
187
|
|
|
if (-1 !== $visibility) { |
188
|
|
|
$sql .= " AND visibility = $visibility "; |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
if (!empty($urlId)) { |
193
|
|
|
$urlId = (int) $urlId; |
194
|
|
|
$sql .= " AND access_url_id = $urlId"; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
if (!empty($onlyThisCourseList)) { |
198
|
|
|
$onlyThisCourseList = array_map('intval', $onlyThisCourseList); |
199
|
|
|
$onlyThisCourseList = implode("','", $onlyThisCourseList); |
200
|
|
|
$sql .= " AND course.id IN ('$onlyThisCourseList') "; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
$allowedFields = [ |
204
|
|
|
'title', |
205
|
|
|
'code', |
206
|
|
|
]; |
207
|
|
|
|
208
|
|
|
if (count($conditionsLike) > 0) { |
209
|
|
|
$sql .= ' AND '; |
210
|
|
|
$temp_conditions = []; |
211
|
|
|
foreach ($conditionsLike as $field => $value) { |
212
|
|
|
if (!in_array($field, $allowedFields)) { |
213
|
|
|
continue; |
214
|
|
|
} |
215
|
|
|
$field = Database::escape_string($field); |
216
|
|
|
$value = Database::escape_string($value); |
217
|
|
|
$simple_like = false; |
218
|
|
|
if ($simple_like) { |
219
|
|
|
$temp_conditions[] = $field." LIKE '$value%'"; |
220
|
|
|
} else { |
221
|
|
|
$temp_conditions[] = $field.' LIKE \'%'.$value.'%\''; |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
$condition = ' AND '; |
225
|
|
|
if (!empty($temp_conditions)) { |
226
|
|
|
$sql .= implode(' '.$condition.' ', $temp_conditions); |
227
|
|
|
} |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
if (empty($orderby)) { |
231
|
|
|
$sql .= ' ORDER BY title '; |
232
|
|
|
} else { |
233
|
|
|
if (in_array($orderby, ['title'])) { |
234
|
|
|
$sql .= " ORDER BY `".Database::escape_string($orderby)."` "; |
235
|
|
|
} else { |
236
|
|
|
$sql .= ' ORDER BY title '; |
237
|
|
|
} |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
$orderdirection = strtoupper($orderdirection); |
241
|
|
|
if (!in_array($orderdirection, ['ASC', 'DESC'])) { |
242
|
|
|
$sql .= 'ASC'; |
243
|
|
|
} else { |
244
|
|
|
$sql .= $orderdirection === 'ASC' ? 'ASC' : 'DESC'; |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
$howmany = (int) $howmany; |
248
|
|
|
if (!empty($howmany)) { |
249
|
|
|
$sql .= ' LIMIT '.$howmany; |
250
|
|
|
} else { |
251
|
|
|
$sql .= ' LIMIT 1000000'; //virtually no limit |
252
|
|
|
} |
253
|
|
|
if (!empty($from)) { |
254
|
|
|
$from = intval($from); |
255
|
|
|
$sql .= ' OFFSET '.intval($from); |
256
|
|
|
} else { |
257
|
|
|
$sql .= ' OFFSET 0'; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
$data = []; |
261
|
|
|
$res = Database::query($sql); |
262
|
|
|
if (Database::num_rows($res) > 0) { |
263
|
|
|
while ($row = Database::fetch_array($res, 'ASSOC')) { |
264
|
|
|
$data[] = $row; |
265
|
|
|
} |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
return $data; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Returns the status of a user in a course, which is COURSEMANAGER or STUDENT. |
273
|
|
|
* |
274
|
|
|
* @param int $userId |
275
|
|
|
* @param int $courseId |
276
|
|
|
* |
277
|
|
|
* @return int|bool the status of the user in that course (or false if the user is not in that course) |
278
|
|
|
*/ |
279
|
|
|
public static function getUserInCourseStatus($userId, $courseId) |
280
|
|
|
{ |
281
|
|
|
$courseId = (int) $courseId; |
282
|
|
|
$userId = (int) $userId; |
283
|
|
|
if (empty($courseId)) { |
284
|
|
|
return false; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
$result = Database::fetch_array( |
288
|
|
|
Database::query( |
289
|
|
|
"SELECT status FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
290
|
|
|
WHERE |
291
|
|
|
c_id = $courseId AND |
292
|
|
|
user_id = $userId" |
293
|
|
|
) |
294
|
|
|
); |
295
|
|
|
|
296
|
|
|
if (empty($result['status'])) { |
297
|
|
|
return false; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
return $result['status']; |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* @param int $userId |
305
|
|
|
* @param int $courseId |
306
|
|
|
* |
307
|
|
|
* @return mixed |
308
|
|
|
*/ |
309
|
|
|
public static function getUserCourseInfo($userId, $courseId) |
310
|
|
|
{ |
311
|
|
|
$sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
312
|
|
|
WHERE |
313
|
|
|
c_id = ".intval($courseId)." AND |
314
|
|
|
user_id = ".intval($userId); |
315
|
|
|
|
316
|
|
|
return Database::fetch_array(Database::query($sql)); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* @param int $userId |
321
|
|
|
* @param int $courseId |
322
|
|
|
* @param bool $isTutor |
323
|
|
|
* |
324
|
|
|
* @return bool |
325
|
|
|
*/ |
326
|
|
|
public static function updateUserCourseTutor($userId, $courseId, $isTutor) |
327
|
|
|
{ |
328
|
|
|
$table = Database::escape_string(TABLE_MAIN_COURSE_USER); |
329
|
|
|
|
330
|
|
|
$courseId = (int) $courseId; |
331
|
|
|
$isTutor = (int) $isTutor; |
332
|
|
|
|
333
|
|
|
$sql = "UPDATE $table SET is_tutor = '".$isTutor."' |
334
|
|
|
WHERE |
335
|
|
|
user_id = ".$userId." AND |
336
|
|
|
c_id = ".$courseId; |
337
|
|
|
|
338
|
|
|
$result = Database::query($sql); |
339
|
|
|
|
340
|
|
|
if (Database::affected_rows($result) > 0) { |
341
|
|
|
return true; |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
return false; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* @param int $userId |
349
|
|
|
* @param int $courseId |
350
|
|
|
* |
351
|
|
|
* @return mixed |
352
|
|
|
*/ |
353
|
|
|
public static function get_tutor_in_course_status($userId, $courseId) |
354
|
|
|
{ |
355
|
|
|
$userId = intval($userId); |
356
|
|
|
$courseId = intval($courseId); |
357
|
|
|
$result = Database::fetch_array( |
358
|
|
|
Database::query( |
359
|
|
|
"SELECT is_tutor |
360
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
361
|
|
|
WHERE |
362
|
|
|
c_id = $courseId AND |
363
|
|
|
user_id = $userId" |
364
|
|
|
) |
365
|
|
|
); |
366
|
|
|
|
367
|
|
|
return $result['is_tutor']; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
/** |
371
|
|
|
* Unsubscribe one or more users from a course. |
372
|
|
|
* |
373
|
|
|
* @param mixed user_id or an array with user ids |
374
|
|
|
* @param string course code |
375
|
|
|
* @param int session id |
376
|
|
|
* |
377
|
|
|
* @return bool |
378
|
|
|
* |
379
|
|
|
* @assert ('', '') === false |
380
|
|
|
*/ |
381
|
|
|
public static function unsubscribe_user($user_id, $course_code, $session_id = 0) |
382
|
|
|
{ |
383
|
|
|
if (empty($user_id)) { |
384
|
|
|
return false; |
385
|
|
|
} |
386
|
|
|
if (!is_array($user_id)) { |
387
|
|
|
$user_id = [$user_id]; |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
if (0 == count($user_id)) { |
391
|
|
|
return false; |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
if (!empty($session_id)) { |
395
|
|
|
$session_id = (int) $session_id; |
396
|
|
|
} else { |
397
|
|
|
$session_id = api_get_session_id(); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
if (empty($course_code)) { |
401
|
|
|
return false; |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
$userList = []; |
405
|
|
|
// Cleaning the $user_id variable |
406
|
|
|
if (is_array($user_id)) { |
407
|
|
|
$new_user_id_list = []; |
408
|
|
|
foreach ($user_id as $my_user_id) { |
409
|
|
|
$new_user_id_list[] = (int) $my_user_id; |
410
|
|
|
} |
411
|
|
|
$new_user_id_list = array_filter($new_user_id_list); |
412
|
|
|
$userList = $new_user_id_list; |
413
|
|
|
$user_ids = implode(',', $new_user_id_list); |
414
|
|
|
} else { |
415
|
|
|
$user_ids = (int) $user_id; |
416
|
|
|
$userList[] = $user_id; |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
$course_info = api_get_course_info($course_code); |
420
|
|
|
$course_id = $course_info['real_id']; |
421
|
|
|
|
422
|
|
|
// Unsubscribe user from all groups in the course. |
423
|
|
|
$sql = "DELETE FROM ".Database::get_course_table(TABLE_GROUP_USER)." |
424
|
|
|
WHERE c_id = $course_id AND user_id IN (".$user_ids.")"; |
425
|
|
|
Database::query($sql); |
426
|
|
|
$sql = "DELETE FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)." |
427
|
|
|
WHERE c_id = $course_id AND user_id IN (".$user_ids.")"; |
428
|
|
|
Database::query($sql); |
429
|
|
|
|
430
|
|
|
// Erase user student publications (works) in the course - by André Boivin |
431
|
|
|
// @todo this should be handled by doctrine. |
432
|
|
|
/*if (!empty($userList)) { |
433
|
|
|
foreach ($userList as $userId) { |
434
|
|
|
// Getting all work from user |
435
|
|
|
$workList = getWorkPerUser($userId); |
436
|
|
|
if (!empty($workList)) { |
437
|
|
|
foreach ($workList as $work) { |
438
|
|
|
$work = $work['work']; |
439
|
|
|
// Getting user results |
440
|
|
|
if (!empty($work->user_results)) { |
441
|
|
|
foreach ($work->user_results as $workSent) { |
442
|
|
|
deleteWorkItem($workSent['id'], $course_info); |
443
|
|
|
} |
444
|
|
|
} |
445
|
|
|
} |
446
|
|
|
} |
447
|
|
|
} |
448
|
|
|
}*/ |
449
|
|
|
|
450
|
|
|
// Unsubscribe user from all blogs in the course. |
451
|
|
|
$sql = "DELETE FROM ".Database::get_course_table(TABLE_BLOGS_REL_USER)." |
452
|
|
|
WHERE c_id = $course_id AND user_id IN ($user_ids)"; |
453
|
|
|
Database::query($sql); |
454
|
|
|
|
455
|
|
|
$sql = "DELETE FROM ".Database::get_course_table(TABLE_BLOGS_TASKS_REL_USER)." |
456
|
|
|
WHERE c_id = $course_id AND user_id IN ($user_ids)"; |
457
|
|
|
Database::query($sql); |
458
|
|
|
|
459
|
|
|
// Deleting users in forum_notification and mailqueue course tables |
460
|
|
|
$sql = "DELETE FROM ".Database::get_course_table(TABLE_FORUM_NOTIFICATION)." |
461
|
|
|
WHERE c_id = $course_id AND user_id IN ($user_ids)"; |
462
|
|
|
Database::query($sql); |
463
|
|
|
|
464
|
|
|
$sql = "DELETE FROM ".Database::get_course_table(TABLE_FORUM_MAIL_QUEUE)." |
465
|
|
|
WHERE c_id = $course_id AND user_id IN ($user_ids)"; |
466
|
|
|
Database::query($sql); |
467
|
|
|
|
468
|
|
|
// Unsubscribe user from the course. |
469
|
|
|
if (!empty($session_id)) { |
470
|
|
|
foreach ($userList as $uid) { |
471
|
|
|
SessionManager::unSubscribeUserFromCourseSession($uid, $course_id, $session_id); |
472
|
|
|
|
473
|
|
|
// check if a user is register in the session with other course |
474
|
|
|
$sql = "SELECT user_id FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)." |
475
|
|
|
WHERE session_id = $session_id AND user_id = $uid"; |
476
|
|
|
$rs = Database::query($sql); |
477
|
|
|
|
478
|
|
|
if (0 == Database::num_rows($rs)) { |
479
|
|
|
SessionManager::unsubscribe_user_from_session($uid, $session_id); |
480
|
|
|
} |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
Event::addEvent( |
484
|
|
|
LOG_UNSUBSCRIBE_USER_FROM_COURSE, |
485
|
|
|
LOG_COURSE_CODE, |
486
|
|
|
$course_code, |
487
|
|
|
api_get_utc_datetime(), |
488
|
|
|
$user_id, |
489
|
|
|
$course_id, |
490
|
|
|
$session_id |
491
|
|
|
); |
492
|
|
|
} else { |
493
|
|
|
$sql = "DELETE FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
494
|
|
|
WHERE |
495
|
|
|
user_id IN ($user_ids) AND |
496
|
|
|
relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND |
497
|
|
|
c_id = $course_id"; |
498
|
|
|
Database::query($sql); |
499
|
|
|
|
500
|
|
|
// add event to system log |
501
|
|
|
$user_id = api_get_user_id(); |
502
|
|
|
|
503
|
|
|
Event::addEvent( |
504
|
|
|
LOG_UNSUBSCRIBE_USER_FROM_COURSE, |
505
|
|
|
LOG_COURSE_CODE, |
506
|
|
|
$course_code, |
507
|
|
|
api_get_utc_datetime(), |
508
|
|
|
$user_id, |
509
|
|
|
$course_id |
510
|
|
|
); |
511
|
|
|
|
512
|
|
|
foreach ($userList as $userId) { |
513
|
|
|
$userInfo = api_get_user_info($userId); |
514
|
|
|
Event::addEvent( |
515
|
|
|
LOG_UNSUBSCRIBE_USER_FROM_COURSE, |
516
|
|
|
LOG_USER_OBJECT, |
517
|
|
|
$userInfo, |
518
|
|
|
api_get_utc_datetime(), |
519
|
|
|
$user_id, |
520
|
|
|
$course_id |
521
|
|
|
); |
522
|
|
|
} |
523
|
|
|
} |
524
|
|
|
if (api_get_configuration_value('catalog_course_subscription_in_user_s_session')) { |
525
|
|
|
// Also unlink the course from the users' currently accessible sessions |
526
|
|
|
/** @var Course $course */ |
527
|
|
|
$course = Container::getCourseRepository()->findOneBy([ |
528
|
|
|
'code' => $course_code, |
529
|
|
|
]); |
530
|
|
|
if (is_null($course)) { |
531
|
|
|
return false; |
532
|
|
|
} |
533
|
|
|
/** @var Chamilo\CoreBundle\Entity\User $user */ |
534
|
|
|
foreach (UserManager::getRepository()->matching( |
535
|
|
|
Criteria::create()->where(Criteria::expr()->in('id', $userList)) |
536
|
|
|
) as $user) { |
537
|
|
|
foreach ($user->getCurrentlyAccessibleSessions() as $session) { |
538
|
|
|
$session->removeCourse($course); |
539
|
|
|
// unsubscribe user from course within this session |
540
|
|
|
SessionManager::unSubscribeUserFromCourseSession($user->getId(), $course->getId(), $session->getId()); |
541
|
|
|
} |
542
|
|
|
} |
543
|
|
|
try { |
544
|
|
|
Database::getManager()->flush(); |
545
|
|
|
} catch (\Doctrine\ORM\OptimisticLockException $exception) { |
546
|
|
|
Display::addFlash( |
547
|
|
|
Display::return_message( |
548
|
|
|
get_lang('InternalDatabaseError').': '.$exception->getMessage(), |
549
|
|
|
'warning' |
550
|
|
|
) |
551
|
|
|
); |
552
|
|
|
|
553
|
|
|
return false; |
554
|
|
|
} |
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
return true; |
558
|
|
|
} |
559
|
|
|
|
560
|
|
|
/** |
561
|
|
|
* @param string $courseCode |
562
|
|
|
* @param int $status |
563
|
|
|
* |
564
|
|
|
* @return bool |
565
|
|
|
*/ |
566
|
|
|
public static function autoSubscribeToCourse($courseCode, $status = STUDENT) |
567
|
|
|
{ |
568
|
|
|
if (api_is_anonymous()) { |
569
|
|
|
return false; |
570
|
|
|
} |
571
|
|
|
|
572
|
|
|
$course = Container::getCourseRepository()->findOneBy(['code' => $courseCode]); |
573
|
|
|
|
574
|
|
|
if (null === $course) { |
575
|
|
|
return false; |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
$visibility = (int) $course->getVisibility(); |
579
|
|
|
|
580
|
|
|
if (in_array($visibility, [ |
581
|
|
|
Course::CLOSED, |
582
|
|
|
//Course::REGISTERED, |
583
|
|
|
Course::HIDDEN, |
584
|
|
|
])) { |
585
|
|
|
Display::addFlash( |
586
|
|
|
Display::return_message( |
587
|
|
|
get_lang('SubscribingNotAllowed'), |
588
|
|
|
'warning' |
589
|
|
|
) |
590
|
|
|
); |
591
|
|
|
|
592
|
|
|
return false; |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
// Private course can allow auto subscription |
596
|
|
|
if (Course::REGISTERED === $visibility && false === $course->getSubscribe()) { |
597
|
|
|
Display::addFlash( |
598
|
|
|
Display::return_message( |
599
|
|
|
get_lang('Subscribing not allowed'), |
600
|
|
|
'warning' |
601
|
|
|
) |
602
|
|
|
); |
603
|
|
|
|
604
|
|
|
return false; |
605
|
|
|
} |
606
|
|
|
|
607
|
|
|
$userId = api_get_user_id(); |
608
|
|
|
|
609
|
|
|
if (api_get_configuration_value('catalog_course_subscription_in_user_s_session')) { |
610
|
|
|
$user = api_get_user_entity($userId); |
611
|
|
|
$sessions = $user->getCurrentlyAccessibleSessions(); |
612
|
|
|
if (empty($sessions)) { |
613
|
|
|
// user has no accessible session |
614
|
|
|
if ($user->getStudentSessions()) { |
615
|
|
|
// user has ancient or future student session(s) but not available now |
616
|
|
|
Display::addFlash( |
617
|
|
|
Display::return_message( |
618
|
|
|
get_lang('CanNotSubscribeToCourseUserSessionExpired'), |
619
|
|
|
'warning' |
620
|
|
|
) |
621
|
|
|
); |
622
|
|
|
|
623
|
|
|
return false; |
624
|
|
|
} |
625
|
|
|
// user has no session at all, create one starting now |
626
|
|
|
$numberOfDays = api_get_configuration_value('user_s_session_duration') ?: 3 * 365; |
627
|
|
|
try { |
628
|
|
|
$duration = new DateInterval(sprintf('P%dD', $numberOfDays)); |
629
|
|
|
} catch (Exception $exception) { |
630
|
|
|
Display::addFlash( |
631
|
|
|
Display::return_message( |
632
|
|
|
get_lang('WrongNumberOfDays').': '.$numberOfDays.': '.$exception->getMessage(), |
633
|
|
|
'warning' |
634
|
|
|
) |
635
|
|
|
); |
636
|
|
|
|
637
|
|
|
return false; |
638
|
|
|
} |
639
|
|
|
$endDate = new DateTime(); |
640
|
|
|
$endDate->add($duration); |
641
|
|
|
$session = new \Chamilo\CoreBundle\Entity\Session(); |
642
|
|
|
$session->setName( |
643
|
|
|
sprintf(get_lang('FirstnameLastnameCourses'), $user->getFirstname(), $user->getLastname()) |
644
|
|
|
); |
645
|
|
|
$session->setAccessEndDate($endDate); |
646
|
|
|
$session->setCoachAccessEndDate($endDate); |
647
|
|
|
$session->setDisplayEndDate($endDate); |
648
|
|
|
$session->setSendSubscriptionNotification(false); |
649
|
|
|
$adminId = api_get_configuration_value('session_automatic_creation_user_id') ?: 1; |
650
|
|
|
$session->setSessionAdmin(api_get_user_entity($adminId)); |
651
|
|
|
$session->addUserInSession(0, $user); |
652
|
|
|
Database::getManager()->persist($session); |
653
|
|
|
try { |
654
|
|
|
Database::getManager()->flush(); |
655
|
|
|
} catch (\Doctrine\ORM\OptimisticLockException $exception) { |
656
|
|
|
Display::addFlash( |
657
|
|
|
Display::return_message( |
658
|
|
|
get_lang('InternalDatabaseError').': '.$exception->getMessage(), |
659
|
|
|
'warning' |
660
|
|
|
) |
661
|
|
|
); |
662
|
|
|
|
663
|
|
|
return false; |
664
|
|
|
} |
665
|
|
|
$accessUrlRelSession = new AccessUrlRelSession(); |
666
|
|
|
$accessUrlRelSession->setUrl(api_get_url_entity()); |
667
|
|
|
$accessUrlRelSession->setSession($session); |
668
|
|
|
Database::getManager()->persist($accessUrlRelSession); |
669
|
|
|
try { |
670
|
|
|
Database::getManager()->flush(); |
671
|
|
|
} catch (\Doctrine\ORM\OptimisticLockException $exception) { |
672
|
|
|
Display::addFlash( |
673
|
|
|
Display::return_message( |
674
|
|
|
get_lang('InternalDatabaseError').': '.$exception->getMessage(), |
675
|
|
|
'warning' |
676
|
|
|
) |
677
|
|
|
); |
678
|
|
|
|
679
|
|
|
return false; |
680
|
|
|
} |
681
|
|
|
} else { |
682
|
|
|
// user has at least one accessible session, let's use it |
683
|
|
|
$session = $sessions[0]; |
684
|
|
|
} |
685
|
|
|
// add chosen course to the user session |
686
|
|
|
$session->addCourse($course); |
687
|
|
|
Database::getManager()->persist($session); |
688
|
|
|
try { |
689
|
|
|
Database::getManager()->flush(); |
690
|
|
|
} catch (\Doctrine\ORM\OptimisticLockException $exception) { |
691
|
|
|
Display::addFlash( |
692
|
|
|
Display::return_message( |
693
|
|
|
get_lang('InternalDatabaseError').': '.$exception->getMessage(), |
694
|
|
|
'warning' |
695
|
|
|
) |
696
|
|
|
); |
697
|
|
|
|
698
|
|
|
return false; |
699
|
|
|
} |
700
|
|
|
// subscribe user to course within this session |
701
|
|
|
SessionManager::subscribe_users_to_session_course([$userId], $session->getId(), $course->getCode()); |
702
|
|
|
|
703
|
|
|
return true; |
704
|
|
|
} |
705
|
|
|
|
706
|
|
|
return self::subscribeUser($userId, $course->getId(), $status, 0); |
707
|
|
|
} |
708
|
|
|
|
709
|
|
|
/** |
710
|
|
|
* Subscribe a user to a course. No checks are performed here to see if |
711
|
|
|
* course subscription is allowed. |
712
|
|
|
* |
713
|
|
|
* @param int $userId |
714
|
|
|
* @param int $courseId |
715
|
|
|
* @param int $status (STUDENT, COURSEMANAGER, COURSE_ADMIN, NORMAL_COURSE_MEMBER) |
716
|
|
|
* @param int $sessionId |
717
|
|
|
* @param int $userCourseCategoryId |
718
|
|
|
* @param bool $checkTeacherPermission |
719
|
|
|
* |
720
|
|
|
* @return bool True on success, false on failure |
721
|
|
|
* |
722
|
|
|
* @assert ('', '') === false |
723
|
|
|
*/ |
724
|
|
|
public static function subscribeUser( |
725
|
|
|
$userId, |
726
|
|
|
$courseId, |
727
|
|
|
$status = STUDENT, |
728
|
|
|
$sessionId = 0, |
729
|
|
|
$userCourseCategoryId = 0, |
730
|
|
|
$checkTeacherPermission = true |
731
|
|
|
) { |
732
|
|
|
$userId = (int) $userId; |
733
|
|
|
$status = (int) $status; |
734
|
|
|
|
735
|
|
|
if (empty($userId) || empty($courseId)) { |
736
|
|
|
return false; |
737
|
|
|
} |
738
|
|
|
|
739
|
|
|
$course = api_get_course_entity($courseId); |
740
|
|
|
|
741
|
|
|
if (null === $course) { |
742
|
|
|
Display::addFlash(Display::return_message(get_lang('This course doesn\'t exist'), 'warning')); |
743
|
|
|
|
744
|
|
|
return false; |
745
|
|
|
} |
746
|
|
|
|
747
|
|
|
$user = api_get_user_entity($userId); |
748
|
|
|
|
749
|
|
|
if (null === $user) { |
750
|
|
|
Display::addFlash(Display::return_message(get_lang('This user doesn\'t exist'), 'warning')); |
751
|
|
|
|
752
|
|
|
return false; |
753
|
|
|
} |
754
|
|
|
|
755
|
|
|
$courseCode = $course->getCode(); |
756
|
|
|
$userCourseCategoryId = (int) $userCourseCategoryId; |
757
|
|
|
$sessionId = empty($sessionId) ? api_get_session_id() : (int) $sessionId; |
758
|
|
|
$status = STUDENT === $status || COURSEMANAGER === $status ? $status : STUDENT; |
759
|
|
|
|
760
|
|
|
if (!empty($sessionId)) { |
761
|
|
|
SessionManager::subscribe_users_to_session_course( |
762
|
|
|
[$userId], |
763
|
|
|
$sessionId, |
764
|
|
|
$courseCode |
765
|
|
|
); |
766
|
|
|
|
767
|
|
|
return true; |
768
|
|
|
} else { |
769
|
|
|
// Check whether the user has not been already subscribed to the course. |
770
|
|
|
$sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
771
|
|
|
WHERE |
772
|
|
|
user_id = $userId AND |
773
|
|
|
relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND |
774
|
|
|
c_id = $courseId |
775
|
|
|
"; |
776
|
|
|
if (Database::num_rows(Database::query($sql)) > 0) { |
777
|
|
|
Display::addFlash(Display::return_message(get_lang('Already registered in course'), 'warning')); |
778
|
|
|
|
779
|
|
|
return false; |
780
|
|
|
} |
781
|
|
|
|
782
|
|
|
if ($checkTeacherPermission && !api_is_course_admin()) { |
783
|
|
|
// Check in advance whether subscription is allowed or not for this course. |
784
|
|
|
if (SUBSCRIBE_NOT_ALLOWED === (int) $course->getSubscribe()) { |
785
|
|
|
Display::addFlash(Display::return_message(get_lang('Subscription not allowed'), 'warning')); |
786
|
|
|
|
787
|
|
|
return false; |
788
|
|
|
} |
789
|
|
|
} |
790
|
|
|
|
791
|
|
|
if (STUDENT === $status) { |
792
|
|
|
// Check if max students per course extra field is set |
793
|
|
|
$extraFieldValue = new ExtraFieldValue('course'); |
794
|
|
|
$value = $extraFieldValue->get_values_by_handler_and_field_variable( |
795
|
|
|
$courseId, |
796
|
|
|
'max_subscribed_students' |
797
|
|
|
); |
798
|
|
|
if (!empty($value) && isset($value['value']) && '' !== $value['value']) { |
799
|
|
|
$maxStudents = (int) $value['value']; |
800
|
|
|
$count = self::get_user_list_from_course_code( |
801
|
|
|
$courseCode, |
802
|
|
|
0, |
803
|
|
|
null, |
804
|
|
|
null, |
805
|
|
|
STUDENT, |
806
|
|
|
true, |
807
|
|
|
false |
808
|
|
|
); |
809
|
|
|
|
810
|
|
|
if ($count >= $maxStudents) { |
811
|
|
|
Display::addFlash( |
812
|
|
|
Display::return_message( |
813
|
|
|
get_lang( |
814
|
|
|
'The maximum number of student has already been reached, it is not possible to subscribe more student.' |
815
|
|
|
), |
816
|
|
|
'warning' |
817
|
|
|
) |
818
|
|
|
); |
819
|
|
|
|
820
|
|
|
return false; |
821
|
|
|
} |
822
|
|
|
} |
823
|
|
|
} |
824
|
|
|
|
825
|
|
|
$maxSort = api_max_sort_value(0, $userId) + 1; |
826
|
|
|
|
827
|
|
|
$insertId = self::insertUserInCourse( |
828
|
|
|
$user, |
829
|
|
|
$course, |
830
|
|
|
['status' => $status, 'sort' => $maxSort, 'user_course_cat' => $userCourseCategoryId] |
831
|
|
|
); |
832
|
|
|
|
833
|
|
|
if ($insertId) { |
834
|
|
|
Display::addFlash( |
835
|
|
|
Display::return_message( |
836
|
|
|
sprintf( |
837
|
|
|
get_lang('User %s has been registered to course %s'), |
838
|
|
|
UserManager::formatUserFullName($user, true), |
839
|
|
|
$course->getTitle() |
840
|
|
|
) |
841
|
|
|
) |
842
|
|
|
); |
843
|
|
|
|
844
|
|
|
$send = (int) api_get_course_setting('email_alert_to_teacher_on_new_user_in_course', $course); |
845
|
|
|
|
846
|
|
|
if (1 === $send) { |
847
|
|
|
self::email_to_tutor( |
848
|
|
|
$userId, |
849
|
|
|
$courseId, |
850
|
|
|
false |
851
|
|
|
); |
852
|
|
|
} elseif (2 === $send) { |
853
|
|
|
self::email_to_tutor( |
854
|
|
|
$userId, |
855
|
|
|
$courseId, |
856
|
|
|
true |
857
|
|
|
); |
858
|
|
|
} |
859
|
|
|
|
860
|
|
|
$subscribe = (int) api_get_course_setting('subscribe_users_to_forum_notifications', $course); |
861
|
|
|
if (1 === $subscribe) { |
862
|
|
|
/*$forums = get_forums(0, true, $sessionId); |
863
|
|
|
foreach ($forums as $forum) { |
864
|
|
|
set_notification('forum', $forum->getIid(), false, $userInfo, $courseInfo); |
865
|
|
|
}*/ |
866
|
|
|
} |
867
|
|
|
|
868
|
|
|
return true; |
869
|
|
|
} |
870
|
|
|
|
871
|
|
|
return false; |
872
|
|
|
} |
873
|
|
|
} |
874
|
|
|
|
875
|
|
|
/** |
876
|
|
|
* Get the course id based on the original id and field name in the |
877
|
|
|
* extra fields. Returns 0 if course was not found. |
878
|
|
|
* |
879
|
|
|
* @param string $original_course_id_value |
880
|
|
|
* @param string $original_course_id_name |
881
|
|
|
* |
882
|
|
|
* @return int Course id |
883
|
|
|
* |
884
|
|
|
* @assert ('', '') === false |
885
|
|
|
*/ |
886
|
|
|
public static function get_course_code_from_original_id( |
887
|
|
|
$original_course_id_value, |
888
|
|
|
$original_course_id_name |
889
|
|
|
) { |
890
|
|
|
$t_cfv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
891
|
|
|
$table_field = Database::get_main_table(TABLE_EXTRA_FIELD); |
892
|
|
|
$extraFieldType = EntityExtraField::COURSE_FIELD_TYPE; |
893
|
|
|
$original_course_id_value = Database::escape_string($original_course_id_value); |
894
|
|
|
$original_course_id_name = Database::escape_string($original_course_id_name); |
895
|
|
|
|
896
|
|
|
$sql = "SELECT item_id |
897
|
|
|
FROM $table_field cf |
898
|
|
|
INNER JOIN $t_cfv cfv |
899
|
|
|
ON cfv.field_id=cf.id |
900
|
|
|
WHERE |
901
|
|
|
variable = '$original_course_id_name' AND |
902
|
|
|
value = '$original_course_id_value' AND |
903
|
|
|
cf.extra_field_type = $extraFieldType |
904
|
|
|
"; |
905
|
|
|
$res = Database::query($sql); |
906
|
|
|
$row = Database::fetch_object($res); |
907
|
|
|
if ($row) { |
908
|
|
|
return $row->item_id; |
909
|
|
|
} else { |
910
|
|
|
return 0; |
911
|
|
|
} |
912
|
|
|
} |
913
|
|
|
|
914
|
|
|
/** |
915
|
|
|
* Gets the course code from the course id. Returns null if course id was not found. |
916
|
|
|
* |
917
|
|
|
* @param int $id Course id |
918
|
|
|
* |
919
|
|
|
* @return string Course code |
920
|
|
|
* @assert ('') === false |
921
|
|
|
*/ |
922
|
|
|
public static function get_course_code_from_course_id($id) |
923
|
|
|
{ |
924
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
925
|
|
|
$id = intval($id); |
926
|
|
|
$sql = "SELECT code FROM $table WHERE id = $id "; |
927
|
|
|
$res = Database::query($sql); |
928
|
|
|
$row = Database::fetch_object($res); |
929
|
|
|
if ($row) { |
930
|
|
|
return $row->code; |
931
|
|
|
} else { |
932
|
|
|
return null; |
933
|
|
|
} |
934
|
|
|
} |
935
|
|
|
|
936
|
|
|
/** |
937
|
|
|
* Add the user $userId visibility to the course $courseCode in the catalogue. |
938
|
|
|
* |
939
|
|
|
* @author David Nos (https://github.com/dnos) |
940
|
|
|
* |
941
|
|
|
* @param int $userId the id of the user |
942
|
|
|
* @param string $courseCode the course code |
943
|
|
|
* @param int $visible (optional) The course visibility in the catalogue to the user (1=visible, 0=invisible) |
944
|
|
|
* |
945
|
|
|
* @return bool true if added succesfully, false otherwise |
946
|
|
|
*/ |
947
|
|
|
public static function addUserVisibilityToCourseInCatalogue( |
948
|
|
|
$userId, |
949
|
|
|
$courseCode, |
950
|
|
|
$visible = 1 |
951
|
|
|
) { |
952
|
|
|
$debug = false; |
953
|
|
|
$userTable = Database::get_main_table(TABLE_MAIN_USER); |
954
|
|
|
$courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER); |
955
|
|
|
$visible = (int) $visible; |
956
|
|
|
if (empty($userId) || empty($courseCode) || ($userId != strval(intval($userId)))) { |
957
|
|
|
return false; |
958
|
|
|
} |
959
|
|
|
|
960
|
|
|
$courseCode = Database::escape_string($courseCode); |
961
|
|
|
$courseInfo = api_get_course_info($courseCode); |
962
|
|
|
$courseId = $courseInfo['real_id']; |
963
|
|
|
|
964
|
|
|
// Check in advance whether the user has already been registered on the platform. |
965
|
|
|
$sql = "SELECT status FROM ".$userTable." WHERE user_id = $userId "; |
966
|
|
|
if (0 == Database::num_rows(Database::query($sql))) { |
967
|
|
|
if ($debug) { |
968
|
|
|
error_log('The user has not been registered to the platform'); |
969
|
|
|
} |
970
|
|
|
|
971
|
|
|
return false; // The user has not been registered to the platform. |
972
|
|
|
} |
973
|
|
|
|
974
|
|
|
// Check whether the user has already been registered to the course visibility in the catalogue. |
975
|
|
|
$sql = "SELECT * FROM $courseUserTable |
976
|
|
|
WHERE |
977
|
|
|
user_id = $userId AND |
978
|
|
|
visible = $visible AND |
979
|
|
|
c_id = $courseId"; |
980
|
|
|
if (Database::num_rows(Database::query($sql)) > 0) { |
981
|
|
|
if ($debug) { |
982
|
|
|
error_log('The user has been already registered to the course visibility in the catalogue'); |
983
|
|
|
} |
984
|
|
|
|
985
|
|
|
return true; // The visibility of the user to the course in the catalogue does already exist. |
986
|
|
|
} |
987
|
|
|
|
988
|
|
|
// Register the user visibility to course in catalogue. |
989
|
|
|
$params = [ |
990
|
|
|
'user_id' => $userId, |
991
|
|
|
'c_id' => $courseId, |
992
|
|
|
'visible' => $visible, |
993
|
|
|
]; |
994
|
|
|
|
995
|
|
|
return Database::insert($courseUserTable, $params); |
996
|
|
|
} |
997
|
|
|
|
998
|
|
|
/** |
999
|
|
|
* Remove the user $userId visibility to the course $courseCode in the catalogue. |
1000
|
|
|
* |
1001
|
|
|
* @author David Nos (https://github.com/dnos) |
1002
|
|
|
* |
1003
|
|
|
* @param int $userId the id of the user |
1004
|
|
|
* @param string $courseCode the course code |
1005
|
|
|
* @param int $visible (optional) The course visibility in the catalogue to the user (1=visible, 0=invisible) |
1006
|
|
|
* |
1007
|
|
|
* @return bool true if removed succesfully or register not found, false otherwise |
1008
|
|
|
*/ |
1009
|
|
|
public static function removeUserVisibilityToCourseInCatalogue( |
1010
|
|
|
$userId, |
1011
|
|
|
$courseCode, |
1012
|
|
|
$visible = 1 |
1013
|
|
|
) { |
1014
|
|
|
$courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER); |
1015
|
|
|
|
1016
|
|
|
if (empty($userId) || empty($courseCode) || ($userId != strval(intval($userId)))) { |
1017
|
|
|
return false; |
1018
|
|
|
} |
1019
|
|
|
|
1020
|
|
|
$courseCode = Database::escape_string($courseCode); |
1021
|
|
|
$courseInfo = api_get_course_info($courseCode); |
1022
|
|
|
$courseId = $courseInfo['real_id']; |
1023
|
|
|
|
1024
|
|
|
// Check whether the user has already been registered to the course visibility in the catalogue. |
1025
|
|
|
$sql = "SELECT * FROM $courseUserTable |
1026
|
|
|
WHERE |
1027
|
|
|
user_id = $userId AND |
1028
|
|
|
visible = $visible AND |
1029
|
|
|
c_id = $courseId"; |
1030
|
|
|
if (Database::num_rows(Database::query($sql)) > 0) { |
1031
|
|
|
$cond = [ |
1032
|
|
|
'user_id = ? AND c_id = ? AND visible = ? ' => [ |
1033
|
|
|
$userId, |
1034
|
|
|
$courseId, |
1035
|
|
|
$visible, |
1036
|
|
|
], |
1037
|
|
|
]; |
1038
|
|
|
|
1039
|
|
|
return Database::delete($courseUserTable, $cond); |
1040
|
|
|
} else { |
1041
|
|
|
return true; // Register does not exist |
1042
|
|
|
} |
1043
|
|
|
} |
1044
|
|
|
|
1045
|
|
|
/** |
1046
|
|
|
* @param string $code |
1047
|
|
|
* |
1048
|
|
|
* @return bool if there already are one or more courses |
1049
|
|
|
* with the same code OR visual_code (visualcode), false otherwise |
1050
|
|
|
*/ |
1051
|
|
|
public static function course_code_exists($code) |
1052
|
|
|
{ |
1053
|
|
|
$code = Database::escape_string($code); |
1054
|
|
|
$sql = "SELECT COUNT(*) as number |
1055
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." |
1056
|
|
|
WHERE code = '$code' OR visual_code = '$code'"; |
1057
|
|
|
$result = Database::fetch_array(Database::query($sql)); |
1058
|
|
|
|
1059
|
|
|
return $result['number'] > 0; |
1060
|
|
|
} |
1061
|
|
|
|
1062
|
|
|
/** |
1063
|
|
|
* @param int $userId |
1064
|
|
|
* @param string $keyword |
1065
|
|
|
* |
1066
|
|
|
* @return array an array with the course info of all the courses (real and virtual) |
1067
|
|
|
* of which the current user is course admin |
1068
|
|
|
*/ |
1069
|
|
|
public static function get_course_list_of_user_as_course_admin($userId, $keyword = '') |
1070
|
|
|
{ |
1071
|
|
|
$user = api_get_user_entity($userId); |
1072
|
|
|
|
1073
|
|
|
if (null === $user) { |
1074
|
|
|
return []; |
1075
|
|
|
} |
1076
|
|
|
|
1077
|
|
|
$url = api_get_url_entity(); |
1078
|
|
|
$user = api_get_user_entity($userId); |
1079
|
|
|
$repo = Container::getUserRepository(); |
1080
|
|
|
|
1081
|
|
|
return $repo->getCourses($user, $url, COURSEMANAGER, $keyword); |
1082
|
|
|
} |
1083
|
|
|
|
1084
|
|
|
/** |
1085
|
|
|
* @param int $userId |
1086
|
|
|
* @param array $courseInfo |
1087
|
|
|
* |
1088
|
|
|
* @return bool|null |
1089
|
|
|
*/ |
1090
|
|
|
public static function isUserSubscribedInCourseAsDrh($userId, $courseInfo) |
1091
|
|
|
{ |
1092
|
|
|
$userId = intval($userId); |
1093
|
|
|
|
1094
|
|
|
if (!api_is_drh()) { |
1095
|
|
|
return false; |
1096
|
|
|
} |
1097
|
|
|
|
1098
|
|
|
if (empty($courseInfo) || empty($userId)) { |
1099
|
|
|
return false; |
1100
|
|
|
} |
1101
|
|
|
|
1102
|
|
|
$courseId = intval($courseInfo['real_id']); |
1103
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
1104
|
|
|
|
1105
|
|
|
$sql = "SELECT * FROM $table |
1106
|
|
|
WHERE |
1107
|
|
|
user_id = $userId AND |
1108
|
|
|
relation_type = ".COURSE_RELATION_TYPE_RRHH." AND |
1109
|
|
|
c_id = $courseId"; |
1110
|
|
|
|
1111
|
|
|
$result = Database::fetch_array(Database::query($sql)); |
1112
|
|
|
|
1113
|
|
|
if (!empty($result)) { |
1114
|
|
|
// The user has been registered in this course. |
1115
|
|
|
return true; |
1116
|
|
|
} |
1117
|
|
|
} |
1118
|
|
|
|
1119
|
|
|
/** |
1120
|
|
|
* Check if user is subscribed inside a course. |
1121
|
|
|
* |
1122
|
|
|
* @param int $userId |
1123
|
|
|
* @param string $course_code , if this parameter is null, it'll check for all courses |
1124
|
|
|
* @param bool $in_a_session True for checking inside sessions too, by default is not checked |
1125
|
|
|
* @param int $session_id |
1126
|
|
|
* |
1127
|
|
|
* @return bool $session_id true if the user is registered in the course, false otherwise |
1128
|
|
|
*/ |
1129
|
|
|
public static function is_user_subscribed_in_course( |
1130
|
|
|
$userId, |
1131
|
|
|
$course_code = null, |
1132
|
|
|
$in_a_session = false, |
1133
|
|
|
$session_id = 0 |
1134
|
|
|
) { |
1135
|
|
|
$userId = (int) $userId; |
1136
|
|
|
$session_id = (int) $session_id; |
1137
|
|
|
|
1138
|
|
|
if (api_get_configuration_value('catalog_course_subscription_in_user_s_session')) { |
1139
|
|
|
// with this option activated, only check whether the course is in one of the users' sessions |
1140
|
|
|
$course = Container::getCourseRepository()->findOneBy([ |
1141
|
|
|
'code' => $course_code, |
1142
|
|
|
]); |
1143
|
|
|
if (is_null($course)) { |
1144
|
|
|
return false; |
1145
|
|
|
} |
1146
|
|
|
|
1147
|
|
|
$user = api_get_user_entity($userId); |
1148
|
|
|
if (is_null($user)) { |
1149
|
|
|
return false; |
1150
|
|
|
} |
1151
|
|
|
foreach ($user->getStudentSessions() as $session) { |
1152
|
|
|
if ($session->isRelatedToCourse($course)) { |
1153
|
|
|
return true; |
1154
|
|
|
} |
1155
|
|
|
} |
1156
|
|
|
|
1157
|
|
|
return false; |
1158
|
|
|
} |
1159
|
|
|
|
1160
|
|
|
if (empty($session_id)) { |
1161
|
|
|
$session_id = api_get_session_id(); |
1162
|
|
|
} |
1163
|
|
|
|
1164
|
|
|
$condition_course = ''; |
1165
|
|
|
if (isset($course_code)) { |
1166
|
|
|
$courseInfo = api_get_course_info($course_code); |
1167
|
|
|
if (empty($courseInfo)) { |
1168
|
|
|
return false; |
1169
|
|
|
} |
1170
|
|
|
$courseId = $courseInfo['real_id']; |
1171
|
|
|
$condition_course = " AND c_id = $courseId"; |
1172
|
|
|
} |
1173
|
|
|
|
1174
|
|
|
$sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
1175
|
|
|
WHERE |
1176
|
|
|
user_id = $userId AND |
1177
|
|
|
relation_type<>".COURSE_RELATION_TYPE_RRHH." |
1178
|
|
|
$condition_course "; |
1179
|
|
|
|
1180
|
|
|
$result = Database::fetch_array(Database::query($sql)); |
1181
|
|
|
|
1182
|
|
|
if (!empty($result)) { |
1183
|
|
|
// The user has been registered in this course. |
1184
|
|
|
return true; |
1185
|
|
|
} |
1186
|
|
|
|
1187
|
|
|
if (!$in_a_session) { |
1188
|
|
|
// The user has not been registered in this course. |
1189
|
|
|
return false; |
1190
|
|
|
} |
1191
|
|
|
|
1192
|
|
|
$tableSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
1193
|
|
|
$sql = "SELECT 1 FROM $tableSessionCourseUser |
1194
|
|
|
WHERE user_id = $userId AND session_id = $session_id $condition_course"; |
1195
|
|
|
|
1196
|
|
|
if (Database::num_rows(Database::query($sql)) > 0) { |
1197
|
|
|
return true; |
1198
|
|
|
} |
1199
|
|
|
|
1200
|
|
|
$sql = "SELECT 1 FROM $tableSessionCourseUser |
1201
|
|
|
WHERE user_id = $userId AND session_id = $session_id AND status = 2 $condition_course"; |
1202
|
|
|
|
1203
|
|
|
if (Database::num_rows(Database::query($sql)) > 0) { |
1204
|
|
|
return true; |
1205
|
|
|
} |
1206
|
|
|
|
1207
|
|
|
$sql = 'SELECT 1 FROM '.Database::get_main_table(TABLE_MAIN_SESSION). |
1208
|
|
|
" WHERE id = $session_id AND id_coach = $userId"; |
1209
|
|
|
|
1210
|
|
|
if (Database::num_rows(Database::query($sql)) > 0) { |
1211
|
|
|
return true; |
1212
|
|
|
} |
1213
|
|
|
|
1214
|
|
|
return false; |
1215
|
|
|
} |
1216
|
|
|
|
1217
|
|
|
/** |
1218
|
|
|
* Is the user a teacher in the given course? |
1219
|
|
|
* |
1220
|
|
|
* @param int $userId |
1221
|
|
|
* @param int $courseId |
1222
|
|
|
* |
1223
|
|
|
* @return bool if the user is a teacher in the course, false otherwise |
1224
|
|
|
*/ |
1225
|
|
|
public static function isCourseTeacher($userId, $courseId) |
1226
|
|
|
{ |
1227
|
|
|
$userId = (int) $userId; |
1228
|
|
|
$courseId = (int) $courseId; |
1229
|
|
|
|
1230
|
|
|
if (empty($courseId) || empty($userId)) { |
1231
|
|
|
return false; |
1232
|
|
|
} |
1233
|
|
|
|
1234
|
|
|
$sql = "SELECT status FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
1235
|
|
|
WHERE c_id = $courseId AND user_id = $userId "; |
1236
|
|
|
$result = Database::query($sql); |
1237
|
|
|
|
1238
|
|
|
if (Database::num_rows($result) > 0) { |
1239
|
|
|
return 1 == Database::result($result, 0, 'status'); |
1240
|
|
|
} |
1241
|
|
|
|
1242
|
|
|
return false; |
1243
|
|
|
} |
1244
|
|
|
|
1245
|
|
|
/** |
1246
|
|
|
* Return user info array of all users registered in a course |
1247
|
|
|
* This only returns the users that are registered in this actual course, not linked courses. |
1248
|
|
|
* |
1249
|
|
|
* @param string $courseCode |
1250
|
|
|
* @param int $sessionId |
1251
|
|
|
* @param string $limit |
1252
|
|
|
* @param string $order_by the field to order the users by. |
1253
|
|
|
* Valid values are 'lastname', 'firstname', 'username', 'email', |
1254
|
|
|
* 'official_code' OR a part of a SQL statement that starts with ORDER BY ... |
1255
|
|
|
* @param int|null $filter_by_status if using the session_id: 0 or 2 (student, coach), |
1256
|
|
|
* if using session_id = 0 STUDENT or COURSEMANAGER |
1257
|
|
|
* @param bool|null $return_count |
1258
|
|
|
* @param bool $add_reports |
1259
|
|
|
* @param bool $resumed_report |
1260
|
|
|
* @param array $extra_field |
1261
|
|
|
* @param array $courseCodeList |
1262
|
|
|
* @param array $userIdList |
1263
|
|
|
* @param string $filterByActive |
1264
|
|
|
* @param array $sessionIdList |
1265
|
|
|
* @param string $searchByKeyword |
1266
|
|
|
* |
1267
|
|
|
* @return array|int |
1268
|
|
|
*/ |
1269
|
|
|
public static function get_user_list_from_course_code( |
1270
|
|
|
$courseCode, |
1271
|
|
|
$sessionId = 0, |
1272
|
|
|
$limit = null, |
1273
|
|
|
$order_by = null, |
1274
|
|
|
$filter_by_status = null, |
1275
|
|
|
$return_count = null, |
1276
|
|
|
$add_reports = false, |
1277
|
|
|
$resumed_report = false, |
1278
|
|
|
$extra_field = [], |
1279
|
|
|
$courseCodeList = [], |
1280
|
|
|
$userIdList = [], |
1281
|
|
|
$filterByActive = null, |
1282
|
|
|
$sessionIdList = [], |
1283
|
|
|
$searchByKeyword = '', |
1284
|
|
|
$options = [] |
1285
|
|
|
) { |
1286
|
|
|
$course_table = Database::get_main_table(TABLE_MAIN_COURSE); |
1287
|
|
|
$sessionTable = Database::get_main_table(TABLE_MAIN_SESSION); |
1288
|
|
|
|
1289
|
|
|
$sessionId = (int) $sessionId; |
1290
|
|
|
$courseCode = Database::escape_string($courseCode); |
1291
|
|
|
$courseInfo = api_get_course_info($courseCode); |
1292
|
|
|
$courseId = 0; |
1293
|
|
|
if (!empty($courseInfo)) { |
1294
|
|
|
$courseId = $courseInfo['real_id']; |
1295
|
|
|
} |
1296
|
|
|
$session = null; |
1297
|
|
|
if (!empty($sessionId)) { |
1298
|
|
|
$session = api_get_session_entity($sessionId); |
1299
|
|
|
} |
1300
|
|
|
$course = api_get_course_entity($courseId); |
1301
|
|
|
$where = []; |
1302
|
|
|
if (empty($order_by)) { |
1303
|
|
|
$order_by = 'user.lastname, user.firstname'; |
1304
|
|
|
if (api_is_western_name_order()) { |
1305
|
|
|
$order_by = 'user.firstname, user.lastname'; |
1306
|
|
|
} |
1307
|
|
|
} |
1308
|
|
|
|
1309
|
|
|
// if the $order_by does not contain 'ORDER BY' |
1310
|
|
|
// we have to check if it is a valid field that can be sorted on |
1311
|
|
|
if (!strstr($order_by, 'ORDER BY')) { |
1312
|
|
|
if (!empty($order_by)) { |
1313
|
|
|
$order_by = "ORDER BY $order_by"; |
1314
|
|
|
} else { |
1315
|
|
|
$order_by = ''; |
1316
|
|
|
} |
1317
|
|
|
} |
1318
|
|
|
|
1319
|
|
|
$filter_by_status_condition = null; |
1320
|
|
|
$sqlInjectWhere = ''; |
1321
|
|
|
$whereExtraField = ''; |
1322
|
|
|
$injectExtraFields = ' , '; |
1323
|
|
|
$sqlInjectJoins = ''; |
1324
|
|
|
if (!empty($options)) { |
1325
|
|
|
$extraFieldModel = new ExtraField('user'); |
1326
|
|
|
$conditions = $extraFieldModel->parseConditions($options, 'user'); |
1327
|
|
|
if (!empty($conditions)) { |
1328
|
|
|
$injectExtraFields = $conditions['inject_extra_fields']; |
1329
|
|
|
|
1330
|
|
|
if (!empty($injectExtraFields)) { |
1331
|
|
|
$injectExtraFields = ', '.$injectExtraFields; |
1332
|
|
|
} else { |
1333
|
|
|
$injectExtraFields = ' , '; |
1334
|
|
|
} |
1335
|
|
|
$sqlInjectJoins = $conditions['inject_joins']; |
1336
|
|
|
$whereExtraField = $conditions['where']; |
1337
|
|
|
} |
1338
|
|
|
} |
1339
|
|
|
|
1340
|
|
|
if (!empty($sessionId) || !empty($sessionIdList)) { |
1341
|
|
|
$sql = 'SELECT DISTINCT |
1342
|
|
|
user.id as user_id, |
1343
|
|
|
user.email, |
1344
|
|
|
session_course_user.status as status_session, |
1345
|
|
|
session_id, |
1346
|
|
|
user.*, |
1347
|
|
|
course.*, |
1348
|
|
|
course.id AS c_id |
1349
|
|
|
'.$injectExtraFields.' |
1350
|
|
|
session.name as session_name |
1351
|
|
|
'; |
1352
|
|
|
if ($return_count) { |
1353
|
|
|
$sql = ' SELECT COUNT(user.id) as count'; |
1354
|
|
|
} |
1355
|
|
|
|
1356
|
|
|
$sessionCondition = " session_course_user.session_id = $sessionId"; |
1357
|
|
|
if (!empty($sessionIdList)) { |
1358
|
|
|
$sessionIdListToString = implode("','", array_map('intval', $sessionIdList)); |
1359
|
|
|
$sessionCondition = " session_course_user.session_id IN ('$sessionIdListToString') "; |
1360
|
|
|
} |
1361
|
|
|
|
1362
|
|
|
$courseCondition = " course.id = $courseId"; |
1363
|
|
|
if (!empty($courseCodeList)) { |
1364
|
|
|
$courseCodeListForSession = array_map(['Database', 'escape_string'], $courseCodeList); |
1365
|
|
|
$courseCodeListForSession = implode("','", $courseCodeListForSession); |
1366
|
|
|
$courseCondition = " course.code IN ('$courseCodeListForSession') "; |
1367
|
|
|
} |
1368
|
|
|
|
1369
|
|
|
$sql .= ' FROM '.Database::get_main_table(TABLE_MAIN_USER).' as user '; |
1370
|
|
|
$sql .= " LEFT JOIN ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)." as session_course_user |
1371
|
|
|
ON |
1372
|
|
|
user.id = session_course_user.user_id AND |
1373
|
|
|
$sessionCondition |
1374
|
|
|
INNER JOIN $course_table course |
1375
|
|
|
ON session_course_user.c_id = course.id AND |
1376
|
|
|
$courseCondition |
1377
|
|
|
INNER JOIN $sessionTable session |
1378
|
|
|
ON session_course_user.session_id = session.id |
1379
|
|
|
$sqlInjectJoins |
1380
|
|
|
"; |
1381
|
|
|
$where[] = ' session_course_user.c_id IS NOT NULL '; |
1382
|
|
|
|
1383
|
|
|
// 2 = coach |
1384
|
|
|
// 0 = student |
1385
|
|
|
if (isset($filter_by_status)) { |
1386
|
|
|
$filter_by_status = (int) $filter_by_status; |
1387
|
|
|
$filter_by_status_condition = " session_course_user.status = $filter_by_status AND "; |
1388
|
|
|
} |
1389
|
|
|
} else { |
1390
|
|
|
if ($return_count) { |
1391
|
|
|
$sql = " SELECT COUNT(*) as count"; |
1392
|
|
|
} else { |
1393
|
|
|
if (empty($courseCode)) { |
1394
|
|
|
$sql = 'SELECT DISTINCT |
1395
|
|
|
course.title, |
1396
|
|
|
course.code, |
1397
|
|
|
course.id AS c_id, |
1398
|
|
|
course_rel_user.status as status_rel, |
1399
|
|
|
user.id as user_id, |
1400
|
|
|
user.email, |
1401
|
|
|
course_rel_user.is_tutor |
1402
|
|
|
'.$injectExtraFields.' |
1403
|
|
|
user.* '; |
1404
|
|
|
} else { |
1405
|
|
|
$sql = 'SELECT DISTINCT |
1406
|
|
|
course_rel_user.status as status_rel, |
1407
|
|
|
user.id as user_id, |
1408
|
|
|
user.email, |
1409
|
|
|
course_rel_user.is_tutor |
1410
|
|
|
'.$injectExtraFields.' |
1411
|
|
|
user.* '; |
1412
|
|
|
} |
1413
|
|
|
} |
1414
|
|
|
|
1415
|
|
|
$sql .= " FROM ".Database::get_main_table(TABLE_MAIN_USER)." as user |
1416
|
|
|
LEFT JOIN ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." as course_rel_user |
1417
|
|
|
ON |
1418
|
|
|
user.id = course_rel_user.user_id AND |
1419
|
|
|
course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." |
1420
|
|
|
INNER JOIN $course_table course |
1421
|
|
|
ON (course_rel_user.c_id = course.id) |
1422
|
|
|
$sqlInjectJoins |
1423
|
|
|
"; |
1424
|
|
|
|
1425
|
|
|
if (!empty($courseId)) { |
1426
|
|
|
$sql .= " AND course_rel_user.c_id = $courseId"; |
1427
|
|
|
} |
1428
|
|
|
$where[] = ' course_rel_user.c_id IS NOT NULL '; |
1429
|
|
|
|
1430
|
|
|
if (isset($filter_by_status) && is_numeric($filter_by_status)) { |
1431
|
|
|
$filter_by_status = (int) $filter_by_status; |
1432
|
|
|
$filter_by_status_condition = " course_rel_user.status = $filter_by_status AND "; |
1433
|
|
|
} |
1434
|
|
|
} |
1435
|
|
|
|
1436
|
|
|
$multiple_access_url = api_get_multiple_access_url(); |
1437
|
|
|
if ($multiple_access_url) { |
1438
|
|
|
$sql .= ' LEFT JOIN '.Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER).' au |
1439
|
|
|
ON (au.user_id = user.id) '; |
1440
|
|
|
} |
1441
|
|
|
|
1442
|
|
|
$extraFieldWasAdded = false; |
1443
|
|
|
if ($return_count && $resumed_report) { |
1444
|
|
|
foreach ($extra_field as $extraField) { |
1445
|
|
|
$extraFieldInfo = UserManager::get_extra_field_information_by_name($extraField); |
1446
|
|
|
if (!empty($extraFieldInfo)) { |
1447
|
|
|
$fieldValuesTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
1448
|
|
|
$sql .= " LEFT JOIN $fieldValuesTable as ufv |
1449
|
|
|
ON ( |
1450
|
|
|
user.id = ufv.item_id AND |
1451
|
|
|
(field_id = ".$extraFieldInfo['id']." OR field_id IS NULL) |
1452
|
|
|
)"; |
1453
|
|
|
$extraFieldWasAdded = true; |
1454
|
|
|
} |
1455
|
|
|
} |
1456
|
|
|
} |
1457
|
|
|
|
1458
|
|
|
$sql .= " WHERE |
1459
|
|
|
$filter_by_status_condition |
1460
|
|
|
".implode(' OR ', $where); |
1461
|
|
|
|
1462
|
|
|
if ($multiple_access_url) { |
1463
|
|
|
$current_access_url_id = api_get_current_access_url_id(); |
1464
|
|
|
$sql .= " AND (access_url_id = $current_access_url_id ) "; |
1465
|
|
|
} |
1466
|
|
|
|
1467
|
|
|
if ($return_count && $resumed_report && $extraFieldWasAdded) { |
1468
|
|
|
$sql .= ' AND field_id IS NOT NULL GROUP BY value '; |
1469
|
|
|
} |
1470
|
|
|
|
1471
|
|
|
if (!empty($courseCodeList)) { |
1472
|
|
|
$courseCodeList = array_map(['Database', 'escape_string'], $courseCodeList); |
1473
|
|
|
$courseCodeList = implode('","', $courseCodeList); |
1474
|
|
|
if (empty($sessionIdList)) { |
1475
|
|
|
$sql .= ' AND course.code IN ("'.$courseCodeList.'")'; |
1476
|
|
|
} |
1477
|
|
|
} |
1478
|
|
|
|
1479
|
|
|
if (!empty($userIdList)) { |
1480
|
|
|
$userIdList = array_map('intval', $userIdList); |
1481
|
|
|
$userIdList = implode('","', $userIdList); |
1482
|
|
|
$sql .= ' AND user.id IN ("'.$userIdList.'")'; |
1483
|
|
|
} |
1484
|
|
|
|
1485
|
|
|
if (isset($filterByActive)) { |
1486
|
|
|
$filterByActive = (int) $filterByActive; |
1487
|
|
|
$sql .= " AND user.active = $filterByActive"; |
1488
|
|
|
} |
1489
|
|
|
|
1490
|
|
|
if (!empty($searchByKeyword)) { |
1491
|
|
|
$searchByKeyword = Database::escape_string($searchByKeyword); |
1492
|
|
|
$sql .= " AND ( |
1493
|
|
|
user.firstname LIKE '$searchByKeyword' OR |
1494
|
|
|
user.username LIKE '$searchByKeyword' OR |
1495
|
|
|
user.lastname LIKE '$searchByKeyword' |
1496
|
|
|
) "; |
1497
|
|
|
} |
1498
|
|
|
|
1499
|
|
|
$sql .= $whereExtraField; |
1500
|
|
|
$sql .= " $order_by $limit"; |
1501
|
|
|
|
1502
|
|
|
$rs = Database::query($sql); |
1503
|
|
|
$users = []; |
1504
|
|
|
|
1505
|
|
|
$extra_fields = UserManager::get_extra_fields( |
1506
|
|
|
0, |
1507
|
|
|
100, |
1508
|
|
|
null, |
1509
|
|
|
null, |
1510
|
|
|
true, |
1511
|
|
|
true |
1512
|
|
|
); |
1513
|
|
|
|
1514
|
|
|
$counter = 1; |
1515
|
|
|
$count_rows = Database::num_rows($rs); |
1516
|
|
|
|
1517
|
|
|
if ($return_count && $resumed_report) { |
1518
|
|
|
return $count_rows; |
1519
|
|
|
} |
1520
|
|
|
$table_user_field_value = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
1521
|
|
|
$tableExtraField = Database::get_main_table(TABLE_EXTRA_FIELD); |
1522
|
|
|
if ($count_rows) { |
1523
|
|
|
while ($user = Database::fetch_array($rs)) { |
1524
|
|
|
if ($return_count) { |
1525
|
|
|
return $user['count']; |
1526
|
|
|
} |
1527
|
|
|
|
1528
|
|
|
$report_info = []; |
1529
|
|
|
$user_info = $user; |
1530
|
|
|
$user_info['status'] = $user['status']; |
1531
|
|
|
if (isset($user['is_tutor'])) { |
1532
|
|
|
$user_info['is_tutor'] = $user['is_tutor']; |
1533
|
|
|
} |
1534
|
|
|
if (!empty($sessionId)) { |
1535
|
|
|
$user_info['status_session'] = $user['status_session']; |
1536
|
|
|
} |
1537
|
|
|
|
1538
|
|
|
$sessionId = isset($user['session_id']) ? $user['session_id'] : 0; |
1539
|
|
|
$sessionName = isset($user['session_name']) ? ' ('.$user['session_name'].') ' : ''; |
1540
|
|
|
|
1541
|
|
|
if ($add_reports) { |
1542
|
|
|
if ($resumed_report) { |
1543
|
|
|
$extra = []; |
1544
|
|
|
if (!empty($extra_fields)) { |
1545
|
|
|
foreach ($extra_fields as $extra) { |
1546
|
|
|
if (in_array($extra['1'], $extra_field)) { |
1547
|
|
|
$user_data = UserManager::get_extra_user_data_by_field( |
1548
|
|
|
$user['user_id'], |
1549
|
|
|
$extra['1'] |
1550
|
|
|
); |
1551
|
|
|
break; |
1552
|
|
|
} |
1553
|
|
|
} |
1554
|
|
|
} |
1555
|
|
|
|
1556
|
|
|
$row_key = '-1'; |
1557
|
|
|
$name = '-'; |
1558
|
|
|
if (!empty($extra)) { |
1559
|
|
|
if (!empty($user_data[$extra['1']])) { |
1560
|
|
|
$row_key = $user_data[$extra['1']]; |
1561
|
|
|
$name = $user_data[$extra['1']]; |
1562
|
|
|
$users[$row_key]['extra_'.$extra['1']] = $name; |
1563
|
|
|
} |
1564
|
|
|
} |
1565
|
|
|
|
1566
|
|
|
if (empty($users[$row_key])) { |
1567
|
|
|
$users[$row_key] = []; |
1568
|
|
|
} |
1569
|
|
|
|
1570
|
|
|
if (!array_key_exists('training_hours', $users[$row_key])) { |
1571
|
|
|
$users[$row_key]['training_hours'] = 0; |
1572
|
|
|
} |
1573
|
|
|
|
1574
|
|
|
$users[$row_key]['training_hours'] += Tracking::get_time_spent_on_the_course( |
1575
|
|
|
$user['user_id'], |
1576
|
|
|
$courseId, |
1577
|
|
|
$sessionId |
1578
|
|
|
); |
1579
|
|
|
|
1580
|
|
|
if (!array_key_exists('count_users', $users[$row_key])) { |
1581
|
|
|
$users[$row_key]['count_users'] = 0; |
1582
|
|
|
} |
1583
|
|
|
|
1584
|
|
|
$users[$row_key]['count_users'] += $counter; |
1585
|
|
|
|
1586
|
|
|
$registered_users_with_extra_field = self::getCountRegisteredUsersWithCourseExtraField( |
1587
|
|
|
$name, |
1588
|
|
|
$tableExtraField, |
1589
|
|
|
$table_user_field_value |
1590
|
|
|
); |
1591
|
|
|
|
1592
|
|
|
$users[$row_key]['count_users_registered'] = $registered_users_with_extra_field; |
1593
|
|
|
$users[$row_key]['average_hours_per_user'] = $users[$row_key]['training_hours'] / $users[$row_key]['count_users']; |
1594
|
|
|
|
1595
|
|
|
$category = Category:: load( |
1596
|
|
|
null, |
1597
|
|
|
null, |
1598
|
|
|
$courseCode, |
1599
|
|
|
null, |
1600
|
|
|
null, |
1601
|
|
|
$sessionId |
1602
|
|
|
); |
1603
|
|
|
|
1604
|
|
|
if (!isset($users[$row_key]['count_certificates'])) { |
1605
|
|
|
$users[$row_key]['count_certificates'] = 0; |
1606
|
|
|
} |
1607
|
|
|
|
1608
|
|
|
if (isset($category[0]) && $category[0]->is_certificate_available($user['user_id'])) { |
1609
|
|
|
$users[$row_key]['count_certificates']++; |
1610
|
|
|
} |
1611
|
|
|
|
1612
|
|
|
foreach ($extra_fields as $extra) { |
1613
|
|
|
if ('ruc' === $extra['1']) { |
1614
|
|
|
continue; |
1615
|
|
|
} |
1616
|
|
|
|
1617
|
|
|
if (!isset($users[$row_key][$extra['1']])) { |
1618
|
|
|
$user_data = UserManager::get_extra_user_data_by_field($user['user_id'], $extra['1']); |
1619
|
|
|
if (!empty($user_data[$extra['1']])) { |
1620
|
|
|
$users[$row_key][$extra['1']] = $user_data[$extra['1']]; |
1621
|
|
|
} |
1622
|
|
|
} |
1623
|
|
|
} |
1624
|
|
|
} else { |
1625
|
|
|
$report_info['course'] = $user['title'].$sessionName; |
1626
|
|
|
$report_info['user'] = api_get_person_name($user['firstname'], $user['lastname']); |
1627
|
|
|
$report_info['email'] = $user['email']; |
1628
|
|
|
$report_info['time'] = api_time_to_hms( |
1629
|
|
|
Tracking::get_time_spent_on_the_course( |
1630
|
|
|
$user['user_id'], |
1631
|
|
|
empty($user['c_id']) ? $courseId : $user['c_id'], |
1632
|
|
|
$sessionId |
1633
|
|
|
) |
1634
|
|
|
); |
1635
|
|
|
|
1636
|
|
|
$category = Category:: load( |
1637
|
|
|
null, |
1638
|
|
|
null, |
1639
|
|
|
$courseCode, |
1640
|
|
|
null, |
1641
|
|
|
null, |
1642
|
|
|
$sessionId |
1643
|
|
|
); |
1644
|
|
|
|
1645
|
|
|
$report_info['certificate'] = Display::label(get_lang('No')); |
1646
|
|
|
if (isset($category[0]) && $category[0]->is_certificate_available($user['user_id'])) { |
1647
|
|
|
$report_info['certificate'] = Display::label(get_lang('Yes'), 'success'); |
1648
|
|
|
} |
1649
|
|
|
|
1650
|
|
|
$progress = (int) Tracking::get_avg_student_progress( |
1651
|
|
|
$user['user_id'], |
1652
|
|
|
$course, |
1653
|
|
|
[], |
1654
|
|
|
$session |
1655
|
|
|
); |
1656
|
|
|
|
1657
|
|
|
$report_info['progress_100'] = 100 == $progress ? Display::label(get_lang('Yes'), 'success') : Display::label(get_lang('No')); |
1658
|
|
|
$report_info['progress'] = $progress."%"; |
1659
|
|
|
foreach ($extra_fields as $extra) { |
1660
|
|
|
$user_data = UserManager::get_extra_user_data_by_field($user['user_id'], $extra['1']); |
1661
|
|
|
$report_info[$extra['1']] = $user_data[$extra['1']]; |
1662
|
|
|
} |
1663
|
|
|
$report_info['user_id'] = $user['user_id']; |
1664
|
|
|
$users[] = $report_info; |
1665
|
|
|
} |
1666
|
|
|
} else { |
1667
|
|
|
$users[$user['user_id']] = $user_info; |
1668
|
|
|
} |
1669
|
|
|
} |
1670
|
|
|
} |
1671
|
|
|
|
1672
|
|
|
return $users; |
1673
|
|
|
} |
1674
|
|
|
|
1675
|
|
|
/** |
1676
|
|
|
* @param bool $resumed_report |
1677
|
|
|
* @param array $extra_field |
1678
|
|
|
* @param array $courseCodeList |
1679
|
|
|
* @param array $userIdList |
1680
|
|
|
* @param array $sessionIdList |
1681
|
|
|
* @param array $options |
1682
|
|
|
* |
1683
|
|
|
* @return array|int |
1684
|
|
|
*/ |
1685
|
|
|
public static function get_count_user_list_from_course_code( |
1686
|
|
|
$resumed_report = false, |
1687
|
|
|
$extra_field = [], |
1688
|
|
|
$courseCodeList = [], |
1689
|
|
|
$userIdList = [], |
1690
|
|
|
$sessionIdList = [], |
1691
|
|
|
$options = [] |
1692
|
|
|
) { |
1693
|
|
|
return self::get_user_list_from_course_code( |
1694
|
|
|
null, |
1695
|
|
|
0, |
1696
|
|
|
null, |
1697
|
|
|
null, |
1698
|
|
|
null, |
1699
|
|
|
true, |
1700
|
|
|
false, |
1701
|
|
|
$resumed_report, |
1702
|
|
|
$extra_field, |
1703
|
|
|
$courseCodeList, |
1704
|
|
|
$userIdList, |
1705
|
|
|
null, |
1706
|
|
|
$sessionIdList, |
1707
|
|
|
null, |
1708
|
|
|
$options |
1709
|
|
|
); |
1710
|
|
|
} |
1711
|
|
|
|
1712
|
|
|
/** |
1713
|
|
|
* Gets subscribed users in a course or in a course/session. |
1714
|
|
|
* |
1715
|
|
|
* @param string $course_code |
1716
|
|
|
* @param int $session_id |
1717
|
|
|
* |
1718
|
|
|
* @return int |
1719
|
|
|
*/ |
1720
|
|
|
public static function get_users_count_in_course( |
1721
|
|
|
$course_code, |
1722
|
|
|
$session_id = 0, |
1723
|
|
|
$status = null |
1724
|
|
|
) { |
1725
|
|
|
// variable initialisation |
1726
|
|
|
$session_id = (int) $session_id; |
1727
|
|
|
$course_code = Database::escape_string($course_code); |
1728
|
|
|
$tblUser = Database::get_main_table(TABLE_MAIN_USER); |
1729
|
|
|
$tblSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
1730
|
|
|
$tblCourseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
1731
|
|
|
$tblUrlUser = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER); |
1732
|
|
|
|
1733
|
|
|
$courseInfo = api_get_course_info($course_code); |
1734
|
|
|
$courseId = $courseInfo['real_id']; |
1735
|
|
|
|
1736
|
|
|
$sql = " |
1737
|
|
|
SELECT DISTINCT count(user.id) as count |
1738
|
|
|
FROM $tblUser as user |
1739
|
|
|
"; |
1740
|
|
|
$where = []; |
1741
|
|
|
if (!empty($session_id)) { |
1742
|
|
|
$sql .= " |
1743
|
|
|
LEFT JOIN $tblSessionCourseUser as session_course_user |
1744
|
|
|
ON user.id = session_course_user.user_id |
1745
|
|
|
AND session_course_user.c_id = $courseId |
1746
|
|
|
AND session_course_user.session_id = $session_id |
1747
|
|
|
"; |
1748
|
|
|
|
1749
|
|
|
$where[] = ' session_course_user.c_id IS NOT NULL '; |
1750
|
|
|
} else { |
1751
|
|
|
$sql .= " |
1752
|
|
|
LEFT JOIN $tblCourseUser as course_rel_user |
1753
|
|
|
ON user.id = course_rel_user.user_id |
1754
|
|
|
AND course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." |
1755
|
|
|
AND course_rel_user.c_id = $courseId |
1756
|
|
|
"; |
1757
|
|
|
$where[] = ' course_rel_user.c_id IS NOT NULL '; |
1758
|
|
|
} |
1759
|
|
|
|
1760
|
|
|
$multiple_access_url = api_get_multiple_access_url(); |
1761
|
|
|
if ($multiple_access_url) { |
1762
|
|
|
$sql .= " LEFT JOIN $tblUrlUser au ON (au.user_id = user.id) "; |
1763
|
|
|
} |
1764
|
|
|
|
1765
|
|
|
$sql .= ' WHERE '.implode(' OR ', $where); |
1766
|
|
|
|
1767
|
|
|
if ($multiple_access_url) { |
1768
|
|
|
$current_access_url_id = api_get_current_access_url_id(); |
1769
|
|
|
$sql .= " AND (access_url_id = $current_access_url_id ) "; |
1770
|
|
|
} |
1771
|
|
|
$rs = Database::query($sql); |
1772
|
|
|
$count = 0; |
1773
|
|
|
if (Database::num_rows($rs)) { |
1774
|
|
|
$user = Database::fetch_array($rs); |
1775
|
|
|
$count = $user['count']; |
1776
|
|
|
} |
1777
|
|
|
|
1778
|
|
|
return $count; |
1779
|
|
|
} |
1780
|
|
|
|
1781
|
|
|
/** |
1782
|
|
|
* Get a list of coaches of a course and a session. |
1783
|
|
|
* |
1784
|
|
|
* @param string $course_code |
1785
|
|
|
* @param int $session_id |
1786
|
|
|
* @param bool $addGeneralCoach |
1787
|
|
|
* |
1788
|
|
|
* @return array List of users |
1789
|
|
|
*/ |
1790
|
|
|
public static function get_coach_list_from_course_code( |
1791
|
|
|
$course_code, |
1792
|
|
|
$session_id, |
1793
|
|
|
$addGeneralCoach = true |
1794
|
|
|
) { |
1795
|
|
|
if (empty($course_code) || empty($session_id)) { |
1796
|
|
|
return []; |
1797
|
|
|
} |
1798
|
|
|
|
1799
|
|
|
$course_code = Database::escape_string($course_code); |
1800
|
|
|
$courseInfo = api_get_course_info($course_code); |
1801
|
|
|
$courseId = $courseInfo['real_id']; |
1802
|
|
|
$session_id = (int) $session_id; |
1803
|
|
|
$users = []; |
1804
|
|
|
|
1805
|
|
|
// We get the coach for the given course in a given session. |
1806
|
|
|
$sql = 'SELECT user_id FROM '.Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER). |
1807
|
|
|
" WHERE session_id = $session_id AND c_id = $courseId AND status = 2"; |
1808
|
|
|
$rs = Database::query($sql); |
1809
|
|
|
while ($user = Database::fetch_array($rs)) { |
1810
|
|
|
$userInfo = api_get_user_info($user['user_id']); |
1811
|
|
|
if ($userInfo) { |
1812
|
|
|
$users[$user['user_id']] = $userInfo; |
1813
|
|
|
} |
1814
|
|
|
} |
1815
|
|
|
|
1816
|
|
|
if ($addGeneralCoach) { |
1817
|
|
|
$table = Database::get_main_table(TABLE_MAIN_SESSION); |
1818
|
|
|
// We get the session coach. |
1819
|
|
|
$sql = "SELECT id_coach FROM $table WHERE id = $session_id"; |
1820
|
|
|
$rs = Database::query($sql); |
1821
|
|
|
$session_id_coach = Database::result($rs, 0, 'id_coach'); |
1822
|
|
|
if (is_int($session_id_coach)) { |
1823
|
|
|
$userInfo = api_get_user_info($session_id_coach); |
1824
|
|
|
if ($userInfo) { |
1825
|
|
|
$users[$session_id_coach] = $userInfo; |
1826
|
|
|
} |
1827
|
|
|
} |
1828
|
|
|
} |
1829
|
|
|
|
1830
|
|
|
return $users; |
1831
|
|
|
} |
1832
|
|
|
|
1833
|
|
|
/** |
1834
|
|
|
* Return user info array of all users registered in a course |
1835
|
|
|
* This only returns the users that are registered in this actual course, not linked courses. |
1836
|
|
|
* |
1837
|
|
|
* @param string $course_code |
1838
|
|
|
* @param bool $with_session |
1839
|
|
|
* @param int $sessionId |
1840
|
|
|
* @param string $date_from |
1841
|
|
|
* @param string $date_to |
1842
|
|
|
* @param bool $includeInvitedUsers Whether include the invited users |
1843
|
|
|
* @param int $groupId |
1844
|
|
|
* @param bool $getCount |
1845
|
|
|
* @param int $start |
1846
|
|
|
* @param int $limit |
1847
|
|
|
* |
1848
|
|
|
* @return array with user id |
1849
|
|
|
*/ |
1850
|
|
|
public static function get_student_list_from_course_code( |
1851
|
|
|
$course_code, |
1852
|
|
|
$with_session = false, |
1853
|
|
|
$sessionId = 0, |
1854
|
|
|
$date_from = null, |
1855
|
|
|
$date_to = null, |
1856
|
|
|
$includeInvitedUsers = true, |
1857
|
|
|
$groupId = 0, |
1858
|
|
|
$getCount = false, |
1859
|
|
|
$start = 0, |
1860
|
|
|
$limit = 0 |
1861
|
|
|
) { |
1862
|
|
|
$userTable = Database::get_main_table(TABLE_MAIN_USER); |
1863
|
|
|
$sessionId = (int) $sessionId; |
1864
|
|
|
$courseInfo = api_get_course_info($course_code); |
1865
|
|
|
if (empty($courseInfo)) { |
1866
|
|
|
return []; |
1867
|
|
|
} |
1868
|
|
|
$courseId = $courseInfo['real_id']; |
1869
|
|
|
$students = []; |
1870
|
|
|
|
1871
|
|
|
$limitCondition = ''; |
1872
|
|
|
if (isset($start) && isset($limit) && !empty($limit)) { |
1873
|
|
|
$start = (int) $start; |
1874
|
|
|
$limit = (int) $limit; |
1875
|
|
|
$limitCondition = " LIMIT $start, $limit"; |
1876
|
|
|
} |
1877
|
|
|
|
1878
|
|
|
$select = '*'; |
1879
|
|
|
if ($getCount) { |
1880
|
|
|
$select = 'count(u.id) as count'; |
1881
|
|
|
} |
1882
|
|
|
|
1883
|
|
|
if (empty($sessionId)) { |
1884
|
|
|
if (empty($groupId)) { |
1885
|
|
|
// students directly subscribed to the course |
1886
|
|
|
$sql = "SELECT $select |
1887
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." cu |
1888
|
|
|
INNER JOIN $userTable u |
1889
|
|
|
ON cu.user_id = u.id |
1890
|
|
|
WHERE c_id = $courseId AND cu.status = ".STUDENT; |
1891
|
|
|
|
1892
|
|
|
if (!$includeInvitedUsers) { |
1893
|
|
|
$sql .= " AND u.status != ".INVITEE; |
1894
|
|
|
} |
1895
|
|
|
$sql .= $limitCondition; |
1896
|
|
|
$rs = Database::query($sql); |
1897
|
|
|
|
1898
|
|
|
if ($getCount) { |
1899
|
|
|
$row = Database::fetch_array($rs); |
1900
|
|
|
|
1901
|
|
|
return (int) $row['count']; |
1902
|
|
|
} |
1903
|
|
|
|
1904
|
|
|
while ($student = Database::fetch_array($rs)) { |
1905
|
|
|
$students[$student['user_id']] = $student; |
1906
|
|
|
} |
1907
|
|
|
} else { |
1908
|
|
|
$students = GroupManager::get_users( |
1909
|
|
|
$groupId, |
1910
|
|
|
false, |
1911
|
|
|
$start, |
1912
|
|
|
$limit, |
1913
|
|
|
$getCount, |
1914
|
|
|
$courseInfo['real_id'] |
1915
|
|
|
); |
1916
|
|
|
$students = array_flip($students); |
1917
|
|
|
} |
1918
|
|
|
} |
1919
|
|
|
|
1920
|
|
|
// students subscribed to the course through a session |
1921
|
|
|
if ($with_session) { |
1922
|
|
|
$joinSession = ''; |
1923
|
|
|
//Session creation date |
1924
|
|
|
if (!empty($date_from) && !empty($date_to)) { |
1925
|
|
|
$joinSession = "INNER JOIN ".Database::get_main_table(TABLE_MAIN_SESSION)." s"; |
1926
|
|
|
} |
1927
|
|
|
|
1928
|
|
|
$sql = "SELECT $select |
1929
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)." scu |
1930
|
|
|
$joinSession |
1931
|
|
|
INNER JOIN $userTable u |
1932
|
|
|
ON scu.user_id = u.id |
1933
|
|
|
WHERE scu.c_id = $courseId AND scu.status <> 2"; |
1934
|
|
|
|
1935
|
|
|
if (!empty($date_from) && !empty($date_to)) { |
1936
|
|
|
$date_from = Database::escape_string($date_from); |
1937
|
|
|
$date_to = Database::escape_string($date_to); |
1938
|
|
|
$sql .= " AND s.access_start_date >= '$date_from' AND s.access_end_date <= '$date_to'"; |
1939
|
|
|
} |
1940
|
|
|
|
1941
|
|
|
if (0 != $sessionId) { |
1942
|
|
|
$sql .= " AND scu.session_id = $sessionId"; |
1943
|
|
|
} |
1944
|
|
|
|
1945
|
|
|
if (!$includeInvitedUsers) { |
1946
|
|
|
$sql .= " AND u.status != ".INVITEE; |
1947
|
|
|
} |
1948
|
|
|
$sql .= $limitCondition; |
1949
|
|
|
|
1950
|
|
|
$rs = Database::query($sql); |
1951
|
|
|
|
1952
|
|
|
if ($getCount) { |
1953
|
|
|
$row = Database::fetch_array($rs); |
1954
|
|
|
|
1955
|
|
|
return (int) $row['count']; |
1956
|
|
|
} |
1957
|
|
|
|
1958
|
|
|
while ($student = Database::fetch_array($rs)) { |
1959
|
|
|
$students[$student['user_id']] = $student; |
1960
|
|
|
} |
1961
|
|
|
} |
1962
|
|
|
|
1963
|
|
|
return $students; |
1964
|
|
|
} |
1965
|
|
|
|
1966
|
|
|
/** |
1967
|
|
|
* Return user info array of all teacher-users registered in a course |
1968
|
|
|
* This only returns the users that are registered in this actual course, not linked courses. |
1969
|
|
|
* |
1970
|
|
|
* @param string $course_code |
1971
|
|
|
* |
1972
|
|
|
* @return array with user id |
1973
|
|
|
*/ |
1974
|
|
|
public static function get_teacher_list_from_course_code($course_code) |
1975
|
|
|
{ |
1976
|
|
|
$courseInfo = api_get_course_info($course_code); |
1977
|
|
|
$courseId = $courseInfo['real_id']; |
1978
|
|
|
if (empty($courseId)) { |
1979
|
|
|
return false; |
1980
|
|
|
} |
1981
|
|
|
|
1982
|
|
|
$sql = "SELECT DISTINCT |
1983
|
|
|
u.id as user_id, |
1984
|
|
|
u.lastname, |
1985
|
|
|
u.firstname, |
1986
|
|
|
u.email, |
1987
|
|
|
u.username, |
1988
|
|
|
u.status |
1989
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." cu |
1990
|
|
|
INNER JOIN ".Database::get_main_table(TABLE_MAIN_USER)." u |
1991
|
|
|
ON (cu.user_id = u.id) |
1992
|
|
|
WHERE |
1993
|
|
|
cu.c_id = $courseId AND |
1994
|
|
|
cu.status = 1 "; |
1995
|
|
|
$rs = Database::query($sql); |
1996
|
|
|
$teachers = []; |
1997
|
|
|
while ($teacher = Database::fetch_array($rs)) { |
1998
|
|
|
$teachers[$teacher['user_id']] = $teacher; |
1999
|
|
|
} |
2000
|
|
|
|
2001
|
|
|
return $teachers; |
2002
|
|
|
} |
2003
|
|
|
|
2004
|
|
|
/** |
2005
|
|
|
* Return user info array of all teacher-users registered in a course |
2006
|
|
|
* This only returns the users that are registered in this actual course, not linked courses. |
2007
|
|
|
* |
2008
|
|
|
* @param int $courseId |
2009
|
|
|
* @param bool $loadAvatars |
2010
|
|
|
* |
2011
|
|
|
* @return array with user id |
2012
|
|
|
*/ |
2013
|
|
|
public static function getTeachersFromCourse($courseId, $loadAvatars = true) |
2014
|
|
|
{ |
2015
|
|
|
$courseId = (int) $courseId; |
2016
|
|
|
|
2017
|
|
|
if (empty($courseId)) { |
2018
|
|
|
return false; |
2019
|
|
|
} |
2020
|
|
|
|
2021
|
|
|
$sql = "SELECT DISTINCT |
2022
|
|
|
u.id as user_id, |
2023
|
|
|
u.lastname, |
2024
|
|
|
u.firstname, |
2025
|
|
|
u.email, |
2026
|
|
|
u.username, |
2027
|
|
|
u.status |
2028
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." cu |
2029
|
|
|
INNER JOIN ".Database::get_main_table(TABLE_MAIN_USER)." u |
2030
|
|
|
ON (cu.user_id = u.id) |
2031
|
|
|
WHERE |
2032
|
|
|
cu.c_id = $courseId AND |
2033
|
|
|
cu.status = 1 "; |
2034
|
|
|
$rs = Database::query($sql); |
2035
|
|
|
$listTeachers = []; |
2036
|
|
|
$teachers = []; |
2037
|
|
|
$url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_popup&course_id='.$courseId; |
2038
|
|
|
while ($teacher = Database::fetch_array($rs)) { |
2039
|
|
|
$teachers['id'] = $teacher['user_id']; |
2040
|
|
|
$teachers['lastname'] = $teacher['lastname']; |
2041
|
|
|
$teachers['firstname'] = $teacher['firstname']; |
2042
|
|
|
$teachers['email'] = $teacher['email']; |
2043
|
|
|
$teachers['username'] = $teacher['username']; |
2044
|
|
|
$teachers['status'] = $teacher['status']; |
2045
|
|
|
$teachers['fullname'] = api_get_person_name($teacher['firstname'], $teacher['lastname']); |
2046
|
|
|
$teachers['avatar'] = ''; |
2047
|
|
|
/*if ($loadAvatars) { |
2048
|
|
|
$userPicture = UserManager::getUserPicture($teacher['user_id'], USER_IMAGE_SIZE_SMALL); |
2049
|
|
|
$teachers['avatar'] = $userPicture; |
2050
|
|
|
}*/ |
2051
|
|
|
$teachers['url'] = $url.'&user_id='.$teacher['user_id']; |
2052
|
|
|
$listTeachers[] = $teachers; |
2053
|
|
|
} |
2054
|
|
|
|
2055
|
|
|
return $listTeachers; |
2056
|
|
|
} |
2057
|
|
|
|
2058
|
|
|
/** |
2059
|
|
|
* Returns a string list of teachers assigned to the given course. |
2060
|
|
|
* |
2061
|
|
|
* @param string $course_code |
2062
|
|
|
* @param string $separator between teachers names |
2063
|
|
|
* @param bool $add_link_to_profile Whether to add a link to the teacher's profile |
2064
|
|
|
* @param bool $orderList |
2065
|
|
|
* |
2066
|
|
|
* @return string List of teachers teaching the course |
2067
|
|
|
*/ |
2068
|
|
|
public static function getTeacherListFromCourseCodeToString( |
2069
|
|
|
$course_code, |
2070
|
|
|
$separator = self::USER_SEPARATOR, |
2071
|
|
|
$add_link_to_profile = false, |
2072
|
|
|
$orderList = false |
2073
|
|
|
) { |
2074
|
|
|
$teacher_list = self::get_teacher_list_from_course_code($course_code); |
2075
|
|
|
$html = ''; |
2076
|
|
|
$list = []; |
2077
|
|
|
if (!empty($teacher_list)) { |
2078
|
|
|
foreach ($teacher_list as $teacher) { |
2079
|
|
|
$teacher_name = api_get_person_name( |
2080
|
|
|
$teacher['firstname'], |
2081
|
|
|
$teacher['lastname'] |
2082
|
|
|
); |
2083
|
|
|
if ($add_link_to_profile) { |
2084
|
|
|
$url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_popup&user_id='.$teacher['user_id']; |
2085
|
|
|
$teacher_name = Display::url( |
2086
|
|
|
$teacher_name, |
2087
|
|
|
$url, |
2088
|
|
|
[ |
2089
|
|
|
'class' => 'ajax', |
2090
|
|
|
'data-title' => $teacher_name, |
2091
|
|
|
] |
2092
|
|
|
); |
2093
|
|
|
} |
2094
|
|
|
$list[] = $teacher_name; |
2095
|
|
|
} |
2096
|
|
|
|
2097
|
|
|
if (!empty($list)) { |
2098
|
|
|
if (true === $orderList) { |
2099
|
|
|
$html .= '<ul class="user-teacher">'; |
2100
|
|
|
foreach ($list as $teacher) { |
2101
|
|
|
$html .= '<li>'; |
2102
|
|
|
$html .= Display::return_icon('teacher.png', '', null, ICON_SIZE_TINY); |
2103
|
|
|
$html .= ' '.$teacher; |
2104
|
|
|
$html .= '</li>'; |
2105
|
|
|
} |
2106
|
|
|
$html .= '</ul>'; |
2107
|
|
|
} else { |
2108
|
|
|
$html .= array_to_string($list, $separator); |
2109
|
|
|
} |
2110
|
|
|
} |
2111
|
|
|
} |
2112
|
|
|
|
2113
|
|
|
return $html; |
2114
|
|
|
} |
2115
|
|
|
|
2116
|
|
|
/** |
2117
|
|
|
* This function returns information about coachs from a course in session. |
2118
|
|
|
* |
2119
|
|
|
* @param int $session_id |
2120
|
|
|
* @param int $courseId |
2121
|
|
|
* |
2122
|
|
|
* @return array containing user_id, lastname, firstname, username |
2123
|
|
|
*/ |
2124
|
|
|
public static function get_coachs_from_course($session_id = 0, $courseId = 0) |
2125
|
|
|
{ |
2126
|
|
|
if (!empty($session_id)) { |
2127
|
|
|
$session_id = intval($session_id); |
2128
|
|
|
} else { |
2129
|
|
|
$session_id = api_get_session_id(); |
2130
|
|
|
} |
2131
|
|
|
|
2132
|
|
|
if (!empty($courseId)) { |
2133
|
|
|
$courseId = intval($courseId); |
2134
|
|
|
} else { |
2135
|
|
|
$courseId = api_get_course_int_id(); |
2136
|
|
|
} |
2137
|
|
|
|
2138
|
|
|
$tbl_user = Database::get_main_table(TABLE_MAIN_USER); |
2139
|
|
|
$tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
2140
|
|
|
|
2141
|
|
|
$sql = "SELECT DISTINCT |
2142
|
|
|
u.id as user_id, |
2143
|
|
|
u.lastname, |
2144
|
|
|
u.firstname, |
2145
|
|
|
u.username |
2146
|
|
|
FROM $tbl_user u |
2147
|
|
|
INNER JOIN $tbl_session_course_user scu |
2148
|
|
|
ON (u.id = scu.user_id) |
2149
|
|
|
WHERE |
2150
|
|
|
scu.session_id = $session_id AND |
2151
|
|
|
scu.c_id = $courseId AND |
2152
|
|
|
scu.status = 2"; |
2153
|
|
|
$rs = Database::query($sql); |
2154
|
|
|
|
2155
|
|
|
$coaches = []; |
2156
|
|
|
if (Database::num_rows($rs) > 0) { |
2157
|
|
|
while ($row = Database::fetch_array($rs)) { |
2158
|
|
|
$completeName = api_get_person_name($row['firstname'], $row['lastname']); |
2159
|
|
|
$coaches[] = $row + ['full_name' => $completeName]; |
2160
|
|
|
} |
2161
|
|
|
} |
2162
|
|
|
|
2163
|
|
|
return $coaches; |
2164
|
|
|
} |
2165
|
|
|
|
2166
|
|
|
/** |
2167
|
|
|
* @param int $session_id |
2168
|
|
|
* @param int $courseId |
2169
|
|
|
* @param string $separator |
2170
|
|
|
* @param bool $add_link_to_profile |
2171
|
|
|
* @param bool $orderList |
2172
|
|
|
* |
2173
|
|
|
* @return string |
2174
|
|
|
*/ |
2175
|
|
|
public static function get_coachs_from_course_to_string( |
2176
|
|
|
$session_id = 0, |
2177
|
|
|
$courseId = 0, |
2178
|
|
|
$separator = self::USER_SEPARATOR, |
2179
|
|
|
$add_link_to_profile = false, |
2180
|
|
|
$orderList = false |
2181
|
|
|
) { |
2182
|
|
|
$coachList = self::get_coachs_from_course($session_id, $courseId); |
2183
|
|
|
$course_coachs = []; |
2184
|
|
|
if (!empty($coachList)) { |
2185
|
|
|
foreach ($coachList as $coach_course) { |
2186
|
|
|
$coach_name = $coach_course['full_name']; |
2187
|
|
|
if ($add_link_to_profile) { |
2188
|
|
|
$url = api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_popup&user_id='.$coach_course['user_id'].'&course_id='.$courseId.'&session_id='.$session_id; |
2189
|
|
|
$coach_name = Display::url( |
2190
|
|
|
$coach_name, |
2191
|
|
|
$url, |
2192
|
|
|
[ |
2193
|
|
|
'class' => 'ajax', |
2194
|
|
|
'data-title' => $coach_name, |
2195
|
|
|
] |
2196
|
|
|
); |
2197
|
|
|
} |
2198
|
|
|
$course_coachs[] = $coach_name; |
2199
|
|
|
} |
2200
|
|
|
} |
2201
|
|
|
|
2202
|
|
|
$html = ''; |
2203
|
|
|
if (!empty($course_coachs)) { |
2204
|
|
|
if (true === $orderList) { |
2205
|
|
|
$html .= '<ul class="user-coachs">'; |
2206
|
|
|
foreach ($course_coachs as $coachs) { |
2207
|
|
|
$html .= Display::tag( |
2208
|
|
|
'li', |
2209
|
|
|
Display::return_icon( |
2210
|
|
|
'teacher.png', |
2211
|
|
|
get_lang('Coach'), |
2212
|
|
|
null, |
2213
|
|
|
ICON_SIZE_TINY |
2214
|
|
|
).' '.$coachs |
2215
|
|
|
); |
2216
|
|
|
} |
2217
|
|
|
$html .= '</ul>'; |
2218
|
|
|
} else { |
2219
|
|
|
$html = array_to_string($course_coachs, $separator); |
2220
|
|
|
} |
2221
|
|
|
} |
2222
|
|
|
|
2223
|
|
|
return $html; |
2224
|
|
|
} |
2225
|
|
|
|
2226
|
|
|
/** |
2227
|
|
|
* Get the list of groups from the course. |
2228
|
|
|
* |
2229
|
|
|
* @param string $course_code |
2230
|
|
|
* @param int $session_id Session ID (optional) |
2231
|
|
|
* @param int $getEmptyGroups get empty groups (optional) |
2232
|
|
|
* |
2233
|
|
|
* @return CGroup[] |
2234
|
|
|
*/ |
2235
|
|
|
public static function get_group_list_of_course( |
2236
|
|
|
$course_code, |
2237
|
|
|
$session_id = 0, |
2238
|
|
|
$getEmptyGroups = 0 |
2239
|
|
|
) { |
2240
|
|
|
$course_info = api_get_course_info($course_code); |
2241
|
|
|
|
2242
|
|
|
if (empty($course_info)) { |
2243
|
|
|
return []; |
2244
|
|
|
} |
2245
|
|
|
$course_id = $course_info['real_id']; |
2246
|
|
|
|
2247
|
|
|
if (empty($course_id)) { |
2248
|
|
|
return []; |
2249
|
|
|
} |
2250
|
|
|
|
2251
|
|
|
$repo = Container::getGroupRepository(); |
2252
|
|
|
|
2253
|
|
|
$course = api_get_course_entity($course_info['real_id']); |
2254
|
|
|
$session = api_get_session_entity($session_id); |
2255
|
|
|
$qb = $repo->getResourcesByCourse($course, $session); |
2256
|
|
|
$groups = $qb->getQuery()->getResult(); |
2257
|
|
|
$groupList = []; |
2258
|
|
|
/** @var CGroup $group */ |
2259
|
|
|
foreach ($groups as $group) { |
2260
|
|
|
if (0 === $getEmptyGroups) { |
2261
|
|
|
if (!$group->hasMembers()) { |
2262
|
|
|
continue; |
2263
|
|
|
} |
2264
|
|
|
} |
2265
|
|
|
$groupList[$group->getIid()] = $group; |
2266
|
|
|
} |
2267
|
|
|
|
2268
|
|
|
/* 0 != $session_id ? $session_condition = ' WHERE g.session_id IN(1,'.intval($session_id).')' : $session_condition = ' WHERE g.session_id = 0'; |
2269
|
|
|
if (0 == $in_get_empty_group) { |
2270
|
|
|
// get only groups that are not empty |
2271
|
|
|
$sql = "SELECT DISTINCT g.iid, g.name |
2272
|
|
|
FROM ".Database::get_course_table(TABLE_GROUP)." AS g |
2273
|
|
|
INNER JOIN ".Database::get_course_table(TABLE_GROUP_USER)." gu |
2274
|
|
|
ON (g.iid = gu.group_id) |
2275
|
|
|
$session_condition |
2276
|
|
|
ORDER BY g.name"; |
2277
|
|
|
} else { |
2278
|
|
|
// get all groups even if they are empty |
2279
|
|
|
$sql = "SELECT g.iid, g.name |
2280
|
|
|
FROM ".Database::get_course_table(TABLE_GROUP)." AS g |
2281
|
|
|
$session_condition |
2282
|
|
|
AND c_id = $course_id"; |
2283
|
|
|
} |
2284
|
|
|
|
2285
|
|
|
$result = Database::query($sql); |
2286
|
|
|
$groupList = []; |
2287
|
|
|
while ($groupData = Database::fetch_array($result)) { |
2288
|
|
|
$groupData['userNb'] = GroupManager::number_of_students($groupData['iid'], $course_id); |
2289
|
|
|
$groupList[$groupData['iid']] = $groupData; |
2290
|
|
|
}*/ |
2291
|
|
|
|
2292
|
|
|
return $groupList; |
2293
|
|
|
} |
2294
|
|
|
|
2295
|
|
|
/** |
2296
|
|
|
* Delete a course |
2297
|
|
|
* This function deletes a whole course-area from the platform. When the |
2298
|
|
|
* given course is a virtual course, the database and directory will not be |
2299
|
|
|
* deleted. |
2300
|
|
|
* When the given course is a real course, also all virtual courses refering |
2301
|
|
|
* to the given course will be deleted. |
2302
|
|
|
* Considering the fact that we remove all traces of the course in the main |
2303
|
|
|
* database, it makes sense to remove all tracking as well (if stats databases exist) |
2304
|
|
|
* so that a new course created with this code would not use the remains of an older |
2305
|
|
|
* course. |
2306
|
|
|
* |
2307
|
|
|
* @param string $code The code of the course to delete |
2308
|
|
|
*/ |
2309
|
|
|
public static function delete_course($code) |
2310
|
|
|
{ |
2311
|
|
|
$table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
2312
|
|
|
$table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE); |
2313
|
|
|
$table_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
2314
|
|
|
|
2315
|
|
|
$table_stats_hotpots = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES); |
2316
|
|
|
$table_stats_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
2317
|
|
|
$table_stats_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
2318
|
|
|
$table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS); |
2319
|
|
|
$table_stats_lastaccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS); |
2320
|
|
|
$table_stats_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
2321
|
|
|
$table_stats_online = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE); |
2322
|
|
|
$table_stats_downloads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS); |
2323
|
|
|
$table_stats_links = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LINKS); |
2324
|
|
|
$table_stats_uploads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS); |
2325
|
|
|
|
2326
|
|
|
if (empty($code)) { |
2327
|
|
|
return false; |
2328
|
|
|
} |
2329
|
|
|
|
2330
|
|
|
$courseRepo = Container::getCourseRepository(); |
2331
|
|
|
/** @var Course $course */ |
2332
|
|
|
$course = $courseRepo->findOneBy(['code' => $code]); |
2333
|
|
|
|
2334
|
|
|
if (null === $course) { |
2335
|
|
|
return false; |
2336
|
|
|
} |
2337
|
|
|
|
2338
|
|
|
$courseId = $course->getId(); |
2339
|
|
|
|
2340
|
|
|
/** @var SequenceResourceRepository $repo */ |
2341
|
|
|
$repo = Database::getManager()->getRepository(SequenceResource::class); |
2342
|
|
|
$sequenceResource = $repo->findRequirementForResource( |
2343
|
|
|
$courseId, |
2344
|
|
|
SequenceResource::COURSE_TYPE |
2345
|
|
|
); |
2346
|
|
|
|
2347
|
|
|
if ($sequenceResource) { |
2348
|
|
|
Display::addFlash( |
2349
|
|
|
Display::return_message( |
2350
|
|
|
get_lang('ThereIsASequenceResourceLinkedToThisCourseYouNeedToDeleteItFirst'), |
2351
|
|
|
'error' |
2352
|
|
|
) |
2353
|
|
|
); |
2354
|
|
|
|
2355
|
|
|
return false; |
2356
|
|
|
} |
2357
|
|
|
|
2358
|
|
|
$count = 0; |
2359
|
|
|
if (api_is_multiple_url_enabled()) { |
2360
|
|
|
$url_id = 1; |
2361
|
|
|
if (-1 != api_get_current_access_url_id()) { |
2362
|
|
|
$url_id = api_get_current_access_url_id(); |
2363
|
|
|
} |
2364
|
|
|
UrlManager::delete_url_rel_course($courseId, $url_id); |
2365
|
|
|
$count = UrlManager::getCountUrlRelCourse($courseId); |
2366
|
|
|
} |
2367
|
|
|
|
2368
|
|
|
if (0 === $count) { |
2369
|
|
|
//self::create_database_dump($code); |
2370
|
|
|
// Cleaning group categories |
2371
|
|
|
$groupCategories = GroupManager::get_categories($course); |
2372
|
|
|
if (!empty($groupCategories)) { |
2373
|
|
|
foreach ($groupCategories as $category) { |
2374
|
|
|
GroupManager::delete_category($category['iid'], $course->getCode()); |
2375
|
|
|
} |
2376
|
|
|
} |
2377
|
|
|
// Cleaning groups |
2378
|
|
|
// @todo should be cleaned by the resource. |
2379
|
|
|
/*$groups = GroupManager::get_groups($courseId); |
2380
|
|
|
if (!empty($groups)) { |
2381
|
|
|
foreach ($groups as $group) { |
2382
|
|
|
GroupManager::deleteGroup($group, $course['code']); |
2383
|
|
|
} |
2384
|
|
|
}*/ |
2385
|
|
|
|
2386
|
|
|
$course_tables = AddCourse::get_course_tables(); |
2387
|
|
|
// Cleaning c_x tables |
2388
|
|
|
if (!empty($courseId)) { |
2389
|
|
|
foreach ($course_tables as $table) { |
2390
|
|
|
if ('document' === $table) { |
2391
|
|
|
// Table document will be deleted by Doctrine. |
2392
|
|
|
continue; |
2393
|
|
|
} |
2394
|
|
|
$table = Database::get_course_table($table); |
2395
|
|
|
//$sql = "DELETE FROM $table WHERE c_id = $courseId "; |
2396
|
|
|
//Database::query($sql); |
2397
|
|
|
} |
2398
|
|
|
} |
2399
|
|
|
|
2400
|
|
|
// Unsubscribe all users from the course |
2401
|
|
|
$sql = "DELETE FROM $table_course_user WHERE c_id = $courseId"; |
2402
|
|
|
Database::query($sql); |
2403
|
|
|
// Delete the course from the sessions tables |
2404
|
|
|
$sql = "DELETE FROM $table_session_course WHERE c_id = $courseId"; |
2405
|
|
|
Database::query($sql); |
2406
|
|
|
$sql = "DELETE FROM $table_session_course_user WHERE c_id = $courseId"; |
2407
|
|
|
Database::query($sql); |
2408
|
|
|
|
2409
|
|
|
// Delete from Course - URL |
2410
|
|
|
// Already deleted because of entities. |
2411
|
|
|
//$sql = "DELETE FROM $table_course_rel_url WHERE c_id = $courseId"; |
2412
|
|
|
//Database::query($sql); |
2413
|
|
|
|
2414
|
|
|
// Delete the course from the stats tables |
2415
|
|
|
$sql = "DELETE FROM $table_stats_hotpots WHERE c_id = $courseId"; |
2416
|
|
|
Database::query($sql); |
2417
|
|
|
$sql = "DELETE FROM $table_stats_attempt WHERE c_id = $courseId"; |
2418
|
|
|
Database::query($sql); |
2419
|
|
|
$sql = "DELETE FROM $table_stats_exercises WHERE c_id = $courseId"; |
2420
|
|
|
Database::query($sql); |
2421
|
|
|
$sql = "DELETE FROM $table_stats_access WHERE c_id = $courseId"; |
2422
|
|
|
Database::query($sql); |
2423
|
|
|
$sql = "DELETE FROM $table_stats_lastaccess WHERE c_id = $courseId"; |
2424
|
|
|
Database::query($sql); |
2425
|
|
|
$sql = "DELETE FROM $table_stats_course_access WHERE c_id = $courseId"; |
2426
|
|
|
Database::query($sql); |
2427
|
|
|
$sql = "DELETE FROM $table_stats_online WHERE c_id = $courseId"; |
2428
|
|
|
Database::query($sql); |
2429
|
|
|
// Do not delete rows from track_e_default as these include course |
2430
|
|
|
// creation and other important things that do not take much space |
2431
|
|
|
// but give information on the course history |
2432
|
|
|
//$sql = "DELETE FROM $table_stats_default WHERE c_id = $courseId"; |
2433
|
|
|
//Database::query($sql); |
2434
|
|
|
$sql = "DELETE FROM $table_stats_downloads WHERE c_id = $courseId"; |
2435
|
|
|
Database::query($sql); |
2436
|
|
|
$sql = "DELETE FROM $table_stats_links WHERE c_id = $courseId"; |
2437
|
|
|
Database::query($sql); |
2438
|
|
|
$sql = "DELETE FROM $table_stats_uploads WHERE c_id = $courseId"; |
2439
|
|
|
Database::query($sql); |
2440
|
|
|
|
2441
|
|
|
// Update ticket |
2442
|
|
|
$table = Database::get_main_table(TABLE_TICKET_TICKET); |
2443
|
|
|
$sql = "UPDATE $table SET course_id = NULL WHERE course_id = $courseId"; |
2444
|
|
|
Database::query($sql); |
2445
|
|
|
|
2446
|
|
|
$repo->deleteSequenceResource( |
2447
|
|
|
$courseId, |
2448
|
|
|
SequenceResource::COURSE_TYPE |
2449
|
|
|
); |
2450
|
|
|
|
2451
|
|
|
// Class |
2452
|
|
|
$table = Database::get_main_table(TABLE_USERGROUP_REL_COURSE); |
2453
|
|
|
$sql = "DELETE FROM $table |
2454
|
|
|
WHERE course_id = $courseId"; |
2455
|
|
|
Database::query($sql); |
2456
|
|
|
|
2457
|
|
|
// Skills |
2458
|
|
|
$table = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER); |
2459
|
|
|
$argumentation = Database::escape_string( |
2460
|
|
|
sprintf( |
2461
|
|
|
get_lang('This skill was obtained through course %s which has been removed since then.'), |
2462
|
|
|
$course->getCode() |
2463
|
|
|
) |
2464
|
|
|
); |
2465
|
|
|
$sql = "UPDATE $table SET course_id = NULL, session_id = NULL, argumentation = '$argumentation' |
2466
|
|
|
WHERE course_id = $courseId"; |
2467
|
|
|
Database::query($sql); |
2468
|
|
|
|
2469
|
|
|
// Should be deleted by doctrine |
2470
|
|
|
//$sql = "DELETE FROM skill_rel_course WHERE c_id = $courseId"; |
2471
|
|
|
//Database::query($sql); |
2472
|
|
|
|
2473
|
|
|
// Deletes all groups, group-users, group-tutors information |
2474
|
|
|
// To prevent fK mix up on some tables |
2475
|
|
|
//GroupManager::deleteAllGroupsFromCourse($courseId); |
2476
|
|
|
|
2477
|
|
|
$appPlugin = new AppPlugin(); |
2478
|
|
|
$appPlugin->performActionsWhenDeletingItem('course', $courseId); |
2479
|
|
|
|
2480
|
|
|
//$repo = Container::getQuizRepository(); |
2481
|
|
|
//$repo->deleteAllByCourse($courseEntity); |
2482
|
|
|
|
2483
|
|
|
// Delete the course from the database |
2484
|
|
|
$courseRepo->deleteCourse($course); |
2485
|
|
|
|
2486
|
|
|
// delete extra course fields |
2487
|
|
|
$extraFieldValues = new ExtraFieldValue('course'); |
2488
|
|
|
$extraFieldValues->deleteValuesByItem($courseId); |
2489
|
|
|
|
2490
|
|
|
// Add event to system log |
2491
|
|
|
Event::addEvent( |
2492
|
|
|
LOG_COURSE_DELETE, |
2493
|
|
|
LOG_COURSE_CODE, |
2494
|
|
|
$code, |
2495
|
|
|
api_get_utc_datetime(), |
2496
|
|
|
api_get_user_id(), |
2497
|
|
|
$courseId |
2498
|
|
|
); |
2499
|
|
|
|
2500
|
|
|
return true; |
2501
|
|
|
} |
2502
|
|
|
} |
2503
|
|
|
|
2504
|
|
|
/** |
2505
|
|
|
* Creates a file called mysql_dump.sql in the course folder. |
2506
|
|
|
* |
2507
|
|
|
* @param string $course_code The code of the course |
2508
|
|
|
* |
2509
|
|
|
* @todo Implementation for single database |
2510
|
|
|
*/ |
2511
|
|
|
public static function create_database_dump($course_code) |
2512
|
|
|
{ |
2513
|
|
|
return false; |
2514
|
|
|
$sql_dump = ''; |
|
|
|
|
2515
|
|
|
$course_code = Database::escape_string($course_code); |
2516
|
|
|
$table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
2517
|
|
|
$sql = "SELECT * FROM $table_course WHERE code = '$course_code'"; |
2518
|
|
|
$res = Database::query($sql); |
2519
|
|
|
$course = Database::fetch_array($res); |
2520
|
|
|
|
2521
|
|
|
$course_tables = AddCourse::get_course_tables(); |
2522
|
|
|
|
2523
|
|
|
if (!empty($course['id'])) { |
2524
|
|
|
//Cleaning c_x tables |
2525
|
|
|
foreach ($course_tables as $table) { |
2526
|
|
|
$table = Database::get_course_table($table); |
2527
|
|
|
$sql = "SELECT * FROM $table WHERE c_id = {$course['id']} "; |
2528
|
|
|
$res_table = Database::query($sql); |
2529
|
|
|
|
2530
|
|
|
while ($row = Database::fetch_array($res_table, 'ASSOC')) { |
2531
|
|
|
$row_to_save = []; |
2532
|
|
|
foreach ($row as $key => $value) { |
2533
|
|
|
$row_to_save[$key] = $key."='".Database::escape_string($row[$key])."'"; |
2534
|
|
|
} |
2535
|
|
|
$sql_dump .= "\nINSERT INTO $table SET ".implode(', ', $row_to_save).';'; |
2536
|
|
|
} |
2537
|
|
|
} |
2538
|
|
|
} |
2539
|
|
|
|
2540
|
|
|
if (is_dir(api_get_path(SYS_COURSE_PATH).$course['directory'])) { |
2541
|
|
|
$file_name = api_get_path(SYS_COURSE_PATH).$course['directory'].'/mysql_dump.sql'; |
2542
|
|
|
$handle = fopen($file_name, 'a+'); |
2543
|
|
|
if (false !== $handle) { |
2544
|
|
|
fwrite($handle, $sql_dump); |
2545
|
|
|
fclose($handle); |
2546
|
|
|
} else { |
2547
|
|
|
//TODO trigger exception in a try-catch |
2548
|
|
|
} |
2549
|
|
|
} |
2550
|
|
|
} |
2551
|
|
|
|
2552
|
|
|
/** |
2553
|
|
|
* Sort courses for a specific user ?? |
2554
|
|
|
* |
2555
|
|
|
* @param int $user_id User ID |
2556
|
|
|
* @param string $course_code Course code |
2557
|
|
|
* |
2558
|
|
|
* @return int Minimum course order |
2559
|
|
|
* |
2560
|
|
|
* @todo Review documentation |
2561
|
|
|
*/ |
2562
|
|
|
public static function userCourseSort($user_id, $course_code) |
2563
|
|
|
{ |
2564
|
|
|
$user_id = (int) $user_id; |
2565
|
|
|
|
2566
|
|
|
if (empty($user_id) || empty($course_code)) { |
2567
|
|
|
return 0; |
2568
|
|
|
} |
2569
|
|
|
|
2570
|
|
|
$course_code = Database::escape_string($course_code); |
2571
|
|
|
$TABLECOURSE = Database::get_main_table(TABLE_MAIN_COURSE); |
2572
|
|
|
$TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
2573
|
|
|
|
2574
|
|
|
$course_title = Database::result( |
2575
|
|
|
Database::query( |
2576
|
|
|
"SELECT title FROM $TABLECOURSE WHERE code = '$course_code'" |
2577
|
|
|
), |
2578
|
|
|
0, |
2579
|
|
|
0 |
2580
|
|
|
); |
2581
|
|
|
if (false === $course_title) { |
2582
|
|
|
$course_title = ''; |
2583
|
|
|
} |
2584
|
|
|
|
2585
|
|
|
$sql = "SELECT course.code as code, course.title as title, cu.sort as sort |
2586
|
|
|
FROM $TABLECOURSUSER as cu, $TABLECOURSE as course |
2587
|
|
|
WHERE course.id = cu.c_id AND user_id = $user_id AND |
2588
|
|
|
cu.relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND |
2589
|
|
|
user_course_cat = 0 |
2590
|
|
|
ORDER BY cu.sort"; |
2591
|
|
|
$result = Database::query($sql); |
2592
|
|
|
|
2593
|
|
|
$course_title_precedent = ''; |
2594
|
|
|
$counter = 0; |
2595
|
|
|
$course_found = false; |
2596
|
|
|
$course_sort = 1; |
2597
|
|
|
|
2598
|
|
|
if (Database::num_rows($result) > 0) { |
2599
|
|
|
while ($courses = Database::fetch_array($result)) { |
2600
|
|
|
if ('' == $course_title_precedent) { |
2601
|
|
|
$course_title_precedent = $courses['title']; |
2602
|
|
|
} |
2603
|
|
|
if (api_strcasecmp($course_title_precedent, $course_title) < 0) { |
2604
|
|
|
$course_found = true; |
2605
|
|
|
if (!empty($courses['sort'])) { |
2606
|
|
|
$course_sort = $courses['sort']; |
2607
|
|
|
} |
2608
|
|
|
if (0 == $counter) { |
2609
|
|
|
$sql = "UPDATE $TABLECOURSUSER |
2610
|
|
|
SET sort = sort+1 |
2611
|
|
|
WHERE |
2612
|
|
|
user_id= $user_id AND |
2613
|
|
|
relation_type <> ".COURSE_RELATION_TYPE_RRHH." |
2614
|
|
|
AND user_course_cat = 0 |
2615
|
|
|
AND sort > $course_sort"; |
2616
|
|
|
$course_sort++; |
2617
|
|
|
} else { |
2618
|
|
|
$sql = "UPDATE $TABLECOURSUSER SET sort = sort+1 |
2619
|
|
|
WHERE |
2620
|
|
|
user_id= $user_id AND |
2621
|
|
|
relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND |
2622
|
|
|
user_course_cat = 0 AND |
2623
|
|
|
sort >= $course_sort"; |
2624
|
|
|
} |
2625
|
|
|
Database::query($sql); |
2626
|
|
|
break; |
2627
|
|
|
} else { |
2628
|
|
|
$course_title_precedent = $courses['title']; |
2629
|
|
|
} |
2630
|
|
|
$counter++; |
2631
|
|
|
} |
2632
|
|
|
|
2633
|
|
|
// We must register the course in the beginning of the list |
2634
|
|
|
if (!$course_found) { |
2635
|
|
|
$course_sort = Database::result( |
2636
|
|
|
Database::query( |
2637
|
|
|
'SELECT min(sort) as min_sort FROM '.$TABLECOURSUSER.' WHERE user_id = "'.$user_id.'" AND user_course_cat="0"' |
2638
|
|
|
), |
2639
|
|
|
0, |
2640
|
|
|
0 |
2641
|
|
|
); |
2642
|
|
|
Database::query("UPDATE $TABLECOURSUSER SET sort = sort+1 WHERE user_id = $user_id AND user_course_cat = 0"); |
2643
|
|
|
} |
2644
|
|
|
} |
2645
|
|
|
|
2646
|
|
|
return (int) $course_sort; |
2647
|
|
|
} |
2648
|
|
|
|
2649
|
|
|
/** |
2650
|
|
|
* check if course exists. |
2651
|
|
|
* |
2652
|
|
|
* @param string $courseCode |
2653
|
|
|
* |
2654
|
|
|
* @return int if exists, false else |
2655
|
|
|
*/ |
2656
|
|
|
public static function course_exists($courseCode) |
2657
|
|
|
{ |
2658
|
|
|
$courseCode = Database::escape_string($courseCode); |
2659
|
|
|
$sql = "SELECT 1 FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." |
2660
|
|
|
WHERE code = '$courseCode'"; |
2661
|
|
|
|
2662
|
|
|
return Database::num_rows(Database::query($sql)); |
2663
|
|
|
} |
2664
|
|
|
|
2665
|
|
|
/** |
2666
|
|
|
* Send an email to tutor after the auth-suscription of a student in your course. |
2667
|
|
|
* |
2668
|
|
|
* @author Carlos Vargas <[email protected]>, Dokeos Latino |
2669
|
|
|
* |
2670
|
|
|
* @param int $user_id the id of the user |
2671
|
|
|
* @param string $courseId the course code |
2672
|
|
|
* @param bool $send_to_tutor_also |
2673
|
|
|
* |
2674
|
|
|
* @return false|null we return the message that is displayed when the action is successful |
2675
|
|
|
*/ |
2676
|
|
|
public static function email_to_tutor($user_id, $courseId, $send_to_tutor_also = false) |
2677
|
|
|
{ |
2678
|
|
|
$user_id = (int) $user_id; |
2679
|
|
|
$courseId = (int) $courseId; |
2680
|
|
|
$information = api_get_course_info_by_id($courseId); |
2681
|
|
|
$course_code = $information['code']; |
2682
|
|
|
$student = api_get_user_info($user_id); |
2683
|
|
|
|
2684
|
|
|
$name_course = $information['title']; |
2685
|
|
|
$sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." |
2686
|
|
|
WHERE c_id = $courseId"; |
2687
|
|
|
|
2688
|
|
|
// TODO: Ivan: This is a mistake, please, have a look at it. Intention here is diffcult to be guessed. |
2689
|
|
|
//if ($send_to_tutor_also = true) |
2690
|
|
|
// Proposed change: |
2691
|
|
|
if ($send_to_tutor_also) { |
2692
|
|
|
$sql .= ' AND is_tutor = 1'; |
2693
|
|
|
} else { |
2694
|
|
|
$sql .= ' AND status = 1'; |
2695
|
|
|
} |
2696
|
|
|
|
2697
|
|
|
$result = Database::query($sql); |
2698
|
|
|
while ($row = Database::fetch_array($result)) { |
2699
|
|
|
$tutor = api_get_user_info($row['user_id']); |
2700
|
|
|
$emailto = $tutor['email']; |
2701
|
|
|
$emailsubject = get_lang('New user in the course').': '.$name_course; |
2702
|
|
|
$emailbody = get_lang('Dear').': '.api_get_person_name($tutor['firstname'], $tutor['lastname'])."\n"; |
2703
|
|
|
$emailbody .= get_lang('MessageNew user in the course').': '.$name_course."\n"; |
2704
|
|
|
$emailbody .= get_lang('Username').': '.$student['username']."\n"; |
2705
|
|
|
if (api_is_western_name_order()) { |
2706
|
|
|
$emailbody .= get_lang('First name').': '.$student['firstname']."\n"; |
2707
|
|
|
$emailbody .= get_lang('Last name').': '.$student['lastname']."\n"; |
2708
|
|
|
} else { |
2709
|
|
|
$emailbody .= get_lang('Last name').': '.$student['lastname']."\n"; |
2710
|
|
|
$emailbody .= get_lang('First name').': '.$student['firstname']."\n"; |
2711
|
|
|
} |
2712
|
|
|
$emailbody .= get_lang('e-mail').': <a href="mailto:'.$student['email'].'">'.$student['email']."</a>\n\n"; |
2713
|
|
|
$recipient_name = api_get_person_name( |
2714
|
|
|
$tutor['firstname'], |
2715
|
|
|
$tutor['lastname'], |
2716
|
|
|
null, |
2717
|
|
|
PERSON_NAME_EMAIL_ADDRESS |
2718
|
|
|
); |
2719
|
|
|
$sender_name = api_get_person_name( |
2720
|
|
|
api_get_setting('administratorName'), |
2721
|
|
|
api_get_setting('administratorSurname'), |
2722
|
|
|
null, |
2723
|
|
|
PERSON_NAME_EMAIL_ADDRESS |
2724
|
|
|
); |
2725
|
|
|
$email_admin = api_get_setting('emailAdministrator'); |
2726
|
|
|
|
2727
|
|
|
$additionalParameters = [ |
2728
|
|
|
'smsType' => SmsPlugin::NEW_USER_SUBSCRIBED_COURSE, |
2729
|
|
|
'userId' => $tutor['user_id'], |
2730
|
|
|
'userUsername' => $student['username'], |
2731
|
|
|
'courseCode' => $course_code, |
2732
|
|
|
]; |
2733
|
|
|
api_mail_html( |
2734
|
|
|
$recipient_name, |
2735
|
|
|
$emailto, |
2736
|
|
|
$emailsubject, |
2737
|
|
|
$emailbody, |
2738
|
|
|
$sender_name, |
2739
|
|
|
$email_admin, |
2740
|
|
|
null, |
2741
|
|
|
null, |
2742
|
|
|
null, |
2743
|
|
|
$additionalParameters |
2744
|
|
|
); |
2745
|
|
|
} |
2746
|
|
|
} |
2747
|
|
|
|
2748
|
|
|
/** |
2749
|
|
|
* @return array |
2750
|
|
|
*/ |
2751
|
|
|
public static function get_special_course_list() |
2752
|
|
|
{ |
2753
|
|
|
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE); |
2754
|
|
|
$tbl_course_field = Database::get_main_table(TABLE_EXTRA_FIELD); |
2755
|
|
|
$tbl_course_field_value = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
2756
|
|
|
$tbl_url_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
2757
|
|
|
|
2758
|
|
|
$extraFieldType = EntityExtraField::COURSE_FIELD_TYPE; |
2759
|
|
|
|
2760
|
|
|
$courseList = []; |
2761
|
|
|
// get course list auto-register |
2762
|
|
|
|
2763
|
|
|
$sql = "SELECT id FROM $tbl_course_field |
2764
|
|
|
WHERE extra_field_type = $extraFieldType AND |
2765
|
|
|
variable = 'special_course'"; |
2766
|
|
|
$result = Database::query($sql); |
2767
|
|
|
$courseList = []; |
2768
|
|
|
|
2769
|
|
|
if (Database::num_rows($result) > 0) { |
2770
|
|
|
$row = Database::fetch_assoc($result); |
2771
|
|
|
// Get list of special courses (appear to all) |
2772
|
|
|
// Note: The value is better indexed as string, so |
2773
|
|
|
// using '1' instead of integer is more efficient |
2774
|
|
|
$sql = "SELECT DISTINCT(item_id) as cid |
2775
|
|
|
FROM $tbl_course_field_value |
2776
|
|
|
WHERE field_id = ".$row['id']." AND value = '1'"; |
2777
|
|
|
$result = Database::query($sql); |
2778
|
|
|
while ($row = Database::fetch_assoc($result)) { |
2779
|
|
|
$courseList[] = $row['cid']; |
2780
|
|
|
} |
2781
|
|
|
if (count($courseList) < 1) { |
2782
|
|
|
return $courseList; |
2783
|
|
|
} |
2784
|
|
|
if (api_get_multiple_access_url()) { |
2785
|
|
|
//we filter the courses by the active URL |
2786
|
|
|
$coursesSelect = ''; |
2787
|
|
|
if (1 == count($courseList)) { |
2788
|
|
|
$coursesSelect = $courseList[0]; |
2789
|
|
|
} else { |
2790
|
|
|
$coursesSelect = implode(',', $courseList); |
2791
|
|
|
} |
2792
|
|
|
$access_url_id = api_get_current_access_url_id(); |
2793
|
|
|
if (-1 != $access_url_id) { |
2794
|
|
|
$sql = "SELECT c_id FROM $tbl_url_course |
2795
|
|
|
WHERE access_url_id = $access_url_id |
2796
|
|
|
AND c_id IN ($coursesSelect)"; |
2797
|
|
|
$result = Database::query($sql); |
2798
|
|
|
while ($row = Database::fetch_assoc($result)) { |
2799
|
|
|
$courseList[] = $row['c_id']; |
2800
|
|
|
} |
2801
|
|
|
} |
2802
|
|
|
} |
2803
|
|
|
} |
2804
|
|
|
|
2805
|
|
|
return $courseList; |
2806
|
|
|
} |
2807
|
|
|
|
2808
|
|
|
/** |
2809
|
|
|
* Get the course codes that have been restricted in the catalogue, and if byUserId is set |
2810
|
|
|
* then the courses that the user is allowed or not to see in catalogue. |
2811
|
|
|
* |
2812
|
|
|
* @param bool $allowed Either if the courses have some users that are or are not allowed to see in catalogue |
2813
|
|
|
* @param int $byUserId if the courses are or are not allowed to see to the user |
2814
|
|
|
* |
2815
|
|
|
* @return array Course codes allowed or not to see in catalogue by some user or the user |
2816
|
|
|
*/ |
2817
|
|
|
public static function getCatalogCourseList($allowed = true, $byUserId = -1) |
2818
|
|
|
{ |
2819
|
|
|
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE); |
2820
|
|
|
$tblCourseRelUserCatalogue = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER); |
2821
|
|
|
$visibility = $allowed ? 1 : 0; |
2822
|
|
|
|
2823
|
|
|
// Restriction by user id |
2824
|
|
|
$currentUserRestriction = ''; |
2825
|
|
|
|
2826
|
|
|
$byUserId = (int) $byUserId; |
2827
|
|
|
if ($byUserId > 0) { |
2828
|
|
|
$currentUserRestriction = " AND tcruc.user_id = $byUserId "; |
2829
|
|
|
} |
2830
|
|
|
|
2831
|
|
|
//we filter the courses from the URL |
2832
|
|
|
$joinAccessUrl = ''; |
2833
|
|
|
$whereAccessUrl = ''; |
2834
|
|
|
if (api_get_multiple_access_url()) { |
2835
|
|
|
$accessUrlId = api_get_current_access_url_id(); |
2836
|
|
|
if (-1 != $accessUrlId) { |
2837
|
|
|
$tblUrlCourse = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
2838
|
|
|
$joinAccessUrl = "LEFT JOIN $tblUrlCourse url_rel_course |
2839
|
|
|
ON url_rel_course.c_id = c.id "; |
2840
|
|
|
$whereAccessUrl = " AND access_url_id = $accessUrlId "; |
2841
|
|
|
} |
2842
|
|
|
} |
2843
|
|
|
|
2844
|
|
|
// get course list auto-register |
2845
|
|
|
$sql = "SELECT DISTINCT(c.code) |
2846
|
|
|
FROM $tblCourseRelUserCatalogue tcruc |
2847
|
|
|
INNER JOIN $courseTable c |
2848
|
|
|
ON (c.id = tcruc.c_id) $joinAccessUrl |
2849
|
|
|
WHERE tcruc.visible = $visibility $currentUserRestriction $whereAccessUrl"; |
2850
|
|
|
|
2851
|
|
|
$result = Database::query($sql); |
2852
|
|
|
$courseList = []; |
2853
|
|
|
|
2854
|
|
|
if (Database::num_rows($result) > 0) { |
2855
|
|
|
while ($resultRow = Database::fetch_array($result)) { |
2856
|
|
|
$courseList[] = $resultRow['code']; |
2857
|
|
|
} |
2858
|
|
|
} |
2859
|
|
|
|
2860
|
|
|
return $courseList; |
2861
|
|
|
} |
2862
|
|
|
|
2863
|
|
|
/** |
2864
|
|
|
* Get list of courses for a given user. |
2865
|
|
|
* |
2866
|
|
|
* @param int $user_id |
2867
|
|
|
* @param bool $include_sessions Whether to include courses from session or not |
2868
|
|
|
* @param bool $adminGetsAllCourses If the user is platform admin, |
2869
|
|
|
* whether he gets all the courses or just his. Note: This does |
2870
|
|
|
* *not* include all sessions |
2871
|
|
|
* @param bool $loadSpecialCourses |
2872
|
|
|
* @param array $skipCourseList List of course ids to skip |
2873
|
|
|
* @param bool $useUserLanguageFilterIfAvailable |
2874
|
|
|
* @param bool $showCoursesSessionWithDifferentKey |
2875
|
|
|
* |
2876
|
|
|
* @return array List of codes and db name |
2877
|
|
|
* |
2878
|
|
|
* @author isaac flores paz |
2879
|
|
|
*/ |
2880
|
|
|
public static function get_courses_list_by_user_id( |
2881
|
|
|
$user_id, |
2882
|
|
|
$include_sessions = false, |
2883
|
|
|
$adminGetsAllCourses = false, |
2884
|
|
|
$loadSpecialCourses = true, |
2885
|
|
|
$skipCourseList = [], |
2886
|
|
|
$useUserLanguageFilterIfAvailable = true, |
2887
|
|
|
$showCoursesSessionWithDifferentKey = false |
2888
|
|
|
) { |
2889
|
|
|
$user_id = intval($user_id); |
2890
|
|
|
$urlId = api_get_current_access_url_id(); |
2891
|
|
|
$course_list = []; |
2892
|
|
|
$codes = []; |
2893
|
|
|
|
2894
|
|
|
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE); |
2895
|
|
|
$tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
2896
|
|
|
$tableCourseUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
2897
|
|
|
$tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY); |
2898
|
|
|
|
2899
|
|
|
$languageCondition = ''; |
2900
|
|
|
$onlyInUserLanguage = api_get_configuration_value('my_courses_show_courses_in_user_language_only'); |
2901
|
|
|
if ($useUserLanguageFilterIfAvailable && $onlyInUserLanguage) { |
2902
|
|
|
$userInfo = api_get_user_info(api_get_user_id()); |
2903
|
|
|
if (!empty($userInfo['language'])) { |
2904
|
|
|
$languageCondition = " AND course.course_language = '".$userInfo['language']."' "; |
2905
|
|
|
} |
2906
|
|
|
} |
2907
|
|
|
|
2908
|
|
|
if ($adminGetsAllCourses && UserManager::is_admin($user_id)) { |
2909
|
|
|
// get the whole courses list |
2910
|
|
|
$sql = "SELECT DISTINCT(course.code), course.id as real_id, course.title |
2911
|
|
|
FROM $tbl_course course |
2912
|
|
|
INNER JOIN $tableCourseUrl url |
2913
|
|
|
ON (course.id = url.c_id) |
2914
|
|
|
WHERE |
2915
|
|
|
url.access_url_id = $urlId |
2916
|
|
|
$languageCondition |
2917
|
|
|
"; |
2918
|
|
|
} else { |
2919
|
|
|
$withSpecialCourses = $withoutSpecialCourses = ''; |
2920
|
|
|
|
2921
|
|
|
if ($loadSpecialCourses) { |
2922
|
|
|
$specialCourseList = self::get_special_course_list(); |
2923
|
|
|
|
2924
|
|
|
if (!empty($specialCourseList)) { |
2925
|
|
|
$specialCourseToString = '"'.implode('","', $specialCourseList).'"'; |
2926
|
|
|
$withSpecialCourses = ' AND course.id IN ('.$specialCourseToString.')'; |
2927
|
|
|
$withoutSpecialCourses = ' AND course.id NOT IN ('.$specialCourseToString.')'; |
2928
|
|
|
} |
2929
|
|
|
|
2930
|
|
|
if (!empty($withSpecialCourses)) { |
2931
|
|
|
$sql = "SELECT DISTINCT (course.code), |
2932
|
|
|
course.id as real_id, |
2933
|
|
|
course_category.code AS category, |
2934
|
|
|
course.title |
2935
|
|
|
FROM $tbl_course_user course_rel_user |
2936
|
|
|
LEFT JOIN $tbl_course course |
2937
|
|
|
ON course.id = course_rel_user.c_id |
2938
|
|
|
LEFT JOIN $tblCourseCategory ON course_category.id = course.category_id |
2939
|
|
|
INNER JOIN $tableCourseUrl url |
2940
|
|
|
ON (course.id = url.c_id) |
2941
|
|
|
WHERE url.access_url_id = $urlId |
2942
|
|
|
$withSpecialCourses |
2943
|
|
|
$languageCondition |
2944
|
|
|
GROUP BY course.code |
2945
|
|
|
ORDER BY course.title, course_rel_user.sort ASC |
2946
|
|
|
"; |
2947
|
|
|
$result = Database::query($sql); |
2948
|
|
|
if (Database::num_rows($result) > 0) { |
2949
|
|
|
while ($result_row = Database::fetch_array($result, 'ASSOC')) { |
2950
|
|
|
$result_row['special_course'] = 1; |
2951
|
|
|
$course_list[] = $result_row; |
2952
|
|
|
$codes[] = $result_row['real_id']; |
2953
|
|
|
} |
2954
|
|
|
} |
2955
|
|
|
} |
2956
|
|
|
} |
2957
|
|
|
|
2958
|
|
|
// get course list not auto-register. Use Distinct to avoid multiple |
2959
|
|
|
// entries when a course is assigned to a HRD (DRH) as watcher |
2960
|
|
|
$sql = "SELECT |
2961
|
|
|
DISTINCT(course.code), |
2962
|
|
|
course.id as real_id, |
2963
|
|
|
course.title |
2964
|
|
|
FROM $tbl_course course |
2965
|
|
|
INNER JOIN $tbl_course_user cru |
2966
|
|
|
ON (course.id = cru.c_id) |
2967
|
|
|
INNER JOIN $tableCourseUrl url |
2968
|
|
|
ON (course.id = url.c_id) |
2969
|
|
|
WHERE |
2970
|
|
|
url.access_url_id = $urlId AND |
2971
|
|
|
cru.user_id = $user_id |
2972
|
|
|
$withoutSpecialCourses |
2973
|
|
|
$languageCondition |
2974
|
|
|
ORDER BY course.title |
2975
|
|
|
"; |
2976
|
|
|
} |
2977
|
|
|
$result = Database::query($sql); |
2978
|
|
|
|
2979
|
|
|
if (Database::num_rows($result)) { |
2980
|
|
|
while ($row = Database::fetch_array($result, 'ASSOC')) { |
2981
|
|
|
if (!empty($skipCourseList)) { |
2982
|
|
|
if (in_array($row['real_id'], $skipCourseList)) { |
2983
|
|
|
continue; |
2984
|
|
|
} |
2985
|
|
|
} |
2986
|
|
|
$course_list[] = $row; |
2987
|
|
|
$codes[] = $row['real_id']; |
2988
|
|
|
} |
2989
|
|
|
} |
2990
|
|
|
|
2991
|
|
|
if (true === $include_sessions) { |
2992
|
|
|
$sql = "SELECT DISTINCT (c.code), |
2993
|
|
|
c.id as real_id, |
2994
|
|
|
s.id as session_id, |
2995
|
|
|
s.name as session_name |
2996
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER)." scu |
2997
|
|
|
INNER JOIN $tbl_course c |
2998
|
|
|
ON (scu.c_id = c.id) |
2999
|
|
|
INNER JOIN ".Database::get_main_table(TABLE_MAIN_SESSION)." s |
3000
|
|
|
ON (s.id = scu.session_id) |
3001
|
|
|
WHERE user_id = $user_id "; |
3002
|
|
|
$r = Database::query($sql); |
3003
|
|
|
while ($row = Database::fetch_array($r, 'ASSOC')) { |
3004
|
|
|
if (!empty($skipCourseList)) { |
3005
|
|
|
if (in_array($row['real_id'], $skipCourseList)) { |
3006
|
|
|
continue; |
3007
|
|
|
} |
3008
|
|
|
} |
3009
|
|
|
|
3010
|
|
|
if ($showCoursesSessionWithDifferentKey) { |
3011
|
|
|
$course_list[] = $row; |
3012
|
|
|
} else { |
3013
|
|
|
if (!in_array($row['real_id'], $codes)) { |
3014
|
|
|
$course_list[] = $row; |
3015
|
|
|
} |
3016
|
|
|
} |
3017
|
|
|
} |
3018
|
|
|
} |
3019
|
|
|
|
3020
|
|
|
return $course_list; |
3021
|
|
|
} |
3022
|
|
|
|
3023
|
|
|
/** |
3024
|
|
|
* Get course ID from a given course directory name. |
3025
|
|
|
* |
3026
|
|
|
* @param string $path Course directory (without any slash) |
3027
|
|
|
* |
3028
|
|
|
* @return string Course code, or false if not found |
3029
|
|
|
*/ |
3030
|
|
|
public static function getCourseCodeFromDirectory($path) |
3031
|
|
|
{ |
3032
|
|
|
$path = Database::escape_string(str_replace('.', '', str_replace('/', '', $path))); |
3033
|
|
|
$res = Database::query("SELECT code FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." |
3034
|
|
|
WHERE directory LIKE BINARY '$path'"); |
3035
|
|
|
if (false === $res) { |
3036
|
|
|
return false; |
3037
|
|
|
} |
3038
|
|
|
if (1 != Database::num_rows($res)) { |
3039
|
|
|
return false; |
3040
|
|
|
} |
3041
|
|
|
$row = Database::fetch_array($res); |
3042
|
|
|
|
3043
|
|
|
return $row['code']; |
3044
|
|
|
} |
3045
|
|
|
|
3046
|
|
|
/** |
3047
|
|
|
* Get course code(s) from visual code. |
3048
|
|
|
* |
3049
|
|
|
* @param string Visual code |
3050
|
|
|
* |
3051
|
|
|
* @return array List of codes for the given visual code |
3052
|
|
|
*/ |
3053
|
|
|
public static function get_courses_info_from_visual_code($code) |
3054
|
|
|
{ |
3055
|
|
|
$result = []; |
3056
|
|
|
$sql_result = Database::query("SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." |
3057
|
|
|
WHERE visual_code = '".Database::escape_string($code)."'"); |
3058
|
|
|
while ($virtual_course = Database::fetch_array($sql_result)) { |
3059
|
|
|
$result[] = $virtual_course; |
3060
|
|
|
} |
3061
|
|
|
|
3062
|
|
|
return $result; |
3063
|
|
|
} |
3064
|
|
|
|
3065
|
|
|
/** |
3066
|
|
|
* Creates a new extra field for a given course. |
3067
|
|
|
* |
3068
|
|
|
* @param string $variable Field's internal variable name |
3069
|
|
|
* @param int $fieldType Field's type |
3070
|
|
|
* @param string $displayText Field's language var name |
3071
|
|
|
* @param string $default Optional. The default value |
3072
|
|
|
* |
3073
|
|
|
* @return int New extra field ID |
3074
|
|
|
*/ |
3075
|
|
|
public static function create_course_extra_field($variable, $fieldType, $displayText, $default = '') |
3076
|
|
|
{ |
3077
|
|
|
$extraField = new ExtraField('course'); |
3078
|
|
|
$params = [ |
3079
|
|
|
'variable' => $variable, |
3080
|
|
|
'field_type' => $fieldType, |
3081
|
|
|
'display_text' => $displayText, |
3082
|
|
|
'default_value' => $default, |
3083
|
|
|
]; |
3084
|
|
|
|
3085
|
|
|
return $extraField->save($params); |
3086
|
|
|
} |
3087
|
|
|
|
3088
|
|
|
/** |
3089
|
|
|
* Update course attributes. Will only update attributes with a non-empty value. |
3090
|
|
|
* Note that you NEED to check that your attributes are valid before using this function. |
3091
|
|
|
* |
3092
|
|
|
* @param int Course id |
3093
|
|
|
* @param array Associative array with field names as keys and field values as values |
3094
|
|
|
* |
3095
|
|
|
* @return Doctrine\DBAL\Driver\Statement|null True if update was successful, false otherwise |
3096
|
|
|
*/ |
3097
|
|
|
public static function update_attributes($id, $attributes) |
3098
|
|
|
{ |
3099
|
|
|
$id = (int) $id; |
3100
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
3101
|
|
|
$sql = "UPDATE $table SET "; |
3102
|
|
|
$i = 0; |
3103
|
|
|
foreach ($attributes as $name => $value) { |
3104
|
|
|
if ('' != $value) { |
3105
|
|
|
if ($i > 0) { |
3106
|
|
|
$sql .= ", "; |
3107
|
|
|
} |
3108
|
|
|
$sql .= " $name = '".Database::escape_string($value)."'"; |
3109
|
|
|
$i++; |
3110
|
|
|
} |
3111
|
|
|
} |
3112
|
|
|
$sql .= " WHERE id = $id"; |
3113
|
|
|
|
3114
|
|
|
return Database::query($sql); |
3115
|
|
|
} |
3116
|
|
|
|
3117
|
|
|
/** |
3118
|
|
|
* Update an extra field value for a given course. |
3119
|
|
|
* |
3120
|
|
|
* @param string $course_code Course code |
3121
|
|
|
* @param string $variable Field variable name |
3122
|
|
|
* @param string $value Optional. Default field value |
3123
|
|
|
* |
3124
|
|
|
* @return bool|int An integer when register a new extra field. And boolean when update the extrafield |
3125
|
|
|
*/ |
3126
|
|
|
public static function update_course_extra_field_value($course_code, $variable, $value = '') |
3127
|
|
|
{ |
3128
|
|
|
$courseInfo = api_get_course_info($course_code); |
3129
|
|
|
$courseId = $courseInfo['real_id']; |
3130
|
|
|
|
3131
|
|
|
$extraFieldValues = new ExtraFieldValue('course'); |
3132
|
|
|
$params = [ |
3133
|
|
|
'item_id' => $courseId, |
3134
|
|
|
'variable' => $variable, |
3135
|
|
|
'value' => $value, |
3136
|
|
|
]; |
3137
|
|
|
|
3138
|
|
|
return $extraFieldValues->save($params); |
3139
|
|
|
} |
3140
|
|
|
|
3141
|
|
|
/** |
3142
|
|
|
* @param int $sessionId |
3143
|
|
|
* |
3144
|
|
|
* @return mixed |
3145
|
|
|
*/ |
3146
|
|
|
public static function get_session_category_id_by_session_id($sessionId) |
3147
|
|
|
{ |
3148
|
|
|
if (empty($sessionId)) { |
3149
|
|
|
return []; |
3150
|
|
|
} |
3151
|
|
|
$sessionId = intval($sessionId); |
3152
|
|
|
$sql = 'SELECT sc.id session_category |
3153
|
|
|
FROM '.Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY).' sc |
3154
|
|
|
INNER JOIN '.Database::get_main_table(TABLE_MAIN_SESSION).' s |
3155
|
|
|
ON sc.id = s.session_category_id |
3156
|
|
|
WHERE s.id = '.$sessionId; |
3157
|
|
|
|
3158
|
|
|
return Database::result( |
3159
|
|
|
Database::query($sql), |
3160
|
|
|
0, |
3161
|
|
|
'session_category' |
3162
|
|
|
); |
3163
|
|
|
} |
3164
|
|
|
|
3165
|
|
|
/** |
3166
|
|
|
* Gets the value of a course extra field. Returns null if it was not found. |
3167
|
|
|
* |
3168
|
|
|
* @param string $variable Name of the extra field |
3169
|
|
|
* @param string $code Course code |
3170
|
|
|
* |
3171
|
|
|
* @return string Value |
3172
|
|
|
*/ |
3173
|
|
|
public static function get_course_extra_field_value($variable, $code) |
3174
|
|
|
{ |
3175
|
|
|
$courseInfo = api_get_course_info($code); |
3176
|
|
|
$courseId = $courseInfo['real_id']; |
3177
|
|
|
|
3178
|
|
|
$extraFieldValues = new ExtraFieldValue('course'); |
3179
|
|
|
$result = $extraFieldValues->get_values_by_handler_and_field_variable($courseId, $variable); |
3180
|
|
|
if (!empty($result['value'])) { |
3181
|
|
|
return $result['value']; |
3182
|
|
|
} |
3183
|
|
|
|
3184
|
|
|
return null; |
3185
|
|
|
} |
3186
|
|
|
|
3187
|
|
|
/** |
3188
|
|
|
* Gets extra field value data and formatted values of a course |
3189
|
|
|
* for extra fields listed in configuration.php in my_course_course_extrafields_to_be_presented |
3190
|
|
|
* (array of variables as value of key 'fields'). |
3191
|
|
|
* |
3192
|
|
|
* @param $courseId int The numeric identifier of the course |
3193
|
|
|
* |
3194
|
|
|
* @return array of data and formatted values as returned by ExtraField::getDataAndFormattedValues |
3195
|
|
|
*/ |
3196
|
|
|
public static function getExtraFieldsToBePresented($courseId) |
3197
|
|
|
{ |
3198
|
|
|
$extraFields = []; |
3199
|
|
|
$fields = api_get_configuration_sub_value('my_course_course_extrafields_to_be_presented/fields'); |
3200
|
|
|
if (!empty($fields) && is_array($fields)) { |
3201
|
|
|
$extraFieldManager = new ExtraField('course'); |
3202
|
|
|
$dataAndFormattedValues = $extraFieldManager->getDataAndFormattedValues($courseId); |
3203
|
|
|
foreach ($fields as $variable) { |
3204
|
|
|
foreach ($dataAndFormattedValues as $value) { |
3205
|
|
|
if ($value['variable'] === $variable && !empty($value['value'])) { |
3206
|
|
|
$extraFields[] = $value; |
3207
|
|
|
} |
3208
|
|
|
} |
3209
|
|
|
} |
3210
|
|
|
} |
3211
|
|
|
|
3212
|
|
|
return $extraFields; |
3213
|
|
|
} |
3214
|
|
|
|
3215
|
|
|
/** |
3216
|
|
|
* Lists details of the course description. |
3217
|
|
|
* |
3218
|
|
|
* @param array The course description |
3219
|
|
|
* @param string The encoding |
3220
|
|
|
* @param bool If true is displayed if false is hidden |
3221
|
|
|
* |
3222
|
|
|
* @return string The course description in html |
3223
|
|
|
*/ |
3224
|
|
|
public static function get_details_course_description_html( |
3225
|
|
|
$descriptions, |
3226
|
|
|
$charset, |
3227
|
|
|
$action_show = true |
3228
|
|
|
) { |
3229
|
|
|
$data = null; |
3230
|
|
|
if (isset($descriptions) && count($descriptions) > 0) { |
3231
|
|
|
foreach ($descriptions as $description) { |
3232
|
|
|
$data .= '<div class="sectiontitle">'; |
3233
|
|
|
if (api_is_allowed_to_edit() && $action_show) { |
3234
|
|
|
//delete |
3235
|
|
|
$data .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&action=delete&description_id='.$description->id.'" onclick="javascript:if(!confirm(\''.addslashes(api_htmlentities( |
3236
|
|
|
get_lang('Please confirm your choice'), |
3237
|
|
|
ENT_QUOTES, |
3238
|
|
|
$charset |
3239
|
|
|
)).'\')) return false;">'; |
3240
|
|
|
$data .= Display::return_icon( |
3241
|
|
|
'delete.gif', |
3242
|
|
|
get_lang('Delete'), |
3243
|
|
|
['style' => 'vertical-align:middle;float:right;'] |
3244
|
|
|
); |
3245
|
|
|
$data .= '</a> '; |
3246
|
|
|
//edit |
3247
|
|
|
$data .= '<a href="'.api_get_self().'?'.api_get_cidreq().'&description_id='.$description->id.'">'; |
3248
|
|
|
$data .= Display::return_icon( |
3249
|
|
|
'edit.png', |
3250
|
|
|
get_lang('Edit'), |
3251
|
|
|
['style' => 'vertical-align:middle;float:right; padding-right:4px;'], |
3252
|
|
|
ICON_SIZE_SMALL |
3253
|
|
|
); |
3254
|
|
|
$data .= '</a> '; |
3255
|
|
|
} |
3256
|
|
|
$data .= $description->title; |
3257
|
|
|
$data .= '</div>'; |
3258
|
|
|
$data .= '<div class="sectioncomment">'; |
3259
|
|
|
$data .= Security::remove_XSS($description->content); |
3260
|
|
|
$data .= '</div>'; |
3261
|
|
|
} |
3262
|
|
|
} else { |
3263
|
|
|
$data .= '<em>'.get_lang('There is no course description so far.').'</em>'; |
3264
|
|
|
} |
3265
|
|
|
|
3266
|
|
|
return $data; |
3267
|
|
|
} |
3268
|
|
|
|
3269
|
|
|
/** |
3270
|
|
|
* Returns the details of a course category. |
3271
|
|
|
* |
3272
|
|
|
* @param string $code Category code |
3273
|
|
|
* |
3274
|
|
|
* @return array Course category |
3275
|
|
|
*/ |
3276
|
|
|
public static function get_course_category($code) |
3277
|
|
|
{ |
3278
|
|
|
$table = Database::get_main_table(TABLE_MAIN_CATEGORY); |
3279
|
|
|
$code = Database::escape_string($code); |
3280
|
|
|
$sql = "SELECT * FROM $table WHERE code = '$code'"; |
3281
|
|
|
|
3282
|
|
|
return Database::fetch_array(Database::query($sql)); |
3283
|
|
|
} |
3284
|
|
|
|
3285
|
|
|
/** |
3286
|
|
|
* Subscribes courses to human resource manager (Dashboard feature). |
3287
|
|
|
* |
3288
|
|
|
* @param int $hr_manager_id Human Resource Manager id |
3289
|
|
|
* @param array $courses_list Courses code |
3290
|
|
|
* |
3291
|
|
|
* @return int |
3292
|
|
|
*/ |
3293
|
|
|
public static function subscribeCoursesToDrhManager($hr_manager_id, $courses_list) |
3294
|
|
|
{ |
3295
|
|
|
$tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
3296
|
|
|
$tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
3297
|
|
|
|
3298
|
|
|
$hr_manager_id = intval($hr_manager_id); |
3299
|
|
|
$affected_rows = 0; |
3300
|
|
|
|
3301
|
|
|
//Deleting assigned courses to hrm_id |
3302
|
|
|
if (api_is_multiple_url_enabled()) { |
3303
|
|
|
$sql = "SELECT s.c_id FROM $tbl_course_rel_user s |
3304
|
|
|
INNER JOIN $tbl_course_rel_access_url a |
3305
|
|
|
ON (a.c_id = s.c_id) |
3306
|
|
|
WHERE |
3307
|
|
|
user_id = $hr_manager_id AND |
3308
|
|
|
relation_type = ".COURSE_RELATION_TYPE_RRHH." AND |
3309
|
|
|
access_url_id = ".api_get_current_access_url_id(); |
3310
|
|
|
} else { |
3311
|
|
|
$sql = "SELECT c_id FROM $tbl_course_rel_user |
3312
|
|
|
WHERE user_id = $hr_manager_id AND relation_type = ".COURSE_RELATION_TYPE_RRHH; |
3313
|
|
|
} |
3314
|
|
|
$result = Database::query($sql); |
3315
|
|
|
if (Database::num_rows($result) > 0) { |
3316
|
|
|
while ($row = Database::fetch_array($result)) { |
3317
|
|
|
$sql = "DELETE FROM $tbl_course_rel_user |
3318
|
|
|
WHERE |
3319
|
|
|
c_id = {$row['c_id']} AND |
3320
|
|
|
user_id = $hr_manager_id AND |
3321
|
|
|
relation_type = ".COURSE_RELATION_TYPE_RRHH; |
3322
|
|
|
Database::query($sql); |
3323
|
|
|
} |
3324
|
|
|
} |
3325
|
|
|
|
3326
|
|
|
// inserting new courses list |
3327
|
|
|
if (is_array($courses_list)) { |
3328
|
|
|
foreach ($courses_list as $course_code) { |
3329
|
|
|
$courseInfo = api_get_course_info($course_code); |
3330
|
|
|
$courseId = $courseInfo['real_id']; |
3331
|
|
|
$sql = "INSERT IGNORE INTO $tbl_course_rel_user(c_id, user_id, status, relation_type) |
3332
|
|
|
VALUES($courseId, $hr_manager_id, ".DRH.", ".COURSE_RELATION_TYPE_RRHH.")"; |
3333
|
|
|
$result = Database::query($sql); |
3334
|
|
|
if (Database::affected_rows($result)) { |
3335
|
|
|
$affected_rows++; |
3336
|
|
|
} |
3337
|
|
|
} |
3338
|
|
|
} |
3339
|
|
|
|
3340
|
|
|
return $affected_rows; |
3341
|
|
|
} |
3342
|
|
|
|
3343
|
|
|
/** |
3344
|
|
|
* get courses followed by human resources manager. |
3345
|
|
|
* |
3346
|
|
|
* @param int $user_id |
3347
|
|
|
* @param int $status |
3348
|
|
|
* @param int $from |
3349
|
|
|
* @param int $limit |
3350
|
|
|
* @param string $column |
3351
|
|
|
* @param string $direction |
3352
|
|
|
* @param bool $getCount |
3353
|
|
|
* |
3354
|
|
|
* @return array courses |
3355
|
|
|
*/ |
3356
|
|
|
public static function get_courses_followed_by_drh( |
3357
|
|
|
$user_id, |
3358
|
|
|
$status = DRH, |
3359
|
|
|
$from = null, |
3360
|
|
|
$limit = null, |
3361
|
|
|
$column = null, |
3362
|
|
|
$direction = null, |
3363
|
|
|
$getCount = false |
3364
|
|
|
) { |
3365
|
|
|
return self::getCoursesFollowedByUser( |
3366
|
|
|
$user_id, |
3367
|
|
|
$status, |
3368
|
|
|
$from, |
3369
|
|
|
$limit, |
3370
|
|
|
$column, |
3371
|
|
|
$direction, |
3372
|
|
|
$getCount |
3373
|
|
|
); |
3374
|
|
|
} |
3375
|
|
|
|
3376
|
|
|
/** |
3377
|
|
|
* get courses followed by user. |
3378
|
|
|
* |
3379
|
|
|
* @param int $user_id |
3380
|
|
|
* @param int $status |
3381
|
|
|
* @param int $from |
3382
|
|
|
* @param int $limit |
3383
|
|
|
* @param string $column |
3384
|
|
|
* @param string $direction |
3385
|
|
|
* @param bool $getCount |
3386
|
|
|
* @param string $keyword |
3387
|
|
|
* @param int $sessionId |
3388
|
|
|
* @param bool $showAllAssignedCourses |
3389
|
|
|
* |
3390
|
|
|
* @return array courses |
3391
|
|
|
*/ |
3392
|
|
|
public static function getCoursesFollowedByUser( |
3393
|
|
|
$user_id, |
3394
|
|
|
$status = null, |
3395
|
|
|
$from = null, |
3396
|
|
|
$limit = null, |
3397
|
|
|
$column = null, |
3398
|
|
|
$direction = null, |
3399
|
|
|
$getCount = false, |
3400
|
|
|
$keyword = null, |
3401
|
|
|
$sessionId = 0, |
3402
|
|
|
$showAllAssignedCourses = false |
3403
|
|
|
) { |
3404
|
|
|
// Database Table Definitions |
3405
|
|
|
$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE); |
3406
|
|
|
$tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
3407
|
|
|
$tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
3408
|
|
|
$sessionId = (int) $sessionId; |
3409
|
|
|
$user_id = (int) $user_id; |
3410
|
|
|
$select = "SELECT DISTINCT c.*, c.id as real_id "; |
3411
|
|
|
|
3412
|
|
|
if ($getCount) { |
3413
|
|
|
$select = "SELECT COUNT(DISTINCT c.id) as count"; |
3414
|
|
|
} |
3415
|
|
|
|
3416
|
|
|
$whereConditions = ''; |
3417
|
|
|
switch ($status) { |
3418
|
|
|
case COURSEMANAGER: |
3419
|
|
|
$whereConditions .= " AND cru.user_id = $user_id"; |
3420
|
|
|
if (!$showAllAssignedCourses) { |
3421
|
|
|
$whereConditions .= " AND cru.status = ".COURSEMANAGER; |
3422
|
|
|
} else { |
3423
|
|
|
$whereConditions .= " AND relation_type = ".COURSE_RELATION_TYPE_COURSE_MANAGER; |
3424
|
|
|
} |
3425
|
|
|
break; |
3426
|
|
|
case DRH: |
3427
|
|
|
$whereConditions .= " AND |
3428
|
|
|
cru.user_id = $user_id AND |
3429
|
|
|
cru.status = ".DRH." AND |
3430
|
|
|
relation_type = '".COURSE_RELATION_TYPE_RRHH."' |
3431
|
|
|
"; |
3432
|
|
|
break; |
3433
|
|
|
} |
3434
|
|
|
|
3435
|
|
|
$keywordCondition = null; |
3436
|
|
|
if (!empty($keyword)) { |
3437
|
|
|
$keyword = Database::escape_string($keyword); |
3438
|
|
|
$keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) "; |
3439
|
|
|
} |
3440
|
|
|
|
3441
|
|
|
$orderBy = null; |
3442
|
|
|
$extraInnerJoin = null; |
3443
|
|
|
|
3444
|
|
|
if (!empty($sessionId)) { |
3445
|
|
|
if (COURSEMANAGER == $status) { |
3446
|
|
|
// Teacher of course or teacher inside session |
3447
|
|
|
$whereConditions = " AND (cru.status = ".COURSEMANAGER." OR srcru.status = 2) "; |
3448
|
|
|
} |
3449
|
|
|
$courseList = SessionManager::get_course_list_by_session_id($sessionId); |
3450
|
|
|
if (!empty($courseList)) { |
3451
|
|
|
$courseListToString = implode("','", array_keys($courseList)); |
3452
|
|
|
$whereConditions .= " AND c.id IN ('".$courseListToString."')"; |
3453
|
|
|
} |
3454
|
|
|
$tableSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE); |
3455
|
|
|
$tableSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
3456
|
|
|
$orderBy = ' ORDER BY position'; |
3457
|
|
|
$extraInnerJoin = " INNER JOIN $tableSessionRelCourse src |
3458
|
|
|
ON (c.id = src.c_id AND src.session_id = $sessionId) |
3459
|
|
|
INNER JOIN $tableSessionRelCourseRelUser srcru |
3460
|
|
|
ON (src.session_id = srcru.session_id AND srcru.c_id = src.c_id) |
3461
|
|
|
"; |
3462
|
|
|
} |
3463
|
|
|
|
3464
|
|
|
$whereConditions .= $keywordCondition; |
3465
|
|
|
$sql = "$select |
3466
|
|
|
FROM $tbl_course c |
3467
|
|
|
INNER JOIN $tbl_course_rel_user cru |
3468
|
|
|
ON (cru.c_id = c.id) |
3469
|
|
|
INNER JOIN $tbl_course_rel_access_url a |
3470
|
|
|
ON (a.c_id = c.id) |
3471
|
|
|
$extraInnerJoin |
3472
|
|
|
WHERE |
3473
|
|
|
access_url_id = ".api_get_current_access_url_id()." |
3474
|
|
|
$whereConditions |
3475
|
|
|
$orderBy |
3476
|
|
|
"; |
3477
|
|
|
if (isset($from) && isset($limit)) { |
3478
|
|
|
$from = intval($from); |
3479
|
|
|
$limit = intval($limit); |
3480
|
|
|
$sql .= " LIMIT $from, $limit"; |
3481
|
|
|
} |
3482
|
|
|
|
3483
|
|
|
$result = Database::query($sql); |
3484
|
|
|
|
3485
|
|
|
if ($getCount) { |
3486
|
|
|
$row = Database::fetch_array($result); |
3487
|
|
|
|
3488
|
|
|
return $row['count']; |
3489
|
|
|
} |
3490
|
|
|
|
3491
|
|
|
$courses = []; |
3492
|
|
|
if (Database::num_rows($result) > 0) { |
3493
|
|
|
while ($row = Database::fetch_array($result)) { |
3494
|
|
|
$courses[$row['code']] = $row; |
3495
|
|
|
} |
3496
|
|
|
} |
3497
|
|
|
|
3498
|
|
|
return $courses; |
3499
|
|
|
} |
3500
|
|
|
|
3501
|
|
|
/** |
3502
|
|
|
* check if a course is special (autoregister). |
3503
|
|
|
* |
3504
|
|
|
* @param int $courseId |
3505
|
|
|
* |
3506
|
|
|
* @return bool |
3507
|
|
|
*/ |
3508
|
|
|
public static function isSpecialCourse($courseId) |
3509
|
|
|
{ |
3510
|
|
|
$extraFieldValue = new ExtraFieldValue('course'); |
3511
|
|
|
$result = $extraFieldValue->get_values_by_handler_and_field_variable( |
3512
|
|
|
$courseId, |
3513
|
|
|
'special_course' |
3514
|
|
|
); |
3515
|
|
|
|
3516
|
|
|
if (!empty($result)) { |
3517
|
|
|
if (1 == $result['value']) { |
3518
|
|
|
return true; |
3519
|
|
|
} |
3520
|
|
|
} |
3521
|
|
|
|
3522
|
|
|
return false; |
3523
|
|
|
} |
3524
|
|
|
|
3525
|
|
|
/** |
3526
|
|
|
* Display special courses (and only these) as several HTML divs of class userportal-course-item. |
3527
|
|
|
* |
3528
|
|
|
* Special courses are courses that stick on top of the list and are "auto-registerable" |
3529
|
|
|
* in the sense that any user clicking them is registered as a student |
3530
|
|
|
* |
3531
|
|
|
* @param int $user_id User id |
3532
|
|
|
* @param bool $load_dirs Whether to show the document quick-loader or not |
3533
|
|
|
* @param bool $useUserLanguageFilterIfAvailable |
3534
|
|
|
* |
3535
|
|
|
* @return array |
3536
|
|
|
*/ |
3537
|
|
|
public static function returnSpecialCourses( |
3538
|
|
|
$user_id, |
3539
|
|
|
$load_dirs = false, |
3540
|
|
|
$useUserLanguageFilterIfAvailable = true |
3541
|
|
|
) { |
3542
|
|
|
$user_id = (int) $user_id; |
3543
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
3544
|
|
|
$specialCourseList = self::get_special_course_list(); |
3545
|
|
|
|
3546
|
|
|
if (empty($specialCourseList)) { |
3547
|
|
|
return []; |
3548
|
|
|
} |
3549
|
|
|
|
3550
|
|
|
// Filter by language |
3551
|
|
|
$languageCondition = ''; |
3552
|
|
|
$onlyInUserLanguage = api_get_configuration_value('my_courses_show_courses_in_user_language_only'); |
3553
|
|
|
if ($useUserLanguageFilterIfAvailable && $onlyInUserLanguage) { |
3554
|
|
|
$userInfo = api_get_user_info(api_get_user_id()); |
3555
|
|
|
if (!empty($userInfo['language'])) { |
3556
|
|
|
$languageCondition = " AND course_language = '".$userInfo['language']."' "; |
3557
|
|
|
} |
3558
|
|
|
} |
3559
|
|
|
|
3560
|
|
|
$sql = "SELECT |
3561
|
|
|
id, |
3562
|
|
|
code, |
3563
|
|
|
subscribe subscr, |
3564
|
|
|
unsubscribe unsubscr |
3565
|
|
|
FROM $table |
3566
|
|
|
WHERE |
3567
|
|
|
id IN ('".implode("','", $specialCourseList)."') |
3568
|
|
|
$languageCondition |
3569
|
|
|
GROUP BY code"; |
3570
|
|
|
|
3571
|
|
|
$rs_special_course = Database::query($sql); |
3572
|
|
|
$number_of_courses = Database::num_rows($rs_special_course); |
3573
|
|
|
$showCustomIcon = api_get_setting('course_images_in_courses_list'); |
3574
|
|
|
|
3575
|
|
|
$courseList = []; |
3576
|
|
|
if ($number_of_courses > 0) { |
3577
|
|
|
while ($course = Database::fetch_array($rs_special_course)) { |
3578
|
|
|
$course_info = api_get_course_info($course['code']); |
3579
|
|
|
$courseId = $course_info['real_id']; |
3580
|
|
|
if (Course::HIDDEN == $course_info['visibility']) { |
3581
|
|
|
continue; |
3582
|
|
|
} |
3583
|
|
|
|
3584
|
|
|
$params = []; |
3585
|
|
|
//Param (course_code) needed to get the student info in page "My courses" |
3586
|
|
|
$params['course_code'] = $course['code']; |
3587
|
|
|
$params['code'] = $course['code']; |
3588
|
|
|
// Get notifications. |
3589
|
|
|
$course_info['id_session'] = null; |
3590
|
|
|
$courseUserInfo = self::getUserCourseInfo($user_id, $courseId); |
3591
|
|
|
|
3592
|
|
|
if (empty($courseUserInfo)) { |
3593
|
|
|
$course_info['status'] = STUDENT; |
3594
|
|
|
} else { |
3595
|
|
|
$course_info['status'] = $courseUserInfo['status']; |
3596
|
|
|
} |
3597
|
|
|
$show_notification = !api_get_configuration_value('hide_course_notification') |
3598
|
|
|
? Display::show_notification($course_info) |
3599
|
|
|
: ''; |
3600
|
|
|
$params['edit_actions'] = ''; |
3601
|
|
|
$params['document'] = ''; |
3602
|
|
|
if (api_is_platform_admin()) { |
3603
|
|
|
$params['edit_actions'] .= api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cid='.$course['real_id']; |
3604
|
|
|
if ($load_dirs) { |
3605
|
|
|
$params['document'] = '<a id="document_preview_'.$courseId.'_0" class="document_preview btn btn-outline-secondary btn-sm" href="javascript:void(0);">' |
3606
|
|
|
.Display::returnFontAwesomeIcon('folder-open').'</a>'; |
3607
|
|
|
$params['document'] .= Display::div('', ['id' => 'document_result_'.$courseId.'_0', 'class' => 'document_preview_container']); |
3608
|
|
|
} |
3609
|
|
|
} else { |
3610
|
|
|
if (Course::CLOSED != $course_info['visibility'] && $load_dirs) { |
3611
|
|
|
$params['document'] = '<a id="document_preview_'.$courseId.'_0" class="document_preview btn btn-outline-secondary btn-sm" href="javascript:void(0);">' |
3612
|
|
|
.Display::returnFontAwesomeIcon('folder-open').'</a>'; |
3613
|
|
|
$params['document'] .= Display::div('', ['id' => 'document_result_'.$courseId.'_0', 'class' => 'document_preview_container']); |
3614
|
|
|
} |
3615
|
|
|
} |
3616
|
|
|
|
3617
|
|
|
$params['visibility'] = $course_info['visibility']; |
3618
|
|
|
$params['status'] = $course_info['status']; |
3619
|
|
|
$params['category'] = $course_info['categoryName']; |
3620
|
|
|
$params['category_code'] = $course_info['categoryCode']; |
3621
|
|
|
$params['icon'] = Display::return_icon( |
3622
|
|
|
'drawing-pin.png', |
3623
|
|
|
null, |
3624
|
|
|
null, |
3625
|
|
|
ICON_SIZE_LARGE, |
3626
|
|
|
null |
3627
|
|
|
); |
3628
|
|
|
|
3629
|
|
|
if ('true' == api_get_setting('display_coursecode_in_courselist')) { |
3630
|
|
|
$params['code_course'] = '('.$course_info['visual_code'].')'; |
3631
|
|
|
} |
3632
|
|
|
|
3633
|
|
|
$params['title'] = $course_info['title']; |
3634
|
|
|
$params['title_cut'] = $course_info['title']; |
3635
|
|
|
$params['link'] = $course_info['course_public_url'].'?sid=0&autoreg=1'; |
3636
|
|
|
if ('true' === api_get_setting('display_teacher_in_courselist')) { |
3637
|
|
|
$params['teachers'] = self::getTeachersFromCourse( |
3638
|
|
|
$courseId, |
3639
|
|
|
true |
3640
|
|
|
); |
3641
|
|
|
} |
3642
|
|
|
|
3643
|
|
|
$params['extrafields'] = CourseManager::getExtraFieldsToBePresented($course_info['real_id']); |
3644
|
|
|
|
3645
|
|
|
if ('true' === $showCustomIcon) { |
3646
|
|
|
$params['thumbnails'] = $course_info['course_image']; |
3647
|
|
|
$params['image'] = $course_info['course_image_large']; |
3648
|
|
|
} |
3649
|
|
|
|
3650
|
|
|
if (Course::CLOSED != $course_info['visibility']) { |
3651
|
|
|
$params['notifications'] = $show_notification; |
3652
|
|
|
} |
3653
|
|
|
|
3654
|
|
|
$params['is_special_course'] = true; |
3655
|
|
|
$courseList[] = $params; |
3656
|
|
|
} |
3657
|
|
|
} |
3658
|
|
|
|
3659
|
|
|
return $courseList; |
3660
|
|
|
} |
3661
|
|
|
|
3662
|
|
|
/** |
3663
|
|
|
* Display courses inside a category (without special courses) as HTML dics of |
3664
|
|
|
* class userportal-course-item. |
3665
|
|
|
* |
3666
|
|
|
* @param int $user_category_id User category id |
3667
|
|
|
* @param bool $load_dirs Whether to show the document quick-loader or not |
3668
|
|
|
* @param int $user_id |
3669
|
|
|
* @param bool $useUserLanguageFilterIfAvailable |
3670
|
|
|
* |
3671
|
|
|
* @return array |
3672
|
|
|
*/ |
3673
|
|
|
public static function returnCoursesCategories( |
3674
|
|
|
$user_category_id, |
3675
|
|
|
$load_dirs = false, |
3676
|
|
|
$user_id = 0, |
3677
|
|
|
$useUserLanguageFilterIfAvailable = true |
3678
|
|
|
) { |
3679
|
|
|
$user_id = $user_id ? (int) $user_id : api_get_user_id(); |
3680
|
|
|
$user_category_id = (int) $user_category_id; |
3681
|
|
|
|
3682
|
|
|
// Table definitions |
3683
|
|
|
$TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE); |
3684
|
|
|
$TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
3685
|
|
|
$TABLE_ACCESS_URL_REL_COURSE = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
3686
|
|
|
$current_url_id = api_get_current_access_url_id(); |
3687
|
|
|
|
3688
|
|
|
// Get course list auto-register |
3689
|
|
|
$special_course_list = self::get_special_course_list(); |
3690
|
|
|
$without_special_courses = ''; |
3691
|
|
|
if (!empty($special_course_list)) { |
3692
|
|
|
$without_special_courses = ' AND course.id NOT IN ("'.implode('","', $special_course_list).'")'; |
3693
|
|
|
} |
3694
|
|
|
|
3695
|
|
|
$userCategoryCondition = " (course_rel_user.user_course_cat = $user_category_id) "; |
3696
|
|
|
if (empty($user_category_id)) { |
3697
|
|
|
$userCategoryCondition = ' (course_rel_user.user_course_cat = 0 OR course_rel_user.user_course_cat IS NULL) '; |
3698
|
|
|
} |
3699
|
|
|
|
3700
|
|
|
$languageCondition = ''; |
3701
|
|
|
$onlyInUserLanguage = api_get_configuration_value('my_courses_show_courses_in_user_language_only'); |
3702
|
|
|
if ($useUserLanguageFilterIfAvailable && $onlyInUserLanguage) { |
3703
|
|
|
$userInfo = api_get_user_info(api_get_user_id()); |
3704
|
|
|
if (!empty($userInfo['language'])) { |
3705
|
|
|
$languageCondition = " AND course.course_language = '".$userInfo['language']."' "; |
3706
|
|
|
} |
3707
|
|
|
} |
3708
|
|
|
|
3709
|
|
|
$sql = "SELECT DISTINCT |
3710
|
|
|
course.id, |
3711
|
|
|
course_rel_user.status status, |
3712
|
|
|
course.code as course_code, |
3713
|
|
|
user_course_cat, |
3714
|
|
|
course_rel_user.sort |
3715
|
|
|
FROM $TABLECOURS course |
3716
|
|
|
INNER JOIN $TABLECOURSUSER course_rel_user |
3717
|
|
|
ON (course.id = course_rel_user.c_id) |
3718
|
|
|
INNER JOIN $TABLE_ACCESS_URL_REL_COURSE url |
3719
|
|
|
ON (url.c_id = course.id) |
3720
|
|
|
WHERE |
3721
|
|
|
course_rel_user.user_id = $user_id AND |
3722
|
|
|
$userCategoryCondition |
3723
|
|
|
$without_special_courses |
3724
|
|
|
$languageCondition |
3725
|
|
|
"; |
3726
|
|
|
// If multiple URL access mode is enabled, only fetch courses |
3727
|
|
|
// corresponding to the current URL. |
3728
|
|
|
if (api_get_multiple_access_url() && -1 != $current_url_id) { |
3729
|
|
|
$sql .= " AND access_url_id = $current_url_id"; |
3730
|
|
|
} |
3731
|
|
|
// Use user's classification for courses (if any). |
3732
|
|
|
$sql .= ' ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC'; |
3733
|
|
|
$result = Database::query($sql); |
3734
|
|
|
|
3735
|
|
|
$showCustomIcon = api_get_setting('course_images_in_courses_list'); |
3736
|
|
|
// Browse through all courses. |
3737
|
|
|
$courseAdded = []; |
3738
|
|
|
$courseList = []; |
3739
|
|
|
|
3740
|
|
|
while ($row = Database::fetch_array($result)) { |
3741
|
|
|
$course_info = api_get_course_info_by_id($row['id']); |
3742
|
|
|
if (empty($course_info)) { |
3743
|
|
|
continue; |
3744
|
|
|
} |
3745
|
|
|
|
3746
|
|
|
if (isset($course_info['visibility']) && |
3747
|
|
|
Course::HIDDEN == $course_info['visibility'] |
3748
|
|
|
) { |
3749
|
|
|
continue; |
3750
|
|
|
} |
3751
|
|
|
|
3752
|
|
|
// Skip if already in list |
3753
|
|
|
if (in_array($course_info['real_id'], $courseAdded)) { |
3754
|
|
|
continue; |
3755
|
|
|
} |
3756
|
|
|
$course_info['id_session'] = null; |
3757
|
|
|
$course_info['status'] = $row['status']; |
3758
|
|
|
// For each course, get if there is any notification icon to show |
3759
|
|
|
// (something that would have changed since the user's last visit). |
3760
|
|
|
$showNotification = !api_get_configuration_value('hide_course_notification') |
3761
|
|
|
? Display::show_notification($course_info) |
3762
|
|
|
: ''; |
3763
|
|
|
$iconName = basename($course_info['course_image']); |
3764
|
|
|
|
3765
|
|
|
$params = []; |
3766
|
|
|
//Param (course_code) needed to get the student process |
3767
|
|
|
$params['course_code'] = $row['course_code']; |
3768
|
|
|
$params['code'] = $row['course_code']; |
3769
|
|
|
|
3770
|
|
|
if ('true' === $showCustomIcon && 'course.png' != $iconName) { |
3771
|
|
|
$params['thumbnails'] = $course_info['course_image']; |
3772
|
|
|
$params['image'] = $course_info['course_image_large']; |
3773
|
|
|
} |
3774
|
|
|
|
3775
|
|
|
$thumbnails = null; |
3776
|
|
|
$image = null; |
3777
|
|
|
if ('true' === $showCustomIcon && 'course.png' != $iconName) { |
3778
|
|
|
$thumbnails = $course_info['course_image']; |
3779
|
|
|
$image = $course_info['course_image_large']; |
3780
|
|
|
} else { |
3781
|
|
|
$image = Display::return_icon( |
3782
|
|
|
'session_default.png', |
3783
|
|
|
null, |
3784
|
|
|
null, |
3785
|
|
|
null, |
3786
|
|
|
null, |
3787
|
|
|
true |
3788
|
|
|
); |
3789
|
|
|
} |
3790
|
|
|
|
3791
|
|
|
$params['course_id'] = $course_info['real_id']; |
3792
|
|
|
$params['edit_actions'] = ''; |
3793
|
|
|
$params['document'] = ''; |
3794
|
|
|
if (api_is_platform_admin()) { |
3795
|
|
|
$params['edit_actions'] .= api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cid='.$course_info['real_id']; |
3796
|
|
|
if ($load_dirs) { |
3797
|
|
|
$params['document'] = '<a id="document_preview_'.$course_info['real_id'].'_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">' |
3798
|
|
|
.Display::returnFontAwesomeIcon('folder-open').'</a>'; |
3799
|
|
|
$params['document'] .= Display::div( |
3800
|
|
|
'', |
3801
|
|
|
[ |
3802
|
|
|
'id' => 'document_result_'.$course_info['real_id'].'_0', |
3803
|
|
|
'class' => 'document_preview_container', |
3804
|
|
|
] |
3805
|
|
|
); |
3806
|
|
|
} |
3807
|
|
|
} |
3808
|
|
|
if ($load_dirs) { |
3809
|
|
|
$params['document'] = '<a id="document_preview_'.$course_info['real_id'].'_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">' |
3810
|
|
|
.Display::returnFontAwesomeIcon('folder-open').'</a>'; |
3811
|
|
|
$params['document'] .= Display::div( |
3812
|
|
|
'', |
3813
|
|
|
[ |
3814
|
|
|
'id' => 'document_result_'.$course_info['real_id'].'_0', |
3815
|
|
|
'class' => 'document_preview_container', |
3816
|
|
|
] |
3817
|
|
|
); |
3818
|
|
|
} |
3819
|
|
|
|
3820
|
|
|
$courseUrl = $course_info['course_public_url'].'?sid=0'; |
3821
|
|
|
$teachers = []; |
3822
|
|
|
if ('true' === api_get_setting('display_teacher_in_courselist')) { |
3823
|
|
|
$teachers = self::getTeachersFromCourse( |
3824
|
|
|
$course_info['real_id'], |
3825
|
|
|
true |
3826
|
|
|
); |
3827
|
|
|
} |
3828
|
|
|
|
3829
|
|
|
$params['status'] = $row['status']; |
3830
|
|
|
if ('true' === api_get_setting('display_coursecode_in_courselist')) { |
3831
|
|
|
$params['code_course'] = '('.$course_info['visual_code'].') '; |
3832
|
|
|
} |
3833
|
|
|
|
3834
|
|
|
$params['current_user_is_teacher'] = false; |
3835
|
|
|
/** @var array $teacher */ |
3836
|
|
|
foreach ($teachers as $teacher) { |
3837
|
|
|
if ($teacher['id'] != $user_id) { |
3838
|
|
|
continue; |
3839
|
|
|
} |
3840
|
|
|
$params['current_user_is_teacher'] = true; |
3841
|
|
|
} |
3842
|
|
|
|
3843
|
|
|
$params['visibility'] = $course_info['visibility']; |
3844
|
|
|
$params['link'] = $courseUrl; |
3845
|
|
|
$params['thumbnails'] = $thumbnails; |
3846
|
|
|
$params['image'] = $image; |
3847
|
|
|
$params['title'] = $course_info['title']; |
3848
|
|
|
$params['title_cut'] = $params['title']; |
3849
|
|
|
$params['category'] = $course_info['categoryName']; |
3850
|
|
|
$params['category_code'] = $course_info['categoryCode']; |
3851
|
|
|
$params['teachers'] = $teachers; |
3852
|
|
|
$params['extrafields'] = CourseManager::getExtraFieldsToBePresented($course_info['real_id']); |
3853
|
|
|
$params['real_id'] = $course_info['real_id']; |
3854
|
|
|
|
3855
|
|
|
if (api_get_configuration_value('enable_unsubscribe_button_on_my_course_page') |
3856
|
|
|
&& '1' === $course_info['unsubscribe'] |
3857
|
|
|
) { |
3858
|
|
|
$params['unregister_button'] = CoursesAndSessionsCatalog::return_unregister_button( |
3859
|
|
|
$course_info, |
3860
|
|
|
Security::get_existing_token(), |
3861
|
|
|
'', |
3862
|
|
|
'' |
3863
|
|
|
); |
3864
|
|
|
} |
3865
|
|
|
|
3866
|
|
|
if (Course::CLOSED != $course_info['visibility']) { |
3867
|
|
|
$params['notifications'] = $showNotification; |
3868
|
|
|
} |
3869
|
|
|
$courseAdded[] = $course_info['real_id']; |
3870
|
|
|
$courseList[] = $params; |
3871
|
|
|
} |
3872
|
|
|
|
3873
|
|
|
return $courseList; |
3874
|
|
|
} |
3875
|
|
|
|
3876
|
|
|
/** |
3877
|
|
|
* Get the course id based on the original id and field name in the extra fields. |
3878
|
|
|
* Returns 0 if course was not found. |
3879
|
|
|
* |
3880
|
|
|
* @param string $value Original course code |
3881
|
|
|
* @param string $variable Original field name |
3882
|
|
|
* |
3883
|
|
|
* @return array |
3884
|
|
|
*/ |
3885
|
|
|
public static function getCourseInfoFromOriginalId($value, $variable) |
3886
|
|
|
{ |
3887
|
|
|
$extraFieldValue = new ExtraFieldValue('course'); |
3888
|
|
|
$result = $extraFieldValue->get_item_id_from_field_variable_and_field_value( |
3889
|
|
|
$variable, |
3890
|
|
|
$value |
3891
|
|
|
); |
3892
|
|
|
|
3893
|
|
|
if (!empty($result)) { |
3894
|
|
|
return api_get_course_info_by_id($result['item_id']); |
3895
|
|
|
} |
3896
|
|
|
|
3897
|
|
|
return []; |
3898
|
|
|
} |
3899
|
|
|
|
3900
|
|
|
/** |
3901
|
|
|
* Display code for one specific course a logged in user is subscribed to. |
3902
|
|
|
* Shows a link to the course, what's new icons... |
3903
|
|
|
* |
3904
|
|
|
* $my_course['d'] - course directory |
3905
|
|
|
* $my_course['i'] - course title |
3906
|
|
|
* $my_course['c'] - visual course code |
3907
|
|
|
* $my_course['k'] - system course code |
3908
|
|
|
* |
3909
|
|
|
* @param array Course details |
3910
|
|
|
* @param int Session ID |
3911
|
|
|
* @param string CSS class to apply to course entry |
3912
|
|
|
* @param bool Whether the session is supposedly accessible now |
3913
|
|
|
* (not in the case it has passed and is in invisible/unaccessible mode) |
3914
|
|
|
* @param bool Whether to show the document quick-loader or not |
3915
|
|
|
* |
3916
|
|
|
* @return string The HTML to be printed for the course entry |
3917
|
|
|
* |
3918
|
|
|
* @version 1.0.3 |
3919
|
|
|
* |
3920
|
|
|
* @todo refactor into different functions for database calls | logic | display |
3921
|
|
|
* @todo replace single-character $my_course['d'] indices |
3922
|
|
|
* @todo move code for what's new icons to a separate function to clear things up |
3923
|
|
|
* @todo add a parameter user_id so that it is possible to show the |
3924
|
|
|
* courselist of other users (=generalisation). |
3925
|
|
|
* This will prevent having to write a new function for this. |
3926
|
|
|
*/ |
3927
|
|
|
public static function get_logged_user_course_html( |
3928
|
|
|
$course, |
3929
|
|
|
$session_id = 0, |
3930
|
|
|
$class = 'courses', |
3931
|
|
|
$session_accessible = true, |
3932
|
|
|
$load_dirs = false |
3933
|
|
|
) { |
3934
|
|
|
$now = date('Y-m-d h:i:s'); |
3935
|
|
|
$user_id = api_get_user_id(); |
3936
|
|
|
$course_info = api_get_course_info_by_id($course['real_id']); |
3937
|
|
|
$course_visibility = (int) $course_info['visibility']; |
3938
|
|
|
$allowUnsubscribe = api_get_configuration_value('enable_unsubscribe_button_on_my_course_page'); |
3939
|
|
|
|
3940
|
|
|
if (Course::HIDDEN === $course_visibility) { |
3941
|
|
|
return ''; |
3942
|
|
|
} |
3943
|
|
|
|
3944
|
|
|
$sessionInfo = []; |
3945
|
|
|
if (!empty($session_id)) { |
3946
|
|
|
$sessionInfo = api_get_session_info($session_id); |
3947
|
|
|
} |
3948
|
|
|
$userInCourseStatus = self::getUserInCourseStatus($user_id, $course_info['real_id']); |
3949
|
|
|
$course_info['status'] = empty($session_id) ? $userInCourseStatus : STUDENT; |
3950
|
|
|
$course_info['id_session'] = $session_id; |
3951
|
|
|
|
3952
|
|
|
$is_coach = api_is_coach($session_id, $course_info['real_id']); |
3953
|
|
|
$isAdmin = api_is_platform_admin(); |
3954
|
|
|
|
3955
|
|
|
// Display course entry. |
3956
|
|
|
// Show a hyperlink to the course, unless the course is closed and user is not course admin. |
3957
|
|
|
$session_url = ''; |
3958
|
|
|
$params = []; |
3959
|
|
|
$params['icon'] = Display::return_icon( |
3960
|
|
|
'session.png', |
3961
|
|
|
null, |
3962
|
|
|
[], |
3963
|
|
|
ICON_SIZE_LARGE, |
3964
|
|
|
null, |
3965
|
|
|
true |
3966
|
|
|
); |
3967
|
|
|
$params['real_id'] = $course_info['real_id']; |
3968
|
|
|
$params['visibility'] = $course_info['visibility']; |
3969
|
|
|
|
3970
|
|
|
// Display the "what's new" icons |
3971
|
|
|
$notifications = ''; |
3972
|
|
|
if ( |
3973
|
|
|
(Course::CLOSED != $course_visibility && Course::HIDDEN != $course_visibility) || |
3974
|
|
|
!api_get_configuration_value('hide_course_notification') |
3975
|
|
|
) { |
3976
|
|
|
$notifications .= Display::show_notification($course_info); |
3977
|
|
|
} |
3978
|
|
|
|
3979
|
|
|
$sessionCourseAvailable = false; |
3980
|
|
|
if ($session_accessible) { |
3981
|
|
|
if (Course::CLOSED != $course_visibility || |
3982
|
|
|
COURSEMANAGER == $userInCourseStatus |
3983
|
|
|
) { |
3984
|
|
|
if (empty($course_info['id_session'])) { |
3985
|
|
|
$course_info['id_session'] = 0; |
3986
|
|
|
} |
3987
|
|
|
|
3988
|
|
|
$sessionCourseStatus = api_get_session_visibility($session_id, $course_info['real_id']); |
3989
|
|
|
|
3990
|
|
|
if (in_array( |
3991
|
|
|
$sessionCourseStatus, |
3992
|
|
|
[SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_AVAILABLE] |
3993
|
|
|
)) { |
3994
|
|
|
$sessionCourseAvailable = true; |
3995
|
|
|
} |
3996
|
|
|
|
3997
|
|
|
if (COURSEMANAGER === $userInCourseStatus || $sessionCourseAvailable) { |
3998
|
|
|
$session_url = $course_info['course_public_url'].'?sid='.$course_info['id_session']; |
3999
|
|
|
$session_title = '<a title="'.$course_info['name'].'" href="'.$session_url.'">'. |
4000
|
|
|
$course_info['name'].'</a>'.$notifications; |
4001
|
|
|
} else { |
4002
|
|
|
$session_title = $course_info['name']; |
4003
|
|
|
} |
4004
|
|
|
} else { |
4005
|
|
|
$session_title = |
4006
|
|
|
$course_info['name'].' '. |
4007
|
|
|
Display::tag('span', get_lang('(the course is currently closed)'), ['class' => 'item_closed']); |
4008
|
|
|
} |
4009
|
|
|
} else { |
4010
|
|
|
$session_title = $course_info['name']; |
4011
|
|
|
} |
4012
|
|
|
|
4013
|
|
|
$thumbnails = null; |
4014
|
|
|
$image = null; |
4015
|
|
|
$showCustomIcon = api_get_setting('course_images_in_courses_list'); |
4016
|
|
|
$iconName = basename($course_info['course_image']); |
4017
|
|
|
|
4018
|
|
|
if ('true' === $showCustomIcon && 'course.png' != $iconName) { |
4019
|
|
|
$thumbnails = $course_info['course_image']; |
4020
|
|
|
$image = $course_info['course_image_large']; |
4021
|
|
|
} else { |
4022
|
|
|
$image = Display::return_icon( |
4023
|
|
|
'session_default.png', |
4024
|
|
|
null, |
4025
|
|
|
null, |
4026
|
|
|
null, |
4027
|
|
|
null, |
4028
|
|
|
true |
4029
|
|
|
); |
4030
|
|
|
} |
4031
|
|
|
$params['thumbnails'] = $thumbnails; |
4032
|
|
|
$params['image'] = $image; |
4033
|
|
|
$params['html_image'] = ''; |
4034
|
|
|
if (!empty($thumbnails)) { |
4035
|
|
|
$params['html_image'] = Display::img($thumbnails, $course_info['name'], ['class' => 'img-responsive']); |
4036
|
|
|
} else { |
4037
|
|
|
$params['html_image'] = Display::return_icon( |
4038
|
|
|
'session.png', |
4039
|
|
|
$course_info['name'], |
4040
|
|
|
['class' => 'img-responsive'], |
4041
|
|
|
ICON_SIZE_LARGE, |
4042
|
|
|
$course_info['name'] |
4043
|
|
|
); |
4044
|
|
|
} |
4045
|
|
|
$params['link'] = $session_url; |
4046
|
|
|
$entityManager = Database::getManager(); |
4047
|
|
|
/** @var SequenceResourceRepository $repo */ |
4048
|
|
|
$repo = $entityManager->getRepository(SequenceResource::class); |
4049
|
|
|
|
4050
|
|
|
$sequences = $repo->getRequirements($course_info['real_id'], SequenceResource::COURSE_TYPE); |
4051
|
|
|
$sequenceList = $repo->checkRequirementsForUser( |
4052
|
|
|
$sequences, |
4053
|
|
|
SequenceResource::COURSE_TYPE, |
4054
|
|
|
$user_id, |
4055
|
|
|
$session_id |
4056
|
|
|
); |
4057
|
|
|
$completed = $repo->checkSequenceAreCompleted($sequenceList); |
4058
|
|
|
//var_dump($course_info['real_id'], $completed); |
4059
|
|
|
$params['completed'] = $completed; |
4060
|
|
|
$params['requirements'] = ''; |
4061
|
|
|
|
4062
|
|
|
if ($isAdmin || |
4063
|
|
|
COURSEMANAGER === $userInCourseStatus || |
4064
|
|
|
$is_coach || |
4065
|
|
|
$user_id == $sessionInfo['session_admin_id'] |
4066
|
|
|
) { |
4067
|
|
|
$params['completed'] = true; |
4068
|
|
|
$params['requirements'] = ''; |
4069
|
|
|
} else { |
4070
|
|
|
if ($sequences && false === $completed) { |
4071
|
|
|
$hasRequirements = false; |
4072
|
|
|
foreach ($sequences as $sequence) { |
4073
|
|
|
if (!empty($sequence['requirements'])) { |
4074
|
|
|
$hasRequirements = true; |
4075
|
|
|
break; |
4076
|
|
|
} |
4077
|
|
|
} |
4078
|
|
|
if ($hasRequirements) { |
4079
|
|
|
$params['requirements'] = CoursesAndSessionsCatalog::getRequirements( |
4080
|
|
|
$course_info['real_id'], |
4081
|
|
|
SequenceResource::COURSE_TYPE, |
4082
|
|
|
false, |
4083
|
|
|
false, |
4084
|
|
|
$session_id |
4085
|
|
|
); |
4086
|
|
|
} |
4087
|
|
|
} |
4088
|
|
|
} |
4089
|
|
|
|
4090
|
|
|
$params['title'] = $session_title; |
4091
|
|
|
$params['name'] = $course_info['name']; |
4092
|
|
|
$params['edit_actions'] = ''; |
4093
|
|
|
$params['document'] = ''; |
4094
|
|
|
$params['category'] = $course_info['categoryName']; |
4095
|
|
|
if (Course::CLOSED != $course_visibility && |
4096
|
|
|
false === $is_coach && $allowUnsubscribe && '1' === $course_info['unsubscribe']) { |
4097
|
|
|
$params['unregister_button'] = |
4098
|
|
|
CoursesAndSessionsCatalog::return_unregister_button( |
4099
|
|
|
['code' => $course_info['code']], |
4100
|
|
|
Security::get_existing_token(), |
4101
|
|
|
'', |
4102
|
|
|
'', |
4103
|
|
|
$session_id |
4104
|
|
|
); |
4105
|
|
|
} |
4106
|
|
|
|
4107
|
|
|
if (Course::CLOSED != $course_visibility && |
4108
|
|
|
Course::HIDDEN != $course_visibility |
4109
|
|
|
) { |
4110
|
|
|
if ($isAdmin) { |
4111
|
|
|
$params['edit_actions'] .= api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cidReq='.$course_info['code']; |
4112
|
|
|
if ($load_dirs) { |
4113
|
|
|
$params['document'] .= '<a |
4114
|
|
|
id="document_preview_'.$course_info['real_id'].'_'.$session_id.'" |
4115
|
|
|
class="document_preview btn btn-default btn-sm" |
4116
|
|
|
href="javascript:void(0);">'. |
4117
|
|
|
Display::returnFontAwesomeIcon('folder-open').'</a>'; |
4118
|
|
|
$params['document'] .= Display::div('', [ |
4119
|
|
|
'id' => 'document_result_'.$course_info['real_id'].'_'.$session_id, |
4120
|
|
|
'class' => 'document_preview_container', |
4121
|
|
|
]); |
4122
|
|
|
} |
4123
|
|
|
} |
4124
|
|
|
} |
4125
|
|
|
if ('true' === api_get_setting('display_teacher_in_courselist')) { |
4126
|
|
|
$teacher_list = self::getTeachersFromCourse($course_info['real_id'], true); |
4127
|
|
|
$course_coachs = self::get_coachs_from_course( |
4128
|
|
|
$session_id, |
4129
|
|
|
$course_info['real_id'], |
4130
|
|
|
true |
4131
|
|
|
); |
4132
|
|
|
$params['teachers'] = $teacher_list; |
4133
|
|
|
|
4134
|
|
|
if ((STUDENT == $course_info['status'] && !empty($session_id)) || |
4135
|
|
|
($is_coach && COURSEMANAGER != $course_info['status']) |
4136
|
|
|
) { |
4137
|
|
|
$params['coaches'] = $course_coachs; |
4138
|
|
|
} |
4139
|
|
|
} |
4140
|
|
|
$special = isset($course['special_course']) ? true : false; |
4141
|
|
|
$params['title'] = $session_title; |
4142
|
|
|
$params['special'] = $special; |
4143
|
|
|
if ('true' === api_get_setting('display_coursecode_in_courselist')) { |
4144
|
|
|
$params['visual_code'] = '('.$course_info['visual_code'].')'; |
4145
|
|
|
} |
4146
|
|
|
$params['extra'] = ''; |
4147
|
|
|
$html = $params; |
4148
|
|
|
|
4149
|
|
|
$session_category_id = null; |
4150
|
|
|
$active = false; |
4151
|
|
|
if (!empty($session_id)) { |
4152
|
|
|
$sessionCoachName = ''; |
4153
|
|
|
if (!empty($sessionInfo['id_coach'])) { |
4154
|
|
|
$coachInfo = api_get_user_info($sessionInfo['id_coach']); |
4155
|
|
|
$sessionCoachName = $coachInfo['complete_name']; |
4156
|
|
|
} |
4157
|
|
|
|
4158
|
|
|
$session_category_id = self::get_session_category_id_by_session_id($course_info['id_session']); |
4159
|
|
|
|
4160
|
|
|
if ( |
4161
|
|
|
'0000-00-00 00:00:00' === $sessionInfo['access_start_date'] || |
4162
|
|
|
empty($sessionInfo['access_start_date']) || |
4163
|
|
|
'0000-00-00' === $sessionInfo['access_start_date'] |
4164
|
|
|
) { |
4165
|
|
|
$sessionInfo['dates'] = ''; |
4166
|
|
|
if ('true' === api_get_setting('show_session_coach')) { |
4167
|
|
|
$sessionInfo['coach'] = get_lang('GeneralCoach').': '.$sessionCoachName; |
4168
|
|
|
} |
4169
|
|
|
$active = true; |
4170
|
|
|
} else { |
4171
|
|
|
$sessionInfo['dates'] = ' - '. |
4172
|
|
|
get_lang('From').' '.$sessionInfo['access_start_date'].' '. |
4173
|
|
|
get_lang('To').' '.$sessionInfo['access_end_date']; |
4174
|
|
|
if ('true' === api_get_setting('show_session_coach')) { |
4175
|
|
|
$sessionInfo['coach'] = get_lang('GeneralCoach').': '.$sessionCoachName; |
4176
|
|
|
} |
4177
|
|
|
$date_start = $sessionInfo['access_start_date']; |
4178
|
|
|
$date_end = $sessionInfo['access_end_date']; |
4179
|
|
|
$active = !$date_end ? ($date_start <= $now) : ($date_start <= $now && $date_end >= $now); |
4180
|
|
|
} |
4181
|
|
|
} |
4182
|
|
|
$user_course_category = ''; |
4183
|
|
|
if (isset($course_info['user_course_cat'])) { |
4184
|
|
|
$user_course_category = $course_info['user_course_cat']; |
4185
|
|
|
} |
4186
|
|
|
$output = [ |
4187
|
|
|
$user_course_category, |
4188
|
|
|
$html, |
4189
|
|
|
$course_info['id_session'], |
4190
|
|
|
$sessionInfo, |
4191
|
|
|
'active' => $active, |
4192
|
|
|
'session_category_id' => $session_category_id, |
4193
|
|
|
]; |
4194
|
|
|
|
4195
|
|
|
if (SkillModel::isAllowed($user_id, false)) { |
4196
|
|
|
$em = Database::getManager(); |
4197
|
|
|
$objUser = api_get_user_entity($user_id); |
4198
|
|
|
$objCourse = api_get_course_entity($course['real_id']); |
4199
|
|
|
$objSession = api_get_session_entity($session_id); |
4200
|
|
|
$skill = $em->getRepository(\Chamilo\CoreBundle\Entity\Skill::class)->getLastByUser($objUser, $objCourse, $objSession); |
4201
|
|
|
|
4202
|
|
|
$output['skill'] = null; |
4203
|
|
|
if ($skill) { |
4204
|
|
|
$output['skill']['name'] = $skill->getName(); |
4205
|
|
|
$output['skill']['icon'] = $skill->getIcon(); |
4206
|
|
|
} |
4207
|
|
|
} |
4208
|
|
|
|
4209
|
|
|
return $output; |
4210
|
|
|
} |
4211
|
|
|
|
4212
|
|
|
/** |
4213
|
|
|
* @param string $source_course_code |
4214
|
|
|
* @param int $source_session_id |
4215
|
|
|
* @param string $destination_course_code |
4216
|
|
|
* @param int $destination_session_id |
4217
|
|
|
* @param array $params |
4218
|
|
|
* |
4219
|
|
|
* @return bool |
4220
|
|
|
*/ |
4221
|
|
|
public static function copy_course( |
4222
|
|
|
$source_course_code, |
4223
|
|
|
$source_session_id, |
4224
|
|
|
$destination_course_code, |
4225
|
|
|
$destination_session_id, |
4226
|
|
|
$params = [], |
4227
|
|
|
$withBaseContent = true |
4228
|
|
|
) { |
4229
|
|
|
$course_info = api_get_course_info($source_course_code); |
4230
|
|
|
|
4231
|
|
|
if (!empty($course_info)) { |
4232
|
|
|
$cb = new CourseBuilder('', $course_info); |
4233
|
|
|
$course = $cb->build($source_session_id, $source_course_code, $withBaseContent); |
4234
|
|
|
$restorer = new CourseRestorer($course); |
4235
|
|
|
$restorer->skip_content = $params; |
4236
|
|
|
$restorer->restore( |
4237
|
|
|
$destination_course_code, |
4238
|
|
|
$destination_session_id, |
4239
|
|
|
true, |
4240
|
|
|
$withBaseContent |
4241
|
|
|
); |
4242
|
|
|
|
4243
|
|
|
return true; |
4244
|
|
|
} |
4245
|
|
|
|
4246
|
|
|
return false; |
4247
|
|
|
} |
4248
|
|
|
|
4249
|
|
|
/** |
4250
|
|
|
* A simpler version of the copy_course, the function creates an empty course with an autogenerated course code. |
4251
|
|
|
* |
4252
|
|
|
* @param string $new_title new course title |
4253
|
|
|
* @param string source course code |
4254
|
|
|
* @param int source session id |
4255
|
|
|
* @param int destination session id |
4256
|
|
|
* @param array $params |
4257
|
|
|
* @param bool $copySessionContent |
4258
|
|
|
* |
4259
|
|
|
* @return Course|null |
4260
|
|
|
*/ |
4261
|
|
|
public static function copy_course_simple( |
4262
|
|
|
$new_title, |
4263
|
|
|
$source_course_code, |
4264
|
|
|
$source_session_id = 0, |
4265
|
|
|
$destination_session_id = 0, |
4266
|
|
|
$params = [], |
4267
|
|
|
$copySessionContent = false |
4268
|
|
|
) { |
4269
|
|
|
$source_course_info = api_get_course_info($source_course_code); |
4270
|
|
|
if (!empty($source_course_info)) { |
4271
|
|
|
$new_course_code = self::generate_nice_next_course_code($source_course_code); |
4272
|
|
|
if ($new_course_code) { |
4273
|
|
|
$newCourse = self::create_course( |
4274
|
|
|
$new_title, |
4275
|
|
|
$new_course_code, |
4276
|
|
|
false |
4277
|
|
|
); |
4278
|
|
|
if (null !== $newCourse) { |
4279
|
|
|
$result = self::copy_course( |
4280
|
|
|
$source_course_code, |
4281
|
|
|
$source_session_id, |
4282
|
|
|
$newCourse->getCode(), |
4283
|
|
|
$destination_session_id, |
4284
|
|
|
$params, |
4285
|
|
|
true |
4286
|
|
|
); |
4287
|
|
|
if ($result) { |
4288
|
|
|
return $newCourse; |
4289
|
|
|
} |
4290
|
|
|
} |
4291
|
|
|
} |
4292
|
|
|
} |
4293
|
|
|
|
4294
|
|
|
return false; |
4295
|
|
|
} |
4296
|
|
|
|
4297
|
|
|
/** |
4298
|
|
|
* Creates a new course code based in a given code. |
4299
|
|
|
* |
4300
|
|
|
* @param string wanted code |
4301
|
|
|
* <code> $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: |
4302
|
|
|
* course3</code> if the course code doest not exist in the DB the same course code will be returned |
4303
|
|
|
* |
4304
|
|
|
* @return string wanted unused code |
4305
|
|
|
*/ |
4306
|
|
|
public static function generate_nice_next_course_code($wanted_code) |
4307
|
|
|
{ |
4308
|
|
|
$course_code_ok = !self::course_code_exists($wanted_code); |
4309
|
|
|
if (!$course_code_ok) { |
4310
|
|
|
$wanted_code = self::generate_course_code($wanted_code); |
4311
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
4312
|
|
|
$wanted_code = Database::escape_string($wanted_code); |
4313
|
|
|
$sql = "SELECT count(id) as count |
4314
|
|
|
FROM $table |
4315
|
|
|
WHERE code LIKE '$wanted_code%'"; |
4316
|
|
|
$result = Database::query($sql); |
4317
|
|
|
if (Database::num_rows($result) > 0) { |
4318
|
|
|
$row = Database::fetch_array($result); |
4319
|
|
|
$count = $row['count'] + 1; |
4320
|
|
|
$wanted_code = $wanted_code.'_'.$count; |
4321
|
|
|
$result = api_get_course_info($wanted_code); |
4322
|
|
|
if (empty($result)) { |
4323
|
|
|
return $wanted_code; |
4324
|
|
|
} |
4325
|
|
|
} |
4326
|
|
|
|
4327
|
|
|
return false; |
4328
|
|
|
} |
4329
|
|
|
|
4330
|
|
|
return $wanted_code; |
4331
|
|
|
} |
4332
|
|
|
|
4333
|
|
|
/** |
4334
|
|
|
* Gets the status of the users agreement in a course course-session. |
4335
|
|
|
* |
4336
|
|
|
* @param int $user_id |
4337
|
|
|
* @param string $course_code |
4338
|
|
|
* @param int $session_id |
4339
|
|
|
* |
4340
|
|
|
* @return bool |
4341
|
|
|
*/ |
4342
|
|
|
public static function is_user_accepted_legal($user_id, $course_code, $session_id = 0) |
4343
|
|
|
{ |
4344
|
|
|
$user_id = (int) $user_id; |
4345
|
|
|
$session_id = (int) $session_id; |
4346
|
|
|
$course_code = Database::escape_string($course_code); |
4347
|
|
|
|
4348
|
|
|
$courseInfo = api_get_course_info($course_code); |
4349
|
|
|
$courseId = $courseInfo['real_id']; |
4350
|
|
|
|
4351
|
|
|
// Course legal |
4352
|
|
|
$enabled = api_get_plugin_setting('courselegal', 'tool_enable'); |
4353
|
|
|
|
4354
|
|
|
if ('true' == $enabled) { |
4355
|
|
|
require_once api_get_path(SYS_PLUGIN_PATH).'courselegal/config.php'; |
4356
|
|
|
$plugin = CourseLegalPlugin::create(); |
4357
|
|
|
|
4358
|
|
|
return $plugin->isUserAcceptedLegal($user_id, $course_code, $session_id); |
4359
|
|
|
} |
4360
|
|
|
|
4361
|
|
|
if (empty($session_id)) { |
4362
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
4363
|
|
|
$sql = "SELECT legal_agreement FROM $table |
4364
|
|
|
WHERE user_id = $user_id AND c_id = $courseId "; |
4365
|
|
|
$result = Database::query($sql); |
4366
|
|
|
if (Database::num_rows($result) > 0) { |
4367
|
|
|
$result = Database::fetch_array($result); |
4368
|
|
|
if (1 == $result['legal_agreement']) { |
4369
|
|
|
return true; |
4370
|
|
|
} |
4371
|
|
|
} |
4372
|
|
|
|
4373
|
|
|
return false; |
4374
|
|
|
} else { |
4375
|
|
|
$table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
4376
|
|
|
$sql = "SELECT legal_agreement FROM $table |
4377
|
|
|
WHERE user_id = $user_id AND c_id = $courseId AND session_id = $session_id"; |
4378
|
|
|
$result = Database::query($sql); |
4379
|
|
|
if (Database::num_rows($result) > 0) { |
4380
|
|
|
$result = Database::fetch_array($result); |
4381
|
|
|
if (1 == $result['legal_agreement']) { |
4382
|
|
|
return true; |
4383
|
|
|
} |
4384
|
|
|
} |
4385
|
|
|
|
4386
|
|
|
return false; |
4387
|
|
|
} |
4388
|
|
|
} |
4389
|
|
|
|
4390
|
|
|
/** |
4391
|
|
|
* Saves the user-course legal agreement. |
4392
|
|
|
* |
4393
|
|
|
* @param int user id |
4394
|
|
|
* @param string course code |
4395
|
|
|
* @param int session id |
4396
|
|
|
* |
4397
|
|
|
* @return bool |
4398
|
|
|
*/ |
4399
|
|
|
public static function save_user_legal($user_id, $courseInfo, $session_id = 0) |
4400
|
|
|
{ |
4401
|
|
|
if (empty($courseInfo)) { |
4402
|
|
|
return false; |
4403
|
|
|
} |
4404
|
|
|
$course_code = $courseInfo['code']; |
4405
|
|
|
|
4406
|
|
|
// Course plugin legal |
4407
|
|
|
$enabled = api_get_plugin_setting('courselegal', 'tool_enable'); |
4408
|
|
|
if ('true' == $enabled) { |
4409
|
|
|
require_once api_get_path(SYS_PLUGIN_PATH).'courselegal/config.php'; |
4410
|
|
|
$plugin = CourseLegalPlugin::create(); |
4411
|
|
|
|
4412
|
|
|
return $plugin->saveUserLegal($user_id, $course_code, $session_id); |
4413
|
|
|
} |
4414
|
|
|
|
4415
|
|
|
$user_id = (int) $user_id; |
4416
|
|
|
$session_id = (int) $session_id; |
4417
|
|
|
$courseId = $courseInfo['real_id']; |
4418
|
|
|
|
4419
|
|
|
if (empty($session_id)) { |
4420
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
4421
|
|
|
$sql = "UPDATE $table SET legal_agreement = '1' |
4422
|
|
|
WHERE user_id = $user_id AND c_id = $courseId "; |
4423
|
|
|
Database::query($sql); |
4424
|
|
|
} else { |
4425
|
|
|
$table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER); |
4426
|
|
|
$sql = "UPDATE $table SET legal_agreement = '1' |
4427
|
|
|
WHERE user_id = $user_id AND c_id = $courseId AND session_id = $session_id"; |
4428
|
|
|
Database::query($sql); |
4429
|
|
|
} |
4430
|
|
|
|
4431
|
|
|
return true; |
4432
|
|
|
} |
4433
|
|
|
|
4434
|
|
|
/** |
4435
|
|
|
* @param int $user_id |
4436
|
|
|
* @param int $course_id |
4437
|
|
|
* @param int $session_id |
4438
|
|
|
* @param int $url_id |
4439
|
|
|
* |
4440
|
|
|
* @return bool |
4441
|
|
|
*/ |
4442
|
|
|
public static function get_user_course_vote($user_id, $course_id, $session_id = 0, $url_id = 0) |
4443
|
|
|
{ |
4444
|
|
|
$table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE); |
4445
|
|
|
$session_id = !isset($session_id) ? api_get_session_id() : intval($session_id); |
4446
|
|
|
$url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id); |
4447
|
|
|
$user_id = intval($user_id); |
4448
|
|
|
|
4449
|
|
|
if (empty($user_id)) { |
4450
|
|
|
return false; |
4451
|
|
|
} |
4452
|
|
|
|
4453
|
|
|
$params = [ |
4454
|
|
|
'user_id' => $user_id, |
4455
|
|
|
'c_id' => $course_id, |
4456
|
|
|
'session_id' => $session_id, |
4457
|
|
|
'url_id' => $url_id, |
4458
|
|
|
]; |
4459
|
|
|
|
4460
|
|
|
$result = Database::select( |
4461
|
|
|
'vote', |
4462
|
|
|
$table_user_course_vote, |
4463
|
|
|
[ |
4464
|
|
|
'where' => [ |
4465
|
|
|
'user_id = ? AND c_id = ? AND session_id = ? AND url_id = ?' => $params, |
4466
|
|
|
], |
4467
|
|
|
], |
4468
|
|
|
'first' |
4469
|
|
|
); |
4470
|
|
|
if (!empty($result)) { |
4471
|
|
|
return $result['vote']; |
4472
|
|
|
} |
4473
|
|
|
|
4474
|
|
|
return false; |
4475
|
|
|
} |
4476
|
|
|
|
4477
|
|
|
/** |
4478
|
|
|
* @param int $course_id |
4479
|
|
|
* @param int $session_id |
4480
|
|
|
* @param int $url_id |
4481
|
|
|
* |
4482
|
|
|
* @return array |
4483
|
|
|
*/ |
4484
|
|
|
public static function get_course_ranking( |
4485
|
|
|
$course_id, |
4486
|
|
|
$session_id = 0, |
4487
|
|
|
$url_id = 0 |
4488
|
|
|
) { |
4489
|
|
|
$table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING); |
4490
|
|
|
|
4491
|
|
|
$session_id = empty($session_id) ? api_get_session_id() : intval($session_id); |
4492
|
|
|
$url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id); |
4493
|
|
|
$now = api_get_utc_datetime(); |
4494
|
|
|
|
4495
|
|
|
$params = [ |
4496
|
|
|
'c_id' => $course_id, |
4497
|
|
|
'session_id' => $session_id, |
4498
|
|
|
'url_id' => $url_id, |
4499
|
|
|
'creation_date' => $now, |
4500
|
|
|
]; |
4501
|
|
|
|
4502
|
|
|
$result = Database::select( |
4503
|
|
|
'c_id, accesses, total_score, users', |
4504
|
|
|
$table_course_ranking, |
4505
|
|
|
['where' => ['c_id = ? AND session_id = ? AND url_id = ?' => $params]], |
4506
|
|
|
'first' |
4507
|
|
|
); |
4508
|
|
|
|
4509
|
|
|
$point_average_in_percentage = 0; |
4510
|
|
|
$point_average_in_star = 0; |
4511
|
|
|
$users_who_voted = 0; |
4512
|
|
|
|
4513
|
|
|
if (!empty($result['users'])) { |
4514
|
|
|
$users_who_voted = $result['users']; |
4515
|
|
|
$point_average_in_percentage = round($result['total_score'] / $result['users'] * 100 / 5, 2); |
4516
|
|
|
$point_average_in_star = round($result['total_score'] / $result['users'], 1); |
4517
|
|
|
} |
4518
|
|
|
|
4519
|
|
|
$result['user_vote'] = false; |
4520
|
|
|
if (!api_is_anonymous()) { |
4521
|
|
|
$result['user_vote'] = self::get_user_course_vote(api_get_user_id(), $course_id, $session_id, $url_id); |
4522
|
|
|
} |
4523
|
|
|
|
4524
|
|
|
$result['point_average'] = $point_average_in_percentage; |
4525
|
|
|
$result['point_average_star'] = $point_average_in_star; |
4526
|
|
|
$result['users_who_voted'] = $users_who_voted; |
4527
|
|
|
|
4528
|
|
|
return $result; |
4529
|
|
|
} |
4530
|
|
|
|
4531
|
|
|
/** |
4532
|
|
|
* Updates the course ranking. |
4533
|
|
|
* |
4534
|
|
|
* @param int course id |
4535
|
|
|
* @param int $session_id |
4536
|
|
|
* @param int url id |
4537
|
|
|
* @param $points_to_add |
4538
|
|
|
* @param bool $add_access |
4539
|
|
|
* @param bool $add_user |
4540
|
|
|
* |
4541
|
|
|
* @return array |
4542
|
|
|
*/ |
4543
|
|
|
public static function update_course_ranking( |
4544
|
|
|
$course_id = 0, |
4545
|
|
|
$session_id = 0, |
4546
|
|
|
$url_id = 0, |
4547
|
|
|
$points_to_add = null, |
4548
|
|
|
$add_access = true, |
4549
|
|
|
$add_user = true |
4550
|
|
|
) { |
4551
|
|
|
// Course catalog stats modifications see #4191 |
4552
|
|
|
$table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING); |
4553
|
|
|
$now = api_get_utc_datetime(); |
4554
|
|
|
$course_id = empty($course_id) ? api_get_course_int_id() : intval($course_id); |
4555
|
|
|
$session_id = empty($session_id) ? api_get_session_id() : intval($session_id); |
4556
|
|
|
$url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id); |
4557
|
|
|
|
4558
|
|
|
$params = [ |
4559
|
|
|
'c_id' => $course_id, |
4560
|
|
|
'session_id' => $session_id, |
4561
|
|
|
'url_id' => $url_id, |
4562
|
|
|
'creation_date' => $now, |
4563
|
|
|
'total_score' => 0, |
4564
|
|
|
'users' => 0, |
4565
|
|
|
]; |
4566
|
|
|
|
4567
|
|
|
$result = Database::select( |
4568
|
|
|
'id, accesses, total_score, users', |
4569
|
|
|
$table_course_ranking, |
4570
|
|
|
['where' => ['c_id = ? AND session_id = ? AND url_id = ?' => $params]], |
4571
|
|
|
'first' |
4572
|
|
|
); |
4573
|
|
|
|
4574
|
|
|
// Problem here every time we load the courses/XXXX/index.php course home page we update the access |
4575
|
|
|
if (empty($result)) { |
4576
|
|
|
if ($add_access) { |
4577
|
|
|
$params['accesses'] = 1; |
4578
|
|
|
} |
4579
|
|
|
//The votes and users are empty |
4580
|
|
|
if (isset($points_to_add) && !empty($points_to_add)) { |
4581
|
|
|
$params['total_score'] = intval($points_to_add); |
4582
|
|
|
} |
4583
|
|
|
if ($add_user) { |
4584
|
|
|
$params['users'] = 1; |
4585
|
|
|
} |
4586
|
|
|
$result = Database::insert($table_course_ranking, $params); |
4587
|
|
|
} else { |
4588
|
|
|
$my_params = []; |
4589
|
|
|
|
4590
|
|
|
if ($add_access) { |
4591
|
|
|
$my_params['accesses'] = intval($result['accesses']) + 1; |
4592
|
|
|
} |
4593
|
|
|
if (isset($points_to_add) && !empty($points_to_add)) { |
4594
|
|
|
$my_params['total_score'] = $result['total_score'] + $points_to_add; |
4595
|
|
|
} |
4596
|
|
|
if ($add_user) { |
4597
|
|
|
$my_params['users'] = $result['users'] + 1; |
4598
|
|
|
} |
4599
|
|
|
|
4600
|
|
|
if (!empty($my_params)) { |
4601
|
|
|
$result = Database::update( |
4602
|
|
|
$table_course_ranking, |
4603
|
|
|
$my_params, |
4604
|
|
|
['c_id = ? AND session_id = ? AND url_id = ?' => $params] |
4605
|
|
|
); |
4606
|
|
|
} |
4607
|
|
|
} |
4608
|
|
|
|
4609
|
|
|
return $result; |
4610
|
|
|
} |
4611
|
|
|
|
4612
|
|
|
/** |
4613
|
|
|
* Add user vote to a course. |
4614
|
|
|
* |
4615
|
|
|
* @param int user id |
4616
|
|
|
* @param int vote [1..5] |
4617
|
|
|
* @param int course id |
4618
|
|
|
* @param int session id |
4619
|
|
|
* @param int url id (access_url_id) |
4620
|
|
|
* |
4621
|
|
|
* @return false|string 'added', 'updated' or 'nothing' |
4622
|
|
|
*/ |
4623
|
|
|
public static function add_course_vote( |
4624
|
|
|
$user_id, |
4625
|
|
|
$vote, |
4626
|
|
|
$course_id, |
4627
|
|
|
$session_id = 0, |
4628
|
|
|
$url_id = 0 |
4629
|
|
|
) { |
4630
|
|
|
$table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE); |
4631
|
|
|
$course_id = empty($course_id) ? api_get_course_int_id() : intval($course_id); |
4632
|
|
|
|
4633
|
|
|
if (empty($course_id) || empty($user_id)) { |
4634
|
|
|
return false; |
4635
|
|
|
} |
4636
|
|
|
|
4637
|
|
|
if (!in_array($vote, [1, 2, 3, 4, 5])) { |
4638
|
|
|
return false; |
4639
|
|
|
} |
4640
|
|
|
|
4641
|
|
|
$session_id = empty($session_id) ? api_get_session_id() : intval($session_id); |
4642
|
|
|
$url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id); |
4643
|
|
|
$vote = intval($vote); |
4644
|
|
|
|
4645
|
|
|
$params = [ |
4646
|
|
|
'user_id' => intval($user_id), |
4647
|
|
|
'c_id' => $course_id, |
4648
|
|
|
'session_id' => $session_id, |
4649
|
|
|
'url_id' => $url_id, |
4650
|
|
|
'vote' => $vote, |
4651
|
|
|
]; |
4652
|
|
|
|
4653
|
|
|
$action_done = 'nothing'; |
4654
|
|
|
$result = Database::select( |
4655
|
|
|
'id, vote', |
4656
|
|
|
$table_user_course_vote, |
4657
|
|
|
['where' => ['user_id = ? AND c_id = ? AND session_id = ? AND url_id = ?' => $params]], |
4658
|
|
|
'first' |
4659
|
|
|
); |
4660
|
|
|
|
4661
|
|
|
if (empty($result)) { |
4662
|
|
|
Database::insert($table_user_course_vote, $params); |
4663
|
|
|
$points_to_add = $vote; |
4664
|
|
|
$add_user = true; |
4665
|
|
|
$action_done = 'added'; |
4666
|
|
|
} else { |
4667
|
|
|
$my_params = ['vote' => $vote]; |
4668
|
|
|
$points_to_add = $vote - $result['vote']; |
4669
|
|
|
$add_user = false; |
4670
|
|
|
|
4671
|
|
|
Database::update( |
4672
|
|
|
$table_user_course_vote, |
4673
|
|
|
$my_params, |
4674
|
|
|
['user_id = ? AND c_id = ? AND session_id = ? AND url_id = ?' => $params] |
4675
|
|
|
); |
4676
|
|
|
$action_done = 'updated'; |
4677
|
|
|
} |
4678
|
|
|
|
4679
|
|
|
// Current points |
4680
|
|
|
if (!empty($points_to_add)) { |
4681
|
|
|
self::update_course_ranking( |
4682
|
|
|
$course_id, |
4683
|
|
|
$session_id, |
4684
|
|
|
$url_id, |
4685
|
|
|
$points_to_add, |
4686
|
|
|
false, |
4687
|
|
|
$add_user |
4688
|
|
|
); |
4689
|
|
|
} |
4690
|
|
|
|
4691
|
|
|
return $action_done; |
4692
|
|
|
} |
4693
|
|
|
|
4694
|
|
|
/** |
4695
|
|
|
* Remove course ranking + user votes. |
4696
|
|
|
* |
4697
|
|
|
* @param int $course_id |
4698
|
|
|
* @param int $session_id |
4699
|
|
|
* @param int $url_id |
4700
|
|
|
*/ |
4701
|
|
|
public static function remove_course_ranking($course_id, $session_id, $url_id = null) |
4702
|
|
|
{ |
4703
|
|
|
$table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING); |
4704
|
|
|
$table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE); |
4705
|
|
|
|
4706
|
|
|
if (!empty($course_id) && isset($session_id)) { |
4707
|
|
|
$url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id); |
4708
|
|
|
$params = [ |
4709
|
|
|
'c_id' => $course_id, |
4710
|
|
|
'session_id' => $session_id, |
4711
|
|
|
'url_id' => $url_id, |
4712
|
|
|
]; |
4713
|
|
|
Database::delete($table_course_ranking, ['c_id = ? AND session_id = ? AND url_id = ?' => $params]); |
4714
|
|
|
Database::delete($table_user_course_vote, ['c_id = ? AND session_id = ? AND url_id = ?' => $params]); |
4715
|
|
|
} |
4716
|
|
|
} |
4717
|
|
|
|
4718
|
|
|
/** |
4719
|
|
|
* Returns an array with the hottest courses. |
4720
|
|
|
* |
4721
|
|
|
* @param int $days number of days |
4722
|
|
|
* @param int $limit number of hottest courses |
4723
|
|
|
* |
4724
|
|
|
* @return array |
4725
|
|
|
*/ |
4726
|
|
|
public static function return_hot_courses($days = 30, $limit = 6) |
4727
|
|
|
{ |
4728
|
|
|
if (api_is_invitee()) { |
4729
|
|
|
return []; |
4730
|
|
|
} |
4731
|
|
|
|
4732
|
|
|
$limit = (int) $limit; |
4733
|
|
|
$userId = api_get_user_id(); |
4734
|
|
|
|
4735
|
|
|
// Getting my courses |
4736
|
|
|
$my_course_list = self::get_courses_list_by_user_id($userId); |
4737
|
|
|
|
4738
|
|
|
$codeList = []; |
4739
|
|
|
foreach ($my_course_list as $course) { |
4740
|
|
|
$codeList[$course['real_id']] = $course['real_id']; |
4741
|
|
|
} |
4742
|
|
|
|
4743
|
|
|
if (api_is_drh()) { |
4744
|
|
|
$courses = self::get_courses_followed_by_drh($userId); |
4745
|
|
|
foreach ($courses as $course) { |
4746
|
|
|
$codeList[$course['real_id']] = $course['real_id']; |
4747
|
|
|
} |
4748
|
|
|
} |
4749
|
|
|
|
4750
|
|
|
$table_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
4751
|
|
|
$table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
4752
|
|
|
$table_course_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
4753
|
|
|
$urlId = api_get_current_access_url_id(); |
4754
|
|
|
//$table_course_access table uses the now() and interval ... |
4755
|
|
|
$now = api_get_utc_datetime(); |
4756
|
|
|
$sql = "SELECT COUNT(course_access_id) course_count, a.c_id, visibility |
4757
|
|
|
FROM $table_course c |
4758
|
|
|
INNER JOIN $table_course_access a |
4759
|
|
|
ON (c.id = a.c_id) |
4760
|
|
|
INNER JOIN $table_course_url u |
4761
|
|
|
ON u.c_id = c.id |
4762
|
|
|
WHERE |
4763
|
|
|
u.access_url_id = $urlId AND |
4764
|
|
|
login_course_date <= '$now' AND |
4765
|
|
|
login_course_date > DATE_SUB('$now', INTERVAL $days DAY) AND |
4766
|
|
|
visibility <> ".Course::CLOSED." AND |
4767
|
|
|
visibility <> ".Course::HIDDEN." |
4768
|
|
|
GROUP BY a.c_id |
4769
|
|
|
ORDER BY course_count DESC |
4770
|
|
|
LIMIT $limit |
4771
|
|
|
"; |
4772
|
|
|
|
4773
|
|
|
$result = Database::query($sql); |
4774
|
|
|
$courses = []; |
4775
|
|
|
if (Database::num_rows($result)) { |
4776
|
|
|
$courses = Database::store_result($result, 'ASSOC'); |
4777
|
|
|
$courses = self::processHotCourseItem($courses, $codeList); |
4778
|
|
|
} |
4779
|
|
|
|
4780
|
|
|
return $courses; |
4781
|
|
|
} |
4782
|
|
|
|
4783
|
|
|
/** |
4784
|
|
|
* Returns an array with the "hand picked" popular courses. |
4785
|
|
|
* Courses only appear in this list if their extra field 'popular_courses' |
4786
|
|
|
* has been selected in the admin page of the course. |
4787
|
|
|
* |
4788
|
|
|
* @return array |
4789
|
|
|
*/ |
4790
|
|
|
public static function returnPopularCoursesHandPicked() |
4791
|
|
|
{ |
4792
|
|
|
if (api_is_invitee()) { |
4793
|
|
|
return []; |
4794
|
|
|
} |
4795
|
|
|
|
4796
|
|
|
$userId = api_get_user_id(); |
4797
|
|
|
|
4798
|
|
|
// Getting my courses |
4799
|
|
|
$my_course_list = self::get_courses_list_by_user_id($userId); |
4800
|
|
|
|
4801
|
|
|
$codeList = []; |
4802
|
|
|
foreach ($my_course_list as $course) { |
4803
|
|
|
$codeList[$course['real_id']] = $course['real_id']; |
4804
|
|
|
} |
4805
|
|
|
|
4806
|
|
|
if (api_is_drh()) { |
4807
|
|
|
$courses = self::get_courses_followed_by_drh($userId); |
4808
|
|
|
foreach ($courses as $course) { |
4809
|
|
|
$codeList[$course['real_id']] = $course['real_id']; |
4810
|
|
|
} |
4811
|
|
|
} |
4812
|
|
|
|
4813
|
|
|
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE); |
4814
|
|
|
$tbl_course_field = Database::get_main_table(TABLE_EXTRA_FIELD); |
4815
|
|
|
$tbl_course_field_value = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
4816
|
|
|
|
4817
|
|
|
//we filter the courses from the URL |
4818
|
|
|
$join_access_url = $where_access_url = ''; |
4819
|
|
|
if (api_get_multiple_access_url()) { |
4820
|
|
|
$access_url_id = api_get_current_access_url_id(); |
4821
|
|
|
if (-1 != $access_url_id) { |
4822
|
|
|
$tbl_url_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
4823
|
|
|
$join_access_url = "LEFT JOIN $tbl_url_course url_rel_course |
4824
|
|
|
ON url_rel_course.c_id = tcfv.item_id "; |
4825
|
|
|
$where_access_url = " AND access_url_id = $access_url_id "; |
4826
|
|
|
} |
4827
|
|
|
} |
4828
|
|
|
|
4829
|
|
|
$extraFieldType = EntityExtraField::COURSE_FIELD_TYPE; |
4830
|
|
|
|
4831
|
|
|
// get course list auto-register |
4832
|
|
|
$sql = "SELECT DISTINCT(c.id) AS c_id |
4833
|
|
|
FROM $tbl_course_field_value tcfv |
4834
|
|
|
INNER JOIN $tbl_course_field tcf |
4835
|
|
|
ON tcfv.field_id = tcf.id $join_access_url |
4836
|
|
|
INNER JOIN $courseTable c |
4837
|
|
|
ON (c.id = tcfv.item_id) |
4838
|
|
|
WHERE |
4839
|
|
|
tcf.extra_field_type = $extraFieldType AND |
4840
|
|
|
tcf.variable = 'popular_courses' AND |
4841
|
|
|
tcfv.value = 1 AND |
4842
|
|
|
visibility <> ".Course::CLOSED." AND |
4843
|
|
|
visibility <> ".Course::HIDDEN." $where_access_url"; |
4844
|
|
|
|
4845
|
|
|
$result = Database::query($sql); |
4846
|
|
|
$courses = []; |
4847
|
|
|
if (Database::num_rows($result)) { |
4848
|
|
|
$courses = Database::store_result($result, 'ASSOC'); |
4849
|
|
|
$courses = self::processHotCourseItem($courses, $codeList); |
4850
|
|
|
} |
4851
|
|
|
|
4852
|
|
|
return $courses; |
4853
|
|
|
} |
4854
|
|
|
|
4855
|
|
|
/** |
4856
|
|
|
* @param array $courses |
4857
|
|
|
* @param array $codeList |
4858
|
|
|
* |
4859
|
|
|
* @return mixed |
4860
|
|
|
*/ |
4861
|
|
|
public static function processHotCourseItem($courses, $codeList = []) |
4862
|
|
|
{ |
4863
|
|
|
$hotCourses = []; |
4864
|
|
|
$ajax_url = api_get_path(WEB_AJAX_PATH).'course.ajax.php?a=add_course_vote'; |
4865
|
|
|
$stok = Security::get_existing_token(); |
4866
|
|
|
$user_id = api_get_user_id(); |
4867
|
|
|
|
4868
|
|
|
foreach ($courses as $courseId) { |
4869
|
|
|
$course_info = api_get_course_info_by_id($courseId['c_id']); |
4870
|
|
|
$courseCode = $course_info['code']; |
4871
|
|
|
$categoryCode = !empty($course_info['categoryCode']) ? $course_info['categoryCode'] : ""; |
4872
|
|
|
$my_course = $course_info; |
4873
|
|
|
$my_course['go_to_course_button'] = ''; |
4874
|
|
|
$my_course['register_button'] = ''; |
4875
|
|
|
|
4876
|
|
|
$access_link = self::get_access_link_by_user( |
4877
|
|
|
$user_id, |
4878
|
|
|
$course_info, |
4879
|
|
|
$codeList |
4880
|
|
|
); |
4881
|
|
|
|
4882
|
|
|
$userRegisteredInCourse = self::is_user_subscribed_in_course($user_id, $course_info['code']); |
4883
|
|
|
$userRegisteredInCourseAsTeacher = self::isCourseTeacher($user_id, $courseId['c_id']); |
4884
|
|
|
$userRegistered = $userRegisteredInCourse && $userRegisteredInCourseAsTeacher; |
4885
|
|
|
$my_course['is_course_student'] = $userRegisteredInCourse; |
4886
|
|
|
$my_course['is_course_teacher'] = $userRegisteredInCourseAsTeacher; |
4887
|
|
|
$my_course['is_registered'] = $userRegistered; |
4888
|
|
|
$my_course['title_cut'] = cut($course_info['title'], 45); |
4889
|
|
|
|
4890
|
|
|
// Course visibility |
4891
|
|
|
if ($access_link && in_array('register', $access_link)) { |
4892
|
|
|
$my_course['register_button'] = Display::url( |
4893
|
|
|
get_lang('Subscribe').' '. |
4894
|
|
|
Display::returnFontAwesomeIcon('sign-in'), |
4895
|
|
|
api_get_path(WEB_COURSE_PATH).$course_info['path']. |
4896
|
|
|
'/index.php?action=subscribe&sec_token='.$stok, |
4897
|
|
|
[ |
4898
|
|
|
'class' => 'btn btn-success btn-sm', |
4899
|
|
|
'title' => get_lang('Subscribe'), |
4900
|
|
|
'aria-label' => get_lang('Subscribe'), |
4901
|
|
|
] |
4902
|
|
|
); |
4903
|
|
|
} |
4904
|
|
|
|
4905
|
|
|
if ($access_link && in_array('enter', $access_link) || |
4906
|
|
|
Course::OPEN_WORLD == $course_info['visibility'] |
4907
|
|
|
) { |
4908
|
|
|
$my_course['go_to_course_button'] = Display::url( |
4909
|
|
|
get_lang('Go to the course').' '. |
4910
|
|
|
Display::returnFontAwesomeIcon('share'), |
4911
|
|
|
api_get_path(WEB_COURSE_PATH).$course_info['path'].'/index.php', |
4912
|
|
|
[ |
4913
|
|
|
'class' => 'btn btn-default btn-sm', |
4914
|
|
|
'title' => get_lang('Go to the course'), |
4915
|
|
|
'aria-label' => get_lang('Go to the course'), |
4916
|
|
|
] |
4917
|
|
|
); |
4918
|
|
|
} |
4919
|
|
|
|
4920
|
|
|
if ($access_link && in_array('unsubscribe', $access_link)) { |
4921
|
|
|
$my_course['unsubscribe_button'] = Display::url( |
4922
|
|
|
get_lang('Unsubscribe').' '. |
4923
|
|
|
Display::returnFontAwesomeIcon('sign-out'), |
4924
|
|
|
api_get_path(WEB_CODE_PATH).'auth/courses.php?action=unsubscribe&unsubscribe='.$courseCode |
4925
|
|
|
.'&sec_token='.$stok.'&category_code='.$categoryCode, |
4926
|
|
|
[ |
4927
|
|
|
'class' => 'btn btn-danger btn-sm', |
4928
|
|
|
'title' => get_lang('Unsubscribe'), |
4929
|
|
|
'aria-label' => get_lang('Unsubscribe'), |
4930
|
|
|
] |
4931
|
|
|
); |
4932
|
|
|
} |
4933
|
|
|
|
4934
|
|
|
// start buycourse validation |
4935
|
|
|
// display the course price and buy button if the buycourses plugin is enabled and this course is configured |
4936
|
|
|
$plugin = BuyCoursesPlugin::create(); |
4937
|
|
|
$isThisCourseInSale = $plugin->buyCoursesForGridCatalogValidator( |
4938
|
|
|
$course_info['real_id'], |
4939
|
|
|
BuyCoursesPlugin::PRODUCT_TYPE_COURSE |
4940
|
|
|
); |
4941
|
|
|
if ($isThisCourseInSale) { |
4942
|
|
|
// set the price label |
4943
|
|
|
$my_course['price'] = $isThisCourseInSale['html']; |
4944
|
|
|
// set the Buy button instead register. |
4945
|
|
|
if ($isThisCourseInSale['verificator'] && !empty($my_course['register_button'])) { |
4946
|
|
|
$my_course['register_button'] = $plugin->returnBuyCourseButton( |
4947
|
|
|
$course_info['real_id'], |
4948
|
|
|
BuyCoursesPlugin::PRODUCT_TYPE_COURSE |
4949
|
|
|
); |
4950
|
|
|
} |
4951
|
|
|
} |
4952
|
|
|
// end buycourse validation |
4953
|
|
|
|
4954
|
|
|
// Description |
4955
|
|
|
$my_course['description_button'] = self::returnDescriptionButton($course_info); |
4956
|
|
|
$my_course['teachers'] = self::getTeachersFromCourse($course_info['real_id'], true); |
4957
|
|
|
$point_info = self::get_course_ranking($course_info['real_id'], 0); |
4958
|
|
|
$my_course['rating_html'] = ''; |
4959
|
|
|
if (false === api_get_configuration_value('hide_course_rating')) { |
4960
|
|
|
$my_course['rating_html'] = Display::return_rating_system( |
4961
|
|
|
'star_'.$course_info['real_id'], |
4962
|
|
|
$ajax_url.'&course_id='.$course_info['real_id'], |
4963
|
|
|
$point_info |
4964
|
|
|
); |
4965
|
|
|
} |
4966
|
|
|
$hotCourses[] = $my_course; |
4967
|
|
|
} |
4968
|
|
|
|
4969
|
|
|
return $hotCourses; |
4970
|
|
|
} |
4971
|
|
|
|
4972
|
|
|
public function totalSubscribedUsersInCourses($urlId) |
4973
|
|
|
{ |
4974
|
|
|
$table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
4975
|
|
|
$table_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
4976
|
|
|
$courseUsers = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
4977
|
|
|
|
4978
|
|
|
$urlId = (int) $urlId; |
4979
|
|
|
|
4980
|
|
|
$sql = "SELECT count(cu.user_id) count |
4981
|
|
|
FROM $courseUsers cu |
4982
|
|
|
INNER JOIN $table_course_rel_access_url u |
4983
|
|
|
ON cu.c_id = u.c_id |
4984
|
|
|
WHERE |
4985
|
|
|
relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND |
4986
|
|
|
u.access_url_id = $urlId AND |
4987
|
|
|
visibility <> ".Course::CLOSED." AND |
4988
|
|
|
visibility <> ".Course::HIDDEN." |
4989
|
|
|
"; |
4990
|
|
|
|
4991
|
|
|
$res = Database::query($sql); |
4992
|
|
|
$row = Database::fetch_array($res); |
4993
|
|
|
|
4994
|
|
|
return $row['count']; |
4995
|
|
|
} |
4996
|
|
|
|
4997
|
|
|
/** |
4998
|
|
|
* Get courses count. |
4999
|
|
|
* |
5000
|
|
|
* @param int $access_url_id Access URL ID (optional) |
5001
|
|
|
* @param int $visibility |
5002
|
|
|
* |
5003
|
|
|
* @return int Number of courses |
5004
|
|
|
*/ |
5005
|
|
|
public static function count_courses($access_url_id = null, $visibility = null) |
5006
|
|
|
{ |
5007
|
|
|
$table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
5008
|
|
|
$table_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
5009
|
|
|
$sql = "SELECT count(c.id) FROM $table_course c"; |
5010
|
|
|
if (!empty($access_url_id) && $access_url_id == intval($access_url_id)) { |
5011
|
|
|
$sql .= ", $table_course_rel_access_url u |
5012
|
|
|
WHERE c.id = u.c_id AND u.access_url_id = $access_url_id"; |
5013
|
|
|
if (!empty($visibility)) { |
5014
|
|
|
$visibility = intval($visibility); |
5015
|
|
|
$sql .= " AND visibility = $visibility "; |
5016
|
|
|
} |
5017
|
|
|
} else { |
5018
|
|
|
if (!empty($visibility)) { |
5019
|
|
|
$visibility = intval($visibility); |
5020
|
|
|
$sql .= " WHERE visibility = $visibility "; |
5021
|
|
|
} |
5022
|
|
|
} |
5023
|
|
|
|
5024
|
|
|
$res = Database::query($sql); |
5025
|
|
|
$row = Database::fetch_row($res); |
5026
|
|
|
|
5027
|
|
|
return $row[0]; |
5028
|
|
|
} |
5029
|
|
|
|
5030
|
|
|
/** |
5031
|
|
|
* Get active courses count. |
5032
|
|
|
* Active = all courses except the ones with hidden visibility. |
5033
|
|
|
* |
5034
|
|
|
* @param int $urlId Access URL ID (optional) |
5035
|
|
|
* |
5036
|
|
|
* @return int Number of courses |
5037
|
|
|
*/ |
5038
|
|
|
public static function countActiveCourses($urlId = null) |
5039
|
|
|
{ |
5040
|
|
|
$table_course = Database::get_main_table(TABLE_MAIN_COURSE); |
5041
|
|
|
$table_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
5042
|
|
|
$sql = "SELECT count(c.id) FROM $table_course c"; |
5043
|
|
|
if (!empty($urlId)) { |
5044
|
|
|
$urlId = (int) $urlId; |
5045
|
|
|
$sql .= ", $table_course_rel_access_url u |
5046
|
|
|
WHERE |
5047
|
|
|
c.id = u.c_id AND |
5048
|
|
|
u.access_url_id = $urlId AND |
5049
|
|
|
visibility <> ".Course::HIDDEN; |
5050
|
|
|
} else { |
5051
|
|
|
$sql .= " WHERE visibility <> ".Course::HIDDEN; |
5052
|
|
|
} |
5053
|
|
|
$res = Database::query($sql); |
5054
|
|
|
$row = Database::fetch_row($res); |
5055
|
|
|
|
5056
|
|
|
return $row[0]; |
5057
|
|
|
} |
5058
|
|
|
|
5059
|
|
|
/** |
5060
|
|
|
* Returns the SQL conditions to filter course only visible by the user in the catalogue. |
5061
|
|
|
* |
5062
|
|
|
* @param string $courseTableAlias Alias of the course table |
5063
|
|
|
* @param bool $hideClosed Whether to hide closed and hidden courses |
5064
|
|
|
* @param bool $checkHidePrivate |
5065
|
|
|
* |
5066
|
|
|
* @return string SQL conditions |
5067
|
|
|
*/ |
5068
|
|
|
public static function getCourseVisibilitySQLCondition($courseTableAlias, $hideClosed = false, $checkHidePrivate = true) |
5069
|
|
|
{ |
5070
|
|
|
$visibilityCondition = ''; |
5071
|
|
|
if ($checkHidePrivate) { |
5072
|
|
|
$hidePrivateSetting = api_get_setting('course_catalog_hide_private'); |
5073
|
|
|
if ('true' === $hidePrivateSetting) { |
5074
|
|
|
$visibilityCondition .= " AND $courseTableAlias.visibility <> ".Course::REGISTERED; |
5075
|
|
|
} |
5076
|
|
|
} |
5077
|
|
|
if ($hideClosed) { |
5078
|
|
|
$visibilityCondition .= " AND $courseTableAlias.visibility NOT IN (".Course::CLOSED.','.Course::HIDDEN.')'; |
5079
|
|
|
} |
5080
|
|
|
|
5081
|
|
|
// Check if course have users allowed to see it in the catalogue, then show only if current user is allowed to see it |
5082
|
|
|
$currentUserId = api_get_user_id(); |
5083
|
|
|
$restrictedCourses = self::getCatalogCourseList(true); |
5084
|
|
|
$allowedCoursesToCurrentUser = self::getCatalogCourseList(true, $currentUserId); |
5085
|
|
|
if (!empty($restrictedCourses)) { |
5086
|
|
|
$visibilityCondition .= ' AND ('.$courseTableAlias.'.code NOT IN ("'.implode('","', $restrictedCourses).'")'; |
5087
|
|
|
$visibilityCondition .= ' OR '.$courseTableAlias.'.code IN ("'.implode('","', $allowedCoursesToCurrentUser).'"))'; |
5088
|
|
|
} |
5089
|
|
|
|
5090
|
|
|
// Check if course have users denied to see it in the catalogue, then show only if current user is not denied to see it |
5091
|
|
|
$restrictedCourses = self::getCatalogCourseList(false); |
5092
|
|
|
$notAllowedCoursesToCurrentUser = self::getCatalogCourseList(false, $currentUserId); |
5093
|
|
|
if (!empty($restrictedCourses)) { |
5094
|
|
|
$visibilityCondition .= ' AND ('.$courseTableAlias.'.code NOT IN ("'.implode('","', $restrictedCourses).'")'; |
5095
|
|
|
$visibilityCondition .= ' OR '.$courseTableAlias.'.code NOT IN ("'.implode('","', $notAllowedCoursesToCurrentUser).'"))'; |
5096
|
|
|
} |
5097
|
|
|
|
5098
|
|
|
return $visibilityCondition; |
5099
|
|
|
} |
5100
|
|
|
|
5101
|
|
|
/** |
5102
|
|
|
* Return a link to go to the course, validating the visibility of the |
5103
|
|
|
* course and the user status. |
5104
|
|
|
* |
5105
|
|
|
* @param int $uid User ID |
5106
|
|
|
* @param array Course details array |
5107
|
|
|
* @param array List of courses to which the user is subscribed (if not provided, will be generated) |
5108
|
|
|
* |
5109
|
|
|
* @return mixed 'enter' for a link to go to the course or 'register' for a link to subscribe, or false if no access |
5110
|
|
|
*/ |
5111
|
|
|
public static function get_access_link_by_user($uid, $course, $user_courses = []) |
5112
|
|
|
{ |
5113
|
|
|
if (empty($uid) || empty($course)) { |
5114
|
|
|
return false; |
5115
|
|
|
} |
5116
|
|
|
|
5117
|
|
|
if (empty($user_courses)) { |
5118
|
|
|
// get the array of courses to which the user is subscribed |
5119
|
|
|
$user_courses = self::get_courses_list_by_user_id($uid); |
5120
|
|
|
foreach ($user_courses as $k => $v) { |
5121
|
|
|
$user_courses[$k] = $v['real_id']; |
5122
|
|
|
} |
5123
|
|
|
} |
5124
|
|
|
|
5125
|
|
|
if (!isset($course['real_id']) && empty($course['real_id'])) { |
5126
|
|
|
$course = api_get_course_info($course['code']); |
5127
|
|
|
} |
5128
|
|
|
|
5129
|
|
|
if (Course::HIDDEN == $course['visibility']) { |
5130
|
|
|
return []; |
5131
|
|
|
} |
5132
|
|
|
|
5133
|
|
|
$is_admin = api_is_platform_admin_by_id($uid); |
5134
|
|
|
$options = []; |
5135
|
|
|
// Register button |
5136
|
|
|
if (!api_is_anonymous($uid) && |
5137
|
|
|
( |
5138
|
|
|
(Course::OPEN_WORLD == $course['visibility'] || Course::OPEN_PLATFORM == $course['visibility']) |
5139
|
|
|
//$course['visibility'] == Course::REGISTERED && $course['subscribe'] == SUBSCRIBE_ALLOWED |
5140
|
|
|
) && |
5141
|
|
|
SUBSCRIBE_ALLOWED == $course['subscribe'] && |
5142
|
|
|
(!in_array($course['real_id'], $user_courses) || empty($user_courses)) |
5143
|
|
|
) { |
5144
|
|
|
$options[] = 'register'; |
5145
|
|
|
} |
5146
|
|
|
|
5147
|
|
|
$isLogin = !api_is_anonymous(); |
5148
|
|
|
|
5149
|
|
|
// Go To Course button (only if admin, if course public or if student already subscribed) |
5150
|
|
|
if ($is_admin || |
5151
|
|
|
Course::OPEN_WORLD == $course['visibility'] && empty($course['registration_code']) || |
5152
|
|
|
($isLogin && Course::OPEN_PLATFORM == $course['visibility'] && empty($course['registration_code'])) || |
5153
|
|
|
(in_array($course['real_id'], $user_courses) && Course::CLOSED != $course['visibility']) |
5154
|
|
|
) { |
5155
|
|
|
$options[] = 'enter'; |
5156
|
|
|
} |
5157
|
|
|
|
5158
|
|
|
if ($is_admin || |
5159
|
|
|
Course::OPEN_WORLD == $course['visibility'] && empty($course['registration_code']) || |
5160
|
|
|
($isLogin && Course::OPEN_PLATFORM == $course['visibility'] && empty($course['registration_code'])) || |
5161
|
|
|
(in_array($course['real_id'], $user_courses) && Course::CLOSED != $course['visibility']) |
5162
|
|
|
) { |
5163
|
|
|
$options[] = 'enter'; |
5164
|
|
|
} |
5165
|
|
|
|
5166
|
|
|
if (Course::HIDDEN != $course['visibility'] && |
5167
|
|
|
empty($course['registration_code']) && |
5168
|
|
|
UNSUBSCRIBE_ALLOWED == $course['unsubscribe'] && |
5169
|
|
|
$isLogin && |
5170
|
|
|
in_array($course['real_id'], $user_courses) |
5171
|
|
|
) { |
5172
|
|
|
$options[] = 'unsubscribe'; |
5173
|
|
|
} |
5174
|
|
|
|
5175
|
|
|
return $options; |
5176
|
|
|
} |
5177
|
|
|
|
5178
|
|
|
/** |
5179
|
|
|
* @param array $courseInfo |
5180
|
|
|
* @param array $teachers |
5181
|
|
|
* @param bool $deleteTeachersNotInList |
5182
|
|
|
* @param bool $editTeacherInSessions |
5183
|
|
|
* @param bool $deleteSessionTeacherNotInList |
5184
|
|
|
* @param array $teacherBackup |
5185
|
|
|
* @param Monolog\Logger $logger |
5186
|
|
|
* |
5187
|
|
|
* @return false|null |
5188
|
|
|
*/ |
5189
|
|
|
public static function updateTeachers( |
5190
|
|
|
$courseInfo, |
5191
|
|
|
$teachers, |
5192
|
|
|
$deleteTeachersNotInList = true, |
5193
|
|
|
$editTeacherInSessions = false, |
5194
|
|
|
$deleteSessionTeacherNotInList = false, |
5195
|
|
|
$teacherBackup = [], |
5196
|
|
|
$logger = null |
5197
|
|
|
) { |
5198
|
|
|
if (!is_array($teachers)) { |
5199
|
|
|
$teachers = [$teachers]; |
5200
|
|
|
} |
5201
|
|
|
|
5202
|
|
|
if (empty($courseInfo) || !isset($courseInfo['real_id'])) { |
5203
|
|
|
return false; |
5204
|
|
|
} |
5205
|
|
|
|
5206
|
|
|
$teachers = array_filter($teachers); |
5207
|
|
|
$courseId = $courseInfo['real_id']; |
5208
|
|
|
$course_code = $courseInfo['code']; |
5209
|
|
|
|
5210
|
|
|
$course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
5211
|
|
|
$alreadyAddedTeachers = self::get_teacher_list_from_course_code($course_code); |
5212
|
|
|
|
5213
|
|
|
if ($deleteTeachersNotInList) { |
5214
|
|
|
// Delete only teacher relations that doesn't match the selected teachers |
5215
|
|
|
$cond = null; |
5216
|
|
|
if (count($teachers) > 0) { |
5217
|
|
|
foreach ($teachers as $key) { |
5218
|
|
|
$key = Database::escape_string($key); |
5219
|
|
|
$cond .= " AND user_id <> '".$key."'"; |
5220
|
|
|
} |
5221
|
|
|
} |
5222
|
|
|
|
5223
|
|
|
// Recover user categories |
5224
|
|
|
$sql = "SELECT * FROM $course_user_table |
5225
|
|
|
WHERE c_id = $courseId AND status = 1 AND relation_type = 0 ".$cond; |
5226
|
|
|
$result = Database::query($sql); |
5227
|
|
|
if (Database::num_rows($result)) { |
5228
|
|
|
$teachersToDelete = Database::store_result($result, 'ASSOC'); |
5229
|
|
|
foreach ($teachersToDelete as $data) { |
5230
|
|
|
$userId = $data['user_id']; |
5231
|
|
|
$teacherBackup[$userId][$course_code] = $data; |
5232
|
|
|
} |
5233
|
|
|
} |
5234
|
|
|
|
5235
|
|
|
$sql = "DELETE FROM $course_user_table |
5236
|
|
|
WHERE c_id = $courseId AND status = 1 AND relation_type = 0 ".$cond; |
5237
|
|
|
|
5238
|
|
|
Database::query($sql); |
5239
|
|
|
} |
5240
|
|
|
|
5241
|
|
|
if (count($teachers) > 0) { |
5242
|
|
|
foreach ($teachers as $userId) { |
5243
|
|
|
$userId = intval($userId); |
5244
|
|
|
// We check if the teacher is already subscribed in this course |
5245
|
|
|
$sql = "SELECT 1 FROM $course_user_table |
5246
|
|
|
WHERE user_id = $userId AND c_id = $courseId"; |
5247
|
|
|
$result = Database::query($sql); |
5248
|
|
|
if (Database::num_rows($result)) { |
5249
|
|
|
$sql = "UPDATE $course_user_table |
5250
|
|
|
SET status = 1 |
5251
|
|
|
WHERE c_id = $courseId AND user_id = $userId "; |
5252
|
|
|
} else { |
5253
|
|
|
$userCourseCategory = '0'; |
5254
|
|
|
if (isset($teacherBackup[$userId]) && |
5255
|
|
|
isset($teacherBackup[$userId][$course_code]) |
5256
|
|
|
) { |
5257
|
|
|
$courseUserData = $teacherBackup[$userId][$course_code]; |
5258
|
|
|
$userCourseCategory = $courseUserData['user_course_cat']; |
5259
|
|
|
if ($logger) { |
5260
|
|
|
$logger->debug("Recovering user_course_cat: $userCourseCategory"); |
5261
|
|
|
} |
5262
|
|
|
} |
5263
|
|
|
|
5264
|
|
|
$sql = "INSERT INTO $course_user_table SET |
5265
|
|
|
c_id = $courseId, |
5266
|
|
|
user_id = $userId, |
5267
|
|
|
status = 1, |
5268
|
|
|
is_tutor = 0, |
5269
|
|
|
sort = 0, |
5270
|
|
|
relation_type = 0, |
5271
|
|
|
user_course_cat = $userCourseCategory |
5272
|
|
|
"; |
5273
|
|
|
} |
5274
|
|
|
Database::query($sql); |
5275
|
|
|
} |
5276
|
|
|
} |
5277
|
|
|
|
5278
|
|
|
if ($editTeacherInSessions) { |
5279
|
|
|
$sessions = SessionManager::get_session_by_course($courseId); |
5280
|
|
|
if (!empty($sessions)) { |
5281
|
|
|
if ($logger) { |
5282
|
|
|
$logger->debug("Edit teachers in sessions"); |
5283
|
|
|
} |
5284
|
|
|
foreach ($sessions as $session) { |
5285
|
|
|
$sessionId = $session['id']; |
5286
|
|
|
// Remove old and add new |
5287
|
|
|
if ($deleteSessionTeacherNotInList) { |
5288
|
|
|
foreach ($teachers as $userId) { |
5289
|
|
|
if ($logger) { |
5290
|
|
|
$logger->debug("Set coach #$userId in session #$sessionId of course #$courseId "); |
5291
|
|
|
} |
5292
|
|
|
SessionManager::set_coach_to_course_session( |
5293
|
|
|
$userId, |
5294
|
|
|
$sessionId, |
5295
|
|
|
$courseId |
5296
|
|
|
); |
5297
|
|
|
} |
5298
|
|
|
|
5299
|
|
|
$teachersToDelete = []; |
5300
|
|
|
if (!empty($alreadyAddedTeachers)) { |
5301
|
|
|
$teachersToDelete = array_diff(array_keys($alreadyAddedTeachers), $teachers); |
5302
|
|
|
} |
5303
|
|
|
|
5304
|
|
|
if (!empty($teachersToDelete)) { |
5305
|
|
|
foreach ($teachersToDelete as $userId) { |
5306
|
|
|
if ($logger) { |
5307
|
|
|
$logger->debug("Delete coach #$userId in session #$sessionId of course #$courseId "); |
5308
|
|
|
} |
5309
|
|
|
SessionManager::set_coach_to_course_session( |
5310
|
|
|
$userId, |
5311
|
|
|
$sessionId, |
5312
|
|
|
$courseId, |
5313
|
|
|
true |
5314
|
|
|
); |
5315
|
|
|
} |
5316
|
|
|
} |
5317
|
|
|
} else { |
5318
|
|
|
// Add new teachers only |
5319
|
|
|
foreach ($teachers as $userId) { |
5320
|
|
|
if ($logger) { |
5321
|
|
|
$logger->debug("Add coach #$userId in session #$sessionId of course #$courseId "); |
5322
|
|
|
} |
5323
|
|
|
SessionManager::set_coach_to_course_session( |
5324
|
|
|
$userId, |
5325
|
|
|
$sessionId, |
5326
|
|
|
$courseId |
5327
|
|
|
); |
5328
|
|
|
} |
5329
|
|
|
} |
5330
|
|
|
} |
5331
|
|
|
} |
5332
|
|
|
} |
5333
|
|
|
} |
5334
|
|
|
|
5335
|
|
|
/** |
5336
|
|
|
* Course available settings variables see c_course_setting table. |
5337
|
|
|
* |
5338
|
|
|
* @return array |
5339
|
|
|
*/ |
5340
|
|
|
public static function getCourseSettingVariables(AppPlugin $appPlugin) |
5341
|
|
|
{ |
5342
|
|
|
$pluginCourseSettings = $appPlugin->getAllPluginCourseSettings(); |
5343
|
|
|
$courseSettings = [ |
5344
|
|
|
// Get allow_learning_path_theme from table |
5345
|
|
|
'allow_learning_path_theme', |
5346
|
|
|
// Get allow_open_chat_window from table |
5347
|
|
|
'allow_open_chat_window', |
5348
|
|
|
'allow_public_certificates', |
5349
|
|
|
// Get allow_user_edit_agenda from table |
5350
|
|
|
'allow_user_edit_agenda', |
5351
|
|
|
// Get allow_user_edit_announcement from table |
5352
|
|
|
'allow_user_edit_announcement', |
5353
|
|
|
// Get allow_user_image_forum from table |
5354
|
|
|
'allow_user_image_forum', |
5355
|
|
|
//Get allow show user list |
5356
|
|
|
'allow_user_view_user_list', |
5357
|
|
|
// Get course_theme from table |
5358
|
|
|
'course_theme', |
5359
|
|
|
//Get allow show user list |
5360
|
|
|
'display_info_advance_inside_homecourse', |
5361
|
|
|
'documents_default_visibility', |
5362
|
|
|
// Get send_mail_setting (work)from table |
5363
|
|
|
'email_alert_manager_on_new_doc', |
5364
|
|
|
// Get send_mail_setting (work)from table |
5365
|
|
|
'email_alert_manager_on_new_quiz', |
5366
|
|
|
// Get send_mail_setting (dropbox) from table |
5367
|
|
|
'email_alert_on_new_doc_dropbox', |
5368
|
|
|
'email_alert_students_on_new_homework', |
5369
|
|
|
// Get send_mail_setting (auth)from table |
5370
|
|
|
'email_alert_to_teacher_on_new_user_in_course', |
5371
|
|
|
'enable_lp_auto_launch', |
5372
|
|
|
'enable_exercise_auto_launch', |
5373
|
|
|
'enable_document_auto_launch', |
5374
|
|
|
'pdf_export_watermark_text', |
5375
|
|
|
'show_system_folders', |
5376
|
|
|
'exercise_invisible_in_session', |
5377
|
|
|
'enable_forum_auto_launch', |
5378
|
|
|
'show_course_in_user_language', |
5379
|
|
|
'email_to_teachers_on_new_work_feedback', |
5380
|
|
|
'student_delete_own_publication', |
5381
|
|
|
'hide_forum_notifications', |
5382
|
|
|
'quiz_question_limit_per_day', |
5383
|
|
|
'subscribe_users_to_forum_notifications', |
5384
|
|
|
]; |
5385
|
|
|
|
5386
|
|
|
$courseModels = ExerciseLib::getScoreModels(); |
5387
|
|
|
if (!empty($courseModels)) { |
5388
|
|
|
$courseSettings[] = 'score_model_id'; |
5389
|
|
|
} |
5390
|
|
|
|
5391
|
|
|
$allowLPReturnLink = api_get_setting('allow_lp_return_link'); |
5392
|
|
|
if ('true' === $allowLPReturnLink) { |
5393
|
|
|
$courseSettings[] = 'lp_return_link'; |
5394
|
|
|
} |
5395
|
|
|
|
5396
|
|
|
if (!empty($pluginCourseSettings)) { |
5397
|
|
|
$courseSettings = array_merge( |
5398
|
|
|
$courseSettings, |
5399
|
|
|
$pluginCourseSettings |
5400
|
|
|
); |
5401
|
|
|
} |
5402
|
|
|
|
5403
|
|
|
return $courseSettings; |
5404
|
|
|
} |
5405
|
|
|
|
5406
|
|
|
/** |
5407
|
|
|
* @param string $variable |
5408
|
|
|
* @param string|array $value |
5409
|
|
|
* @param int $courseId |
5410
|
|
|
* |
5411
|
|
|
* @return bool |
5412
|
|
|
*/ |
5413
|
|
|
public static function saveCourseConfigurationSetting(AppPlugin $appPlugin, $variable, $value, $courseId) |
5414
|
|
|
{ |
5415
|
|
|
$settingList = self::getCourseSettingVariables($appPlugin); |
5416
|
|
|
|
5417
|
|
|
if (!in_array($variable, $settingList)) { |
5418
|
|
|
return false; |
5419
|
|
|
} |
5420
|
|
|
|
5421
|
|
|
$courseSettingTable = Database::get_course_table(TABLE_COURSE_SETTING); |
5422
|
|
|
|
5423
|
|
|
if (is_array($value)) { |
5424
|
|
|
$value = implode(',', $value); |
5425
|
|
|
} |
5426
|
|
|
|
5427
|
|
|
$settingFromDatabase = self::getCourseSetting($variable, $courseId); |
5428
|
|
|
|
5429
|
|
|
if (!empty($settingFromDatabase)) { |
5430
|
|
|
// Update |
5431
|
|
|
Database::update( |
5432
|
|
|
$courseSettingTable, |
5433
|
|
|
['value' => $value], |
5434
|
|
|
['variable = ? AND c_id = ?' => [$variable, $courseId]] |
5435
|
|
|
); |
5436
|
|
|
|
5437
|
|
|
if ($settingFromDatabase['value'] != $value) { |
5438
|
|
|
Event::addEvent( |
5439
|
|
|
LOG_COURSE_SETTINGS_CHANGED, |
5440
|
|
|
$variable, |
5441
|
|
|
$settingFromDatabase['value']." -> $value" |
5442
|
|
|
); |
5443
|
|
|
} |
5444
|
|
|
} else { |
5445
|
|
|
// Create |
5446
|
|
|
Database::insert( |
5447
|
|
|
$courseSettingTable, |
5448
|
|
|
[ |
5449
|
|
|
'title' => $variable, |
5450
|
|
|
'value' => $value, |
5451
|
|
|
'c_id' => $courseId, |
5452
|
|
|
'variable' => $variable, |
5453
|
|
|
] |
5454
|
|
|
); |
5455
|
|
|
|
5456
|
|
|
Event::addEvent( |
5457
|
|
|
LOG_COURSE_SETTINGS_CHANGED, |
5458
|
|
|
$variable, |
5459
|
|
|
$value |
5460
|
|
|
); |
5461
|
|
|
} |
5462
|
|
|
|
5463
|
|
|
return true; |
5464
|
|
|
} |
5465
|
|
|
|
5466
|
|
|
/** |
5467
|
|
|
* Get course setting. |
5468
|
|
|
* |
5469
|
|
|
* @param string $variable |
5470
|
|
|
* @param int $courseId |
5471
|
|
|
* |
5472
|
|
|
* @return array |
5473
|
|
|
*/ |
5474
|
|
|
public static function getCourseSetting($variable, $courseId) |
5475
|
|
|
{ |
5476
|
|
|
$courseSetting = Database::get_course_table(TABLE_COURSE_SETTING); |
5477
|
|
|
$courseId = (int) $courseId; |
5478
|
|
|
$variable = Database::escape_string($variable); |
5479
|
|
|
$sql = "SELECT variable, value FROM $courseSetting |
5480
|
|
|
WHERE c_id = $courseId AND variable = '$variable'"; |
5481
|
|
|
$result = Database::query($sql); |
5482
|
|
|
|
5483
|
|
|
return Database::fetch_array($result); |
5484
|
|
|
} |
5485
|
|
|
|
5486
|
|
|
public static function saveSettingChanges($courseInfo, $params) |
5487
|
|
|
{ |
5488
|
|
|
if (empty($courseInfo) || empty($params)) { |
5489
|
|
|
return false; |
5490
|
|
|
} |
5491
|
|
|
|
5492
|
|
|
$userId = api_get_user_id(); |
5493
|
|
|
$now = api_get_utc_datetime(); |
5494
|
|
|
|
5495
|
|
|
foreach ($params as $name => $value) { |
5496
|
|
|
$emptyValue = ' - '; |
5497
|
|
|
if (isset($courseInfo[$name]) && $courseInfo[$name] != $value) { |
5498
|
|
|
if ('' !== $courseInfo[$name]) { |
5499
|
|
|
$emptyValue = $courseInfo[$name]; |
5500
|
|
|
} |
5501
|
|
|
|
5502
|
|
|
$changedTo = $emptyValue.' -> '.$value; |
5503
|
|
|
|
5504
|
|
|
Event::addEvent( |
5505
|
|
|
LOG_COURSE_SETTINGS_CHANGED, |
5506
|
|
|
$name, |
5507
|
|
|
$changedTo, |
5508
|
|
|
$now, |
5509
|
|
|
$userId, |
5510
|
|
|
$courseInfo['real_id'] |
5511
|
|
|
); |
5512
|
|
|
} |
5513
|
|
|
} |
5514
|
|
|
|
5515
|
|
|
return true; |
5516
|
|
|
} |
5517
|
|
|
|
5518
|
|
|
/** |
5519
|
|
|
* Get information from the track_e_course_access table. |
5520
|
|
|
* |
5521
|
|
|
* @param int $courseId |
5522
|
|
|
* @param int $sessionId |
5523
|
|
|
* @param string $startDate |
5524
|
|
|
* @param string $endDate |
5525
|
|
|
* |
5526
|
|
|
* @return array |
5527
|
|
|
*/ |
5528
|
|
|
public static function getCourseAccessPerCourseAndSession( |
5529
|
|
|
$courseId, |
5530
|
|
|
$sessionId, |
5531
|
|
|
$startDate, |
5532
|
|
|
$endDate |
5533
|
|
|
) { |
5534
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
5535
|
|
|
$courseId = (int) $courseId; |
5536
|
|
|
$sessionId = (int) $sessionId; |
5537
|
|
|
$startDate = Database::escape_string($startDate); |
5538
|
|
|
$endDate = Database::escape_string($endDate); |
5539
|
|
|
|
5540
|
|
|
$sql = "SELECT * FROM $table |
5541
|
|
|
WHERE |
5542
|
|
|
c_id = $courseId AND |
5543
|
|
|
session_id = $sessionId AND |
5544
|
|
|
login_course_date BETWEEN '$startDate' AND '$endDate' |
5545
|
|
|
"; |
5546
|
|
|
|
5547
|
|
|
$result = Database::query($sql); |
5548
|
|
|
|
5549
|
|
|
return Database::store_result($result); |
5550
|
|
|
} |
5551
|
|
|
|
5552
|
|
|
/** |
5553
|
|
|
* Get login information from the track_e_course_access table, for any |
5554
|
|
|
* course in the given session. |
5555
|
|
|
* |
5556
|
|
|
* @param int $sessionId |
5557
|
|
|
* @param int $userId |
5558
|
|
|
* |
5559
|
|
|
* @return array |
5560
|
|
|
*/ |
5561
|
|
|
public static function getFirstCourseAccessPerSessionAndUser($sessionId, $userId) |
5562
|
|
|
{ |
5563
|
|
|
$sessionId = (int) $sessionId; |
5564
|
|
|
$userId = (int) $userId; |
5565
|
|
|
|
5566
|
|
|
$table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
5567
|
|
|
$sql = "SELECT * FROM $table |
5568
|
|
|
WHERE session_id = $sessionId AND user_id = $userId |
5569
|
|
|
ORDER BY login_course_date ASC |
5570
|
|
|
LIMIT 1"; |
5571
|
|
|
|
5572
|
|
|
$result = Database::query($sql); |
5573
|
|
|
$courseAccess = []; |
5574
|
|
|
if (Database::num_rows($result)) { |
5575
|
|
|
$courseAccess = Database::fetch_array($result, 'ASSOC'); |
5576
|
|
|
} |
5577
|
|
|
|
5578
|
|
|
return $courseAccess; |
5579
|
|
|
} |
5580
|
|
|
|
5581
|
|
|
/** |
5582
|
|
|
* @param int $courseId |
5583
|
|
|
* @param int $sessionId |
5584
|
|
|
* @param bool $getAllSessions |
5585
|
|
|
* |
5586
|
|
|
* @return mixed |
5587
|
|
|
*/ |
5588
|
|
|
public static function getCountForum( |
5589
|
|
|
$courseId, |
5590
|
|
|
$sessionId = 0, |
5591
|
|
|
$getAllSessions = false |
5592
|
|
|
) { |
5593
|
|
|
$forum = Database::get_course_table(TABLE_FORUM); |
5594
|
|
|
if ($getAllSessions) { |
5595
|
|
|
$sql = "SELECT count(*) as count |
5596
|
|
|
FROM $forum f |
5597
|
|
|
WHERE f.c_id = %s"; |
5598
|
|
|
} else { |
5599
|
|
|
$sql = "SELECT count(*) as count |
5600
|
|
|
FROM $forum f |
5601
|
|
|
WHERE f.c_id = %s and f.session_id = %s"; |
5602
|
|
|
} |
5603
|
|
|
|
5604
|
|
|
$sql = sprintf($sql, intval($courseId), intval($sessionId)); |
5605
|
|
|
$result = Database::query($sql); |
5606
|
|
|
$row = Database::fetch_array($result); |
5607
|
|
|
|
5608
|
|
|
return $row['count']; |
5609
|
|
|
} |
5610
|
|
|
|
5611
|
|
|
/** |
5612
|
|
|
* @param int $userId |
5613
|
|
|
* @param int $courseId |
5614
|
|
|
* @param int $sessionId |
5615
|
|
|
* |
5616
|
|
|
* @return mixed |
5617
|
|
|
*/ |
5618
|
|
|
public static function getCountPostInForumPerUser( |
5619
|
|
|
$userId, |
5620
|
|
|
$courseId, |
5621
|
|
|
$sessionId = 0 |
5622
|
|
|
) { |
5623
|
|
|
$forum = Database::get_course_table(TABLE_FORUM); |
5624
|
|
|
$forum_post = Database::get_course_table(TABLE_FORUM_POST); |
5625
|
|
|
|
5626
|
|
|
$sql = "SELECT count(distinct post_id) as count |
5627
|
|
|
FROM $forum_post p |
5628
|
|
|
INNER JOIN $forum f |
5629
|
|
|
ON f.forum_id = p.forum_id AND f.c_id = p.c_id |
5630
|
|
|
WHERE p.poster_id = %s and f.session_id = %s and p.c_id = %s"; |
5631
|
|
|
|
5632
|
|
|
$sql = sprintf( |
5633
|
|
|
$sql, |
5634
|
|
|
intval($userId), |
5635
|
|
|
intval($sessionId), |
5636
|
|
|
intval($courseId) |
5637
|
|
|
); |
5638
|
|
|
|
5639
|
|
|
$result = Database::query($sql); |
5640
|
|
|
$row = Database::fetch_array($result); |
5641
|
|
|
|
5642
|
|
|
return $row['count']; |
5643
|
|
|
} |
5644
|
|
|
|
5645
|
|
|
/** |
5646
|
|
|
* @param int $userId |
5647
|
|
|
* @param int $courseId |
5648
|
|
|
* @param int $sessionId |
5649
|
|
|
* |
5650
|
|
|
* @return mixed |
5651
|
|
|
*/ |
5652
|
|
|
public static function getCountForumPerUser( |
5653
|
|
|
$userId, |
5654
|
|
|
$courseId, |
5655
|
|
|
$sessionId = 0 |
5656
|
|
|
) { |
5657
|
|
|
$forum = Database::get_course_table(TABLE_FORUM); |
5658
|
|
|
$forum_post = Database::get_course_table(TABLE_FORUM_POST); |
5659
|
|
|
|
5660
|
|
|
$sql = "SELECT count(distinct f.forum_id) as count |
5661
|
|
|
FROM $forum_post p |
5662
|
|
|
INNER JOIN $forum f |
5663
|
|
|
ON f.forum_id = p.forum_id AND f.c_id = p.c_id |
5664
|
|
|
WHERE p.poster_id = %s and f.session_id = %s and p.c_id = %s"; |
5665
|
|
|
|
5666
|
|
|
$sql = sprintf( |
5667
|
|
|
$sql, |
5668
|
|
|
intval($userId), |
5669
|
|
|
intval($sessionId), |
5670
|
|
|
intval($courseId) |
5671
|
|
|
); |
5672
|
|
|
|
5673
|
|
|
$result = Database::query($sql); |
5674
|
|
|
$row = Database::fetch_array($result); |
5675
|
|
|
|
5676
|
|
|
return $row['count']; |
5677
|
|
|
} |
5678
|
|
|
|
5679
|
|
|
/** |
5680
|
|
|
* Returns the course name from a given code. |
5681
|
|
|
* |
5682
|
|
|
* @param string $code |
5683
|
|
|
* |
5684
|
|
|
* @return string |
5685
|
|
|
*/ |
5686
|
|
|
public static function getCourseNameFromCode($code) |
5687
|
|
|
{ |
5688
|
|
|
$tbl_main_categories = Database::get_main_table(TABLE_MAIN_COURSE); |
5689
|
|
|
$code = Database::escape_string($code); |
5690
|
|
|
$sql = "SELECT title |
5691
|
|
|
FROM $tbl_main_categories |
5692
|
|
|
WHERE code = '$code'"; |
5693
|
|
|
$result = Database::query($sql); |
5694
|
|
|
if ($col = Database::fetch_array($result)) { |
5695
|
|
|
return $col['title']; |
5696
|
|
|
} |
5697
|
|
|
} |
5698
|
|
|
|
5699
|
|
|
/** |
5700
|
|
|
* Generates a course code from a course title. |
5701
|
|
|
* |
5702
|
|
|
* @todo Such a function might be useful in other places too. It might be moved in the CourseManager class. |
5703
|
|
|
* @todo the function might be upgraded for avoiding code duplications (currently, |
5704
|
|
|
* it might suggest a code that is already in use) |
5705
|
|
|
* |
5706
|
|
|
* @param string $title A course title |
5707
|
|
|
* |
5708
|
|
|
* @return string A proposed course code |
5709
|
|
|
* + |
5710
|
|
|
* @assert (null,null) === false |
5711
|
|
|
* @assert ('ABC_DEF', null) === 'ABCDEF' |
5712
|
|
|
* @assert ('ABC09*^[%A', null) === 'ABC09A' |
5713
|
|
|
*/ |
5714
|
|
|
public static function generate_course_code($title) |
5715
|
|
|
{ |
5716
|
|
|
return substr( |
5717
|
|
|
preg_replace('/[^A-Z0-9]/', '', strtoupper(api_replace_dangerous_char($title))), |
5718
|
|
|
0, |
5719
|
|
|
self::MAX_COURSE_LENGTH_CODE |
5720
|
|
|
); |
5721
|
|
|
} |
5722
|
|
|
|
5723
|
|
|
/** |
5724
|
|
|
* this function gets all the users of the course, |
5725
|
|
|
* including users from linked courses. |
5726
|
|
|
* |
5727
|
|
|
* @param $filterByActive |
5728
|
|
|
* |
5729
|
|
|
* @return array |
5730
|
|
|
*/ |
5731
|
|
|
public static function getCourseUsers($filterByActive = null) |
5732
|
|
|
{ |
5733
|
|
|
// This would return only the users from real courses: |
5734
|
|
|
return self::get_user_list_from_course_code( |
5735
|
|
|
api_get_course_id(), |
5736
|
|
|
api_get_session_id(), |
5737
|
|
|
null, |
5738
|
|
|
null, |
5739
|
|
|
null, |
5740
|
|
|
null, |
5741
|
|
|
false, |
5742
|
|
|
false, |
5743
|
|
|
[], |
5744
|
|
|
[], |
5745
|
|
|
[], |
5746
|
|
|
$filterByActive |
5747
|
|
|
); |
5748
|
|
|
} |
5749
|
|
|
|
5750
|
|
|
/** |
5751
|
|
|
* this function gets all the groups of the course, |
5752
|
|
|
* not including linked courses. |
5753
|
|
|
* |
5754
|
|
|
* @return CGroup[] |
5755
|
|
|
*/ |
5756
|
|
|
public static function getCourseGroups() |
5757
|
|
|
{ |
5758
|
|
|
$sessionId = api_get_session_id(); |
5759
|
|
|
$courseCode = api_get_course_id(); |
5760
|
|
|
if (0 != $sessionId) { |
5761
|
|
|
$groupList = self::get_group_list_of_course( |
5762
|
|
|
$courseCode, |
5763
|
|
|
$sessionId, |
5764
|
|
|
1 |
5765
|
|
|
); |
5766
|
|
|
} else { |
5767
|
|
|
$groupList = self::get_group_list_of_course( |
5768
|
|
|
$courseCode, |
5769
|
|
|
0, |
5770
|
|
|
1 |
5771
|
|
|
); |
5772
|
|
|
} |
5773
|
|
|
|
5774
|
|
|
return $groupList; |
5775
|
|
|
} |
5776
|
|
|
|
5777
|
|
|
/** |
5778
|
|
|
* @param FormValidator $form |
5779
|
|
|
* @param array $alreadySelected |
5780
|
|
|
* |
5781
|
|
|
* @return HTML_QuickForm_element |
5782
|
|
|
*/ |
5783
|
|
|
public static function addUserGroupMultiSelect(&$form, $alreadySelected, $addShortCut = false) |
5784
|
|
|
{ |
5785
|
|
|
$userList = self::getCourseUsers(true); |
5786
|
|
|
$groupList = self::getCourseGroups(); |
5787
|
|
|
|
5788
|
|
|
$array = self::buildSelectOptions( |
5789
|
|
|
$groupList, |
5790
|
|
|
$userList, |
5791
|
|
|
$alreadySelected |
5792
|
|
|
); |
5793
|
|
|
|
5794
|
|
|
$result = []; |
5795
|
|
|
foreach ($array as $content) { |
5796
|
|
|
$result[$content['value']] = $content['content']; |
5797
|
|
|
} |
5798
|
|
|
|
5799
|
|
|
$multiple = $form->addElement( |
5800
|
|
|
'advmultiselect', |
5801
|
|
|
'users', |
5802
|
|
|
get_lang('Users'), |
5803
|
|
|
$result, |
5804
|
|
|
['select_all_checkbox' => true, 'id' => 'users'] |
5805
|
|
|
); |
5806
|
|
|
|
5807
|
|
|
$sessionId = api_get_session_id(); |
5808
|
|
|
if ($addShortCut && empty($sessionId)) { |
5809
|
|
|
$addStudents = []; |
5810
|
|
|
foreach ($userList as $user) { |
5811
|
|
|
if (STUDENT == $user['status_rel']) { |
5812
|
|
|
$addStudents[] = $user['user_id']; |
5813
|
|
|
} |
5814
|
|
|
} |
5815
|
|
|
if (!empty($addStudents)) { |
5816
|
|
|
$form->addHtml( |
5817
|
|
|
'<script> |
5818
|
|
|
$(function() { |
5819
|
|
|
$("#add_students").on("click", function() { |
5820
|
|
|
var addStudents = '.json_encode($addStudents).'; |
5821
|
|
|
$.each(addStudents, function( index, value ) { |
5822
|
|
|
var option = $("#users option[value=\'USER:"+value+"\']"); |
5823
|
|
|
if (option.val()) { |
5824
|
|
|
$("#users_to").append(new Option(option.text(), option.val())) |
5825
|
|
|
option.remove(); |
5826
|
|
|
} |
5827
|
|
|
}); |
5828
|
|
|
|
5829
|
|
|
return false; |
5830
|
|
|
}); |
5831
|
|
|
}); |
5832
|
|
|
</script>' |
5833
|
|
|
); |
5834
|
|
|
|
5835
|
|
|
$form->addLabel( |
5836
|
|
|
'', |
5837
|
|
|
Display::url(get_lang('Add learners'), '#', ['id' => 'add_students', 'class' => 'btn btn-primary']) |
5838
|
|
|
); |
5839
|
|
|
} |
5840
|
|
|
} |
5841
|
|
|
|
5842
|
|
|
return $multiple; |
5843
|
|
|
} |
5844
|
|
|
|
5845
|
|
|
/** |
5846
|
|
|
* This function separates the users from the groups |
5847
|
|
|
* users have a value USER:XXX (with XXX the groups id have a value |
5848
|
|
|
* GROUP:YYY (with YYY the group id). |
5849
|
|
|
* |
5850
|
|
|
* @param array $to Array of strings that define the type and id of each destination |
5851
|
|
|
* |
5852
|
|
|
* @return array Array of groups and users (each an array of IDs) |
5853
|
|
|
*/ |
5854
|
|
|
public static function separateUsersGroups($to) |
5855
|
|
|
{ |
5856
|
|
|
$groupList = []; |
5857
|
|
|
$userList = []; |
5858
|
|
|
|
5859
|
|
|
foreach ($to as $to_item) { |
5860
|
|
|
if (!empty($to_item)) { |
5861
|
|
|
$parts = explode(':', $to_item); |
5862
|
|
|
$type = isset($parts[0]) ? $parts[0] : ''; |
5863
|
|
|
$id = isset($parts[1]) ? $parts[1] : ''; |
5864
|
|
|
|
5865
|
|
|
switch ($type) { |
5866
|
|
|
case 'GROUP': |
5867
|
|
|
$groupList[] = (int) $id; |
5868
|
|
|
break; |
5869
|
|
|
case 'USER': |
5870
|
|
|
$userList[] = (int) $id; |
5871
|
|
|
break; |
5872
|
|
|
} |
5873
|
|
|
} |
5874
|
|
|
} |
5875
|
|
|
|
5876
|
|
|
$send_to['groups'] = $groupList; |
5877
|
|
|
$send_to['users'] = $userList; |
5878
|
|
|
|
5879
|
|
|
return $send_to; |
5880
|
|
|
} |
5881
|
|
|
|
5882
|
|
|
/** |
5883
|
|
|
* Shows the form for sending a message to a specific group or user. |
5884
|
|
|
* |
5885
|
|
|
* @return HTML_QuickForm_element |
5886
|
|
|
*/ |
5887
|
|
|
public static function addGroupMultiSelect(FormValidator $form, CGroup $group, $to = []) |
5888
|
|
|
{ |
5889
|
|
|
$groupUsers = GroupManager::get_subscribed_users($group); |
5890
|
|
|
$array = self::buildSelectOptions([$group], $groupUsers, $to); |
5891
|
|
|
|
5892
|
|
|
$result = []; |
5893
|
|
|
foreach ($array as $content) { |
5894
|
|
|
$result[$content['value']] = $content['content']; |
5895
|
|
|
} |
5896
|
|
|
|
5897
|
|
|
return $form->addElement('advmultiselect', 'users', get_lang('Users'), $result); |
5898
|
|
|
} |
5899
|
|
|
|
5900
|
|
|
/** |
5901
|
|
|
* this function shows the form for sending a message to a specific group or user. |
5902
|
|
|
* |
5903
|
|
|
* @param CGroup[] $groupList |
5904
|
|
|
* @param array $userList |
5905
|
|
|
* @param array $alreadySelected |
5906
|
|
|
* |
5907
|
|
|
* @return array |
5908
|
|
|
*/ |
5909
|
|
|
public static function buildSelectOptions($groupList = [], $userList = [], $alreadySelected = []) |
5910
|
|
|
{ |
5911
|
|
|
if (empty($alreadySelected)) { |
5912
|
|
|
$alreadySelected = []; |
5913
|
|
|
} |
5914
|
|
|
|
5915
|
|
|
$result = []; |
5916
|
|
|
// adding the groups to the select form |
5917
|
|
|
if ($groupList) { |
5918
|
|
|
foreach ($groupList as $thisGroup) { |
5919
|
|
|
$groupId = $thisGroup->getIid(); |
5920
|
|
|
if (is_array($alreadySelected)) { |
5921
|
|
|
if (!in_array( |
5922
|
|
|
"GROUP:".$groupId, |
5923
|
|
|
$alreadySelected |
5924
|
|
|
) |
5925
|
|
|
) { |
5926
|
|
|
$userCount = $thisGroup->getMembers()->count(); |
5927
|
|
|
|
5928
|
|
|
// $alreadySelected is the array containing the groups (and users) that are already selected |
5929
|
|
|
$userLabel = ($userCount > 0) ? get_lang('Users') : get_lang('user'); |
5930
|
|
|
$userDisabled = ($userCount > 0) ? "" : "disabled=disabled"; |
5931
|
|
|
$result[] = [ |
5932
|
|
|
'disabled' => $userDisabled, |
5933
|
|
|
'value' => "GROUP:".$groupId, |
5934
|
|
|
// The space before "G" is needed in order to advmultiselect.php js puts groups first |
5935
|
|
|
'content' => " G: ".$thisGroup->getName()." - ".$userCount." ".$userLabel, |
5936
|
|
|
]; |
5937
|
|
|
} |
5938
|
|
|
} |
5939
|
|
|
} |
5940
|
|
|
} |
5941
|
|
|
|
5942
|
|
|
// adding the individual users to the select form |
5943
|
|
|
if ($userList) { |
5944
|
|
|
foreach ($userList as $user) { |
5945
|
|
|
if (is_array($alreadySelected)) { |
5946
|
|
|
if (!in_array( |
5947
|
|
|
"USER:".$user['user_id'], |
5948
|
|
|
$alreadySelected |
5949
|
|
|
) |
5950
|
|
|
) { |
5951
|
|
|
// $alreadySelected is the array containing the users (and groups) that are already selected |
5952
|
|
|
$result[] = [ |
5953
|
|
|
'value' => "USER:".$user['user_id'], |
5954
|
|
|
'content' => api_get_person_name($user['firstname'], $user['lastname']), |
5955
|
|
|
]; |
5956
|
|
|
} |
5957
|
|
|
} |
5958
|
|
|
} |
5959
|
|
|
} |
5960
|
|
|
|
5961
|
|
|
return $result; |
5962
|
|
|
} |
5963
|
|
|
|
5964
|
|
|
/** |
5965
|
|
|
* @return array a list (array) of all courses |
5966
|
|
|
*/ |
5967
|
|
|
public static function get_course_list() |
5968
|
|
|
{ |
5969
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
5970
|
|
|
|
5971
|
|
|
return Database::store_result(Database::query("SELECT *, id as real_id FROM $table")); |
5972
|
|
|
} |
5973
|
|
|
|
5974
|
|
|
/** |
5975
|
|
|
* Returns course code from a given gradebook category's id. |
5976
|
|
|
* |
5977
|
|
|
* @param int Category ID |
5978
|
|
|
* |
5979
|
|
|
* @return string Course code |
5980
|
|
|
*/ |
5981
|
|
|
public static function get_course_by_category($category_id) |
5982
|
|
|
{ |
5983
|
|
|
$category_id = (int) $category_id; |
5984
|
|
|
$sql = 'SELECT c_id FROM '.Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY).' |
5985
|
|
|
WHERE id='.$category_id; |
5986
|
|
|
$info = Database::fetch_array(Database::query($sql), 'ASSOC'); |
5987
|
|
|
|
5988
|
|
|
return $info ? $info['c_id'] : false; |
5989
|
|
|
} |
5990
|
|
|
|
5991
|
|
|
/** |
5992
|
|
|
* This function gets all the courses that are not in a session. |
5993
|
|
|
* |
5994
|
|
|
* @param date Start date |
5995
|
|
|
* @param date End date |
5996
|
|
|
* @param bool $includeClosed Whether to include closed and hidden courses |
5997
|
|
|
* |
5998
|
|
|
* @return array Not-in-session courses |
5999
|
|
|
*/ |
6000
|
|
|
public static function getCoursesWithoutSession( |
6001
|
|
|
$startDate = null, |
6002
|
|
|
$endDate = null, |
6003
|
|
|
$includeClosed = false |
6004
|
|
|
) { |
6005
|
|
|
$dateConditional = ($startDate && $endDate) ? |
6006
|
|
|
" WHERE session_id IN (SELECT id FROM ".Database::get_main_table(TABLE_MAIN_SESSION). |
6007
|
|
|
" WHERE access_start_date = '$startDate' AND access_end_date = '$endDate')" : null; |
6008
|
|
|
$visibility = ($includeClosed ? '' : 'visibility NOT IN (0, 4) AND '); |
6009
|
|
|
|
6010
|
|
|
$sql = "SELECT id, code, title |
6011
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_COURSE)." |
6012
|
|
|
WHERE $visibility code NOT IN ( |
6013
|
|
|
SELECT DISTINCT course_code |
6014
|
|
|
FROM ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE).$dateConditional." |
6015
|
|
|
) |
6016
|
|
|
ORDER BY id"; |
6017
|
|
|
|
6018
|
|
|
$result = Database::query($sql); |
6019
|
|
|
$courses = []; |
6020
|
|
|
while ($row = Database::fetch_array($result)) { |
6021
|
|
|
$courses[] = $row; |
6022
|
|
|
} |
6023
|
|
|
|
6024
|
|
|
return $courses; |
6025
|
|
|
} |
6026
|
|
|
|
6027
|
|
|
/** |
6028
|
|
|
* Get list of courses based on users of a group for a group admin. |
6029
|
|
|
* |
6030
|
|
|
* @param int $userId The user id |
6031
|
|
|
* |
6032
|
|
|
* @return array |
6033
|
|
|
*/ |
6034
|
|
|
public static function getCoursesFollowedByGroupAdmin($userId) |
6035
|
|
|
{ |
6036
|
|
|
$coursesList = []; |
6037
|
|
|
$courseTable = Database::get_main_table(TABLE_MAIN_COURSE); |
6038
|
|
|
$courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
6039
|
|
|
$userGroup = new UserGroupModel(); |
6040
|
|
|
$userIdList = $userGroup->getGroupUsersByUser($userId); |
6041
|
|
|
|
6042
|
|
|
if (empty($userIdList)) { |
6043
|
|
|
return []; |
6044
|
|
|
} |
6045
|
|
|
|
6046
|
|
|
$sql = "SELECT DISTINCT(c.id), c.title |
6047
|
|
|
FROM $courseTable c |
6048
|
|
|
INNER JOIN $courseUserTable cru ON c.id = cru.c_id |
6049
|
|
|
WHERE ( |
6050
|
|
|
cru.user_id IN (".implode(', ', $userIdList).") |
6051
|
|
|
AND cru.relation_type = 0 |
6052
|
|
|
)"; |
6053
|
|
|
|
6054
|
|
|
if (api_is_multiple_url_enabled()) { |
6055
|
|
|
$courseAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
6056
|
|
|
$accessUrlId = api_get_current_access_url_id(); |
6057
|
|
|
|
6058
|
|
|
if (-1 != $accessUrlId) { |
6059
|
|
|
$sql = "SELECT DISTINCT(c.id), c.title |
6060
|
|
|
FROM $courseTable c |
6061
|
|
|
INNER JOIN $courseUserTable cru ON c.id = cru.c_id |
6062
|
|
|
INNER JOIN $courseAccessUrlTable crau ON c.id = crau.c_id |
6063
|
|
|
WHERE crau.access_url_id = $accessUrlId |
6064
|
|
|
AND ( |
6065
|
|
|
cru.id_user IN (".implode(', ', $userIdList).") AND |
6066
|
|
|
cru.relation_type = 0 |
6067
|
|
|
)"; |
6068
|
|
|
} |
6069
|
|
|
} |
6070
|
|
|
|
6071
|
|
|
$result = Database::query($sql); |
6072
|
|
|
while ($row = Database::fetch_assoc($result)) { |
6073
|
|
|
$coursesList[] = $row; |
6074
|
|
|
} |
6075
|
|
|
|
6076
|
|
|
return $coursesList; |
6077
|
|
|
} |
6078
|
|
|
|
6079
|
|
|
/** |
6080
|
|
|
* Direct course link see #5299. |
6081
|
|
|
* |
6082
|
|
|
* You can send to your students an URL like this |
6083
|
|
|
* http://chamilodev.beeznest.com/main/auth/inscription.php?c=ABC&e=3 |
6084
|
|
|
* Where "c" is the course code and "e" is the exercise Id, after a successful |
6085
|
|
|
* registration the user will be sent to the course or exercise |
6086
|
|
|
* |
6087
|
|
|
* @param array $form_data |
6088
|
|
|
* |
6089
|
|
|
* @return array |
6090
|
|
|
*/ |
6091
|
|
|
public static function redirectToCourse($form_data) |
6092
|
|
|
{ |
6093
|
|
|
$course_code_redirect = Session::read('course_redirect'); |
6094
|
|
|
$_user = api_get_user_info(); |
6095
|
|
|
$userId = api_get_user_id(); |
6096
|
|
|
|
6097
|
|
|
if (!empty($course_code_redirect)) { |
6098
|
|
|
$course_info = api_get_course_info($course_code_redirect); |
6099
|
|
|
if (!empty($course_info)) { |
6100
|
|
|
if (in_array( |
6101
|
|
|
$course_info['visibility'], |
6102
|
|
|
[Course::OPEN_PLATFORM, Course::OPEN_WORLD] |
6103
|
|
|
) |
6104
|
|
|
) { |
6105
|
|
|
if (self::is_user_subscribed_in_course($userId, $course_info['code'])) { |
6106
|
|
|
$form_data['action'] = $course_info['course_public_url']; |
6107
|
|
|
$form_data['message'] = sprintf(get_lang('You have been registered to course %s'), $course_info['title']); |
6108
|
|
|
$form_data['button'] = Display::button( |
6109
|
|
|
'next', |
6110
|
|
|
get_lang('Go to the course', null, $_user['language']), |
6111
|
|
|
['class' => 'btn btn-primary btn-large'] |
6112
|
|
|
); |
6113
|
|
|
|
6114
|
|
|
$exercise_redirect = (int) Session::read('exercise_redirect'); |
6115
|
|
|
// Specify the course id as the current context does not |
6116
|
|
|
// hold a global $_course array |
6117
|
|
|
$objExercise = new Exercise($course_info['real_id']); |
6118
|
|
|
$result = $objExercise->read($exercise_redirect); |
6119
|
|
|
|
6120
|
|
|
if (!empty($exercise_redirect) && !empty($result)) { |
6121
|
|
|
$form_data['action'] = api_get_path(WEB_CODE_PATH). |
6122
|
|
|
'exercise/overview.php?exerciseId='.$exercise_redirect.'&cid='.$course_info['real_id']; |
6123
|
|
|
$form_data['message'] .= '<br />'.get_lang('Go to the test'); |
6124
|
|
|
$form_data['button'] = Display::button( |
6125
|
|
|
'next', |
6126
|
|
|
get_lang('Go', null, $_user['language']), |
6127
|
|
|
['class' => 'btn btn-primary btn-large'] |
6128
|
|
|
); |
6129
|
|
|
} |
6130
|
|
|
|
6131
|
|
|
if (!empty($form_data['action'])) { |
6132
|
|
|
header('Location: '.$form_data['action']); |
6133
|
|
|
exit; |
6134
|
|
|
} |
6135
|
|
|
} |
6136
|
|
|
} |
6137
|
|
|
} |
6138
|
|
|
} |
6139
|
|
|
|
6140
|
|
|
return $form_data; |
6141
|
|
|
} |
6142
|
|
|
|
6143
|
|
|
/** |
6144
|
|
|
* Return tab of params to display a course title in the My Courses tab |
6145
|
|
|
* Check visibility, right, and notification icons, and load_dirs option |
6146
|
|
|
* get html course params. |
6147
|
|
|
* |
6148
|
|
|
* @param $courseId |
6149
|
|
|
* @param bool $loadDirs |
6150
|
|
|
* |
6151
|
|
|
* @return array with keys ['right_actions'] ['teachers'] ['notifications'] |
6152
|
|
|
*/ |
6153
|
|
|
public static function getCourseParamsForDisplay($courseId, $loadDirs = false) |
6154
|
|
|
{ |
6155
|
|
|
$userId = api_get_user_id(); |
6156
|
|
|
$courseId = intval($courseId); |
6157
|
|
|
// Table definitions |
6158
|
|
|
$TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE); |
6159
|
|
|
$TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
6160
|
|
|
$TABLE_ACCESS_URL_REL_COURSE = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE); |
6161
|
|
|
$current_url_id = api_get_current_access_url_id(); |
6162
|
|
|
|
6163
|
|
|
// Get course list auto-register |
6164
|
|
|
$special_course_list = self::get_special_course_list(); |
6165
|
|
|
|
6166
|
|
|
$without_special_courses = ''; |
6167
|
|
|
if (!empty($special_course_list)) { |
6168
|
|
|
$without_special_courses = ' AND course.id NOT IN ("'.implode('","', $special_course_list).'")'; |
6169
|
|
|
} |
6170
|
|
|
|
6171
|
|
|
//AND course_rel_user.relation_type<>".COURSE_RELATION_TYPE_RRHH." |
6172
|
|
|
$sql = "SELECT |
6173
|
|
|
course.id, |
6174
|
|
|
course.title, |
6175
|
|
|
course.code, |
6176
|
|
|
course.subscribe subscr, |
6177
|
|
|
course.unsubscribe unsubscr, |
6178
|
|
|
course_rel_user.status status, |
6179
|
|
|
course_rel_user.sort sort, |
6180
|
|
|
course_rel_user.user_course_cat user_course_cat |
6181
|
|
|
FROM |
6182
|
|
|
$TABLECOURS course |
6183
|
|
|
INNER JOIN $TABLECOURSUSER course_rel_user |
6184
|
|
|
ON (course.id = course_rel_user.c_id) |
6185
|
|
|
INNER JOIN $TABLE_ACCESS_URL_REL_COURSE url |
6186
|
|
|
ON (url.c_id = course.id) |
6187
|
|
|
WHERE |
6188
|
|
|
course.id = $courseId AND |
6189
|
|
|
course_rel_user.user_id = $userId |
6190
|
|
|
$without_special_courses |
6191
|
|
|
"; |
6192
|
|
|
|
6193
|
|
|
// If multiple URL access mode is enabled, only fetch courses |
6194
|
|
|
// corresponding to the current URL. |
6195
|
|
|
if (api_get_multiple_access_url() && -1 != $current_url_id) { |
6196
|
|
|
$sql .= " AND url.c_id = course.id AND access_url_id = $current_url_id"; |
6197
|
|
|
} |
6198
|
|
|
// Use user's classification for courses (if any). |
6199
|
|
|
$sql .= " ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC"; |
6200
|
|
|
|
6201
|
|
|
$result = Database::query($sql); |
6202
|
|
|
|
6203
|
|
|
// Browse through all courses. We can only have one course because |
6204
|
|
|
// of the course.id=".intval($courseId) in sql query |
6205
|
|
|
$course = Database::fetch_array($result); |
6206
|
|
|
$course_info = api_get_course_info_by_id($courseId); |
6207
|
|
|
if (empty($course_info)) { |
6208
|
|
|
return ''; |
6209
|
|
|
} |
6210
|
|
|
|
6211
|
|
|
//$course['id_session'] = null; |
6212
|
|
|
$course_info['id_session'] = null; |
6213
|
|
|
$course_info['status'] = $course['status']; |
6214
|
|
|
|
6215
|
|
|
// For each course, get if there is any notification icon to show |
6216
|
|
|
// (something that would have changed since the user's last visit). |
6217
|
|
|
$show_notification = !api_get_configuration_value('hide_course_notification') |
6218
|
|
|
? Display::show_notification($course_info) |
6219
|
|
|
: ''; |
6220
|
|
|
|
6221
|
|
|
// New code displaying the user's status in respect to this course. |
6222
|
|
|
$status_icon = Display::return_icon( |
6223
|
|
|
'blackboard.png', |
6224
|
|
|
$course_info['title'], |
6225
|
|
|
[], |
6226
|
|
|
ICON_SIZE_LARGE |
6227
|
|
|
); |
6228
|
|
|
|
6229
|
|
|
$params = []; |
6230
|
|
|
$params['right_actions'] = ''; |
6231
|
|
|
|
6232
|
|
|
if (api_is_platform_admin()) { |
6233
|
|
|
if ($loadDirs) { |
6234
|
|
|
$params['right_actions'] .= '<a id="document_preview_'.$course_info['real_id'].'_0" class="document_preview" href="javascript:void(0);">'.Display::return_icon('folder.png', get_lang('Documents'), ['align' => 'absmiddle'], ICON_SIZE_SMALL).'</a>'; |
6235
|
|
|
$params['right_actions'] .= '<a href="'.api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cid='.$course['real_id'].'">'. |
6236
|
|
|
Display::return_icon('edit.png', get_lang('Edit'), ['align' => 'absmiddle'], ICON_SIZE_SMALL). |
6237
|
|
|
'</a>'; |
6238
|
|
|
$params['right_actions'] .= Display::div( |
6239
|
|
|
'', |
6240
|
|
|
[ |
6241
|
|
|
'id' => 'document_result_'.$course_info['real_id'].'_0', |
6242
|
|
|
'class' => 'document_preview_container', |
6243
|
|
|
] |
6244
|
|
|
); |
6245
|
|
|
} else { |
6246
|
|
|
$params['right_actions'] .= |
6247
|
|
|
'<a class="btn btn-default btn-sm" title="'.get_lang('Edit').'" href="'.api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cid='.$course['real_id'].'">'. |
6248
|
|
|
Display::returnFontAwesomeIcon('pencil').'</a>'; |
6249
|
|
|
} |
6250
|
|
|
} else { |
6251
|
|
|
if (Course::CLOSED != $course_info['visibility']) { |
6252
|
|
|
if ($loadDirs) { |
6253
|
|
|
$params['right_actions'] .= '<a id="document_preview_'.$course_info['real_id'].'_0" class="document_preview" href="javascript:void(0);">'. |
6254
|
|
|
Display::return_icon('folder.png', get_lang('Documents'), ['align' => 'absmiddle'], ICON_SIZE_SMALL).'</a>'; |
6255
|
|
|
$params['right_actions'] .= Display::div( |
6256
|
|
|
'', |
6257
|
|
|
[ |
6258
|
|
|
'id' => 'document_result_'.$course_info['real_id'].'_0', |
6259
|
|
|
'class' => 'document_preview_container', |
6260
|
|
|
] |
6261
|
|
|
); |
6262
|
|
|
} else { |
6263
|
|
|
if (COURSEMANAGER == $course_info['status']) { |
6264
|
|
|
$params['right_actions'] .= '<a |
6265
|
|
|
class="btn btn-default btn-sm" title="'.get_lang('Edit').'" href="'.api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cid='.$course['real_id'].'">'. |
6266
|
|
|
Display::returnFontAwesomeIcon('pencil').'</a>'; |
6267
|
|
|
} |
6268
|
|
|
} |
6269
|
|
|
} |
6270
|
|
|
} |
6271
|
|
|
|
6272
|
|
|
$course_title_url = ''; |
6273
|
|
|
if (Course::CLOSED != $course_info['visibility'] || COURSEMANAGER == $course['status']) { |
6274
|
|
|
$course_title_url = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/?id_session=0'; |
6275
|
|
|
$course_title = Display::url($course_info['title'], $course_title_url); |
6276
|
|
|
} else { |
6277
|
|
|
$course_title = $course_info['title'].' '.Display::tag( |
6278
|
|
|
'span', |
6279
|
|
|
get_lang('(the course is currently closed)'), |
6280
|
|
|
['class' => 'item_closed'] |
6281
|
|
|
); |
6282
|
|
|
} |
6283
|
|
|
|
6284
|
|
|
// Start displaying the course block itself |
6285
|
|
|
if ('true' === api_get_setting('display_coursecode_in_courselist')) { |
6286
|
|
|
$course_title .= ' ('.$course_info['visual_code'].') '; |
6287
|
|
|
} |
6288
|
|
|
$teachers = ''; |
6289
|
|
|
if ('true' === api_get_setting('display_teacher_in_courselist')) { |
6290
|
|
|
$teachers = self::getTeacherListFromCourseCodeToString( |
6291
|
|
|
$course['code'], |
6292
|
|
|
self::USER_SEPARATOR, |
6293
|
|
|
true |
6294
|
|
|
); |
6295
|
|
|
} |
6296
|
|
|
$params['link'] = $course_title_url; |
6297
|
|
|
$params['icon'] = $status_icon; |
6298
|
|
|
$params['title'] = $course_title; |
6299
|
|
|
$params['teachers'] = $teachers; |
6300
|
|
|
if (Course::CLOSED != $course_info['visibility']) { |
6301
|
|
|
$params['notifications'] = $show_notification; |
6302
|
|
|
} |
6303
|
|
|
|
6304
|
|
|
return $params; |
6305
|
|
|
} |
6306
|
|
|
|
6307
|
|
|
/** |
6308
|
|
|
* Get the course id based on the original id and field name in the extra fields. |
6309
|
|
|
* Returns 0 if course was not found. |
6310
|
|
|
* |
6311
|
|
|
* @param string $original_course_id_value Original course id |
6312
|
|
|
* @param string $original_course_id_name Original field name |
6313
|
|
|
* |
6314
|
|
|
* @return int Course id |
6315
|
|
|
*/ |
6316
|
|
|
public static function get_course_id_from_original_id($original_course_id_value, $original_course_id_name) |
6317
|
|
|
{ |
6318
|
|
|
$extraFieldValue = new ExtraFieldValue('course'); |
6319
|
|
|
$value = $extraFieldValue->get_item_id_from_field_variable_and_field_value( |
6320
|
|
|
$original_course_id_name, |
6321
|
|
|
$original_course_id_value |
6322
|
|
|
); |
6323
|
|
|
|
6324
|
|
|
if ($value) { |
6325
|
|
|
return $value['item_id']; |
6326
|
|
|
} |
6327
|
|
|
|
6328
|
|
|
return 0; |
6329
|
|
|
} |
6330
|
|
|
|
6331
|
|
|
/** |
6332
|
|
|
* Helper function to create a default gradebook (if necessary) upon course creation. |
6333
|
|
|
* |
6334
|
|
|
* @param int $modelId The gradebook model ID |
6335
|
|
|
* @param string $courseCode Course code |
6336
|
|
|
*/ |
6337
|
|
|
public static function createDefaultGradebook($modelId, $courseCode) |
6338
|
|
|
{ |
6339
|
|
|
if ('true' === api_get_setting('gradebook_enable_grade_model')) { |
6340
|
|
|
//Create gradebook_category for the new course and add |
6341
|
|
|
// a gradebook model for the course |
6342
|
|
|
if (isset($modelId) && |
6343
|
|
|
!empty($modelId) && |
6344
|
|
|
'-1' != $modelId |
6345
|
|
|
) { |
6346
|
|
|
GradebookUtils::create_default_course_gradebook( |
6347
|
|
|
$courseCode, |
6348
|
|
|
$modelId |
6349
|
|
|
); |
6350
|
|
|
} |
6351
|
|
|
} |
6352
|
|
|
} |
6353
|
|
|
|
6354
|
|
|
/** |
6355
|
|
|
* Helper function to check if there is a course template and, if so, to |
6356
|
|
|
* copy the template as basis for the new course. |
6357
|
|
|
* |
6358
|
|
|
* @param string $courseCode Course code |
6359
|
|
|
* @param int $courseTemplate 0 if no course template is defined |
6360
|
|
|
*/ |
6361
|
|
|
public static function useTemplateAsBasisIfRequired($courseCode, $courseTemplate) |
6362
|
|
|
{ |
6363
|
|
|
$template = api_get_setting('course_creation_use_template'); |
6364
|
|
|
$teacherCanSelectCourseTemplate = 'true' === api_get_setting('teacher_can_select_course_template'); |
6365
|
|
|
$courseTemplate = isset($courseTemplate) ? intval($courseTemplate) : 0; |
6366
|
|
|
|
6367
|
|
|
$useTemplate = false; |
6368
|
|
|
|
6369
|
|
|
if ($teacherCanSelectCourseTemplate && $courseTemplate) { |
6370
|
|
|
$useTemplate = true; |
6371
|
|
|
$originCourse = api_get_course_info_by_id($courseTemplate); |
6372
|
|
|
} elseif (!empty($template)) { |
6373
|
|
|
$useTemplate = true; |
6374
|
|
|
$originCourse = api_get_course_info_by_id($template); |
6375
|
|
|
} |
6376
|
|
|
|
6377
|
|
|
if ($useTemplate) { |
6378
|
|
|
// Include the necessary libraries to generate a course copy |
6379
|
|
|
// Call the course copy object |
6380
|
|
|
$originCourse['official_code'] = $originCourse['code']; |
6381
|
|
|
$cb = new CourseBuilder(null, $originCourse); |
6382
|
|
|
$course = $cb->build(null, $originCourse['code']); |
6383
|
|
|
$cr = new CourseRestorer($course); |
6384
|
|
|
$cr->set_file_option(); |
6385
|
|
|
$cr->restore($courseCode); |
6386
|
|
|
} |
6387
|
|
|
} |
6388
|
|
|
|
6389
|
|
|
/** |
6390
|
|
|
* Helper method to get the number of users defined with a specific course extra field. |
6391
|
|
|
* |
6392
|
|
|
* @param string $name Field title |
6393
|
|
|
* @param string $tableExtraFields The extra fields table name |
6394
|
|
|
* @param string $tableUserFieldValues The user extra field value table name |
6395
|
|
|
* |
6396
|
|
|
* @return int The number of users with this extra field with a specific value |
6397
|
|
|
*/ |
6398
|
|
|
public static function getCountRegisteredUsersWithCourseExtraField( |
6399
|
|
|
$name, |
6400
|
|
|
$tableExtraFields = '', |
6401
|
|
|
$tableUserFieldValues = '' |
6402
|
|
|
) { |
6403
|
|
|
if (empty($tableExtraFields)) { |
6404
|
|
|
$tableExtraFields = Database::get_main_table(TABLE_EXTRA_FIELD); |
6405
|
|
|
} |
6406
|
|
|
if (empty($tableUserFieldValues)) { |
6407
|
|
|
$tableUserFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES); |
6408
|
|
|
} |
6409
|
|
|
|
6410
|
|
|
$registered_users_with_extra_field = 0; |
6411
|
|
|
if (!empty($name) && '-' != $name) { |
6412
|
|
|
$extraFieldType = EntityExtraField::COURSE_FIELD_TYPE; |
6413
|
|
|
$name = Database::escape_string($name); |
6414
|
|
|
$sql = "SELECT count(v.item_id) as count |
6415
|
|
|
FROM $tableUserFieldValues v |
6416
|
|
|
INNER JOIN $tableExtraFields f |
6417
|
|
|
ON (f.id = v.field_id) |
6418
|
|
|
WHERE value = '$name' AND extra_field_type = $extraFieldType"; |
6419
|
|
|
$result_count = Database::query($sql); |
6420
|
|
|
if (Database::num_rows($result_count)) { |
6421
|
|
|
$row_count = Database::fetch_array($result_count); |
6422
|
|
|
$registered_users_with_extra_field = $row_count['count']; |
6423
|
|
|
} |
6424
|
|
|
} |
6425
|
|
|
|
6426
|
|
|
return $registered_users_with_extra_field; |
6427
|
|
|
} |
6428
|
|
|
|
6429
|
|
|
/** |
6430
|
|
|
* Get the course categories form a course list. |
6431
|
|
|
* |
6432
|
|
|
* @return array |
6433
|
|
|
*/ |
6434
|
|
|
public static function getCourseCategoriesFromCourseList(array $courseList) |
6435
|
|
|
{ |
6436
|
|
|
$allCategories = array_column($courseList, 'category'); |
6437
|
|
|
$categories = array_unique($allCategories); |
6438
|
|
|
|
6439
|
|
|
sort($categories); |
6440
|
|
|
|
6441
|
|
|
return $categories; |
6442
|
|
|
} |
6443
|
|
|
|
6444
|
|
|
/** |
6445
|
|
|
* Display the description button of a course in the course catalog. |
6446
|
|
|
* |
6447
|
|
|
* @param array $course |
6448
|
|
|
* @param string $url |
6449
|
|
|
* |
6450
|
|
|
* @return string HTML string |
6451
|
|
|
*/ |
6452
|
|
|
public static function returnDescriptionButton($course, $url = '') |
6453
|
|
|
{ |
6454
|
|
|
if (empty($course)) { |
6455
|
|
|
return ''; |
6456
|
|
|
} |
6457
|
|
|
|
6458
|
|
|
$class = ''; |
6459
|
|
|
if ('true' === api_get_setting('show_courses_descriptions_in_catalog')) { |
6460
|
|
|
$title = $course['title']; |
6461
|
|
|
if (empty($url)) { |
6462
|
|
|
$class = 'ajax'; |
6463
|
|
|
$url = api_get_path(WEB_CODE_PATH). |
6464
|
|
|
'inc/ajax/course_home.ajax.php?a=show_course_information&code='.$course['code']; |
6465
|
|
|
} else { |
6466
|
|
|
if (false !== strpos($url, 'ajax')) { |
6467
|
|
|
$class = 'ajax'; |
6468
|
|
|
} |
6469
|
|
|
} |
6470
|
|
|
|
6471
|
|
|
return Display::url( |
6472
|
|
|
Display::returnFontAwesomeIcon('info-circle', 'lg'), |
6473
|
|
|
$url, |
6474
|
|
|
[ |
6475
|
|
|
'class' => "$class btn btn-default btn-sm", |
6476
|
|
|
'data-title' => $title, |
6477
|
|
|
'title' => get_lang('Description'), |
6478
|
|
|
'aria-label' => get_lang('Description'), |
6479
|
|
|
'data-size' => 'lg', |
6480
|
|
|
] |
6481
|
|
|
); |
6482
|
|
|
} |
6483
|
|
|
|
6484
|
|
|
return ''; |
6485
|
|
|
} |
6486
|
|
|
|
6487
|
|
|
/** |
6488
|
|
|
* @return int |
6489
|
|
|
*/ |
6490
|
|
|
public static function getCountOpenCourses() |
6491
|
|
|
{ |
6492
|
|
|
$visibility = [ |
6493
|
|
|
Course::REGISTERED, |
6494
|
|
|
Course::OPEN_PLATFORM, |
6495
|
|
|
Course::OPEN_WORLD, |
6496
|
|
|
]; |
6497
|
|
|
|
6498
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
6499
|
|
|
$sql = "SELECT count(id) count |
6500
|
|
|
FROM $table |
6501
|
|
|
WHERE visibility IN (".implode(',', $visibility).")"; |
6502
|
|
|
$result = Database::query($sql); |
6503
|
|
|
$row = Database::fetch_array($result); |
6504
|
|
|
|
6505
|
|
|
return (int) $row['count']; |
6506
|
|
|
} |
6507
|
|
|
|
6508
|
|
|
/** |
6509
|
|
|
* @return int |
6510
|
|
|
*/ |
6511
|
|
|
public static function getCountExercisesFromOpenCourse() |
6512
|
|
|
{ |
6513
|
|
|
$visibility = [ |
6514
|
|
|
Course::REGISTERED, |
6515
|
|
|
Course::OPEN_PLATFORM, |
6516
|
|
|
Course::OPEN_WORLD, |
6517
|
|
|
]; |
6518
|
|
|
|
6519
|
|
|
$table = Database::get_main_table(TABLE_MAIN_COURSE); |
6520
|
|
|
$tableExercise = Database::get_course_table(TABLE_QUIZ_TEST); |
6521
|
|
|
$sql = "SELECT count(e.iid) count |
6522
|
|
|
FROM $table c |
6523
|
|
|
INNER JOIN $tableExercise e |
6524
|
|
|
ON (c.id = e.c_id) |
6525
|
|
|
WHERE e.active <> -1 AND visibility IN (".implode(',', $visibility).")"; |
6526
|
|
|
$result = Database::query($sql); |
6527
|
|
|
$row = Database::fetch_array($result); |
6528
|
|
|
|
6529
|
|
|
return (int) $row['count']; |
6530
|
|
|
} |
6531
|
|
|
|
6532
|
|
|
/** |
6533
|
|
|
* retrieves all the courses that the user has already subscribed to. |
6534
|
|
|
* |
6535
|
|
|
* @param int $user_id |
6536
|
|
|
* |
6537
|
|
|
* @return array an array containing all the information of the courses of the given user |
6538
|
|
|
*/ |
6539
|
|
|
public static function getCoursesByUserCourseCategory($user_id) |
6540
|
|
|
{ |
6541
|
|
|
$course = Database::get_main_table(TABLE_MAIN_COURSE); |
6542
|
|
|
$courseRelUser = Database::get_main_table(TABLE_MAIN_COURSE_USER); |
6543
|
|
|
$avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition(); |
6544
|
|
|
$visibilityCondition = self::getCourseVisibilitySQLCondition('course', true); |
6545
|
|
|
|
6546
|
|
|
// Secondly we select the courses that are in a category (user_course_cat<>0) and |
6547
|
|
|
// sort these according to the sort of the category |
6548
|
|
|
$user_id = (int) $user_id; |
6549
|
|
|
$sql = "SELECT |
6550
|
|
|
course.code k, |
6551
|
|
|
course.visual_code vc, |
6552
|
|
|
course.subscribe subscr, |
6553
|
|
|
course.unsubscribe unsubscr, |
6554
|
|
|
course.title i, |
6555
|
|
|
course.tutor_name t, |
6556
|
|
|
course.category_code cat, |
6557
|
|
|
course.directory dir, |
6558
|
|
|
course_rel_user.status status, |
6559
|
|
|
course_rel_user.sort sort, |
6560
|
|
|
course_rel_user.user_course_cat user_course_cat |
6561
|
|
|
FROM $course course, $courseRelUser course_rel_user |
6562
|
|
|
WHERE |
6563
|
|
|
course.id = course_rel_user.c_id AND |
6564
|
|
|
course_rel_user.relation_type <> ".COURSE_RELATION_TYPE_RRHH." AND |
6565
|
|
|
course_rel_user.user_id = '".$user_id."' |
6566
|
|
|
$avoidCoursesCondition |
6567
|
|
|
$visibilityCondition |
6568
|
|
|
ORDER BY course_rel_user.sort ASC"; |
6569
|
|
|
|
6570
|
|
|
$result = Database::query($sql); |
6571
|
|
|
$courses = []; |
6572
|
|
|
while ($row = Database::fetch_array($result, 'ASOC')) { |
6573
|
|
|
$courses[] = [ |
6574
|
|
|
'code' => $row['k'], |
6575
|
|
|
'visual_code' => $row['vc'], |
6576
|
|
|
'title' => $row['i'], |
6577
|
|
|
'directory' => $row['dir'], |
6578
|
|
|
'status' => $row['status'], |
6579
|
|
|
'tutor' => $row['t'], |
6580
|
|
|
'subscribe' => $row['subscr'], |
6581
|
|
|
'category' => $row['cat'], |
6582
|
|
|
'unsubscribe' => $row['unsubscr'], |
6583
|
|
|
'sort' => $row['sort'], |
6584
|
|
|
'user_course_category' => $row['user_course_cat'], |
6585
|
|
|
]; |
6586
|
|
|
} |
6587
|
|
|
|
6588
|
|
|
return $courses; |
6589
|
|
|
} |
6590
|
|
|
|
6591
|
|
|
/** |
6592
|
|
|
* @param string $listType |
6593
|
|
|
* |
6594
|
|
|
* @return string |
6595
|
|
|
*/ |
6596
|
|
|
public static function getCourseListTabs($listType) |
6597
|
|
|
{ |
6598
|
|
|
$tabs = [ |
6599
|
|
|
[ |
6600
|
|
|
'content' => get_lang('Standard list'), |
6601
|
|
|
'url' => api_get_path(WEB_CODE_PATH).'admin/course_list.php', |
6602
|
|
|
], |
6603
|
|
|
[ |
6604
|
|
|
'content' => get_lang('Management List'), |
6605
|
|
|
'url' => api_get_path(WEB_CODE_PATH).'admin/course_list_admin.php', |
6606
|
|
|
], |
6607
|
|
|
]; |
6608
|
|
|
|
6609
|
|
|
$default = 1; |
6610
|
|
|
switch ($listType) { |
6611
|
|
|
case 'simple': |
6612
|
|
|
$default = 1; |
6613
|
|
|
break; |
6614
|
|
|
case 'admin': |
6615
|
|
|
$default = 2; |
6616
|
|
|
break; |
6617
|
|
|
} |
6618
|
|
|
|
6619
|
|
|
return Display::tabsOnlyLink($tabs, $default); |
6620
|
|
|
} |
6621
|
|
|
|
6622
|
|
|
public static function getUrlMarker($courseId) |
6623
|
|
|
{ |
6624
|
|
|
if (UrlManager::getCountAccessUrlFromCourse($courseId) > 1) { |
6625
|
|
|
return ' '.Display::returnFontAwesomeIcon( |
6626
|
|
|
'link', |
6627
|
|
|
null, |
6628
|
|
|
null, |
6629
|
|
|
null, |
6630
|
|
|
get_lang('CourseUsedInOtherURL') |
6631
|
|
|
); |
6632
|
|
|
} |
6633
|
|
|
|
6634
|
|
|
return ''; |
6635
|
|
|
} |
6636
|
|
|
|
6637
|
|
|
/** |
6638
|
|
|
* @param User $user |
6639
|
|
|
* @param Course $course |
6640
|
|
|
* @param array $relationInfo |
6641
|
|
|
* |
6642
|
|
|
* @throws \Doctrine\ORM\ORMException |
6643
|
|
|
* @throws \Doctrine\ORM\OptimisticLockException |
6644
|
|
|
* |
6645
|
|
|
* @return int|null |
6646
|
|
|
*/ |
6647
|
|
|
public static function insertUserInCourse(User $user, Course $course, array $relationInfo = []): ?int |
6648
|
|
|
{ |
6649
|
|
|
$relationInfo = array_merge( |
6650
|
|
|
['relation_type' => 0, 'status' => STUDENT, 'sort' => 0, 'user_course_cat' => 0], |
6651
|
|
|
$relationInfo |
6652
|
|
|
); |
6653
|
|
|
|
6654
|
|
|
$courseRelUser = (new CourseRelUser()) |
6655
|
|
|
->setCourse($course) |
6656
|
|
|
->setUser($user) |
6657
|
|
|
->setStatus($relationInfo['status']) |
6658
|
|
|
->setSort($relationInfo['sort']) |
6659
|
|
|
->setUserCourseCat($relationInfo['user_course_cat']); |
6660
|
|
|
|
6661
|
|
|
$course->addUsers($courseRelUser); |
6662
|
|
|
|
6663
|
|
|
$em = Database::getManager(); |
6664
|
|
|
$em->persist($course); |
6665
|
|
|
$em->flush(); |
6666
|
|
|
|
6667
|
|
|
$insertId = $courseRelUser->getId(); |
6668
|
|
|
|
6669
|
|
|
Event::logSubscribedUserInCourse($user->getId(), $course->getId()); |
6670
|
|
|
|
6671
|
|
|
return $insertId; |
6672
|
|
|
} |
6673
|
|
|
/** |
6674
|
|
|
* Check if a specific access-url-related setting is a problem or not. |
6675
|
|
|
* |
6676
|
|
|
* @param array $_configuration The $_configuration array |
6677
|
|
|
* @param int $accessUrlId The access URL ID |
6678
|
|
|
* @param string $param |
6679
|
|
|
* @param string $msgLabel |
6680
|
|
|
* |
6681
|
|
|
* @return bool|string |
6682
|
|
|
*/ |
6683
|
|
|
private static function checkCreateCourseAccessUrlParam($_configuration, $accessUrlId, $param, $msgLabel) |
6684
|
|
|
{ |
6685
|
|
|
if (isset($_configuration[$accessUrlId][$param]) && $_configuration[$accessUrlId][$param] > 0) { |
6686
|
|
|
$num = null; |
6687
|
|
|
switch ($param) { |
6688
|
|
|
case 'hosting_limit_courses': |
6689
|
|
|
$num = self::count_courses($accessUrlId); |
6690
|
|
|
break; |
6691
|
|
|
case 'hosting_limit_active_courses': |
6692
|
|
|
$num = self::countActiveCourses($accessUrlId); |
6693
|
|
|
break; |
6694
|
|
|
} |
6695
|
|
|
|
6696
|
|
|
if ($num && $num >= $_configuration[$accessUrlId][$param]) { |
6697
|
|
|
api_warn_hosting_contact($param); |
6698
|
|
|
|
6699
|
|
|
Display::addFlash( |
6700
|
|
|
Display::return_message($msgLabel) |
6701
|
|
|
); |
6702
|
|
|
|
6703
|
|
|
return true; |
6704
|
|
|
} |
6705
|
|
|
} |
6706
|
|
|
|
6707
|
|
|
return false; |
6708
|
|
|
} |
6709
|
|
|
|
6710
|
|
|
/** |
6711
|
|
|
* Fill course with all necessary items. |
6712
|
|
|
* |
6713
|
|
|
* @param array $params Parameters from the course creation form |
6714
|
|
|
* @param int $authorId |
6715
|
|
|
*/ |
6716
|
|
|
private static function fillCourse(Course $course, $params, $authorId = 0) |
6717
|
|
|
{ |
6718
|
|
|
$authorId = empty($authorId) ? api_get_user_id() : (int) $authorId; |
6719
|
|
|
|
6720
|
|
|
AddCourse::fillCourse( |
6721
|
|
|
$course, |
6722
|
|
|
$params['exemplary_content'], |
6723
|
|
|
$authorId |
6724
|
|
|
); |
6725
|
|
|
|
6726
|
|
|
if (isset($params['gradebook_model_id'])) { |
6727
|
|
|
self::createDefaultGradebook( |
6728
|
|
|
$params['gradebook_model_id'], |
6729
|
|
|
$course->getCode() |
6730
|
|
|
); |
6731
|
|
|
} |
6732
|
|
|
|
6733
|
|
|
// If parameter defined, copy the contents from a specific |
6734
|
|
|
// template course into this new course |
6735
|
|
|
if (isset($params['course_template'])) { |
6736
|
|
|
self::useTemplateAsBasisIfRequired( |
6737
|
|
|
$course->getCode(), |
6738
|
|
|
$params['course_template'] |
6739
|
|
|
); |
6740
|
|
|
} |
6741
|
|
|
$params['course_code'] = $course->getCode(); |
6742
|
|
|
$params['item_id'] = $course->getId(); |
6743
|
|
|
|
6744
|
|
|
$courseFieldValue = new ExtraFieldValue('course'); |
6745
|
|
|
//$courseFieldValue->saveFieldValues($params); |
6746
|
|
|
} |
6747
|
|
|
|
6748
|
|
|
public static function addVisibilityOptions(FormValidator $form): void |
6749
|
|
|
{ |
6750
|
|
|
$group = []; |
6751
|
|
|
$group[] = $form->createElement( |
6752
|
|
|
'radio', |
6753
|
|
|
'visibility', |
6754
|
|
|
get_lang('Course access'), |
6755
|
|
|
get_lang('Public - access allowed for the whole world'), |
6756
|
|
|
Course::OPEN_WORLD |
6757
|
|
|
); |
6758
|
|
|
$group[] = $form->createElement( |
6759
|
|
|
'radio', |
6760
|
|
|
'visibility', |
6761
|
|
|
null, |
6762
|
|
|
get_lang(' Open - access allowed for users registered on the platform'), |
6763
|
|
|
Course::OPEN_PLATFORM |
6764
|
|
|
); |
6765
|
|
|
$group[] = $form->createElement( |
6766
|
|
|
'radio', |
6767
|
|
|
'visibility', |
6768
|
|
|
null, |
6769
|
|
|
get_lang('Private access (access authorized to group members only)'), |
6770
|
|
|
Course::REGISTERED |
6771
|
|
|
); |
6772
|
|
|
$group[] = $form->createElement( |
6773
|
|
|
'radio', |
6774
|
|
|
'visibility', |
6775
|
|
|
null, |
6776
|
|
|
get_lang('Closed - the course is only accessible to the teachers'), |
6777
|
|
|
Course::CLOSED |
6778
|
|
|
); |
6779
|
|
|
// The "hidden" visibility is only available to portal admins |
6780
|
|
|
if (api_is_platform_admin()) { |
6781
|
|
|
$group[] = $form->createElement( |
6782
|
|
|
'radio', |
6783
|
|
|
'visibility', |
6784
|
|
|
null, |
6785
|
|
|
get_lang('Hidden - Completely hidden to all users except the administrators'), |
6786
|
|
|
Course::HIDDEN |
6787
|
|
|
); |
6788
|
|
|
} |
6789
|
|
|
$form->addGroup($group, '', get_lang('Course access')); |
6790
|
|
|
} |
6791
|
|
|
} |
6792
|
|
|
|
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.