Test Setup Failed
Push — master ( ec638a...cb9435 )
by Julito
51:10
created

CourseManager::getUserCourseCategoryForCourse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 23
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 14
nc 2
nop 2
dl 23
loc 23
rs 9.0856
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt*/
3
4
use Chamilo\CoreBundle\Entity\ExtraField as EntityExtraField;
5
use ChamiloSession as Session;
6
//use Chamilo\CourseBundle\Manager\SettingsManager;
7
use Chamilo\CourseBundle\ToolChain;
8
use Chamilo\CoreBundle\Entity\Course;
9
use Chamilo\CourseBundle\Component\CourseCopy\CourseBuilder;
10
use Chamilo\CourseBundle\Component\CourseCopy\CourseRestorer;
11
use Chamilo\CourseBundle\Manager\SettingsManager;
12
13
/**
14
 * Class CourseManager
15
 *
16
 * This is the course library for Chamilo.
17
 *
18
 * All main course functions should be placed here.
19
 *
20
 * Many functions of this library deal with providing support for
21
 * virtual/linked/combined courses (this was already used in several universities
22
 * but not available in standard Chamilo).
23
 *
24
 * There are probably some places left with the wrong code.
25
 *
26
 * @package chamilo.library
27
 */
28
class CourseManager
29
{
30
    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
    const USER_SEPARATOR = ' |';
34
    const COURSE_FIELD_TYPE_CHECKBOX = 10;
35
    public $columns = array();
36
    public static $em;
37
    private static $manager;
38
    public static $toolList;
39
    public static $courseSettingsManager;
40
41
     /**
42
     * @param \Doctrine\ORM\EntityManager
43
     */
44
    public static function setEntityManager($em)
45
    {
46
        self::$em = $em;
47
    }
48
49
    /**
50
     * @return \Doctrine\ORM\EntityManager
51
     */
52
    public static function getEntityManager()
53
    {
54
        return self::$em;
55
    }
56
57
    /**
58
     * @return Chamilo\CoreBundle\Entity\CourseManager
59
     */
60
    public static function setCourseManager($manager)
61
    {
62
        self::$manager = $manager;
63
    }
64
65
    /**
66
     * @return SettingsManager
67
     */
68
    public static function getCourseSettingsManager()
69
    {
70
        return self::$courseSettingsManager;
71
    }
72
73
    /**
74
     * @param SettingsManager $courseSettingsManager
75
     */
76
    public static function setCourseSettingsManager($courseSettingsManager)
77
    {
78
        self::$courseSettingsManager = $courseSettingsManager;
79
    }
80
81
    /**
82
     * @return Chamilo\CoreBundle\Entity\Manager\CourseManager
83
     */
84
    public static function getManager()
85
    {
86
        return self::$manager;
87
    }
88
89
    /**
90
     * Creates a course
91
     * @param   array $params columns in the main.course table
92
     *
93
     * @return  mixed  false if the course was not created, array with the course info
94
     */
95
    public static function create_course($params, $authorId = 0)
96
    {
97
        global $_configuration;
98
        // Check portal limits
99
        $access_url_id = 1;
100
        if (api_get_multiple_access_url()) {
101
            $access_url_id = api_get_current_access_url_id();
102
        }
103
104
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
105
106
        if (isset($_configuration[$access_url_id]) && is_array($_configuration[$access_url_id])) {
107
            $return = self::checkCreateCourseAccessUrlParam(
108
                $_configuration,
109
                $access_url_id,
110
                'hosting_limit_courses',
111
                'PortalCoursesLimitReached'
112
            );
113
            if ($return != false) {
114
                return $return;
115
            }
116
            $return = self::checkCreateCourseAccessUrlParam(
117
                $_configuration,
118
                $access_url_id,
119
                'hosting_limit_active_courses',
120
                'PortalActiveCoursesLimitReached'
121
            );
122
            if ($return != false) {
123
                return $return;
124
            }
125
        }
126
127
        if (empty($params['title'])) {
128
            return false;
129
        }
130
131
        if (empty($params['wanted_code'])) {
132
            $params['wanted_code'] = $params['title'];
133
            // Check whether the requested course code has already been occupied.
134
            $substring = api_substr($params['title'], 0, self::MAX_COURSE_LENGTH_CODE);
135
            if ($substring === false || empty($substring)) {
136
                return false;
137
            } else {
138
                $params['wanted_code'] = self::generate_course_code($substring);
139
            }
140
        }
141
142
        // Create the course keys
143
        $keys = AddCourse::define_course_keys($params['wanted_code']);
144
145
        $params['exemplary_content'] = isset($params['exemplary_content']) ? $params['exemplary_content'] : false;
146
147
        if (count($keys)) {
148
            $params['code'] = $keys['currentCourseCode'];
149
            $params['visual_code'] = $keys['currentCourseId'];
150
            $params['directory'] = $keys['currentCourseRepository'];
151
152
            $course_info = api_get_course_info($params['code']);
153
154
            if (empty($course_info)) {
155
                $course_id = AddCourse::register_course($params);
156
                $course_info = api_get_course_info_by_id($course_id);
157
158
                if (!empty($course_info)) {
159
                    self::fillCourse($course_info, $params, $authorId);
160
161
                    return $course_info;
162
                }
163
            }
164
        }
165
166
        return false;
167
    }
168
169
    /**
170
     * Returns all the information of a given course code
171
     * @param string $course_code , the course code
172
     * @return array with all the fields of the course table
173
     * @deprecated Use api_get_course_info() instead
174
     * @author Patrick Cool <[email protected]>, Ghent University
175
     * @assert ('') === false
176
     */
177
    public static function get_course_information($course_code)
178
    {
179
        return Database::fetch_array(
180
            Database::query(
181
                "SELECT *, id as real_id FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
182
                WHERE code='" . Database::escape_string($course_code) . "'"), 'ASSOC'
183
        );
184
    }
185
186
    /**
187
     * Returns a list of courses. Should work with quickform syntax
188
     * @param    integer $from Offset (from the 7th = '6'). Optional.
189
     * @param    integer $howmany Number of results we want. Optional.
190
     * @param    int $orderby The column we want to order it by. Optional, defaults to first column.
191
     * @param    string $orderdirection The direction of the order (ASC or DESC). Optional, defaults to ASC.
192
     * @param    int $visibility The visibility of the course, or all by default.
193
     * @param    string $startwith If defined, only return results for which the course *title* begins with this string
194
     * @param    string $urlId The Access URL ID, if using multiple URLs
195
     * @param    bool $alsoSearchCode An extension option to indicate that we also want to search for course codes (not *only* titles)
196
     * @param    array $conditionsLike
197
     * @return array
198
     */
199
    public static function get_courses_list(
200
        $from = 0,
201
        $howmany = 0,
202
        $orderby = 1,
203
        $orderdirection = 'ASC',
204
        $visibility = -1,
205
        $startwith = '',
206
        $urlId = null,
207
        $alsoSearchCode = false,
208
        $conditionsLike = array()
209
    ) {
210
        $sql = "SELECT course.* FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . " course ";
211
212
        if (!empty($urlId)) {
213
            $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
214
            $sql .= " INNER JOIN $table url ON (url.c_id = course.id) ";
215
        }
216
217
        if (!empty($startwith)) {
218
            $sql .= "WHERE (title LIKE '" . Database::escape_string($startwith) . "%' ";
219
            if ($alsoSearchCode) {
220
                $sql .= "OR code LIKE '" . Database::escape_string($startwith) . "%' ";
221
            }
222
            $sql .= ') ';
223 View Code Duplication
            if ($visibility !== -1 && $visibility == strval(intval($visibility))) {
224
                $sql .= " AND visibility = $visibility ";
225
            }
226 View Code Duplication
        } else {
227
            $sql .= "WHERE 1 ";
228
            if ($visibility !== -1 && $visibility == strval(intval($visibility))) {
229
                $sql .= " AND visibility = $visibility ";
230
            }
231
        }
232
233
        if (!empty($urlId)) {
234
            $urlId = intval($urlId);
235
            $sql .= " AND access_url_id= $urlId";
236
        }
237
238
        $allowedFields = array(
239
            'title',
240
            'code'
241
        );
242
243
        if (count($conditionsLike) > 0) {
244
            $sql .= ' AND ';
245
            $temp_conditions = array();
246
            foreach ($conditionsLike as $field => $value) {
247
                if (!in_array($field, $allowedFields)) {
248
                    continue;
249
                }
250
                $field = Database::escape_string($field);
251
                $value = Database::escape_string($value);
252
                $simple_like = false;
253 View Code Duplication
                if ($simple_like) {
254
                    $temp_conditions[] = $field . " LIKE '$value%'";
255
                } else {
256
                    $temp_conditions[] = $field . ' LIKE \'%' . $value . '%\'';
257
                }
258
            }
259
            $condition = ' AND ';
260
            if (!empty($temp_conditions)) {
261
                $sql .= implode(' ' . $condition . ' ', $temp_conditions);
262
            }
263
        }
264
265
        if (!empty($orderby)) {
266
            $sql .= " ORDER BY " . Database::escape_string($orderby) . " ";
267
        } else {
268
            $sql .= " ORDER BY 1 ";
269
        }
270
271
        if (!in_array($orderdirection, array('ASC', 'DESC'))) {
272
            $sql .= 'ASC';
273
        } else {
274
            $sql .= ($orderdirection == 'ASC' ? 'ASC' : 'DESC');
275
        }
276
277
        if (!empty($howmany) && is_int($howmany) and $howmany > 0) {
278
            $sql .= ' LIMIT ' . Database::escape_string($howmany);
279
        } else {
280
            $sql .= ' LIMIT 1000000'; //virtually no limit
281
        }
282
        if (!empty($from)) {
283
            $from = intval($from);
284
            $sql .= ' OFFSET ' . intval($from);
285
        } else {
286
            $sql .= ' OFFSET 0';
287
        }
288
289
        $data = [];
290
        $res = Database::query($sql);
291
        if (Database::num_rows($res) > 0) {
292
            while ($row = Database::fetch_array($res, 'ASSOC')) {
293
                $data[] = $row;
294
            }
295
        }
296
297
        return $data;
298
    }
299
300
    /**
301
     * Returns the status of a user in a course, which is COURSEMANAGER or STUDENT.
302
     * @param   int $userId
303
     * @param   int $courseId
304
     *
305
     * @return int|bool the status of the user in that course (or false if the user is not in that course)
306
     */
307
    public static function getUserInCourseStatus($userId, $courseId)
308
    {
309
        $courseId = (int) $courseId;
310
        if (empty($courseId)) {
311
            return false;
312
        }
313
314
        $result = Database::fetch_array(
315
            Database::query(
316
                "SELECT status FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
317
                WHERE
318
                    c_id  = $courseId AND
319
                    user_id = " . intval($userId)
320
            )
321
        );
322
323
        return $result['status'];
324
    }
325
326
    /**
327
     * @param int $userId
328
     * @param int $courseId
329
     *
330
     * @return mixed
331
     */
332 View Code Duplication
    public static function getUserCourseInfo($userId, $courseId)
333
    {
334
335
        $result = Database::fetch_array(
336
            Database::query("
337
                SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
338
                WHERE
339
                    c_id  = '" . intval($courseId). "' AND
340
                    user_id = " . intval($userId)
341
            )
342
        );
343
344
        return $result;
345
    }
346
347
    /**
348
     * @param int  $userId
349
     * @param int  $courseId
350
     * @param bool $isTutor
351
     *
352
     * @return bool
353
     */
354
    public static function updateUserCourseTutor($userId, $courseId, $isTutor)
355
    {
356
        $table = Database::escape_string(TABLE_MAIN_COURSE_USER);
357
358
        $courseId = intval($courseId);
359
        $isTutor = intval($isTutor);
360
361
        $sql = "UPDATE $table SET is_tutor = '".$isTutor."'
362
			    WHERE
363
				    user_id = '".$userId."' AND
364
				    c_id = '".$courseId."'";
365
366
        $result = Database::query($sql);
367
368
        if (Database::affected_rows($result) > 0) {
369
            return true;
370
        } else {
371
            return false;
372
        }
373
    }
374
375
    /**
376
     * @param int $user_id
377
     * @param int $courseId
378
     *
379
     * @return mixed
380
     */
381 View Code Duplication
    public static function get_tutor_in_course_status($user_id, $courseId)
382
    {
383
        $result = Database::fetch_array(
384
            Database::query("
385
                SELECT is_tutor
386
                FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
387
                WHERE
388
                    c_id = '" . Database::escape_string($courseId) . "' AND
389
                    user_id = " . intval($user_id)
390
            )
391
        );
392
393
        return $result['is_tutor'];
394
    }
395
396
    /**
397
     * Unsubscribe one or more users from a course
398
     *
399
     * @param   mixed   user_id or an array with user ids
400
     * @param   string  course code
401
     * @param   int     session id
402
     * @assert ('', '') === false
403
     *
404
     */
405
    public static function unsubscribe_user($user_id, $course_code, $session_id = 0)
406
    {
407
        if (!is_array($user_id)) {
408
            $user_id = array($user_id);
409
        }
410
411
        if (count($user_id) == 0) {
412
            return;
413
        }
414
415
        if (!empty($session_id)) {
416
            $session_id = intval($session_id);
417
        } else {
418
            $session_id = api_get_session_id();
419
        }
420
421
        $user_list = array();
422
423
        // Cleaning the $user_id variable
424
        if (is_array($user_id)) {
425
            $new_user_id_list = array();
426
            foreach ($user_id as $my_user_id) {
427
                $new_user_id_list[] = intval($my_user_id);
428
            }
429
            $new_user_id_list = array_filter($new_user_id_list);
430
            $user_list = $new_user_id_list;
431
            $user_ids = implode(',', $new_user_id_list);
432
        } else {
433
            $user_ids = intval($user_id);
434
            $user_list[] = $user_id;
435
        }
436
437
        $course_info = api_get_course_info($course_code);
438
        $course_id = $course_info['real_id'];
439
440
        // Unsubscribe user from all groups in the course.
441
        $sql = "DELETE FROM " . Database::get_course_table(TABLE_GROUP_USER) . "
442
                WHERE c_id = $course_id AND user_id IN (" . $user_ids . ")";
443
        Database::query($sql);
444
        $sql = "DELETE FROM " . Database::get_course_table(TABLE_GROUP_TUTOR) . "
445
                WHERE c_id = $course_id AND user_id IN (" . $user_ids . ")";
446
        Database::query($sql);
447
448
        // Erase user student publications (works) in the course - by André Boivin
449
450
        if (!empty($user_list)) {
451
            require_once api_get_path(SYS_CODE_PATH) . 'work/work.lib.php';
452
            foreach ($user_list as $userId) {
453
                // Getting all work from user
454
                $workList = getWorkPerUser($userId);
455
                if (!empty($workList)) {
456
                    foreach ($workList as $work) {
457
                        $work = $work['work'];
458
                        // Getting user results
459
                        if (!empty($work->user_results)) {
460
                            foreach ($work->user_results as $workSent) {
461
                                deleteWorkItem($workSent['id'], $course_info);
462
                            }
463
                        }
464
                    }
465
                }
466
            }
467
        }
468
469
        // Unsubscribe user from all blogs in the course.
470
        Database::query("DELETE FROM " . Database::get_course_table(TABLE_BLOGS_REL_USER) . " WHERE c_id = $course_id AND  user_id IN (" . $user_ids . ")");
471
        Database::query("DELETE FROM " . Database::get_course_table(TABLE_BLOGS_TASKS_REL_USER) . " WHERE c_id = $course_id AND  user_id IN (" . $user_ids . ")");
472
473
        // Deleting users in forum_notification and mailqueue course tables
474
        $sql = "DELETE FROM  " . Database::get_course_table(TABLE_FORUM_NOTIFICATION) . "
475
                WHERE c_id = $course_id AND user_id IN (" . $user_ids . ")";
476
        Database::query($sql);
477
478
        $sql = "DELETE FROM " . Database::get_course_table(TABLE_FORUM_MAIL_QUEUE) . "
479
                WHERE c_id = $course_id AND user_id IN (" . $user_ids . ")";
480
        Database::query($sql);
481
482
        // Unsubscribe user from the course.
483
        if (!empty($session_id)) {
484
485
            // Delete in table session_rel_course_rel_user
486
            $sql = "DELETE FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
487
                    WHERE
488
                        session_id ='" . $session_id . "' AND
489
                        c_id = '" . $course_id . "' AND
490
                        user_id IN ($user_ids)";
491
            Database::query($sql);
492
493
            foreach ($user_list as $uid) {
494
                // check if a user is register in the session with other course
495
                $sql = "SELECT user_id FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
496
                        WHERE session_id='$session_id' AND user_id='$uid'";
497
                $rs = Database::query($sql);
498
499
                if (Database::num_rows($rs) == 0) {
500
                    // Delete in table session_rel_user
501
                    $sql = "DELETE FROM " . Database::get_main_table(TABLE_MAIN_SESSION_USER) . "
502
                            WHERE
503
                                session_id ='" . $session_id . "' AND
504
                                user_id = '$uid' AND
505
                                relation_type<>" . SESSION_RELATION_TYPE_RRHH . "";
506
                    Database::query($sql);
507
                }
508
            }
509
510
            // Update the table session
511
            $sql = "SELECT COUNT(*) FROM " . Database::get_main_table(TABLE_MAIN_SESSION_USER) . "
512
                    WHERE session_id = '" . $session_id . "' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
513
            $row = Database::fetch_array(Database::query($sql));
514
            $count = $row[0];
515
            // number of users by session
516
            $sql = "UPDATE " . Database::get_main_table(TABLE_MAIN_SESSION) . " SET nbr_users = '$count'
517
                    WHERE id = '" . $session_id . "'";
518
            Database::query($sql);
519
520
            // Update the table session_rel_course
521
            $sql = "SELECT COUNT(*) FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
522
                    WHERE session_id = '$session_id' AND c_id = '$course_id' AND status<>2";
523
            $row = Database::fetch_array(@Database::query($sql));
524
            $count = $row[0];
525
526
            // number of users by session and course
527
            $sql = "UPDATE " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE) . "
528
                    SET nbr_users = '$count'
529
                    WHERE session_id = '$session_id' AND c_id = '$course_id'";
530
            Database::query($sql);
531
532
        } else {
533
            $sql = "DELETE FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
534
                    WHERE
535
                        user_id IN (" . $user_ids . ") AND
536
                        relation_type<>" . COURSE_RELATION_TYPE_RRHH . " AND
537
                        c_id = '" . $course_id . "'";
538
            Database::query($sql);
539
540
            // add event to system log
541
            $user_id = api_get_user_id();
542
543
            Event::addEvent(
544
                LOG_UNSUBSCRIBE_USER_FROM_COURSE,
545
                LOG_COURSE_CODE,
546
                $course_code,
547
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
548
                $user_id
549
            );
550
551
            foreach ($user_list as $userId) {
552
                $userInfo = api_get_user_info($userId);
553
                Event::addEvent(
554
                    LOG_UNSUBSCRIBE_USER_FROM_COURSE,
555
                    LOG_USER_OBJECT,
556
                    $userInfo,
557
                    api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
558
                    $user_id
559
                );
560
            }
561
        }
562
    }
563
564
    /**
565
     * Subscribe a user to a course. No checks are performed here to see if
566
     * course subscription is allowed.
567
     * @param   int     $user_id
568
     * @param   string  $course_code
569
     * @param   int     $status (STUDENT, COURSEMANAGER, COURSE_ADMIN, NORMAL_COURSE_MEMBER)
570
     * @param   int $session_id
571
     * @param   int $userCourseCategoryId
572
     *
573
     * @return  bool    True on success, false on failure
574
     * @see add_user_to_course
575
     * @assert ('', '') === false
576
     */
577
    public static function subscribe_user(
578
        $user_id,
579
        $course_code,
580
        $status = STUDENT,
581
        $session_id = 0,
582
        $userCourseCategoryId = 0
583
    ) {
584
        if ($user_id != strval(intval($user_id))) {
585
            return false; //detected possible SQL injection
586
        }
587
588
        $course_code = Database::escape_string($course_code);
589
        $courseInfo = api_get_course_info($course_code);
590
        $courseId = $courseInfo['real_id'];
591
        $courseCode = $courseInfo['code'];
592
        $userCourseCategoryId = intval($userCourseCategoryId);
593
594
        if (empty($user_id) || empty($course_code)) {
595
            return false;
596
        }
597
598
        if (!empty($session_id)) {
599
            $session_id = intval($session_id);
600
        } else {
601
            $session_id = api_get_session_id();
602
        }
603
604
        $status = ($status == STUDENT || $status == COURSEMANAGER) ? $status : STUDENT;
605
606
        // A preliminary check whether the user has bben already registered on the platform.
607
        $sql = "SELECT status FROM " . Database::get_main_table(TABLE_MAIN_USER) . "
608
                WHERE user_id = '$user_id' ";
609
        if (Database::num_rows(Database::query($sql)) == 0) {
610
            return false; // The user has not been registered to the platform.
611
        }
612
613
        // Check whether the user has not been already subscribed to the course.
614
        $sql = "SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "                    
615
                WHERE 
616
                    user_id = '$user_id' AND 
617
                    relation_type <> " . COURSE_RELATION_TYPE_RRHH . " AND 
618
                    c_id = $courseId
619
                ";
620
        if (empty($session_id)) {
621
            if (Database::num_rows(Database::query($sql)) > 0) {
622
                // The user has been already subscribed to the course.
623
                return false;
624
            }
625
        }
626
627
        if (!empty($session_id)) {
628
            SessionManager::subscribe_users_to_session_course(array($user_id), $session_id, $courseCode);
629
        } else {
630
            self::add_user_to_course(
631
                $user_id,
632
                $courseCode,
633
                $status,
634
                $userCourseCategoryId
635
            );
636
637
            // Add event to the system log
638
            Event::addEvent(
639
                LOG_SUBSCRIBE_USER_TO_COURSE,
640
                LOG_COURSE_CODE,
641
                $course_code,
642
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
643
                api_get_user_id()
644
            );
645
646
            $user_info = api_get_user_info($user_id);
647
            Event::addEvent(
648
                LOG_SUBSCRIBE_USER_TO_COURSE,
649
                LOG_USER_OBJECT,
650
                $user_info,
651
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
652
                api_get_user_id()
653
            );
654
        }
655
656
        return true;
657
    }
658
659
    /**
660
     * Get the course id based on the original id and field name in the
661
     * extra fields. Returns 0 if course was not found
662
     *
663
     * @param string $original_course_id_value
664
     * @param string $original_course_id_name
665
     * @return int Course id
666
     *
667
     * @assert ('', '') === false
668
     */
669
    public static function get_course_code_from_original_id($original_course_id_value, $original_course_id_name)
670
    {
671
        $t_cfv = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
672
        $table_field = Database::get_main_table(TABLE_EXTRA_FIELD);
673
        $extraFieldType = EntityExtraField::COURSE_FIELD_TYPE;
674
675
        $original_course_id_value = Database::escape_string($original_course_id_value);
676
        $original_course_id_name = Database::escape_string($original_course_id_name);
677
678
        $sql = "SELECT item_id
679
                FROM $table_field cf
680
                INNER JOIN $t_cfv cfv
681
                ON cfv.field_id=cf.id
682
                WHERE
683
                    variable = '$original_course_id_name' AND
684
                    value = '$original_course_id_value' AND
685
                    cf.extra_field_type = $extraFieldType
686
                ";
687
        $res = Database::query($sql);
688
        $row = Database::fetch_object($res);
689
        if ($row) {
690
            return $row->item_id;
691
        } else {
692
            return 0;
693
        }
694
    }
695
696
    /**
697
     * Gets the course code from the course id. Returns null if course id was not found
698
     *
699
     * @param int $id Course id
700
     * @return string Course code
701
     * @assert ('') === false
702
     */
703
    public static function get_course_code_from_course_id($id)
704
    {
705
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
706
        $id = intval($id);
707
        $sql = "SELECT code FROM $table WHERE id = '$id' ";
708
        $res = Database::query($sql);
709
        $row = Database::fetch_object($res);
710
        if ($row) {
711
            return $row->code;
712
        } else {
713
            return null;
714
        }
715
    }
716
717
    /**
718
     * Subscribe a user $user_id to a course defined by $courseCode.
719
     * @author Hugues Peeters
720
     * @author Roan Embrechts
721
     *
722
     * @param   int $user_id the id of the user
723
     * @param   string $courseCode the course code
724
     * @param   int $status (optional) The user's status in the course
725
     * @param   int $userCourseCategoryId
726
     * @param   int The user category in which this subscription will be classified
727
     *
728
     * @return false|string true if subscription succeeds, boolean false otherwise.
729
     * @assert ('', '') === false
730
     */
731
    public static function add_user_to_course(
732
        $user_id,
733
        $courseCode,
734
        $status = STUDENT,
735
        $userCourseCategoryId = 0
736
    ) {
737
        $debug = false;
738
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
739
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
740
        $course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
741
742
        $status = ($status == STUDENT || $status == COURSEMANAGER) ? $status : STUDENT;
743 View Code Duplication
        if (empty($user_id) || empty($courseCode) || ($user_id != strval(intval($user_id)))) {
744
            return false;
745
        }
746
747
        $courseCode = Database::escape_string($courseCode);
748
        $courseInfo = api_get_course_info($courseCode);
749
        $courseId = $courseInfo['real_id'];
750
751
        // Check in advance whether the user has already been registered on the platform.
752
        $sql = "SELECT status FROM " . $user_table . " WHERE user_id = $user_id ";
753 View Code Duplication
        if (Database::num_rows(Database::query($sql)) == 0) {
754
            if ($debug) {
755
                error_log('The user has not been registered to the platform');
756
            }
757
            return false; // The user has not been registered to the platform.
758
        }
759
760
        // Check whether the user has already been subscribed to this course.
761
        $sql = "SELECT * FROM $course_user_table
762
                WHERE
763
                    user_id = $user_id AND
764
                    relation_type <> " . COURSE_RELATION_TYPE_RRHH . " AND
765
                    c_id = $courseId";
766 View Code Duplication
        if (Database::num_rows(Database::query($sql)) > 0) {
767
            if ($debug) {
768
                error_log('The user has been already subscribed to the course');
769
            }
770
            return false; // The user has been subscribed to the course.
771
        }
772
773
        if (!api_is_course_admin()) {
774
            // Check in advance whether subscription is allowed or not for this course.
775
            $sql = "SELECT code, visibility FROM $course_table
776
                    WHERE id = $courseId AND subscribe = '" . SUBSCRIBE_NOT_ALLOWED . "'";
777 View Code Duplication
            if (Database::num_rows(Database::query($sql)) > 0) {
778
                if ($debug) {
779
                    error_log('Subscription is not allowed for this course');
780
                }
781
                return false; // Subscription is not allowed for this course.
782
            }
783
        }
784
785
        // Ok, subscribe the user.
786
        $max_sort = api_max_sort_value('0', $user_id);
787
        $params = [
788
            'c_id' => $courseId,
789
            'user_id' => $user_id,
790
            'status' => $status,
791
            'sort' => $max_sort + 1,
792
            'relation_type' => 0,
793
            'user_course_cat' => (int) $userCourseCategoryId
794
        ];
795
        $insertId = Database::insert($course_user_table, $params);
796
797
        return $insertId;
798
    }
799
800
    /**
801
     * Add the user $userId visibility to the course $courseCode in the catalogue.
802
     * @author David Nos (https://github.com/dnos)
803
     *
804
     * @param  int $userId the id of the user
805
     * @param  string $courseCode the course code
806
     * @param  int $visible (optional) The course visibility in the catalogue to the user (1=visible, 0=invisible)
807
     *
808
     * @return boolean true if added succesfully, false otherwise.
809
     */
810
    public static function addUserVisibilityToCourseInCatalogue($userId, $courseCode, $visible = 1)
811
    {
812
        $debug = false;
813
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
814
        $courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER);
815
816 View Code Duplication
        if (empty($userId) || empty($courseCode) || ($userId != strval(intval($userId)))) {
817
            return false;
818
        }
819
820
        $courseCode = Database::escape_string($courseCode);
821
        $courseInfo = api_get_course_info($courseCode);
822
        $courseId = $courseInfo['real_id'];
823
824
        // Check in advance whether the user has already been registered on the platform.
825
        $sql = "SELECT status FROM " . $userTable . " WHERE user_id = $userId ";
826
        if (Database::num_rows(Database::query($sql)) == 0) {
827
            if ($debug) {
828
                error_log('The user has not been registered to the platform');
829
            }
830
            return false; // The user has not been registered to the platform.
831
        }
832
833
        // Check whether the user has already been registered to the course visibility in the catalogue.
834
        $sql = "SELECT * FROM $courseUserTable
835
                WHERE
836
                    user_id = $userId AND
837
                    visible = " . $visible . " AND
838
                    c_id = $courseId";
839
        if (Database::num_rows(Database::query($sql)) > 0) {
840
            if ($debug) {
841
                error_log('The user has been already registered to the course visibility in the catalogue');
842
            }
843
            return true; // The visibility of the user to the course in the catalogue does already exist.
844
        }
845
846
        // Register the user visibility to course in catalogue.
847
        $params = [
848
            'user_id' => $userId,
849
            'c_id' => $courseId,
850
            'visible' => $visible
851
        ];
852
        $insertId = Database::insert($courseUserTable, $params);
853
854
        return $insertId;
855
    }
856
857
858
    /**
859
     * Remove the user $userId visibility to the course $courseCode in the catalogue.
860
     * @author David Nos (https://github.com/dnos)
861
     *
862
     * @param  int $userId the id of the user
863
     * @param  string $courseCode the course code
864
     * @param  int $visible (optional) The course visibility in the catalogue to the user (1=visible, 0=invisible)
865
     *
866
     * @return boolean true if removed succesfully or register not found, false otherwise.
867
     */
868
    public static function removeUserVisibilityToCourseInCatalogue($userId, $courseCode, $visible = 1)
869
    {
870
        $courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER);
871
872 View Code Duplication
        if (empty($userId) || empty($courseCode) || ($userId != strval(intval($userId)))) {
873
            return false;
874
        }
875
876
        $courseCode = Database::escape_string($courseCode);
877
        $courseInfo = api_get_course_info($courseCode);
878
        $courseId = $courseInfo['real_id'];
879
880
        // Check whether the user has already been registered to the course visibility in the catalogue.
881
        $sql = "SELECT * FROM $courseUserTable
882
                WHERE
883
                    user_id = $userId AND
884
                    visible = " . $visible . " AND
885
                    c_id = $courseId";
886
        if (Database::num_rows(Database::query($sql)) > 0) {
887
            $cond = array(
888
                'user_id = ? AND c_id = ? AND visible = ? ' => array(
889
                    $userId,
890
                    $courseId,
891
                    $visible
892
                )
893
            );
894
            return Database::delete($courseUserTable, $cond);
895
        } else {
896
            return true; // Register does not exist
897
        }
898
    }
899
900
    /**
901
     * @return boolean if there already are one or more courses
902
     *  with the same code OR visual_code (visualcode), false otherwise
903
     */
904
    public static function course_code_exists($wanted_course_code)
905
    {
906
        $wanted_course_code = Database::escape_string($wanted_course_code);
907
        $sql = "SELECT COUNT(*) as number
908
                FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
909
                WHERE code = '$wanted_course_code' OR visual_code = '$wanted_course_code'";
910
        $result = Database::fetch_array(Database::query($sql));
911
912
        return $result['number'] > 0;
913
    }
914
915
    /**
916
     * Get course list as coach
917
     *
918
     * @param int $user_id
919
     * @param bool $include_courses_in_sessions
920
     * @return array Course list
921
     *
922
     **/
923
    public static function get_course_list_as_coach($user_id, $include_courses_in_sessions = false)
924
    {
925
        // 1. Getting courses as teacher (No session)
926
        $courses_temp = self::get_course_list_of_user_as_course_admin($user_id);
927
        $courseList = array();
928
929
        if (!empty($courses_temp)) {
930
            foreach ($courses_temp as $course_item) {
931
                $courseList[0][$course_item['code']] = $course_item['code'];
932
            }
933
        }
934
935
        //2. Include courses in sessions
936
        if ($include_courses_in_sessions) {
937
            $sessions = Tracking::get_sessions_coached_by_user($user_id);
938
939
            if (!empty($sessions)) {
940
                foreach ($sessions as $session_item) {
941
                    $courses = Tracking:: get_courses_followed_by_coach($user_id, $session_item['id']);
942
                    if (is_array($courses)) {
943
                        foreach ($courses as $course_item) {
944
                            $courseList[$session_item['id']][$course_item] = $course_item;
945
                        }
946
                    }
947
                }
948
            }
949
        }
950
951
        return $courseList;
952
    }
953
954
    /**
955
     * @param int $user_id
956
     * @param bool $include_sessions
957
     * @return array
958
     */
959
    public static function get_user_list_from_courses_as_coach($user_id, $include_sessions = true)
960
    {
961
        $students_in_courses = array();
962
        $sessions = self::get_course_list_as_coach($user_id, true);
963
964
        if (!empty($sessions)) {
965
            foreach ($sessions as $session_id => $courses) {
966
                if (!$include_sessions) {
967
                    if (!empty($session_id)) {
968
                        continue;
969
                    }
970
                }
971
                if (empty($session_id)) {
972
                    foreach ($courses as $course_code) {
973
                        $students_in_course = self::get_user_list_from_course_code($course_code);
974
975
                        foreach ($students_in_course as $user_item) {
0 ignored issues
show
Bug introduced by
The expression $students_in_course of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
976
                            //Only students
977
                            if ($user_item['status_rel'] == STUDENT) {
978
                                $students_in_courses[$user_item['user_id']] = $user_item['user_id'];
979
                            }
980
                        }
981
                    }
982
                } else {
983
                    $students_in_course = SessionManager::get_users_by_session($session_id, '0');
984
                    if (is_array($students_in_course)) {
985
                        foreach ($students_in_course as $user_item) {
986
                            $students_in_courses[$user_item['user_id']] = $user_item['user_id'];
987
                        }
988
                    }
989
                }
990
            }
991
        }
992
993
        $students = Tracking:: get_student_followed_by_coach($user_id);
994
        if (!empty($students_in_courses)) {
995
            if (!empty($students)) {
996
                $students = array_merge($students, $students_in_courses);
997
            } else {
998
                $students = $students_in_courses;
999
            }
1000
        }
1001
1002
        if (!empty($students)) {
1003
            $students = array_unique($students);
1004
        }
1005
        return $students;
1006
    }
1007
1008
    /**
1009
     * @param int $user_id
1010
     * @param string $startsWith Optional
1011
     * @return array An array with the course info of all the courses (real and virtual)
1012
     * of which the current user is course admin.
1013
     */
1014
    public static function get_course_list_of_user_as_course_admin($user_id, $startsWith = null)
1015
    {
1016
        if ($user_id != strval(intval($user_id))) {
1017
            return array();
1018
        }
1019
1020
        // Definitions database tables and variables
1021
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
1022
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1023
        $user_id = intval($user_id);
1024
        $data = array();
1025
1026
        $sql = "SELECT
1027
                    course.code,
1028
                    course.title,
1029
                    course.id,
1030
                    course.id as real_id,
1031
                    course.category_code
1032
                FROM $tbl_course_user as course_rel_user
1033
                INNER JOIN $tbl_course as course
1034
                ON course.id = course_rel_user.c_id
1035
                WHERE
1036
                    course_rel_user.user_id='$user_id' AND
1037
                    course_rel_user.status='1'
1038
        ";
1039
1040
        if (api_get_multiple_access_url()) {
1041
            $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
1042
            $access_url_id = api_get_current_access_url_id();
1043
            if ($access_url_id != -1) {
1044
                $sql = "
1045
                    SELECT
1046
                        course.code,
1047
                        course.title,
1048
                        course.id,
1049
                        course.id as real_id
1050
                    FROM $tbl_course_user as course_rel_user
1051
                    INNER JOIN $tbl_course as course
1052
                    ON course.id = course_rel_user.c_id
1053
                    INNER JOIN $tbl_course_rel_access_url course_rel_url
1054
                    ON (course_rel_url.c_id = course.id)
1055
                    WHERE
1056
                        access_url_id = $access_url_id  AND
1057
                        course_rel_user.user_id = '$user_id' AND
1058
                        course_rel_user.status = '1'
1059
                ";
1060
            }
1061
        }
1062
1063
        if (!empty($startsWith)) {
1064
            $startsWith = Database::escape_string($startsWith);
1065
1066
            $sql .= " AND (course.title LIKE '$startsWith%' OR course.code LIKE '$startsWith%')";
1067
        }
1068
1069
        $sql .= ' ORDER BY course.title';
1070
1071
        $result_nb_cours = Database::query($sql);
1072
        if (Database::num_rows($result_nb_cours) > 0) {
1073
            while ($row = Database::fetch_array($result_nb_cours, 'ASSOC')) {
1074
                $data[$row['id']] = $row;
1075
            }
1076
        }
1077
1078
        return $data;
1079
    }
1080
1081
    /**
1082
     * @param int $userId
1083
     * @param array $courseInfo
1084
     * @return boolean|null
1085
     */
1086
    public static function isUserSubscribedInCourseAsDrh($userId, $courseInfo)
1087
    {
1088
        $userId = intval($userId);
1089
1090
        if (!api_is_drh()) {
1091
            return false;
1092
        }
1093
1094
        if (empty($courseInfo) || empty($userId)) {
1095
            return false;
1096
        }
1097
1098
        $courseId = intval($courseInfo['real_id']);
1099
        $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
1100
1101
        $sql = "SELECT * FROM $table
1102
                WHERE
1103
                    user_id = $userId AND
1104
                    relation_type = " . COURSE_RELATION_TYPE_RRHH . " AND
1105
                    c_id = $courseId";
1106
1107
        $result = Database::fetch_array(Database::query($sql));
1108
1109
        if (!empty($result)) {
1110
            // The user has been registered in this course.
1111
            return true;
1112
        }
1113
    }
1114
1115
    /**
1116
     * Check if user is subscribed inside a course
1117
     * @param  int $user_id
1118
     * @param  string $course_code , if this parameter is null, it'll check for all courses
1119
     * @param  bool $in_a_session True for checking inside sessions too, by default is not checked
1120
     * @return bool   $session_id true if the user is registered in the course, false otherwise
1121
     */
1122
    public static function is_user_subscribed_in_course(
1123
        $user_id,
1124
        $course_code = null,
1125
        $in_a_session = false,
1126
        $session_id = null
1127
    ) {
1128
        $user_id = intval($user_id);
1129
1130
        if (empty($session_id)) {
1131
            $session_id = api_get_session_id();
1132
        } else {
1133
            $session_id = intval($session_id);
1134
        }
1135
1136
        $condition_course = '';
1137
        if (isset($course_code)) {
1138
            $courseInfo = api_get_course_info($course_code);
1139
            if (empty($courseInfo)) {
1140
                return false;
1141
            }
1142
            $courseId = $courseInfo['real_id'];
1143
            $condition_course = ' AND c_id = ' . $courseId;
1144
        }
1145
1146
        $sql = "SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
1147
                WHERE
1148
                    user_id = $user_id AND
1149
                    relation_type<>" . COURSE_RELATION_TYPE_RRHH . "
1150
                    $condition_course ";
1151
1152
        $result = Database::fetch_array(Database::query($sql));
1153
1154
        if (!empty($result)) {
1155
            // The user has been registered in this course.
1156
            return true;
1157
        }
1158
1159
        if (!$in_a_session) {
1160
            // The user has not been registered in this course.
1161
            return false;
1162
        }
1163
1164
        $tableSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1165
        $sql = 'SELECT 1 FROM ' . $tableSessionCourseUser .
1166
            ' WHERE user_id = ' . $user_id . ' ' . $condition_course;
1167
        if (Database::num_rows(Database::query($sql)) > 0) {
1168
            return true;
1169
        }
1170
1171
        $sql = 'SELECT 1 FROM ' . $tableSessionCourseUser .
1172
            ' WHERE user_id = ' . $user_id . ' AND status=2 ' . $condition_course;
1173
        if (Database::num_rows(Database::query($sql)) > 0) {
1174
            return true;
1175
        }
1176
1177
        $sql = 'SELECT 1 FROM ' . Database::get_main_table(TABLE_MAIN_SESSION) .
1178
            ' WHERE id = ' . $session_id . ' AND id_coach=' . $user_id;
1179
1180
        if (Database::num_rows(Database::query($sql)) > 0) {
1181
            return true;
1182
        }
1183
1184
        return false;
1185
    }
1186
1187
    /**
1188
     *    Is the user a teacher in the given course?
1189
     *
1190
     * @param integer $user_id , the id (int) of the user
1191
     * @param $course_code , the course code
1192
     *
1193
     * @return boolean if the user is a teacher in the course, false otherwise
1194
     */
1195
    public static function is_course_teacher($user_id, $course_code)
1196
    {
1197
        if ($user_id != strval(intval($user_id))) {
1198
            return false;
1199
        }
1200
1201
        $courseInfo = api_get_course_info($course_code);
1202
        $courseId = $courseInfo['real_id'];
1203
1204
        $result = Database::query(
1205
            'SELECT status FROM ' . Database::get_main_table(TABLE_MAIN_COURSE_USER) .
1206
            ' WHERE c_id = ' . $courseId . ' AND user_id = ' . $user_id . ''
1207
        );
1208
1209
        if (Database::num_rows($result) > 0) {
1210
            return Database::result($result, 0, 'status') == 1;
1211
        }
1212
1213
        return false;
1214
    }
1215
1216
    /**
1217
     *    Is the user subscribed in the real course or linked courses?
1218
     *
1219
     * @param int the id of the user
1220
     * @param int $courseId
1221
     * @deprecated linked_courses definition doesn't exists
1222
     * @return boolean if the user is registered in the real course or linked courses, false otherwise
1223
     */
1224
    public static function is_user_subscribed_in_real_or_linked_course($user_id, $courseId, $session_id = '')
1225
    {
1226
        if ($user_id != strval(intval($user_id))) {
1227
            return false;
1228
        }
1229
1230
        $courseId = intval($courseId);
1231
1232
        if ($session_id == '') {
1233
            $result = Database::fetch_array(
1234
                Database::query(
1235
                    "SELECT *
1236
                    FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . " course
1237
                    LEFT JOIN " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . " course_user
1238
                    ON course.id = course_user.c_id
1239
                    WHERE
1240
                        course_user.user_id = '$user_id' AND
1241
                        course_user.relation_type<>" . COURSE_RELATION_TYPE_RRHH . " AND
1242
                        ( course.id = '$courseId')"
1243
                )
1244
            );
1245
            return !empty($result);
1246
        }
1247
1248
        $session_id = intval($session_id);
1249
1250
        // From here we trust session id.
1251
        // Is he/she subscribed to the session's course?
1252
1253
        // A user?
1254 View Code Duplication
        if (Database::num_rows(Database::query("SELECT user_id
1255
                FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
1256
                WHERE session_id='" . $session_id . "'
1257
                AND user_id ='$user_id'"))
1258
        ) {
1259
            return true;
1260
        }
1261
1262
        // A course coach?
1263 View Code Duplication
        if (Database::num_rows(Database::query("SELECT user_id
1264
                FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . "
1265
                WHERE session_id='" . $session_id . "'
1266
                AND user_id = '$user_id' AND status = 2
1267
                AND c_id ='$courseId'"))
1268
        ) {
1269
            return true;
1270
        }
1271
1272
        // A session coach?
1273 View Code Duplication
        if (Database::num_rows(Database::query("SELECT id_coach
1274
                FROM " . Database::get_main_table(TABLE_MAIN_SESSION) . " AS session
1275
                WHERE session.id='" . $session_id . "'
1276
                AND id_coach='$user_id'"))
1277
        ) {
1278
            return true;
1279
        }
1280
1281
        return false;
1282
    }
1283
1284
    /**
1285
     * Return user info array of all users registered in a course
1286
     * This only returns the users that are registered in this actual course, not linked courses.
1287
     * @param string $course_code
1288
     * @param int $session_id
1289
     * @param string $limit
1290
     * @param string $order_by the field to order the users by.
1291
     * Valid values are 'lastname', 'firstname', 'username', 'email', 'official_code' OR a part of a SQL statement
1292
     * that starts with ORDER BY ...
1293
     * @param integer|null $filter_by_status if using the session_id: 0 or 2 (student, coach),
1294
     * if using session_id = 0 STUDENT or COURSEMANAGER
1295
     * @param boolean|null $return_count
1296
     * @param bool $add_reports
1297
     * @param bool $resumed_report
1298
     * @param array $extra_field
1299
     * @param array $courseCodeList
1300
     * @param array $userIdList
1301
     * @param string $filterByActive
1302
     * @param array $sessionIdList
1303
     * @return array|int
1304
     */
1305
    public static function get_user_list_from_course_code(
1306
        $course_code = null,
1307
        $session_id = 0,
1308
        $limit = null,
1309
        $order_by = null,
1310
        $filter_by_status = null,
1311
        $return_count = null,
1312
        $add_reports = false,
1313
        $resumed_report = false,
1314
        $extra_field = array(),
1315
        $courseCodeList = array(),
1316
        $userIdList = array(),
1317
        $filterByActive = null,
1318
        $sessionIdList = array()
1319
    ) {
1320
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
1321
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1322
1323
        $session_id = intval($session_id);
1324
        $course_code = Database::escape_string($course_code);
1325
        $courseInfo = api_get_course_info($course_code);
1326
        $courseId = 0;
1327
        if (!empty($courseInfo)) {
1328
            $courseId = $courseInfo['real_id'];
1329
        }
1330
1331
        $where = array();
1332
        if (empty($order_by)) {
1333
            $order_by = 'user.lastname, user.firstname';
1334
            if (api_is_western_name_order()) {
1335
                $order_by = 'user.firstname, user.lastname';
1336
            }
1337
        }
1338
1339
        // if the $order_by does not contain 'ORDER BY'
1340
        // we have to check if it is a valid field that can be sorted on
1341
        if (!strstr($order_by, 'ORDER BY')) {
1342
            if (!empty($order_by)) {
1343
                $order_by = 'ORDER BY ' . $order_by;
1344
            } else {
1345
                $order_by = '';
1346
            }
1347
        }
1348
1349
        $filter_by_status_condition = null;
1350
1351
        if (!empty($session_id) || !empty($sessionIdList)) {
1352
            $sql = 'SELECT DISTINCT
1353
                        user.user_id,
1354
                        user.email,
1355
                        session_course_user.status as status_session,
1356
                        session_id,
1357
                        user.*,
1358
                        course.*,
1359
                        session.name as session_name
1360
                    ';
1361
            if ($return_count) {
1362
                $sql = " SELECT COUNT(user.user_id) as count";
1363
            }
1364
1365
            $sessionCondition = " session_course_user.session_id = $session_id";
1366
            if (!empty($sessionIdList)) {
1367
                $sessionIdListTostring = implode("','", array_map('intval', $sessionIdList));
1368
                $sessionCondition = " session_course_user.session_id IN ('$sessionIdListTostring') ";
1369
            }
1370
1371
            $courseCondition = " course.id = $courseId";
1372
            if (!empty($courseCodeList)) {
1373
                $courseCodeListForSession = array_map(array('Database', 'escape_string'), $courseCodeList);
1374
                $courseCodeListForSession = implode('","', $courseCodeListForSession);
1375
                $courseCondition = ' course.code IN ("' . $courseCodeListForSession . '")  ';
1376
            }
1377
1378
            $sql .= ' FROM ' . Database::get_main_table(TABLE_MAIN_USER) . ' as user ';
1379
            $sql .= " LEFT JOIN ".Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . " as session_course_user
1380
                      ON
1381
                        user.id = session_course_user.user_id AND
1382
                        $sessionCondition
1383
                        INNER JOIN $course_table course 
1384
                        ON session_course_user.c_id = course.id AND
1385
                        $courseCondition
1386
                        INNER JOIN $sessionTable session 
1387
                        ON session_course_user.session_id = session.id
1388
                   ";
1389
            $where[] = ' session_course_user.c_id IS NOT NULL ';
1390
1391
            // 2 = coach
1392
            // 0 = student
1393
            if (isset($filter_by_status)) {
1394
                $filter_by_status = intval($filter_by_status);
1395
                $filter_by_status_condition = " session_course_user.status = $filter_by_status AND ";
1396
            }
1397
        } else {
1398
            if ($return_count) {
1399
                $sql = " SELECT COUNT(*) as count";
1400
            } else {
1401
                if (empty($course_code)) {
1402
                    $sql = 'SELECT DISTINCT
1403
                                course.title,
1404
                                course.code,
1405
                                course_rel_user.status as status_rel,
1406
                                user.id as user_id,
1407
                                user.email,
1408
                                course_rel_user.is_tutor,
1409
                                user.*  ';
1410
                } else {
1411
                    $sql = 'SELECT DISTINCT
1412
                                course_rel_user.status as status_rel,
1413
                                user.id as user_id,
1414
                                user.email,
1415
                                course_rel_user.is_tutor,
1416
                                user.*  ';
1417
                }
1418
            }
1419
1420
            $sql .= ' FROM ' . Database::get_main_table(TABLE_MAIN_USER) . ' as user '
1421
                  . ' LEFT JOIN ' . Database::get_main_table(TABLE_MAIN_COURSE_USER) . ' as course_rel_user
1422
                      ON 
1423
                        user.id = course_rel_user.user_id AND
1424
                        course_rel_user.relation_type <> ' . COURSE_RELATION_TYPE_RRHH . '  '
1425
                  . " INNER JOIN $course_table course ON course_rel_user.c_id = course.id ";
1426
1427
            if (!empty($course_code)) {
1428
                $sql .= ' AND course_rel_user.c_id = "' . $courseId . '"';
1429
            }
1430
            $where[] = ' course_rel_user.c_id IS NOT NULL ';
1431
1432
            if (isset($filter_by_status) && is_numeric($filter_by_status)) {
1433
                $filter_by_status = intval($filter_by_status);
1434
                $filter_by_status_condition = " course_rel_user.status = $filter_by_status AND ";
1435
            }
1436
        }
1437
1438
        $multiple_access_url = api_get_multiple_access_url();
1439
        if ($multiple_access_url) {
1440
            $sql .= ' LEFT JOIN ' . Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER) . ' au
1441
                      ON (au.user_id = user.id) ';
1442
        }
1443
1444
        $extraFieldWasAdded = false;
1445
        if ($return_count && $resumed_report) {
1446
            foreach ($extra_field as $extraField) {
1447
                $extraFieldInfo = UserManager::get_extra_field_information_by_name($extraField);
1448
                if (!empty($extraFieldInfo)) {
1449
                    $fieldValuesTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1450
                    $sql .= ' LEFT JOIN '.$fieldValuesTable.' as ufv
1451
                            ON (
1452
                                user.id = ufv.item_id AND
1453
                                (field_id = '.$extraFieldInfo['id'].' OR field_id IS NULL)
1454
                            )';
1455
                    $extraFieldWasAdded = true;
1456
                }
1457
            }
1458
        }
1459
1460
        $sql .= ' WHERE ' . $filter_by_status_condition . ' ' . 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(array('Database', 'escape_string'), $courseCodeList);
1473
            $courseCodeList = implode('","', $courseCodeList);
1474
            if (empty($sessionIdList)) {
1475
                $sql .= ' AND course.code IN ("'.$courseCodeList.'")';
1476
            }
1477
        }
1478
1479 View Code Duplication
        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 = intval($filterByActive);
1487
            $sql .= ' AND user.active = ' . $filterByActive;
1488
        }
1489
1490
        $sql .= ' ' . $order_by . ' ' . $limit;
1491
1492
        $rs = Database::query($sql);
1493
        $users = array();
1494
1495
        $extra_fields = UserManager::get_extra_fields(0, 100, null, null, true, true);
1496
1497
        $counter = 1;
1498
        $count_rows = Database::num_rows($rs);
1499
1500
        if ($return_count && $resumed_report) {
1501
            return $count_rows;
1502
        }
1503
1504
        $table_user_field_value = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
1505
        $tableExtraField = Database::get_main_table(TABLE_EXTRA_FIELD);
1506
        if ($count_rows) {
1507
            while ($user = Database::fetch_array($rs)) {
1508
                if ($return_count) {
1509
                    return $user['count'];
1510
                }
1511
                $report_info = array();
1512
1513
                $user_info = $user;
1514
                $user_info['status'] = $user['status'];
1515
1516
                if (isset($user['is_tutor'])) {
1517
                    $user_info['is_tutor'] = $user['is_tutor'];
1518
                }
1519
1520
                if (!empty($session_id)) {
1521
                    $user_info['status_session'] = $user['status_session'];
1522
                }
1523
1524
                $sessionId = isset($user['session_id']) ? $user['session_id'] : 0;
1525
                $course_code = isset($user['code']) ? $user['code'] : null;
1526
1527
                if ($add_reports) {
1528
                    if ($resumed_report) {
1529
                        $extra = array();
1530
1531
                        if (!empty($extra_fields)) {
1532
                            foreach ($extra_fields as $extra) {
1533
                                if (in_array($extra['1'], $extra_field)) {
1534
                                    $user_data = UserManager::get_extra_user_data_by_field(
1535
                                        $user['user_id'],
1536
                                        $extra['1']
1537
                                    );
1538
                                    break;
1539
                                }
1540
                            }
1541
                        }
1542
1543
                        $row_key = '-1';
1544
                        $name = '-';
1545
1546
                        if (!empty($extra)) {
1547
                            if (!empty($user_data[$extra['1']])) {
1548
                                $row_key = $user_data[$extra['1']];
1549
                                $name = $user_data[$extra['1']];
1550
                                $users[$row_key]['extra_'.$extra['1']] = $name;
1551
                            }
1552
                        }
1553
1554
                        $users[$row_key]['training_hours'] += Tracking::get_time_spent_on_the_course(
1555
                            $user['user_id'],
1556
                            $courseId,
1557
                            $sessionId
1558
                        );
1559
1560
                        $users[$row_key]['count_users'] += $counter;
1561
1562
                        $registered_users_with_extra_field = self::getCountRegisteredUsersWithCourseExtraField(
1563
                            $name,
1564
                            $tableExtraField,
1565
                            $table_user_field_value
1566
                        );
1567
1568
                        $users[$row_key]['count_users_registered'] = $registered_users_with_extra_field;
1569
                        $users[$row_key]['average_hours_per_user'] = $users[$row_key]['training_hours'] / $users[$row_key]['count_users'];
1570
1571
                        $category = Category:: load(
1572
                            null,
1573
                            null,
1574
                            $course_code,
1575
                            null,
1576
                            null,
1577
                            $sessionId
1578
                        );
1579
1580
                        if (!isset($users[$row_key]['count_certificates'])) {
1581
                            $users[$row_key]['count_certificates'] = 0;
1582
                        }
1583
1584
                        if (isset($category[0]) && $category[0]->is_certificate_available($user['user_id'])) {
1585
                            $users[$row_key]['count_certificates']++;
1586
                        }
1587
1588
                        foreach ($extra_fields as $extra) {
1589
                            if ($extra['1'] == 'ruc') {
1590
                                continue;
1591
                            }
1592
1593
                            if (!isset($users[$row_key][$extra['1']])) {
1594
                                $user_data = UserManager::get_extra_user_data_by_field($user['user_id'], $extra['1']);
1595
                                if (!empty($user_data[$extra['1']])) {
1596
                                    $users[$row_key][$extra['1']] = $user_data[$extra['1']];
1597
                                }
1598
                            }
1599
                        }
1600
                    } else {
1601
                        $sessionName = !empty($sessionId) ? ' - '.$user['session_name'] : '';
1602
                        $report_info['course'] = $user['title'].$sessionName;
1603
                        $report_info['user'] = api_get_person_name($user['firstname'], $user['lastname']);
1604
                        $report_info['email'] = $user['email'];
1605
                        $report_info['time'] = api_time_to_hms(
1606
                            Tracking::get_time_spent_on_the_course(
1607
                                $user['user_id'],
1608
                                $courseId,
1609
                                $sessionId
1610
                            )
1611
                        );
1612
1613
                        $category = Category:: load(
1614
                            null,
1615
                            null,
1616
                            $course_code,
1617
                            null,
1618
                            null,
1619
                            $sessionId
1620
                        );
1621
1622
                        $report_info['certificate'] = Display::label(get_lang('No'));
1623
                        if (isset($category[0]) && $category[0]->is_certificate_available($user['user_id'])) {
1624
                            $report_info['certificate'] = Display::label(get_lang('Yes'), 'success');
1625
                        }
1626
1627
                        $progress = intval(
1628
                            Tracking::get_avg_student_progress(
1629
                                $user['user_id'],
1630
                                $course_code,
1631
                                array(),
1632
                                $sessionId
1633
                            )
1634
                        );
1635
                        $report_info['progress_100'] = $progress == 100 ? Display::label(get_lang('Yes'), 'success') : Display::label(get_lang('No'));
1636
                        $report_info['progress'] = $progress . "%";
1637
1638
                        foreach ($extra_fields as $extra) {
1639
                            $user_data = UserManager::get_extra_user_data_by_field($user['user_id'], $extra['1']);
1640
                            $report_info[$extra['1']] = $user_data[$extra['1']];
1641
                        }
1642
                        $report_info['user_id'] = $user['user_id'];
1643
                        $users[] = $report_info;
1644
                    }
1645
                } else {
1646
                    $users[$user['user_id']] = $user_info;
1647
                }
1648
            }
1649
        }
1650
1651
        return $users;
1652
    }
1653
1654
    /**
1655
     * @param bool $resumed_report
1656
     * @param array $extra_field
1657
     * @param array $courseCodeList
1658
     * @param array $userIdList
1659
     * @param array $sessionIdList
1660
     * @return array|int
1661
     */
1662
    public static function get_count_user_list_from_course_code(
1663
        $resumed_report = false,
1664
        $extra_field = array(),
1665
        $courseCodeList = array(),
1666
        $userIdList = array(),
1667
        $sessionIdList = array()
1668
    ) {
1669
        return self::get_user_list_from_course_code(
1670
            null,
1671
            0,
1672
            null,
1673
            null,
1674
            null,
1675
            true,
1676
            false,
1677
            $resumed_report,
1678
            $extra_field,
1679
            $courseCodeList,
1680
            $userIdList,
1681
            null,
1682
            $sessionIdList
1683
        );
1684
    }
1685
1686
    /**
1687
     * Gets subscribed users in a course or in a course/session
1688
     *
1689
     * @param   string $course_code
1690
     * @param   int $session_id
1691
     * @return  int
1692
     */
1693
    public static function get_users_count_in_course(
1694
        $course_code,
1695
        $session_id = 0,
1696
        $status = null
1697
    ) {
1698
        // variable initialisation
1699
        $session_id = intval($session_id);
1700
        $course_code = Database::escape_string($course_code);
1701
1702
        $courseInfo = api_get_course_info($course_code);
1703
        $courseId = $courseInfo['real_id'];
1704
1705
        $sql = 'SELECT DISTINCT count(user.id) as count  
1706
                FROM ' . Database::get_main_table(TABLE_MAIN_USER) . ' as user ';
1707
        $where = array();
1708
        if (!empty($session_id)) {
1709
            $sql .= ' LEFT JOIN ' . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . ' as session_course_user
1710
                      ON
1711
                        user.user_id = session_course_user.user_id AND
1712
                        session_course_user.c_id = "' . $courseId . '" AND
1713
                        session_course_user.session_id  = ' . $session_id;
1714
1715
            $where[] = ' session_course_user.c_id IS NOT NULL ';
1716
        } else {
1717
            $sql .= ' LEFT JOIN ' . Database::get_main_table(TABLE_MAIN_COURSE_USER) . ' as course_rel_user
1718
                        ON
1719
                            user.user_id = course_rel_user.user_id AND
1720
                            course_rel_user.relation_type<>' . COURSE_RELATION_TYPE_RRHH . ' AND
1721
                            course_rel_user.c_id = ' . $courseId ;
1722
            $where[] = ' course_rel_user.c_id IS NOT NULL ';
1723
        }
1724
1725
        $multiple_access_url = api_get_multiple_access_url();
1726
        if ($multiple_access_url) {
1727
            $sql .= ' LEFT JOIN ' . Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER) . '  au
1728
                      ON (au.user_id = user.user_id) ';
1729
        }
1730
1731
        $sql .= ' WHERE ' . implode(' OR ', $where);
1732
1733
        if ($multiple_access_url) {
1734
            $current_access_url_id = api_get_current_access_url_id();
1735
            $sql .= " AND (access_url_id =  $current_access_url_id ) ";
1736
        }
1737
        $rs = Database::query($sql);
1738
        $count = 0;
1739
        if (Database::num_rows($rs)) {
1740
            $user = Database::fetch_array($rs);
1741
            $count = $user['count'];
1742
        }
1743
1744
        return $count;
1745
    }
1746
1747
    /**
1748
     * Get a list of coaches of a course and a session
1749
     * @param   string  $course_code
1750
     * @param   int     $session_id
1751
     * @param   bool $addGeneralCoach
1752
     * @return  array   List of users
1753
     */
1754
    public static function get_coach_list_from_course_code($course_code, $session_id, $addGeneralCoach = true)
1755
    {
1756
        if (empty($course_code) || empty($session_id)) {
1757
            return array();
1758
        }
1759
1760
        $course_code = Database::escape_string($course_code);
1761
        $courseInfo = api_get_course_info($course_code);
1762
        $courseId = $courseInfo['real_id'];
1763
1764
        $session_id = intval($session_id);
1765
        $users = array();
1766
1767
        // We get the coach for the given course in a given session.
1768
        $sql = 'SELECT user_id FROM ' . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) .
1769
               ' WHERE session_id ="' . $session_id . '" AND c_id="' . $courseId . '" AND status = 2';
1770
        $rs = Database::query($sql);
1771
        while ($user = Database::fetch_array($rs)) {
1772
            $userInfo = api_get_user_info($user['user_id']);
1773
            if ($userInfo) {
1774
                $users[$user['user_id']] = $userInfo;
1775
            }
1776
        }
1777
1778
        if ($addGeneralCoach) {
1779
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1780
            // We get the session coach.
1781
            $sql = 'SELECT id_coach FROM '.$table.' WHERE id='.$session_id;
1782
            $rs = Database::query($sql);
1783
            $session_id_coach = Database::result($rs, 0, 'id_coach');
1784
            $userInfo = api_get_user_info($session_id_coach);
1785
            if ($userInfo) {
1786
                $users[$session_id_coach] = $userInfo;
1787
            }
1788
        }
1789
1790
        return $users;
1791
    }
1792
1793
    /**
1794
     *  Return user info array of all users registered in a course
1795
     *  This only returns the users that are registered in this actual course, not linked courses.
1796
     *
1797
     * @param string $course_code
1798
     * @param boolean $with_session
1799
     * @param integer $session_id
1800
     * @param string $date_from
1801
     * @param string $date_to
1802
     * @param boolean $includeInvitedUsers Whether include the invited users
1803
     * @param int $groupId
1804
     * @return array with user id
1805
     */
1806
    public static function get_student_list_from_course_code(
1807
        $course_code,
1808
        $with_session = false,
1809
        $session_id = 0,
1810
        $date_from = null,
1811
        $date_to = null,
1812
        $includeInvitedUsers = true,
1813
        $groupId = 0
1814
    ) {
1815
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
1816
        $session_id = intval($session_id);
1817
        $course_code = Database::escape_string($course_code);
1818
        $courseInfo = api_get_course_info($course_code);
1819
        $courseId = $courseInfo['real_id'];
1820
        $students = array();
1821
1822
        if ($session_id == 0) {
1823
            if (empty($groupId)) {
1824
                // students directly subscribed to the course
1825
                $sql = "SELECT *
1826
                        FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)." cu
1827
                        INNER JOIN $userTable u
1828
                        ON cu.user_id = u.user_id
1829
                        WHERE c_id = '$courseId' AND cu.status = ".STUDENT;
1830
1831
                if (!$includeInvitedUsers) {
1832
                    $sql .= " AND u.status != ".INVITEE;
1833
                }
1834
                $rs = Database::query($sql);
1835
                while ($student = Database::fetch_array($rs)) {
1836
                    $students[$student['user_id']] = $student;
1837
                }
1838
            } else {
1839
                $students = GroupManager::get_users(
1840
                    $groupId,
1841
                    false,
1842
                    null,
1843
                    null,
1844
                    false,
1845
                    $courseInfo['real_id']
1846
                );
1847
                $students = array_flip($students);
1848
            }
1849
        }
1850
1851
        // students subscribed to the course through a session
1852
        if ($with_session) {
1853
            $joinSession = "";
1854
            //Session creation date
1855
            if (!empty($date_from) && !empty($date_to)) {
1856
                $joinSession = "INNER JOIN " . Database::get_main_table(TABLE_MAIN_SESSION) . " s";
1857
            }
1858
1859
            $sql_query = "SELECT *
1860
                          FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . " scu
1861
                          $joinSession
1862
                          INNER JOIN $userTable u ON scu.user_id = u.user_id
1863
                          WHERE scu.c_id = '$courseId' AND scu.status <> 2";
1864
1865
            if (!empty($date_from) && !empty($date_to)) {
1866
                $date_from = Database::escape_string($date_from);
1867
                $date_to = Database::escape_string($date_to);
1868
                $sql_query .= " AND s.access_start_date >= '$date_from' AND s.access_end_date <= '$date_to'";
1869
            }
1870
1871
            if ($session_id != 0) {
1872
                $sql_query .= ' AND scu.session_id = ' . $session_id;
1873
            }
1874
1875
            if (!$includeInvitedUsers) {
1876
                $sql_query .= " AND u.status != " . INVITEE;
1877
            }
1878
1879
            $rs = Database::query($sql_query);
1880
            while ($student = Database::fetch_array($rs)) {
1881
                $students[$student['user_id']] = $student;
1882
            }
1883
        }
1884
1885
        return $students;
1886
    }
1887
1888
    /**
1889
     * Return user info array of all teacher-users registered in a course
1890
     * This only returns the users that are registered in this actual course, not linked courses.
1891
     *
1892
     * @param string $course_code
1893
     * @return array with user id
1894
     */
1895
    public static function get_teacher_list_from_course_code($course_code)
1896
    {
1897
        $courseInfo = api_get_course_info($course_code);
1898
        $courseId = $courseInfo['real_id'];
1899
        if (empty($courseId)) {
1900
            return false;
1901
        }
1902
1903
        $sql = "SELECT DISTINCT
1904
                    u.id as user_id,
1905
                    u.lastname,
1906
                    u.firstname,
1907
                    u.email,
1908
                    u.username,
1909
                    u.status
1910
                FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . " cu
1911
                INNER JOIN " . Database::get_main_table(TABLE_MAIN_USER) . " u
1912
                ON (cu.user_id = u.id)
1913
                WHERE
1914
                    cu.c_id = $courseId AND
1915
                    cu.status = 1 ";
1916
        $rs = Database::query($sql);
1917
        $teachers = array();
1918
        while ($teacher = Database::fetch_array($rs)) {
1919
            $teachers[$teacher['user_id']] = $teacher;
1920
        }
1921
1922
        return $teachers;
1923
    }
1924
1925
    /**
1926
     * Return user info array of all teacher-users registered in a course
1927
     * This only returns the users that are registered in this actual course, not linked courses.
1928
     *
1929
     * @param int $courseId
1930
     * @param bool $loadAvatars
1931
     *
1932
     * @return array with user id
1933
     */
1934
    public static function getTeachersFromCourse($courseId, $loadAvatars = true)
1935
    {
1936
        $courseId = (int) $courseId;
1937
1938
        if (empty($courseId)) {
1939
            return false;
1940
        }
1941
1942
        $sql = "SELECT DISTINCT
1943
                    u.id as user_id,
1944
                    u.lastname,
1945
                    u.firstname,
1946
                    u.email,
1947
                    u.username,
1948
                    u.status
1949
                FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . " cu
1950
                INNER JOIN " . Database::get_main_table(TABLE_MAIN_USER) . " u
1951
                ON (cu.user_id = u.id)
1952
                WHERE
1953
                    cu.c_id = $courseId AND
1954
                    cu.status = 1 ";
1955
        $rs = Database::query($sql);
1956
        $listTeachers = array();
1957
        $teachers = array();
1958
        $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup';
1959
        while ($teacher = Database::fetch_array($rs)) {
1960
            $teachers['id'] = $teacher['user_id'];
1961
            $teachers['lastname'] = $teacher['lastname'];
1962
            $teachers['firstname'] = $teacher['firstname'];
1963
            $teachers['email'] = $teacher['email'];
1964
            $teachers['username'] = $teacher['username'];
1965
            $teachers['status'] = $teacher['status'];
1966
            $teachers['avatar'] = '';
1967
            if ($loadAvatars) {
1968
                $userPicture = UserManager::getUserPicture($teacher['user_id'], USER_IMAGE_SIZE_SMALL);
1969
                $teachers['avatar'] = $userPicture;
1970
            }
1971
            $teachers['url'] = $url.'&user_id='. $teacher['user_id'];
1972
            $listTeachers[] = $teachers;
1973
        }
1974
1975
        return $listTeachers;
1976
    }
1977
1978
    /**
1979
     * Returns a string list of teachers assigned to the given course
1980
     * @param string $course_code
1981
     * @param string $separator between teachers names
1982
     * @param bool $add_link_to_profile Whether to add a link to the teacher's profile
1983
     * @return string List of teachers teaching the course
1984
     */
1985 View Code Duplication
    public static function get_teacher_list_from_course_code_to_string(
1986
        $course_code,
1987
        $separator = self::USER_SEPARATOR,
1988
        $add_link_to_profile = false,
1989
        $orderList = false
1990
    ) {
1991
        $teacher_list = self::get_teacher_list_from_course_code($course_code);
1992
        $html = '';
1993
        $list = array();
1994
        if (!empty($teacher_list)) {
1995
            foreach ($teacher_list as $teacher) {
1996
                $teacher_name = api_get_person_name(
1997
                    $teacher['firstname'],
1998
                    $teacher['lastname']
1999
                );
2000
                if ($add_link_to_profile) {
2001
                    $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&user_id=' . $teacher['user_id'];
2002
                    $teacher_name = Display::url(
2003
                        $teacher_name,
2004
                        $url,
2005
                        [
2006
                            'class' => 'ajax',
2007
                            'data-title' => $teacher_name
2008
                        ]
2009
                    );
2010
                }
2011
                $list[] = $teacher_name;
2012
            }
2013
2014
            if (!empty($list)) {
2015
                if ($orderList === true) {
2016
                    $html .= '<ul class="user-teacher">';
2017
                    foreach ($list as $teacher){
2018
                        $html .= Display::tag('li', Display::return_icon('teacher.png', $teacher, null, ICON_SIZE_TINY) . ' ' . $teacher);
2019
                    }
2020
                    $html .= '</ul>';
2021
                } else {
2022
                    $html .= array_to_string($list, $separator);
2023
                }
2024
            }
2025
        }
2026
2027
        return $html;
2028
    }
2029
2030
    /**
2031
     * This function returns information about coachs from a course in session
2032
     * @param int $session_id
2033
     * @param int $courseId
2034
     *
2035
     * @return array containing user_id, lastname, firstname, username
2036
     */
2037
    public static function get_coachs_from_course($session_id = 0, $courseId = 0)
2038
    {
2039
        if (!empty($session_id)) {
2040
            $session_id = intval($session_id);
2041
        } else {
2042
            $session_id = api_get_session_id();
2043
        }
2044
2045
        if (!empty($courseId)) {
2046
            $courseId = intval($courseId);
2047
        } else {
2048
            $courseId = api_get_course_int_id();
2049
        }
2050
2051
        $tbl_user = Database:: get_main_table(TABLE_MAIN_USER);
2052
        $tbl_session_course_user = Database:: get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2053
2054
        $sql = "SELECT DISTINCT 
2055
                    u.user_id,
2056
                    u.lastname,
2057
                    u.firstname,
2058
                    u.username
2059
                FROM $tbl_user u 
2060
                INNER JOIN $tbl_session_course_user scu
2061
                ON (u.user_id = scu.user_id)
2062
                WHERE
2063
                    scu.session_id = '$session_id' AND
2064
                    scu.c_id = '$courseId' AND
2065
                    scu.status = 2";
2066
        $rs = Database::query($sql);
2067
2068
        $coaches = array();
2069
        if (Database::num_rows($rs) > 0) {
2070 View Code Duplication
            while ($row = Database::fetch_array($rs)) {
2071
                $completeName = api_get_person_name($row['firstname'], $row['lastname']);
2072
                $coaches[] = $row + ['full_name' => $completeName];
2073
            }
2074
        }
2075
2076
        return $coaches;
2077
    }
2078
2079
    /**
2080
     * @param int $session_id
2081
     * @param int $courseId
2082
     * @param string $separator
2083
     * @param bool $add_link_to_profile
2084
     * @return string
2085
     */
2086 View Code Duplication
    public static function get_coachs_from_course_to_string(
2087
        $session_id = 0,
2088
        $courseId = 0,
2089
        $separator = self::USER_SEPARATOR,
2090
        $add_link_to_profile = false,
2091
        $orderList = false
2092
    ) {
2093
        $coachList = self::get_coachs_from_course($session_id, $courseId);
2094
        $course_coachs = array();
2095
        if (!empty($coachList)) {
2096
            foreach ($coachList as $coach_course) {
2097
                $coach_name = $coach_course['full_name'];
2098
                if ($add_link_to_profile) {
2099
                    $url = api_get_path(WEB_AJAX_PATH) . 'user_manager.ajax.php?a=get_user_popup&user_id=' . $coach_course['user_id'];
2100
                    $coach_name = Display::url(
2101
                        $coach_name,
2102
                        $url,
2103
                        [
2104
                            'class' => 'ajax',
2105
                            'data-title' => $coach_name
2106
                        ]
2107
                    );
2108
                }
2109
                $course_coachs[] = $coach_name;
2110
            }
2111
        }
2112
2113
        $html = '';
2114
        if (!empty($course_coachs)) {
2115
            if ($orderList === true) {
2116
                $html .= '<ul class="user-coachs">';
2117
                foreach ($course_coachs as $coachs) {
2118
                    $html .= Display::tag(
2119
                        'li',
2120
                        Display::return_icon('teacher.png', $coachs, null, ICON_SIZE_TINY) . ' ' . $coachs
2121
                    );
2122
                }
2123
                $html .= '</ul>';
2124
            } else {
2125
                $html = array_to_string($course_coachs, $separator);
2126
            }
2127
        }
2128
2129
        return $html;
2130
    }
2131
2132
    /**
2133
     * Return user info array of all users registered in the specified course
2134
     * this includes the users of the course itself and the users of all linked courses.
2135
     *
2136
     * @param string $course_code
2137
     * @param bool $with_sessions
2138
     * @param int $session_id
2139
     * @return array with user info
2140
     */
2141
    public static function get_real_and_linked_user_list($course_code, $with_sessions = true, $session_id = 0)
2142
    {
2143
        $list = array();
2144
        $userList = self::get_user_list_from_course_code($course_code, $session_id);
2145
        foreach ($userList as $user) {
0 ignored issues
show
Bug introduced by
The expression $userList of type array|integer is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
2146
            $list[] = $user;
2147
        }
2148
2149
        return $list;
2150
    }
2151
2152
    /**
2153
     * Get the list of groups from the course
2154
     * @param   string $course_code
2155
     * @param   int $session_id Session ID (optional)
2156
     * @param   integer $in_get_empty_group get empty groups (optional)
2157
     * @return  array   List of groups info
2158
     */
2159
    public static function get_group_list_of_course($course_code, $session_id = 0, $in_get_empty_group = 0)
2160
    {
2161
        $course_info = api_get_course_info($course_code);
2162
2163
        if (empty($course_info)) {
2164
            return array();
2165
        }
2166
        $course_id = $course_info['real_id'];
2167
2168
        if (empty($course_id)) {
2169
            return array();
2170
        }
2171
2172
        $group_list = array();
2173
        $session_id != 0 ? $session_condition = ' WHERE g.session_id IN(1,' . intval($session_id) . ')' : $session_condition = ' WHERE g.session_id = 0';
2174
2175
        if ($in_get_empty_group == 0) {
2176
            // get only groups that are not empty
2177
            $sql = "SELECT DISTINCT g.id, g.iid, g.name
2178
                    FROM " . Database::get_course_table(TABLE_GROUP) . " AS g
2179
                    INNER JOIN " . Database::get_course_table(TABLE_GROUP_USER) . " gu
2180
                    ON (g.id = gu.group_id AND g.c_id = $course_id AND gu.c_id = $course_id)
2181
                    $session_condition
2182
                    ORDER BY g.name";
2183
        } else {
2184
            // get all groups even if they are empty
2185
            $sql = "SELECT g.id, g.name, g.iid 
2186
                    FROM " . Database::get_course_table(TABLE_GROUP) . " AS g
2187
                    $session_condition
2188
                    AND c_id = $course_id";
2189
        }
2190
        $result = Database::query($sql);
2191
2192
        while ($group_data = Database::fetch_array($result)) {
2193
            $group_data['userNb'] = GroupManager::number_of_students($group_data['id'], $course_id);
2194
            $group_list[$group_data['id']] = $group_data;
2195
        }
2196
        return $group_list;
2197
    }
2198
2199
    /**
2200
     * Delete a course
2201
     * This function deletes a whole course-area from the platform. When the
2202
     * given course is a virtual course, the database and directory will not be
2203
     * deleted.
2204
     * When the given course is a real course, also all virtual courses refering
2205
     * to the given course will be deleted.
2206
     * Considering the fact that we remove all traces of the course in the main
2207
     * database, it makes sense to remove all tracking as well (if stats databases exist)
2208
     * so that a new course created with this code would not use the remains of an older
2209
     * course.
2210
     *
2211
     * @param string The code of the course to delete
2212
     * @param string $code
2213
     * @todo When deleting a virtual course: unsubscribe users from that virtual
2214
     * course from the groups in the real course if they are not subscribed in
2215
     * that real course.
2216
     * @todo Remove globals
2217
     */
2218
    public static function delete_course($code)
2219
    {
2220
        $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
2221
        $table_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2222
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2223
        $table_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2224
        $table_course_survey = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY);
2225
        $table_course_survey_question = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION);
2226
        $table_course_survey_question_option = Database::get_main_table(TABLE_MAIN_SHARED_SURVEY_QUESTION_OPTION);
2227
        $table_course_rel_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
2228
2229
        $table_stats_hotpots = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTPOTATOES);
2230
        $table_stats_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
2231
        $table_stats_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
2232
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
2233
        $table_stats_lastaccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LASTACCESS);
2234
        $table_stats_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
2235
        $table_stats_online = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ONLINE);
2236
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
2237
        $table_stats_downloads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS);
2238
        $table_stats_links = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LINKS);
2239
        $table_stats_uploads = Database::get_main_table(TABLE_STATISTIC_TRACK_E_UPLOADS);
2240
2241
        $codeFiltered = Database::escape_string($code);
2242
        $sql = "SELECT * FROM $table_course WHERE code='" . $codeFiltered . "'";
2243
        $res = Database::query($sql);
2244
2245
        if (Database::num_rows($res) == 0) {
2246
            return;
2247
        }
2248
2249
        $sql = "SELECT * FROM $table_course
2250
                WHERE code = '" . $codeFiltered . "'";
2251
        $res = Database::query($sql);
2252
        $course = Database::fetch_array($res);
2253
        $courseId = $course['id'];
2254
2255
        $count = 0;
2256
        if (api_is_multiple_url_enabled()) {
2257
            $url_id = 1;
2258
            if (api_get_current_access_url_id() != -1) {
2259
                $url_id = api_get_current_access_url_id();
2260
            }
2261
            UrlManager::delete_url_rel_course($courseId, $url_id);
2262
            $count = UrlManager::getCountUrlRelCourse($courseId);
2263
        }
2264
2265
        if ($count == 0) {
2266
            self::create_database_dump($code);
2267
2268
            $course_tables = AddCourse::get_course_tables();
2269
2270
            // Cleaning group categories
2271
            $groupCategories = GroupManager::get_categories($course['code']);
2272
2273
            if (!empty($groupCategories)) {
2274
                foreach ($groupCategories as $category) {
2275
                    GroupManager::delete_category($category['id'], $course['code']);
2276
                }
2277
            }
2278
2279
            // Cleaning groups
2280
            $groups = GroupManager::get_groups($courseId);
2281
            if (!empty($groups)) {
2282
                foreach ($groups as $group) {
2283
                    GroupManager::delete_groups($group, $course['code']);
2284
                }
2285
            }
2286
2287
            // Cleaning c_x tables
2288
            if (!empty($courseId)) {
2289
                foreach ($course_tables as $table) {
2290
                    $table = Database::get_course_table($table);
2291
                    $sql = "DELETE FROM $table WHERE c_id = $courseId ";
2292
                    Database::query($sql);
2293
                }
2294
            }
2295
2296
            $course_dir = api_get_path(SYS_COURSE_PATH) . $course['directory'];
2297
            $archive_dir = api_get_path(SYS_ARCHIVE_PATH) . $course['directory'] . '_' . time();
2298
            if (is_dir($course_dir)) {
2299
                rename($course_dir, $archive_dir);
2300
            }
2301
2302
            // Unsubscribe all users from the course
2303
            $sql = "DELETE FROM $table_course_user WHERE c_id='" . $courseId . "'";
2304
            Database::query($sql);
2305
            // Delete the course from the sessions tables
2306
            $sql = "DELETE FROM $table_session_course WHERE c_id='" . $courseId . "'";
2307
            Database::query($sql);
2308
            $sql = "DELETE FROM $table_session_course_user WHERE c_id='" . $courseId . "'";
2309
            Database::query($sql);
2310
2311
            // Delete from Course - URL
2312
            $sql = "DELETE FROM $table_course_rel_url WHERE c_id = '" . $courseId. "'";
2313
            Database::query($sql);
2314
2315
            $sql = 'SELECT survey_id FROM ' . $table_course_survey . ' WHERE course_code="' . $codeFiltered . '"';
2316
            $result_surveys = Database::query($sql);
2317 View Code Duplication
            while ($surveys = Database::fetch_array($result_surveys)) {
2318
                $survey_id = $surveys[0];
2319
                $sql = 'DELETE FROM ' . $table_course_survey_question . ' WHERE survey_id="' . $survey_id . '"';
2320
                Database::query($sql);
2321
                $sql = 'DELETE FROM ' . $table_course_survey_question_option . ' WHERE survey_id="' . $survey_id . '"';
2322
                Database::query($sql);
2323
                $sql = 'DELETE FROM ' . $table_course_survey . ' WHERE survey_id="' . $survey_id . '"';
2324
                Database::query($sql);
2325
            }
2326
2327
            // Delete the course from the stats tables
2328
            $sql = "DELETE FROM $table_stats_hotpots WHERE c_id = $courseId";
2329
            Database::query($sql);
2330
            $sql = "DELETE FROM $table_stats_attempt WHERE c_id = $courseId";
2331
            Database::query($sql);
2332
            $sql = "DELETE FROM $table_stats_exercises WHERE c_id = $courseId";
2333
            Database::query($sql);
2334
            $sql = "DELETE FROM $table_stats_access WHERE c_id = $courseId";
2335
            Database::query($sql);
2336
            $sql = "DELETE FROM $table_stats_lastaccess WHERE c_id = $courseId";
2337
            Database::query($sql);
2338
            $sql = "DELETE FROM $table_stats_course_access WHERE c_id = $courseId";
2339
            Database::query($sql);
2340
            $sql = "DELETE FROM $table_stats_online WHERE c_id = $courseId";
2341
            Database::query($sql);
2342
            // Do not delete rows from track_e_default as these include course
2343
            // creation and other important things that do not take much space
2344
            // but give information on the course history
2345
            //$sql = "DELETE FROM $table_stats_default WHERE c_id = $courseId";
2346
            //Database::query($sql);
2347
            $sql = "DELETE FROM $table_stats_downloads WHERE c_id = $courseId";
2348
            Database::query($sql);
2349
            $sql = "DELETE FROM $table_stats_links WHERE c_id = $courseId";
2350
            Database::query($sql);
2351
            $sql = "DELETE FROM $table_stats_uploads WHERE c_id = $courseId";
2352
            Database::query($sql);
2353
2354
            // Update ticket
2355
            $table = Database::get_main_table(TABLE_TICKET_TICKET);
2356
            $sql = "UPDATE $table SET course_id = NULL WHERE course_id = $courseId";
2357
            Database::query($sql);
2358
2359
            // Class
2360
            $table = Database::get_main_table(TABLE_USERGROUP_REL_COURSE);
2361
            $sql = "DELETE FROM $table
2362
                    WHERE course_id = $courseId";
2363
            Database::query($sql);
2364
2365
            // Skills
2366
            $table = Database::get_main_table(TABLE_MAIN_SKILL_REL_USER);
2367
            $argumentation = Database::escape_string(sprintf(get_lang('SkillFromCourseXDeletedSinceThen'), $course['code']));
2368
            error_log($argumentation);
2369
            $sql = "UPDATE $table SET course_id = NULL, session_id = NULL, argumentation = '$argumentation' WHERE course_id = $courseId";
2370
            Database::query($sql);
2371
2372
            Category::deleteCategoryFromCourse($courseId);
2373
2374
            // Delete the course from the database
2375
            $sql = "DELETE FROM $table_course WHERE code = '" . $codeFiltered . "'";
2376
            Database::query($sql);
2377
2378
            // delete extra course fields
2379
            $extraFieldValues = new ExtraFieldValue('course');
2380
            $extraFieldValues->deleteValuesByItem($courseId);
2381
2382
            // Add event to system log
2383
            $user_id = api_get_user_id();
2384
            Event::addEvent(
2385
                LOG_COURSE_DELETE,
2386
                LOG_COURSE_CODE,
2387
                $code,
2388
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2389
                $user_id,
2390
                $courseId
2391
            );
2392
        }
2393
    }
2394
2395
    /**
2396
     * Creates a file called mysql_dump.sql in the course folder
2397
     * @param string $course_code The code of the course
2398
     * @todo Implementation for single database
2399
     */
2400
    public static function create_database_dump($course_code)
2401
    {
2402
        $sql_dump = '';
2403
        $course_code = Database::escape_string($course_code);
2404
        $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
2405
        $sql = "SELECT * FROM $table_course WHERE code = '$course_code'";
2406
        $res = Database::query($sql);
2407
        $course = Database::fetch_array($res);
2408
2409
        $course_tables = AddCourse::get_course_tables();
2410
2411
        if (!empty($course['id'])) {
2412
            //Cleaning c_x tables
2413
            foreach ($course_tables as $table) {
2414
                $table = Database::get_course_table($table);
2415
                $sql = "SELECT * FROM $table WHERE c_id = {$course['id']} ";
2416
                $res_table = Database::query($sql);
2417
2418
                while ($row = Database::fetch_array($res_table, 'ASSOC')) {
2419
                    $row_to_save = array();
2420
                    foreach ($row as $key => $value) {
2421
                        $row_to_save[$key] = $key . "='" . Database::escape_string($row[$key]) . "'";
2422
                    }
2423
                    $sql_dump .= "\nINSERT INTO $table SET " . implode(', ', $row_to_save) . ';';
2424
                }
2425
            }
2426
        }
2427
2428
        if (is_dir(api_get_path(SYS_COURSE_PATH) . $course['directory'])) {
2429
            $file_name = api_get_path(SYS_COURSE_PATH) . $course['directory'] . '/mysql_dump.sql';
2430
            $handle = fopen($file_name, 'a+');
2431
            if ($handle !== false) {
2432
                fwrite($handle, $sql_dump);
2433
                fclose($handle);
2434
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
2435
                //TODO trigger exception in a try-catch
2436
            }
2437
        }
2438
    }
2439
2440
    /**
2441
     * Sort courses for a specific user ??
2442
     * @param   int     User ID
2443
     * @param   string  Course code
2444
     * @param integer $user_id
2445
     * @return  int     Minimum course order
2446
     * @todo Review documentation
2447
     */
2448
    public static function userCourseSort($user_id, $course_code)
2449
    {
2450
        if ($user_id != strval(intval($user_id))) {
2451
            return false;
2452
        }
2453
2454
        $course_code = Database::escape_string($course_code);
2455
        $TABLECOURSE = Database::get_main_table(TABLE_MAIN_COURSE);
2456
        $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2457
2458
        $course_title = Database::result(Database::query('SELECT title FROM ' . $TABLECOURSE . ' WHERE code="' . $course_code . '"'),
2459
            0, 0);
2460
2461
        $sql = 'SELECT course.code as code, course.title as title, cu.sort as sort
2462
                FROM ' . $TABLECOURSUSER . ' as cu, ' . $TABLECOURSE . ' as course
2463
                WHERE   course.id = cu.c_id AND user_id = "' . $user_id . '" AND
2464
                        cu.relation_type<>' . COURSE_RELATION_TYPE_RRHH . ' AND
2465
                        user_course_cat = 0
2466
                ORDER BY cu.sort';
2467
        $result = Database::query($sql);
2468
2469
        $course_title_precedent = '';
2470
        $counter = 0;
2471
        $course_found = false;
2472
        $course_sort = 1;
2473
2474
        if (Database::num_rows($result) > 0) {
2475
            while ($courses = Database::fetch_array($result)) {
2476
                if ($course_title_precedent == '') {
2477
                    $course_title_precedent = $courses['title'];
2478
                }
2479
                if (api_strcasecmp($course_title_precedent, $course_title) < 0) {
2480
                    $course_found = true;
2481
                    $course_sort = $courses['sort'];
2482
                    if ($counter == 0) {
2483
                        $sql = 'UPDATE ' . $TABLECOURSUSER . '
2484
                                SET sort = sort+1
2485
                                WHERE
2486
                                    user_id= "' . $user_id . '" AND
2487
                                    relation_type<>' . COURSE_RELATION_TYPE_RRHH . '
2488
                                    AND user_course_cat="0"
2489
                                    AND sort > "' . $course_sort . '"';
2490
                        $course_sort++;
2491
                    } else {
2492
                        $sql = 'UPDATE ' . $TABLECOURSUSER . ' SET sort = sort+1
2493
                                WHERE
2494
                                    user_id= "' . $user_id . '" AND
2495
                                    relation_type<>' . COURSE_RELATION_TYPE_RRHH . ' AND
2496
                                    user_course_cat="0" AND
2497
                                    sort >= "' . $course_sort . '"';
2498
                    }
2499
                    Database::query($sql);
2500
                    break;
2501
2502
                } else {
2503
                    $course_title_precedent = $courses['title'];
2504
                }
2505
                $counter++;
2506
            }
2507
2508
            // We must register the course in the beginning of the list
2509
            if (!$course_found) {
2510
                $course_sort = Database::result(Database::query('SELECT min(sort) as min_sort FROM ' . $TABLECOURSUSER . ' WHERE user_id="' . $user_id . '" AND user_course_cat="0"'),
2511
                    0, 0);
2512
                Database::query('UPDATE ' . $TABLECOURSUSER . ' SET sort = sort+1 WHERE user_id= "' . $user_id . '" AND user_course_cat="0"');
2513
            }
2514
        }
2515
        return $course_sort;
2516
    }
2517
2518
    /**
2519
     * check if course exists
2520
     * @param string $course_code
2521
     * @return integer if exists, false else
2522
     */
2523 View Code Duplication
    public static function course_exists($course_code)
2524
    {
2525
        $sql = 'SELECT 1 FROM ' . Database::get_main_table(TABLE_MAIN_COURSE) . '
2526
                WHERE code="' . Database::escape_string($course_code) . '"';
2527
2528
        return Database::num_rows(Database::query($sql));
2529
    }
2530
2531
    /**
2532
     * Send an email to tutor after the auth-suscription of a student in your course
2533
     * @author Carlos Vargas <[email protected]>, Dokeos Latino
2534
     * @param  int $user_id the id of the user
2535
     * @param  string $courseId the course code
2536
     * @param  bool $send_to_tutor_also
2537
     * @return false|null we return the message that is displayed when the action is successful
2538
     */
2539
    public static function email_to_tutor($user_id, $courseId, $send_to_tutor_also = false)
2540
    {
2541
        if ($user_id != strval(intval($user_id))) {
2542
            return false;
2543
        }
2544
        $courseId = intval($courseId);
2545
        $information = api_get_course_info_by_id($courseId);
2546
        $course_code = $information['code'];
2547
2548
        $student = api_get_user_info($user_id);
2549
2550
        $name_course = $information['title'];
2551
        $sql = "SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . " 
2552
                WHERE c_id ='" . $courseId . "'";
2553
2554
        // TODO: Ivan: This is a mistake, please, have a look at it. Intention here is diffcult to be guessed.
2555
        //if ($send_to_tutor_also = true)
2556
        // Proposed change:
2557
        if ($send_to_tutor_also) {
2558
            $sql .= " AND is_tutor=1";
2559
        } else {
2560
            $sql .= " AND status=1";
2561
        }
2562
2563
        $result = Database::query($sql);
2564
        while ($row = Database::fetch_array($result)) {
2565
            $tutor = api_get_user_info($row['user_id']);
2566
            $emailto = $tutor['email'];
2567
            $emailsubject = get_lang('NewUserInTheCourse') . ': ' . $name_course;
2568
            $emailbody = get_lang('Dear') . ': ' . api_get_person_name($tutor['firstname'], $tutor['lastname']) . "\n";
2569
            $emailbody .= get_lang('MessageNewUserInTheCourse') . ': ' . $name_course . "\n";
2570
            $emailbody .= get_lang('UserName') . ': ' . $student['username'] . "\n";
2571
            if (api_is_western_name_order()) {
2572
                $emailbody .= get_lang('FirstName') . ': ' . $student['firstname'] . "\n";
2573
                $emailbody .= get_lang('LastName') . ': ' . $student['lastname'] . "\n";
2574
            } else {
2575
                $emailbody .= get_lang('LastName') . ': ' . $student['lastname'] . "\n";
2576
                $emailbody .= get_lang('FirstName') . ': ' . $student['firstname'] . "\n";
2577
            }
2578
            $emailbody .= get_lang('Email') . ': <a href="mailto:' . $student['email'] . '">' . $student['email'] ."</a>\n\n";
2579
            $recipient_name = api_get_person_name($tutor['firstname'], $tutor['lastname'], null,
2580
                PERSON_NAME_EMAIL_ADDRESS);
2581
            $sender_name = api_get_person_name(api_get_setting('administratorName'),
2582
                api_get_setting('administratorSurname'), null, PERSON_NAME_EMAIL_ADDRESS);
2583
            $email_admin = api_get_setting('emailAdministrator');
2584
2585
            $additionalParameters = array(
2586
                'smsType' => SmsPlugin::NEW_USER_SUBSCRIBED_COURSE,
2587
                'userId' => $tutor['user_id'],
2588
                'userUsername' => $student['username'],
2589
                'courseCode' => $course_code
2590
            );
2591
            api_mail_html(
2592
                $recipient_name,
2593
                $emailto,
2594
                $emailsubject,
2595
                $emailbody,
2596
                $sender_name,
2597
                $email_admin,
2598
                null,
2599
                null,
2600
                null,
2601
                $additionalParameters
2602
            );
2603
        }
2604
    }
2605
2606
    /**
2607
     * @return array
2608
     */
2609
    public static function get_special_course_list()
2610
    {
2611
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
2612
        $tbl_course_field = Database::get_main_table(TABLE_EXTRA_FIELD);
2613
        $tbl_course_field_value = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
2614
2615
        //we filter the courses from the URL
2616
        $join_access_url = $where_access_url = '';
2617
        if (api_get_multiple_access_url()) {
2618
            $access_url_id = api_get_current_access_url_id();
2619
            if ($access_url_id != -1) {
2620
                $tbl_url_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
2621
                $join_access_url = "LEFT JOIN $tbl_url_course url_rel_course
2622
                                    ON url_rel_course.c_id = tcfv.item_id ";
2623
                $where_access_url = " AND access_url_id = $access_url_id ";
2624
            }
2625
        }
2626
2627
        $extraFieldType = EntityExtraField::COURSE_FIELD_TYPE;
2628
2629
        // get course list auto-register
2630
        $sql = "SELECT DISTINCT(c.id)
2631
                FROM $tbl_course_field_value tcfv
2632
                INNER JOIN $tbl_course_field tcf
2633
                ON tcfv.field_id =  tcf.id $join_access_url
2634
                INNER JOIN $courseTable c
2635
                ON (c.id = tcfv.item_id)
2636
                WHERE
2637
                    tcf.extra_field_type = $extraFieldType AND
2638
                    tcf.variable = 'special_course' AND
2639
                    tcfv.value = 1  $where_access_url";
2640
2641
        $result = Database::query($sql);
2642
        $courseList = array();
2643
2644
        if (Database::num_rows($result) > 0) {
2645
            while ($row = Database::fetch_array($result)) {
2646
                $courseList[] = $row['id'];
2647
            }
2648
        }
2649
2650
        return $courseList;
2651
    }
2652
2653
    /**
2654
     * Get the course codes that have been restricted in the catalogue, and if byUserId is set
2655
     * then the courses that the user is allowed or not to see in catalogue
2656
     *
2657
     * @param boolean $allowed Either if the courses have some users that are or are not allowed to see in catalogue
2658
     * @param boolean $byUserId if the courses are or are not allowed to see to the user
2659
     * @return array Course codes allowed or not to see in catalogue by some user or the user
2660
     */
2661
    public static function getCatalogueCourseList($allowed = true, $byUserId = -1)
2662
    {
2663
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
2664
        $tblCourseRelUserCatalogue = Database::get_main_table(TABLE_MAIN_COURSE_CATALOGUE_USER);
2665
        $visibility = $allowed ? 1 : 0;
2666
2667
        // Restriction by user id
2668
        $currentUserRestriction = "";
2669
        if ($byUserId > 0) {
2670
            $byUserId = (int) $byUserId;
2671
            $currentUserRestriction = " AND tcruc.user_id = $byUserId ";
2672
        }
2673
2674
        //we filter the courses from the URL
2675
        $joinAccessUrl = '';
2676
        $whereAccessUrl = '';
2677
        if (api_get_multiple_access_url()) {
2678
            $accessUrlId = api_get_current_access_url_id();
2679
            if ($accessUrlId != -1) {
2680
                $tblUrlCourse = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
2681
                $joinAccessUrl = "LEFT JOIN $tblUrlCourse url_rel_course
2682
                                    ON url_rel_course.c_id = c.id ";
2683
                $whereAccessUrl = " AND access_url_id = $accessUrlId ";
2684
            }
2685
        }
2686
2687
        // get course list auto-register
2688
        $sql = "SELECT DISTINCT(c.code)
2689
                FROM $tblCourseRelUserCatalogue tcruc
2690
                INNER JOIN $courseTable c
2691
                ON (c.id = tcruc.c_id) $joinAccessUrl
2692
                WHERE tcruc.visible = $visibility $currentUserRestriction $whereAccessUrl";
2693
2694
        $result = Database::query($sql);
2695
        $courseList = array();
2696
2697
        if (Database::num_rows($result) > 0) {
2698
            while ($resultRow = Database::fetch_array($result)) {
2699
                $courseList[] = $resultRow['code'];
2700
            }
2701
        }
2702
2703
        return $courseList;
2704
    }
2705
2706
    /**
2707
     * Get list of courses for a given user
2708
     *
2709
     * @param int $user_id
2710
     * @param boolean $include_sessions Whether to include courses from session or not
2711
     * @param boolean $adminGetsAllCourses If the user is platform admin,
2712
     * whether he gets all the courses or just his. Note: This does *not* include all sessions
2713
     * @param bool $loadSpecialCourses
2714
     * @param array $skipCourseList List of course ids to skip
2715
     * @return array List of codes and db name
2716
     * @author isaac flores paz
2717
     */
2718
    public static function get_courses_list_by_user_id(
2719
        $user_id,
2720
        $include_sessions = false,
2721
        $adminGetsAllCourses = false,
2722
        $loadSpecialCourses = true,
2723
        $skipCourseList = []
2724
    ) {
2725
        $user_id = intval($user_id);
2726
        $urlId = api_get_current_access_url_id();
2727
        $course_list = array();
2728
        $codes = array();
2729
2730
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
2731
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
2732
        $tbl_user_course_category = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
2733
        $tableCourseUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
2734
2735
        if ($adminGetsAllCourses && UserManager::is_admin($user_id)) {
2736
            // get the whole courses list
2737
            $sql = "SELECT DISTINCT(course.code), course.id as real_id
2738
                    FROM $tbl_course course 
2739
                    INNER JOIN $tableCourseUrl url 
2740
                    ON (course.id = url.c_id)
2741
                    WHERE url.access_url_id = $urlId      
2742
                ";
2743
        } else {
2744
            $withSpecialCourses = $withoutSpecialCourses = '';
2745
            if ($loadSpecialCourses) {
2746
                $specialCourseList = self::get_special_course_list();
2747
2748
                if (!empty($specialCourseList)) {
2749
                    $specialCourseToString = '"'.implode(
2750
                            '","',
2751
                            $specialCourseList
2752
                        ).'"';
2753
                    $withSpecialCourses = ' AND course.id IN ('.$specialCourseToString.')';
2754
                    $withoutSpecialCourses = ' AND course.id NOT IN ('.$specialCourseToString.')';
2755
                }
2756
2757
                if (!empty($withSpecialCourses)) {
2758
                    $sql = "SELECT DISTINCT(course.code), course.id as real_id
2759
                            FROM $tbl_course_user course_rel_user
2760
                            LEFT JOIN $tbl_course course
2761
                            ON course.id = course_rel_user.c_id
2762
                            LEFT JOIN $tbl_user_course_category user_course_category
2763
                            ON course_rel_user.user_course_cat = user_course_category.id
2764
                            INNER JOIN $tableCourseUrl url 
2765
                            ON (course.id = url.c_id)  
2766
                            WHERE url.access_url_id = $urlId $withSpecialCourses                        
2767
                            GROUP BY course.code
2768
                            ORDER BY user_course_category.sort, course.title, course_rel_user.sort ASC
2769
                    ";
2770
                    $rs_special_course = Database::query($sql);
2771
                    if (Database::num_rows($rs_special_course) > 0) {
2772
                        while ($result_row = Database::fetch_array(
2773
                            $rs_special_course
2774
                        )) {
2775
                            $result_row['special_course'] = 1;
2776
                            $course_list[] = $result_row;
2777
                            $codes[] = $result_row['real_id'];
2778
                        }
2779
                    }
2780
                }
2781
            }
2782
2783
            // get course list not auto-register. Use Distinct to avoid multiple
2784
            // entries when a course is assigned to a HRD (DRH) as watcher
2785
            $sql = "SELECT 
2786
                    DISTINCT(course.code), 
2787
                    course.id as real_id,
2788
                    course.title
2789
                    FROM $tbl_course course
2790
                    INNER JOIN $tbl_course_user cru 
2791
                    ON (course.id = cru.c_id)
2792
                    INNER JOIN $tableCourseUrl url 
2793
                    ON (course.id = url.c_id) 
2794
                    WHERE 
2795
                        url.access_url_id = $urlId AND 
2796
                        cru.user_id = '$user_id' 
2797
                        $withoutSpecialCourses
2798
                    ORDER BY course.title
2799
                    ";
2800
        }
2801
        $result = Database::query($sql);
2802
2803
        if (Database::num_rows($result)) {
2804 View Code Duplication
            while ($row = Database::fetch_array($result, 'ASSOC')) {
2805
                if (!empty($skipCourseList)) {
2806
                    if (in_array($row['real_id'], $skipCourseList)) {
2807
                        continue;
2808
                    }
2809
                }
2810
                $course_list[] = $row;
2811
                $codes[] = $row['real_id'];
2812
            }
2813
        }
2814
2815
        if ($include_sessions === true) {
2816
            $sql = "SELECT DISTINCT(c.code), c.id as real_id
2817
                    FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER) . " s,
2818
                    $tbl_course c
2819
                    WHERE user_id = $user_id AND s.c_id = c.id";
2820
            $r = Database::query($sql);
2821
            while ($row = Database::fetch_array($r, 'ASSOC')) {
2822
                if (!empty($skipCourseList)) {
2823
                    if (in_array($row['real_id'], $skipCourseList)) {
2824
                        continue;
2825
                    }
2826
                }
2827
                if (!in_array($row['real_id'], $codes)) {
2828
                    $course_list[] = $row;
2829
                }
2830
            }
2831
        }
2832
2833
        return $course_list;
2834
    }
2835
2836
    /**
2837
     * Get course ID from a given course directory name
2838
     * @param   string  $path Course directory (without any slash)
2839
     *
2840
     * @return  string  Course code, or false if not found
2841
     */
2842
    public static function get_course_id_from_path($path)
2843
    {
2844
        $path = Database::escape_string(str_replace('.', '', str_replace('/', '', $path)));
2845
        $res = Database::query("SELECT code FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
2846
                WHERE directory LIKE BINARY '$path'");
2847
        if ($res === false) {
2848
            return false;
2849
        }
2850
        if (Database::num_rows($res) != 1) {
2851
            return false;
2852
        }
2853
        $row = Database::fetch_array($res);
2854
2855
        return $row['code'];
2856
    }
2857
2858
    /**
2859
     * Get course code(s) from visual code
2860
     * @deprecated
2861
     * @param   string  Visual code
2862
     * @return  array   List of codes for the given visual code
2863
     */
2864
    public static function get_courses_info_from_visual_code($code)
2865
    {
2866
        $result = array();
2867
        $sql_result = Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_COURSE) . "
2868
                WHERE visual_code = '" . Database::escape_string($code) . "'");
2869
        while ($virtual_course = Database::fetch_array($sql_result)) {
2870
            $result[] = $virtual_course;
2871
        }
2872
        return $result;
2873
    }
2874
2875
    /**
2876
     * Get emails of tutors to course
2877
     * @param int $courseId
2878
     * @return array List of emails of tutors to course
2879
     *
2880
     * @author Carlos Vargas <[email protected]>, Dokeos Latino
2881
     * */
2882
    public static function get_emails_of_tutors_to_course($courseId)
2883
    {
2884
        $list = array();
2885
        $res = Database::query("SELECT user_id FROM " . Database::get_main_table(TABLE_MAIN_COURSE_USER) . "
2886
                WHERE c_id ='" . intval($courseId) . "' AND status=1");
2887
        while ($list_users = Database::fetch_array($res)) {
2888
            $result = Database::query("SELECT * FROM " . Database::get_main_table(TABLE_MAIN_USER) . "
2889
                    WHERE user_id=" . $list_users['user_id']);
2890 View Code Duplication
            while ($row_user = Database::fetch_array($result)) {
2891
                $name_teacher = api_get_person_name($row_user['firstname'], $row_user['lastname']);
2892
                $list[] = array($row_user['email'] => $name_teacher);
2893
            }
2894
        }
2895
        return $list;
2896
    }
2897
2898
    /**
2899
     * Get coaches emails by session
2900
     * @param int session id
2901
     * @param int $courseId
2902
     * @param integer $session_id
2903
     * @return array  array(email => name_tutor)  by coach
2904
     * @author Carlos Vargas <[email protected]>
2905
     */
2906
    public static function get_email_of_tutor_to_session($session_id, $courseId)
2907
    {
2908
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2909
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2910
        $coachs_emails = array();
2911
2912
        $courseId = intval($courseId);
2913
        $session_id = intval($session_id);
2914
2915
        $sql = "SELECT user_id
2916
                FROM $tbl_session_course_user
2917
                WHERE
2918
                    session_id = '$session_id' AND
2919
                    c_id = '$courseId' AND
2920
                    status = 2
2921
                ";
2922
        $rs = Database::query($sql);
2923
2924
        if (Database::num_rows($rs) > 0) {
2925
2926
            $user_ids = array();
2927
            while ($row = Database::fetch_array($rs)) {
2928
                $user_ids[] = $row['user_id'];
2929
            }
2930
2931
            $sql = "SELECT firstname, lastname, email FROM $tbl_user
2932
                    WHERE user_id IN (" . implode(",", $user_ids) . ")";
2933
            $rs_user = Database::query($sql);
2934
2935
            while ($row_emails = Database::fetch_array($rs_user)) {
2936
                $mail_tutor = array(
2937
                    'email' => $row_emails['email'],
2938
                    'complete_name' => api_get_person_name($row_emails['firstname'], $row_emails['lastname'])
2939
                );
2940
                $coachs_emails[] = $mail_tutor;
2941
            }
2942
        }
2943
        return $coachs_emails;
2944
    }
2945
2946
    /**
2947
     * Creates a new extra field for a given course
2948
     * @param    string    Field's internal variable name
2949
     * @param    int        Field's type
2950
     * @param    string    Field's language var name
2951
     * @param integer $fieldType
2952
     * @param string $default
2953
     * @return boolean     new extra field id
2954
     */
2955
    public static function create_course_extra_field($variable, $fieldType, $displayText, $default)
2956
    {
2957
        $extraField = new ExtraField('course');
2958
        $params = [
2959
            'variable' => $variable,
2960
            'field_type' => $fieldType,
2961
            'display_text' => $displayText,
2962
            'default_value' => $default
2963
        ];
2964
2965
        return $extraField->save($params);
2966
    }
2967
2968
    /**
2969
     * Updates course attribute. Note that you need to check that your
2970
     * attribute is valid before you use this function
2971
     *
2972
     * @param int $id Course id
2973
     * @param string $name Attribute name
2974
     * @param string $value Attribute value
2975
     *
2976
     * @return Doctrine\DBAL\Driver\Statement|null True if attribute was successfully updated,
2977
     * false if course was not found or attribute name is invalid
2978
     */
2979
    public static function update_attribute($id, $name, $value)
2980
    {
2981
        $id = (int)$id;
2982
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
2983
        $sql = "UPDATE $table SET $name = '" . Database::escape_string($value) . "'
2984
                WHERE id = '$id'";
2985
2986
        return Database::query($sql);
2987
    }
2988
2989
    /**
2990
     * Update course attributes. Will only update attributes with a non-empty value.
2991
     * Note that you NEED to check that your attributes are valid before using this function
2992
     *
2993
     * @param int Course id
2994
     * @param array Associative array with field names as keys and field values as values
2995
     * @return Doctrine\DBAL\Driver\Statement|null True if update was successful, false otherwise
2996
     */
2997
    public static function update_attributes($id, $attributes)
2998
    {
2999
        $id = (int)$id;
3000
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
3001
        $sql = "UPDATE $table SET ";
3002
        $i = 0;
3003
        foreach ($attributes as $name => $value) {
3004
            if ($value != '') {
3005
                if ($i > 0) {
3006
                    $sql .= ", ";
3007
                }
3008
                $sql .= " $name = '" . Database::escape_string($value) . "'";
3009
                $i++;
3010
            }
3011
        }
3012
        $sql .= " WHERE id = '$id'";
3013
3014
        return Database::query($sql);
3015
    }
3016
3017
    /**
3018
     * Update an extra field value for a given course
3019
     * @param    integer    Course ID
3020
     * @param    string    Field variable name
3021
     * @param    string    Field value
3022
     * @return    boolean|null    true if field updated, false otherwise
3023
     */
3024
    public static function update_course_extra_field_value($course_code, $variable, $value = '')
3025
    {
3026
        $courseInfo = api_get_course_info($course_code);
3027
        $courseId = $courseInfo['real_id'];
3028
3029
        $extraFieldValues = new ExtraFieldValue('course');
3030
        $params = [
3031
            'item_id' => $courseId,
3032
            'variable' => $variable,
3033
            'value' => $value
3034
        ];
3035
3036
        return $extraFieldValues->save($params);
3037
    }
3038
3039
    /**
3040
     * @param int $session_id
3041
     * @return mixed
3042
     */
3043
    public static function get_session_category_id_by_session_id($session_id)
3044
    {
3045
        if (empty($session_id)) {
3046
            return [];
3047
        }
3048
3049
        $sql = 'SELECT sc.id session_category
3050
                FROM ' . Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY) . ' sc
3051
                INNER JOIN ' . Database::get_main_table(TABLE_MAIN_SESSION) . ' s
3052
                ON sc.id = s.session_category_id 
3053
                WHERE s.id="' . intval($session_id) . '"';
3054
3055
        return Database::result(
3056
            Database::query($sql),
3057
            0,
3058
            'session_category'
3059
        );
3060
    }
3061
3062
    /**
3063
     * Gets the value of a course extra field. Returns null if it was not found
3064
     *
3065
     * @param string $variable Name of the extra field
3066
     * @param string $code Course code
3067
     *
3068
     * @return string Value
3069
     */
3070
    public static function get_course_extra_field_value($variable, $code)
3071
    {
3072
        $courseInfo = api_get_course_info($code);
3073
        $courseId = $courseInfo['real_id'];
3074
3075
        $extraFieldValues = new ExtraFieldValue('course');
3076
        $result = $extraFieldValues->get_values_by_handler_and_field_variable($courseId, $variable);
3077
        if (!empty($result['value'])) {
3078
            return $result['value'];
3079
        }
3080
3081
        return null;
3082
    }
3083
3084
    /**
3085
     * Lists details of the course description
3086
     * @param array        The course description
3087
     * @param string    The encoding
3088
     * @param bool        If true is displayed if false is hidden
3089
     * @return string     The course description in html
3090
     */
3091
    public static function get_details_course_description_html($descriptions, $charset, $action_show = true)
3092
    {
3093
        $data = null;
3094
        if (isset($descriptions) && count($descriptions) > 0) {
3095
            foreach ($descriptions as $description) {
3096
                $data .= '<div class="sectiontitle">';
3097
                if (api_is_allowed_to_edit() && $action_show) {
3098
                    //delete
3099
                    $data .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&action=delete&description_id=' . $description->id . '" onclick="javascript:if(!confirm(\'' . addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),
3100
                                ENT_QUOTES, $charset)) . '\')) return false;">';
3101
                    $data .= Display::return_icon('delete.gif', get_lang('Delete'),
3102
                        array('style' => 'vertical-align:middle;float:right;'));
3103
                    $data .= '</a> ';
3104
                    //edit
3105
                    $data .= '<a href="' . api_get_self() . '?' . api_get_cidreq() . '&description_id=' . $description->id . '">';
3106
                    $data .= Display::return_icon('edit.png', get_lang('Edit'),
3107
                        array('style' => 'vertical-align:middle;float:right; padding-right:4px;'), ICON_SIZE_SMALL);
3108
                    $data .= '</a> ';
3109
                }
3110
                $data .= $description->title;
3111
                $data .= '</div>';
3112
                $data .= '<div class="sectioncomment">';
3113
                $data .= $description->content;
3114
                $data .= '</div>';
3115
            }
3116
        } else {
3117
            $data .= '<em>' . get_lang('ThisCourseDescriptionIsEmpty') . '</em>';
3118
        }
3119
3120
        return $data;
3121
    }
3122
3123
    /**
3124
     * Returns the details of a course category
3125
     *
3126
     * @param string Category code
3127
     * @return array Course category
3128
     */
3129 View Code Duplication
    public static function get_course_category($code)
3130
    {
3131
        $table_categories = Database::get_main_table(TABLE_MAIN_CATEGORY);
3132
        $code = Database::escape_string($code);
3133
        $sql = "SELECT * FROM $table_categories WHERE code = '$code'";
3134
        return Database::fetch_array(Database::query($sql));
3135
    }
3136
3137
    /**
3138
     * Returns the details of a course category
3139
     *
3140
     * @param string Category code
3141
     * @return array Course category
3142
     */
3143
    public static function getCategoriesList()
3144
    {
3145
        $table_categories = Database::get_main_table(TABLE_MAIN_CATEGORY);
3146
        $sql = "SELECT * FROM $table_categories";
3147
        $result = Database::query($sql);
3148
        $category = array();
3149 View Code Duplication
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3150
            $category[$row['code']] = $row['name'];
3151
        }
3152
        return $category;
3153
    }
3154
3155
    /**
3156
     * Subscribes courses to human resource manager (Dashboard feature)
3157
     * @param    int   $hr_manager_id      Human Resource Manager id
3158
     * @param    array $courses_list       Courses code
3159
     * @return int
3160
     **/
3161
    public static function subscribeCoursesToDrhManager($hr_manager_id, $courses_list)
3162
    {
3163
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
3164
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
3165
3166
        $hr_manager_id = intval($hr_manager_id);
3167
        $affected_rows = 0;
3168
3169
        //Deleting assigned courses to hrm_id
3170
        if (api_is_multiple_url_enabled()) {
3171
            $sql = "SELECT s.c_id FROM $tbl_course_rel_user s
3172
                    INNER JOIN $tbl_course_rel_access_url a
3173
                    ON (a.c_id = s.c_id)
3174
                    WHERE
3175
                        user_id = $hr_manager_id AND
3176
                        relation_type=" . COURSE_RELATION_TYPE_RRHH . " AND
3177
                        access_url_id = " . api_get_current_access_url_id() . "";
3178
        } else {
3179
            $sql = "SELECT c_id FROM $tbl_course_rel_user
3180
                    WHERE user_id = $hr_manager_id AND relation_type=" . COURSE_RELATION_TYPE_RRHH . " ";
3181
        }
3182
        $result = Database::query($sql);
3183 View Code Duplication
        if (Database::num_rows($result) > 0) {
3184
            while ($row = Database::fetch_array($result)) {
3185
                $sql = "DELETE FROM $tbl_course_rel_user
3186
                        WHERE
3187
                            c_id = '{$row['c_id']}' AND
3188
                            user_id = $hr_manager_id AND
3189
                            relation_type=" . COURSE_RELATION_TYPE_RRHH . " ";
3190
                Database::query($sql);
3191
            }
3192
        }
3193
3194
        // inserting new courses list
3195
        if (is_array($courses_list)) {
3196
            foreach ($courses_list as $course_code) {
3197
                $courseInfo = api_get_course_info($course_code);
3198
                $courseId = $courseInfo['real_id'];
3199
                $sql = "INSERT IGNORE INTO $tbl_course_rel_user(c_id, user_id, status, relation_type)
3200
                        VALUES($courseId, $hr_manager_id, '" . DRH . "', '" . COURSE_RELATION_TYPE_RRHH . "')";
3201
                $result = Database::query($sql);
3202
                if (Database::affected_rows($result)) {
3203
                    $affected_rows++;
3204
                }
3205
            }
3206
        }
3207
3208
        return $affected_rows;
3209
    }
3210
3211
    /**
3212
     * get courses followed by human resources manager
3213
     * @param int $user_id
3214
     * @param int $status
3215
     * @param int $from
3216
     * @param int $limit
3217
     * @param string $column
3218
     * @param string $direction
3219
     * @param bool $getCount
3220
     *
3221
     * @return array    courses
3222
     */
3223
    public static function get_courses_followed_by_drh(
3224
        $user_id,
3225
        $status = DRH,
3226
        $from = null,
3227
        $limit = null,
3228
        $column = null,
3229
        $direction = null,
3230
        $getCount = false
3231
    ) {
3232
        return self::getCoursesFollowedByUser(
3233
            $user_id,
3234
            $status,
3235
            $from,
3236
            $limit,
3237
            $column,
3238
            $direction,
3239
            $getCount
3240
        );
3241
    }
3242
3243
    /**
3244
     * get courses followed by user
3245
     * @param   int $user_id
3246
     * @param   int $status
3247
     * @param   int $from
3248
     * @param   int $limit
3249
     * @param   string $column
3250
     * @param   string $direction
3251
     * @param   boolean $getCount
3252
     * @param   string $keyword
3253
     * @param   int $sessionId
3254
     * @param   boolean $showAllAssignedCourses
3255
     * @return  array   courses
3256
     */
3257
    public static function getCoursesFollowedByUser(
3258
        $user_id,
3259
        $status = null,
3260
        $from = null,
3261
        $limit = null,
3262
        $column = null,
3263
        $direction = null,
3264
        $getCount = false,
3265
        $keyword = null,
3266
        $sessionId = 0,
3267
        $showAllAssignedCourses = false
3268
    ) {
3269
        // Database Table Definitions
3270
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3271
        $tbl_course_rel_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
3272
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
3273
        $sessionId = (int) $sessionId;
3274
        $user_id = (int) $user_id;
3275
        $select = "SELECT DISTINCT *, c.id as real_id ";
3276
3277
        if ($getCount) {
3278
            $select = "SELECT COUNT(DISTINCT c.id) as count";
3279
        }
3280
3281
        $whereConditions = '';
3282
        switch ($status) {
3283
            case COURSEMANAGER:
3284
                $whereConditions .= " AND cru.user_id = '$user_id'";
3285
                if (!$showAllAssignedCourses) {
3286
                    $whereConditions .= " AND cru.status = " . COURSEMANAGER;
3287
                } else {
3288
                    $whereConditions .= " AND relation_type = " . COURSE_RELATION_TYPE_COURSE_MANAGER;
3289
                }
3290
                break;
3291
            case DRH:
3292
                $whereConditions .= " AND
3293
                    cru.user_id = '$user_id' AND
3294
                    cru.status = " . DRH . " AND
3295
                    relation_type = '" . COURSE_RELATION_TYPE_RRHH . "'
3296
                ";
3297
                break;
3298
        }
3299
3300
        $keywordCondition = null;
3301
        if (!empty($keyword)) {
3302
            $keyword = Database::escape_string($keyword);
3303
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3304
        }
3305
3306
        $orderBy = null;
3307
        $extraInnerJoin = null;
3308
3309
        if (!empty($sessionId)) {
3310
            if ($status == COURSEMANAGER) {
3311
                // Teacher of course or teacher inside session
3312
                $whereConditions = " AND (cru.status = " . COURSEMANAGER." OR srcru.status = 2) ";
3313
            }
3314
            $courseList = SessionManager::get_course_list_by_session_id(
3315
                $sessionId
3316
            );
3317
            if (!empty($courseList)) {
3318
                $courseListToString = implode("','", array_keys($courseList));
3319
                $whereConditions .= " AND c.id IN ('" . $courseListToString . "')";
3320
            }
3321
            $tableSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3322
            $tableSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3323
            $orderBy = ' ORDER BY position';
3324
            $extraInnerJoin = " INNER JOIN $tableSessionRelCourse src
3325
                                ON (c.id = src.c_id AND src.session_id = $sessionId)
3326
                                INNER JOIN $tableSessionRelCourseRelUser srcru 
3327
                                ON (src.session_id = srcru.session_id AND srcru.c_id = src.c_id)
3328
                            ";
3329
        }
3330
3331
        $whereConditions .= $keywordCondition;
3332
        $sql = "$select
3333
                FROM $tbl_course c
3334
                INNER JOIN $tbl_course_rel_user cru 
3335
                ON (cru.c_id = c.id)
3336
                INNER JOIN $tbl_course_rel_access_url a 
3337
                ON (a.c_id = c.id)
3338
                $extraInnerJoin
3339
                WHERE
3340
                    access_url_id = " . api_get_current_access_url_id() . "
3341
                    $whereConditions
3342
                $orderBy
3343
                ";
3344 View Code Duplication
        if (isset($from) && isset($limit)) {
3345
            $from = intval($from);
3346
            $limit = intval($limit);
3347
            $sql .= " LIMIT $from, $limit";
3348
        }
3349
3350
        $result = Database::query($sql);
3351
3352
        if ($getCount) {
3353
            $row = Database::fetch_array($result);
3354
            return $row['count'];
3355
        }
3356
3357
        $courses = array();
3358
        if (Database::num_rows($result) > 0) {
3359
            while ($row = Database::fetch_array($result)) {
3360
                $courses[$row['code']] = $row;
3361
            }
3362
        }
3363
3364
        return $courses;
3365
    }
3366
3367
    /**
3368
     * check if a course is special (autoregister)
3369
     * @param int $courseId
3370
     * @return bool
3371
     */
3372
    public static function isSpecialCourse($courseId)
3373
    {
3374
        $extraFieldValue = new ExtraFieldValue('course');
3375
        $result = $extraFieldValue->get_values_by_handler_and_field_variable(
3376
            $courseId,
3377
            'special_course'
3378
        );
3379
3380
        if (!empty($result)) {
3381
            if ($result['value'] == 1) {
3382
                return true;
3383
            }
3384
        }
3385
3386
        return false;
3387
    }
3388
3389
    /**
3390
     * Update course picture
3391
     * @param   array  $courseInfo
3392
     * @param   string  File name
3393
     * @param   string  The full system name of the image from which course picture will be created.
3394
     * @param   string $cropParameters Optional string that contents "x,y,width,height" of a cropped image format
3395
     * @return  bool    Returns the resulting. In case of internal error or negative validation returns FALSE.
3396
     */
3397
    public static function update_course_picture($courseInfo, $filename, $source_file = null, $cropParameters = null)
3398
    {
3399
        if (empty($courseInfo)) {
3400
            return false;
3401
        }
3402
3403
        // course path
3404
        $store_path = api_get_path(SYS_COURSE_PATH) . $courseInfo['path'];
3405
        // image name for courses
3406
        $course_image = $store_path . '/course-pic.png';
3407
        $course_medium_image = $store_path . '/course-pic85x85.png';
3408
3409
        if (file_exists($course_image)) {
3410
            unlink($course_image);
3411
        }
3412
        if (file_exists($course_medium_image)) {
3413
            unlink($course_medium_image);
3414
        }
3415
3416
        //Crop the image to adjust 4:3 ratio
3417
        $image = new Image($source_file);
3418
        $image->crop($cropParameters);
3419
3420
        //Resize the images in two formats
3421
        $medium = new Image($source_file);
3422
        $medium->resize(85);
3423
        $medium->send_image($course_medium_image, -1, 'png');
3424
        $normal = new Image($source_file);
3425
        $normal->resize(400);
3426
        $normal->send_image($course_image, -1, 'png');
3427
3428
        $result = $medium && $normal;
3429
3430
        return $result ? $result : false;
3431
    }
3432
3433
    /**
3434
     * Deletes the course picture
3435
     * @param string $courseCode
3436
     */
3437
    public static function deleteCoursePicture($courseCode)
3438
    {
3439
        $course_info = api_get_course_info($courseCode);
3440
        // course path
3441
        $storePath = api_get_path(SYS_COURSE_PATH) . $course_info['path'];
3442
        // image name for courses
3443
        $courseImage = $storePath . '/course-pic.png';
3444
        $courseMediumImage = $storePath . '/course-pic85x85.png';
3445
        $courseSmallImage = $storePath . '/course-pic32.png';
3446
3447
        if (file_exists($courseImage)) {
3448
            unlink($courseImage);
3449
        }
3450
        if (file_exists($courseMediumImage)) {
3451
            unlink($courseMediumImage);
3452
        }
3453
        if (file_exists($courseSmallImage)) {
3454
            unlink($courseSmallImage);
3455
        }
3456
    }
3457
3458
    /**
3459
     * Builds the course block in user_portal.php
3460
     * @todo use Twig
3461
     *
3462
     * @param array $params
3463
     * @return string
3464
     */
3465
    public static function course_item_html_no_icon($params)
3466
    {
3467
        $html = '<div class="course_item">';
3468
        $html .= '<div class="row">';
3469
        $html .= '<div class="col-md-7">';
3470
3471
        $notifications = isset($params['notifications']) ? $params['notifications'] : null;
3472
3473
        $html .= '<h3>' . $params['title'] . $notifications . '</h3> ';
3474
3475
        if (isset($params['description'])) {
3476
            $html .= '<p>' . $params['description'] . '</p>';
3477
        }
3478
        if (!empty($params['subtitle'])) {
3479
            $html .= '<small>' . $params['subtitle'] . '</small>';
3480
        }
3481 View Code Duplication
        if (!empty($params['teachers'])) {
3482
            $html .= '<h5 class="teacher">' . Display::return_icon('teacher.png', get_lang('Teacher'), array(),
3483
                    ICON_SIZE_TINY) . $params['teachers'] . '</h5>';
3484
        }
3485 View Code Duplication
        if (!empty($params['coaches'])) {
3486
            $html .= '<h5 class="teacher">' . Display::return_icon('teacher.png', get_lang('Coach'), array(),
3487
                    ICON_SIZE_TINY) . $params['coaches'] . '</h5>';
3488
        }
3489
3490
        $html .= '</div>';
3491
        $params['right_actions'] = isset($params['right_actions']) ? $params['right_actions'] : null;
3492
        $html .= '<div class="pull-right course-box-actions">' . $params['right_actions'] . '</div>';
3493
        $html .= '</div>';
3494
        $html .= '</div>';
3495
3496
        return $html;
3497
    }
3498
3499
    /**
3500
     * @param $params
3501
     * @param bool|false $is_sub_content
3502
     * @return string
3503
     */
3504
    public static function session_items_html($params, $is_sub_content = false)
3505
    {
3506
        $html = '';
3507
        $html .= '<div class="row">';
3508
        $html .= '<div class="col-md-2">';
3509
        if (!empty($params['link'])){
3510
            $html .= '<a class="thumbnail" href="'.$params['link'].'">';
3511
            $html .= $params['icon'];
3512
            $html .= '</a>';
3513
        }else{
3514
            $html .= $params['icon'];
3515
        }
3516
        $html .= '</div>';
3517
        $html .= '<div class="col-md-10">';
3518
        $html .= $params['title'];
3519
        $html .= $params['coaches'];
3520
        $html .= '</div>';
3521
        $html .= '</div>';
3522
3523
        return $html;
3524
    }
3525
3526
    /**
3527
     * Display special courses (and only these) as several HTML divs of class userportal-course-item
3528
     *
3529
     * Special courses are courses that stick on top of the list and are "auto-registerable"
3530
     * in the sense that any user clicking them is registered as a student
3531
     * @param int       $user_id User id
3532
     * @param bool      $load_dirs Whether to show the document quick-loader or not
3533
     * @return string
3534
     */
3535
    public static function returnSpecialCourses($user_id, $load_dirs = false)
3536
    {
3537
        $user_id = intval($user_id);
3538
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
3539
        $specialCourseList = self::get_special_course_list();
3540
3541
        if (empty($specialCourseList)) {
3542
            return [];
3543
        }
3544
3545
        $sql = "SELECT
3546
                    id,
3547
                    code,
3548
                    subscribe subscr,
3549
                    unsubscribe unsubscr
3550
                FROM $table                      
3551
                WHERE 
3552
                    id IN ('".implode("','", $specialCourseList)."')
3553
                GROUP BY code";
3554
3555
        $rs_special_course = Database::query($sql);
3556
        $number_of_courses = Database::num_rows($rs_special_course);
3557
        $showCustomIcon = api_get_setting('course_images_in_courses_list');
3558
3559
        $courseList = [];
3560
        if ($number_of_courses > 0) {
3561
            while ($course = Database::fetch_array($rs_special_course)) {
3562
                $course_info = api_get_course_info($course['code']);
3563
                $courseId = $course_info['real_id'];
3564
                if ($course_info['visibility'] == COURSE_VISIBILITY_HIDDEN) {
3565
                    continue;
3566
                }
3567
3568
                $params = [];
3569
                //Param (course_code) needed to get the student info in page "My courses"
3570
                $params['course_code'] = $course['code'];
3571
                // Get notifications.
3572
                $course_info['id_session'] = null;
3573
                $courseUserInfo = self::getUserCourseInfo($user_id, $courseId);
3574
3575
                if (empty($courseUserInfo)) {
3576
                    $course_info['status'] = STUDENT;
3577
                } else {
3578
                    $course_info['status'] = $courseUserInfo['status'];
3579
                }
3580
                $show_notification = !api_get_configuration_value('hide_course_notification')
3581
                    ? Display::show_notification($course_info)
3582
                    : '';
3583
                $params['edit_actions'] = '';
3584
                $params['document'] = '';
3585
                if (api_is_platform_admin()) {
3586
                    $params['edit_actions'] .= api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course['code'];
3587
                    if ($load_dirs) {
3588
                        $params['document'] = '<a id="document_preview_' . $courseId . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
3589
                           . Display::returnFontAwesomeIcon('folder-open') . '</a>';
3590
                        $params['document'] .= Display::div('', ['id' => 'document_result_' . $courseId . '_0', 'class' => 'document_preview_container']);
3591
                    }
3592
                } else {
3593
                    if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED && $load_dirs) {
3594
                        $params['document'] = '<a id="document_preview_' . $courseId . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
3595
                           . Display::returnFontAwesomeIcon('folder-open') . '</a>';
3596
                        $params['document'] .= Display::div('', ['id' => 'document_result_' . $courseId . '_0', 'class' => 'document_preview_container']);
3597
                    }
3598
                }
3599
3600
                $params['visibility'] = $course_info['visibility'];
3601
                $params['status'] = $course_info['status'];
3602
                $params['category'] = $course_info['categoryName'];
3603
                $params['icon'] = Display::return_icon('drawing-pin.png',null, null, ICON_SIZE_LARGE, null);
3604
3605 View Code Duplication
                if (api_get_setting('display_coursecode_in_courselist') == 'true') {
3606
                    $params['code_course']  = '(' . $course_info['visual_code'] . ')';
3607
                }
3608
3609
                $params['title'] = $course_info['title'];
3610
                $params['title_cut'] = cut($course_info['title'], 45);
3611
                $params['link'] = $course_info['course_public_url'].'?id_session=0&autoreg=1';
3612
                if (api_get_setting('display_teacher_in_courselist') === 'true') {
3613
                    $params['teachers'] = self::getTeachersFromCourse($courseId, true);
3614
                }
3615
3616
                if ($showCustomIcon === 'true') {
3617
                    $params['thumbnails'] = $course_info['course_image'];
3618
                    $params['image'] = $course_info['course_image_large'];
3619
                }
3620
3621
                if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
3622
                    $params['notifications'] = $show_notification;
3623
                }
3624
3625
                $params['is_special_course'] = true;
3626
                $courseList[] = $params;
3627
            }
3628
        }
3629
3630
        return $courseList;
3631
    }
3632
3633
    /**
3634
     * Display courses (without special courses) as several HTML divs
3635
     * of course categories, as class userportal-catalog-item.
3636
     * @uses displayCoursesInCategory() to display the courses themselves
3637
     * @param int $user_id
3638
     * @param bool  $load_dirs Whether to show the document quick-loader or not
3639
     * @param integer $user_id
3640
     * @return string
3641
     */
3642
    public static function returnCourses($user_id, $load_dirs = false)
3643
    {
3644
        $user_id = intval($user_id);
3645
        if (empty($user_id)) {
3646
            $user_id = api_get_user_id();
3647
        }
3648
        // Step 1: We get all the categories of the user
3649
        $table = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
3650
        $sql = "SELECT id, title FROM $table
3651
                WHERE user_id = '" . $user_id . "'
3652
                ORDER BY sort ASC";
3653
3654
        $result = Database::query($sql);
3655
        $listItems = [
3656
            'in_category' => [],
3657
            'not_category' => []
3658
        ];
3659
        while ($row = Database::fetch_array($result)) {
3660
            // We simply display the title of the category.
3661
            $courseInCategory = self::returnCoursesCategories(
3662
                $row['id'],
3663
                $load_dirs
3664
            );
3665
3666
            $params = [
3667
                'id_category' => $row ['id'],
3668
                'title_category' => $row['title'],
3669
                'courses' => $courseInCategory
3670
            ];
3671
            $listItems['in_category'][] = $params;
3672
        }
3673
3674
        // Step 2: We display the course without a user category.
3675
        $coursesNotCategory = self::returnCoursesCategories(0, $load_dirs);
3676
3677
        if ($coursesNotCategory) {
3678
            $listItems['not_category'] = $coursesNotCategory;
3679
        }
3680
3681
        return $listItems;
3682
    }
3683
3684
    /**
3685
     *  Display courses inside a category (without special courses) as HTML dics of
3686
     *  class userportal-course-item.
3687
     * @param int      $user_category_id User category id
3688
     * @param bool     $load_dirs Whether to show the document quick-loader or not
3689
     * @return string
3690
     */
3691
    public static function returnCoursesCategories($user_category_id, $load_dirs = false)
3692
    {
3693
        $user_id = api_get_user_id();
3694
        $user_category_id = (int) $user_category_id;
3695
3696
        // Table definitions
3697
        $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
3698
        $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
3699
        $TABLE_ACCESS_URL_REL_COURSE = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
3700
        $current_url_id = api_get_current_access_url_id();
3701
3702
        // Get course list auto-register
3703
        $special_course_list = self::get_special_course_list();
3704
        $without_special_courses = '';
3705
        if (!empty($special_course_list)) {
3706
            $without_special_courses = ' AND course.id NOT IN ("' . implode('","', $special_course_list) . '")';
3707
        }
3708
3709
        $userCategoryCondition = " (course_rel_user.user_course_cat = $user_category_id) ";
3710
        if (empty($user_category_id)) {
3711
            $userCategoryCondition = ' (course_rel_user.user_course_cat = 0 OR course_rel_user.user_course_cat IS NULL) ';
3712
        }
3713
3714
        $sql = "SELECT DISTINCT
3715
                    course.id,
3716
                    course_rel_user.status status,
3717
                    course.code as course_code
3718
                FROM $TABLECOURS course 
3719
                INNER JOIN $TABLECOURSUSER course_rel_user
3720
                ON (course.id = course_rel_user.c_id)
3721
                INNER JOIN $TABLE_ACCESS_URL_REL_COURSE url
3722
                ON (url.c_id = course.id)
3723
                WHERE
3724
                    course_rel_user.user_id = '" . $user_id . "' AND
3725
                    $userCategoryCondition
3726
                    $without_special_courses ";
3727
3728
        // If multiple URL access mode is enabled, only fetch courses
3729
        // corresponding to the current URL.
3730
        if (api_get_multiple_access_url() && $current_url_id != -1) {
3731
            $sql .= " AND access_url_id='" . $current_url_id . "'";
3732
        }
3733
        // Use user's classification for courses (if any).
3734
        $sql .= " ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
3735
        $result = Database::query($sql);
3736
3737
        $courseList = array();
3738
        $showCustomIcon = api_get_setting('course_images_in_courses_list');
3739
        // Browse through all courses.
3740
        $courseAdded = [];
3741
        while ($row = Database::fetch_array($result)) {
3742
            $course_info = api_get_course_info_by_id($row['id']);
3743
            if (isset($course_info['visibility']) &&
3744
                $course_info['visibility'] == COURSE_VISIBILITY_HIDDEN
3745
            ) {
3746
                continue;
3747
            }
3748
3749
            // Skip if already in list
3750
            if (in_array($course_info['real_id'], $courseAdded)) {
3751
                continue;
3752
            }
3753
            $course_info['id_session'] = null;
3754
            $course_info['status'] = $row['status'];
3755
            // For each course, get if there is any notification icon to show
3756
            // (something that would have changed since the user's last visit).
3757
            $showNotification = !api_get_configuration_value('hide_course_notification')
3758
                ? Display::show_notification($course_info)
3759
                : '';
3760
            $iconName = basename($course_info['course_image']);
3761
3762
            $params = array();
3763
            //Param (course_code) needed to get the student process
3764
            $params['course_code'] = $row['course_code'];
3765
3766
            if ($showCustomIcon === 'true' && $iconName != 'course.png') {
3767
                $params['thumbnails'] = $course_info['course_image'];
3768
                $params['image'] = $course_info['course_image_large'];
3769
            }
3770
3771
            $thumbnails = null;
3772
            $image = null;
3773
3774 View Code Duplication
            if ($showCustomIcon === 'true' && $iconName != 'course.png') {
3775
                $thumbnails = $course_info['course_image'];
3776
                $image = $course_info['course_image_large'];
3777
            }else{
3778
                $image = Display::return_icon('session_default.png', null, null, null,null, true);
3779
            }
3780
3781
            $params['course_id'] = $course_info['real_id'];
3782
            $params['edit_actions'] = '';
3783
            $params['document'] = '';
3784 View Code Duplication
            if (api_is_platform_admin()) {
3785
                $params['edit_actions'] .= api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course_info['code'];
3786
                if ($load_dirs) {
3787
                    $params['document'] = '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
3788
                               . Display::returnFontAwesomeIcon('folder-open') . '</a>';
3789
                    $params['document'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container'));
3790
                }
3791
            }
3792
            if ($load_dirs) {
3793
                $params['document'] = '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
3794
                    . Display::returnFontAwesomeIcon('folder-open') . '</a>';
3795
                $params['document'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container'));
3796
            }
3797
3798
            $courseUrl = api_get_path(WEB_COURSE_PATH) . $course_info['path'] . '/index.php?id_session=0';
3799
            $teachers = [];
3800
            if (api_get_setting('display_teacher_in_courselist') === 'true') {
3801
                $teachers = self::getTeachersFromCourse($course_info['real_id'], false);
3802
            }
3803
3804
            $params['status'] = $row['status'];
3805 View Code Duplication
            if (api_get_setting('display_coursecode_in_courselist') == 'true') {
3806
                $params['code_course'] = '(' . $course_info['visual_code'] . ') ';
3807
            }
3808
3809
            $params['current_user_is_teacher'] = false;
3810
3811
            /** @var array $teacher */
3812
            foreach ($teachers as $teacher) {
0 ignored issues
show
Bug introduced by
The expression $teachers of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
3813
                if ($teacher['id'] != $user_id) {
3814
                    continue;
3815
                }
3816
3817
                $params['current_user_is_teacher'] = true;
3818
            }
3819
3820
            $params['visibility'] = $course_info['visibility'];
3821
            $params['link'] = $courseUrl;
3822
            $params['thumbnails'] = $thumbnails;
3823
            $params['image'] = $image;
3824
            $params['title'] = $course_info['title'];
3825
            $params['title_cut'] = cut($course_info['title'], 45);
3826
            $params['category'] = $course_info['categoryName'];
3827
            $params['teachers'] = $teachers;
3828
3829
            if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
3830
                $params['notifications'] = $showNotification;
3831
            }
3832
            $courseAdded[] = $course_info['real_id'];
3833
            $courseList[] = $params;
3834
        }
3835
3836
        return $courseList;
3837
    }
3838
3839
    /**
3840
     *  Display courses inside a category (without special courses) as HTML dics of
3841
     *  class userportal-course-item.
3842
     * @deprecated use self::returnCoursesCategories(0);
3843
     * @param int      User category id
3844
     * @param bool      Whether to show the document quick-loader or not
3845
     * @return string
3846
     */
3847
    public static function returnCoursesWithoutCategories($user_category_id, $load_dirs = false)
3848
    {
3849
        $user_id = api_get_user_id();
3850
        // Table definitions
3851
        $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
3852
        $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
3853
        $TABLE_ACCESS_URL_REL_COURSE = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
3854
        $current_url_id = api_get_current_access_url_id();
3855
        $courseList = [];
3856
3857
        // Get course list auto-register
3858
        $special_course_list = self::get_special_course_list();
3859
3860
        $without_special_courses = '';
3861
        if (!empty($special_course_list)) {
3862
            $without_special_courses = ' AND course.id NOT IN ("' . implode('","', $special_course_list) . '")';
3863
        }
3864
3865
        $sql = "SELECT
3866
                    course.id,
3867
                    course.title,
3868
                    course.code,
3869
                    course.subscribe subscr,
3870
                    course.unsubscribe unsubscr,
3871
                    course_rel_user.status status,
3872
                    course_rel_user.sort sort,
3873
                    course_rel_user.user_course_cat user_course_cat
3874
                FROM $TABLECOURS course 
3875
                INNER JOIN $TABLECOURSUSER course_rel_user
3876
                ON (course.id = course_rel_user.c_id)
3877
                INNER JOIN $TABLE_ACCESS_URL_REL_COURSE url
3878
                ON (url.c_id = course.id)
3879
                WHERE
3880
                    course_rel_user.user_id = '" . $user_id . "' AND
3881
                    course_rel_user.user_course_cat = '" . $user_category_id . "'
3882
                    $without_special_courses ";
3883
3884
        // If multiple URL access mode is enabled, only fetch courses
3885
        // corresponding to the current URL.
3886
        if (api_get_multiple_access_url() && $current_url_id != -1) {
3887
            $sql .= " AND url.c_id = course.id AND access_url_id='" . $current_url_id . "'";
3888
        }
3889
        // Use user's classification for courses (if any).
3890
        $sql .= " ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
3891
        $result = Database::query($sql);
3892
3893
        $showCustomIcon = api_get_setting('course_images_in_courses_list');
3894
        // Browse through all courses.
3895
        while ($row = Database::fetch_array($result)) {
3896
            $course_info = api_get_course_info($row['code']);
3897
            if (isset($course_info['visibility']) &&
3898
                $course_info['visibility'] == COURSE_VISIBILITY_HIDDEN
3899
            ) {
3900
                continue;
3901
            }
3902
            $course_info['id_session'] = null;
3903
            $course_info['status'] = $row['status'];
3904
3905
            // For each course, get if there is any notification icon to show
3906
            // (something that would have changed since the user's last visit).
3907
            $showNotification = !api_get_configuration_value('hide_course_notification')
3908
                ? Display::show_notification($course_info)
3909
                : '';
3910
3911
            $thumbnails = null;
3912
            $image = null;
3913
3914
            $iconName = basename($course_info['course_image']);
3915 View Code Duplication
            if ($showCustomIcon === 'true' && $iconName != 'course.png') {
3916
                $thumbnails = $course_info['course_image'];
3917
                $image = $course_info['course_image_large'];
3918
            }else{
3919
                $image = Display::return_icon('session_default.png', null, null, null,null, true);
3920
            }
3921
3922
            $params = array();
3923
            //Param (course_code) needed to get the student process
3924
            $params['course_code'] = $row['code'];
3925
            $params['edit_actions'] = '';
3926
            $params['document'] = '';
3927 View Code Duplication
            if (api_is_platform_admin()) {
3928
                $params['edit_actions'] .= api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course_info['code'];
3929
                if($load_dirs){
3930
                    $params['document'] = '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
3931
                               . Display::returnFontAwesomeIcon('folder-open') . '</a>';
3932
                    $params['document'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container'));
3933
                }
3934
            }
3935
            if ($load_dirs) {
3936
                $params['document'] = '<a id="document_preview_' . $course_info['real_id'] . '_0" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">'
3937
                    . Display::returnFontAwesomeIcon('folder-open') . '</a>';
3938
                $params['document'] .= Display::div('', array('id' => 'document_result_' . $course_info['real_id'] . '_0', 'class' => 'document_preview_container'));
3939
            }
3940
3941
            $course_title_url = api_get_path(WEB_COURSE_PATH) . $course_info['path'] . '/index.php?id_session=0';
3942
3943
            $teachers = [];
3944
            if (api_get_setting('display_teacher_in_courselist') === 'true') {
3945
                $teachers = self::getTeachersFromCourse($course_info['real_id'], false);
3946
            }
3947
            $params['status'] = $row['status'];
3948
3949 View Code Duplication
            if (api_get_setting('display_coursecode_in_courselist') == 'true') {
3950
                $params['code_course'] = '(' . $course_info['visual_code'] . ') ';
3951
            }
3952
3953
            $params['visibility'] = $course_info['visibility'];
3954
            $params['link'] = $course_title_url;
3955
            $params['thumbnails'] = $thumbnails;
3956
            $params['image'] = $image;
3957
            $params['title'] = $course_info['title'];
3958
            $params['category'] = $course_info['categoryName'];
3959
            $params['teachers'] = $teachers;
3960
3961
            if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
3962
                $params['notifications'] = $showNotification;
3963
            }
3964
3965
            $courseList[] = $params;
3966
        }
3967
3968
        return $courseList;
3969
    }
3970
3971
    /**
3972
     * Retrieves the user defined course categories
3973
     * @param int $userId
3974
     * @return array
3975
     */
3976 View Code Duplication
    public static function get_user_course_categories($userId = 0)
3977
    {
3978
        $userId = empty($userId) ? api_get_user_id() : (int) $userId;
3979
        $table_category = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
3980
        $sql = "SELECT * FROM $table_category 
3981
                WHERE user_id = $userId
3982
                ORDER BY sort ASC
3983
                ";
3984
        $result = Database::query($sql);
3985
        $output = array();
3986
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3987
            $output[$row['id']] = $row;
3988
        }
3989
        return $output;
3990
    }
3991
3992
    /**
3993
     * Return an array the user_category id and title for the course $courseId for user $userId
3994
     * @param $userId
3995
     * @param $courseId
3996
     * @return array
3997
     */
3998 View Code Duplication
    public static function getUserCourseCategoryForCourse($userId, $courseId)
3999
    {
4000
        $tblCourseRelUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
4001
        $tblUserCategory = Database::get_main_table(TABLE_USER_COURSE_CATEGORY);
4002
        $courseId = intval($courseId);
4003
        $userId = intval($userId);
4004
4005
        $sql = "SELECT user_course_cat, title
4006
                FROM $tblCourseRelUser cru
4007
                LEFT JOIN $tblUserCategory ucc
4008
                ON cru.user_course_cat = ucc.id
4009
                WHERE
4010
                    cru.user_id = $userId AND c_id= $courseId ";
4011
4012
        $res = Database::query($sql);
4013
4014
        $data = array();
4015
        if (Database::num_rows($res) > 0) {
4016
            $data = Database::fetch_assoc($res);
4017
        }
4018
4019
        return $data;
4020
    }
4021
4022
    /**
4023
     * Get the course id based on the original id and field name in the extra fields.
4024
     * Returns 0 if course was not found
4025
     *
4026
     * @param string $value Original course code
4027
     * @param string $variable Original field name
4028
     * @return array
4029
     */
4030
    public static function getCourseInfoFromOriginalId($value, $variable)
4031
    {
4032
        $extraFieldValue = new ExtraFieldValue('course');
4033
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
4034
            $variable,
4035
            $value
4036
        );
4037
4038
        if (!empty($result)) {
4039
            $courseInfo = api_get_course_info_by_id($result['item_id']);
4040
            return $courseInfo;
4041
        }
4042
4043
        return [];
4044
    }
4045
4046
    /**
4047
     * Display code for one specific course a logged in user is subscribed to.
4048
     * Shows a link to the course, what's new icons...
4049
     *
4050
     * $my_course['d'] - course directory
4051
     * $my_course['i'] - course title
4052
     * $my_course['c'] - visual course code
4053
     * $my_course['k']  - system course code
4054
     *
4055
     * @param   array       Course details
4056
     * @param   integer     Session ID
4057
     * @param   string      CSS class to apply to course entry
4058
     * @param   boolean     Whether the session is supposedly accessible now
4059
     * (not in the case it has passed and is in invisible/unaccessible mode)
4060
     * @param bool      Whether to show the document quick-loader or not
4061
     * @return  string      The HTML to be printed for the course entry
4062
     *
4063
     * @version 1.0.3
4064
     * @todo refactor into different functions for database calls | logic | display
4065
     * @todo replace single-character $my_course['d'] indices
4066
     * @todo move code for what's new icons to a separate function to clear things up
4067
     * @todo add a parameter user_id so that it is possible to show the
4068
     * courselist of other users (=generalisation).
4069
     * This will prevent having to write a new function for this.
4070
     */
4071
    public static function get_logged_user_course_html(
4072
        $course,
4073
        $session_id = 0,
4074
        $class = 'courses',
4075
        $session_accessible = true,
4076
        $load_dirs = false
4077
    ) {
4078
        $now = date('Y-m-d h:i:s');
4079
        $user_id = api_get_user_id();
4080
        $course_info = api_get_course_info_by_id($course['real_id']);
4081
        $course_visibility = $course_info['visibility'];
4082
4083
        if ($course_visibility == COURSE_VISIBILITY_HIDDEN) {
4084
            return '';
4085
        }
4086
4087
        $userInCourseStatus = self::getUserInCourseStatus(
4088
            $user_id,
4089
            $course_info['real_id']
4090
        );
4091
4092
        $course_info['status'] = empty($session_id) ? $userInCourseStatus : STUDENT;
4093
        $course_info['id_session'] = $session_id;
4094
4095
        $is_coach = api_is_coach($session_id, $course_info['real_id']);
4096
4097
        // Display course entry.
4098
        // Show a hyperlink to the course, unless the course is closed and user is not course admin.
4099
        $session_url = '';
4100
        $params = array();
4101
        $params['icon'] = Display::return_icon(
4102
            'blackboard_blue.png',
4103
            null,
4104
            array(),
4105
            ICON_SIZE_LARGE,
4106
            null,
4107
            true
4108
        );
4109
4110
        // Display the "what's new" icons
4111
        $notifications = '';
4112
        if (
4113
            ($course_visibility != COURSE_VISIBILITY_CLOSED && $course_visibility != COURSE_VISIBILITY_HIDDEN) ||
4114
            !api_get_configuration_value('hide_course_notification')
4115
        ) {
4116
            $notifications .= Display::show_notification($course_info);
4117
        }
4118
4119
        if ($session_accessible) {
4120
            if ($course_visibility != COURSE_VISIBILITY_CLOSED ||
4121
                $userInCourseStatus == COURSEMANAGER
4122
            ) {
4123
                if (empty($course_info['id_session'])) {
4124
                    $course_info['id_session'] = 0;
4125
                }
4126
4127
                $sessionCourseAvailable = false;
4128
                $sessionCourseStatus = api_get_session_visibility($session_id, $course_info['real_id']);
4129
4130
                if (in_array($sessionCourseStatus,
4131
                    array(SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_AVAILABLE))) {
4132
                    $sessionCourseAvailable = true;
4133
                }
4134
4135
                if ($userInCourseStatus == COURSEMANAGER || $sessionCourseAvailable) {
4136
                    $session_url = $course_info['course_public_url'] . '?id_session=' . $course_info['id_session'];
4137
                    $session_title = '<a href="' . $session_url. '">'. $course_info['name'] . '</a>'.$notifications;
4138
                } else {
4139
                    $session_title = $course_info['name'];
4140
                }
4141
4142
            } else {
4143
                $session_title =
4144
                    $course_info['name'] . ' ' .
4145
                    Display::tag('span', get_lang('CourseClosed'), array('class' => 'item_closed'));
4146
            }
4147
        } else {
4148
            $session_title = $course_info['name'];
4149
        }
4150
4151
        $thumbnails = null;
4152
        $image = null;
4153
        $showCustomIcon = api_get_setting('course_images_in_courses_list');
4154
        $iconName = basename($course_info['course_image']);
4155
4156 View Code Duplication
        if ($showCustomIcon === 'true' && $iconName != 'course.png') {
4157
            $thumbnails = $course_info['course_image'];
4158
            $image = $course_info['course_image_large'];
4159
        } else {
4160
            $image = Display::return_icon('session_default.png', null, null, null,null, true);
4161
        }
4162
        $params['thumbnails'] = $thumbnails;
4163
        $params['image'] = $image;
4164
        $params['link'] = $session_url;
4165
        $params['title'] = $session_title;
4166
        $params['edit_actions'] = '';
4167
        $params['document'] = '';
4168
        $params['category'] = $course_info['categoryName'];
4169
4170
        if ($course_visibility != COURSE_VISIBILITY_CLOSED &&
4171
            $course_visibility != COURSE_VISIBILITY_HIDDEN
4172
        ) {
4173
            if (api_is_platform_admin()) {
4174
                $params['edit_actions'] .= api_get_path(WEB_CODE_PATH) . 'course_info/infocours.php?cidReq=' . $course_info['code'];
4175
                if ($load_dirs) {
4176
                    $params['document'] .= '<a id="document_preview_' . $course_info['real_id'] . '_' . $course_info['id_session'] . '" class="document_preview btn btn-default btn-sm" href="javascript:void(0);">' .
4177
                        Display::returnFontAwesomeIcon('folder-open') . '</a>';
4178
                    $params['document'] .= Display::div('', array(
4179
                        'id' => 'document_result_' . $course_info['real_id'] . '_' . $course_info['id_session'],
4180
                        'class' => 'document_preview_container'
4181
                    ));
4182
                }
4183
            }
4184
        }
4185
4186
        if (api_get_setting('display_coursecode_in_courselist') === 'true') {
4187
            $session_title .= ' (' . $course_info['visual_code'] . ') ';
4188
        }
4189
4190
        if (api_get_setting('display_teacher_in_courselist') === 'true') {
4191
            $teacher_list = self::getTeachersFromCourse(
4192
                $course_info['real_id'],
4193
                true
4194
            );
4195
4196
            $course_coachs = self::get_coachs_from_course(
4197
                $course_info['id_session'],
4198
                $course_info['real_id']
4199
            );
4200
            $params['teachers'] = $teacher_list;
4201
4202
            if (($course_info['status'] == STUDENT && !empty($course_info['id_session'])) ||
4203
                ($is_coach && $course_info['status'] != COURSEMANAGER)
4204
            ) {
4205
                $params['coaches'] = $course_coachs;
4206
            }
4207
        }
4208
4209
        $session_title .= isset($course['special_course']) ? ' ' .
4210
                          Display::return_icon('klipper.png', get_lang('CourseAutoRegister')) : '';
4211
4212
        $params['title'] = $session_title;
4213
        $params['extra'] = '';
4214
        $html = $params;
4215
4216
        $session_category_id = null;
4217
        if (1) {
4218
            $session = '';
4219
            $active = false;
4220
            if (!empty($course_info['id_session'])) {
4221
                $session = api_get_session_info($course_info['id_session']);
4222
                $sessionCoachName = '';
4223
                if (!empty($session['id_coach'])) {
4224
                    $coachInfo = api_get_user_info($session['id_coach']);
4225
                    $sessionCoachName = $coachInfo['complete_name'];
4226
                }
4227
4228
                $session_category_id = self::get_session_category_id_by_session_id($course_info['id_session']);
4229
4230
                if (
4231
                    $session['access_start_date'] == '0000-00-00 00:00:00' || empty($session['access_start_date']) ||
4232
                    $session['access_start_date'] == '0000-00-00'
4233
                ) {
4234
                    $session['dates'] = '';
4235 View Code Duplication
                    if (api_get_setting('show_session_coach') === 'true') {
4236
                        $session['coach'] = get_lang('GeneralCoach') . ': ' . $sessionCoachName;
4237
                    }
4238
                    $active = true;
4239
                } else {
4240
                    $session ['dates'] = ' - ' . get_lang('From') . ' ' . $session['access_start_date'] . ' ' . get_lang('To') . ' ' . $session['access_end_date'];
4241 View Code Duplication
                    if (api_get_setting('show_session_coach') === 'true') {
4242
                        $session['coach'] = get_lang('GeneralCoach') . ': ' . $sessionCoachName;
4243
                    }
4244
                    $date_start = $session['access_start_date'];
4245
                    $date_end = $session['access_end_date'];
4246
                    $active = !$date_end ? ($date_start <= $now) : ($date_start <= $now && $date_end >= $now);
4247
                }
4248
            }
4249
            $user_course_category = '';
4250
            if (isset($course_info['user_course_cat'])) {
4251
                $user_course_category = $course_info['user_course_cat'];
4252
            }
4253
            $output = array(
4254
                $user_course_category,
4255
                $html,
4256
                $course_info['id_session'],
4257
                $session,
4258
                'active' => $active,
4259
                'session_category_id' => $session_category_id
4260
            );
4261
4262
            if (api_get_setting('allow_skills_tool') === 'true') {
4263
                $entityManager = Database::getManager();
4264
                $objUser = $entityManager->find('ChamiloUserBundle:User', $user_id);
4265
                $objCourse = $entityManager->find('ChamiloCoreBundle:Course', $course['real_id']);
4266
                $objSession = $entityManager->find('ChamiloCoreBundle:Session', $session_id);
4267
4268
                $skill = $entityManager
4269
                    ->getRepository('ChamiloCoreBundle:Skill')
4270
                    ->getLastByUser($objUser, $objCourse, $objSession);
4271
4272
                $output['skill'] = null;
4273
4274
                if ($skill) {
4275
                    $output['skill']['name'] = $skill->getName();
4276
                    $output['skill']['icon'] = $skill->getIcon();
4277
                }
4278
            }
4279
        } else {
4280
            $output = array($course_info['user_course_cat'], $html);
4281
        }
4282
4283
        return $output;
4284
    }
4285
4286
    /**
4287
     *
4288
     * @param    string    source course code
4289
     * @param     int        source session id
4290
     * @param    string    destination course code
4291
     * @param     int        destination session id
4292
     * @param integer $source_session_id
4293
     * @param integer $destination_session_id
4294
     * @return  bool
4295
     */
4296
    public static function copy_course(
4297
        $source_course_code,
4298
        $source_session_id,
4299
        $destination_course_code,
4300
        $destination_session_id,
4301
        $params = array()
4302
    ) {
4303
        $course_info = api_get_course_info($source_course_code);
4304
4305
        if (!empty($course_info)) {
4306
            $cb = new CourseBuilder('', $course_info);
4307
            $course = $cb->build($source_session_id, $source_course_code, true);
4308
            $course_restorer = new CourseRestorer($course);
4309
            $course_restorer->skip_content = $params;
4310
            $course_restorer->restore($destination_course_code, $destination_session_id, true, true);
4311
            return true;
4312
        }
4313
        return false;
4314
    }
4315
4316
    /**
4317
     * A simpler version of the copy_course, the function creates an empty course with an autogenerated course code
4318
     *
4319
     * @param    string    new course title
4320
     * @param    string    source course code
4321
     * @param     int        source session id
4322
     * @param     int        destination session id
4323
     * @param    bool    new copied tools (Exercises and LPs)will be set to invisible by default?
4324
     * @param string $new_title
4325
     *
4326
     * @return     array
4327
     */
4328
    public static function copy_course_simple(
4329
        $new_title,
4330
        $source_course_code,
4331
        $source_session_id = 0,
4332
        $destination_session_id = 0,
4333
        $params = array()
4334
    ) {
4335
        $source_course_info = api_get_course_info($source_course_code);
4336
        if (!empty($source_course_info)) {
4337
            $new_course_code = self::generate_nice_next_course_code($source_course_code);
4338
            if ($new_course_code) {
4339
                $new_course_info = self::create_course($new_title, $new_course_code, false);
4340
                if (!empty($new_course_info['code'])) {
4341
                    $result = self::copy_course($source_course_code, $source_session_id, $new_course_info['code'],
4342
                        $destination_session_id, $params);
4343
                    if ($result) {
4344
                        return $new_course_info;
4345
                    }
4346
                }
4347
            }
4348
        }
4349
4350
        return false;
4351
    }
4352
4353
    /**
4354
     * Creates a new course code based in a given code
4355
     *
4356
     * @param string    wanted code
4357
     * <code>    $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3</code>
4358
     * if the course code doest not exist in the DB the same course code will be returned
4359
     * @return string    wanted unused code
4360
     */
4361
    public static function generate_nice_next_course_code($wanted_code)
4362
    {
4363
        $course_code_ok = !self::course_code_exists($wanted_code);
4364 View Code Duplication
        if (!$course_code_ok) {
4365
            $wanted_code = self::generate_course_code($wanted_code);
4366
            $table = Database::get_main_table(TABLE_MAIN_COURSE);
4367
            $wanted_code = Database::escape_string($wanted_code);
4368
            $sql = "SELECT count(id) as count
4369
                    FROM $table
4370
                    WHERE code LIKE '$wanted_code%'";
4371
            $result = Database::query($sql);
4372
            if (Database::num_rows($result) > 0) {
4373
                $row = Database::fetch_array($result);
4374
                $count = $row['count'] + 1;
4375
                $wanted_code = $wanted_code . '_' . $count;
4376
                $result = api_get_course_info($wanted_code);
4377
                if (empty($result)) {
4378
                    return $wanted_code;
4379
                }
4380
            }
4381
4382
            return false;
4383
        }
4384
4385
        return $wanted_code;
4386
    }
4387
4388
    /**
4389
     * Gets the status of the users agreement in a course course-session
4390
     *
4391
     * @param int $user_id
4392
     * @param string $course_code
4393
     * @param int $session_id
4394
     * @return boolean
4395
     */
4396
    public static function is_user_accepted_legal($user_id, $course_code, $session_id = null)
4397
    {
4398
        $user_id = intval($user_id);
4399
        $course_code = Database::escape_string($course_code);
4400
        $session_id = intval($session_id);
4401
4402
        $courseInfo = api_get_course_info($course_code);
4403
        $courseId = $courseInfo['real_id'];
4404
4405
        // Course legal
4406
        $enabled = api_get_plugin_setting('courselegal', 'tool_enable');
4407
4408 View Code Duplication
        if ($enabled == 'true') {
4409
            require_once api_get_path(SYS_PLUGIN_PATH) . 'courselegal/config.php';
4410
            $plugin = CourseLegalPlugin::create();
4411
            return $plugin->isUserAcceptedLegal($user_id, $course_code, $session_id);
4412
        }
4413
4414
        if (empty($session_id)) {
4415
            $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
4416
            $sql = "SELECT legal_agreement FROM $table
4417
                    WHERE user_id = $user_id AND c_id = $courseId ";
4418
            $result = Database::query($sql);
4419
            if (Database::num_rows($result) > 0) {
4420
                $result = Database::fetch_array($result);
4421
                if ($result['legal_agreement'] == 1) {
4422
                    return true;
4423
                }
4424
            }
4425
            return false;
4426
        } else {
4427
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4428
            $sql = "SELECT legal_agreement FROM $table
4429
                    WHERE user_id = $user_id AND c_id = $courseId AND session_id = $session_id";
4430
            $result = Database::query($sql);
4431
            if (Database::num_rows($result) > 0) {
4432
                $result = Database::fetch_array($result);
4433
                if ($result['legal_agreement'] == 1) {
4434
                    return true;
4435
                }
4436
            }
4437
            return false;
4438
        }
4439
    }
4440
4441
    /**
4442
     * Saves the user-course legal agreement
4443
     * @param   int user id
4444
     * @param   string course code
4445
     * @param   int session id
4446
     * @return mixed
4447
     */
4448
    public static function save_user_legal($user_id, $course_code, $session_id = null)
4449
    {
4450
        // Course plugin legal
4451
        $enabled = api_get_plugin_setting('courselegal', 'tool_enable');
4452
4453 View Code Duplication
        if ($enabled == 'true') {
4454
            require_once api_get_path(SYS_PLUGIN_PATH) . 'courselegal/config.php';
4455
            $plugin = CourseLegalPlugin::create();
4456
            return $plugin->saveUserLegal($user_id, $course_code, $session_id);
4457
        }
4458
4459
        $user_id = intval($user_id);
4460
        $course_code = Database::escape_string($course_code);
4461
        $session_id = intval($session_id);
4462
4463
        $courseInfo = api_get_course_info($course_code);
4464
        $courseId = $courseInfo['real_id'];
4465
4466
        if (empty($session_id)) {
4467
            $table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
4468
            $sql = "UPDATE $table SET legal_agreement = '1'
4469
                    WHERE user_id = $user_id AND c_id  = $courseId ";
4470
            Database::query($sql);
4471
        } else {
4472
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4473
            $sql = "UPDATE  $table SET legal_agreement = '1'
4474
                    WHERE user_id = $user_id AND c_id = $courseId AND session_id = $session_id";
4475
            Database::query($sql);
4476
        }
4477
    }
4478
4479
    /**
4480
     * @param int $user_id
4481
     * @param int $course_id
4482
     * @param int $session_id
4483
     * @param int $url_id
4484
     * @return bool
4485
     */
4486
    public static function get_user_course_vote($user_id, $course_id, $session_id = null, $url_id = null)
4487
    {
4488
        $table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE);
4489
4490
        $session_id = !isset($session_id) ? api_get_session_id() : intval($session_id);
4491
        $url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id);
4492
        $user_id = intval($user_id);
4493
4494
        if (empty($user_id)) {
4495
            return false;
4496
        }
4497
4498
        $params = array(
4499
            'user_id' => $user_id,
4500
            'c_id' => $course_id,
4501
            'session_id' => $session_id,
4502
            'url_id' => $url_id
4503
        );
4504
4505
        $result = Database::select(
4506
            'vote',
4507
            $table_user_course_vote,
4508
            array(
4509
                'where' => array(
4510
                    'user_id = ? AND c_id = ? AND session_id = ? AND url_id = ?' => $params
4511
                )
4512
            ),
4513
            'first'
4514
        );
4515
        if (!empty($result)) {
4516
            return $result['vote'];
4517
        }
4518
        return false;
4519
    }
4520
4521
    /**
4522
     * @param int $course_id
4523
     * @param int $session_id
4524
     * @param int $url_id
4525
     * @return array
4526
     */
4527
    public static function get_course_ranking($course_id, $session_id = null, $url_id = null)
4528
    {
4529
        $table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING);
4530
4531
        $session_id = !isset($session_id) ? api_get_session_id() : intval($session_id);
4532
        $url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id);
4533
        $now = api_get_utc_datetime();
4534
4535
        $params = array(
4536
            'c_id' => $course_id,
4537
            'session_id' => $session_id,
4538
            'url_id' => $url_id,
4539
            'creation_date' => $now,
4540
        );
4541
4542
        $result = Database::select(
4543
            'c_id, accesses, total_score, users',
4544
            $table_course_ranking,
4545
            array('where' => array('c_id = ? AND session_id = ? AND url_id = ?' => $params)),
4546
            'first'
4547
        );
4548
4549
        $point_average_in_percentage = 0;
4550
        $point_average_in_star = 0;
4551
        $users_who_voted = 0;
4552
4553
        if (!empty($result['users'])) {
4554
            $users_who_voted = $result['users'];
4555
            $point_average_in_percentage = round($result['total_score'] / $result['users'] * 100 / 5, 2);
4556
            $point_average_in_star = round($result['total_score'] / $result['users'], 1);
4557
        }
4558
4559
        $result['user_vote'] = false;
4560
4561
        if (!api_is_anonymous()) {
4562
            $result['user_vote'] = self::get_user_course_vote(api_get_user_id(), $course_id, $session_id, $url_id);
4563
        }
4564
4565
        $result['point_average'] = $point_average_in_percentage;
4566
        $result['point_average_star'] = $point_average_in_star;
4567
        $result['users_who_voted'] = $users_who_voted;
4568
4569
        return $result;
4570
    }
4571
4572
    /**
4573
     *
4574
     * Updates the course ranking
4575
     * @param int   course id
4576
     * @param int   session id
4577
     * @param id    url id
4578
     * @param integer $session_id
4579
     * @return array
4580
     **/
4581
    public static function update_course_ranking(
4582
        $course_id = null,
4583
        $session_id = null,
4584
        $url_id = null,
4585
        $points_to_add = null,
4586
        $add_access = true,
4587
        $add_user = true
4588
    ) {
4589
        // Course catalog stats modifications see #4191
4590
        $table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING);
4591
4592
        $now = api_get_utc_datetime();
4593
4594
        $course_id = empty($course_id) ? api_get_course_int_id() : intval($course_id);
4595
        $session_id = !isset($session_id) ? api_get_session_id() : intval($session_id);
4596
        $url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id);
4597
4598
        $params = array(
4599
            'c_id' => $course_id,
4600
            'session_id' => $session_id,
4601
            'url_id' => $url_id,
4602
            'creation_date' => $now,
4603
            'total_score' => 0,
4604
            'users' => 0
4605
        );
4606
4607
        $result = Database::select(
4608
            'id, accesses, total_score, users',
4609
            $table_course_ranking,
4610
            array('where' => array('c_id = ? AND session_id = ? AND url_id = ?' => $params)),
4611
            'first'
4612
        );
4613
4614
        // Problem here every time we load the courses/XXXX/index.php course home page we update the access
4615
4616
        if (empty($result)) {
4617
            if ($add_access) {
4618
                $params['accesses'] = 1;
4619
            }
4620
            //The votes and users are empty
4621
            if (isset($points_to_add) && !empty($points_to_add)) {
4622
                $params['total_score'] = intval($points_to_add);
4623
            }
4624
            if ($add_user) {
4625
                $params['users'] = 1;
4626
            }
4627
            $result = Database::insert($table_course_ranking, $params);
4628
        } else {
4629
            $my_params = array();
4630
4631
            if ($add_access) {
4632
                $my_params['accesses'] = intval($result['accesses']) + 1;
4633
            }
4634
            if (isset($points_to_add) && !empty($points_to_add)) {
4635
                $my_params['total_score'] = $result['total_score'] + $points_to_add;
4636
            }
4637
            if ($add_user) {
4638
                $my_params['users'] = $result['users'] + 1;
4639
            }
4640
4641
            if (!empty($my_params)) {
4642
                $result = Database::update(
4643
                    $table_course_ranking,
4644
                    $my_params,
4645
                    array('c_id = ? AND session_id = ? AND url_id = ?' => $params)
4646
                );
4647
            }
4648
        }
4649
4650
        return $result;
4651
    }
4652
4653
    /**
4654
     * Add user vote to a course
4655
     *
4656
     * @param   int user id
4657
     * @param   int vote [1..5]
4658
     * @param   int course id
4659
     * @param   int session id
4660
     * @param   int url id (access_url_id)
4661
     * @return    false|string 'added', 'updated' or 'nothing'
4662
     */
4663
    public static function add_course_vote($user_id, $vote, $course_id, $session_id = null, $url_id = null)
4664
    {
4665
        $table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE);
4666
        $course_id = empty($course_id) ? api_get_course_int_id() : intval($course_id);
4667
4668
        if (empty($course_id) || empty($user_id)) {
4669
            return false;
4670
        }
4671
4672
        if (!in_array($vote, array(1, 2, 3, 4, 5))) {
4673
            return false;
4674
        }
4675
4676
        $session_id = !isset($session_id) ? api_get_session_id() : intval($session_id);
4677
        $url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id);
4678
        $vote = intval($vote);
4679
4680
        $params = array(
4681
            'user_id' => intval($user_id),
4682
            'c_id' => $course_id,
4683
            'session_id' => $session_id,
4684
            'url_id' => $url_id,
4685
            'vote' => $vote
4686
        );
4687
4688
        $action_done = 'nothing';
4689
4690
        $result = Database::select(
4691
            'id, vote',
4692
            $table_user_course_vote,
4693
            array('where' => array('user_id = ? AND c_id = ? AND session_id = ? AND url_id = ?' => $params)),
4694
            'first'
4695
        );
4696
4697
        if (empty($result)) {
4698
            Database::insert($table_user_course_vote, $params);
4699
            $points_to_add = $vote;
4700
            $add_user = true;
4701
            $action_done = 'added';
4702
        } else {
4703
            $my_params = array('vote' => $vote);
4704
            $points_to_add = $vote - $result['vote'];
4705
            $add_user = false;
4706
4707
            Database::update(
4708
                $table_user_course_vote,
4709
                $my_params,
4710
                array('user_id = ? AND c_id = ? AND session_id = ? AND url_id = ?' => $params)
4711
            );
4712
            $action_done = 'updated';
4713
        }
4714
4715
        // Current points
4716
        if (!empty($points_to_add)) {
4717
            self::update_course_ranking(
4718
                $course_id,
4719
                $session_id,
4720
                $url_id,
4721
                $points_to_add,
4722
                false,
4723
                $add_user
4724
            );
4725
        }
4726
        return $action_done;
4727
    }
4728
4729
    /**
4730
     * Remove course ranking + user votes
4731
     *
4732
     * @param int $course_id
4733
     * @param int $session_id
4734
     * @param int $url_id
4735
     *
4736
     */
4737
    public static function remove_course_ranking($course_id, $session_id, $url_id = null)
4738
    {
4739
        $table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING);
4740
        $table_user_course_vote = Database::get_main_table(TABLE_MAIN_USER_REL_COURSE_VOTE);
4741
4742
        if (!empty($course_id) && isset($session_id)) {
4743
            $url_id = empty($url_id) ? api_get_current_access_url_id() : intval($url_id);
4744
            $params = array(
4745
                'c_id' => $course_id,
4746
                'session_id' => $session_id,
4747
                'url_id' => $url_id,
4748
            );
4749
            Database::delete($table_course_ranking, array('c_id = ? AND session_id = ? AND url_id = ?' => $params));
4750
            Database::delete($table_user_course_vote, array('c_id = ? AND session_id = ? AND url_id = ?' => $params));
4751
        }
4752
    }
4753
4754
    /**
4755
     * Returns an array with the hottest courses
4756
     * @param   int $days number of days
4757
     * @param   int $limit number of hottest courses
4758
     * @return array
4759
     */
4760
    public static function return_hot_courses($days = 30, $limit = 6)
4761
    {
4762
        if (api_is_invitee()) {
4763
            return array();
4764
        }
4765
4766
        $limit = intval($limit);
4767
4768
        // Getting my courses
4769
        $my_course_list = self::get_courses_list_by_user_id(api_get_user_id());
4770
4771
        $my_course_code_list = array();
4772
        foreach ($my_course_list as $course) {
4773
            $my_course_code_list[$course['real_id']] = $course['real_id'];
4774
        }
4775
4776
        if (api_is_drh()) {
4777
            $courses = self::get_courses_followed_by_drh(api_get_user_id());
4778
            foreach ($courses as $course) {
4779
                $my_course_code_list[$course['real_id']] = $course['real_id'];
4780
            }
4781
        }
4782
4783
        $table_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
4784
        $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
4785
        $table_course_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
4786
4787
        //$table_course_access table uses the now() and interval ...
4788
        $now = api_get_utc_datetime(time());
4789
        $sql = "SELECT COUNT(course_access_id) course_count, a.c_id, visibility
4790
                FROM $table_course c
4791
                INNER JOIN $table_course_access a
4792
                ON (c.id = a.c_id)
4793
                INNER JOIN $table_course_url u
4794
                ON u.c_id = c.id
4795
                WHERE
4796
                    u.access_url_id = " . api_get_current_access_url_id() . " AND
4797
                    login_course_date <= '$now' AND
4798
                    login_course_date > DATE_SUB('$now', INTERVAL $days DAY) AND
4799
                    visibility <> '" . COURSE_VISIBILITY_CLOSED . "' AND visibility <> '" . COURSE_VISIBILITY_HIDDEN . "'
4800
                GROUP BY a.c_id
4801
                ORDER BY course_count DESC
4802
                LIMIT $limit
4803
            ";
4804
4805
        $result = Database::query($sql);
4806
        $courses = array();
4807
4808
        if (Database::num_rows($result)) {
4809
            $courses = Database::store_result($result, 'ASSOC');
4810
            $courses = self::process_hot_course_item($courses, $my_course_code_list);
4811
        }
4812
4813
        return $courses;
4814
    }
4815
4816
    /**
4817
     * @param array $courses
4818
     * @param array $my_course_code_list
4819
     * @return mixed
4820
     */
4821
    public static function process_hot_course_item($courses, $my_course_code_list = array())
4822
    {
4823
        $hotCourses = [];
4824
        $ajax_url = api_get_path(WEB_AJAX_PATH) . 'course.ajax.php?a=add_course_vote';
4825
        $stok = Security::get_existing_token();
4826
        $user_id = api_get_user_id();
4827
4828
        foreach ($courses as $courseId) {
4829
            $course_info = api_get_course_info_by_id($courseId['c_id']);
4830
            $courseCode = $course_info['code'];
4831
            $categoryCode = !empty($course_info['categoryCode']) ? $course_info['categoryCode'] : "";
4832
            $my_course = $course_info;
4833
            $my_course['go_to_course_button'] = '';
4834
            $my_course['register_button'] = '';
4835
4836
            $access_link = self::get_access_link_by_user(
4837
                api_get_user_id(),
4838
                $course_info,
4839
                $my_course_code_list
4840
            );
4841
4842
            $userRegisterdInCourse = self::is_user_subscribed_in_course($user_id, $course_info['code']);
4843
            $userRegisterdInCourseAsTeacher = self::is_course_teacher($user_id, $course_info['code']);
4844
            $userRegisterd = ($userRegisterdInCourse && $userRegisterdInCourseAsTeacher);
4845
4846
            $my_course['is_registerd'] = $userRegisterd;
4847
4848
            $my_course['title_cut'] = cut($course_info['title'], 45);
4849
            // if user registered as student
4850
            /* if ($userRegisterdInCourse) {
4851
                $icon = '<em class="fa fa-graduation-cap"></em>';
4852
                $title = get_lang("AlreadyRegisteredToCourse");
4853
                $my_course['already_register_as'] = Display::tag(
4854
                    'button',
4855
                    $icon,
4856
                    array(
4857
                        'id' => 'register',
4858
                        'class' => 'btn btn-default btn-sm',
4859
                        'title' => $title,
4860
                        'aria-label' => $title
4861
                    )
4862
                );
4863
            } elseif ($userRegisterdInCourseAsTeacher) {
4864
                // if user registered as teacher
4865
                $icon = '<em class="fa fa-suitcase"></em>';
4866
                $title = get_lang("YouAreATeacherOfThisCourse");
4867
                $my_course['already_register_as'] = Display::tag(
4868
                    'button',
4869
                    $icon,
4870
                    array(
4871
                        'id' => 'register',
4872
                        'class' => 'btn btn-default btn-sm',
4873
                        'title' => $title,
4874
                        'aria-label' => $title
4875
                    )
4876
                );
4877
            } */
4878
4879
            //Course visibility
4880 View Code Duplication
            if ($access_link && in_array('register', $access_link)) {
4881
                $my_course['register_button'] = Display::url(
4882
                    get_lang('Subscribe') . ' ' .
4883
                    Display::returnFontAwesomeIcon('sign-in'),
4884
                    api_get_path(WEB_COURSE_PATH) . $course_info['path'] .
4885
                     '/index.php?action=subscribe&sec_token=' . $stok,
4886
                    array(
4887
                        'class' => 'btn btn-success btn-sm',
4888
                        'title' => get_lang('Subscribe'),
4889
                        'aria-label' => get_lang('Subscribe')
4890
                    )
4891
                );
4892
4893
            }
4894
4895 View Code Duplication
            if ($access_link && in_array('enter',
4896
                    $access_link) || $course_info['visibility'] == COURSE_VISIBILITY_OPEN_WORLD
4897
            ) {
4898
                $my_course['go_to_course_button'] = Display::url(
4899
                    get_lang('GoToCourse'). ' ' .
4900
                    Display::returnFontAwesomeIcon('share'),
4901
                    api_get_path(WEB_COURSE_PATH) . $course_info['path'] . '/index.php',
4902
                    array(
4903
                        'class' => 'btn btn-default btn-sm',
4904
                        'title' => get_lang('GoToCourse'),
4905
                        'aria-label' => get_lang('GoToCourse')
4906
                    )
4907
                );
4908
4909
            }
4910
4911
            if ($access_link && in_array('unsubscribe', $access_link)) {
4912
                $my_course['unsubscribe_button'] = Display::url(
4913
                    get_lang('Unreg') . ' ' .
4914
                    Display::returnFontAwesomeIcon('sign-out'),
4915
                    api_get_path(WEB_CODE_PATH) . 'auth/courses.php?action=unsubscribe&unsubscribe=' . $courseCode
4916
                    . '&sec_token=' . $stok . '&category_code=' . $categoryCode,
4917
                    array(
4918
                        'class' => 'btn btn-danger btn-sm',
4919
                        'title' => get_lang('Unreg'),
4920
                        'aria-label' => get_lang('Unreg')
4921
                    )
4922
                );
4923
4924
            }
4925
4926
            // start buycourse validation
4927
            // display the course price and buy button if the buycourses plugin is enabled and this course is configured
4928
            $plugin = BuyCoursesPlugin::create();
4929
            $isThisCourseInSale = $plugin->buyCoursesForGridCatalogValidator(
4930
                $course_info['real_id'],
4931
                BuyCoursesPlugin::PRODUCT_TYPE_COURSE
4932
            );
4933
            if ($isThisCourseInSale) {
4934
                // set the price label
4935
                $my_course['price'] = $isThisCourseInSale['html'];
4936
                // set the Buy button instead register.
4937
                if ($isThisCourseInSale['verificator'] && !empty($my_course['register_button'])) {
4938
                    $my_course['register_button'] = $plugin->returnBuyCourseButton($course_info['real_id'], BuyCoursesPlugin::PRODUCT_TYPE_COURSE);
4939
                }
4940
            }
4941
            // end buycourse validation
4942
4943
            //Description
4944
            $my_course['description_button'] = '';
4945
            /* if ($course_info['visibility'] == COURSE_VISIBILITY_OPEN_WORLD || in_array($course_info['real_id'],
4946
                    $my_course_code_list)
4947
            ) { */
4948
                $my_course['description_button'] = Display::url(
4949
                    Display::returnFontAwesomeIcon('info-circle'),
4950
                    api_get_path(WEB_AJAX_PATH) . 'course_home.ajax.php?a=show_course_information&code=' . $course_info['code'],
4951
                    [
4952
                        'class' => 'btn btn-default btn-sm ajax',
4953
                        'data-title' => get_lang('Description'),
4954
                        'title' => get_lang('Description'),
4955
                        'aria-label' => get_lang('Description')
4956
                    ]
4957
                );
4958
            //}
4959
            /* get_lang('Description') */
4960
            $my_course['teachers'] = self::getTeachersFromCourse($course_info['real_id'], true);
4961
            $point_info = self::get_course_ranking($course_info['real_id'], 0);
4962
4963
            $my_course['rating_html'] = '';
4964
            if (api_get_configuration_value('hide_course_rating') === false) {
4965
                $my_course['rating_html'] = Display::return_rating_system(
4966
                    'star_'.$course_info['real_id'],
4967
                    $ajax_url.'&course_id='.$course_info['real_id'],
4968
                    $point_info
4969
                );
4970
            }
4971
            $hotCourses[] = $my_course;
4972
        }
4973
4974
        return $hotCourses;
4975
    }
4976
4977
    /**
4978
     * @param int $limit
4979
     * @return array
4980
     */
4981
    public static function return_most_accessed_courses($limit = 5)
4982
    {
4983
        $table_course_ranking = Database::get_main_table(TABLE_STATISTIC_TRACK_COURSE_RANKING);
4984
        $params['url_id'] = api_get_current_access_url_id();
4985
4986
        $result = Database::select(
4987
            'c_id, accesses, total_score, users',
4988
            $table_course_ranking,
4989
            array('where' => array('url_id = ?' => $params), 'order' => 'accesses DESC', 'limit' => $limit),
4990
            'all',
4991
            true
4992
        );
4993
4994
        return $result;
4995
    }
4996
4997
    /**
4998
     * Get courses count
4999
     * @param int Access URL ID (optional)
5000
     * @param int $visibility
5001
     * @param integer $access_url_id
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
     * @return int Number of courses
5036
     */
5037
    public static function countActiveCourses($urlId = null)
5038
    {
5039
        $table_course = Database::get_main_table(TABLE_MAIN_COURSE);
5040
        $table_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
5041
        $sql = "SELECT count(id) FROM $table_course c";
5042
        if (!empty($urlId) && $urlId == intval($urlId)) {
5043
            $sql .= ", $table_course_rel_access_url u
5044
                    WHERE
5045
                        c.id = u.c_id AND
5046
                        u.access_url_id = $urlId AND
5047
                        visibility <> " . COURSE_VISIBILITY_HIDDEN;
5048
        } else {
5049
            $sql .= " WHERE visibility <> " . COURSE_VISIBILITY_HIDDEN;
5050
        }
5051
        $res = Database::query($sql);
5052
        $row = Database::fetch_row($res);
5053
        return $row[0];
5054
    }
5055
5056
    /**
5057
     * Returns the SQL conditions to filter course only visible by the user in the catalogue
5058
     *
5059
     * @param string $courseTableAlias Alias of the course table
5060
     * @param bool $hideClosed Whether to hide closed and hidden courses
5061
     * @return string SQL conditions
5062
     */
5063
    public static function getCourseVisibilitySQLCondition($courseTableAlias, $hideClosed = false) {
5064
        $visibilityCondition = '';
5065
        $hidePrivate = api_get_setting('course_catalog_hide_private');
5066
        if ($hidePrivate === 'true') {
5067
            $visibilityCondition .= ' AND '.$courseTableAlias.'.visibility <> '.COURSE_VISIBILITY_REGISTERED;
5068
        }
5069
        if ($hideClosed) {
5070
            $visibilityCondition .= ' AND ' . $courseTableAlias . '.visibility NOT IN (' . COURSE_VISIBILITY_CLOSED .','. COURSE_VISIBILITY_HIDDEN .')';
5071
        }
5072
5073
        // Check if course have users allowed to see it in the catalogue, then show only if current user is allowed to see it
5074
        $currentUserId = api_get_user_id();
5075
        $restrictedCourses = self::getCatalogueCourseList(true);
5076
        $allowedCoursesToCurrentUser = self::getCatalogueCourseList(true, $currentUserId);
5077 View Code Duplication
        if (!empty($restrictedCourses)) {
5078
            $visibilityCondition .= ' AND ('.$courseTableAlias.'.code NOT IN ("' . implode('","', $restrictedCourses) . '")';
5079
            $visibilityCondition .= ' OR '.$courseTableAlias.'.code IN ("' . implode('","', $allowedCoursesToCurrentUser) . '"))';
5080
        }
5081
5082
        // Check if course have users denied to see it in the catalogue, then show only if current user is not denied to see it
5083
        $restrictedCourses = self::getCatalogueCourseList(false);
5084
        $notAllowedCoursesToCurrentUser = self::getCatalogueCourseList(false, $currentUserId);
5085 View Code Duplication
        if (!empty($restrictedCourses)) {
5086
            $visibilityCondition .= ' AND ('.$courseTableAlias.'.code NOT IN ("' . implode('","', $restrictedCourses) . '")';
5087
            $visibilityCondition .= ' OR '.$courseTableAlias.'.code NOT IN ("' . implode('","', $notAllowedCoursesToCurrentUser) . '"))';
5088
        }
5089
5090
        return $visibilityCondition;
5091
    }
5092
5093
    /**
5094
     * Get available le courses count
5095
     * @param int Access URL ID (optional)
5096
     * @param integer $accessUrlId
5097
     * @return int Number of courses
5098
     */
5099
    public static function countAvailableCourses($accessUrlId = null)
5100
    {
5101
        $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
5102
        $tableCourseRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
5103
        $specialCourseList = self::get_special_course_list();
5104
5105
        $withoutSpecialCourses = '';
5106
        if (!empty($specialCourseList)) {
5107
            $withoutSpecialCourses = ' AND c.id NOT IN ("' . implode('","', $specialCourseList) . '")';
5108
        }
5109
5110
        $visibilityCondition = self::getCourseVisibilitySQLCondition('c', true);
5111
5112
        if (!empty($accessUrlId) && $accessUrlId == intval($accessUrlId)) {
5113
            $sql = "SELECT count(c.id) FROM $tableCourse c, $tableCourseRelAccessUrl u
5114
                    WHERE
5115
                        c.id = u.c_id AND
5116
                        u.access_url_id = $accessUrlId AND
5117
                        c.visibility != 0 AND
5118
                        c.visibility != 4
5119
                        $withoutSpecialCourses
5120
                        $visibilityCondition
5121
                    ";
5122
        }
5123
        $res = Database::query($sql);
5124
        $row = Database::fetch_row($res);
5125
5126
        return $row[0];
5127
    }
5128
5129
    /**
5130
     * Return a link to go to the course, validating the visibility of the
5131
     * course and the user status
5132
     * @param int User ID
5133
     * @param array Course details array
5134
     * @param array  List of courses to which the user is subscribed (if not provided, will be generated)
5135
     * @param integer $uid
5136
     * @return mixed 'enter' for a link to go to the course or 'register' for a link to subscribe, or false if no access
5137
     */
5138
    static function get_access_link_by_user($uid, $course, $user_courses = array())
5139
    {
5140
        if (empty($uid) or empty($course)) {
5141
            return false;
5142
        }
5143
5144
        if (empty($user_courses)) {
5145
            // get the array of courses to which the user is subscribed
5146
            $user_courses = self::get_courses_list_by_user_id($uid);
5147
            foreach ($user_courses as $k => $v) {
5148
                $user_courses[$k] = $v['real_id'];
5149
            }
5150
        }
5151
5152
        if (!isset($course['real_id']) && empty($course['real_id'])) {
5153
            $course = api_get_course_info($course['code']);
5154
        }
5155
5156
        if ($course['visibility'] == COURSE_VISIBILITY_HIDDEN) {
5157
            return array();
5158
        }
5159
5160
        $is_admin = api_is_platform_admin_by_id($uid);
5161
        $options = array();
5162
        // Register button
5163
        if (!api_is_anonymous($uid) &&
5164
            (
5165
            ($course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD || $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM)
5166
                //$course['visibility'] == COURSE_VISIBILITY_REGISTERED && $course['subscribe'] == SUBSCRIBE_ALLOWED
5167
            ) &&
5168
            $course['subscribe'] == SUBSCRIBE_ALLOWED &&
5169
            (!in_array($course['real_id'], $user_courses) || empty($user_courses))
5170
        ) {
5171
            $options[] = 'register';
5172
        }
5173
5174
        // Go To Course button (only if admin, if course public or if student already subscribed)
5175 View Code Duplication
        if ($is_admin ||
5176
            $course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD && empty($course['registration_code']) ||
5177
            (api_user_is_login($uid) && $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM && empty($course['registration_code'])) ||
5178
            (in_array($course['real_id'], $user_courses) && $course['visibility'] != COURSE_VISIBILITY_CLOSED)
5179
        ) {
5180
            $options[] = 'enter';
5181
        }
5182
5183 View Code Duplication
        if ($is_admin ||
5184
            $course['visibility'] == COURSE_VISIBILITY_OPEN_WORLD && empty($course['registration_code']) ||
5185
            (api_user_is_login($uid) && $course['visibility'] == COURSE_VISIBILITY_OPEN_PLATFORM && empty($course['registration_code'])) ||
5186
            (in_array($course['real_id'], $user_courses) && $course['visibility'] != COURSE_VISIBILITY_CLOSED)
5187
        ) {
5188
            $options[] = 'enter';
5189
        }
5190
5191
        if ($course['visibility'] != COURSE_VISIBILITY_HIDDEN && empty($course['registration_code']) && $course['unsubscribe'] == UNSUBSCRIBE_ALLOWED && api_user_is_login($uid) && (in_array($course['real_id'],
5192
                $user_courses))
5193
        ) {
5194
            $options[] = 'unsubscribe';
5195
        }
5196
5197
        return $options;
5198
    }
5199
5200
    /**
5201
     * @param array $courseInfo
5202
     * @param array $teachers
5203
     * @param bool $deleteTeachersNotInList
5204
     * @param bool $editTeacherInSessions
5205
     * @param bool $deleteSessionTeacherNotInList
5206
     * @param array $teacherBackup
5207
     * @param Monolog\Logger $logger
5208
     *
5209
     * @return false|null
5210
     */
5211
    public static function updateTeachers(
5212
        $courseInfo,
5213
        $teachers,
5214
        $deleteTeachersNotInList = true,
5215
        $editTeacherInSessions = false,
5216
        $deleteSessionTeacherNotInList = false,
5217
        $teacherBackup = array(),
5218
        $logger = null
5219
    ) {
5220
        if (!is_array($teachers)) {
5221
            $teachers = array($teachers);
5222
        }
5223
5224
        if (empty($courseInfo) || !isset($courseInfo['real_id'])) {
5225
            return false;
5226
        }
5227
5228
        $teachers = array_filter($teachers);
5229
        $courseId = $courseInfo['real_id'];
5230
        $course_code = $courseInfo['code'];
5231
5232
        $course_user_table = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5233
        $alreadyAddedTeachers = self::get_teacher_list_from_course_code($course_code);
5234
5235
        if ($deleteTeachersNotInList) {
5236
            // Delete only teacher relations that doesn't match the selected teachers
5237
            $cond = null;
5238
            if (count($teachers) > 0) {
5239
                foreach ($teachers as $key) {
5240
                    $key = Database::escape_string($key);
5241
                    $cond .= " AND user_id <> '" . $key . "'";
5242
                }
5243
            }
5244
5245
            // Recover user categories
5246
            $sql = 'SELECT * FROM ' . $course_user_table . '
5247
                    WHERE c_id ="' . $courseId . '" AND status="1" AND relation_type = 0 ' . $cond;
5248
            $result = Database::query($sql);
5249
            if (Database::num_rows($result)) {
5250
                $teachersToDelete = Database::store_result($result, 'ASSOC');
5251
                foreach ($teachersToDelete as $data) {
5252
                    $userId = $data['user_id'];
5253
                    $teacherBackup[$userId][$course_code] = $data;
5254
                }
5255
            }
5256
5257
            $sql = 'DELETE FROM ' . $course_user_table . '
5258
                    WHERE c_id ="' . $courseId . '" AND status="1" AND relation_type = 0 ' . $cond;
5259
5260
            Database::query($sql);
5261
        }
5262
5263
        if (count($teachers) > 0) {
5264
            foreach ($teachers as $userId) {
5265
                $userId = intval($userId);
5266
                // We check if the teacher is already subscribed in this course
5267
                $sql = 'SELECT 1 FROM ' . $course_user_table . '
5268
                        WHERE user_id = "' . $userId . '" AND c_id = "' . $courseId . '" ';
5269
                $result = Database::query($sql);
5270
                if (Database::num_rows($result)) {
5271
                    $sql = 'UPDATE ' . $course_user_table . ' 
5272
                            SET status = "1"
5273
                            WHERE c_id = "' . $courseId . '" AND user_id = "' . $userId . '"  ';
5274
                } else {
5275
                    $userCourseCategory = '0';
5276
                    if (isset($teacherBackup[$userId]) &&
5277
                        isset($teacherBackup[$userId][$course_code])
5278
                    ) {
5279
                        $courseUserData = $teacherBackup[$userId][$course_code];
5280
                        $userCourseCategory = $courseUserData['user_course_cat'];
5281
                        if ($logger) {
5282
                            $logger->addInfo("Recovering user_course_cat: $userCourseCategory");
5283
                        }
5284
                    }
5285
5286
                    $sql = "INSERT INTO $course_user_table SET
5287
                            c_id = $courseId,
5288
                            user_id = $userId,
5289
                            status = '1',
5290
                            is_tutor = '0',
5291
                            sort = '0',
5292
                            relation_type = '0',
5293
                            user_course_cat = '$userCourseCategory'
5294
                    ";
5295
                }
5296
                Database::query($sql);
5297
            }
5298
        }
5299
5300
        if ($editTeacherInSessions) {
5301
            $sessions = SessionManager::get_session_by_course($courseId);
5302
            if (!empty($sessions)) {
5303
                if ($logger) {
5304
                    $logger->addInfo("Edit teachers in sessions");
5305
                }
5306
                foreach ($sessions as $session) {
5307
                    $sessionId = $session['id'];
5308
                    // Remove old and add new
5309
                    if ($deleteSessionTeacherNotInList) {
5310
                        foreach ($teachers as $userId) {
5311
                            if ($logger) {
5312
                                $logger->addInfo("Set coach #$userId in session #$sessionId of course #$courseId ");
5313
                            }
5314
                            SessionManager::set_coach_to_course_session(
5315
                                $userId,
5316
                                $sessionId,
5317
                                $courseId
5318
                            );
5319
                        }
5320
5321
                        $teachersToDelete = array();
5322
                        if (!empty($alreadyAddedTeachers)) {
5323
                            $teachersToDelete = array_diff(array_keys($alreadyAddedTeachers), $teachers);
5324
                        }
5325
5326 View Code Duplication
                        if (!empty($teachersToDelete)) {
5327
                            foreach ($teachersToDelete as $userId) {
5328
                                if ($logger) {
5329
                                    $logger->addInfo("Delete coach #$userId in session #$sessionId of course #$courseId ");
5330
                                }
5331
                                SessionManager::set_coach_to_course_session(
5332
                                    $userId,
5333
                                    $sessionId,
5334
                                    $courseId,
5335
                                    true
5336
                                );
5337
                            }
5338
                        }
5339 View Code Duplication
                    } else {
5340
                        // Add new teachers only
5341
                        foreach ($teachers as $userId) {
5342
                            if ($logger) {
5343
                                $logger->addInfo("Add coach #$userId in session #$sessionId of course #$courseId ");
5344
                            }
5345
                            SessionManager::set_coach_to_course_session(
5346
                                $userId,
5347
                                $sessionId,
5348
                                $courseId
5349
                            );
5350
                        }
5351
                    }
5352
                }
5353
            }
5354
        }
5355
    }
5356
5357
    /**
5358
     * Course available settings variables see c_course_setting table
5359
     * @param AppPlugin $appPlugin
5360
     * @return array
5361
     */
5362
    public static function getCourseSettingVariables(AppPlugin $appPlugin)
5363
    {
5364
        $pluginCourseSettings = $appPlugin->getAllPluginCourseSettings();
5365
        $courseSettings = array(
5366
            // Get allow_learning_path_theme from table
5367
            'allow_learning_path_theme',
5368
            // Get allow_open_chat_window from table
5369
            'allow_open_chat_window',
5370
            'allow_public_certificates',
5371
            // Get allow_user_edit_agenda from table
5372
            'allow_user_edit_agenda',
5373
            // Get allow_user_edit_announcement from table
5374
            'allow_user_edit_announcement',
5375
            // Get allow_user_image_forum from table
5376
            'allow_user_image_forum',
5377
            //Get allow show user list
5378
            'allow_user_view_user_list',
5379
            // Get course_theme from table
5380
            'course_theme',
5381
            //Get allow show user list
5382
            'display_info_advance_inside_homecourse',
5383
            'documents_default_visibility',
5384
            // Get send_mail_setting (work)from table
5385
            'email_alert_manager_on_new_doc',
5386
            // Get send_mail_setting (work)from table
5387
            'email_alert_manager_on_new_quiz',
5388
            // Get send_mail_setting (dropbox) from table
5389
            'email_alert_on_new_doc_dropbox',
5390
            'email_alert_students_on_new_homework',
5391
            // Get send_mail_setting (auth)from table
5392
            'email_alert_to_teacher_on_new_user_in_course',
5393
            'enable_lp_auto_launch',
5394
            'pdf_export_watermark_text',
5395
            'show_system_folders',
5396
            'exercise_invisible_in_session',
5397
            'enable_forum_auto_launch',
5398
            'show_course_in_user_language'
5399
        );
5400
5401
        $allowLPReturnLink = api_get_setting('allow_lp_return_link');
5402
        if ($allowLPReturnLink === 'true') {
5403
            $courseSettings[] = 'lp_return_link';
5404
        }
5405
5406
        if (!empty($pluginCourseSettings)) {
5407
            $courseSettings = array_merge(
5408
                $courseSettings,
5409
                $pluginCourseSettings
5410
            );
5411
        }
5412
5413
        return $courseSettings;
5414
    }
5415
5416
    /**
5417
     * @param AppPlugin $appPlugin
5418
     * @param string $variable
5419
     * @param string $value
5420
     * @param int $courseId
5421
     * @return bool
5422
     */
5423
    public static function saveCourseConfigurationSetting(AppPlugin $appPlugin, $variable, $value, $courseId)
5424
    {
5425
        $settingList = self::getCourseSettingVariables($appPlugin);
5426
5427
        if (!in_array($variable, $settingList)) {
5428
5429
            return false;
5430
        }
5431
5432
        $courseSettingTable = Database::get_course_table(TABLE_COURSE_SETTING);
5433
        if (self::hasCourseSetting($variable, $courseId)) {
5434
            // Update
5435
            Database::update(
5436
                $courseSettingTable,
5437
                array('value' => $value),
5438
                array('variable = ? AND c_id = ?' => array($variable, $courseId))
5439
            );
5440
        } else {
5441
            // Create
5442
            Database::insert(
5443
                $courseSettingTable,
5444
                ['title' => $variable, 'value' => $value, 'c_id' => $courseId, 'variable' => $variable]
5445
            );
5446
        }
5447
        return true;
5448
    }
5449
5450
    /**
5451
     * Check if course setting exists
5452
     * @param string $variable
5453
     * @param int $courseId
5454
     * @return bool
5455
     */
5456 View Code Duplication
    public static function hasCourseSetting($variable, $courseId)
5457
    {
5458
        $courseSetting = Database::get_course_table(TABLE_COURSE_SETTING);
5459
        $courseId = intval($courseId);
5460
        $variable = Database::escape_string($variable);
5461
        $sql = "SELECT variable FROM $courseSetting
5462
                WHERE c_id = $courseId AND variable = '$variable'";
5463
        $result = Database::query($sql);
5464
5465
        return Database::num_rows($result) > 0;
5466
    }
5467
5468
    /**
5469
     * Get information from the track_e_course_access table
5470
     * @param int $sessionId
5471
     * @param int $userId
5472
     * @return array
5473
     */
5474 View Code Duplication
    public static function getCourseAccessPerSessionAndUser($sessionId, $userId, $limit = null)
5475
    {
5476
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
5477
5478
        $sessionId = intval($sessionId);
5479
        $userId = intval($userId);
5480
5481
        $sql = "SELECT * FROM $table
5482
                WHERE session_id = $sessionId AND user_id = $userId";
5483
5484
        if (!empty($limit)) {
5485
            $limit = intval($limit);
5486
            $sql .= " LIMIT $limit";
5487
        }
5488
        $result = Database::query($sql);
5489
5490
        return Database::store_result($result);
5491
    }
5492
5493
    /**
5494
     * Get information from the track_e_course_access table
5495
     * @param int $courseId
5496
     * @param int $sessionId
5497
     * @param string $startDate
5498
     * @param string $endDate
5499
     * @return array
5500
     */
5501 View Code Duplication
    public static function getCourseAccessPerCourseAndSession(
5502
        $courseId,
5503
        $sessionId,
5504
        $startDate,
5505
        $endDate
5506
    ) {
5507
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
5508
        $courseId = intval($courseId);
5509
        $sessionId = intval($sessionId);
5510
        $startDate = Database::escape_string($startDate);
5511
        $endDate = Database::escape_string($endDate);
5512
5513
        $sql = "SELECT * FROM $table
5514
                WHERE
5515
                    c_id = $courseId AND
5516
                    session_id = $sessionId AND
5517
                    login_course_date BETWEEN '$startDate' AND '$endDate'
5518
                ";
5519
5520
        $result = Database::query($sql);
5521
5522
        return Database::store_result($result);
5523
    }
5524
5525
    /**
5526
     * Get login information from the track_e_course_access table, for any
5527
     * course in the given session
5528
     * @param int $sessionId
5529
     * @param int $userId
5530
     * @return array
5531
     */
5532
    public static function getFirstCourseAccessPerSessionAndUser($sessionId, $userId)
5533
    {
5534
        $sessionId = intval($sessionId);
5535
        $userId = intval($userId);
5536
5537
        $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
5538
        $sql = "SELECT * FROM $table
5539
                WHERE session_id = $sessionId AND user_id = $userId
5540
                ORDER BY login_course_date ASC
5541
                LIMIT 1";
5542
5543
        $result = Database::query($sql);
5544
        $courseAccess = array();
5545
        if (Database::num_rows($result)) {
5546
            $courseAccess = Database::fetch_array($result, 'ASSOC');
5547
        }
5548
        return $courseAccess;
5549
    }
5550
5551
    /**
5552
     * @param int $courseId
5553
     * @param int $sessionId
5554
     * @param bool $getAllSessions
5555
     * @return mixed
5556
     */
5557
    public static function getCountForum(
5558
        $courseId,
5559
        $sessionId = 0,
5560
        $getAllSessions = false
5561
    ) {
5562
        $forum = Database::get_course_table(TABLE_FORUM);
5563
        if ($getAllSessions) {
5564
            $sql = "SELECT count(*) as count
5565
                    FROM $forum f
5566
                    WHERE f.c_id = %s";
5567
        } else {
5568
            $sql = "SELECT count(*) as count
5569
                    FROM $forum f
5570
                    WHERE f.c_id = %s and f.session_id = %s";
5571
        }
5572
5573
        $sql = sprintf($sql, intval($courseId), intval($sessionId));
5574
        $result = Database::query($sql);
5575
        $row = Database::fetch_array($result);
5576
5577
        return $row['count'];
5578
    }
5579
5580
    /**
5581
     * @param int $userId
5582
     * @param int $courseId
5583
     * @param int $sessionId
5584
     * @return mixed
5585
     */
5586
    public static function getCountPostInForumPerUser(
5587
        $userId,
5588
        $courseId,
5589
        $sessionId = 0
5590
    ) {
5591
        $forum = Database::get_course_table(TABLE_FORUM);
5592
        $forum_post = Database::get_course_table(TABLE_FORUM_POST);
5593
5594
        $sql = "SELECT count(distinct post_id) as count
5595
                FROM $forum_post p
5596
                INNER JOIN $forum f
5597
                ON f.forum_id = p.forum_id AND f.c_id = p.c_id
5598
                WHERE p.poster_id = %s and f.session_id = %s and p.c_id = %s";
5599
5600
        $sql = sprintf(
5601
            $sql,
5602
            intval($userId),
5603
            intval($sessionId),
5604
            intval($courseId)
5605
        );
5606
5607
        $result = Database::query($sql);
5608
        $row = Database::fetch_array($result);
5609
        return $row['count'];
5610
    }
5611
5612
    /**
5613
     * @param int $userId
5614
     * @param int $courseId
5615
     * @param int $sessionId
5616
     * @return mixed
5617
     */
5618
    public static function getCountForumPerUser(
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 f.forum_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
        return $row['count'];
5642
    }
5643
5644
    /**
5645
     * Returns the course name from a given code
5646
     * @param string $code
5647
     */
5648 View Code Duplication
    public static function getCourseNameFromCode($code)
5649
    {
5650
        $tbl_main_categories = Database::get_main_table(TABLE_MAIN_COURSE);
5651
        $sql = 'SELECT title
5652
                FROM ' . $tbl_main_categories . '
5653
                WHERE code = "' . Database::escape_string($code) . '"';
5654
        $result = Database::query($sql);
5655
        if ($col = Database::fetch_array($result)) {
5656
            return $col['title'];
5657
        }
5658
    }
5659
5660
    /**
5661
     * Generates a course code from a course title
5662
     * @todo Such a function might be useful in other places too. It might be moved in the CourseManager class.
5663
     * @todo the function might be upgraded for avoiding code duplications (currently, it might suggest a code that is already in use)
5664
     * @param string $title A course title
5665
     * @return string A proposed course code
5666
     * +
5667
     * @assert (null,null) === false
5668
     * @assert ('ABC_DEF', null) === 'ABCDEF'
5669
     * @assert ('ABC09*^[%A', null) === 'ABC09A'
5670
     */
5671
    public static function generate_course_code($title)
5672
    {
5673
        return substr(
5674
            preg_replace('/[^A-Z0-9]/', '', strtoupper(api_replace_dangerous_char($title))),
5675
            0,
5676
            self::MAX_COURSE_LENGTH_CODE
5677
        );
5678
    }
5679
5680
    /**
5681
     * @param $courseId
5682
     * @return array
5683
     */
5684
    public static function getCourseSettings($courseId)
5685
    {
5686
        $settingTable = Database::get_course_table(TABLE_COURSE_SETTING);
5687
        $courseId = intval($courseId);
5688
        $sql = "SELECT * FROM $settingTable WHERE c_id = $courseId";
5689
        $result = Database::query($sql);
5690
        $settings = array();
5691
        if (Database::num_rows($result)) {
5692
            while ($row = Database::fetch_array($result, 'ASSOC')) {
5693
                $settings[$row['variable']] = $row;
5694
            }
5695
        }
5696
        return $settings;
5697
    }
5698
5699
    /**
5700
     * this function gets all the users of the course,
5701
     * including users from linked courses
5702
     */
5703
    public static function getCourseUsers()
5704
    {
5705
        //this would return only the users from real courses:
5706
        $session_id = api_get_session_id();
5707
        if ($session_id != 0) {
5708
            $user_list = self::get_real_and_linked_user_list(api_get_course_id(), true, $session_id);
5709
        } else {
5710
            $user_list = self::get_real_and_linked_user_list(api_get_course_id(), false, 0);
5711
        }
5712
5713
        return $user_list;
5714
    }
5715
5716
    /**
5717
     * this function gets all the groups of the course,
5718
     * not including linked courses
5719
     */
5720 View Code Duplication
    public static function getCourseGroups()
5721
    {
5722
        $session_id = api_get_session_id();
5723
        if ($session_id != 0) {
5724
            $new_group_list = self::get_group_list_of_course(api_get_course_id(), $session_id, 1);
5725
        } else {
5726
            $new_group_list = self::get_group_list_of_course(api_get_course_id(), 0, 1);
5727
        }
5728
5729
        return $new_group_list;
5730
    }
5731
5732
    /**
5733
     * @param FormValidator $form
5734
     * @param array $to_already_selected
5735
     *
5736
     * @return HTML_QuickForm_element
5737
     */
5738 View Code Duplication
    public static function addUserGroupMultiSelect(&$form, $to_already_selected)
5739
    {
5740
        $user_list = self::getCourseUsers();
5741
        $group_list = self::getCourseGroups();
5742
        $array = self::buildSelectOptions($group_list, $user_list, $to_already_selected);
5743
5744
        $result = array();
5745
        foreach ($array as $content) {
5746
            $result[$content['value']] = $content['content'];
5747
        }
5748
5749
        return $form->addElement(
5750
            'advmultiselect',
5751
            'users',
5752
            get_lang('Users'),
5753
            $result,
5754
            array('select_all_checkbox' => true)
5755
        );
5756
    }
5757
5758
    /**
5759
     * This function separates the users from the groups
5760
     * users have a value USER:XXX (with XXX the groups id have a value
5761
     *  GROUP:YYY (with YYY the group id)
5762
     * @param  array $to Array of strings that define the type and id of each destination
5763
     * @return array Array of groups and users (each an array of IDs)
5764
     */
5765
    public static function separateUsersGroups($to)
5766
    {
5767
        $grouplist = array();
5768
        $userlist = array();
5769
5770
        foreach ($to as $to_item) {
5771
            if (!empty($to_item)) {
5772
                $parts = explode(':', $to_item);
5773
                $type = isset($parts[0]) ? $parts[0] : '';
5774
                $id = isset($parts[1]) ? $parts[1] : '';
5775
5776
                switch ($type) {
5777
                    case 'GROUP':
5778
                        $grouplist[] = intval($id);
5779
                        break;
5780
                    case 'USER':
5781
                        $userlist[] = intval($id);
5782
                        break;
5783
                }
5784
            }
5785
        }
5786
5787
        $send_to['groups'] = $grouplist;
5788
        $send_to['users'] = $userlist;
5789
5790
        return $send_to;
5791
    }
5792
5793
    /**
5794
     * Shows the form for sending a message to a specific group or user.
5795
     * @param FormValidator $form
5796
     * @param int $group_id id
0 ignored issues
show
Bug introduced by
There is no parameter named $group_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
5797
     * @param array $to
5798
     */
5799 View Code Duplication
    public static function addGroupMultiSelect($form, $groupInfo, $to = array())
5800
    {
5801
        $group_users = GroupManager::get_subscribed_users($groupInfo);
5802
        $array = self::buildSelectOptions(null, $group_users, $to);
5803
5804
        $result = array();
5805
        foreach ($array as $content) {
5806
            $result[$content['value']] = $content['content'];
5807
        }
5808
5809
        return $form->addElement('advmultiselect', 'users', get_lang('Users'), $result);
5810
    }
5811
5812
    /**
5813
     * this function shows the form for sending a message to a specific group or user.
5814
     * @param array $group_list
5815
     * @param array $user_list
5816
     * @param array $to_already_selected
5817
     * @return array
5818
     */
5819
    public static function buildSelectOptions(
5820
        $group_list = array(),
5821
        $user_list = array(),
5822
        $to_already_selected = array()
5823
    ) {
5824
        if (empty($to_already_selected)) {
5825
            $to_already_selected = array();
5826
        }
5827
5828
        $result = array();
5829
        // adding the groups to the select form
5830
        if ($group_list) {
5831
            foreach ($group_list as $this_group) {
5832
                if (is_array($to_already_selected)) {
5833
                    if (!in_array(
5834
                        "GROUP:" . $this_group['id'],
5835
                        $to_already_selected
5836
                    )
5837
                    ) { // $to_already_selected is the array containing the groups (and users) that are already selected
5838
                        $user_label = ($this_group['userNb'] > 0) ? get_lang('Users') : get_lang('LowerCaseUser');
5839
                        $user_disabled = ($this_group['userNb'] > 0) ? "" : "disabled=disabled";
5840
                        $result[] = array(
5841
                            'disabled' => $user_disabled,
5842
                            'value' => "GROUP:" . $this_group['id'],
5843
                            'content' => "G: " . $this_group['name'] . " - " . $this_group['userNb'] . " " . $user_label
5844
                        );
5845
                    }
5846
                }
5847
            }
5848
        }
5849
5850
        // adding the individual users to the select form
5851
        if ($user_list) {
5852
            foreach ($user_list as $user) {
5853
                if (is_array($to_already_selected)) {
5854
                    if (!in_array(
5855
                        "USER:" . $user['user_id'],
5856
                        $to_already_selected
5857
                    )
5858
                    ) { // $to_already_selected is the array containing the users (and groups) that are already selected
5859
5860
                        $result[] = array(
5861
                            'value' => "USER:" . $user['user_id'],
5862
                            'content' => api_get_person_name($user['firstname'], $user['lastname'])
5863
                        );
5864
                    }
5865
                }
5866
            }
5867
        }
5868
5869
        return $result;
5870
    }
5871
5872
    /**
5873
     * @return array a list (array) of all courses.
5874
     */
5875
    public static function get_course_list()
5876
    {
5877
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
5878
        return Database::store_result(Database::query("SELECT *, id as real_id FROM $table"));
5879
    }
5880
5881
    /**
5882
     * Returns course code from a given gradebook category's id
5883
     * @param int  $category_id
5884
     * @return int course id
5885
     */
5886 View Code Duplication
    public static function get_course_by_category($category_id)
5887
    {
5888
        $category_id = intval($category_id);
5889
        $info = Database::fetch_array(
5890
            Database::query('SELECT c_id FROM ' . Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY) . '
5891
            WHERE id=' . $category_id), 'ASSOC'
5892
        );
5893
        return $info ? $info['c_id'] : false;
5894
    }
5895
5896
    /**
5897
     * This function gets all the courses that are not in a session
5898
     * @param date Start date
5899
     * @param date End date
5900
     * @param   bool    $includeClosed Whether to include closed and hidden courses
5901
     * @return array Not-in-session courses
5902
     */
5903
    public static function getCoursesWithoutSession($startDate = null, $endDate = null, $includeClosed = false)
5904
    {
5905
        $dateConditional = ($startDate && $endDate) ?
5906
            " WHERE session_id IN (SELECT id FROM " . Database::get_main_table(TABLE_MAIN_SESSION) .
5907
            " WHERE access_start_date = '$startDate' AND access_end_date = '$endDate')" :
5908
            null;
5909
        $visibility = ($includeClosed ? '' : 'visibility NOT IN (0, 4) AND ');
5910
5911
        $query = "SELECT id, code, title
5912
                FROM " . Database::get_main_table(TABLE_MAIN_COURSE). "
5913
                WHERE $visibility code NOT IN (
5914
                    SELECT DISTINCT course_code FROM " . Database::get_main_table(TABLE_MAIN_SESSION_COURSE) . $dateConditional . ")
5915
                ORDER BY id";
5916
5917
        $result = Database::query($query);
5918
        $courses = array();
5919
        while ($row = Database::fetch_array($result)) {
5920
            $courses[] = $row;
5921
        }
5922
        return $courses;
5923
    }
5924
5925
    /**
5926
     * Get list of courses based on users of a group for a group admin
5927
     * @param int $userId The user id
5928
     * @return array
5929
     */
5930 View Code Duplication
    public static function getCoursesFollowedByGroupAdmin($userId)
5931
    {
5932
        $coursesList = [];
5933
5934
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
5935
        $courseUserTable = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5936
        $userGroup = new UserGroup();
5937
        $userIdList = $userGroup->getGroupUsersByUser($userId);
5938
5939
        if (empty($userIdList)) {
5940
            return [];
5941
        }
5942
5943
        $sql = "SELECT DISTINCT(c.id), c.title
5944
                FROM $courseTable c
5945
                INNER JOIN $courseUserTable cru ON c.id = cru.c_id
5946
                WHERE (
5947
                    cru.user_id IN (" . implode(', ', $userIdList) . ")
5948
                    AND cru.relation_type = 0
5949
                )";
5950
5951
        if (api_is_multiple_url_enabled()) {
5952
            $courseAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
5953
            $accessUrlId = api_get_current_access_url_id();
5954
5955
            if ($accessUrlId != -1) {
5956
                $sql = "SELECT DISTINCT(c.id), c.title
5957
                        FROM $courseTable c
5958
                        INNER JOIN $courseUserTable cru ON c.id = cru.c_id
5959
                        INNER JOIN $courseAccessUrlTable crau ON c.id = crau.c_id
5960
                        WHERE crau.access_url_id = $accessUrlId
5961
                            AND (
5962
                            cru.id_user IN (" . implode(', ', $userIdList) . ") AND
5963
                            cru.relation_type = 0
5964
                        )";
5965
            }
5966
        }
5967
5968
        $result = Database::query($sql);
5969
5970
        while ($row = Database::fetch_assoc($result)) {
5971
            $coursesList[] = $row;
5972
        }
5973
5974
        return $coursesList;
5975
    }
5976
5977
    /**
5978
     * Direct course link see #5299
5979
     *
5980
     * You can send to your students an URL like this
5981
     * http://chamilodev.beeznest.com/main/auth/inscription.php?c=ABC&e=3
5982
     * Where "c" is the course code and "e" is the exercise Id, after a successful
5983
     * registration the user will be sent to the course or exercise
5984
     *
5985
     */
5986
    public static function redirectToCourse($form_data)
5987
    {
5988
        $course_code_redirect = Session::read('course_redirect');
5989
        $_user = api_get_user_info();
5990
        $user_id = api_get_user_id();
5991
5992
        if (!empty($course_code_redirect)) {
5993
            $course_info = api_get_course_info($course_code_redirect);
5994
            if (!empty($course_info)) {
5995
                if (in_array($course_info['visibility'],
5996
                    array(COURSE_VISIBILITY_OPEN_PLATFORM, COURSE_VISIBILITY_OPEN_WORLD))
5997
                ) {
5998
                    if (self::is_user_subscribed_in_course($user_id, $course_info['code'])) {
5999
6000
                        $form_data['action'] = $course_info['course_public_url'];
6001
                        $form_data['message'] = sprintf(get_lang('YouHaveBeenRegisteredToCourseX'), $course_info['title']);
6002
                        $form_data['button'] = Display::button(
6003
                            'next',
6004
                            get_lang('GoToCourse', null, $_user['language']),
6005
                            array('class' => 'btn btn-primary btn-large')
6006
                        );
6007
6008
                        $exercise_redirect = intval(Session::read('exercise_redirect'));
6009
                        // Specify the course id as the current context does not
6010
                        // hold a global $_course array
6011
                        $objExercise = new Exercise($course_info['real_id']);
6012
                        $result = $objExercise->read($exercise_redirect);
6013
6014
                        if (!empty($exercise_redirect) && !empty($result)) {
6015
                            $form_data['action'] = api_get_path(WEB_CODE_PATH) . 'exercise/overview.php?exerciseId='.$exercise_redirect.'&cidReq='.$course_info['code'];
6016
                            $form_data['message'] .= '<br />'.get_lang('YouCanAccessTheExercise');
6017
                            $form_data['button'] = Display::button(
6018
                                'next',
6019
                                get_lang('Go', null, $_user['language']),
6020
                                array('class' => 'btn btn-primary btn-large')
6021
                            );
6022
                        }
6023
6024
                        if (!empty($form_data['action'])) {
6025
                            header('Location: '.$form_data['action']);
6026
                            exit;
6027
                        }
6028
                    }
6029
                }
6030
            }
6031
        }
6032
6033
        return $form_data;
6034
    }
6035
6036
    /**
6037
     * return html code for displaying a course title in the standard view (not the Session view)
6038
     * @param $courseId
6039
     * @param bool $loadDirs
6040
     * @return string
6041
     */
6042
    public static function displayCourseHtml($courseId, $loadDirs = false)
6043
    {
6044
        $params = self::getCourseParamsForDisplay($courseId, $loadDirs);
6045
        $html = self::course_item_html($params, false);
0 ignored issues
show
Bug introduced by
It seems like $params defined by self::getCourseParamsFor...y($courseId, $loadDirs) on line 6044 can also be of type string; however, CourseManager::course_item_html() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
6046
6047
        return $html;
6048
    }
6049
6050
    /**
6051
     * Return tab of params to display a course title in the My Courses tab
6052
     * Check visibility, right, and notification icons, and load_dirs option
6053
     * @param $courseId
6054
     * @param bool $loadDirs
6055
     * @return array with keys ['right_actions'] ['teachers'] ['notifications']
6056
     */
6057
    public static function getCourseParamsForDisplay($courseId, $loadDirs = false)
6058
    {
6059
        $user_id = api_get_user_id();
6060
        // Table definitions
6061
        $TABLECOURS = Database::get_main_table(TABLE_MAIN_COURSE);
6062
        $TABLECOURSUSER = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6063
        $TABLE_ACCESS_URL_REL_COURSE = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
6064
        $current_url_id = api_get_current_access_url_id();
6065
6066
        // Get course list auto-register
6067
        $special_course_list = self::get_special_course_list();
6068
6069
        $without_special_courses = '';
6070
        if (!empty($special_course_list)) {
6071
            $without_special_courses = ' AND course.id NOT IN ("'.implode('","',$special_course_list).'")';
6072
        }
6073
6074
        //AND course_rel_user.relation_type<>".COURSE_RELATION_TYPE_RRHH."
6075
        $sql = "SELECT 
6076
                    course.id, 
6077
                    course.title, 
6078
                    course.code, 
6079
                    course.subscribe subscr, 
6080
                    course.unsubscribe unsubscr, 
6081
                    course_rel_user.status status,
6082
                    course_rel_user.sort sort, 
6083
                    course_rel_user.user_course_cat user_course_cat
6084
                FROM
6085
                $TABLECOURS course 
6086
                INNER JOIN $TABLECOURSUSER course_rel_user                
6087
                ON (course.id = course_rel_user.c_id)
6088
                INNER JOIN $TABLE_ACCESS_URL_REL_COURSE url
6089
                ON (url.c_id = course.id)
6090
                WHERE
6091
                    course.id=".intval($courseId)." AND
6092
                    course_rel_user.user_id = ".intval($user_id)."
6093
                    $without_special_courses
6094
                ";
6095
6096
        // If multiple URL access mode is enabled, only fetch courses
6097
        // corresponding to the current URL.
6098
        if (api_get_multiple_access_url() && $current_url_id != -1) {
6099
            $sql .= " AND url.c_id = course.id AND access_url_id=".intval($current_url_id);
6100
        }
6101
        // Use user's classification for courses (if any).
6102
        $sql .= " ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
6103
6104
        $result = Database::query($sql);
6105
6106
        // Browse through all courses. We can only have one course because
6107
        // of the  course.id=".intval($courseId) in sql query
6108
        $course = Database::fetch_array($result);
6109
        $course_info = api_get_course_info_by_id($courseId);
6110
        if (empty($course_info)) {
6111
            return '';
6112
        }
6113
6114
        //$course['id_session'] = null;
6115
        $course_info['id_session'] = null;
6116
        $course_info['status'] = $course['status'];
6117
6118
        // For each course, get if there is any notification icon to show
6119
        // (something that would have changed since the user's last visit).
6120
        $show_notification = !api_get_configuration_value('hide_course_notification')
6121
            ? Display::show_notification($course_info)
6122
            : '';
6123
6124
        // New code displaying the user's status in respect to this course.
6125
        $status_icon = Display::return_icon(
6126
            'blackboard.png',
6127
            $course_info['title'],
6128
            array(),
6129
            ICON_SIZE_LARGE
6130
        );
6131
6132
        $params = array();
6133
        $params['right_actions'] = '';
6134
6135
        if (api_is_platform_admin()) {
6136 View Code Duplication
            if ($loadDirs) {
6137
                $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'), array('align' => 'absmiddle'),ICON_SIZE_SMALL).'</a>';
6138
                $params['right_actions'] .= '<a href="'.api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cidReq='.$course['code'].'">'.Display::return_icon('edit.png', get_lang('Edit'), array('align' => 'absmiddle'),ICON_SIZE_SMALL).'</a>';
6139
                $params['right_actions'] .= Display::div('', array('id' => 'document_result_'.$course_info['real_id'].'_0', 'class'=>'document_preview_container'));
6140
            } else {
6141
                $params['right_actions'].= '<a class="btn btn-default btn-sm" title="'.get_lang('Edit').'" href="'.api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cidReq='.$course['code'].'">'.Display::returnFontAwesomeIcon('pencil').'</a>';
6142
            }
6143
6144
            if ($course_info['status'] == COURSEMANAGER) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
6145
                //echo Display::return_icon('teachers.gif', get_lang('Status').': '.get_lang('Teacher'), array('style'=>'width: 11px; height: 11px;'));
6146
            }
6147
        } else {
6148
            if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
6149 View Code Duplication
                if ($loadDirs) {
6150
                    $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'), array('align' => 'absmiddle'),ICON_SIZE_SMALL).'</a>';
6151
                    $params['right_actions'] .= Display::div('', array('id' => 'document_result_'.$course_info['real_id'].'_0', 'class'=>'document_preview_container'));
6152
                } else {
6153
                    if ($course_info['status'] == COURSEMANAGER) {
6154
                        $params['right_actions'].= '<a class="btn btn-default btn-sm" title="'.get_lang('Edit').'" href="'.api_get_path(WEB_CODE_PATH).'course_info/infocours.php?cidReq='.$course['code'].'">'.Display::returnFontAwesomeIcon('pencil').'</a>';
6155
                    }
6156
                }
6157
            }
6158
        }
6159
6160
        $course_title_url = '';
6161 View Code Duplication
        if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED || $course['status'] == COURSEMANAGER) {
6162
            $course_title_url = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/?id_session=0';
6163
            $course_title = Display::url($course_info['title'], $course_title_url);
6164
        } else {
6165
            $course_title = $course_info['title'].' '.Display::tag('span',get_lang('CourseClosed'), array('class'=>'item_closed'));
6166
        }
6167
6168
        // Start displaying the course block itself
6169
        if (api_get_setting('display_coursecode_in_courselist') === 'true') {
6170
            $course_title .= ' ('.$course_info['visual_code'].') ';
6171
        }
6172
        $teachers = '';
6173
        if (api_get_setting('display_teacher_in_courselist') === 'true') {
6174
            $teachers = self::get_teacher_list_from_course_code_to_string($course['code'], self::USER_SEPARATOR, true);
6175
        }
6176
        $params['link'] = $course_title_url;
6177
        $params['icon'] = $status_icon;
6178
        $params['title'] = $course_title;
6179
        $params['teachers'] = $teachers;
6180
        if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
6181
            $params['notifications'] = $show_notification;
6182
        }
6183
6184
        return $params;
6185
    }
6186
6187
    /**
6188
     * Get the course id based on the original id and field name in the extra fields.
6189
     * Returns 0 if course was not found
6190
     *
6191
     * @param string $original_course_id_value Original course id
6192
     * @param string $original_course_id_name Original field name
6193
     * @return int Course id
6194
     */
6195
    public static function get_course_id_from_original_id($original_course_id_value, $original_course_id_name)
6196
    {
6197
        $extraFieldValue = new ExtraFieldValue('course');
6198
        $value = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
6199
            $original_course_id_name,
6200
            $original_course_id_value
6201
        );
6202
6203
        if ($value) {
6204
            return $value['item_id'];
6205
        }
6206
        return 0;
6207
    }
6208
6209
    /**
6210
     * Helper function to create a default gradebook (if necessary) upon course creation
6211
     * @param   int     $modelId    The gradebook model ID
6212
     * @param   int  $courseId Course code
6213
     * @return  void
6214
     */
6215
    public static function createDefaultGradebook($modelId, $courseId)
6216
    {
6217
        if (api_get_setting('gradebook_enable_grade_model') === 'true') {
6218
            //Create gradebook_category for the new course and add
6219
            // a gradebook model for the course
6220
            if (isset($modelId) &&
6221
                !empty($modelId) &&
6222
                $modelId != '-1'
6223
            ) {
6224
                GradebookUtils::createDefaultCourseGradebook(
6225
                    $courseId,
6226
                    $modelId
6227
                );
6228
            }
6229
        }
6230
    }
6231
6232
    /**
6233
     * Helper function to check if there is a course template and, if so, to
6234
     * copy the template as basis for the new course
6235
     * @param   string  $courseCode   Course code
6236
     * @param   int     $courseTemplate 0 if no course template is defined
6237
     */
6238
    public static function useTemplateAsBasisIfRequired($courseCode, $courseTemplate)
6239
    {
6240
        $template = api_get_setting('course_creation_use_template');
6241
        $teacherCanSelectCourseTemplate = api_get_setting('teacher_can_select_course_template') === 'true';
6242
        $courseTemplate = isset($courseTemplate) ? intval($courseTemplate) : 0;
6243
6244
        $useTemplate = false;
6245
6246
        if ($teacherCanSelectCourseTemplate && $courseTemplate) {
6247
            $useTemplate = true;
6248
            $originCourse = api_get_course_info_by_id($courseTemplate);
6249
        } elseif (!empty($template)) {
6250
            $useTemplate = true;
6251
            $originCourse = api_get_course_info_by_id($template);
6252
        }
6253
6254
        if ($useTemplate) {
6255
            // Include the necessary libraries to generate a course copy
6256
            // Call the course copy object
6257
            $originCourse['official_code'] = $originCourse['code'];
6258
            $cb = new CourseBuilder(null, $originCourse);
6259
            $course = $cb->build(null, $originCourse['code']);
6260
            $cr = new CourseRestorer($course);
6261
            $cr->set_file_option();
6262
            $cr->restore($courseCode);
6263
        }
6264
    }
6265
6266
    /**
6267
     * Helper method to get the number of users defined with a specific course extra field
6268
     * @param   string  $name   Field title
6269
     * @param   string  $tableExtraFields The extra fields table name
6270
     * @param   string  $tableUserFieldValues The user extra field value table name
6271
     * @return  int     The number of users with this extra field with a specific value
6272
     */
6273
    public static function getCountRegisteredUsersWithCourseExtraField($name, $tableExtraFields = '', $tableUserFieldValues = '')
6274
    {
6275
        if (empty($tableExtraFields)) {
6276
            $tableExtraFields = Database::get_main_table(TABLE_EXTRA_FIELD);
6277
        }
6278
        if (empty($tableUserFieldValues)) {
6279
            $tableUserFieldValues = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6280
        }
6281
6282
        $registered_users_with_extra_field = 0;
6283
6284
        if (!empty($name) && $name != '-') {
6285
            $extraFieldType = EntityExtraField::COURSE_FIELD_TYPE;
6286
            $name = Database::escape_string($name);
6287
            $sql = "SELECT count(v.item_id) as count
6288
                    FROM $tableUserFieldValues v 
6289
                    INNER JOIN $tableExtraFields f
6290
                    ON (f.id = v.field_id)
6291
                    WHERE value = '$name' AND extra_field_type = $extraFieldType";
6292
            $result_count = Database::query($sql);
6293
            if (Database::num_rows($result_count)) {
6294
                $row_count = Database::fetch_array($result_count);
6295
                $registered_users_with_extra_field = $row_count['count'];
6296
            }
6297
        }
6298
6299
        return $registered_users_with_extra_field;
6300
    }
6301
6302
    /**
6303
     * Check if a specific access-url-related setting is a problem or not
6304
     * @param array $_configuration The $_configuration array
6305
     * @param int $accessUrlId The access URL ID
6306
     * @param string $param
6307
     * @param string $msgLabel
6308
     * @return bool|string
6309
     */
6310
    private static function checkCreateCourseAccessUrlParam($_configuration, $accessUrlId, $param, $msgLabel)
6311
    {
6312
        if (isset($_configuration[$accessUrlId][$param]) && $_configuration[$accessUrlId][$param] > 0) {
6313
            $num = self::count_courses($accessUrlId);
6314
            if ($num >= $_configuration[$accessUrlId][$param]) {
6315
                api_warn_hosting_contact($param);
6316
6317
                Display::addFlash(
6318
                    Display::return_message($msgLabel)
6319
                );
6320
            }
6321
        }
6322
        return false;
6323
    }
6324
6325
    /**
6326
     * @param int $user_id
6327
     * @param $filter
6328
     * @param bool $load_dirs
6329
     * @param int $getCount
6330
     * @param int $start
6331
     * @param null $maxPerPage
6332
     * @return null|string
6333
     */
6334
    public static function displayCourses(
6335
        $user_id,
6336
        $filter,
6337
        $load_dirs,
6338
        $getCount,
6339
        $start = null,
6340
        $maxPerPage = null
6341
    ) {
6342
        // Table definitions
6343
        $TABLECOURS = Database:: get_main_table(TABLE_MAIN_COURSE);
6344
        $TABLECOURSUSER = Database:: get_main_table(TABLE_MAIN_COURSE_USER);
6345
        $TABLE_ACCESS_URL_REL_COURSE = Database:: get_main_table(
6346
            TABLE_MAIN_ACCESS_URL_REL_COURSE
6347
        );
6348
        $current_url_id = api_get_current_access_url_id();
6349
6350
        // Get course list auto-register
6351
        $special_course_list = self::get_special_course_list();
6352
6353
        $without_special_courses = '';
6354
6355
        if (!empty($special_course_list)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
6356
            //$without_special_courses = ' AND course.code NOT IN ("'.implode('","',$special_course_list).'")';
6357
        }
6358
6359
        $select = " SELECT DISTINCT
6360
                     course.id,
6361
                     course.title,
6362
                     course.code,
6363
                     course.subscribe subscr,
6364
                     course.unsubscribe unsubscr,
6365
                     course_rel_user.status status,
6366
                     course_rel_user.sort sort,
6367
                     course_rel_user.user_course_cat user_course_cat,
6368
                     course.id as real_id
6369
         ";
6370
6371
        $from = "$TABLECOURS course, $TABLECOURSUSER  course_rel_user, $TABLE_ACCESS_URL_REL_COURSE url ";
6372
6373
        $where = "  course.id = course_rel_user.c_id AND
6374
                     url.c_id = course.id AND
6375
                     course_rel_user.user_id = '".$user_id."' AND
6376
                     course_rel_user.user_course_cat = 0
6377
                     ";
6378
6379
        $order = " ORDER BY course_rel_user.user_course_cat, course_rel_user.sort ASC";
6380
6381
6382
        if ($getCount) {
6383
            $select = "SELECT count(course.id) as total";
6384
        }
6385
6386
        $sql = "$select FROM $from WHERE $where $without_special_courses ";
6387
6388
        // corresponding to the current URL.
6389
        if (api_get_multiple_access_url() && $current_url_id != -1) {
6390
            $sql .= " AND url.c_id = course.id AND access_url_id='".$current_url_id."'";
6391
        }
6392
6393
        $sql .= $order;
6394
6395 View Code Duplication
        if (isset($start) && isset($maxPerPage)) {
6396
            $start = intval($start);
6397
            $maxPerPage = intval($maxPerPage);
6398
            $limitCondition = " LIMIT $start, $maxPerPage";
6399
            $sql .= $limitCondition;
6400
        }
6401
6402 View Code Duplication
        if ($getCount) {
6403
            $result = Database::query($sql);
6404
            $row = Database::fetch_array($result);
6405
6406
            return $row['total'];
6407
        }
6408
        $result = Database::query($sql);
6409
6410
        $html = null;
6411
        $course_list = array();
6412
6413
        // Browse through all courses.
6414
        while ($course = Database::fetch_array($result)) {
6415
            $course_info = api_get_course_info($course['code']);
6416
            $course_info['id_session'] = null;
6417
            $course_info['status'] = $course['status'];
6418
6419
            //In order to avoid doubles
6420
            if (in_array($course_info['real_id'], $course_list)) {
6421
                continue;
6422
            } else {
6423
                $course_list[] = $course_info['real_id'];
6424
            }
6425
6426
            // For each course, get if there is any notification icon to show
6427
            // (something that would have changed since the user's last visit).
6428
            $show_notification = Display:: show_notification($course_info);
6429
6430
            // New code displaying the user's status in respect to this course.
6431
            $status_icon = Display::return_icon(
6432
                'blackboard.png',
6433
                $course_info['title'],
6434
                array(),
6435
                ICON_SIZE_LARGE
6436
            );
6437
6438
            $params = array();
6439
            $params['right_actions'] = '';
6440
6441
            if (api_is_platform_admin()) {
6442 View Code Duplication
                if ($load_dirs) {
6443
                    $params['right_actions'] .= '<a id="document_preview_'.$course_info['real_id'].'_0" class="document_preview" href="javascript:void(0);">'.Display::return_icon(
6444
                            'folder.png',
6445
                            get_lang('Documents'),
6446
                            array('align' => 'absmiddle'),
6447
                            ICON_SIZE_SMALL
6448
                        ).'</a>';
6449
                    $params['right_actions'] .= '<a href="'.api_get_path(
6450
                            WEB_CODE_PATH
6451
                        ).'course_info/infocours.php?cidReq='.$course['code'].'">'.Display::return_icon(
6452
                            'edit.png',
6453
                            get_lang('Edit'),
6454
                            array('align' => 'absmiddle'),
6455
                            ICON_SIZE_SMALL
6456
                        ).'</a>';
6457
                    $params['right_actions'] .= Display::div(
6458
                        '',
6459
                        array(
6460
                            'id' => 'document_result_'.$course_info['real_id'].'_0',
6461
                            'class' => 'document_preview_container',
6462
                        )
6463
                    );
6464
                } else {
6465
                    $params['right_actions'] .= '<a href="'.api_get_path(
6466
                            WEB_CODE_PATH
6467
                        ).'course_info/infocours.php?cidReq='.$course['code'].'">'.Display::return_icon(
6468
                            'edit.png',
6469
                            get_lang('Edit'),
6470
                            array('align' => 'absmiddle'),
6471
                            ICON_SIZE_SMALL
6472
                        ).'</a>';
6473
                }
6474
6475
                if ($course_info['status'] == COURSEMANAGER) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
6476
                    //echo Display::return_icon('teachers.gif', get_lang('Status').': '.get_lang('Teacher'), array('style'=>'width: 11px; height: 11px;'));
6477
                }
6478 View Code Duplication
            } else {
6479
                if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
6480
                    if ($load_dirs) {
6481
                        $params['right_actions'] .= '<a id="document_preview_'.$course_info['real_id'].'_0" class="document_preview" href="javascript:void(0);">'.Display::return_icon(
6482
                                'folder.png',
6483
                                get_lang('Documents'),
6484
                                array('align' => 'absmiddle'),
6485
                                ICON_SIZE_SMALL
6486
                            ).'</a>';
6487
                        $params['right_actions'] .= Display::div(
6488
                            '',
6489
                            array(
6490
                                'id' => 'document_result_'.$course_info['real_id'].'_0',
6491
                                'class' => 'document_preview_container',
6492
                            )
6493
                        );
6494
                    } else {
6495
                        if ($course_info['status'] == COURSEMANAGER) {
6496
                            $params['right_actions'] .= '<a href="'.api_get_path(
6497
                                    WEB_CODE_PATH
6498
                                ).'course_info/infocours.php?cidReq='.$course['code'].'">'.Display::return_icon(
6499
                                    'edit.png',
6500
                                    get_lang('Edit'),
6501
                                    array('align' => 'absmiddle'),
6502
                                    ICON_SIZE_SMALL
6503
                                ).'</a>';
6504
                        }
6505
                    }
6506
                }
6507
            }
6508
6509
            $course_title_url = '';
6510 View Code Duplication
            if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED || $course['status'] == COURSEMANAGER) {
6511
                //$course_title_url = api_get_path(WEB_COURSE_PATH).$course_info['path'].'/index.php?id_session=0';
6512
                $course_title_url = api_get_path(
6513
                        WEB_COURSE_PATH
6514
                    ).$course_info['code'].'/index.php?id_session=0';
6515
                $course_title = Display::url(
6516
                    $course_info['title'],
6517
                    $course_title_url
6518
                );
6519
            } else {
6520
                $course_title = $course_info['title']." ".Display::tag(
6521
                        'span',
6522
                        get_lang('CourseClosed'),
6523
                        array('class' => 'item_closed')
6524
                    );
6525
            }
6526
6527
            // Start displaying the course block itself
6528
            if (api_get_setting(
6529
                    'course.display_coursecode_in_courselist'
6530
                ) == 'true'
6531
            ) {
6532
                $course_title .= ' ('.$course_info['visual_code'].') ';
6533
            }
6534
            $teachers = null;
6535
            if (api_get_setting('course.display_teacher_in_courselist') == 'true'
6536
            ) {
6537
                $teachers = $course_info['teacher_list_formatted'];
6538
            }
6539
6540
            $params['link'] = $course_title_url;
6541
            $params['icon'] = $status_icon;
6542
            $params['title'] = $course_title;
6543
            $params['teachers'] = $teachers;
6544
6545
            if ($course_info['visibility'] != COURSE_VISIBILITY_CLOSED) {
6546
                $params['notifications'] = $show_notification;
6547
            }
6548
            $is_subcontent = true;
6549
            if (empty($user_category_id)) {
6550
                $is_subcontent = false;
6551
            }
6552
            $html .= self::course_item_html($params, $is_subcontent);
6553
        }
6554
6555
        return $html;
6556
    }
6557
6558
    /**
6559
     * Builds the course block in user_portal.php
6560
     * @todo use Twig
6561
     * @param array $params
6562
     * @param bool|false $is_sub_content
6563
     * @return string
6564
     */
6565
    public static function course_item_html($params, $is_sub_content = false)
6566
    {
6567
        $html = '';
6568
        $class = "panel panel-default";
6569
        if ($is_sub_content) {
6570
            $class = "course_item";
6571
        }
6572
        $html .= '<div class="'.$class.'">';
6573
        $html .= '<div class="panel-body">';
6574
        $html .= '<div class="course-items">';
6575
        $html .= ' <div class="row">';
6576
        $html .= '<div class="col-md-2">';
6577
        if (!empty($params['link'])) {
6578
            $html .= '<a class="thumbnail" href="'.$params['link'].'">';
6579
            $html .= $params['icon'];
6580
            $html .= '</a>';
6581
        } else {
6582
            $html .= '<div class="thumbnail">';
6583
            $html .= $params['icon'];
6584
            $html .= '</div>';
6585
        }
6586
        $html .= '</div>';
6587
        $notifications = isset($params['notifications']) ? $params['notifications'] : '';
6588
        $param_class = isset($params['class']) ? $params['class'] : '';
6589
        $params['right_actions'] = isset($params['right_actions']) ? $params['right_actions'] : '';
6590
6591
        $html .= '<div class="col-md-10 '.$param_class.'">';
6592
        $html .= '<div class="pull-right">'.$params['right_actions'].'</div>';
6593
        $html .= '<h4 class="course-items-title">'.$params['title'].$notifications.'</h4> ';
6594
6595
        if (isset($params['show_description'], $params['description']) && $params['show_description'] == 1) {
6596
            $html .= '<p class="description-session">'.$params['description'].'</p>';
6597
        }
6598
        if (!empty($params['subtitle'])) {
6599
            $html .= '<div class="subtitle-session">'.$params['subtitle'].'</div>';
6600
        }
6601 View Code Duplication
        if (!empty($params['teachers'])) {
6602
            $teachers = $params['teachers'];
6603
            $html .= '<h5 class="course-items-session">'.
6604
                Display::return_icon(
6605
                    'teacher.png',
6606
                    get_lang('Teacher'),
6607
                    array(),
6608
                    ICON_SIZE_TINY
6609
                ).
6610
                $teachers.'</h5>';
6611
        }
6612
        if (!empty($params['coaches'])) {
6613
            $coaches = '';
6614
            if (is_array($params['coaches'])) {
6615
                foreach ($params['coaches'] as $coach) {
6616
                    $coaches .= $coach['full_name'];
6617
                }
6618
            }
6619
            $html .= '<h5 class="course-items-session">'.
6620
                Display::return_icon(
6621
                    'teacher.png',
6622
                    get_lang('Coach'),
6623
                    array(),
6624
                    ICON_SIZE_TINY
6625
                ).
6626
                $coaches.
6627
                '</h5>';
6628
        }
6629
6630
        $html .= '</div>';
6631
        $html .= '</div>';
6632
6633
        $html .= '</div>';
6634
6635
        $html .= '</div>';
6636
        $html .= '</div>';
6637
6638
        return $html;
6639
    }
6640
6641
    /**
6642
     * Fill course with all necessary items
6643
     * @param array $courseInfo Course info array
6644
     * @param array $params Parameters from the course creation form
6645
     * @param int $authorId
6646
     * @return void
6647
     */
6648
    private static function fillCourse($courseInfo, $params, $authorId = 0)
6649
    {
6650
        $authorId = empty($authorId) ? api_get_user_id() : (int) $authorId;
6651
6652
        AddCourse::prepare_course_repository($courseInfo['directory'], $courseInfo['code']);
6653
        AddCourse::fill_db_course(
6654
            $courseInfo['real_id'],
6655
            $courseInfo['directory'],
6656
            $courseInfo['course_language'],
6657
            $params['exemplary_content'],
6658
            $authorId
6659
        );
6660
6661
        if (isset($params['gradebook_model_id'])) {
6662
            self::createDefaultGradebook($params['gradebook_model_id'], $courseInfo['real_id']);
6663
        }
6664
        // If parameter defined, copy the contents from a specific
6665
        // template course into this new course
6666
        if (isset($params['course_template'])) {
6667
            self::useTemplateAsBasisIfRequired($courseInfo['id'], $params['course_template']);
6668
        }
6669
        $params['course_code'] = $courseInfo['code'];
6670
        $params['item_id'] = $courseInfo['real_id'];
6671
6672
        $courseFieldValue = new ExtraFieldValue('course');
6673
        $courseFieldValue->saveFieldValues($params);
6674
    }
6675
6676
    /**
6677
     * Get the course categories form a course list
6678
     * @param array $courseList
6679
     * @return array
6680
     */
6681
    public static function getCourseCategoriesFromCourseList(array $courseList)
6682
    {
6683
        $allCategories = array_column($courseList, 'category');
6684
        $categories = array_unique($allCategories);
6685
6686
        sort($categories);
6687
6688
        return $categories;
6689
    }
6690
6691
    /**
6692
     * @param ToolChain $toolList
6693
     */
6694
    public static function setToolList($toolList)
6695
    {
6696
        self::$toolList = $toolList;
6697
    }
6698
6699
    /**
6700
     * @return ToolChain
6701
     */
6702
    public static function getToolList()
6703
    {
6704
        return self::$toolList;
6705
    }
6706
}
6707