Completed
Push — master ( 626f54...3fdf06 )
by Julito
39:11 queued 08:33
created

SessionManager::getTotalUserCoursesInSession()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 29
Code Lines 14

Duplication

Lines 29
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
eloc 14
nc 3
nop 1
dl 29
loc 29
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
5
use \ExtraField as ExtraFieldModel;
6
use Chamilo\CoreBundle\Entity\ExtraField;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, ExtraField.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
7
use Chamilo\CoreBundle\Entity\Session;
8
9
/**
10
 * Class SessionManager
11
 *
12
 * This is the session library for Chamilo.
13
 * All main sessions functions should be placed here.
14
 * This class provides methods for sessions management.
15
 * Include/require it in your code to use its features.
16
 *
17
 * @package chamilo.library
18
 *
19
 */
20
class SessionManager
21
{
22
    public static $_debug = false;
23
24
    /**
25
     * Constructor
26
     */
27
    public function __construct()
28
    {
29
    }
30
31
    /**
32
     * Fetches a session from the database
33
     * @param  int $id Session Id
34
     *
35
     * @return  array   Session details
36
     */
37
    public static function fetch($id)
38
    {
39
        $em = Database::getManager();
40
        /** @var Session $session */
41
        $session = $em->find('ChamiloCoreBundle:Session', $id);
42
43
        if (!$session) {
44
            return [];
45
        }
46
47
        return [
48
            'id' => $session->getId(),
49
            'id_coach' => $session->getGeneralCoach() ? $session->getGeneralCoach()->getId() : null,
50
            'session_category_id' => $session->getCategory() ? $session->getCategory()->getId() : null,
51
            'name' => $session->getName(),
52
            'description' => $session->getDescription(),
53
            'show_description' => $session->getShowDescription(),
54
            'duration' => $session->getDuration(),
55
            'nbr_courses' => $session->getNbrCourses(),
56
            'nbr_users' => $session->getNbrUsers(),
57
            'nbr_classes' => $session->getNbrClasses(),
58
            'session_admin_id' => $session->getSessionAdminId(),
59
            'visibility' => $session->getVisibility(),
60
            'promotion_id' => $session->getPromotionId(),
61
            'display_start_date' => $session->getDisplayStartDate()
62
                ? $session->getDisplayStartDate()->format('Y-m-d H:i:s')
63
                : null,
64
            'display_end_date' => $session->getDisplayEndDate()
65
                ? $session->getDisplayEndDate()->format('Y-m-d H:i:s')
66
                : null,
67
            'access_start_date' => $session->getAccessStartDate()
68
                ? $session->getAccessStartDate()->format('Y-m-d H:i:s')
69
                : null,
70
            'access_end_date' => $session->getAccessEndDate()
71
                ? $session->getAccessEndDate()->format('Y-m-d H:i:s')
72
                : null,
73
            'coach_access_start_date' => $session->getCoachAccessStartDate()
74
                ? $session->getCoachAccessStartDate()->format('Y-m-d H:i:s')
75
                : null,
76
            'coach_access_end_date' => $session->getCoachAccessEndDate()
77
                ? $session->getCoachAccessEndDate()->format('Y-m-d H:i:s')
78
                : null,
79
            'send_subscription_notification' => $session->getSendSubscriptionNotification()
80
        ];
81
    }
82
83
    /**
84
     * Create a session
85
     * @author Carlos Vargas <[email protected]>, from existing code
86
     * @param   string  $name
87
     * @param   string  $startDate (YYYY-MM-DD hh:mm:ss)
88
     * @param   string  $endDate (YYYY-MM-DD hh:mm:ss)
89
     * @param   string  $displayStartDate (YYYY-MM-DD hh:mm:ss)
90
     * @param   string  $displayEndDate (YYYY-MM-DD hh:mm:ss)
91
     * @param   string  $coachStartDate (YYYY-MM-DD hh:mm:ss)
92
     * @param   string  $coachEndDate (YYYY-MM-DD hh:mm:ss)
93
     * @param   mixed   $coachId If integer, this is the session coach id, if string, the coach ID will be looked for from the user table
94
     * @param   integer $sessionCategoryId ID of the session category in which this session is registered
95
     * @param   integer $visibility Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
96
     * @param   bool    $fixSessionNameIfExists
97
     * @param   string  $duration
98
     * @param   string  $description Optional. The session description
99
     * @param   int     $showDescription Optional. Whether show the session description
100
     * @param   array   $extraFields
101
     * @param   int     $sessionAdminId Optional. If this sessions was created by a session admin, assign it to him
102
     * @param boolean $sendSubscriptionNotification Optional.
103
     *          Whether send a mail notification to users being subscribed
104
     * @todo use an array to replace all this parameters or use the model.lib.php ...
105
     * @return mixed       Session ID on success, error message otherwise
106
     * */
107
    public static function create_session(
108
        $name,
109
        $startDate,
110
        $endDate,
111
        $displayStartDate,
112
        $displayEndDate,
113
        $coachStartDate,
114
        $coachEndDate,
115
        $coachId,
116
        $sessionCategoryId,
117
        $visibility = 1,
118
        $fixSessionNameIfExists = false,
119
        $duration = null,
120
        $description = null,
121
        $showDescription = 0,
122
        $extraFields = array(),
123
        $sessionAdminId = 0,
124
        $sendSubscriptionNotification = false
125
    ) {
126
        global $_configuration;
127
128
        //Check portal limits
129
        $access_url_id = 1;
130
131
        if (api_get_multiple_access_url()) {
132
            $access_url_id = api_get_current_access_url_id();
133
        }
134
135
        if (is_array($_configuration[$access_url_id]) &&
136
            isset($_configuration[$access_url_id]['hosting_limit_sessions']) &&
137
            $_configuration[$access_url_id]['hosting_limit_sessions'] > 0
138
        ) {
139
            $num = self::count_sessions();
140
            if ($num >= $_configuration[$access_url_id]['hosting_limit_sessions']) {
141
                api_warn_hosting_contact('hosting_limit_sessions');
142
                return get_lang('PortalSessionsLimitReached');
143
            }
144
        }
145
146
        $name = Database::escape_string(trim($name));
147
        $sessionCategoryId = intval($sessionCategoryId);
148
        $visibility = intval($visibility);
149
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
150
151
        $startDate = Database::escape_string($startDate);
152
        $endDate = Database::escape_string($endDate);
153
154
        if (empty($name)) {
155
            $msg = get_lang('SessionNameIsRequired');
156
            return $msg;
157
        } elseif (empty($coachId)) {
158
            $msg = get_lang('CoachIsRequired');
159
            return $msg;
160
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
161
            $msg = get_lang('InvalidStartDate');
162
            return $msg;
163
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
164
            $msg = get_lang('InvalidEndDate');
165
            return $msg;
166
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
167
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
168
            return $msg;
169
        } else {
170
            $ready_to_create = false;
171
            if ($fixSessionNameIfExists) {
172
                $name = self::generateNextSessionName($name);
173
                if ($name) {
174
                    $ready_to_create = true;
175
                } else {
176
                    $msg = get_lang('SessionNameAlreadyExists');
177
                    return $msg;
178
                }
179
            } else {
180
                $rs = Database::query("SELECT 1 FROM $tbl_session WHERE name='" . $name . "'");
181
                if (Database::num_rows($rs)) {
182
                    $msg = get_lang('SessionNameAlreadyExists');
183
                    return $msg;
184
                }
185
                $ready_to_create = true;
186
            }
187
188
            if ($ready_to_create) {
189
                $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
190
                $values = array(
191
                    'name' => $name,
192
                    'id_coach' => $coachId,
193
                    'session_admin_id' => $sessionAdminId,
194
                    'visibility' => $visibility,
195
                    'description' => $description,
196
                    'show_description' => intval($showDescription),
197
                    'send_subscription_notification' => (int) $sendSubscriptionNotification
198
                );
199
200
                if (!empty($startDate)) {
201
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
202
                }
203
204
                if (!empty($endDate)) {
205
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
206
                }
207
208
                if (!empty($displayStartDate)) {
209
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
210
                }
211
212
                if (!empty($displayEndDate)) {
213
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
214
                }
215
216
                if (!empty($coachStartDate)) {
217
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
218
                }
219
                if (!empty($coachEndDate)) {
220
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
221
                }
222
223
                if (!empty($sessionCategoryId)) {
224
                    $values['session_category_id'] = $sessionCategoryId;
225
                }
226
227
                $session_id = Database::insert($tbl_session, $values);
228
229
                $duration = intval($duration);
230
231 View Code Duplication
                if (!empty($duration)) {
232
                    $sql = "UPDATE $tbl_session SET
233
                        access_start_date = NULL,
234
                        access_end_date = NULL,
235
                        display_start_date = NULL,
236
                        display_end_date = NULL,
237
                        coach_access_start_date = NULL,
238
                        coach_access_end_date = NULL,
239
                        duration = $duration
240
                    WHERE id = $session_id";
241
                    Database::query($sql);
242
                } else {
243
                    $sql = "UPDATE $tbl_session
244
                        SET duration = 0
245
                        WHERE id = $session_id";
246
                    Database::query($sql);
247
                }
248
249
                if (!empty($session_id)) {
250
                    $extraFields['item_id'] = $session_id;
251
252
                    $sessionFieldValue = new ExtraFieldValue('session');
253
                    $sessionFieldValue->saveFieldValues($extraFields);
254
255
                    /*
256
                      Sends a message to the user_id = 1
257
258
                      $user_info = api_get_user_info(1);
259
                      $complete_name = $user_info['firstname'].' '.$user_info['lastname'];
260
                      $subject = api_get_setting('siteName').' - '.get_lang('ANewSessionWasCreated');
261
                      $message = get_lang('ANewSessionWasCreated')." <br /> ".get_lang('NameOfTheSession').' : '.$name;
262
                      api_mail_html($complete_name, $user_info['email'], $subject, $message);
263
                     *
264
                     */
265
                    //Adding to the correct URL
266
                    $access_url_id = api_get_current_access_url_id();
267
                    UrlManager::add_session_to_url($session_id, $access_url_id);
268
269
                    // add event to system log
270
                    $user_id = api_get_user_id();
271
                    Event::addEvent(
272
                        LOG_SESSION_CREATE,
273
                        LOG_SESSION_ID,
274
                        $session_id,
275
                        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...
276
                        $user_id
277
                    );
278
                }
279
280
                return $session_id;
281
            }
282
        }
283
    }
284
285
    /**
286
     * @param string $name
287
     *
288
     * @return bool
289
     */
290 View Code Duplication
    public static function session_name_exists($name)
291
    {
292
        $name = Database::escape_string($name);
293
        $sql = "SELECT COUNT(*) as count FROM " . Database::get_main_table(TABLE_MAIN_SESSION) . "
294
                WHERE name = '$name'";
295
        $result = Database::fetch_array(Database::query($sql));
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
296
297
        return $result['count'] > 0;
298
    }
299
300
    /**
301
     * @param string $where_condition
302
     *
303
     * @return mixed
304
     */
305
    public static function get_count_admin($where_condition = '')
306
    {
307
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
308
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
309
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
310
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
311
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
312
313
        $where = 'WHERE 1=1 ';
314
        $user_id = api_get_user_id();
315
316
        $extraJoin = '';
317
318
        if (api_is_session_admin() &&
319
            api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
320
        ) {
321
            $where .= " AND (
322
                            s.session_admin_id = $user_id  OR
323
                            sru.user_id = '$user_id' AND
324
                            sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
325
                            )
326
                      ";
327
328
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
329
                           ON sru.session_id = s.id ";
330
        }
331
332
        $today = api_get_utc_datetime();
333
        $today = api_strtotime($today, 'UTC');
0 ignored issues
show
Bug introduced by
It seems like $today defined by api_strtotime($today, 'UTC') on line 333 can also be of type null or object<DateTime>; however, api_strtotime() does only seem to accept string, 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...
334
        $today = date('Y-m-d', $today);
335
336
        if (!empty($where_condition)) {
337
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
338
339
            $where_condition = str_replace('category_name', 'sc.name', $where_condition);
340
            $where_condition = str_replace(
341
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
342
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
343
                , $where_condition
344
            );
345
            $where_condition = str_replace(
346
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
347
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
348
                $where_condition
349
            );
350
        } else {
351
            $where_condition = " AND 1 = 1";
352
        }
353
354
        $courseCondition = null;
355
        if (strpos($where_condition, 'c.id')) {
356
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
357
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
358
            $courseCondition = " INNER JOIN $table course_rel_session
359
                                 ON (s.id = course_rel_session.session_id)
360
                                 INNER JOIN $tableCourse c
361
                                 ON (course_rel_session.c_id = c.id)
362
                                ";
363
        }
364
365
        $sql = "SELECT COUNT(id) as total_rows FROM (
366
                SELECT DISTINCT
367
                 IF (
368
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
369
                    (s.access_start_date IS NULL AND s.access_end_date  = IS NULL ) OR
370
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
371
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
372
				, 1, 0) as session_active,
373
                s.id
374
                FROM $tbl_session s
375
                LEFT JOIN $tbl_session_category sc
376
                ON s.session_category_id = sc.id
377
                INNER JOIN $tbl_user u
378
                ON s.id_coach = u.user_id
379
                $courseCondition
380
                $extraJoin
381
                $where $where_condition ) as session_table";
382
383
        if (api_is_multiple_url_enabled()) {
384
385
            $access_url_id = api_get_current_access_url_id();
386
            if ($access_url_id != -1) {
387
                $where.= " AND ar.access_url_id = $access_url_id ";
388
389
                $sql = "SELECT count(id) as total_rows FROM (
390
                SELECT DISTINCT
391
                  IF (
392
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
393
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
394
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
395
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
396
				, 1, 0)
397
				as session_active,
398
				s.id
399
                FROM $tbl_session s
400
                    LEFT JOIN  $tbl_session_category sc
401
                    ON s.session_category_id = sc.id
402
                    INNER JOIN $tbl_user u ON s.id_coach = u.user_id
403
                    INNER JOIN $table_access_url_rel_session ar
404
                    ON ar.session_id = s.id
405
                    $courseCondition
406
                    $extraJoin
407
                $where $where_condition) as session_table";
408
            }
409
        }
410
411
        $result_rows = Database::query($sql);
412
        $row = Database::fetch_array($result_rows);
413
        $num = $row['total_rows'];
414
415
        return $num;
416
    }
417
418
    /**
419
     * Gets the admin session list callback of the session/session_list.php page
420
     * @param array $options order and limit keys
421
     * @param boolean $get_count Whether to get all the results or only the count
422
     * @return mixed Integer for number of rows, or array of results
423
     * @assert (array(),true) !== false
424
     */
425
    public static function get_sessions_admin($options = array(), $get_count = false)
426
    {
427
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
428
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
429
430
        $where = 'WHERE 1 = 1 ';
431
        $user_id = api_get_user_id();
432
433 View Code Duplication
        if (!api_is_platform_admin()) {
434
            if (api_is_session_admin() &&
435
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
436
            ) {
437
                $where .=" AND s.session_admin_id = $user_id ";
438
            }
439
        }
440
441
        if (!api_is_platform_admin() && api_is_teacher() &&
442
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
443
        ) {
444
            $where .=" AND s.id_coach = $user_id ";
445
        }
446
447
        $extra_field = new ExtraFieldModel('session');
448
        $conditions = $extra_field->parseConditions($options);
449
        $inject_joins = $conditions['inject_joins'];
450
        $where .= $conditions['where'];
451
        $inject_where = $conditions['inject_where'];
452
        $inject_extra_fields = $conditions['inject_extra_fields'];
453
454
        $order = $conditions['order'];
455
        $limit = $conditions['limit'];
456
457
        $isMakingOrder = false;
458
459
        if ($get_count == true) {
460
            $select = " SELECT count(DISTINCT s.id) as total_rows";
461
        } else {
462
            $select =
463
                "SELECT DISTINCT 
464
                 s.name,
465
                 s.display_start_date, 
466
                 s.display_end_date, 
467
                 access_start_date, 
468
                 access_end_date, 
469
                 s.visibility, 
470
                 s.session_category_id, 
471
                 $inject_extra_fields 
472
                 s.id 
473
             ";
474
475
            $isMakingOrder = strpos($options['order'], 'category_name') === 0;
476
        }
477
478
        $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
479
480
        if ($isMakingOrder || $isFilteringSessionCategory) {
481
            $inject_joins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
482
483
            if ($isFilteringSessionCategory) {
484
                $where = str_replace('category_name', 'sc.name', $where);
485
            }
486
487
            if ($isMakingOrder) {
488
                $order = str_replace('category_name', 'sc.name', $order);
489
            }
490
        }
491
492
        $query = "$select FROM $tbl_session s $inject_joins $where $inject_where";
493
494
        if (api_is_multiple_url_enabled()) {
495
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
496
            $access_url_id = api_get_current_access_url_id();
497
            if ($access_url_id != -1) {
498
                $where.= " AND ar.access_url_id = $access_url_id ";
499
                $query = "$select
500
                        FROM $tbl_session s $inject_joins
501
                        INNER JOIN $table_access_url_rel_session ar
502
                        ON (ar.session_id = s.id) $where";
503
            }
504
        }
505
506
        $query .= $order;
507
        $query .= $limit;
508
        $result = Database::query($query);
509
510
        $categories = self::get_all_session_category();
511
        $orderedCategories = array();
512
        if (!empty($categories)) {
513
            foreach ($categories as $category) {
514
                $orderedCategories[$category['id']] = $category['name'];
515
            }
516
        }
517
518
        $formatted_sessions = array();
519
520
        if (Database::num_rows($result)) {
521
            $sessions = Database::store_result($result, 'ASSOC');
522
            if ($get_count) {
523
                return $sessions[0]['total_rows'];
524
            }
525
526
            foreach ($sessions as $session) {
527
                $session_id = $session['id'];
528
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
529
530 View Code Duplication
                if (isset($session['session_active']) && $session['session_active'] == 1) {
531
                    $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
532
                } else {
533
                    $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
534
                }
535
536
                $session = self::convert_dates_to_local($session, true);
537
538 View Code Duplication
                switch ($session['visibility']) {
539
                    case SESSION_VISIBLE_READ_ONLY: //1
540
                        $session['visibility'] = get_lang('ReadOnly');
541
                        break;
542
                    case SESSION_VISIBLE:           //2
543
                    case SESSION_AVAILABLE:         //4
544
                        $session['visibility'] = get_lang('Visible');
545
                        break;
546
                    case SESSION_INVISIBLE:         //3
547
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
548
                        break;
549
                }
550
551
                // Cleaning double selects.
552 View Code Duplication
                foreach ($session as $key => &$value) {
0 ignored issues
show
Bug introduced by
The expression $session of type false|array<string,null|...d_date":"string|null"}> 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...
553
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
554
                        $options = explode('::', $value);
555
                    }
556
                    $original_key = $key;
557
558
                    if (strpos($key, '_second') === false) {
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...
559
                    } else {
560
                        $key = str_replace('_second', '', $key);
561
                    }
562
563
                    if (isset($options_by_double[$key])) {
564
                        if (isset($options[0])) {
565
                            if (isset($options_by_double[$key][$options[0]])) {
566
                                if (strpos($original_key, '_second') === false) {
567
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
568
                                } else {
569
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
570
                                }
571
                            }
572
                        }
573
                    }
574
                }
575
                $formatted_sessions[$session_id] = $session;
576
                $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
577
                $formatted_sessions[$session_id]['category_name'] = $categoryName;
578
            }
579
        }
580
        return $formatted_sessions;
581
    }
582
583
    /**
584
     *  Get total of records for progress of learning paths in the given session
585
     *  @param int session id
586
     *  @return int
587
     */
588
    public static function get_count_session_lp_progress($sessionId = 0)
589
    {
590
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
591
        $tbl_lp_view = Database::get_course_table(TABLE_LP_VIEW);
592
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
593
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
594
595
        $sessionId = intval($sessionId);
596
597
        $sql = "SELECT  count(*) as total_rows
598
                FROM $tbl_lp_view v
599
                INNER JOIN $tbl_lp l ON l.id = v.lp_id
600
                INNER JOIN $tbl_user u ON u.user_id = v.user_id
601
                INNER JOIN $tbl_course c
602
                WHERE v.session_id = " . $sessionId;
603
        $result_rows = Database::query($sql);
604
        $row = Database::fetch_array($result_rows);
605
        $num = $row['total_rows'];
606
607
        return $num;
608
    }
609
610
    /**
611
     * Gets the progress of learning paths in the given session
612
     * @param int   $sessionId
613
     * @param int $courseId
614
     * @param string $date_from
615
     * @param string $date_to
616
     * @param array options order and limit keys
617
     * @return array table with user name, lp name, progress
618
     */
619
    public static function get_session_lp_progress($sessionId = 0, $courseId = 0, $date_from, $date_to, $options)
620
    {
621
        //escaping vars
622
        $sessionId = $sessionId == 'T' ? 'T' : intval($sessionId);
623
        $courseId = intval($courseId);
624
        $date_from = Database :: escape_string($date_from);
625
        $date_to = Database :: escape_string($date_to);
626
627
        //tables
628
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
629
        $user = Database::get_main_table(TABLE_MAIN_USER);
630
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
631
632
        $course = api_get_course_info_by_id($courseId);
633
634
        //getting all the students of the course
635
        //we are not using this because it only returns user ids
636
        /* if (empty($sessionId)
637
          {
638
          // Registered students in a course outside session.
639
          $users = CourseManager :: get_student_list_from_course_code($course_code);
640
          } else {
641
          // Registered students in session.
642
          $users = CourseManager :: get_student_list_from_course_code($course_code, true, $sessionId);
643
          } */
644
645
        $sessionCond = 'and session_id = %s';
646
        if ($sessionId == 'T') {
647
            $sessionCond = "";
648
        }
649
650
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
651
652
        $limit = null;
653
        if (!empty($options['limit'])) {
654
            $limit = " LIMIT " . $options['limit'];
655
        }
656
657
        if (!empty($options['where'])) {
658
            $where .= ' '.$options['where'];
659
        }
660
661
        $order = null;
662
        if (!empty($options['order'])) {
663
            $order = " ORDER BY " . $options['order'];
664
        }
665
666
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
667
                FROM $session_course_user s
668
                INNER JOIN $user u ON u.user_id = s.user_id
669
                $where
670
                $order
671
                $limit";
672
673
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
674
675
        $rs = Database::query($sql_query);
676
        while ($user = Database::fetch_array($rs)) {
677
            $users[$user['user_id']] = $user;
678
        }
679
680
        //Get lessons
681
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
682
683
        $table = array();
684
        foreach ($users as $user) {
685
            $data = array(
686
                'lastname' => $user[1],
687
                'firstname' => $user[2],
688
                'username' => $user[3],
689
            );
690
691
            $sessionCond = 'AND v.session_id = %d';
692
            if ($sessionId == 'T') {
693
                $sessionCond = "";
694
            }
695
696
            //Get lessons progress by user
697
            $sql = "SELECT v.lp_id as id, v.progress
698
                    FROM  $tbl_course_lp_view v
699
                    WHERE v.c_id = %d
700
                    AND v.user_id = %d
701
            $sessionCond";
702
703
            $sql_query = sprintf($sql,
704
                intval($courseId),
705
                intval($user['user_id']),
706
                $sessionId
707
            );
708
709
            $result = Database::query($sql_query);
710
711
            $user_lessons = array();
712
            while ($row = Database::fetch_array($result)) {
713
                $user_lessons[$row['id']] = $row;
714
            }
715
716
            //Match course lessons with user progress
717
            $progress = 0;
718
            $count = 0;
719
            foreach ($lessons as $lesson) {
720
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
721
                $progress += $data[$lesson['id']];
722
                $data[$lesson['id']] = $data[$lesson['id']] . '%';
723
                $count++;
724
            }
725
            if ($count == 0) {
726
                $data['total'] = 0;
727
            } else {
728
                $data['total'] = round($progress / $count, 2) . '%';
729
            }
730
            $table[] = $data;
731
        }
732
733
        return $table;
734
    }
735
736
    /**
737
     * Gets the survey answers
738
     * @param int   $sessionId
739
     * @param int   $courseId
740
     * @param int   $surveyId
741
     * @param array options order and limit keys
742
     * @todo fix the query
743
     * @return array table with user name, lp name, progress
744
     */
745
    public static function get_survey_overview($sessionId = 0, $courseId = 0, $surveyId = 0, $date_from, $date_to, $options)
746
    {
747
        //escaping vars
748
        $sessionId = intval($sessionId);
749
        $courseId = intval($courseId);
750
        $surveyId = intval($surveyId);
751
        $date_from = Database::escape_string($date_from);
752
        $date_to = Database::escape_string($date_to);
753
754
        //tables
755
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
756
        $user = Database::get_main_table(TABLE_MAIN_USER);
757
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
758
        $c_survey = Database::get_course_table(TABLE_SURVEY);
759
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
760
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
761
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
762
763
        $course = api_get_course_info_by_id($courseId);
764
765
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
766
767
        $limit = null;
768
        if (!empty($options['limit'])) {
769
            $limit = " LIMIT " . $options['limit'];
770
        }
771
772
        if (!empty($options['where'])) {
773
            $where .= ' '.$options['where'];
774
        }
775
776
        $order = null;
777
        if (!empty($options['order'])) {
778
            $order = " ORDER BY " . $options['order'];
779
        }
780
781
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
782
                FROM $session_course_user s
783
                INNER JOIN $user u ON u.user_id = s.user_id
784
                $where $order $limit";
785
786
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
787
        $rs = Database::query($sql_query);
788
        while ($user = Database::fetch_array($rs)) {
789
            $users[$user['user_id']] = $user;
790
        }
791
792
        //Get survey questions
793
        $questions = SurveyManager::get_questions($surveyId, $courseId);
794
795
        //Survey is anonymous?
796
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
797
        $row = Database::fetch_array($result);
798
        $anonymous = ($row['anonymous'] == 1) ? true : false;
799
800
        $table = array();
801
        foreach ($users as $user) {
802
            $data = array(
803
                'lastname' => ($anonymous ? '***' : $user[1]),
804
                'firstname' => ($anonymous ? '***' : $user[2]),
805
                'username' => ($anonymous ? '***' : $user[3]),
806
            );
807
808
            //Get questions by user
809
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
810
                    FROM $c_survey_answer sa
811
                    INNER JOIN $c_survey_question sq
812
                    ON sq.question_id = sa.question_id
813
                    LEFT JOIN $c_survey_question_option sqo
814
                    ON
815
                      sqo.c_id = sa.c_id AND
816
                      sqo.question_id = sq.question_id AND
817
                      sqo.question_option_id = sa.option_id AND
818
                      sqo.survey_id = sq.survey_id
819
                    WHERE
820
                      sa.survey_id = %d AND
821
                      sa.c_id = %d AND
822
                      sa.user = %d
823
            "; //. $where_survey;
824
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
825
826
            $result = Database::query($sql_query);
827
828
            $user_questions = array();
829
            while ($row = Database::fetch_array($result)) {
830
                $user_questions[$row['question_id']] = $row;
831
            }
832
833
            //Match course lessons with user progress
834
            foreach ($questions as $question_id => $question) {
835
                $option_text = 'option_text';
836
                if ($user_questions[$question_id]['type'] == 'open') {
837
                    $option_text = 'option_id';
838
                }
839
                $data[$question_id] = $user_questions[$question_id][$option_text];
840
            }
841
842
            $table[] = $data;
843
        }
844
        return $table;
845
    }
846
847
    /**
848
     * Gets the progress of the given session
849
     * @param int   $sessionId
850
     * @param int   $courseId
851
     * @param array options order and limit keys
852
     *
853
     * @return array table with user name, lp name, progress
854
     */
855
    public static function get_session_progress($sessionId, $courseId, $date_from, $date_to, $options)
856
    {
857
        $sessionId = intval($sessionId);
858
859
        $getAllSessions = false;
860
        if (empty($sessionId)) {
861
            $sessionId = 0;
862
            $getAllSessions = true;
863
        }
864
865
        //tables
866
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
867
        $user = Database::get_main_table(TABLE_MAIN_USER);
868
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
869
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
870
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
871
        $wiki = Database::get_course_table(TABLE_WIKI);
872
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
873
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
874
875
        $course = api_get_course_info_by_id($courseId);
876
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
877
878
        $limit = null;
879
        if (!empty($options['limit'])) {
880
            $limit = " LIMIT " . $options['limit'];
881
        }
882
883
        if (!empty($options['where'])) {
884
            $where .= ' '.$options['where'];
885
        }
886
887
        $order = null;
888
        if (!empty($options['order'])) {
889
            $order = " ORDER BY " . $options['order'];
890
        }
891
892
        //TODO, fix create report without session
893
        $queryVariables = array($course['real_id']);
894
        if (!empty($sessionId)) {
895
            $where .= ' AND session_id = %s';
896
            $queryVariables[] = $sessionId;
897
            $sql = "SELECT
898
                        u.user_id, u.lastname, u.firstname, u.username,
899
                        u.email, s.c_id, s.session_id
900
                    FROM $session_course_user s
901
                    INNER JOIN $user u
902
                    ON u.user_id = s.user_id
903
                    $where $order $limit";
904
        } else {
905
            $sql = "SELECT
906
                        u.user_id, u.lastname, u.firstname, u.username,
907
                        u.email, s.c_id, s.session_id
908
                    FROM $session_course_user s
909
                    INNER JOIN $user u ON u.user_id = s.user_id
910
                    $where $order $limit";
911
        }
912
913
        $sql_query = vsprintf($sql, $queryVariables);
914
        $rs = Database::query($sql_query);
915
        while ($user = Database::fetch_array($rs)) {
916
            $users[$user['user_id']] = $user;
917
        }
918
919
        /**
920
         *  Lessons
921
         */
922
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s ";  //AND session_id = %s
923
        $sql_query = sprintf($sql, $course['real_id']);
924
        $result = Database::query($sql_query);
925
        $arrLesson = array(array());
926 View Code Duplication
        while ($row = Database::fetch_array($result)) {
927
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
928
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
929
            } else {
930
                $arrLesson[$row['session_id']]['lessons_total'] ++;
931
            }
932
        }
933
934
        /**
935
         *  Exercises
936
         */
937
        $exercises = ExerciseLib::get_all_exercises($course, $sessionId, false, '', $getAllSessions);
938
        $exercises_total = count($exercises);
939
940
        /**
941
         *  Assignments
942
         */
943
        //total
944
        $params = [$course['real_id']];
945
        if ($getAllSessions) {
946
            $sql = "SELECT count(w.id) as count
947
                    FROM $workTable w
948
                    LEFT JOIN $workTableAssignment a
949
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
950
                    WHERE 
951
                        w.c_id = %s AND 
952
                        parent_id = 0 AND 
953
                        active IN (1, 0)";
954
        } else {
955
            $sql = "SELECT count(w.id) as count
956
                    FROM $workTable w
957
                    LEFT JOIN $workTableAssignment a
958
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
959
                    WHERE 
960
                        w.c_id = %s AND 
961
                        parent_id = 0 AND 
962
                        active IN (1, 0)";
963
964
            if (empty($sessionId)) {
965
                $sql .= ' AND w.session_id = NULL ';
966
            } else {
967
                $sql .= ' AND w.session_id = %s ';
968
                $params[] = $sessionId;
969
            }
970
        }
971
972
        $sql_query = vsprintf($sql, $params);
973
        $result = Database::query($sql_query);
974
        $row = Database::fetch_array($result);
975
        $assignments_total = $row['count'];
976
977
        /**
978
         * Wiki
979
         */
980
        if ($getAllSessions) {
981
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
982
                    WHERE c_id = %s";
983
        } else {
984
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
985
                    WHERE c_id = %s and session_id = %s";
986
        }
987
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
988
        $result = Database::query($sql_query);
989
        $row = Database::fetch_array($result);
990
        $wiki_total = $row['count'];
991
992
        /**
993
         * Surveys
994
         */
995
        $survey_user_list = array();
996
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
997
998
        $surveys_total = count($survey_list);
999 View Code Duplication
        foreach ($survey_list as $survey) {
0 ignored issues
show
Bug introduced by
The expression $survey_list 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...
1000
            $user_list = SurveyManager::get_people_who_filled_survey(
1001
                $survey['survey_id'],
1002
                false,
1003
                $course['real_id']
1004
            );
1005
            foreach ($user_list as $user_id) {
1006
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id] ++ : $survey_user_list[$user_id] = 1;
1007
            }
1008
        }
1009
1010
        /**
1011
         * Forums
1012
         */
1013
        $forums_total = CourseManager::getCountForum(
1014
            $course['real_id'],
1015
            $sessionId,
1016
            $getAllSessions
1017
        );
1018
1019
        //process table info
1020
        foreach ($users as $user) {
1021
            //Course description
1022
            $sql = "SELECT count(*) as count
1023
                    FROM $table_stats_access
1024
                    WHERE access_tool = 'course_description'
1025
                    AND c_id = '%s'
1026
                    AND access_session_id = %s
1027
                    AND access_user_id = %s ";
1028
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1029
1030
            $result = Database::query($sql_query);
1031
            $row = Database::fetch_array($result);
1032
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1033
1034
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1035
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1036
            } else {
1037
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1038
            }
1039
1040
            //Lessons
1041
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1042
            $lessons_progress = Tracking::get_avg_student_progress(
1043
                $user['user_id'],
1044
                $course['code'],
1045
                array(),
1046
                $user['id_session']
1047
            );
1048
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1049
            $lessons_left = $lessons_total - $lessons_done;
1050
1051
            //Exercises
1052
            $exercises_progress = str_replace('%', '', Tracking::get_exercise_student_progress($exercises, $user['user_id'], $course['real_id'], $user['id_session']));
1053
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1054
            $exercises_left = $exercises_total - $exercises_done;
1055
1056
            //Assignments
1057
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1058
            $assignments_left = $assignments_total - $assignments_done;
1059
            if (!empty($assignments_total)) {
1060
                $assignments_progress = round((( $assignments_done * 100 ) / $assignments_total), 2);
1061
            } else {
1062
                $assignments_progress = 0;
1063
            }
1064
1065
            //Wiki
1066
            //total revisions per user
1067
            $sql = "SELECT count(*) as count
1068
                    FROM $wiki
1069
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1070
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1071
            $result = Database::query($sql_query);
1072
            $row = Database::fetch_array($result);
1073
            $wiki_revisions = $row['count'];
1074
            //count visited wiki pages
1075
            $sql = "SELECT count(distinct default_value) as count
1076
                    FROM $table_stats_default
1077
                    WHERE
1078
                        default_user_id = %s AND
1079
                        default_event_type = 'wiki_page_view' AND
1080
                        default_value_type = 'wiki_page_id' AND
1081
                        c_id = %s
1082
                    ";
1083
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1084
            $result = Database::query($sql_query);
1085
            $row = Database::fetch_array($result);
1086
1087
            $wiki_read = $row['count'];
1088
            $wiki_unread = $wiki_total - $wiki_read;
1089
            if (!empty($wiki_total)) {
1090
                $wiki_progress = round((( $wiki_read * 100 ) / $wiki_total), 2);
1091
            } else {
1092
                $wiki_progress = 0;
1093
            }
1094
1095
            //Surveys
1096
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1097
            $surveys_left = $surveys_total - $surveys_done;
1098
            if (!empty($surveys_total)) {
1099
                $surveys_progress = round((( $surveys_done * 100 ) / $surveys_total), 2);
1100
            } else {
1101
                $surveys_progress = 0;
1102
            }
1103
1104
            //Forums
1105
            $forums_done = CourseManager::getCountForumPerUser(
1106
                $user['user_id'],
1107
                $course['real_id'],
1108
                $user['id_session']
1109
            );
1110
            $forums_left = $forums_total - $forums_done;
1111
            if (!empty($forums_total)) {
1112
                $forums_progress = round((( $forums_done * 100 ) / $forums_total), 2);
1113
            } else {
1114
                $forums_progress = 0;
1115
            }
1116
1117
            //Overall Total
1118
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1119
1120
            $link = '<a href="' . api_get_path(WEB_CODE_PATH) . 'mySpace/myStudents.php?student=' . $user[0] . '&details=true&course=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1121
            $linkForum = '<a href="' . api_get_path(WEB_CODE_PATH) . 'forum/index.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1122
            $linkWork = '<a href="' . api_get_path(WEB_CODE_PATH) . 'work/work.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1123
            $linkWiki = '<a href="' . api_get_path(WEB_CODE_PATH) . 'wiki/index.php?cidReq=' . $course['code'] . '&session_id=' . $user['id_session'] . '&action=statistics"> %s </a>';
1124
            $linkSurvey = '<a href="' . api_get_path(WEB_CODE_PATH) . 'survey/survey_list.php?cidReq=' . $course['code'] . '&id_session=' . $user['id_session'] . '"> %s </a>';
1125
1126
            $table[] = array(
1127
                'lastname' => $user[1],
1128
                'firstname' => $user[2],
1129
                'username' => $user[3],
1130
                #'profile'   => '',
1131
                'total' => round($overall_total, 2) . '%',
1132
                'courses' => sprintf($link, $course_description_progress . '%'),
1133
                'lessons' => sprintf($link, $lessons_progress . '%'),
1134
                'exercises' => sprintf($link, $exercises_progress . '%'),
1135
                'forums' => sprintf($link, $forums_progress . '%'),
1136
                'homeworks' => sprintf($link, $assignments_progress . '%'),
1137
                'wikis' => sprintf($link, $wiki_progress . '%'),
1138
                'surveys' => sprintf($link, $surveys_progress . '%'),
1139
                //course description
1140
                'course_description_progress' => $course_description_progress . '%',
1141
                //lessons
1142
                'lessons_total' => sprintf($link, $lessons_total),
1143
                'lessons_done' => sprintf($link, $lessons_done),
1144
                'lessons_left' => sprintf($link, $lessons_left),
1145
                'lessons_progress' => sprintf($link, $lessons_progress . '%'),
1146
                //exercises
1147
                'exercises_total' => sprintf($link, $exercises_total),
1148
                'exercises_done' => sprintf($link, $exercises_done),
1149
                'exercises_left' => sprintf($link, $exercises_left),
1150
                'exercises_progress' => sprintf($link, $exercises_progress . '%'),
1151
                //forums
1152
                'forums_total' => sprintf($linkForum, $forums_total),
1153
                'forums_done' => sprintf($linkForum, $forums_done),
1154
                'forums_left' => sprintf($linkForum, $forums_left),
1155
                'forums_progress' => sprintf($linkForum, $forums_progress . '%'),
1156
                //assignments
1157
                'assignments_total' => sprintf($linkWork, $assignments_total),
1158
                'assignments_done' => sprintf($linkWork, $assignments_done),
1159
                'assignments_left' => sprintf($linkWork, $assignments_left),
1160
                'assignments_progress' => sprintf($linkWork, $assignments_progress . '%'),
1161
                //wiki
1162
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1163
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1164
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1165
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1166
                'wiki_progress' => sprintf($linkWiki, $wiki_progress . '%'),
1167
                //survey
1168
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1169
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1170
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1171
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress . '%'),
1172
            );
1173
        }
1174
1175
        return $table;
1176
    }
1177
1178
    /**
1179
     * @return int
1180
     */
1181 View Code Duplication
    public static function get_number_of_tracking_access_overview()
1182
    {
1183
        $table = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1184
        $sql = "SELECT COUNT(course_access_id) count FROM $table";
1185
        $result = Database::query($sql);
1186
        $row = Database::fetch_assoc($result);
1187
1188
        return $row['count'];
1189
    }
1190
1191
    /**
1192
     * Get the ip, total of clicks, login date and time logged in for all user, in one session
1193
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1194
     *
1195
     * @author César Perales <[email protected]>, Beeznest Team
1196
     * @version 1.9.6
1197
     */
1198
    public static function get_user_data_access_tracking_overview(
1199
        $sessionId,
1200
        $courseId,
1201
        $studentId = 0,
1202
        $profile = '',
1203
        $date_from = '',
1204
        $date_to = '',
1205
        $options
1206
    ) {
1207
        //escaping variables
1208
        $sessionId = intval($sessionId);
1209
        $courseId = intval($courseId);
1210
        $studentId = intval($studentId);
1211
        $profile = intval($profile);
1212
        $date_from = Database::escape_string($date_from);
1213
        $date_to = Database::escape_string($date_to);
1214
1215
        // database table definition
1216
        $user = Database :: get_main_table(TABLE_MAIN_USER);
1217
        $course = Database :: get_main_table(TABLE_MAIN_COURSE);
1218
        $track_e_login = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1219
        $track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1220
        $sessionTable = Database :: get_main_table(TABLE_MAIN_SESSION);
1221
1222
        global $export_csv;
1223
        if ($export_csv) {
1224
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1225
        } else {
1226
            $is_western_name_order = api_is_western_name_order();
1227
        }
1228
1229
        $where = null;
1230
        if (isset($sessionId) && !empty($sessionId)) {
1231
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1232
        }
1233
        if (isset($courseId) && !empty($courseId)) {
1234
            $where .= sprintf(" AND c.id = %d", $courseId);
1235
        }
1236
        if (isset($studentId) && !empty($studentId)) {
1237
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1238
        }
1239
        if (isset($profile) && !empty($profile)) {
1240
            $where .= sprintf(" AND u.status = %d", $profile);
1241
        }
1242
        if (!empty($date_to) && !empty($date_from)) {
1243
            $where .= sprintf(
1244
                " AND a.login_course_date >= '%s 00:00:00'
1245
                 AND a.login_course_date <= '%s 23:59:59'",
1246
                $date_from,
1247
                $date_to
1248
            );
1249
        }
1250
1251
        $limit = null;
1252
        if (!empty($options['limit'])) {
1253
            $limit = " LIMIT " . $options['limit'];
1254
        }
1255
1256
        if (!empty($options['where'])) {
1257
            $where .= ' '.$options['where'];
1258
        }
1259
1260
        $order = null;
1261
        if (!empty($options['order'])) {
1262
            $order = " ORDER BY " . $options['order'];
1263
        }
1264
1265
        //TODO add course name
1266
        $sql = "SELECT
1267
                a.login_course_date ,
1268
                u.username ,
1269
                " . ($is_western_name_order ? "
1270
                    u.firstname,
1271
                    u.lastname,
1272
                    " : "
1273
                    u.lastname,
1274
                    u.firstname,
1275
                ") . "
1276
                a.logout_course_date,
1277
                a.counter,
1278
                c.title,
1279
                c.code,
1280
                u.user_id,
1281
                a.session_id
1282
            FROM $track_e_course_access a
1283
            INNER JOIN $user u ON a.user_id = u.user_id
1284
            INNER JOIN $course c ON a.c_id = c.id
1285
            $where $order $limit";
1286
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1287
1288
        $data = array();
1289
        while ($user = Database::fetch_assoc($result)) {
1290
            $data[] = $user;
1291
        }
1292
1293
        //foreach
1294
        foreach ($data as $key => $info) {
1295
            $sql = "SELECT
1296
                    name
1297
                    FROM $sessionTable
1298
                    WHERE
1299
                    id = {$info['session_id']}";
1300
            $result = Database::query($sql);
1301
            $session = Database::fetch_assoc($result);
1302
1303
            // building array to display
1304
            $return[] = array(
1305
                'user_id' => $info['user_id'],
1306
                'logindate' => $info['login_course_date'],
1307
                'username' => $info['username'],
1308
                'firstname' => $info['firstname'],
1309
                'lastname' => $info['lastname'],
1310
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1311
                'ip' => '',
1312
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1313
                'session' => $session['name']
1314
            );
1315
        }
1316
1317
        foreach ($return as $key => $info) {
1318
            //Search for ip, we do less querys if we iterate the final array
1319
            $sql = sprintf("SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1", $info['user_id'], $info['logindate']); //TODO add select by user too
1320
            $result = Database::query($sql);
1321
            $ip = Database::fetch_assoc($result);
1322
            //if no ip founded, we search the closest higher ip
1323
            if (empty($ip['user_ip'])) {
1324
                $sql = sprintf("SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s'  ORDER BY login_date ASC LIMIT 1", $info['user_id'], $info['logindate']); //TODO add select by user too
1325
                $result = Database::query($sql);
1326
                $ip = Database::fetch_assoc($result);
1327
            }
1328
            #add ip to final array
1329
            $return[$key]['ip'] = $ip['user_ip'];
1330
        }
1331
1332
        return $return;
1333
    }
1334
1335
    /**
1336
     * Creates a new course code based in given code
1337
     *
1338
     * @param string	$session_name
1339
     * <code>
1340
     * $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1341
     * if the course code doest not exist in the DB the same course code will be returned
1342
     * </code>
1343
     * @return string	wanted unused code
1344
     */
1345 View Code Duplication
    public static function generateNextSessionName($session_name)
1346
    {
1347
        $session_name_ok = !self::session_name_exists($session_name);
1348
        if (!$session_name_ok) {
1349
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1350
            $session_name = Database::escape_string($session_name);
1351
            $sql = "SELECT count(*) as count FROM $table
1352
                    WHERE name LIKE '$session_name%'";
1353
            $result = Database::query($sql);
1354
            if (Database::num_rows($result) > 0) {
1355
                $row = Database::fetch_array($result);
1356
                $count = $row['count'] + 1;
1357
                $session_name = $session_name . '_' . $count;
1358
                $result = self::session_name_exists($session_name);
1359
                if (!$result) {
1360
                    return $session_name;
1361
                }
1362
            }
1363
            return false;
1364
        }
1365
1366
        return $session_name;
1367
    }
1368
1369
    /**
1370
     * Edit a session
1371
     * @author Carlos Vargas from existing code
1372
     * @param integer   $id Session primary key
1373
     * @param string    $name
1374
     * @param string    $startDate
1375
     * @param string    $endDate
1376
     * @param string    $displayStartDate
1377
     * @param string    $displayEndDate
1378
     * @param string    $coachStartDate
1379
     * @param string    $coachEndDate
1380
     * @param integer   $coachId
1381
     * @param integer   $sessionCategoryId
1382
     * @param int       $visibility
1383
     * @param string    $description
1384
     * @param int       $showDescription
1385
     * @param int       $duration
1386
     * @param array     $extraFields
1387
     * @param int       $sessionAdminId
1388
     * @param boolean $sendSubscriptionNotification Optional.
1389
     *          Whether send a mail notification to users being subscribed
1390
     * @return mixed
1391
     */
1392
    public static function edit_session(
1393
        $id,
1394
        $name,
1395
        $startDate,
1396
        $endDate,
1397
        $displayStartDate,
1398
        $displayEndDate,
1399
        $coachStartDate,
1400
        $coachEndDate,
1401
        $coachId,
1402
        $sessionCategoryId,
1403
        $visibility,
1404
        $description = null,
1405
        $showDescription = 0,
1406
        $duration = null,
1407
        $extraFields = array(),
1408
        $sessionAdminId = 0,
1409
        $sendSubscriptionNotification = false
1410
    ) {
1411
        $coachId = intval($coachId);
1412
        $sessionCategoryId = intval($sessionCategoryId);
1413
        $visibility = intval($visibility);
1414
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1415
1416
        if (empty($name)) {
1417
            Display::addFlash(
1418
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1419
            );
1420
1421
            return false;
1422
        } elseif (empty($coachId)) {
1423
            Display::addFlash(
1424
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1425
            );
1426
1427
            return false;
1428
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') && !api_is_valid_date($startDate, 'Y-m-d H:i:s')) {
1429
            Display::addFlash(
1430
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1431
            );
1432
1433
            return false;
1434
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') && !api_is_valid_date($endDate, 'Y-m-d H:i:s')) {
1435
            Display::addFlash(
1436
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1437
            );
1438
1439
            return false;
1440
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1441
            Display::addFlash(
1442
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1443
            );
1444
1445
            return false;
1446
        } else {
1447
            $sessionInfo = self::get_session_by_name($name);
1448
            $exists = false;
1449
1450
            if (!empty($sessionInfo)) {
1451
                if ($sessionInfo['id'] != $id) {
1452
                    $exists = true;
1453
                }
1454
            }
1455
1456
            if ($exists) {
1457
                Display::addFlash(
1458
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1459
                );
1460
1461
                return false;
1462
            } else {
1463
                $values = [
1464
                    'name' => $name,
1465
                    'duration' => $duration,
1466
                    'id_coach' => $coachId,
1467
                    'description'=> $description,
1468
                    'show_description' => intval($showDescription),
1469
                    'visibility' => $visibility,
1470
                    'send_subscription_notification' => $sendSubscriptionNotification,
1471
                    'access_start_date' => null,
1472
                    'access_end_date' => null,
1473
                    'display_start_date' => null,
1474
                    'display_end_date' => null,
1475
                    'coach_access_start_date' => null,
1476
                    'coach_access_end_date' => null
1477
                ];
1478
1479
                if (!empty($sessionAdminId)) {
1480
                    $values['session_admin_id'] = $sessionAdminId;
1481
                }
1482
1483
                if (!empty($startDate)) {
1484
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1485
                }
1486
1487
                if (!empty($endDate)) {
1488
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1489
                }
1490
1491
                if (!empty($displayStartDate)) {
1492
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1493
                }
1494
1495
                if (!empty($displayEndDate)) {
1496
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1497
                }
1498
1499
                if (!empty($coachStartDate)) {
1500
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1501
                }
1502
                if (!empty($coachEndDate)) {
1503
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1504
                }
1505
1506
                if (!empty($sessionCategoryId)) {
1507
                    $values['session_category_id'] = $sessionCategoryId;
1508
                } else {
1509
                    $values['session_category_id'] = null;
1510
                }
1511
1512
                Database::update(
1513
                    $tbl_session,
1514
                    $values,
1515
                    array('id = ?' => $id)
1516
                );
1517
1518
                if (!empty($extraFields)) {
1519
                    $extraFields['item_id'] = $id;
1520
                    $sessionFieldValue = new ExtraFieldValue('session');
1521
                    $sessionFieldValue->saveFieldValues($extraFields);
1522
                }
1523
1524
                return $id;
1525
            }
1526
        }
1527
    }
1528
1529
    /**
1530
     * Delete session
1531
     * @author Carlos Vargas  from existing code
1532
     * @param	array	$id_checked an array to delete sessions
1533
     * @param   boolean  $from_ws optional, true if the function is called
1534
     * by a webservice, false otherwise.
1535
     * @return	void	Nothing, or false on error
1536
     * */
1537
    public static function delete($id_checked, $from_ws = false)
1538
    {
1539
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1540
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1541
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1542
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1543
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1544
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1545
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1546
        $tbl_student_publication_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1547
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1548
        $em = Database::getManager();
1549
1550
        $userId = api_get_user_id();
1551
1552
        /** @var \Chamilo\CoreBundle\Entity\Repository\SequenceRepository $repo */
1553
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1554
        $sequenceResourse = $repo->findRequirementForResource(
1555
            $id_checked,
1556
            \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
1557
        );
1558
1559
        if ($sequenceResourse) {
1560
            Display::addFlash(Display::return_message(get_lang('ThereIsASequenceResourceLinkedToThisSessionYouNeedToDeleteItFirst'), 'error'));
1561
            return false;
1562
        }
1563
1564
        if (is_array($id_checked)) {
1565
            foreach ($id_checked as $sessionId) {
1566
                self::delete($sessionId);
1567
            }
1568
        } else {
1569
            $id_checked = intval($id_checked);
1570
        }
1571
1572
        if (SessionManager::allowed($id_checked) && !$from_ws) {
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1537 can also be of type array; however, SessionManager::allowed() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1573
            $qb = $em
1574
                ->createQuery('
1575
                    SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
1576
                    WHERE s.id = ?1
1577
                ')
1578
                ->setParameter(1, $id_checked);
1579
1580
            $res = $qb->getSingleScalarResult();
1581
1582
            if ($res != $userId && !api_is_platform_admin()) {
1583
                api_not_allowed(true);
1584
            }
1585
        }
1586
1587
        // Delete documents inside a session
1588
        $courses = SessionManager::getCoursesInSession($id_checked);
1589
        foreach ($courses as $courseId) {
1590
            $courseInfo = api_get_course_info_by_id($courseId);
1591
            DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1537 can also be of type array; however, DocumentManager::deleteDocumentsFromSession() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1592
1593
            $works = Database::select(
1594
                '*',
1595
                $tbl_student_publication,
1596
                [
1597
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]]
1598
                ]
1599
            );
1600
1601
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
1602
1603
            foreach ($works as $index => $work) {
1604
                if ($work['filetype'] = 'folder') {
1605
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
1606
                }
1607
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
1608
            }
1609
        }
1610
1611
        Database::query("DELETE FROM $tbl_student_publication WHERE session_id IN($id_checked)");
1612
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
1613
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
1614
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
1615
        Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
1616
        Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
1617
1618
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id IN ($id_checked)";
1619
        Database::query($sql);
1620
1621
        $sql = "DELETE FROM $tbl_session WHERE id IN ($id_checked)";
1622
        Database::query($sql);
1623
1624
        $extraFieldValue = new ExtraFieldValue('session');
1625
        $extraFieldValue->deleteValuesByItem($id_checked);
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1537 can also be of type array; however, ExtraFieldValue::deleteValuesByItem() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1626
1627
        $repo->deleteResource(
1628
            $id_checked,
0 ignored issues
show
Bug introduced by
It seems like $id_checked defined by parameter $id_checked on line 1537 can also be of type array; however, Chamilo\CoreBundle\Entit...itory::deleteResource() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1629
            \Chamilo\CoreBundle\Entity\SequenceResource::SESSION_TYPE
1630
        );
1631
1632
        // Add event to system log
1633
        Event::addEvent(
1634
            LOG_SESSION_DELETE,
1635
            LOG_SESSION_ID,
1636
            $id_checked,
1637
            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...
1638
            $userId
1639
        );
1640
1641
        return true;
1642
    }
1643
1644
    /**
1645
     * @param int $id promotion id
1646
     *
1647
     * @return bool
1648
     */
1649 View Code Duplication
    public static function clear_session_ref_promotion($id)
1650
    {
1651
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1652
        $id = intval($id);
1653
        $sql = "UPDATE $tbl_session 
1654
                SET promotion_id = 0
1655
                WHERE promotion_id = $id";
1656
        if (Database::query($sql)) {
1657
            return true;
1658
        } else {
1659
            return false;
1660
        }
1661
    }
1662
1663
    /**
1664
     * Subscribes students to the given session and optionally (default) unsubscribes previous users
1665
     *
1666
     * @author Carlos Vargas from existing code
1667
     * @author Julio Montoya. Cleaning code.
1668
     * @param int $id_session
1669
     * @param array $user_list
1670
     * @param int $session_visibility
1671
     * @param bool $empty_users
1672
     * @return bool
1673
     */
1674
    public static function subscribe_users_to_session(
1675
        $id_session,
1676
        $user_list,
1677
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
1678
        $empty_users = true
1679
    ) {
1680
        if ($id_session != strval(intval($id_session))) {
1681
            return false;
1682
        }
1683
1684
        foreach ($user_list as $intUser) {
1685
            if ($intUser != strval(intval($intUser))) {
1686
                return false;
1687
            }
1688
        }
1689
1690
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1691
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1692
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1693
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1694
1695
        $entityManager = Database::getManager();
1696
        $session = $entityManager->find('ChamiloCoreBundle:Session', $id_session);
1697
1698
        // from function parameter
1699
        if (empty($session_visibility)) {
1700
            $session_visibility = $session->getVisibility();
1701
            //default status loaded if empty
1702
            // by default readonly 1
1703
            if (empty($session_visibility)) {
1704
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1705
            }
1706
        } else {
1707
            if (!in_array($session_visibility, array(SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE))) {
1708
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1709
            }
1710
        }
1711
1712
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
1713
                WHERE session_id = $id_session AND status = 0";
1714
        $result = Database::query($sql);
1715
        $existingUsers = array();
1716
        while ($row = Database::fetch_array($result)) {
1717
            $existingUsers[] = $row['user_id'];
1718
        }
1719
1720
        $sql = "SELECT c_id FROM $tbl_session_rel_course
1721
                WHERE session_id = $id_session";
1722
        $result = Database::query($sql);
1723
        $course_list = array();
1724
        while ($row = Database::fetch_array($result)) {
1725
            $course_list[] = $row['c_id'];
1726
        }
1727
1728
        if ($session->getSendSubscriptionNotification() &&
1729
            is_array($user_list)
1730
        ) {
1731
            // Sending emails only
1732
            foreach ($user_list as $user_id) {
1733
                if (in_array($user_id, $existingUsers)) {
1734
                    continue;
1735
                }
1736
1737
                $tplSubject = new Template(null, false, false, false, false, false);
1738
                $layoutSubject = $tplSubject->get_template(
1739
                    'mail/subject_subscription_to_session_confirmation.tpl'
1740
                );
1741
                $subject = $tplSubject->fetch($layoutSubject);
1742
1743
                $user_info = api_get_user_info($user_id);
1744
1745
                $tplContent = new Template(null, false, false, false, false, false);
1746
                // Variables for default template
1747
                $tplContent->assign(
1748
                    'complete_name',
1749
                    stripslashes($user_info['complete_name'])
1750
                );
1751
                $tplContent->assign('session_name', $session->getName());
1752
                $tplContent->assign(
1753
                    'session_coach',
1754
                    $session->getGeneralCoach()->getCompleteName()
1755
                );
1756
                $layoutContent = $tplContent->get_template(
1757
                    'mail/content_subscription_to_session_confirmation.tpl'
1758
                );
1759
                $content = $tplContent->fetch($layoutContent);
1760
1761
                api_mail_html(
1762
                    $user_info['complete_name'],
1763
                    $user_info['mail'],
1764
                    $subject,
1765
                    $content,
1766
                    api_get_person_name(
1767
                        api_get_setting('administratorName'),
1768
                        api_get_setting('administratorSurname')
1769
                    ),
1770
                    api_get_setting('emailAdministrator')
1771
                );
1772
            }
1773
        }
1774
1775
        foreach ($course_list as $courseId) {
1776
            // for each course in the session
1777
            $nbr_users = 0;
1778
            $courseId = intval($courseId);
1779
1780
            $sql = "SELECT DISTINCT user_id
1781
                    FROM $tbl_session_rel_course_rel_user
1782
                    WHERE
1783
                        session_id = $id_session AND
1784
                        c_id = $courseId AND
1785
                        status = 0
1786
                    ";
1787
            $result = Database::query($sql);
1788
            $existingUsers = array();
1789
            while ($row = Database::fetch_array($result)) {
1790
                $existingUsers[] = $row['user_id'];
1791
            }
1792
1793
            // Delete existing users
1794 View Code Duplication
            if ($empty_users) {
1795
                foreach ($existingUsers as $existing_user) {
1796
                    if (!in_array($existing_user, $user_list)) {
1797
                        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
1798
                                WHERE
1799
                                    session_id = $id_session AND
1800
                                    c_id = $courseId AND
1801
                                    user_id = $existing_user AND
1802
                                    status = 0 ";
1803
                        $result = Database::query($sql);
1804
1805
                        Event::addEvent(
1806
                            LOG_SESSION_DELETE_USER_COURSE,
1807
                            LOG_USER_ID,
1808
                            $existing_user,
1809
                            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...
1810
                            api_get_user_id(),
1811
                            $courseId,
1812
                            $id_session
1813
                        );
1814
1815
                        if (Database::affected_rows($result)) {
1816
                            $nbr_users--;
1817
                        }
1818
                    }
1819
                }
1820
            }
1821
1822
            // Replace with this new function
1823
            // insert new users into session_rel_course_rel_user and ignore if they already exist
1824
1825
            foreach ($user_list as $enreg_user) {
1826 View Code Duplication
                if (!in_array($enreg_user, $existingUsers)) {
1827
                    $enreg_user = Database::escape_string($enreg_user);
1828
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility, status)
1829
                            VALUES($id_session, $courseId, $enreg_user, $session_visibility, 0)";
1830
                    $result = Database::query($sql);
1831
1832
                    Event::addEvent(
1833
                        LOG_SESSION_ADD_USER_COURSE,
1834
                        LOG_USER_ID,
1835
                        $enreg_user,
1836
                        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...
1837
                        api_get_user_id(),
1838
                        $courseId,
1839
                        $id_session
1840
                    );
1841
1842
                    if (Database::affected_rows($result)) {
1843
1844
                        $nbr_users++;
1845
                    }
1846
                }
1847
            }
1848
1849
            // Count users in this session-course relation
1850
            $sql = "SELECT COUNT(user_id) as nbUsers
1851
                    FROM $tbl_session_rel_course_rel_user
1852
                    WHERE session_id = $id_session AND c_id = $courseId AND status<>2";
1853
            $rs = Database::query($sql);
1854
            list($nbr_users) = Database::fetch_array($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1855
            // update the session-course relation to add the users total
1856
            $sql = "UPDATE $tbl_session_rel_course SET nbr_users = $nbr_users
1857
                    WHERE session_id = $id_session AND c_id = $courseId";
1858
            Database::query($sql);
1859
        }
1860
1861
        // Delete users from the session
1862
        if ($empty_users === true) {
1863
            $sql = "DELETE FROM $tbl_session_rel_user
1864
                    WHERE session_id = $id_session AND relation_type<>" . SESSION_RELATION_TYPE_RRHH . "";
1865
            Database::query($sql);
1866
        }
1867
1868
        // Insert missing users into session
1869
        $nbr_users = 0;
1870
1871
        foreach ($user_list as $enreg_user) {
1872
            $enreg_user = Database::escape_string($enreg_user);
1873
            $nbr_users++;
1874
            $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
1875
                    VALUES (0, $id_session, $enreg_user, '" . api_get_utc_datetime() . "')";
1876
            Database::query($sql);
1877
        }
1878
1879
        // update number of users in the session
1880
        $nbr_users = count($user_list);
1881
        if ($empty_users) {
1882
            // update number of users in the session
1883
            $sql = "UPDATE $tbl_session SET nbr_users= $nbr_users
1884
                    WHERE id = $id_session ";
1885
            Database::query($sql);
1886
        } else {
1887
            $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + $nbr_users
1888
                    WHERE id = $id_session";
1889
            Database::query($sql);
1890
        }
1891
    }
1892
1893
    /**
1894
     * Returns user list of the current users subscribed in the course-session
1895
     * @param int $sessionId
1896
     * @param array $courseInfo
1897
     * @param int $status
1898
     *
1899
     * @return array
1900
     */
1901
    public static function getUsersByCourseSession(
1902
        $sessionId,
1903
        $courseInfo,
1904
        $status = null
1905
    ) {
1906
        $sessionId = intval($sessionId);
1907
        $courseCode = $courseInfo['code'];
1908
        $courseId = $courseInfo['real_id'];
1909
1910
        if (empty($sessionId) || empty($courseCode)) {
1911
            return array();
1912
        }
1913
1914
        $statusCondition = null;
1915 View Code Duplication
        if (isset($status) && !is_null($status)) {
1916
            $status = intval($status);
1917
            $statusCondition = " AND status = $status";
1918
        }
1919
1920
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1921
1922
        $sql = "SELECT DISTINCT user_id
1923
                FROM $table
1924
                WHERE
1925
                    session_id = $sessionId AND
1926
                    c_id = $courseId
1927
                    $statusCondition
1928
                ";
1929
        $result = Database::query($sql);
1930
        $existingUsers = array();
1931
        while ($row = Database::fetch_array($result)) {
1932
            $existingUsers[] = $row['user_id'];
1933
        }
1934
1935
        return $existingUsers;
1936
    }
1937
1938
    /**
1939
     * Remove a list of users from a course-session
1940
     * @param array $userList
1941
     * @param int $sessionId
1942
     * @param array $courseInfo
1943
     * @param int $status
1944
     * @param bool $updateTotal
1945
     * @return bool
1946
     */
1947
    public static function removeUsersFromCourseSession(
1948
        $userList,
1949
        $sessionId,
1950
        $courseInfo,
1951
        $status = null,
1952
        $updateTotal = true
1953
    ) {
1954
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1955
        $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1956
        $sessionId = intval($sessionId);
1957
1958
        if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
1959
            return false;
1960
        }
1961
1962
        is_array($courseInfo) ? $courseId = $courseInfo['real_id'] : $courseId = $courseInfo;
1963
1964
        $statusCondition = null;
1965 View Code Duplication
        if (isset($status) && !is_null($status))  {
1966
            $status = intval($status);
1967
            $statusCondition  = " AND status = $status";
1968
        }
1969
1970
        foreach ($userList as $userId) {
1971
            $userId = intval($userId);
1972
            $sql = "DELETE FROM $table
1973
                    WHERE
1974
                        session_id = $sessionId AND
1975
                        c_id = $courseId AND
1976
                        user_id = $userId
1977
                        $statusCondition
1978
                    ";
1979
            Database::query($sql);
1980
        }
1981
1982
        if ($updateTotal) {
1983
            // Count users in this session-course relation
1984
            $sql = "SELECT COUNT(user_id) as nbUsers
1985
                    FROM $table
1986
                    WHERE
1987
                        session_id = $sessionId AND
1988
                        c_id = $courseId AND
1989
                        status <> 2";
1990
            $result = Database::query($sql);
1991
            list($userCount) = Database::fetch_array($result);
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1992
1993
            // update the session-course relation to add the users total
1994
            $sql = "UPDATE $tableSessionCourse
1995
                    SET nbr_users = $userCount
1996
                    WHERE
1997
                        session_id = $sessionId AND
1998
                        c_id = $courseId";
1999
            Database::query($sql);
2000
        }
2001
    }
2002
2003
    /**
2004
     * Subscribe a user to an specific course inside a session.
2005
     *
2006
     * @param array $user_list
2007
     * @param int $session_id
2008
     * @param string $course_code
2009
     * @param int $session_visibility
2010
     * @param bool $removeUsersNotInList
2011
     * @return bool
2012
     */
2013
    public static function subscribe_users_to_session_course(
2014
        $user_list,
2015
        $session_id,
2016
        $course_code,
2017
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2018
        $removeUsersNotInList = false
2019
    ) {
2020
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2021
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2022
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2023
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2024
2025
        if (empty($session_id) || empty($course_code)) {
2026
            return false;
2027
        }
2028
2029
        $session_id = intval($session_id);
2030
        $course_code = Database::escape_string($course_code);
2031
        $courseInfo = api_get_course_info($course_code);
2032
        $courseId = $courseInfo['real_id'];
2033
2034
        $session_visibility = intval($session_visibility);
2035
2036
        if ($removeUsersNotInList) {
2037
2038
            $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
2039
2040
            if (!empty($user_list)) {
2041
                $userToDelete = array_diff($currentUsers, $user_list);
2042
            } else {
2043
                $userToDelete = $currentUsers;
2044
            }
2045
2046
            if (!empty($userToDelete)) {
2047
                self::removeUsersFromCourseSession(
2048
                    $userToDelete,
2049
                    $session_id,
2050
                    $courseInfo,
2051
                    0,
2052
                    true
2053
                );
2054
            }
2055
        }
2056
2057
        $nbr_users = 0;
2058
        foreach ($user_list as $enreg_user) {
2059
            $enreg_user = intval($enreg_user);
2060
            // Checking if user exists in session - course - user table.
2061
            $sql = "SELECT count(user_id) as count
2062
                    FROM $tbl_session_rel_course_rel_user
2063
                    WHERE
2064
                        session_id = $session_id AND
2065
                        c_id = $courseId and
2066
                        user_id = $enreg_user ";
2067
            $result = Database::query($sql);
2068
            $count = 0;
2069
2070
            if (Database::num_rows($result) > 0) {
2071
                $row = Database::fetch_array($result, 'ASSOC');
2072
                $count = $row['count'];
2073
            }
2074
2075
            if ($count == 0) {
2076
                $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id, visibility)
2077
                        VALUES ($session_id, $courseId, $enreg_user, $session_visibility)";
2078
                $result = Database::query($sql);
2079
                if (Database::affected_rows($result)) {
2080
                    $nbr_users++;
2081
                }
2082
            }
2083
2084
            // Checking if user exists in session - user table.
2085
            $sql = "SELECT count(user_id) as count
2086
                    FROM $tbl_session_rel_user
2087
                    WHERE session_id = $session_id AND user_id = $enreg_user ";
2088
            $result = Database::query($sql);
2089
            $count = 0;
2090
2091
            if (Database::num_rows($result) > 0) {
2092
                $row = Database::fetch_array($result, 'ASSOC');
2093
                $count = $row['count'];
2094
            }
2095
2096 View Code Duplication
            if (empty($count)) {
2097
                // If user is not registered to a session then add it.
2098
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, registered_at)
2099
                        VALUES ($session_id, $enreg_user, '" . api_get_utc_datetime() . "')";
2100
                Database::query($sql);
2101
2102
                $sql = "UPDATE $tbl_session SET nbr_users = nbr_users + 1
2103
                        WHERE id = $session_id ";
2104
                Database::query($sql);
2105
            }
2106
        }
2107
2108
        // count users in this session-course relation
2109
        $sql = "SELECT COUNT(user_id) as nbUsers
2110
                FROM $tbl_session_rel_course_rel_user
2111
                WHERE session_id = $session_id AND c_id = $courseId AND status <> 2";
2112
        $rs = Database::query($sql);
2113
        list($nbr_users) = Database::fetch_array($rs);
0 ignored issues
show
Bug introduced by
It seems like $rs can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
2114
        // update the session-course relation to add the users total
2115
        $sql = "UPDATE $tbl_session_rel_course
2116
                SET nbr_users = $nbr_users
2117
                WHERE session_id = $session_id AND c_id = $courseId";
2118
        Database::query($sql);
2119
    }
2120
2121
    /**
2122
     * Unsubscribe user from session
2123
     *
2124
     * @param int Session id
2125
     * @param int User id
2126
     * @return bool True in case of success, false in case of error
2127
     */
2128
    public static function unsubscribe_user_from_session($session_id, $user_id)
2129
    {
2130
        $session_id = (int) $session_id;
2131
        $user_id = (int) $user_id;
2132
2133
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2134
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2135
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2136
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2137
2138
        $sql = "DELETE FROM $tbl_session_rel_user
2139
                WHERE
2140
                    session_id = $session_id AND
2141
                    user_id = $user_id AND
2142
                    relation_type <> " . SESSION_RELATION_TYPE_RRHH . "";
2143
        $result = Database::query($sql);
2144
        $return = Database::affected_rows($result);
2145
2146
        // Update number of users
2147
        $sql = "UPDATE $tbl_session
2148
                SET nbr_users = nbr_users - $return
2149
                WHERE id = $session_id ";
2150
        Database::query($sql);
2151
2152
        // Get the list of courses related to this session
2153
        $course_list = SessionManager::get_course_list_by_session_id($session_id);
2154
2155
        if (!empty($course_list)) {
2156
            foreach ($course_list as $course) {
0 ignored issues
show
Bug introduced by
The expression $course_list of type integer|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...
2157
                $courseId = $course['id'];
2158
                // Delete user from course
2159
                $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2160
                        WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2161
                $result = Database::query($sql);
2162
2163
                Event::addEvent(
2164
                    LOG_SESSION_DELETE_USER_COURSE,
2165
                    LOG_USER_ID,
2166
                    $user_id,
2167
                    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...
2168
                    api_get_user_id(),
2169
                    $courseId,
2170
                    $session_id
2171
                );
2172
2173
                if (Database::affected_rows($result)) {
2174
                    // Update number of users in this relation
2175
                    $sql = "UPDATE $tbl_session_rel_course SET 
2176
                            nbr_users = nbr_users - 1
2177
                            WHERE session_id = $session_id AND c_id = $courseId";
2178
                    Database::query($sql);
2179
                }
2180
            }
2181
        }
2182
2183
        return true;
2184
    }
2185
2186
    /**
2187
     * Subscribes courses to the given session and optionally (default)
2188
     * unsubscribes previous users
2189
     * @author Carlos Vargas from existing code
2190
     * @param	int		$sessionId
2191
     * @param	array	$courseList List of courses int ids
2192
     * @param	bool	$removeExistingCoursesWithUsers Whether to unsubscribe
2193
     * existing courses and users (true, default) or not (false)
2194
     * @param $copyEvaluation from base course to session course
2195
     * @return	void	Nothing, or false on error
2196
     * */
2197
    public static function add_courses_to_session(
2198
        $sessionId,
2199
        $courseList,
2200
        $removeExistingCoursesWithUsers = true,
2201
        $copyEvaluation = false
2202
    ) {
2203
        $sessionId = intval($sessionId);
2204
2205
        if (empty($sessionId) || empty($courseList)) {
2206
            return false;
2207
        }
2208
2209
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2210
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2211
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2212
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2213
2214
        // Get list of courses subscribed to this session
2215
        $sql = "SELECT c_id
2216
                FROM $tbl_session_rel_course
2217
                WHERE session_id = $sessionId";
2218
        $rs = Database::query($sql);
2219
        $existingCourses = Database::store_result($rs);
2220
        $nbr_courses = count($existingCourses);
2221
2222
        // Get list of users subscribed to this session
2223
        $sql = "SELECT user_id
2224
                FROM $tbl_session_rel_user
2225
                WHERE
2226
                    session_id = $sessionId AND
2227
                    relation_type<>" . SESSION_RELATION_TYPE_RRHH;
2228
        $result = Database::query($sql);
2229
        $user_list = Database::store_result($result);
2230
2231
        // Remove existing courses from the session.
2232
        if ($removeExistingCoursesWithUsers === true && !empty($existingCourses)) {
2233
            foreach ($existingCourses as $existingCourse) {
2234
                if (!in_array($existingCourse['c_id'], $courseList)) {
2235
2236
                    $sql = "DELETE FROM $tbl_session_rel_course
2237
                            WHERE
2238
                                c_id = " . $existingCourse['c_id'] . " AND
2239
                                session_id = $sessionId";
2240
                    Database::query($sql);
2241
2242
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2243
                            WHERE
2244
                                c_id = ".$existingCourse['c_id']." AND
2245
                                session_id = $sessionId";
2246
                    Database::query($sql);
2247
2248
                    Event::addEvent(
2249
                        LOG_SESSION_DELETE_COURSE,
2250
                        LOG_COURSE_ID,
2251
                        $existingCourse['c_id'],
2252
                        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...
2253
                        api_get_user_id(),
2254
                        $existingCourse['c_id'],
2255
                        $sessionId
2256
                    );
2257
2258
                    CourseManager::remove_course_ranking(
2259
                        $existingCourse['c_id'],
2260
                        $sessionId
2261
                    );
2262
2263
                    $nbr_courses--;
2264
                }
2265
            }
2266
        }
2267
2268
        // Pass through the courses list we want to add to the session
2269
        foreach ($courseList as $courseId) {
2270
            $courseInfo = api_get_course_info_by_id($courseId);
2271
2272
            // If course doesn't exists continue!
2273
            if (empty($courseInfo)) {
2274
                continue;
2275
            }
2276
2277
            $exists = false;
2278
            // check if the course we want to add is already subscribed
2279
            foreach ($existingCourses as $existingCourse) {
2280
                if ($courseId == $existingCourse['c_id']) {
2281
                    $exists = true;
2282
                }
2283
            }
2284
2285
            if (!$exists) {
2286
                // Copy gradebook categories and links (from base course)
2287
                // to the new course session
2288
                if ($copyEvaluation) {
2289
                    $cats = Category::load(null, null, $courseInfo['code']);
2290
                    if (!empty($cats)) {
2291
                        $categoryIdList = [];
2292
                        /** @var Category $cat */
2293
                        foreach ($cats as $cat) {
2294
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2295
                        }
2296
                        $newCategoryIdList = [];
2297
                        foreach ($cats as $cat) {
2298
                            $links = $cat->get_links(null, false, $courseInfo['code'], 0);
2299
2300
                            $cat->set_session_id($sessionId);
2301
                            $oldCategoryId= $cat->get_id();
2302
                            $newId = $cat->add();
2303
                            $newCategoryIdList[$oldCategoryId] = $newId;
2304
                            $parentId = $cat->get_parent_id();
2305
2306
                            if (!empty($parentId)) {
2307
                                $newParentId = $newCategoryIdList[$parentId];
2308
                                $cat->set_parent_id($newParentId);
2309
                                $cat->save();
2310
                            }
2311
2312
                            /** @var AbstractLink $link */
2313
                            foreach ($links as $link) {
2314
                                $newCategoryId = $newCategoryIdList[$link->get_category_id()];
2315
                                $link->set_category_id($newCategoryId);
2316
                                $link->add();
2317
                            }
2318
                        }
2319
2320
                        // Create
2321
                        DocumentManager::generateDefaultCertificate(
2322
                            $courseInfo,
2323
                            true,
2324
                            $sessionId
2325
                        );
2326
                    }
2327
                }
2328
2329
                // If the course isn't subscribed yet
2330
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2331
                        VALUES ($sessionId, $courseId, 0, 0)";
2332
                Database::query($sql);
2333
2334
                Event::addEvent(
2335
                    LOG_SESSION_ADD_COURSE,
2336
                    LOG_COURSE_ID,
2337
                    $courseId,
2338
                    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...
2339
                    api_get_user_id(),
2340
                    $courseId,
2341
                    $sessionId
2342
                );
2343
2344
                // We add the current course in the existing courses array,
2345
                // to avoid adding another time the current course
2346
                $existingCourses[] = array('c_id' => $courseId);
2347
                $nbr_courses++;
2348
2349
                // subscribe all the users from the session to this course inside the session
2350
                $nbr_users = 0;
2351 View Code Duplication
                foreach ($user_list as $enreg_user) {
2352
                    $enreg_user_id = intval($enreg_user['user_id']);
2353
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_course_rel_user (session_id, c_id, user_id)
2354
                            VALUES ($sessionId, $courseId, $enreg_user_id)";
2355
                    $result = Database::query($sql);
2356
2357
                    Event::addEvent(
2358
                        LOG_SESSION_ADD_USER_COURSE,
2359
                        LOG_USER_ID,
2360
                        $enreg_user_id,
2361
                        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...
2362
                        api_get_user_id(),
2363
                        $courseId,
2364
                        $sessionId
2365
                    );
2366
2367
                    if (Database::affected_rows($result)) {
2368
                        $nbr_users++;
2369
                    }
2370
                }
2371
                $sql = "UPDATE $tbl_session_rel_course
2372
                        SET nbr_users = $nbr_users
2373
                        WHERE session_id = $sessionId AND c_id = $courseId";
2374
                Database::query($sql);
2375
            }
2376
        }
2377
2378
        $sql = "UPDATE $tbl_session
2379
                SET nbr_courses = $nbr_courses
2380
                WHERE id = $sessionId";
2381
        Database::query($sql);
2382
    }
2383
2384
    /**
2385
     * Unsubscribe course from a session
2386
     *
2387
     * @param int $session_id
2388
     * @param int $course_id
2389
     * @return bool True in case of success, false otherwise
2390
     */
2391
    public static function unsubscribe_course_from_session($session_id, $course_id)
2392
    {
2393
        $session_id = (int) $session_id;
2394
        $course_id = (int) $course_id;
2395
2396
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2397
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2398
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2399
2400
        // Get course code
2401
        $course_code = CourseManager::get_course_code_from_course_id($course_id);
2402
        $course_id = intval($course_id);
2403
2404
        if (empty($course_code)) {
2405
            return false;
2406
        }
2407
2408
        // Unsubscribe course
2409
        $sql = "DELETE FROM $tbl_session_rel_course
2410
                WHERE c_id = $course_id AND session_id = $session_id";
2411
        $result = Database::query($sql);
2412
        $nb_affected = Database::affected_rows($result);
2413
2414
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2415
                WHERE c_id = $course_id AND session_id = $session_id";
2416
        Database::query($sql);
2417
2418
        Event::addEvent(
2419
            LOG_SESSION_DELETE_COURSE,
2420
            LOG_COURSE_ID,
2421
            $course_id,
2422
            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...
2423
            api_get_user_id(),
2424
            $course_id,
2425
            $session_id
2426
        );
2427
2428
        if ($nb_affected > 0) {
2429
            // Update number of courses in the session
2430
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
2431
                    WHERE id = $session_id";
2432
            Database::query($sql);
2433
            return true;
2434
        } else {
2435
            return false;
2436
        }
2437
    }
2438
2439
    /**
2440
     * Creates a new extra field for a given session
2441
     * @param	string	$variable Field's internal variable name
2442
     * @param	int		$fieldType Field's type
2443
     * @param	string	$displayText Field's language var name
2444
     * @return int     new extra field id
2445
     */
2446 View Code Duplication
    public static function create_session_extra_field($variable, $fieldType, $displayText)
2447
    {
2448
        $extraField = new ExtraFieldModel('session');
2449
        $params = [
2450
            'variable' => $variable,
2451
            'field_type' => $fieldType,
2452
            'display_text' => $displayText,
2453
        ];
2454
2455
        return $extraField->save($params);
2456
    }
2457
2458
    /**
2459
     * Update an extra field value for a given session
2460
     * @param	integer	Course ID
2461
     * @param	string	Field variable name
2462
     * @param	string	Field value
2463
     * @return	boolean	true if field updated, false otherwise
2464
     */
2465 View Code Duplication
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
2466
    {
2467
        $extraFieldValue = new ExtraFieldValue('session');
2468
        $params = [
2469
            'item_id' => $sessionId,
2470
            'variable' => $variable,
2471
            'value' => $value,
2472
        ];
2473
        return $extraFieldValue->save($params);
2474
    }
2475
2476
    /**
2477
     * Checks the relationship between a session and a course.
2478
     * @param int $session_id
2479
     * @param int $courseId
2480
     * @return bool Returns TRUE if the session and the course are related, FALSE otherwise.
2481
     * */
2482 View Code Duplication
    public static function relation_session_course_exist($session_id, $courseId)
2483
    {
2484
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2485
        $return_value = false;
2486
        $sql = "SELECT c_id FROM $tbl_session_course
2487
                WHERE
2488
                  session_id = " . intval($session_id) . " AND
2489
                  c_id = " . intval($courseId);
2490
        $result = Database::query($sql);
2491
        $num = Database::num_rows($result);
2492
        if ($num > 0) {
2493
            $return_value = true;
2494
        }
2495
        return $return_value;
2496
    }
2497
2498
    /**
2499
     * Get the session information by name
2500
     * @param string $session_name
2501
     * @return mixed false if the session does not exist, array if the session exist
2502
     * */
2503
    public static function get_session_by_name($session_name)
2504
    {
2505
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2506
        $session_name = trim($session_name);
2507
        if (empty($session_name)) {
2508
            return false;
2509
        }
2510
2511
        $sql = 'SELECT *
2512
		        FROM ' . $tbl_session . '
2513
		        WHERE name = "' . Database::escape_string($session_name) . '"';
2514
        $result = Database::query($sql);
2515
        $num = Database::num_rows($result);
2516
        if ($num > 0) {
2517
            return Database::fetch_array($result);
2518
        } else {
2519
            return false;
2520
        }
2521
    }
2522
2523
    /**
2524
     * Create a session category
2525
     * @author Jhon Hinojosa <[email protected]>, from existing code
2526
     * @param	string 		name
2527
     * @param 	integer		year_start
2528
     * @param 	integer		month_start
2529
     * @param 	integer		day_start
2530
     * @param 	integer		year_end
2531
     * @param 	integer		month_end
2532
     * @param 	integer		day_end
2533
     * @return $id_session;
0 ignored issues
show
Documentation introduced by
The doc-type $id_session; could not be parsed: Unknown type name "$id_session" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
2534
     * */
2535
    public static function create_category_session(
2536
        $sname,
2537
        $syear_start,
2538
        $smonth_start,
2539
        $sday_start,
2540
        $syear_end,
2541
        $smonth_end,
2542
        $sday_end
2543
    ) {
2544
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2545
        $name = trim($sname);
2546
        $year_start = intval($syear_start);
2547
        $month_start = intval($smonth_start);
2548
        $day_start = intval($sday_start);
2549
        $year_end = intval($syear_end);
2550
        $month_end = intval($smonth_end);
2551
        $day_end = intval($sday_end);
2552
2553
        $date_start = "$year_start-" . (($month_start < 10) ? "0$month_start" : $month_start) . "-" . (($day_start < 10) ? "0$day_start" : $day_start);
2554
        $date_end = "$year_end-" . (($month_end < 10) ? "0$month_end" : $month_end) . "-" . (($day_end < 10) ? "0$day_end" : $day_end);
2555
2556 View Code Duplication
        if (empty($name)) {
2557
            $msg = get_lang('SessionCategoryNameIsRequired');
2558
            return $msg;
2559
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2560
            $msg = get_lang('InvalidStartDate');
2561
            return $msg;
2562
        } elseif (!$month_end && !$day_end && !$year_end) {
2563
            $date_end = '';
2564
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2565
            $msg = get_lang('InvalidEndDate');
2566
            return $msg;
2567
        } elseif ($date_start >= $date_end) {
2568
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2569
            return $msg;
2570
        }
2571
2572
        $access_url_id = api_get_current_access_url_id();
2573
        $params = [
2574
            'name' => $name,
2575
            'date_start' => $date_start,
2576
            'access_url_id' => $access_url_id
2577
        ];
2578
2579
        if (!empty($date_end)) {
2580
            $params['date_end'] = $date_end;
2581
        }
2582
2583
        $id = Database::insert($tbl_session_category, $params);
2584
2585
        // Add event to system log
2586
        $user_id = api_get_user_id();
2587
        Event::addEvent(
2588
            LOG_SESSION_CATEGORY_CREATE,
2589
            LOG_SESSION_CATEGORY_ID,
2590
            $id,
0 ignored issues
show
Security Bug introduced by
It seems like $id defined by \Database::insert($tbl_session_category, $params) on line 2583 can also be of type false; however, Event::addEvent() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2591
            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...
2592
            $user_id
2593
        );
2594
2595
        return $id;
2596
    }
2597
2598
    /**
2599
     * Edit a sessions categories
2600
     * @author Jhon Hinojosa <[email protected]>,from existing code
2601
     * @param	integer		id
2602
     * @param	string 		name
2603
     * @param 	integer		year_start
2604
     * @param 	integer		month_start
2605
     * @param 	integer		day_start
2606
     * @param 	integer		year_end
2607
     * @param 	integer		month_end
2608
     * @param 	integer		day_end
2609
     * @return $id;
0 ignored issues
show
Documentation introduced by
The doc-type $id; could not be parsed: Unknown type name "$id" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
2610
     * The parameter id is a primary key
2611
     * */
2612
    public static function edit_category_session(
2613
        $id,
2614
        $sname,
2615
        $syear_start,
2616
        $smonth_start,
2617
        $sday_start,
2618
        $syear_end,
2619
        $smonth_end,
2620
        $sday_end
2621
    ) {
2622
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2623
        $name = trim($sname);
2624
        $year_start = intval($syear_start);
2625
        $month_start = intval($smonth_start);
2626
        $day_start = intval($sday_start);
2627
        $year_end = intval($syear_end);
2628
        $month_end = intval($smonth_end);
2629
        $day_end = intval($sday_end);
2630
        $id = intval($id);
2631
        $date_start = "$year_start-" . (($month_start < 10) ? "0$month_start" : $month_start) . "-" . (($day_start < 10) ? "0$day_start" : $day_start);
2632
        $date_end = "$year_end-" . (($month_end < 10) ? "0$month_end" : $month_end) . "-" . (($day_end < 10) ? "0$day_end" : $day_end);
2633
2634 View Code Duplication
        if (empty($name)) {
2635
            $msg = get_lang('SessionCategoryNameIsRequired');
2636
            return $msg;
2637
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2638
            $msg = get_lang('InvalidStartDate');
2639
            return $msg;
2640
        } elseif (!$month_end && !$day_end && !$year_end) {
2641
            $date_end = null;
2642
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2643
            $msg = get_lang('InvalidEndDate');
2644
            return $msg;
2645
        } elseif ($date_start >= $date_end) {
2646
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2647
            return $msg;
2648
        }
2649
        if ($date_end <> null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $date_end of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
2650
            $sql = "UPDATE $tbl_session_category
2651
                    SET
2652
                        name = '" . Database::escape_string($name) . "',
2653
                        date_start = '$date_start' ,
2654
                        date_end = '$date_end'
2655
                    WHERE id= $id";
2656
        } else {
2657
            $sql = "UPDATE $tbl_session_category SET
2658
                        name = '" . Database::escape_string($name) . "',
2659
                        date_start = '$date_start',
2660
                        date_end = NULL
2661
                    WHERE id= $id";
2662
        }
2663
        $result = Database::query($sql);
2664
        return ($result ? true : false);
2665
    }
2666
2667
    /**
2668
     * Delete sessions categories
2669
     * @author Jhon Hinojosa <[email protected]>, from existing code
2670
     * @param	array	id_checked
2671
     * @param	bool	include delete session
2672
     * @param	bool	optional, true if the function is called by a webservice, false otherwise.
2673
     * @return	void	Nothing, or false on error
2674
     * The parameters is a array to delete sessions
2675
     * */
2676
    public static function delete_session_category($id_checked, $delete_session = false, $from_ws = false)
2677
    {
2678
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2679
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2680
        if (is_array($id_checked)) {
2681
            $id_checked = Database::escape_string(implode(',', $id_checked));
2682
        } else {
2683
            $id_checked = intval($id_checked);
2684
        }
2685
2686
        //Setting session_category_id to 0
2687
        $sql = "UPDATE $tbl_session SET session_category_id = 0
2688
                WHERE session_category_id IN (" . $id_checked . ")";
2689
        Database::query($sql);
2690
2691
        $sql = "SELECT id FROM $tbl_session WHERE session_category_id IN (" . $id_checked . ")";
2692
        $result = Database::query($sql);
2693
        while ($rows = Database::fetch_array($result)) {
2694
            $session_id = $rows['id'];
2695
            if ($delete_session) {
2696
                if ($from_ws) {
2697
                    SessionManager::delete($session_id, true);
2698
                } else {
2699
                    SessionManager::delete($session_id);
2700
                }
2701
            }
2702
        }
2703
        $sql = "DELETE FROM $tbl_session_category WHERE id IN (" . $id_checked . ")";
2704
        Database::query($sql);
2705
2706
        // Add event to system log
2707
        $user_id = api_get_user_id();
2708
        Event::addEvent(
2709
            LOG_SESSION_CATEGORY_DELETE,
2710
            LOG_SESSION_CATEGORY_ID,
2711
            $id_checked,
2712
            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...
2713
            $user_id
2714
        );
2715
2716
        return true;
2717
    }
2718
2719
    /**
2720
     * Get a list of sessions of which the given conditions match with an = 'cond'
2721
     * @param  array $conditions a list of condition example :
2722
     * array('status' => STUDENT) or
2723
     * array('s.name' => array('operator' => 'LIKE', value = '%$needle%'))
2724
     * @param  array $order_by a list of fields on which sort
2725
     * @return array An array with all sessions of the platform.
2726
     * @todo   optional course code parameter, optional sorting parameters...
2727
     */
2728
    public static function get_sessions_list($conditions = array(), $order_by = array(), $from = null, $to = null)
2729
    {
2730
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
2731
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2732
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
2733
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
2734
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2735
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
2736
        $access_url_id = api_get_current_access_url_id();
2737
        $return_array = array();
2738
2739
        $sql_query = " SELECT
2740
                    DISTINCT(s.id),
2741
                    s.name,
2742
                    s.nbr_courses,
2743
                    s.access_start_date,
2744
                    s.access_end_date,
2745
                    u.firstname,
2746
                    u.lastname,
2747
                    sc.name as category_name,
2748
                    s.promotion_id
2749
				FROM $session_table s
2750
				INNER JOIN $user_table u ON s.id_coach = u.user_id
2751
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
2752
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
2753
				LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
2754
				INNER JOIN $course_table c ON sco.c_id = c.id
2755
				WHERE ar.access_url_id = $access_url_id ";
2756
2757
        $availableFields = array(
2758
            's.id',
2759
            's.name',
2760
            'c.id'
2761
        );
2762
2763
        $availableOperator = array(
2764
            'like',
2765
            '>=',
2766
            '<=',
2767
            '=',
2768
        );
2769
2770
        if (count($conditions) > 0) {
2771
            foreach ($conditions as $field => $options) {
2772
                $operator = strtolower($options['operator']);
2773
                $value = Database::escape_string($options['value']);
2774
                $sql_query .= ' AND ';
2775
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
2776
                    $sql_query .= $field . " $operator '" . $value . "'";
2777
                }
2778
            }
2779
        }
2780
2781
        $orderAvailableList = array('name');
2782
2783
        if (count($order_by) > 0) {
2784
            $order = null;
2785
            $direction = null;
2786
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
2787
                $order = $order_by[0];
2788
            }
2789
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), array('desc', 'asc'))) {
2790
                $direction = $order_by[1];
2791
            }
2792
2793
            if (!empty($order)) {
2794
                $sql_query .= " ORDER BY $order $direction ";
2795
            }
2796
        }
2797
2798
        if (!is_null($from) && !is_null($to)) {
2799
            $to = intval($to);
2800
            $from = intval($from);
2801
            $sql_query .= "LIMIT $from, $to";
2802
        }
2803
2804
        $sql_result = Database::query($sql_query);
2805
        if (Database::num_rows($sql_result) > 0) {
2806
            while ($result = Database::fetch_array($sql_result)) {
2807
                $return_array[$result['id']] = $result;
2808
            }
2809
        }
2810
2811
        return $return_array;
2812
    }
2813
2814
    /**
2815
     * Get the session category information by id
2816
     * @param string session category ID
2817
     * @return mixed false if the session category does not exist, array if the session category exists
2818
     */
2819 View Code Duplication
    public static function get_session_category($id)
2820
    {
2821
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2822
        $id = intval($id);
2823
        $sql = "SELECT id, name, date_start, date_end
2824
                FROM $tbl_session_category
2825
                WHERE id= $id";
2826
        $result = Database::query($sql);
2827
        $num = Database::num_rows($result);
2828
        if ($num > 0) {
2829
            return Database::fetch_array($result);
2830
        } else {
2831
            return false;
2832
        }
2833
    }
2834
2835
    /**
2836
     * Get all session categories (filter by access_url_id)
2837
     * @return mixed false if the session category does not exist, array if the session category exists
2838
     */
2839
    public static function get_all_session_category()
2840
    {
2841
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2842
        $id = api_get_current_access_url_id();
2843
        $sql = 'SELECT * FROM ' . $tbl_session_category . '
2844
                WHERE access_url_id = ' . $id . '
2845
                ORDER BY name ASC';
2846
        $result = Database::query($sql);
2847
        if (Database::num_rows($result) > 0) {
2848
            $data = Database::store_result($result, 'ASSOC');
2849
            return $data;
2850
        } else {
2851
            return false;
2852
        }
2853
    }
2854
2855
    /**
2856
     * Assign a coach to course in session with status = 2
2857
     * @param int  $user_id
2858
     * @param int  $session_id
2859
     * @param int  $courseId
2860
     * @param bool $nocoach optional, if is true the user don't be a coach now,
2861
     * otherwise it'll assign a coach
2862
     * @return bool true if there are affected rows, otherwise false
2863
     */
2864
    public static function set_coach_to_course_session(
2865
        $user_id,
2866
        $session_id = 0,
2867
        $courseId = 0,
2868
        $nocoach = false
2869
    ) {
2870
        // Definition of variables
2871
        $user_id = intval($user_id);
2872
2873
        if (!empty($session_id)) {
2874
            $session_id = intval($session_id);
2875
        } else {
2876
            $session_id = api_get_session_id();
2877
        }
2878
2879
        if (!empty($courseId)) {
2880
            $courseId = intval($courseId);
2881
        } else {
2882
            $courseId = api_get_course_id();
2883
        }
2884
2885
        if (empty($session_id) || empty($courseId) || empty($user_id)) {
2886
            return false;
2887
        }
2888
2889
        // Table definition
2890
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2891
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2892
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
2893
2894
        // check if user is a teacher
2895
        $sql = "SELECT * FROM $tbl_user
2896
                WHERE status = 1 AND user_id = $user_id";
2897
2898
        $rs_check_user = Database::query($sql);
2899
2900
        if (Database::num_rows($rs_check_user) > 0) {
2901
            if ($nocoach) {
2902
                // check if user_id exists in session_rel_user (if the user is
2903
                // subscribed to the session in any manner)
2904
                $sql = "SELECT user_id FROM $tbl_session_rel_user
2905
                        WHERE
2906
                            session_id = $session_id AND
2907
                            user_id = $user_id";
2908
                $res = Database::query($sql);
2909
2910 View Code Duplication
                if (Database::num_rows($res) > 0) {
2911
                    // The user is already subscribed to the session. Change the
2912
                    // record so the user is NOT a coach for this course anymore
2913
                    // and then exit
2914
                    $sql = "UPDATE $tbl_session_rel_course_rel_user
2915
                            SET status = 0
2916
                            WHERE
2917
                                session_id = $session_id AND
2918
                                c_id = $courseId AND
2919
                                user_id = $user_id ";
2920
                    $result = Database::query($sql);
2921
                    if (Database::affected_rows($result) > 0)
2922
                        return true;
2923
                    else
2924
                        return false;
2925
                } else {
2926
                    // The user is not subscribed to the session, so make sure
2927
                    // he isn't subscribed to a course in this session either
2928
                    // and then exit
2929
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2930
                            WHERE
2931
                                session_id = $session_id AND
2932
                                c_id = $courseId AND
2933
                                user_id = $user_id ";
2934
                    $result = Database::query($sql);
2935
                    if (Database::affected_rows($result) > 0) {
2936
                        return true;
2937
                    } else {
2938
                        return false;
2939
                    }
2940
                }
2941
            } else {
2942
                // Assign user as a coach to course
2943
                // First check if the user is registered to the course
2944
                $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
2945
                        WHERE
2946
                            session_id = $session_id AND
2947
                            c_id = $courseId AND
2948
                            user_id = $user_id";
2949
                $rs_check = Database::query($sql);
2950
2951
                // Then update or insert.
2952 View Code Duplication
                if (Database::num_rows($rs_check) > 0) {
2953
                    $sql = "UPDATE $tbl_session_rel_course_rel_user SET status = 2
2954
					        WHERE
2955
					            session_id = $session_id AND
2956
					            c_id = $courseId AND
2957
					            user_id = $user_id ";
2958
                    $result = Database::query($sql);
2959
                    if (Database::affected_rows($result) > 0) {
2960
                        return true;
2961
                    } else {
2962
                        return false;
2963
                    }
2964
                } else {
2965
                    $sql = "INSERT INTO $tbl_session_rel_course_rel_user(session_id, c_id, user_id, status)
2966
                            VALUES($session_id, $courseId, $user_id, 2)";
2967
                    $result = Database::query($sql);
2968
                    if (Database::affected_rows($result) > 0) {
2969
                        return true;
2970
                    } else {
2971
                        return false;
2972
                    }
2973
                }
2974
            }
2975
        } else {
2976
            return false;
2977
        }
2978
    }
2979
2980
    /**
2981
     * @param int $sessionId
2982
     * @return bool
2983
     */
2984 View Code Duplication
    public static function removeAllDrhFromSession($sessionId)
2985
    {
2986
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2987
2988
        $sessionId = (int) $sessionId;
2989
2990
        if (empty($sessionId)) {
2991
            return false;
2992
        }
2993
2994
        $sql = "DELETE FROM $tbl_session_rel_user
2995
                WHERE
2996
                    session_id = $sessionId AND                            
2997
                    relation_type =" . SESSION_RELATION_TYPE_RRHH;
2998
        Database::query($sql);
2999
3000
        return true;
3001
    }
3002
3003
    /**
3004
     * Subscribes sessions to human resource manager (Dashboard feature)
3005
     * @param array $userInfo Human Resource Manager info
3006
     * @param array $sessions_list Sessions id
3007
     * @param bool $sendEmail
3008
     * @param bool $removeSessionsFromUser
3009
     * @return int
3010
     * */
3011
    public static function subscribeSessionsToDrh(
3012
        $userInfo,
3013
        $sessions_list,
3014
        $sendEmail = false,
3015
        $removeSessionsFromUser = true
3016
    ) {
3017
        // Database Table Definitions
3018
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3019
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3020
3021
        if (empty($userInfo)) {
3022
3023
            return 0;
3024
        }
3025
3026
        $userId = $userInfo['user_id'];
3027
3028
        // Only subscribe DRH users.
3029
        $rolesAllowed = array(
3030
            DRH,
3031
            SESSIONADMIN,
3032
            PLATFORM_ADMIN,
3033
            COURSE_TUTOR
3034
        );
3035
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3036
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3037
3038
            return 0;
3039
        }
3040
3041
        $affected_rows = 0;
3042
        // Deleting assigned sessions to hrm_id.
3043
        if ($removeSessionsFromUser) {
3044
            if (api_is_multiple_url_enabled()) {
3045
                $sql = "SELECT s.session_id
3046
                        FROM $tbl_session_rel_user s
3047
                        INNER JOIN $tbl_session_rel_access_url a 
3048
                        ON (a.session_id = s.session_id)
3049
                        WHERE
3050
                            s.user_id = $userId AND
3051
                            relation_type = " . SESSION_RELATION_TYPE_RRHH . " AND
3052
                            access_url_id = " . api_get_current_access_url_id();
3053
            } else {
3054
                $sql = "SELECT s.session_id 
3055
                        FROM $tbl_session_rel_user s
3056
                        WHERE user_id = $userId AND relation_type=" . SESSION_RELATION_TYPE_RRHH;
3057
            }
3058
            $result = Database::query($sql);
3059
3060 View Code Duplication
            if (Database::num_rows($result) > 0) {
3061
                while ($row = Database::fetch_array($result)) {
3062
                    $sql = "DELETE FROM $tbl_session_rel_user
3063
                            WHERE
3064
                                session_id = {$row['session_id']} AND
3065
                                user_id = $userId AND
3066
                                relation_type =" . SESSION_RELATION_TYPE_RRHH;
3067
                    Database::query($sql);
3068
                }
3069
            }
3070
        }
3071
3072
        // Inserting new sessions list.
3073
        if (!empty($sessions_list) && is_array($sessions_list)) {
3074
            foreach ($sessions_list as $session_id) {
3075
                $session_id = intval($session_id);
3076
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3077
                        VALUES (
3078
                            $session_id,
3079
                            $userId,
3080
                            '" . SESSION_RELATION_TYPE_RRHH . "',
3081
                            '" . api_get_utc_datetime() . "'
3082
                        )";
3083
                Database::query($sql);
3084
                $affected_rows++;
3085
            }
3086
        }
3087
3088
        return $affected_rows;
3089
    }
3090
3091
    /**
3092
     * @param int $sessionId
3093
     * @return array
3094
     */
3095
    public static function getDrhUsersInSession($sessionId)
3096
    {
3097
        return self::get_users_by_session($sessionId, SESSION_RELATION_TYPE_RRHH);
3098
    }
3099
3100
    /**
3101
     * @param int $userId
3102
     * @param int $sessionId
3103
     * @return array
3104
     */
3105
    public static function getSessionFollowedByDrh($userId, $sessionId)
3106
    {
3107
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3108
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3109
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3110
3111
        $userId = intval($userId);
3112
        $sessionId = intval($sessionId);
3113
3114
        $select = " SELECT * ";
3115
        if (api_is_multiple_url_enabled()) {
3116
            $sql = " $select FROM $tbl_session s
3117
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3118
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3119
                    WHERE
3120
                        sru.user_id = '$userId' AND
3121
                        sru.session_id = '$sessionId' AND
3122
                        sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "' AND
3123
                        access_url_id = " . api_get_current_access_url_id() . "
3124
                        ";
3125
        } else {
3126
            $sql = "$select FROM $tbl_session s
3127
                     INNER JOIN $tbl_session_rel_user sru
3128
                     ON
3129
                        sru.session_id = s.id AND
3130
                        sru.user_id = '$userId' AND
3131
                        sru.session_id = '$sessionId' AND
3132
                        sru.relation_type = '" . SESSION_RELATION_TYPE_RRHH . "'
3133
                    ";
3134
        }
3135
3136
        $result = Database::query($sql);
3137
        if (Database::num_rows($result)) {
3138
            $row = Database::fetch_array($result, 'ASSOC');
3139
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3140
3141
            return $row;
3142
        }
3143
3144
        return array();
3145
    }
3146
3147
    /**
3148
     * Get sessions followed by human resources manager
3149
     * @param int $userId
3150
     * @param int $start
3151
     * @param int $limit
3152
     * @param bool $getCount
3153
     * @param bool $getOnlySessionId
3154
     * @param bool $getSql
3155
     * @param string $orderCondition
3156
     * @param string $keyword
3157
     * @param string $description
3158
     *
3159
     * @return array sessions
3160
     */
3161
    public static function get_sessions_followed_by_drh(
3162
        $userId,
3163
        $start = null,
3164
        $limit = null,
3165
        $getCount = false,
3166
        $getOnlySessionId = false,
3167
        $getSql = false,
3168
        $orderCondition = null,
3169
        $keyword = '',
3170
        $description = ''
3171
    ) {
3172
        return self::getSessionsFollowedByUser(
3173
            $userId,
3174
            DRH,
3175
            $start,
3176
            $limit,
3177
            $getCount,
3178
            $getOnlySessionId,
3179
            $getSql,
3180
            $orderCondition,
3181
            $keyword,
3182
            $description
3183
        );
3184
    }
3185
3186
    /**
3187
     * Get sessions followed by human resources manager
3188
     * @param int $userId
3189
     * @param int $status Optional
3190
     * @param int $start
3191
     * @param int $limit
3192
     * @param bool $getCount
3193
     * @param bool $getOnlySessionId
3194
     * @param bool $getSql
3195
     * @param string $orderCondition
3196
     * @param string $keyword
3197
     * @param string $description
3198
     * @return array sessions
3199
     */
3200
    public static function getSessionsFollowedByUser(
3201
        $userId,
3202
        $status = null,
3203
        $start = null,
3204
        $limit = null,
3205
        $getCount = false,
3206
        $getOnlySessionId = false,
3207
        $getSql = false,
3208
        $orderCondition = null,
3209
        $keyword = '',
3210
        $description = ''
3211
    ) {
3212
        // Database Table Definitions
3213
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3214
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3215
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3216
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3217
3218
        $userId = intval($userId);
3219
3220
        $select = " SELECT DISTINCT * ";
3221
3222
        if ($getCount) {
3223
            $select = " SELECT count(DISTINCT(s.id)) as count ";
3224
        }
3225
3226
        if ($getOnlySessionId) {
3227
            $select = " SELECT DISTINCT(s.id) ";
3228
        }
3229
3230
        $limitCondition = null;
3231 View Code Duplication
        if (!empty($start) && !empty($limit)) {
3232
            $limitCondition = " LIMIT " . intval($start) . ", " . intval($limit);
3233
        }
3234
3235
        if (empty($orderCondition)) {
3236
            $orderCondition = " ORDER BY s.name ";
3237
        }
3238
3239
        $whereConditions = null;
3240
        $sessionCourseConditions = null;
3241
        $sessionConditions = null;
3242
        $sessionQuery = null;
3243
        $courseSessionQuery = null;
3244
3245
        switch ($status) {
3246
            case DRH:
3247
                $sessionQuery = "SELECT sru.session_id
3248
                                 FROM
3249
                                 $tbl_session_rel_user sru
3250
                                 WHERE
3251
                                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3252
                                    sru.user_id = $userId";
3253
                break;
3254
            case COURSEMANAGER:
3255
                $courseSessionQuery = "
3256
                    SELECT scu.session_id as id
3257
                    FROM $tbl_session_rel_course_rel_user scu
3258
                    WHERE (scu.status = 2 AND scu.user_id = $userId)";
3259
3260
                $whereConditions = " OR (s.id_coach = $userId) ";
3261
                break;
3262
            default:
3263
                $sessionQuery = "SELECT sru.session_id
3264
                                 FROM
3265
                                 $tbl_session_rel_user sru
3266
                                 WHERE
3267
                                    sru.user_id = $userId";
3268
                break;
3269
        }
3270
3271
        $keywordCondition = '';
3272 View Code Duplication
        if (!empty($keyword)) {
3273
            $keyword = Database::escape_string($keyword);
3274
            $keywordCondition = " AND (s.name LIKE '%$keyword%' ) ";
3275
3276
            if (!empty($description)) {
3277
                $description = Database::escape_string($description);
3278
                $keywordCondition = " AND (s.name LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
3279
            }
3280
        }
3281
3282
        $whereConditions .= $keywordCondition;
3283
        $subQuery = $sessionQuery.$courseSessionQuery;
3284
3285
        $sql = " $select FROM $tbl_session s
3286
                INNER JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3287
                WHERE
3288
                    access_url_id = ".api_get_current_access_url_id()." AND
3289
                    s.id IN (
3290
                        $subQuery
3291
                    )
3292
                    $whereConditions
3293
                    $orderCondition
3294
                    $limitCondition";
3295
3296
        if ($getSql) {
3297
            return $sql;
3298
        }
3299
3300
        $result = Database::query($sql);
3301
3302
        if ($getCount) {
3303
            $row = Database::fetch_array($result);
3304
            return $row['count'];
3305
        }
3306
3307
        $sessions = array();
3308
        if (Database::num_rows($result) > 0) {
3309
            $sysUploadPath = api_get_path(SYS_UPLOAD_PATH). 'sessions/';
3310
            $webUploadPath = api_get_path(WEB_UPLOAD_PATH). 'sessions/';
3311
            $imgPath = Display::return_icon('session_default_small.png', null, null, null, null, true);
3312
3313
            $tableExtraFields = Database::get_main_table(TABLE_EXTRA_FIELD);
3314
            $sql = "SELECT id FROM " . $tableExtraFields . "
3315
                    WHERE extra_field_type = 3 AND variable='image'";
3316
            $resultField = Database::query($sql);
3317
            $imageFieldId = Database::fetch_assoc($resultField);
3318
3319
            while ($row = Database::fetch_array($result)) {
3320
3321
                $row['image'] =  null;
3322
                $sessionImage = $sysUploadPath . $imageFieldId['id'] . '_' . $row['id'] . '.png';
3323
3324
                if (is_file($sessionImage)) {
3325
                    $sessionImage = $webUploadPath . $imageFieldId['id'] . '_' . $row['id'] . '.png';
3326
                    $row['image'] = $sessionImage;
3327
                } else {
3328
                    $row['image'] =  $imgPath;
3329
                }
3330
3331
                if ($row['display_start_date'] == '0000-00-00 00:00:00' || $row['display_start_date'] == '0000-00-00') {
3332
                    $row['display_start_date'] = null;
3333
                }
3334
3335
                if ($row['display_end_date'] == '0000-00-00 00:00:00' || $row['display_end_date'] == '0000-00-00') {
3336
                    $row['display_end_date'] = null;
3337
                }
3338
3339
                if ($row['access_start_date'] == '0000-00-00 00:00:00' || $row['access_start_date'] == '0000-00-00') {
3340
                    $row['access_start_date'] = null;
3341
                }
3342
3343
                if ($row['access_end_date'] == '0000-00-00 00:00:00' || $row['access_end_date'] == '0000-00-00') {
3344
                    $row['access_end_date'] = null;
3345
                }
3346
3347
                if (
3348
                    $row['coach_access_start_date'] == '0000-00-00 00:00:00' ||
3349
                    $row['coach_access_start_date'] == '0000-00-00'
3350
                ) {
3351
                    $row['coach_access_start_date'] = null;
3352
                }
3353
3354
                if (
3355
                    $row['coach_access_end_date'] == '0000-00-00 00:00:00' ||
3356
                    $row['coach_access_end_date'] == '0000-00-00'
3357
                ) {
3358
                    $row['coach_access_end_date'] = null;
3359
                }
3360
3361
                $sessions[$row['id']] = $row;
3362
3363
            }
3364
        }
3365
3366
        return $sessions;
3367
    }
3368
3369
    /**
3370
     * Gets the list (or the count) of courses by session filtered by access_url
3371
     * @param int $session_id The session id
3372
     * @param string $course_name The course code
3373
     * @param string $orderBy Field to order the data
3374
     * @param boolean $getCount Optional. Count the session courses
3375
     * @return array|int List of courses. Whether $getCount is true, return the count
3376
     */
3377
    public static function get_course_list_by_session_id(
3378
        $session_id,
3379
        $course_name = '',
3380
        $orderBy = null,
3381
        $getCount = false
3382
    ) {
3383
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3384
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3385
3386
        $session_id = intval($session_id);
3387
3388
        $sqlSelect = "*, c.id, c.id as real_id";
3389
3390
        if ($getCount) {
3391
            $sqlSelect = "COUNT(1) as count";
3392
        }
3393
3394
        // select the courses
3395
        $sql = "SELECT $sqlSelect
3396
                FROM $tbl_course c
3397
                INNER JOIN $tbl_session_rel_course src
3398
                ON (c.id = src.c_id)
3399
		        WHERE src.session_id = '$session_id' ";
3400
3401
        if (!empty($course_name)) {
3402
            $course_name = Database::escape_string($course_name);
3403
            $sql .= " AND c.title LIKE '%$course_name%' ";
3404
        }
3405
3406
        if (!empty($orderBy)) {
3407
            $orderBy = Database::escape_string($orderBy);
3408
            $orderBy = " ORDER BY $orderBy";
3409
        } else {
3410
            if (SessionManager::orderCourseIsEnabled()) {
3411
                $orderBy .= " ORDER BY position ";
3412
            } else {
3413
                $orderBy .= " ORDER BY title ";
3414
            }
3415
        }
3416
3417
        $sql .= Database::escape_string($orderBy);
3418
        $result = Database::query($sql);
3419
        $num_rows = Database::num_rows($result);
3420
        $courses = array();
3421
        if ($num_rows > 0) {
3422
            if ($getCount) {
3423
                $count = Database::fetch_assoc($result);
3424
3425
                return intval($count['count']);
3426
            }
3427
3428
            while ($row = Database::fetch_array($result,'ASSOC'))	{
3429
                $courses[$row['real_id']] = $row;
3430
            }
3431
        }
3432
3433
        return $courses;
3434
    }
3435
3436
    /**
3437
     * Gets the list of courses by session filtered by access_url
3438
     *
3439
     * @param $userId
3440
     * @param $sessionId
3441
     * @param null $from
3442
     * @param null $limit
3443
     * @param null $column
3444
     * @param null $direction
3445
     * @param bool $getCount
3446
     * @return array
3447
     */
3448
    public static function getAllCoursesFollowedByUser(
3449
        $userId,
3450
        $sessionId,
3451
        $from = null,
3452
        $limit = null,
3453
        $column = null,
3454
        $direction = null,
3455
        $getCount = false,
3456
        $keyword = null
3457
    ) {
3458
        if (empty($sessionId)) {
3459
            $sessionsSQL = SessionManager::get_sessions_followed_by_drh(
3460
                $userId,
3461
                null,
3462
                null,
3463
                null,
3464
                true,
3465
                true
3466
            );
3467
        } else {
3468
            $sessionsSQL = intval($sessionId);
3469
        }
3470
3471
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3472
        $tbl_session_rel_course	= Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3473
3474
        if ($getCount) {
3475
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
3476
        } else {
3477
            $select = "SELECT DISTINCT c.* ";
3478
        }
3479
3480
        $keywordCondition = null;
3481
        if (!empty($keyword)) {
3482
            $keyword = Database::escape_string($keyword);
3483
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3484
        }
3485
3486
        // Select the courses
3487
        $sql = "$select
3488
                FROM $tbl_course c
3489
                INNER JOIN $tbl_session_rel_course src
3490
                ON c.id = src.c_id
3491
		        WHERE
3492
		            src.session_id IN ($sessionsSQL)
3493
		            $keywordCondition
3494
		        ";
3495 View Code Duplication
        if ($getCount) {
3496
            $result = Database::query($sql);
3497
            $row = Database::fetch_array($result,'ASSOC');
3498
            return $row['count'];
3499
        }
3500
3501 View Code Duplication
        if (isset($from) && isset($limit)) {
3502
            $from = intval($from);
3503
            $limit = intval($limit);
3504
            $sql .= " LIMIT $from, $limit";
3505
        }
3506
3507
        $result = Database::query($sql);
3508
        $num_rows = Database::num_rows($result);
3509
        $courses = array();
3510
3511
        if ($num_rows > 0) {
3512
            while ($row = Database::fetch_array($result,'ASSOC'))	{
3513
                $courses[$row['id']] = $row;
3514
            }
3515
        }
3516
3517
        return $courses;
3518
    }
3519
3520
    /**
3521
     * Gets the list of courses by session filtered by access_url
3522
     * @param int $session_id
3523
     * @param string $course_name
3524
     * @return array list of courses
3525
     */
3526
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
3527
    {
3528
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3529
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3530
3531
        $session_id = intval($session_id);
3532
        $course_name = Database::escape_string($course_name);
3533
3534
        // select the courses
3535
        $sql = "SELECT c.id, c.title FROM $tbl_course c
3536
                INNER JOIN $tbl_session_rel_course src
3537
                ON c.id = src.c_id
3538
		        WHERE ";
3539
3540
        if (!empty($session_id)) {
3541
            $sql .= "src.session_id LIKE '$session_id' AND ";
3542
        }
3543
3544
        if (!empty($course_name)) {
3545
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
3546
        }
3547
3548
        $sql .= "ORDER BY title;";
3549
        $result = Database::query($sql);
3550
        $num_rows = Database::num_rows($result);
3551
        $courses = array();
3552
        if ($num_rows > 0) {
3553
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3554
                $courses[$row['id']] = $row;
3555
            }
3556
        }
3557
3558
        return $courses;
3559
    }
3560
3561
3562
    /**
3563
     * Gets the count of courses by session filtered by access_url
3564
     * @param int session id
3565
     * @return array list of courses
3566
     */
3567
    public static function getCourseCountBySessionId($session_id, $keyword = null)
3568
    {
3569
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3570
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3571
        $session_id = intval($session_id);
3572
3573
        // select the courses
3574
        $sql = "SELECT COUNT(c.code) count
3575
                FROM $tbl_course c
3576
                INNER JOIN $tbl_session_rel_course src
3577
                ON c.id = src.c_id
3578
		        WHERE src.session_id = '$session_id' ";
3579
3580
        $keywordCondition = null;
3581
        if (!empty($keyword)) {
3582
            $keyword = Database::escape_string($keyword);
3583
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
3584
        }
3585
        $sql .= $keywordCondition;
3586
3587
        $result = Database::query($sql);
3588
        $num_rows = Database::num_rows($result);
3589
        if ($num_rows > 0) {
3590
            $row = Database::fetch_array($result,'ASSOC');
3591
            return $row['count'];
3592
        }
3593
3594
        return null;
3595
    }
3596
3597
    /**
3598
     * Get the session id based on the original id and field name in the extra fields.
3599
     * Returns 0 if session was not found
3600
     *
3601
     * @param string $value Original session id
3602
     * @param string $variable Original field name
3603
     * @return int Session id
3604
     */
3605
    public static function getSessionIdFromOriginalId($value, $variable)
3606
    {
3607
        $extraFieldValue = new ExtraFieldValue('session');
3608
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
3609
            $variable,
3610
            $value
3611
        );
3612
3613
        if (!empty($result)) {
3614
            return $result['item_id'];
3615
        }
3616
3617
        return 0;
3618
    }
3619
3620
    /**
3621
     * Get users by session
3622
     * @param  int $id session id
3623
     * @param    int $status filter by status coach = 2
3624
     * @param bool $getCount Optional. Allow get the number of rows from the result
3625
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
3626
     */
3627
    public static function get_users_by_session($id, $status = null, $getCount = false)
3628
    {
3629
        if (empty($id)) {
3630
            return array();
3631
        }
3632
        $id = intval($id);
3633
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3634
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3635
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
3636
3637
        $selectedField = 'u.user_id,lastname, firstname, username, relation_type, access_url_id';
3638
3639
        if ($getCount) {
3640
            $selectedField = 'count(1) AS count';
3641
        }
3642
3643
        $sql = "SELECT $selectedField
3644
                FROM $tbl_user u
3645
                INNER JOIN $tbl_session_rel_user
3646
                ON u.user_id = $tbl_session_rel_user.user_id AND
3647
                $tbl_session_rel_user.session_id = $id
3648
                LEFT OUTER JOIN $table_access_url_user uu
3649
                ON (uu.user_id = u.user_id)
3650
                ";
3651
3652
        $urlId = api_get_current_access_url_id();
3653
        if (isset($status) && $status != '') {
3654
            $status = intval($status);
3655
            $sql .= " WHERE relation_type = $status AND (access_url_id = $urlId OR access_url_id is null )";
3656
        } else {
3657
            $sql .= " WHERE (access_url_id = $urlId OR access_url_id is null )";
3658
        }
3659
3660
        $sql .= " ORDER BY relation_type, ";
3661
        $sql .= api_sort_by_first_name() ? ' firstname, lastname' : '  lastname, firstname';
3662
3663
        $result = Database::query($sql);
3664
3665
        if ($getCount) {
3666
            $count = Database::fetch_assoc($result);
3667
3668
            return $count['count'];
3669
        }
3670
3671
        $return = array();
3672
        while ($row = Database::fetch_array($result, 'ASSOC')) {
3673
            $return[] = $row;
3674
        }
3675
3676
        return $return;
3677
    }
3678
3679
    /**
3680
     * The general coach (field: session.id_coach)
3681
     * @param int $user_id user id
3682
     * @param boolean   $asPlatformAdmin The user is platform admin, return everything
3683
     * @return array
3684
     */
3685
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
3686
    {
3687
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3688
        $user_id = intval($user_id);
3689
3690
        // Session where we are general coach
3691
        $sql = "SELECT DISTINCT *
3692
                FROM $session_table";
3693
3694
        if (!$asPlatformAdmin) {
3695
            $sql .= " WHERE id_coach = $user_id";
3696
        }
3697
3698
        if (api_is_multiple_url_enabled()) {
3699
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3700
            $access_url_id = api_get_current_access_url_id();
3701
3702
            $sqlCoach = '';
3703
            if (!$asPlatformAdmin) {
3704
                $sqlCoach = " id_coach = $user_id AND ";
3705
            }
3706
3707
            if ($access_url_id != -1) {
3708
                $sql = 'SELECT DISTINCT session.*
3709
                    FROM ' . $session_table . ' session INNER JOIN ' . $tbl_session_rel_access_url . ' session_rel_url
3710
                    ON (session.id = session_rel_url.session_id)
3711
                    WHERE '.$sqlCoach.' access_url_id = ' . $access_url_id;
3712
            }
3713
        }
3714
        $sql .= ' ORDER by name';
3715
        $result = Database::query($sql);
3716
3717
        return Database::store_result($result, 'ASSOC');
3718
    }
3719
3720
    /**
3721
     * @param int $user_id
3722
     * @return array
3723
     * @deprecated use get_sessions_by_general_coach()
3724
     */
3725
    public static function get_sessions_by_coach($user_id)
3726
    {
3727
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3728
        return Database::select('*', $session_table, array('where' => array('id_coach = ?' => $user_id)));
3729
    }
3730
3731
    /**
3732
     * @param int $user_id
3733
     * @param int $courseId
3734
     * @param int $session_id
3735
     * @return array|bool
3736
     */
3737 View Code Duplication
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
3738
    {
3739
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3740
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3741
        $sql = "SELECT session_rcru.status
3742
                FROM $tbl_session_rel_course_rel_user session_rcru, $tbl_user user
3743
                WHERE
3744
                    session_rcru.user_id = user.user_id AND
3745
                    session_rcru.session_id = '" . intval($session_id) . "' AND
3746
                    session_rcru.c_id ='" . intval($courseId) . "' AND
3747
                    user.user_id = " . intval($user_id);
3748
3749
        $result = Database::query($sql);
3750
        $status = false;
3751
        if (Database::num_rows($result)) {
3752
            $status = Database::fetch_row($result);
3753
            $status = $status['0'];
3754
        }
3755
3756
        return $status;
3757
    }
3758
3759
    /**
3760
     * Gets user status within a session
3761
     * @param int $user_id
3762
     * @param int $courseId
3763
     * @param $session_id
3764
     * @return int
3765
     * @assert (null,null,null) === false
3766
     */
3767
    public static function get_user_status_in_session($user_id, $courseId, $session_id)
3768
    {
3769
        if (empty($user_id) or empty($courseId) or empty($session_id)) {
3770
            return false;
3771
        }
3772
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3773
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
3774
        $sql = "SELECT session_rcru.status
3775
                FROM $tbl_session_rel_course_rel_user session_rcru, $tbl_user user
3776
                WHERE session_rcru.user_id = user.user_id AND
3777
                    session_rcru.session_id = '" . intval($session_id) . "' AND
3778
                    session_rcru.c_id ='" . intval($courseId) . "' AND
3779
                    user.user_id = " . intval($user_id);
3780
        $result = Database::query($sql);
3781
        $status = false;
3782
        if (Database::num_rows($result)) {
3783
            $status = Database::fetch_row($result);
3784
            $status = $status['0'];
3785
        }
3786
        return $status;
3787
    }
3788
3789
    /**
3790
     * @param int $id
3791
     * @return array
3792
     */
3793
    public static function get_all_sessions_by_promotion($id)
3794
    {
3795
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
3796
        return Database::select('*', $t, array('where' => array('promotion_id = ?' => $id)));
3797
    }
3798
3799
    /**
3800
     * @param int $promotion_id
3801
     * @param array $list
3802
     */
3803
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
3804
    {
3805
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
3806
        $params = array();
3807
        $params['promotion_id'] = 0;
3808
        Database::update($t, $params, array('promotion_id = ?' => $promotion_id));
3809
3810
        $params['promotion_id'] = $promotion_id;
3811
        if (!empty($list)) {
3812
            foreach ($list as $session_id) {
3813
                $session_id = intval($session_id);
3814
                Database::update($t, $params, array('id = ?' => $session_id));
3815
            }
3816
        }
3817
    }
3818
3819
    /**
3820
     * Updates a session status
3821
     * @param	int 	session id
3822
     * @param	int 	status
3823
     */
3824
    public static function set_session_status($session_id, $status)
3825
    {
3826
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
3827
        $params['visibility'] = $status;
3828
        Database::update($t, $params, array('id = ?' => $session_id));
3829
    }
3830
3831
    /**
3832
     * Copies a session with the same data to a new session.
3833
     * The new copy is not assigned to the same promotion. @see subscribe_sessions_to_promotions() for that
3834
     * @param   int     Session ID
3835
     * @param   bool    Whether to copy the relationship with courses
3836
     * @param   bool    Whether to copy the relationship with users
3837
     * @param   bool    New courses will be created
3838
     * @param   bool    Whether to set exercises and learning paths in the new session to invisible by default
3839
     * @return  int     The new session ID on success, 0 otherwise
3840
     * @todo make sure the extra session fields are copied too
3841
     */
3842
    public static function copy(
3843
        $id,
3844
        $copy_courses = true,
3845
        $copy_users = true,
3846
        $create_new_courses = false,
3847
        $set_exercises_lp_invisible = false
3848
    ) {
3849
        $id = intval($id);
3850
        $s = self::fetch($id);
3851
        // Check all dates before copying
3852
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
3853
        $now = time() - date('Z');
3854
        // Timestamp in one month
3855
        $inOneMonth = $now + (30*24*3600);
3856
        $inOneMonth = api_get_local_time($inOneMonth);
3857
        if (api_strtotime($s['access_start_date']) < $now) {
3858
            $s['access_start_date'] = api_get_local_time($now);
3859
        }
3860
        if (api_strtotime($s['display_start_date']) < $now) {
3861
            $s['display_start_date'] = api_get_local_time($now);
3862
        }
3863
        if (api_strtotime($s['coach_access_start_date']) < $now) {
3864
            $s['coach_access_start_date'] = api_get_local_time($now);
3865
        }
3866
        if (api_strtotime($s['access_end_date']) < $now) {
3867
            $s['access_end_date'] = $inOneMonth;
3868
        }
3869
        if (api_strtotime($s['display_end_date']) < $now) {
3870
            $s['display_end_date'] = $inOneMonth;
3871
        }
3872
        if (api_strtotime($s['coach_access_end_date']) < $now) {
3873
            $s['coach_access_end_date'] = $inOneMonth;
3874
        }
3875
        // Now try to create the session
3876
        $sid = self::create_session(
3877
            $s['name'] . ' ' . get_lang('CopyLabelSuffix'),
3878
            $s['access_start_date'],
3879
            $s['access_end_date'],
3880
            $s['display_start_date'],
3881
            $s['display_end_date'],
3882
            $s['coach_access_start_date'],
3883
            $s['coach_access_end_date'],
3884
            (int)$s['id_coach'],
3885
            $s['session_category_id'],
3886
            (int)$s['visibility'],
3887
            true
3888
        );
3889
3890
        if (!is_numeric($sid) || empty($sid)) {
3891
            return false;
3892
        }
3893
3894
        if ($copy_courses) {
3895
            // Register courses from the original session to the new session
3896
            $courses = self::get_course_list_by_session_id($id);
3897
3898
            $short_courses = $new_short_courses = array();
3899
            if (is_array($courses) && count($courses) > 0) {
3900
                foreach ($courses as $course) {
3901
                    $short_courses[] = $course;
3902
                }
3903
            }
3904
3905
            $courses = null;
3906
3907
            //We will copy the current courses of the session to new courses
3908
            if (!empty($short_courses)) {
3909
                if ($create_new_courses) {
3910
                    //Just in case
3911
                    if (function_exists('ini_set')) {
3912
                        api_set_memory_limit('256M');
3913
                        ini_set('max_execution_time', 0);
3914
                    }
3915
                    $params = array();
3916
                    $params['skip_lp_dates'] = true;
3917
3918
                    foreach ($short_courses as $course_data) {
3919
                        $course_info = CourseManager::copy_course_simple(
3920
                            $course_data['title'].' '.get_lang(
3921
                                'CopyLabelSuffix'
3922
                            ),
3923
                            $course_data['course_code'],
3924
                            $id,
3925
                            $sid,
3926
                            $params
3927
                        );
3928
3929
                        if ($course_info) {
3930
                            //By default new elements are invisible
3931
                            if ($set_exercises_lp_invisible) {
3932
                                $list = new LearnpathList('', $course_info['code'], $sid);
3933
                                $flat_list = $list->get_flat_list();
3934
                                if (!empty($flat_list)) {
3935
                                    foreach ($flat_list as $lp_id => $data) {
3936
                                        api_item_property_update(
3937
                                            $course_info,
3938
                                            TOOL_LEARNPATH,
3939
                                            $lp_id,
3940
                                            'invisible',
3941
                                            api_get_user_id(),
3942
                                            0,
3943
                                            0,
3944
                                            0,
3945
                                            0,
3946
                                            $sid
3947
                                        );
3948
                                    }
3949
                                }
3950
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
3951
                                $course_id = $course_info['real_id'];
3952
                                //@todo check this query
3953
                                $sql = "UPDATE $quiz_table SET active = 0
3954
                                        WHERE c_id = $course_id AND session_id = $sid";
3955
                                Database::query($sql);
3956
                            }
3957
                            $new_short_courses[] = $course_info['real_id'];
3958
                        }
3959
                    }
3960
                } else {
3961
                    foreach ($short_courses as $course_data) {
3962
                        $new_short_courses[] = $course_data['id'];
3963
                    }
3964
                }
3965
3966
                $short_courses = $new_short_courses;
3967
                self::add_courses_to_session($sid, $short_courses, true);
3968
                $short_courses = null;
3969
            }
3970
        }
3971
        if ($copy_users) {
3972
            // Register users from the original session to the new session
3973
            $users = self::get_users_by_session($id);
3974
            $short_users = array();
3975
            if (is_array($users) && count($users) > 0) {
3976
                foreach ($users as $user) {
3977
                    $short_users[] = $user['user_id'];
3978
                }
3979
            }
3980
            $users = null;
3981
            //Subscribing in read only mode
3982
            self::subscribe_users_to_session($sid, $short_users, SESSION_VISIBLE_READ_ONLY, true);
3983
            $short_users = null;
3984
        }
3985
        return $sid;
3986
    }
3987
3988
    /**
3989
     * @param int $user_id
3990
     * @param int $session_id
3991
     * @return bool
3992
     */
3993
    static function user_is_general_coach($user_id, $session_id)
3994
    {
3995
        $session_id = intval($session_id);
3996
        $user_id = intval($user_id);
3997
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3998
        $sql = "SELECT DISTINCT id
3999
	         	FROM $session_table
4000
	         	WHERE session.id_coach =  '" . $user_id . "' AND id = '$session_id'";
4001
        $result = Database::query($sql);
4002
        if ($result && Database::num_rows($result)) {
4003
            return true;
4004
        }
4005
        return false;
4006
    }
4007
4008
    /**
4009
     * Get the number of sessions
4010
     * @param  int ID of the URL we want to filter on (optional)
4011
     * @return int Number of sessions
4012
     */
4013 View Code Duplication
    public static function count_sessions($access_url_id = null)
4014
    {
4015
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4016
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4017
        $sql = "SELECT count(id) FROM $session_table s";
4018
        if (!empty($access_url_id) && $access_url_id == intval($access_url_id)) {
4019
            $sql .= ", $access_url_rel_session_table u " .
4020
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4021
        }
4022
        $res = Database::query($sql);
4023
        $row = Database::fetch_row($res);
4024
        return $row[0];
4025
    }
4026
4027
    /**
4028
     * Protect a session to be edited.
4029
     * @param int $id
4030
     * @param bool $checkSession
4031
     * @return mixed | bool true if pass the check, api_not_allowed otherwise
4032
     */
4033
    public static function protectSession($id, $checkSession = true)
4034
    {
4035
        // api_protect_admin_script(true);
4036
        if (self::allowToManageSessions()) {
4037
4038
            if (api_is_platform_admin()) {
4039
                return true;
4040
            }
4041
4042
            if ($checkSession) {
4043
                if (self::allowed($id)) {
4044
                    return true;
4045
                } else {
4046
                    api_not_allowed(true);
4047
                }
4048
            }
4049
        } else {
4050
            api_not_allowed(true);
4051
        }
4052
    }
4053
4054
    /**
4055
     * @param int $id
4056
     * @return bool
4057
     */
4058
    private static function allowed($id)
4059
    {
4060
        $sessionInfo = self::fetch($id);
4061
4062
        if (empty($sessionInfo)) {
4063
            return false;
4064
        }
4065
4066
        if (api_is_platform_admin()) {
4067
            return true;
4068
        }
4069
4070
        $userId = api_get_user_id();
4071
4072
        if (api_is_session_admin() &&
4073
            api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true'
4074
        ) {
4075
            if ($sessionInfo['session_admin_id'] != $userId) {
4076
                return false;
4077
            }
4078
        }
4079
4080
        if (api_is_teacher() &&
4081
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
4082
        ) {
4083
            if ($sessionInfo['id_coach'] != $userId) {
4084
                return false;
4085
            }
4086
        }
4087
4088
        return true;
4089
    }
4090
4091
    /**
4092
     * @return bool
4093
     */
4094
    public static function allowToManageSessions()
4095
    {
4096
        if (self::allowManageAllSessions()) {
4097
            return true;
4098
        }
4099
4100
        $setting = api_get_setting('allow_teachers_to_create_sessions');
4101
4102
        if (api_is_teacher() && $setting == 'true') {
4103
4104
            return true;
4105
        }
4106
4107
        return false;
4108
    }
4109
4110
    /**
4111
     * @return bool
4112
     */
4113
    public static function allowOnlyMySessions()
4114
    {
4115
        if (self::allowToManageSessions() &&
4116
            !api_is_platform_admin() &&
4117
            api_is_teacher()
4118
        ) {
4119
            return true;
4120
        }
4121
4122
        return false;
4123
    }
4124
4125
    /**
4126
     * @return bool
4127
     */
4128
    public static function allowManageAllSessions()
4129
    {
4130
        if (api_is_platform_admin() || api_is_session_admin()) {
4131
            return true;
4132
        }
4133
4134
        return false;
4135
    }
4136
4137
    /**
4138
     * @param $id
4139
     * @return bool
4140
     */
4141
    public static function protect_teacher_session_edit($id)
4142
    {
4143
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4144
            api_not_allowed(true);
4145
        } else {
4146
            return true;
4147
        }
4148
    }
4149
4150
    /**
4151
     * @param int $courseId
4152
     * @return array
4153
     */
4154
    public static function get_session_by_course($courseId)
4155
    {
4156
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4157
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4158
        $courseId = intval($courseId);
4159
        $sql = "SELECT name, s.id
4160
                FROM $table_session_course sc
4161
                INNER JOIN $table_session s ON (sc.session_id = s.id)
4162
                WHERE sc.c_id = '$courseId' ";
4163
        $result = Database::query($sql);
4164
4165
        return Database::store_result($result);
4166
    }
4167
4168
    /**
4169
     * @param int $user_id
4170
     * @param bool $ignoreVisibilityForAdmins
4171
     * @param bool $ignoreTimeLimit
4172
     *
4173
     * @return array
4174
     */
4175
    public static function get_sessions_by_user($user_id, $ignoreVisibilityForAdmins = false, $ignoreTimeLimit = false)
4176
    {
4177
        $sessionCategories = UserManager::get_sessions_by_category(
4178
            $user_id,
4179
            false,
4180
            $ignoreVisibilityForAdmins,
4181
            $ignoreTimeLimit
4182
        );
4183
4184
        $sessionArray = array();
4185
        if (!empty($sessionCategories)) {
4186
            foreach ($sessionCategories as $category) {
4187
                if (isset($category['sessions'])) {
4188
                    foreach ($category['sessions'] as $session) {
4189
                        $sessionArray[] = $session;
4190
                    }
4191
                }
4192
            }
4193
        }
4194
4195
        return $sessionArray;
4196
    }
4197
4198
    /**
4199
     * @param string $file
4200
     * @param bool $updateSession options:
4201
     *  true: if the session exists it will be updated.
4202
     *  false: if session exists a new session will be created adding a counter session1, session2, etc
4203
     * @param int $defaultUserId
4204
     * @param mixed $logger
4205
     * @param array $extraFields convert a file row to an extra field. Example in CSV file there's a SessionID then it will
4206
     * converted to extra_external_session_id if you set this: array('SessionId' => 'extra_external_session_id')
4207
     * @param string $extraFieldId
4208
     * @param int $daysCoachAccessBeforeBeginning
4209
     * @param int $daysCoachAccessAfterBeginning
4210
     * @param int $sessionVisibility
4211
     * @param array $fieldsToAvoidUpdate
4212
     * @param bool $deleteUsersNotInList
4213
     * @param bool $updateCourseCoaches
4214
     * @param bool $sessionWithCoursesModifier
4215
     * @param int $showDescription
4216
     * @param array $teacherBackupList
4217
     * @param array $groupBackup
4218
     * @return array
4219
     */
4220
    public static function importCSV(
4221
        $file,
4222
        $updateSession,
4223
        $defaultUserId = null,
4224
        $logger = null,
4225
        $extraFields = array(),
4226
        $extraFieldId = null,
4227
        $daysCoachAccessBeforeBeginning = null,
4228
        $daysCoachAccessAfterBeginning = null,
4229
        $sessionVisibility = 1,
4230
        $fieldsToAvoidUpdate = array(),
4231
        $deleteUsersNotInList = false,
4232
        $updateCourseCoaches = false,
4233
        $sessionWithCoursesModifier = false,
4234
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
4235
        $removeAllTeachersFromCourse = true,
4236
        $showDescription = null,
4237
        &$teacherBackupList = array(),
4238
        &$groupBackup = array()
4239
    ) {
4240
        $content = file($file);
4241
4242
        $error_message = null;
4243
        $session_counter = 0;
4244
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
4245
4246
        $eol = PHP_EOL;
4247
        if (PHP_SAPI != 'cli') {
4248
            $eol = '<br />';
4249
        }
4250
4251
        $debug = false;
4252
        if (isset($logger)) {
4253
            $debug = true;
4254
        }
4255
4256
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
4257
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4258
        $tbl_session_course  = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4259
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4260
4261
        $sessions = array();
4262
4263
        if (!api_strstr($content[0], ';')) {
4264
            $error_message = get_lang('NotCSV');
4265
        } else {
4266
            $tag_names = array();
4267
4268
            foreach ($content as $key => $enreg) {
4269
                $enreg = explode(';', trim($enreg));
4270 View Code Duplication
                if ($key) {
4271
                    foreach ($tag_names as $tag_key => $tag_name) {
4272
                        if (isset($enreg[$tag_key])) {
4273
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
4274
                        }
4275
                    }
4276
                } else {
4277
                    foreach ($enreg as $tag_name) {
4278
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
4279
                    }
4280
                    if (!in_array('SessionName', $tag_names) ||
4281
                        !in_array('DateStart', $tag_names) ||
4282
                        !in_array('DateEnd', $tag_names)
4283
                    ) {
4284
                        $error_message = get_lang('NoNeededData');
4285
                        break;
4286
                    }
4287
                }
4288
            }
4289
4290
            $sessionList = array();
4291
            // Looping the sessions.
4292
            foreach ($sessions as $enreg) {
4293
                $user_counter = 0;
4294
                $course_counter = 0;
4295
4296
                if (isset($extraFields) && !empty($extraFields)) {
4297
                    foreach ($extraFields as $original => $to) {
4298
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
4299
                    }
4300
                }
4301
4302
                $session_name = $enreg['SessionName'];
4303
                // Default visibility
4304
                $visibilityAfterExpirationPerSession = $sessionVisibility;
4305
4306
                if (isset($enreg['VisibilityAfterExpiration'])) {
4307
                    $visibility = $enreg['VisibilityAfterExpiration'];
4308
                    switch ($visibility) {
4309
                        case 'read_only':
4310
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
4311
                            break;
4312
                        case 'accessible':
4313
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
4314
                            break;
4315
                        case 'not_accessible':
4316
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
4317
                            break;
4318
                    }
4319
                }
4320
4321
                if (empty($session_name)) {
4322
                    continue;
4323
                }
4324
4325
                // We assume the dates are already in UTC
4326
                $dateStart = explode('/', $enreg['DateStart']);
4327
                $dateEnd = explode('/', $enreg['DateEnd']);
4328
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
4329
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
4330
4331
                $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
4332
                $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
4333
4334
                $extraParameters = null;
4335
                if (!is_null($showDescription)) {
4336
                    $extraParameters .= ' , show_description = '.intval($showDescription);
4337
                }
4338
4339
                $coachBefore = '';
4340
                $coachAfter = '';
4341
4342
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
4343
                    $date = new \DateTime($dateStart);
4344
                    $interval = new DateInterval(
4345
                        'P'.$daysCoachAccessBeforeBeginning.'D'
4346
                    );
4347
                    $date->sub($interval);
4348
                    $coachBefore = $date->format('Y-m-d h:i');
4349
                    $coachBefore = api_get_utc_datetime($coachBefore);
4350
4351
                    $extraParameters .= " , coach_access_start_date = '$coachBefore'";
4352
4353
                    $date = new \DateTime($dateEnd);
4354
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
4355
                    $date->add($interval);
4356
                    $coachAfter = $date->format('Y-m-d h:i');
4357
4358
                    $coachAfter = api_get_utc_datetime($coachAfter);
4359
                    $extraParameters .= " , coach_access_end_date = '$coachAfter'";
4360
                }
4361
4362
                $dateStart = api_get_utc_datetime($dateStart);
4363
                $dateEnd = api_get_utc_datetime($dateEnd);
4364
4365
                $extraSessionParameters = null;
4366
                if (!empty($sessionDescription)) {
4367
                    $extraSessionParameters = " , description = '".Database::escape_string($sessionDescription)."'";
4368
                }
4369
4370
                $sessionCondition = '';
4371
                if (!empty($session_category_id)) {
4372
                    $sessionCondition = " , session_category_id = '$session_category_id' ";
4373
                }
4374
4375
                // Searching a general coach.
4376
                if (!empty($enreg['Coach'])) {
4377
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
4378
                    if ($coach_id === false) {
4379
                        // If the coach-user does not exist - I'm the coach.
4380
                        $coach_id = $defaultUserId;
4381
                    }
4382
                } else {
4383
                    $coach_id = $defaultUserId;
4384
                }
4385
4386
                if (!$updateSession) {
4387
                    // Always create a session.
4388
                    $unique_name = false;
4389
                    $i = 0;
4390
                    // Change session name, verify that session doesn't exist.
4391
                    $suffix = null;
4392 View Code Duplication
                    while (!$unique_name) {
4393
                        if ($i > 1) {
4394
                            $suffix = ' - ' . $i;
4395
                        }
4396
                        $sql = 'SELECT 1 FROM ' . $tbl_session . '
4397
                                WHERE name="' . Database::escape_string($session_name). $suffix . '"';
4398
                        $rs = Database::query($sql);
4399
4400
                        if (Database::result($rs, 0, 0)) {
4401
                            $i++;
4402
                        } else {
4403
                            $unique_name = true;
4404
                            $session_name .= $suffix;
4405
                        }
4406
                    }
4407
4408
                    // Creating the session.
4409
                    $sql = "INSERT IGNORE INTO $tbl_session SET
4410
                            name = '" . Database::escape_string($session_name). "',
4411
                            id_coach = '$coach_id',
4412
                            access_start_date = '$dateStart',
4413
                            access_end_date = '$dateEnd',
4414
                            display_start_date = '$dateStart',
4415
                            display_end_date = '$dateEnd',
4416
                            visibility = '$visibilityAfterExpirationPerSession',                            
4417
                            session_admin_id = " . $defaultUserId . " 
4418
                            $sessionCondition $extraParameters $extraSessionParameters";
4419
                    Database::query($sql);
4420
4421
                    $session_id = Database::insert_id();
4422
                    if ($debug) {
4423
                        if ($session_id) {
4424 View Code Duplication
                            foreach ($enreg as $key => $value) {
4425
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4426
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4427
                                }
4428
                            }
4429
4430
                            $logger->addInfo("Sessions - Session created: #$session_id - $session_name");
4431
                        } else {
4432
                            $logger->addError("Sessions - Session NOT created: $session_name");
4433
                        }
4434
                    }
4435
                    $session_counter++;
4436
                } else {
4437
                    $sessionId = null;
4438
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
4439
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
4440
                        if (empty($sessionId)) {
4441
                            $my_session_result = false;
4442
                        } else {
4443
                            $my_session_result = true;
4444
                        }
4445
                    } else {
4446
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
4447
                    }
4448
4449
                    if ($my_session_result === false) {
4450
4451
                        // Creating a session.
4452
                        $sql = "INSERT IGNORE INTO $tbl_session SET
4453
                                name = '$session_name',
4454
                                id_coach = '$coach_id',
4455
                                access_start_date = '$dateStart',
4456
                                access_end_date = '$dateEnd',
4457
                                display_start_date = '$dateStart',
4458
                                display_end_date = '$dateEnd',
4459
                                visibility = '$visibilityAfterExpirationPerSession' 
4460
                                $extraParameters 
4461
                                $extraSessionParameters
4462
                                $sessionCondition
4463
                                ";
4464
4465
                        Database::query($sql);
4466
4467
                        // We get the last insert id.
4468
                        $my_session_result = SessionManager::get_session_by_name($enreg['SessionName']);
4469
                        $session_id = $my_session_result['id'];
4470
4471
                        if ($session_id) {
4472 View Code Duplication
                            foreach ($enreg as $key => $value) {
4473
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4474
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4475
                                }
4476
                            }
4477
                            if ($debug) {
4478
                                $logger->addInfo("Sessions - #$session_id created: $session_name");
4479
                            }
4480
4481
                            // Delete session-user relation only for students
4482
                            $sql = "DELETE FROM $tbl_session_user
4483
                                    WHERE session_id = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
4484
                            Database::query($sql);
4485
4486
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
4487
                            Database::query($sql);
4488
4489
                            // Delete session-course-user relationships students and coaches.
4490 View Code Duplication
                            if ($updateCourseCoaches) {
4491
                                $sql = "DELETE FROM $tbl_session_course_user
4492
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
4493
                                Database::query($sql);
4494
                            } else {
4495
                                // Delete session-course-user relation ships *only* for students.
4496
                                $sql = "DELETE FROM $tbl_session_course_user
4497
                                        WHERE session_id = '$session_id' AND status <> 2";
4498
                                Database::query($sql);
4499
                            }
4500
                        }
4501
                    } else {
4502
                        // Updating the session.
4503
                        $params = array(
4504
                            'id_coach' => $coach_id,
4505
                            'access_start_date' => $dateStart,
4506
                            'access_end_date' => $dateEnd,
4507
                            'display_start_date' => $dateStart,
4508
                            'display_end_date' => $dateEnd,
4509
                            'visibility' => $visibilityAfterExpirationPerSession,
4510
                            'session_category_id' => $session_category_id
4511
                        );
4512
4513
                        if (!empty($sessionDescription)) {
4514
                            $params['description'] = $sessionDescription;
4515
                        }
4516
4517
                        if (!empty($fieldsToAvoidUpdate)) {
4518
                            foreach ($fieldsToAvoidUpdate as $field) {
4519
                                unset($params[$field]);
4520
                            }
4521
                        }
4522
4523
                        if (isset($sessionId) && !empty($sessionId)) {
4524
                            $session_id = $sessionId;
4525
                            if (!empty($enreg['SessionName'])) {
4526
                                ///$params['name'] = $enreg['SessionName'];
4527
                                $sessionName = Database::escape_string($enreg['SessionName']);
4528
                                $sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
4529
                                Database::query($sql);
4530
                            }
4531
                        } else {
4532
                            $my_session_result = SessionManager::get_session_by_name($session_name);
4533
                            $session_id = $my_session_result['id'];
4534
                        }
4535
4536
                        if ($debug) {
4537
                            $logger->addError("Sessions - Session #$session_id to be updated: '$session_name'");
4538
                        }
4539
4540
                        if ($session_id) {
4541
                            if ($debug) {
4542
                                $logger->addError("Sessions - Session to be updated #$session_id");
4543
                            }
4544
4545
                            $sessionInfo = api_get_session_info($session_id);
4546
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
4547
4548
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
4549 View Code Duplication
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
4550
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
4551
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
4552
                                ) {
4553
                                    $params['coach_access_start_date'] = $coachBefore;
4554
                                }
4555
4556 View Code Duplication
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
4557
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
4558
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
4559
                                ) {
4560
                                    $params['coach_access_end_date'] = $coachAfter;
4561
                                }
4562
                            }
4563
4564
                            Database::update($tbl_session, $params, array('id = ?' => $session_id));
4565
4566 View Code Duplication
                            foreach ($enreg as $key => $value) {
4567
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
4568
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
4569
                                }
4570
                            }
4571
4572
                            // Delete session-user relation only for students
4573
                            $sql = "DELETE FROM $tbl_session_user
4574
                                    WHERE session_id = '$session_id' AND relation_type <> " . SESSION_RELATION_TYPE_RRHH;
4575
                            Database::query($sql);
4576
4577
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
4578
                            Database::query($sql);
4579
4580
                            // Delete session-course-user relationships students and coaches.
4581 View Code Duplication
                            if ($updateCourseCoaches) {
4582
                                $sql = "DELETE FROM $tbl_session_course_user
4583
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
4584
                                Database::query($sql);
4585
                            } else {
4586
                                // Delete session-course-user relation ships *only* for students.
4587
                                $sql = "DELETE FROM $tbl_session_course_user
4588
                                        WHERE session_id = '$session_id' AND status <> 2";
4589
                                Database::query($sql);
4590
                            }
4591
                        } else {
4592
                            if ($debug) {
4593
                                $logger->addError(
4594
                                    "Sessions - Session not found"
4595
                                );
4596
                            }
4597
                        }
4598
                    }
4599
                    $session_counter++;
4600
                }
4601
4602
                $sessionList[] = $session_id;
4603
                $users = explode('|', $enreg['Users']);
4604
4605
                // Adding the relationship "Session - User" for students
4606
                $userList = array();
4607
4608
                if (is_array($users)) {
4609
                    foreach ($users as $user) {
4610
                        $user_id = UserManager::get_user_id_from_username($user);
4611
                        if ($user_id !== false) {
4612
                            $userList[] = $user_id;
4613
                            // Insert new users.
4614
                            $sql = "INSERT IGNORE INTO $tbl_session_user SET
4615
                                    user_id = '$user_id',
4616
                                    session_id = '$session_id',
4617
                                    registered_at = '" . api_get_utc_datetime() . "'";
4618
                            Database::query($sql);
4619
                            if ($debug) {
4620
                                $logger->addInfo("Sessions - Adding User #$user_id ($user) to session #$session_id");
4621
                            }
4622
                            $user_counter++;
4623
                        }
4624
                    }
4625
                }
4626
4627
                if ($deleteUsersNotInList) {
4628
                    // Getting user in DB in order to compare to the new list.
4629
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
4630
4631
                    if (!empty($usersListInDatabase)) {
4632
                        if (empty($userList)) {
4633
                            foreach ($usersListInDatabase as $userInfo) {
0 ignored issues
show
Bug introduced by
The expression $usersListInDatabase 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...
4634
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
4635
                            }
4636
                        } else {
4637
                            foreach ($usersListInDatabase as $userInfo) {
0 ignored issues
show
Bug introduced by
The expression $usersListInDatabase 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...
4638
                                if (!in_array($userInfo['user_id'], $userList)) {
4639
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
4640
                                }
4641
                            }
4642
                        }
4643
                    }
4644
                }
4645
4646
                $courses = explode('|', $enreg['Courses']);
4647
4648
                // See BT#6449
4649
                $onlyAddFirstCoachOrTeacher = false;
4650
4651
                if ($sessionWithCoursesModifier) {
4652
                    if (count($courses) >= 2) {
4653
                        // Only first teacher in course session;
4654
                        $onlyAddFirstCoachOrTeacher = true;
4655
4656
                        // Remove all teachers from course.
4657
                        $removeAllTeachersFromCourse = false;
4658
                    }
4659
                }
4660
4661
                foreach ($courses as $course) {
4662
                    $courseArray = bracketsToArray($course);
4663
                    $course_code = $courseArray[0];
4664
4665
                    if (CourseManager::course_exists($course_code)) {
4666
4667
                        $courseInfo = api_get_course_info($course_code);
4668
                        $courseId = $courseInfo['real_id'];
4669
4670
                        // Adding the course to a session.
4671
                        $sql = "INSERT IGNORE INTO $tbl_session_course
4672
                                SET c_id = '$courseId', session_id='$session_id'";
4673
                        Database::query($sql);
4674
4675
                        SessionManager::installCourse($session_id, $courseInfo['real_id']);
4676
4677
                        if ($debug) {
4678
                            $logger->addInfo("Sessions - Adding course '$course_code' to session #$session_id");
4679
                        }
4680
4681
                        $course_counter++;
4682
4683
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
4684
                        $course_users   = isset($courseArray[2]) ? $courseArray[2] : null;
4685
4686
                        $course_users   = explode(',', $course_users);
4687
                        $course_coaches = explode(',', $course_coaches);
4688
4689
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
4690
                        $addTeachersToSession = true;
4691
4692
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
4693
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
4694
                        }
4695
4696
                        // If any user provided for a course, use the users array.
4697
                        if (empty($course_users)) {
4698
                            if (!empty($userList)) {
4699
                                SessionManager::subscribe_users_to_session_course(
4700
                                    $userList,
4701
                                    $session_id,
4702
                                    $course_code
4703
                                );
4704
                                if ($debug) {
4705
                                    $msg = "Sessions - Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
4706
                                    $logger->addInfo($msg);
4707
                                }
4708
                            }
4709
                        }
4710
4711
                        // Adding coaches to session course user.
4712
                        if (!empty($course_coaches)) {
4713
                            $savedCoaches = array();
4714
                            // only edit if add_teachers_to_sessions_courses is set.
4715
                            if ($addTeachersToSession) {
4716
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
4717
                                    // Adding course teachers as course session teachers.
4718
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
4719
                                        $course_code
4720
                                    );
4721
4722
                                    if (!empty($alreadyAddedTeachers)) {
4723
                                        $teachersToAdd = array();
4724
                                        foreach ($alreadyAddedTeachers as $user) {
4725
                                            $teachersToAdd[] = $user['username'];
4726
                                        }
4727
                                        $course_coaches = array_merge(
4728
                                            $course_coaches,
4729
                                            $teachersToAdd
4730
                                        );
4731
                                    }
4732
                                }
4733
4734 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
4735
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
4736
                                    if ($coach_id !== false) {
4737
                                        // Just insert new coaches
4738
                                        SessionManager::updateCoaches($session_id, $courseId, array($coach_id), false);
4739
4740
                                        if ($debug) {
4741
                                            $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
4742
                                        }
4743
                                        $savedCoaches[] = $coach_id;
4744
                                    } else {
4745
                                        $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
4746
                                    }
4747
                                }
4748
                            }
4749
4750
                            // Custom courses/session coaches
4751
                            $teacherToAdd = null;
4752
                            // Only one coach is added.
4753
                            if ($onlyAddFirstCoachOrTeacher == true) {
4754
4755 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
4756
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
4757
                                    if ($coach_id !== false) {
4758
                                        $teacherToAdd = $coach_id;
4759
                                        break;
4760
                                    }
4761
                                }
4762
4763
                                // Un subscribe everyone that's not in the list.
4764
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
4765 View Code Duplication
                                if (!empty($teacherList)) {
4766
                                    foreach ($teacherList as $teacher) {
4767
                                        if ($teacherToAdd != $teacher['user_id']) {
4768
4769
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
4770
                                                    WHERE
4771
                                                        user_id = ".$teacher['user_id']." AND
4772
                                                        course_code = '".$course_code."'
4773
                                                    ";
4774
4775
                                            $result = Database::query($sql);
4776
                                            $userCourseData = Database::fetch_array($result, 'ASSOC');
4777
                                            $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
4778
4779
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
4780
                                                    WHERE
4781
                                                        user_id = ".$teacher['user_id']." AND
4782
                                                        c_id = '".$courseInfo['real_id']."'
4783
                                                    ";
4784
4785
                                            $result = Database::query($sql);
4786
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
4787
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
4788
                                            }
4789
4790
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
4791
                                                    WHERE
4792
                                                        user_id = ".$teacher['user_id']." AND
4793
                                                        c_id = '".$courseInfo['real_id']."'
4794
                                                    ";
4795
4796
                                            $result = Database::query($sql);
4797
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
4798
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
4799
                                            }
4800
4801
                                            CourseManager::unsubscribe_user(
4802
                                                $teacher['user_id'],
4803
                                                $course_code
4804
                                            );
4805
                                        }
4806
                                    }
4807
                                }
4808
4809
                                if (!empty($teacherToAdd)) {
4810
                                    SessionManager::updateCoaches($session_id, $courseId, array($teacherToAdd), true);
4811
4812
                                    $userCourseCategory = '';
4813 View Code Duplication
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
4814
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
4815
                                    ) {
4816
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
4817
                                        $userCourseCategory = $courseUserData['user_course_cat'];
4818
                                    }
4819
4820
                                    CourseManager::subscribe_user(
4821
                                        $teacherToAdd,
4822
                                        $course_code,
4823
                                        COURSEMANAGER,
4824
                                        0,
4825
                                        $userCourseCategory
4826
                                    );
4827
4828 View Code Duplication
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
4829
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
4830
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
4831
                                    ) {
4832
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
4833
                                            GroupManager::subscribe_users(
4834
                                                $teacherToAdd,
4835
                                                $data['group_id'],
4836
                                                $data['c_id']
4837
                                            );
4838
                                        }
4839
                                    }
4840
4841 View Code Duplication
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
4842
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
4843
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
4844
                                    ) {
4845
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
4846
                                            GroupManager::subscribe_tutors(
4847
                                                $teacherToAdd,
4848
                                                $data['group_id'],
4849
                                                $data['c_id']
4850
                                            );
4851
                                        }
4852
                                    }
4853
                                }
4854
                            }
4855
4856
                            // See BT#6449#note-195
4857
                            // All coaches are added.
4858
                            if ($removeAllTeachersFromCourse) {
4859
                                $teacherToAdd = null;
4860 View Code Duplication
                                foreach ($course_coaches as $course_coach) {
4861
                                    $coach_id = UserManager::get_user_id_from_username(
4862
                                        $course_coach
4863
                                    );
4864
                                    if ($coach_id !== false) {
4865
                                        $teacherToAdd[] = $coach_id;
4866
                                    }
4867
                                }
4868
4869
                                if (!empty($teacherToAdd)) {
4870
                                    // Deleting all course teachers and adding the only coach as teacher.
4871
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
4872
4873 View Code Duplication
                                    if (!empty($teacherList)) {
4874
                                        foreach ($teacherList as $teacher) {
4875
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
4876
4877
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
4878
                                                        WHERE
4879
                                                            user_id = ".$teacher['user_id']." AND
4880
                                                            course_code = '".$course_code."'
4881
                                                        ";
4882
4883
                                                $result = Database::query($sql);
4884
                                                $userCourseData = Database::fetch_array($result, 'ASSOC');
4885
                                                $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
4886
4887
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
4888
                                                    WHERE
4889
                                                        user_id = ".$teacher['user_id']." AND
4890
                                                        c_id = '".$courseInfo['real_id']."'
4891
                                                    ";
4892
4893
                                                $result = Database::query($sql);
4894
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
4895
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
4896
                                                }
4897
4898
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
4899
                                                        WHERE
4900
                                                            user_id = ".$teacher['user_id']." AND
4901
                                                            c_id = '".$courseInfo['real_id']."'
4902
                                                        ";
4903
4904
                                                $result = Database::query($sql);
4905
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
4906
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
4907
                                                }
4908
4909
                                                CourseManager::unsubscribe_user(
4910
                                                    $teacher['user_id'],
4911
                                                    $course_code
4912
                                                );
4913
                                            }
4914
                                        }
4915
                                    }
4916
4917
                                    foreach ($teacherToAdd as $teacherId) {
4918
                                        $userCourseCategory = '';
4919 View Code Duplication
                                        if (isset($teacherBackupList[$teacherId]) &&
4920
                                            isset($teacherBackupList[$teacherId][$course_code])
4921
                                        ) {
4922
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
4923
                                            $userCourseCategory = $courseUserData['user_course_cat'];
4924
                                        }
4925
4926
                                        CourseManager::subscribe_user(
4927
                                            $teacherId,
4928
                                            $course_code,
4929
                                            COURSEMANAGER,
4930
                                            0,
4931
                                            $userCourseCategory
4932
                                        );
4933
4934 View Code Duplication
                                        if (isset($groupBackup['user'][$teacherId]) &&
4935
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
4936
                                            !empty($groupBackup['user'][$teacherId][$course_code])
4937
                                        ) {
4938
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
4939
                                                GroupManager::subscribe_users(
4940
                                                    $teacherId,
4941
                                                    $data['group_id'],
4942
                                                    $data['c_id']
4943
                                                );
4944
                                            }
4945
                                        }
4946
4947 View Code Duplication
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
4948
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
4949
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
4950
                                        ) {
4951
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
4952
                                                GroupManager::subscribe_tutors(
4953
                                                    $teacherId,
4954
                                                    $data['group_id'],
4955
                                                    $data['c_id']
4956
                                                );
4957
                                            }
4958
                                        }
4959
                                    }
4960
                                }
4961
                            }
4962
4963
                            // Continue default behaviour.
4964
                            if ($onlyAddFirstCoachOrTeacher == false) {
4965
                                // Checking one more time see BT#6449#note-149
4966
                                $coaches = SessionManager::getCoachesByCourseSession($session_id, $courseId);
4967
                                // Update coaches if only there's 1 course see BT#6449#note-189
4968
                                if (empty($coaches) || count($courses) == 1) {
4969 View Code Duplication
                                    foreach ($course_coaches as $course_coach) {
4970
                                        $course_coach = trim($course_coach);
4971
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
4972
                                        if ($coach_id !== false) {
4973
                                            // Just insert new coaches
4974
                                            SessionManager::updateCoaches(
4975
                                                $session_id,
4976
                                                $courseId,
4977
                                                array($coach_id),
4978
                                                false
4979
                                            );
4980
4981
                                            if ($debug) {
4982
                                                $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
4983
                                            }
4984
                                            $savedCoaches[] = $coach_id;
4985
                                        } else {
4986
                                            $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
4987
                                        }
4988
                                    }
4989
                                }
4990
                            }
4991
                        }
4992
4993
                        // Adding Students, updating relationship "Session - Course - User".
4994
                        $course_users = array_filter($course_users);
4995
4996
                        if (!empty($course_users)) {
4997 View Code Duplication
                            foreach ($course_users as $user) {
4998
                                $user_id = UserManager::get_user_id_from_username($user);
4999
5000
                                if ($user_id !== false) {
5001
                                    SessionManager::subscribe_users_to_session_course(
5002
                                        array($user_id),
5003
                                        $session_id,
5004
                                        $course_code
5005
                                    );
5006
                                    if ($debug) {
5007
                                        $logger->addInfo("Sessions - Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
5008
                                    }
5009
                                } else {
5010
                                    $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
5011
                                }
5012
                            }
5013
                        }
5014
5015
                        $inserted_in_course[$course_code] = $courseInfo['title'];
5016
                    }
5017
                }
5018
                $access_url_id = api_get_current_access_url_id();
5019
                UrlManager::add_session_to_url($session_id, $access_url_id);
5020
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter' WHERE id = '$session_id'";
5021
                Database::query($sql);
5022
            }
5023
        }
5024
5025
        return array(
5026
            'error_message' => $error_message,
5027
            'session_counter' => $session_counter,
5028
            'session_list' => $sessionList,
5029
        );
5030
    }
5031
5032
    /**
5033
     * @param int $sessionId
5034
     * @param int $courseId
5035
     * @return array
5036
     */
5037 View Code Duplication
    public static function getCoachesByCourseSession($sessionId, $courseId)
5038
    {
5039
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5040
        $sessionId = intval($sessionId);
5041
        $courseId = intval($courseId);
5042
5043
        $sql = "SELECT user_id FROM $table
5044
                WHERE
5045
                    session_id = '$sessionId' AND
5046
                    c_id = '$courseId' AND
5047
                    status = 2";
5048
        $result = Database::query($sql);
5049
5050
        $coaches = array();
5051
        if (Database::num_rows($result) > 0) {
5052
            while ($row = Database::fetch_row($result)) {
5053
                $coaches[] = $row[0];
5054
            }
5055
        }
5056
5057
        return $coaches;
5058
    }
5059
5060
    /**
5061
     * @param int $sessionId
5062
     * @param int $courseId
5063
     * @return string
5064
     */
5065
    public static function getCoachesByCourseSessionToString(
5066
        $sessionId,
5067
        $courseId
5068
    ) {
5069
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
5070
        $list = array();
5071 View Code Duplication
        if (!empty($coaches)) {
5072
            foreach ($coaches as $coachId) {
5073
                $userInfo = api_get_user_info($coachId);
5074
                $list[] = api_get_person_name(
5075
                    $userInfo['firstname'],
5076
                    $userInfo['lastname']
5077
                );
5078
            }
5079
        }
5080
5081
        return array_to_string($list, CourseManager::USER_SEPARATOR);
5082
    }
5083
5084
    /**
5085
     * Get all coaches added in the session - course relationship
5086
     * @param int $sessionId
5087
     * @return array
5088
     */
5089
    public static function getCoachesBySession($sessionId)
5090
    {
5091
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5092
        $sessionId = intval($sessionId);
5093
5094
        $sql = "SELECT DISTINCT user_id
5095
                FROM $table
5096
                WHERE session_id = '$sessionId' AND status = 2";
5097
        $result = Database::query($sql);
5098
5099
        $coaches = array();
5100
        if (Database::num_rows($result) > 0) {
5101
            while ($row = Database::fetch_array($result)) {
5102
                $coaches[] = $row['user_id'];
5103
            }
5104
        }
5105
5106
        return $coaches;
5107
    }
5108
5109
    /**
5110
     * @param int $userId
5111
     * @return array
5112
     */
5113
    public static function getAllCoursesFromAllSessionFromDrh($userId)
5114
    {
5115
        $sessions = SessionManager::get_sessions_followed_by_drh($userId);
5116
        $coursesFromSession = array();
5117
        if (!empty($sessions)) {
5118
            foreach ($sessions as $session) {
5119
                $courseList = SessionManager::get_course_list_by_session_id($session['id']);
5120
                foreach ($courseList as $course) {
0 ignored issues
show
Bug introduced by
The expression $courseList of type integer|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...
5121
                    $coursesFromSession[] = $course['code'];
5122
                }
5123
            }
5124
        }
5125
        return $coursesFromSession;
5126
    }
5127
5128
    /**
5129
     * @param string $status
5130
     * @param int $userId
5131
     * @param bool $getCount
5132
     * @param int  $from
5133
     * @param int  $numberItems
5134
     * @param int $column
5135
     * @param string $direction
5136
     * @param string $keyword
5137
     * @param string $active
5138
     * @param string $lastConnectionDate
5139
     * @param array $sessionIdList
5140
     * @param array $studentIdList
5141
     * @param int $filterByStatus
5142
     * @return array|int
5143
     */
5144
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
5145
        $status,
5146
        $userId,
5147
        $getCount = false,
5148
        $from = null,
5149
        $numberItems = null,
5150
        $column = 1,
5151
        $direction = 'asc',
5152
        $keyword = null,
5153
        $active = null,
5154
        $lastConnectionDate = null,
5155
        $sessionIdList = array(),
5156
        $studentIdList = array(),
5157
        $filterByStatus = null
5158
    ) {
5159
        $filterByStatus = intval($filterByStatus);
5160
5161
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
5162
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5163
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
5164
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5165
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
5166
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
5167
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5168
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
5169
5170
        $direction = in_array(strtolower($direction), array('asc', 'desc')) ? $direction : 'asc';
5171
        $column = Database::escape_string($column);
5172
        $userId = intval($userId);
5173
5174
        $limitCondition = null;
5175
5176 View Code Duplication
        if (isset($from) && isset($numberItems)) {
5177
            $from = intval($from);
5178
            $numberItems = intval($numberItems);
5179
            $limitCondition = "LIMIT $from, $numberItems";
5180
        }
5181
5182
        $urlId = api_get_current_access_url_id();
5183
5184
        $sessionConditions = null;
5185
        $courseConditions = null;
5186
        $userConditions = null;
5187
5188
        if (isset($active)) {
5189
            $active = intval($active);
5190
            $userConditions .= " AND active = $active";
5191
        }
5192
5193
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
5194
        $courseConditions = ' AND 1 <> 1';
5195
        if (!empty($courseList)) {
5196
            $courseIdList = array_column($courseList, 'id');
5197
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
5198
        }
5199
5200
        $userConditionsFromDrh = '';
5201
5202
        // Classic DRH
5203
        if (empty($studentIdList)) {
5204
            $studentListSql = UserManager::get_users_followed_by_drh(
5205
                $userId,
5206
                $filterByStatus,
5207
                true,
5208
                false
5209
            );
5210
            $studentIdList = array_keys($studentListSql);
5211
            $studentListSql = "'".implode("','", $studentIdList)."'";
5212
        } else {
5213
            $studentIdList = array_map('intval', $studentIdList);
5214
            $studentListSql = "'".implode("','", $studentIdList)."'";
5215
        }
5216
        if (!empty($studentListSql)) {
5217
            $userConditionsFromDrh = " AND u.user_id IN (".$studentListSql.") ";
5218
        }
5219
5220
        switch ($status) {
5221
            case 'drh':
5222
                break;
5223
            case 'drh_all':
5224
                // Show all by DRH
5225
                if (empty($sessionIdList)) {
5226
                    $sessionsListSql = SessionManager::get_sessions_followed_by_drh(
5227
                        $userId,
5228
                        null,
5229
                        null,
5230
                        false,
5231
                        true,
5232
                        true
5233
                    );
5234
                } else {
5235
                    $sessionIdList = array_map('intval', $sessionIdList);
5236
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
5237
                }
5238
                if (!empty($sessionsListSql)) {
5239
                    $sessionConditions = " AND s.id IN (".$sessionsListSql.") ";
5240
                }
5241
                break;
5242
            case 'session_admin':
5243
                $sessionConditions = " AND s.id_coach = $userId ";
5244
                $userConditionsFromDrh = '';
5245
                break;
5246
            case 'admin':
5247
                break;
5248
            case 'teacher':
5249
                $sessionConditions = " AND s.id_coach = $userId ";
5250
                $userConditionsFromDrh = '';
5251
                break;
5252
        }
5253
5254
        $select = "SELECT DISTINCT u.* ";
5255
        $masterSelect = "SELECT DISTINCT * FROM ";
5256
5257
        if ($getCount) {
5258
            $select = "SELECT DISTINCT u.user_id ";
5259
            $masterSelect = "SELECT COUNT(DISTINCT(user_id)) as count FROM ";
5260
        }
5261
5262
        if (!empty($filterByStatus)) {
5263
            $userConditions .= " AND u.status = ".$filterByStatus;
5264
        }
5265
5266
        if (!empty($lastConnectionDate)) {
5267
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
5268
            $userConditions .=  " AND u.last_login <= '$lastConnectionDate' ";
5269
        }
5270
5271 View Code Duplication
        if (!empty($keyword)) {
5272
            $keyword = Database::escape_string($keyword);
5273
            $userConditions .= " AND (
5274
                u.username LIKE '%$keyword%' OR
5275
                u.firstname LIKE '%$keyword%' OR
5276
                u.lastname LIKE '%$keyword%' OR
5277
                u.official_code LIKE '%$keyword%' OR
5278
                u.email LIKE '%$keyword%'
5279
            )";
5280
        }
5281
5282
        $where = " WHERE
5283
                   access_url_id = $urlId
5284
                   $userConditions
5285
        ";
5286
5287
        $userUnion = '';
5288
        if (!empty($userConditionsFromDrh)) {
5289
            $userUnion = "
5290
            UNION (
5291
                $select                    
5292
                FROM $tbl_user u
5293
                INNER JOIN $tbl_user_rel_access_url url ON (url.user_id = u.id)
5294
                $where
5295
                $userConditionsFromDrh
5296
            )";
5297
        }
5298
5299
        $sql = "$masterSelect (
5300
                ($select
5301
                FROM $tbl_session s
5302
                    INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.session_id)
5303
                    INNER JOIN $tbl_user u ON (u.user_id = su.user_id)
5304
                    INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
5305
                    $where
5306
                    $sessionConditions
5307
                ) UNION (
5308
                    $select
5309
                    FROM $tbl_course c
5310
                    INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
5311
                    INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
5312
                    INNER JOIN $tbl_course_rel_access_url url ON (url.c_id = c.id)
5313
                    $where
5314
                    $courseConditions
5315
                ) $userUnion
5316
                ) as t1
5317
                ";
5318
5319
        if ($getCount) {
5320
            $result = Database::query($sql);
5321
            $count = 0;
5322
            if (Database::num_rows($result)) {
5323
                $rows = Database::fetch_array($result);
5324
                $count = $rows['count'];
5325
            }
5326
            return $count;
5327
        }
5328
5329 View Code Duplication
        if (!empty($column) && !empty($direction)) {
5330
            $column = str_replace('u.', '', $column);
5331
            $sql .= " ORDER BY $column $direction ";
5332
        }
5333
5334
        $sql .= $limitCondition;
5335
        $result = Database::query($sql);
5336
        $result = Database::store_result($result);
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
5337
5338
        return $result ;
5339
    }
5340
5341
    /**
5342
     * @param int $sessionId
5343
     * @param int $courseId
5344
     * @param array $coachList
5345
     * @param bool $deleteCoachesNotInList
5346
     */
5347
    public static function updateCoaches(
5348
        $sessionId,
5349
        $courseId,
5350
        $coachList,
5351
        $deleteCoachesNotInList = false
5352
    ) {
5353
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
5354
5355
        if (!empty($coachList)) {
5356
            foreach ($coachList as $userId) {
5357
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
5358
            }
5359
        }
5360
5361
        if ($deleteCoachesNotInList) {
5362
            if (!empty($coachList)) {
5363
                $coachesToDelete = array_diff($currentCoaches, $coachList);
5364
            } else {
5365
                $coachesToDelete = $currentCoaches;
5366
            }
5367
5368
            if (!empty($coachesToDelete)) {
5369
                foreach ($coachesToDelete as $userId) {
5370
                    self::set_coach_to_course_session(
5371
                        $userId,
5372
                        $sessionId,
5373
                        $courseId,
5374
                        true
5375
                    );
5376
                }
5377
            }
5378
        }
5379
    }
5380
5381
    /**
5382
     * @param array $sessions
5383
     * @param array $sessionsDestination
5384
     * @return string
5385
     */
5386
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
5387
    {
5388
        $messages = array();
5389
        if (!empty($sessions)) {
5390
            foreach ($sessions as $sessionId) {
5391
                $sessionInfo = self::fetch($sessionId);
5392
                $userList = self::get_users_by_session($sessionId, 0);
5393
                if (!empty($userList)) {
5394
                    $newUserList = array();
5395
                    $userToString = null;
5396
                    foreach ($userList as $userInfo) {
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...
5397
                        $newUserList[] = $userInfo['user_id'];
5398
                        $userToString .= $userInfo['firstname'] . ' ' . $userInfo['lastname'] . '<br />';
5399
                    }
5400
5401
                    if (!empty($sessionsDestination)) {
5402
                        foreach ($sessionsDestination as $sessionDestinationId) {
5403
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
5404
                            $messages[] = Display::return_message(
5405
                                sprintf(get_lang('AddingStudentsFromSessionXToSessionY'), $sessionInfo['name'], $sessionDestinationInfo['name']), 'info', false
5406
                            );
5407
                            if ($sessionId == $sessionDestinationId) {
5408
                                $messages[] = Display::return_message(sprintf(get_lang('SessionXSkipped'), $sessionDestinationId), 'warning', false);
5409
                                continue;
5410
                            }
5411
                            $messages[] = Display::return_message(get_lang('StudentList') . '<br />' . $userToString, 'info', false);
5412
                            SessionManager::subscribe_users_to_session(
5413
                                $sessionDestinationId,
5414
                                $newUserList,
5415
                                SESSION_VISIBLE_READ_ONLY,
5416
                                false
5417
                            );
5418
                        }
5419
                    } else {
5420
                        $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
5421
                    }
5422
                } else {
5423
                    $messages[] = Display::return_message(
5424
                        get_lang('NoStudentsFoundForSession').' #'.$sessionInfo['name'],
5425
                        'warning'
5426
                    );
5427
                }
5428
            }
5429
        } else {
5430
            $messages[] = Display::return_message(get_lang('NoData'), 'warning');
5431
        }
5432
        return $messages;
5433
    }
5434
5435
    /**
5436
     * Assign coaches of a session(s) as teachers to a given course (or courses)
5437
     * @param array A list of session IDs
5438
     * @param array A list of course IDs
5439
     * @return string
5440
     */
5441
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
5442
    {
5443
        $coachesPerSession = array();
5444
        foreach ($sessions as $sessionId) {
5445
            $coaches = self::getCoachesBySession($sessionId);
5446
            $coachesPerSession[$sessionId] = $coaches;
5447
        }
5448
5449
        $result = array();
5450
5451
        if (!empty($courses)) {
5452
            foreach ($courses as $courseId) {
5453
                $courseInfo = api_get_course_info_by_id($courseId);
5454
                foreach ($coachesPerSession as $sessionId => $coachList) {
5455
                    CourseManager::updateTeachers(
5456
                        $courseInfo,
5457
                        $coachList,
5458
                        false,
5459
                        false,
5460
                        false
5461
                    );
5462
                    $result[$courseInfo['code']][$sessionId] = $coachList;
5463
                }
5464
            }
5465
        }
5466
        $sessionUrl = api_get_path(WEB_CODE_PATH) . 'admin/resume_session.php?id_session=';
5467
5468
        $htmlResult = null;
5469
5470
        if (!empty($result)) {
5471
            foreach ($result as $courseCode => $data) {
5472
                $url = api_get_course_url($courseCode);
5473
                $htmlResult .= sprintf(
5474
                    get_lang('CoachesSubscribedAsATeacherInCourseX'),
5475
                    Display::url($courseCode, $url, array('target' => '_blank'))
5476
                );
5477
                foreach ($data as $sessionId => $coachList) {
5478
                    $sessionInfo = self::fetch($sessionId);
5479
                    $htmlResult .= '<br />';
5480
                    $htmlResult .= Display::url(
5481
                        get_lang('Session') . ': ' . $sessionInfo['name'] . ' <br />', $sessionUrl . $sessionId, array('target' => '_blank')
5482
                    );
5483
                    $teacherList = array();
5484
                    foreach ($coachList as $coachId) {
5485
                        $userInfo = api_get_user_info($coachId);
5486
                        $teacherList[] = $userInfo['complete_name'];
5487
                    }
5488
                    if (!empty($teacherList)) {
5489
                        $htmlResult .= implode(', ', $teacherList);
5490
                    } else {
5491
                        $htmlResult .= get_lang('NothingToAdd');
5492
                    }
5493
                }
5494
                $htmlResult .= '<br />';
5495
            }
5496
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
5497
        }
5498
        return $htmlResult;
5499
    }
5500
5501
    /**
5502
     * @param string $keyword
5503
     * @param string $active
5504
     * @param string $lastConnectionDate
5505
     * @param array $sessionIdList
5506
     * @param array $studentIdList
5507
     * @param int $userStatus STUDENT|COURSEMANAGER constants
0 ignored issues
show
Documentation introduced by
There is no parameter named $userStatus. Did you maybe mean $filterUserStatus?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
5508
     *
5509
     * @return array|int
5510
     */
5511
    public static function getCountUserTracking(
5512
        $keyword = null,
5513
        $active = null,
5514
        $lastConnectionDate = null,
5515
        $sessionIdList = array(),
5516
        $studentIdList = array(),
5517
        $filterUserStatus = null
5518
    ) {
5519
        $userId = api_get_user_id();
5520
        $drhLoaded = false;
5521
5522
        if (api_is_drh()) {
5523
            if (api_drh_can_access_all_session_content()) {
5524
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
5525
                    'drh_all',
5526
                    $userId,
5527
                    true,
5528
                    null,
5529
                    null,
5530
                    null,
5531
                    null,
5532
                    $keyword,
5533
                    $active,
5534
                    $lastConnectionDate,
5535
                    $sessionIdList,
5536
                    $studentIdList,
5537
                    $filterUserStatus
5538
                );
5539
                $drhLoaded = true;
5540
            }
5541
        }
5542
5543
        if ($drhLoaded == false) {
5544
            $count = UserManager::getUsersFollowedByUser(
5545
                $userId,
5546
                $filterUserStatus,
5547
                false,
5548
                false,
5549
                true,
5550
                null,
5551
                null,
5552
                null,
5553
                null,
5554
                $active,
5555
                $lastConnectionDate,
5556
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
5557
                $keyword
5558
            );
5559
        }
5560
5561
        return $count;
5562
    }
5563
5564
    /**
5565
     * Get teachers followed by a user
5566
     * @param int $userId
5567
     * @param int $active
5568
     * @param string $lastConnectionDate
5569
     * @param bool $getCount
5570
     * @param array $sessionIdList
5571
     * @return array|int
5572
     */
5573
    public static function getTeacherTracking(
5574
        $userId,
5575
        $active = 1,
5576
        $lastConnectionDate = null,
5577
        $getCount = false,
5578
        $sessionIdList = array()
5579
    ) {
5580
        $teacherListId = array();
5581
5582
        if (api_is_drh() || api_is_platform_admin()) {
5583
            // Followed teachers by drh
5584
            if (api_drh_can_access_all_session_content()) {
5585
                if (empty($sessionIdList)) {
5586
                    $sessions = SessionManager::get_sessions_followed_by_drh($userId);
5587
                    $sessionIdList = array();
5588
                    foreach ($sessions as $session) {
5589
                        $sessionIdList[] = $session['id'];
5590
                    }
5591
                }
5592
5593
                $sessionIdList = array_map('intval', $sessionIdList);
5594
                $sessionToString = implode("', '",  $sessionIdList);
5595
5596
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
5597
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5598
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
5599
5600
                // Select the teachers.
5601
                $sql = "SELECT DISTINCT(cu.user_id) FROM $course c
5602
                        INNER JOIN $sessionCourse src ON c.id = src.c_id
5603
                        INNER JOIN $courseUser cu ON (cu.c_id = c.id)
5604
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
5605
                $result = Database::query($sql);
5606
                while($row = Database::fetch_array($result, 'ASSOC')) {
5607
                    $teacherListId[$row['user_id']] = $row['user_id'];
5608
                }
5609
            } else {
5610
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
5611
                foreach ($teacherResult as $userInfo) {
5612
                    $teacherListId[] = $userInfo['user_id'];
5613
                }
5614
            }
5615
        }
5616
5617
        if (!empty($teacherListId)) {
5618
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
5619
5620
            $select = "SELECT DISTINCT u.* ";
5621
            if ($getCount) {
5622
                $select = "SELECT count(DISTINCT(u.user_id)) as count";
5623
            }
5624
5625
            $sql = "$select FROM $tableUser u";
5626
5627
            if (!empty($lastConnectionDate)) {
5628
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
5629
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
5630
            }
5631
            $active = intval($active);
5632
            $teacherListId = implode("','", $teacherListId);
5633
            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
5634
5635
            if (!empty($lastConnectionDate)) {
5636
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
5637
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
5638
            }
5639
5640
            $sql .= $where;
5641
            $result = Database::query($sql);
5642
            if (Database::num_rows($result)) {
5643
                if ($getCount) {
5644
                    $row = Database::fetch_array($result);
5645
                    return $row['count'];
5646
                } else {
5647
5648
                    return Database::store_result($result, 'ASSOC');
5649
                }
5650
            }
5651
        }
5652
5653
        return 0;
5654
    }
5655
5656
    /**
5657
     * Get the list of course tools that have to be dealt with in case of
5658
     * registering any course to a session
5659
     * @return array The list of tools to be dealt with (literal names)
5660
     */
5661
    public static function getCourseToolToBeManaged()
5662
    {
5663
        return array(
5664
            'courseDescription',
5665
            'courseIntroduction',
5666
        );
5667
    }
5668
5669
    /**
5670
     * Calls the methods bound to each tool when a course is registered into a session
5671
     * @param int $sessionId
5672
     * @param int $courseId
5673
     * @return void
5674
     */
5675 View Code Duplication
    public static function installCourse($sessionId, $courseId)
5676
    {
5677
        return true;
5678
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
5679
5680
        foreach ($toolList as $tool) {
5681
            $method = 'add' . $tool;
5682
            if (method_exists(get_class(), $method)) {
5683
                self::$method($sessionId, $courseId);
5684
            }
5685
        }
5686
    }
5687
5688
    /**
5689
     * Calls the methods bound to each tool when a course is unregistered from
5690
     * a session
5691
     * @param int $sessionId
5692
     * @param int $courseId
5693
     */
5694 View Code Duplication
    public static function unInstallCourse($sessionId, $courseId)
5695
    {
5696
        return true;
5697
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged(); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
5698
5699
        foreach ($toolList as $tool) {
5700
            $method = 'remove' . $tool;
5701
            if (method_exists(get_class(), $method)) {
5702
                self::$method($sessionId, $courseId);
5703
            }
5704
        }
5705
    }
5706
5707
    /**
5708
     * @param int $sessionId
5709
     * @param int $courseId
5710
     */
5711
    public static function addCourseIntroduction($sessionId, $courseId)
5712
    {
5713
        // @todo create a tool intro lib
5714
        $sessionId = intval($sessionId);
5715
        $courseId = intval($courseId);
5716
5717
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
5718
        $sql = "SELECT * FROM $TBL_INTRODUCTION WHERE c_id = $courseId";
5719
        $result = Database::query($sql);
5720
        $result = Database::store_result($result, 'ASSOC');
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, store_result() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
5721
5722
        if (!empty($result)) {
5723
            foreach ($result as $result) {
5724
                // @todo check if relation exits.
5725
                $result['session_id'] = $sessionId;
5726
                Database::insert($TBL_INTRODUCTION, $result);
5727
            }
5728
        }
5729
    }
5730
5731
    /**
5732
     * @param int $sessionId
5733
     * @param int $courseId
5734
     */
5735
    public static function removeCourseIntroduction($sessionId, $courseId)
5736
    {
5737
        $sessionId = intval($sessionId);
5738
        $courseId = intval($courseId);
5739
        $TBL_INTRODUCTION = Database::get_course_table(TABLE_TOOL_INTRO);
5740
        $sql = "DELETE FROM $TBL_INTRODUCTION
5741
                WHERE c_id = $courseId AND session_id = $sessionId";
5742
        Database::query($sql);
5743
    }
5744
5745
    /**
5746
     * @param int $sessionId
5747
     * @param int $courseId
5748
     */
5749
    public static function addCourseDescription($sessionId, $courseId)
5750
    {
5751
        /* $description = new CourseDescription();
5752
          $descriptions = $description->get_descriptions($courseId);
5753
          foreach ($descriptions as $description) {
5754
          } */
5755
    }
5756
5757
    /**
5758
     * @param int $sessionId
5759
     * @param int $courseId
5760
     */
5761
    public static function removeCourseDescription($sessionId, $courseId)
5762
    {
5763
5764
    }
5765
5766
    /**
5767
     * @param array $userSessionList format see self::importSessionDrhCSV()
5768
     * @param bool $sendEmail
5769
     * @param bool $removeOldRelationShips
5770
     * @return string
5771
     */
5772
    public static function subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips)
5773
    {
5774
        if (!empty($userSessionList)) {
5775
            foreach ($userSessionList as $userId => $data) {
5776
                $sessionList = array();
5777
                foreach ($data['session_list'] as $sessionInfo) {
5778
                    $sessionList[] = $sessionInfo['session_id'];
5779
                }
5780
                $userInfo = $data['user_info'];
5781
                self::subscribeSessionsToDrh(
5782
                    $userInfo,
5783
                    $sessionList,
5784
                    $sendEmail,
5785
                    $removeOldRelationShips
5786
                );
5787
            }
5788
        }
5789
    }
5790
5791
    /**
5792
     * @param array $userSessionList format see self::importSessionDrhCSV()
5793
     *
5794
     * @return string
5795
     */
5796
    public static function checkSubscribeDrhToSessionList($userSessionList)
5797
    {
5798
        $message = null;
5799
        if (!empty($userSessionList)) {
5800
            if (!empty($userSessionList)) {
5801
                foreach ($userSessionList as $userId => $data) {
5802
                    $userInfo = $data['user_info'];
5803
5804
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
5805
                    if (!empty($sessionListSubscribed)) {
5806
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
5807
                    }
5808
5809
                    $sessionList = array();
5810
                    if (!empty($data['session_list'])) {
5811
                        foreach ($data['session_list'] as $sessionInfo) {
5812
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
5813
                                $sessionList[] = $sessionInfo['session_info']['name'];
5814
                            }
5815
                        }
5816
                    }
5817
5818
                    $message .= '<strong>' . get_lang('User') . '</strong> ' . $userInfo['complete_name'] . ' <br />';
5819
5820
                    if (!in_array($userInfo['status'], array(DRH)) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
5821
                        $message .= get_lang('UserMustHaveTheDrhRole') . '<br />';
5822
                        continue;
5823
                    }
5824
5825
                    if (!empty($sessionList)) {
5826
                        $message .= '<strong>' . get_lang('Sessions') . ':</strong> <br />';
5827
                        $message .= implode(', ', $sessionList) . '<br /><br />';
5828
                    } else {
5829
                        $message .= get_lang('NoSessionProvided') . ' <br /><br />';
5830
                    }
5831
                }
5832
            }
5833
        }
5834
5835
        return $message;
5836
    }
5837
5838
    /**
5839
     * @param string $file
5840
     * @param bool $sendEmail
5841
     * @param bool $removeOldRelationShips
5842
     *
5843
     * @return string
5844
     */
5845
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
5846
    {
5847
        $list = Import::csv_reader($file);
5848
5849
        if (!empty($list)) {
5850
            $userSessionList = array();
5851
            foreach ($list as $data) {
5852
                $userInfo = api_get_user_info_from_username($data['Username']);
5853
                $sessionInfo = self::get_session_by_name($data['SessionName']);
5854
5855
                if (!empty($userInfo) && !empty($sessionInfo)) {
5856
                    $userSessionList[$userInfo['user_id']]['session_list'][] = array(
5857
                        'session_id' => $sessionInfo['id'],
5858
                        'session_info' => $sessionInfo,
5859
                    );
5860
                    $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
5861
                }
5862
            }
5863
5864
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
5865
            return self::checkSubscribeDrhToSessionList($userSessionList);
5866
        }
5867
    }
5868
5869
    /**
5870
     * Courses re-ordering in resume_session.php flag see BT#8316
5871
     */
5872
    public static function orderCourseIsEnabled()
5873
    {
5874
        $sessionCourseOrder = api_get_setting('session_course_ordering');
5875
        if ($sessionCourseOrder === 'true') {
5876
            return true;
5877
        }
5878
5879
        return false;
5880
    }
5881
5882
    /**
5883
     * @param string $direction (up/down)
5884
     * @param int $sessionId
5885
     * @param int $courseId
5886
     * @return bool
5887
     */
5888
    public static function move($direction, $sessionId, $courseId)
5889
    {
5890
        if (!self::orderCourseIsEnabled()) {
5891
            return false;
5892
        }
5893
5894
        $sessionId = intval($sessionId);
5895
        $courseId = intval($courseId);
5896
5897
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5898
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
5899
5900
        $position = array();
5901
        $count = 0;
5902
        foreach ($courseList as $course) {
0 ignored issues
show
Bug introduced by
The expression $courseList of type integer|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...
5903
            if ($course['position'] == '') {
5904
                $course['position'] = $count;
5905
            }
5906
            $position[$course['code']] = $course['position'];
5907
            // Saving current order.
5908
            $sql = "UPDATE $table SET position = $count
5909
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
5910
            Database::query($sql);
5911
            $count++;
5912
        }
5913
5914
        // Loading new positions.
5915
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
5916
5917
        $found = false;
5918
5919
        switch ($direction) {
5920
            case 'up':
5921
                $courseList = array_reverse($courseList);
5922
                break;
5923
            case 'down':
5924
                break;
5925
        }
5926
5927
        foreach ($courseList as $course) {
0 ignored issues
show
Bug introduced by
The expression $courseList of type integer|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...
5928
            if ($found) {
5929
                $nextId = $course['real_id'];
5930
                $nextOrder = $course['position'];
5931
                break;
5932
            }
5933
5934
            if ($courseId == $course['real_id']) {
5935
                $thisCourseCode = $course['real_id'];
5936
                $thisOrder = $course['position'];
5937
                $found = true;
5938
            }
5939
        }
5940
5941
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
5942
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
5943
        Database::query($sql1);
5944
5945
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
5946
                 WHERE session_id = $sessionId AND c_id = $nextId";
5947
        Database::query($sql2);
5948
5949
        return true;
5950
    }
5951
5952
    /**
5953
     * @param int $sessionId
5954
     * @param int $courseId
5955
     * @return bool
5956
     */
5957
    public static function moveUp($sessionId, $courseId)
5958
    {
5959
        return self::move('up', $sessionId, $courseId);
5960
    }
5961
5962
    /**
5963
     * @param int $sessionId
5964
     * @param string $courseCode
5965
     * @return bool
5966
     */
5967
    public static function moveDown($sessionId, $courseCode)
5968
    {
5969
        return self::move('down', $sessionId, $courseCode);
5970
    }
5971
5972
    /**
5973
     * Use the session duration to allow/block user access see BT#8317
5974
     * Needs these DB changes
5975
     * ALTER TABLE session ADD COLUMN duration int;
5976
     * ALTER TABLE session_rel_user ADD COLUMN duration int;
5977
     */
5978
    public static function durationPerUserIsEnabled()
5979
    {
5980
        return api_get_configuration_value('session_duration_feature');
5981
    }
5982
5983
    /**
5984
     * Returns the number of days the student has left in a session when using
5985
     * sessions durations
5986
     * @param int $userId
5987
     * @param int $sessionId
5988
     * @param int $duration in days
5989
     * @return int
5990
     */
5991
    public static function getDayLeftInSession($sessionId, $userId, $duration)
5992
    {
5993
        // Get an array with the details of the first access of the student to
5994
        // this session
5995
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
5996
            $sessionId,
5997
            $userId
5998
        );
5999
6000
        $currentTime = time();
6001
6002
        // If no previous access, return false
6003
        if (count($courseAccess) == 0) {
6004
            return false;
6005
        }
6006
6007
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
6008
6009
        $endDateInSeconds = $firstAccess + $duration*24*60*60;
6010
        $leftDays = round(($endDateInSeconds- $currentTime) / 60 / 60 / 24);
6011
6012
        return $leftDays;
6013
    }
6014
6015
    /**
6016
     * @param int $duration
6017
     * @param int $userId
6018
     * @param int $sessionId
6019
     */
6020
    public static function editUserSessionDuration($duration, $userId, $sessionId)
6021
    {
6022
        $duration = intval($duration);
6023
        $userId = intval($userId);
6024
        $sessionId = intval($sessionId);
6025
6026
        if (empty($userId) || empty($sessionId)) {
6027
            return false;
6028
        }
6029
6030
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6031
        $parameters = array('duration' => $duration);
6032
        $where = array('session_id = ? AND user_id = ? ' => array($sessionId, $userId));
6033
        Database::update($table, $parameters, $where);
6034
    }
6035
6036
    /**
6037
     * Gets one row from the session_rel_user table
6038
     * @param int $userId
6039
     * @param int $sessionId
6040
     *
6041
     * @return array
6042
     */
6043 View Code Duplication
    public static function getUserSession($userId, $sessionId)
6044
    {
6045
        $userId = intval($userId);
6046
        $sessionId = intval($sessionId);
6047
6048
        if (empty($userId) || empty($sessionId)) {
6049
            return false;
6050
        }
6051
6052
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6053
        $sql = "SELECT * FROM $table
6054
                WHERE session_id = $sessionId AND user_id = $userId";
6055
        $result = Database::query($sql);
6056
        $values = array();
6057
        if (Database::num_rows($result)) {
6058
            $values = Database::fetch_array($result, 'ASSOC');
6059
        }
6060
6061
        return $values;
6062
    }
6063
6064
    /**
6065
     * Check if user is subscribed inside a session as student
6066
     * @param int $sessionId The session id
6067
     * @param int $userId The user id
6068
     * @return boolean Whether is subscribed
6069
     */
6070
    public static function isUserSubscribedAsStudent($sessionId, $userId)
6071
    {
6072
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6073
6074
        $sessionId = intval($sessionId);
6075
        $userId = intval($userId);
6076
6077
        // COUNT(1) actually returns the number of rows from the table (as if
6078
        // counting the results from the first column)
6079
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
6080
                WHERE
6081
                    session_id = $sessionId AND
6082
                    user_id = $userId AND
6083
                    relation_type = 0";
6084
6085
        $result = Database::fetch_assoc(Database::query($sql));
0 ignored issues
show
Bug introduced by
It seems like \Database::query($sql) can be null; however, fetch_assoc() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
6086
6087
        if (!empty($result) && $result['qty'] > 0) {
6088
            return true;
6089
        }
6090
6091
        return false;
6092
    }
6093
6094
    /**
6095
     * Get the session coached by a user (general coach and course-session coach)
6096
     * @param int $coachId The coach id
6097
     * @param boolean $checkSessionRelUserVisibility Check the session visibility
6098
     * @param boolean $asPlatformAdmin The user is a platform admin and we want all sessions
6099
     * @return array The session list
6100
     */
6101
    public static function getSessionsCoachedByUser($coachId, $checkSessionRelUserVisibility = false, $asPlatformAdmin = false)
6102
    {
6103
        // Get all sessions where $coachId is the general coach
6104
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
6105
        // Get all sessions where $coachId is the course - session coach
6106
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
6107
        $sessionsByCoach = array();
6108
        if (!empty($courseSessionList)) {
6109
            foreach ($courseSessionList as $userCourseSubscription) {
6110
                $session = $userCourseSubscription->getSession();
6111
                $sessionsByCoach[$session->getId()] = api_get_session_info(
6112
                    $session->getId()
6113
                );
6114
            }
6115
        }
6116
6117
        if (!empty($sessionsByCoach)) {
6118
            $sessions = array_merge($sessions, $sessionsByCoach);
6119
        }
6120
6121
        // Remove repeated sessions
6122
        if (!empty($sessions)) {
6123
            $cleanSessions = array();
6124
            foreach ($sessions as $session) {
6125
                $cleanSessions[$session['id']] = $session;
6126
            }
6127
            $sessions = $cleanSessions;
6128
        }
6129
6130
        if ($checkSessionRelUserVisibility) {
6131
            if (!empty($sessions)) {
6132
                $newSessions = array();
6133
                foreach ($sessions as $session) {
6134
                    $visibility = api_get_session_visibility($session['id']);
6135
                    if ($visibility == SESSION_INVISIBLE) {
6136
                        continue;
6137
                    }
6138
                    $newSessions[] = $session;
6139
                }
6140
                $sessions = $newSessions;
6141
            }
6142
        }
6143
6144
        return $sessions;
6145
    }
6146
6147
    /**
6148
     * Check if the course belongs to the session
6149
     * @param int $sessionId The session id
6150
     * @param string $courseCode The course code
6151
     *
6152
     * @return bool
6153
     */
6154
    public static function sessionHasCourse($sessionId, $courseCode)
6155
    {
6156
        $sessionId = intval($sessionId);
6157
        $courseCode = Database::escape_string($courseCode);
6158
6159
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
6160
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6161
6162
        $sql = "SELECT COUNT(1) AS qty
6163
                FROM $courseTable c
6164
                INNER JOIN $sessionRelCourseTable src
6165
                ON c.id = src.c_id
6166
                WHERE src.session_id = $sessionId
6167
                AND c.code = '$courseCode'  ";
6168
6169
        $result = Database::query($sql);
6170
6171
        if ($result !== false) {
6172
            $data = Database::fetch_assoc($result);
6173
6174
            if ($data['qty'] > 0) {
6175
                return true;
6176
            }
6177
        }
6178
6179
        return false;
6180
    }
6181
6182
    /**
6183
     * Get the list of course coaches
6184
     * @return array The list
6185
     */
6186
    public static function getAllCourseCoaches()
6187
    {
6188
        $coaches = array();
6189
6190
        $scuTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6191
        $userTable = Database::get_main_table(TABLE_MAIN_USER);
6192
6193
        $idResult = Database::select('DISTINCT user_id', $scuTable, array(
6194
            'where' => array(
6195
                'status = ?' => 2,
6196
            ),
6197
        ));
6198
6199
        if ($idResult != false) {
6200
            foreach ($idResult as $idData) {
6201
                $userResult = Database::select('user_id, lastname, firstname, username', $userTable, array(
6202
                    'where' => array(
6203
                        'user_id = ?' => $idData['user_id'],
6204
                    ),
6205
                ), 'first');
6206
6207
                if ($userResult != false) {
6208
                    $coaches[] = array(
6209
                        'id' => $userResult['user_id'],
6210
                        'lastname' => $userResult['lastname'],
6211
                        'firstname' => $userResult['firstname'],
6212
                        'username' => $userResult['username'],
6213
                        'completeName' => api_get_person_name(
6214
                            $userResult['firstname'],
6215
                            $userResult['lastname']
6216
                        ),
6217
                    );
6218
                }
6219
            }
6220
        }
6221
6222
        return $coaches;
6223
    }
6224
6225
    /**
6226
     * Calculate the total user time in the platform
6227
     * @param int $userId The user id
6228
     * @param string $from Optional. From date
6229
     * @param string $until Optional. Until date
6230
     * @return string The time (hh:mm:ss)
6231
     */
6232
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
6233
    {
6234
        $userId = intval($userId);
6235
6236
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6237
6238
        $whereConditions = array(
6239
            'login_user_id = ? ' => $userId,
6240
        );
6241
6242 View Code Duplication
        if (!empty($from) && !empty($until)) {
6243
            $whereConditions["AND (login_date >= '?' "] = $from;
6244
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
6245
        }
6246
6247
        $trackResult = Database::select(
6248
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
6249
            $trackLoginTable,
6250
            array(
6251
                'where' => $whereConditions,
6252
            ), 'first'
6253
        );
6254
6255
        if ($trackResult != false) {
6256
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
6257
        }
6258
6259
        return '00:00:00';
6260
    }
6261
6262
    /**
6263
     * Get the courses list by a course coach
6264
     * @param int $coachId The coach id
6265
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
6266
     */
6267
    public static function getCoursesListByCourseCoach($coachId)
6268
    {
6269
        $entityManager = Database::getManager();
6270
        $scuRepo = $entityManager->getRepository(
6271
            'ChamiloCoreBundle:SessionRelCourseRelUser'
6272
        );
6273
6274
        return $scuRepo->findBy([
6275
            'user' => $coachId,
6276
            'status' => SessionRelCourseRelUser::STATUS_COURSE_COACH
6277
        ]);
6278
    }
6279
6280
    /**
6281
     * Returns list of a few data from session (name, short description, start
6282
     * date, end date) and the given extra fields if defined based on a
6283
     * session category Id.
6284
     * @param int $categoryId The internal ID of the session category
6285
     * @param string $target Value to search for in the session field values
6286
     * @param array $extraFields A list of fields to be scanned and returned
6287
     * @return mixed
6288
     */
6289
    public static function getShortSessionListAndExtraByCategory(
6290
        $categoryId,
6291
        $target,
6292
        $extraFields = null,
6293
        $publicationDate = null
6294
    ) {
6295
        $categoryId = (int) $categoryId;
6296
        $sessionList = array();
6297
        // Check if categoryId is valid
6298
        if ($categoryId > 0) {
6299
            $target = Database::escape_string($target);
6300
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
6301
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6302
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6303
            // Join session field and session field values tables
6304
            $joinTable = $sfTable . ' sf INNER JOIN ' . $sfvTable . ' sfv ON sf.id = sfv.field_id';
6305
            $fieldsArray = array();
6306
            foreach ($extraFields as $field) {
0 ignored issues
show
Bug introduced by
The expression $extraFields of type array|null 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...
6307
                $fieldsArray[] = Database::escape_string($field);
6308
            }
6309
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6310
            if (isset ($publicationDate)) {
6311
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
6312
                $wherePublication = " AND id NOT IN (
6313
                    SELECT sfv.item_id FROM $joinTable
6314
                    WHERE
6315
                        sf.extra_field_type = $extraFieldType AND
6316
                        ((sf.variable = 'publication_start_date' AND sfv.value > '$publicationDateString' and sfv.value != '') OR
6317
                        (sf.variable = 'publication_end_date' AND sfv.value < '$publicationDateString' and sfv.value != ''))
6318
                )";
6319
            }
6320
            // Get the session list from session category and target
6321
            $sessionList = Database::select(
6322
                'id, name, access_start_date, access_end_date',
6323
                $sTable,
6324
                array(
6325
                    'where' => array(
6326
                        "session_category_id = ? AND id IN (
6327
                            SELECT sfv.item_id FROM $joinTable
6328
                            WHERE
6329
                                sf.extra_field_type = $extraFieldType AND
6330
                                sfv.item_id = session.id AND
6331
                                sf.variable = 'target' AND
6332
                                sfv.value = ?
6333
                        ) $wherePublication" => array($categoryId, $target),
6334
                    ),
6335
                )
6336
            );
6337
            $whereFieldVariables = array();
6338
            $whereFieldIds = array();
6339
            if (
6340
                is_array($fieldsArray) &&
6341
                count($fieldsArray) > 0
6342
            ) {
6343
                $whereParams = '?';
6344
                for ($i = 1; $i < count($fieldsArray); $i++) {
6345
                    $whereParams .= ', ?';
6346
                }
6347
                $whereFieldVariables = ' variable IN ( ' . $whereParams .' )';
6348
                $whereFieldIds = 'field_id IN ( ' . $whereParams .  ' )';
6349
            }
6350
            // Get session fields
6351
            $extraField = new ExtraFieldModel('session');
6352
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
6353
            $fieldsList = $extraField->get_all(array(
6354
                ' variable IN ( ' . $questionMarks . ' )' => $fieldsArray,
6355
            ));
6356
            // Index session fields
6357
            foreach ($fieldsList as $field) {
6358
                $fields[$field['id']] = $field['variable'];
6359
            }
6360
            // Get session field values
6361
            $extra = new ExtraFieldValue('session');
6362
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
6363
            $sessionFieldValueList = $extra->get_all(array ('where' => array('field_id IN ( ' . $questionMarksFields . ' )' => array_keys($fields))));
6364
            // Add session fields values to session list
6365
            foreach ($sessionList as $id => &$session) {
6366
                foreach ($sessionFieldValueList as $sessionFieldValue) {
6367
                    // Match session field values to session
6368
                    if ($sessionFieldValue['item_id'] == $id) {
6369
                        // Check if session field value is set in session field list
6370
                        if (isset($fields[$sessionFieldValue['field_id']])) {
6371
                            // Avoid overwriting the session's ID field
6372
                            if ($fields[$sessionFieldValue['field_id']] != 'id') {
6373
                                $var = $fields[$sessionFieldValue['field_id']];
6374
                                $val = $sessionFieldValue['value'];
6375
                                // Assign session field value to session
6376
                                $session[$var] = $val;
6377
                            }
6378
                        }
6379
                    }
6380
                }
6381
            }
6382
        }
6383
6384
        return $sessionList;
6385
    }
6386
6387
    /**
6388
     * Return the Session Category id searched by name
6389
     * @param string $categoryName Name attribute of session category used for search query
6390
     * @param bool $force boolean used to get even if something is wrong (e.g not unique name)
6391
     * @return int|array If success, return category id (int), else it will return an array
6392
     * with the next structure:
6393
     * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
6394
     */
6395
    public static function getSessionCategoryIdByName($categoryName, $force = false)
6396
    {
6397
        // Start error result
6398
        $errorResult = array('error' => true, 'errorMessage' => get_lang('ThereWasAnError'));
6399
        $categoryName = Database::escape_string($categoryName);
6400
        // Check if is not empty category name
6401
        if (!empty($categoryName)) {
6402
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
6403
            // Get all session category with same name
6404
            $result = Database::select(
6405
                'id',
6406
                $sessionCategoryTable,
6407
                array(
6408
                    'where' => array(
6409
                        'name = ?' => $categoryName,
6410
                    ),
6411
                )
6412
            );
6413
            // Check the result
6414
            if ($result < 1) {
6415
                // If not found any result, update error message
6416
                $errorResult['errorMessage'] = 'Not found any session category name ' . $categoryName;
6417
            } elseif (count($result) > 1 && !$force) {
6418
                // If found more than one result and force is disabled, update error message
6419
                $errorResult['errorMessage'] = 'Found many session categories';
6420
            } elseif (count($result) == 1 || $force) {
6421
                // If found just one session category or force option is enabled
6422
6423
                return key($result);
6424
            }
6425
        } else {
6426
            // category name is empty, update error message
6427
            $errorResult['errorMessage'] = 'Not valid category name';
6428
        }
6429
6430
        return $errorResult;
6431
    }
6432
6433
    /**
6434
     * Return all data from sessions (plus extra field, course and coach data) by category id
6435
     * @param int $sessionCategoryId session category id used to search sessions
6436
     * @return array If success, return session list and more session related data, else it will return an array
6437
     * with the next structure:
6438
     * array('error' => true, 'errorMessage' => ERROR_MESSAGE)
6439
     */
6440
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
6441
    {
6442
        // Start error result
6443
        $errorResult = array(
6444
            'error' => true,
6445
            'errorMessage' => get_lang('ThereWasAnError'),
6446
        );
6447
6448
        $sessionCategoryId = intval($sessionCategoryId);
6449
        // Check if session category id is valid
6450
        if ($sessionCategoryId > 0) {
6451
            // Get table names
6452
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
6453
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6454
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6455
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6456
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
6457
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
6458
6459
            // Get all data from all sessions whit the session category specified
6460
            $sessionList = Database::select(
6461
                '*',
6462
                $sessionTable,
6463
                array(
6464
                    'where' => array(
6465
                        'session_category_id = ?' => $sessionCategoryId,
6466
                    ),
6467
                )
6468
            );
6469
6470
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6471
6472
            // Check if session list query had result
6473
            if (!empty($sessionList)) {
6474
                // implode all session id
6475
                $sessionIdsString = '(' . implode(', ', array_keys($sessionList)) . ')';
6476
                // Get all field variables
6477
                $sessionFieldList = Database::select(
6478
                    'id, variable',
6479
                    $sessionFieldTable,
6480
                    array('extra_field_type = ? ' => array($extraFieldType))
6481
                );
6482
6483
                // Get all field values
6484
                $sql = "SELECT item_id, field_id, value FROM
6485
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
6486
                        ON (f.id = v.field_id)
6487
                        WHERE
6488
                            item_id IN $sessionIdsString AND
6489
                            extra_field_type = $extraFieldType
6490
                ";
6491
                $result = Database::query($sql);
6492
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
6493
6494
                // Check if session field values had result
6495
                if (!empty($sessionFieldValueList)) {
6496
                    $sessionFieldValueListBySession = array();
6497
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
6498
                        // Create an array to index ids to session id
6499
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
6500
                    }
6501
                }
6502
                // Query used to find course-coaches from sessions
6503
                $sql = "SELECT
6504
                            scu.session_id,
6505
                            c.id AS course_id,
6506
                            c.code AS course_code,
6507
                            c.title AS course_title,
6508
                            u.username AS coach_username,
6509
                            u.firstname AS coach_firstname,
6510
                            u.lastname AS coach_lastname
6511
                        FROM $courseTable c
6512
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
6513
                        INNER JOIN $userTable u ON scu.user_id = u.user_id
6514
                        WHERE scu.status = 2 AND scu.session_id IN $sessionIdsString
6515
                        ORDER BY scu.session_id ASC ";
6516
                $res = Database::query($sql);
6517
                $sessionCourseList = Database::store_result($res, 'ASSOC');
6518
                // Check if course list had result
6519
                if (!empty($sessionCourseList)) {
6520
                    foreach ($sessionCourseList as $key => $sessionCourse) {
6521
                        // Create an array to index ids to session_id
6522
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
6523
                    }
6524
                }
6525
                // Join lists
6526
                if (is_array($sessionList)) {
6527
                    foreach ($sessionList as $id => &$row) {
6528
                        if (
6529
                            !empty($sessionFieldValueListBySession) &&
6530
                            is_array($sessionFieldValueListBySession[$id])
6531
                        ) {
6532
                            // If have an index array for session extra fields, use it to join arrays
6533
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
6534
                                $row['extra'][$key] = array(
6535
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
6536
                                    'value' => $sessionFieldValueList[$key]['value'],
6537
                                );
6538
                            }
6539
                        }
6540
                        if (
6541
                            !empty($sessionCourseListBySession) &&
6542
                            is_array($sessionCourseListBySession[$id])
6543
                        ) {
6544
                            // If have an index array for session course coach, use it to join arrays
6545
                            foreach ($sessionCourseListBySession[$id] as $key) {
6546
                                $row['course'][$key] = array(
6547
                                    'course_id' => $sessionCourseList[$key]['course_id'],
6548
                                    'course_code' => $sessionCourseList[$key]['course_code'],
6549
                                    'course_title' => $sessionCourseList[$key]['course_title'],
6550
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
6551
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
6552
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
6553
                                );
6554
                            }
6555
                        }
6556
                    }
6557
                }
6558
6559
                return $sessionList;
6560
            } else {
6561
                // Not found result, update error message
6562
                $errorResult['errorMessage'] = 'Not found any session for session category id ' . $sessionCategoryId;
6563
            }
6564
        }
6565
6566
        return $errorResult;
6567
    }
6568
6569
    /**
6570
     * Return session description from session id
6571
     * @param int $sessionId
6572
     * @return string
6573
     */
6574
    public static function getDescriptionFromSessionId($sessionId)
6575
    {
6576
        // Init variables
6577
        $sessionId = intval($sessionId);
6578
        $description = '';
6579
        // Check if session id is valid
6580
        if ($sessionId > 0) {
6581
            // Select query from session id
6582
            $rows = Database::select(
6583
                'description',
6584
                Database::get_main_table(TABLE_MAIN_SESSION),
6585
                array(
6586
                    'where' => array(
6587
                        'id = ?' => $sessionId,
6588
                    ),
6589
                )
6590
            );
6591
6592
            // Check if select query result is not empty
6593
            if (!empty($rows)) {
6594
                // Get session description
6595
                $description = $rows[0]['description'];
6596
            }
6597
        }
6598
6599
        return $description;
6600
    }
6601
6602
    /**
6603
     * Get a session list filtered by name, description or any of the given extra fields
6604
     * @param string $term The term to search
6605
     * @param array $extraFieldsToInclude Extra fields to include in the session data
6606
     * @return array The list
6607
     */
6608
    public static function searchSession($term, $extraFieldsToInclude = array())
6609
    {
6610
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
6611
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
6612
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
6613
6614
        $term = Database::escape_string($term);
6615
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
6616
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
6617
            $resultData = Database::select('*', $sTable, array(
6618
                'where' => array(
6619
                    "name LIKE %?% " => $term,
6620
                    " OR description LIKE %?% " => $term,
6621
                    " OR id IN (
6622
                    SELECT item_id
6623
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
6624
                    ON (v.field_id = e.id)
6625
                    WHERE value LIKE %?% AND extra_field_type = $extraFieldType
6626
                ) " => $term,
6627
                ),
6628
            ));
6629
        } else {
6630
            $resultData = Database::select('*', $sTable, array(
6631
                'where' => array(
6632
                    "name LIKE %?% " => $term,
6633
                    "OR description LIKE %?% " => $term,
6634
                ),
6635
            ));
6636
6637
            return $resultData;
6638
        }
6639
6640
        foreach ($resultData as $id => &$session) {
6641
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
6642
        }
6643
6644
        return $resultData;
6645
    }
6646
6647
    /**
6648
     * @param $sessionId
6649
     * @param array $extraFieldsToInclude
6650
     * @return array
6651
     */
6652
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = array())
6653
    {
6654
        $extraData = array();
6655
6656
        $variables = array();
6657
        $variablePlaceHolders = array();
6658
6659
        foreach ($extraFieldsToInclude as $sessionExtraField) {
6660
            $variablePlaceHolders[] = "?";
6661
            $variables[] = Database::escape_string($sessionExtraField);
6662
        }
6663
6664
        $sessionExtraField = new ExtraFieldModel('session');
6665
        $fieldList = $sessionExtraField->get_all(array(
6666
            "variable IN ( " . implode(", ", $variablePlaceHolders) . " ) " => $variables,
6667
        ));
6668
6669
        $fields = array();
6670
6671
        // Index session fields
6672
        foreach ($fieldList as $field) {
6673
            $fields[$field['id']] = $field['variable'];
6674
        }
6675
6676
        // Get session field values
6677
        $extra = new ExtraFieldValue('session');
6678
        $sessionFieldValueList = $extra->get_all(
6679
            array(
6680
                "field_id IN ( " . implode(", ", $variablePlaceHolders) . " )" => array_keys($fields),
6681
            )
6682
        );
6683
6684
        foreach ($sessionFieldValueList as $sessionFieldValue) {
6685
            // Match session field values to session
6686
            if ($sessionFieldValue['item_id'] != $sessionId) {
6687
                continue;
6688
            }
6689
6690
            // Check if session field value is set in session field list
6691
            if (!isset($fields[$sessionFieldValue['field_id']])) {
6692
                continue;
6693
            }
6694
6695
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
6696
            $extrafieldValue = $sessionFieldValue['value'];
6697
6698
            $extraData[] = array(
6699
                'variable' => $extrafieldVariable,
6700
                'value' => $extrafieldValue,
6701
            );
6702
        }
6703
6704
        return $extraData;
6705
    }
6706
6707
    /**
6708
     * @param int $sessionId
6709
     *
6710
     * @return bool
6711
     */
6712
    public static function isValidId($sessionId)
6713
    {
6714
        $sessionId = intval($sessionId);
6715
        if ($sessionId > 0) {
6716
            $rows = Database::select(
6717
                'id',
6718
                Database::get_main_table(TABLE_MAIN_SESSION),
6719
                array('where' => array('id = ?' => $sessionId))
6720
            );
6721
            if (!empty($rows)) {
6722
6723
                return true;
6724
            }
6725
        }
6726
6727
        return false;
6728
    }
6729
6730
    /**
6731
     * Get list of sessions based on users of a group for a group admin
6732
     * @param int $userId The user id
6733
     * @return array
6734
     */
6735 View Code Duplication
    public static function getSessionsFollowedForGroupAdmin($userId)
6736
    {
6737
        $sessionList = array();
6738
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
6739
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6740
        $userGroup = new UserGroup();
6741
        $userIdList = $userGroup->getGroupUsersByUser($userId);
6742
6743
        if (empty($userIdList)) {
6744
            return [];
6745
        }
6746
6747
        $sql = "SELECT DISTINCT s.*
6748
                FROM $sessionTable s
6749
                INNER JOIN $sessionUserTable sru 
6750
                ON s.id = sru.id_session
6751
                WHERE
6752
                    (sru.id_user IN (" . implode(', ', $userIdList) . ")
6753
                    AND sru.relation_type = 0
6754
                )";
6755
6756
        if (api_is_multiple_url_enabled()) {
6757
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
6758
            $accessUrlId = api_get_current_access_url_id();
6759
6760
            if ($accessUrlId != -1) {
6761
                $sql = "SELECT DISTINCT s.*
6762
                        FROM $sessionTable s
6763
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
6764
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
6765
                        WHERE
6766
                            srau.access_url_id = $accessUrlId
6767
                            AND (
6768
                                sru.id_user IN (" . implode(', ', $userIdList) . ")
6769
                                AND sru.relation_type = 0
6770
                            )";
6771
            }
6772
        }
6773
6774
        $result = Database::query($sql);
6775
6776
        while ($row = Database::fetch_assoc($result)) {
6777
            $sessionList[] = $row;
6778
        }
6779
6780
        return $sessionList;
6781
    }
6782
6783
    /**
6784
     * @param array $sessionInfo
6785
     * @return string
6786
     */
6787
    public static function getSessionVisibility($sessionInfo)
6788
    {
6789
        switch ($sessionInfo['visibility']) {
6790
            case 1:
6791
                return get_lang('ReadOnly');
6792
            case 2:
6793
               return get_lang('Visible');
6794
            case 3:
6795
                return api_ucfirst(get_lang('Invisible'));
6796
        }
6797
    }
6798
6799
    /**
6800
     * Converts "start date" and "end date" to "From start date to end date" string
6801
     * @param string $startDate
6802
     * @param string $endDate
6803
     * @param bool $showTime
6804
     * @param bool $dateHuman
6805
     *
6806
     * @return string
6807
     */
6808
    private static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
6809
    {
6810
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
6811
        $startDateToLocal = api_get_local_time(
6812
            $startDate,
6813
            null,
6814
            null,
6815
            true,
6816
            $showTime,
6817
            $dateHuman
6818
        );
6819
        $endDateToLocal = api_get_local_time(
6820
            $endDate,
6821
            null,
6822
            null,
6823
            true,
6824
            $showTime,
6825
            $dateHuman
6826
        );
6827
6828
        $result = '';
6829
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
6830
            $result = sprintf(
6831
                get_lang('FromDateXToDateY'),
6832
                api_format_date($startDateToLocal, DATE_TIME_FORMAT_LONG_24H),
6833
                api_format_date($endDateToLocal, DATE_TIME_FORMAT_LONG_24H)
6834
            );
6835
        } else {
6836
            if (!empty($startDateToLocal)) {
6837
                $result = get_lang('From').' '.api_format_date($startDateToLocal, DATE_TIME_FORMAT_LONG_24H);
6838
            }
6839
            if (!empty($endDateToLocal)) {
6840
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, DATE_TIME_FORMAT_LONG_24H);
6841
            }
6842
        }
6843
        if (empty($result)) {
6844
            $result = get_lang('NoTimeLimits');
6845
        }
6846
6847
        return $result;
6848
    }
6849
6850
    /**
6851
     * Returns a human readable string
6852
     * @params array $sessionInfo An array with all the session dates
6853
     * @return string
6854
     */
6855
    public static function parseSessionDates($sessionInfo, $showTime = false)
6856
    {
6857
        $displayDates = self::convertSessionDateToString(
6858
            $sessionInfo['display_start_date'],
6859
            $sessionInfo['display_end_date'],
6860
            $showTime,
6861
            true
6862
        );
6863
        $accessDates = self::convertSessionDateToString(
6864
            $sessionInfo['access_start_date'],
6865
            $sessionInfo['access_end_date'],
6866
            $showTime,
6867
            true
6868
        );
6869
6870
        $coachDates = self::convertSessionDateToString(
6871
            $sessionInfo['coach_access_start_date'],
6872
            $sessionInfo['coach_access_end_date'],
6873
            $showTime,
6874
            true
6875
        );
6876
6877
        $result = [
6878
            'access' => $accessDates,
6879
            'display' => $displayDates,
6880
            'coach' => $coachDates
6881
        ];
6882
6883
        return $result;
6884
    }
6885
6886
    /**
6887
     * @param FormValidator $form
6888
     *
6889
     * @return array
6890
     */
6891
    public static function setForm(FormValidator & $form, $sessionId = 0)
6892
    {
6893
        $categoriesList = SessionManager::get_all_session_category();
6894
        $userInfo = api_get_user_info();
6895
6896
        $categoriesOptions = array(
6897
            '0' => get_lang('None')
6898
        );
6899
6900
        if ($categoriesList != false) {
6901
            foreach ($categoriesList as $categoryItem) {
6902
                $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
6903
            }
6904
        }
6905
6906
        // Database Table Definitions
6907
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
6908
6909
        $form->addElement('text', 'name', get_lang('SessionName'), array(
6910
            'maxlength' => 50,
6911
        ));
6912
        $form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
6913
        $form->addRule('name', get_lang('SessionNameAlreadyExists'), 'callback', 'check_session_name');
6914
6915
        if (!api_is_platform_admin() && api_is_teacher()) {
6916
            $form->addElement(
6917
                'select',
6918
                'coach_username',
6919
                get_lang('CoachName'),
6920
                [api_get_user_id() => $userInfo['complete_name']],
6921
                array(
6922
                    'id' => 'coach_username',
6923
                    'style' => 'width:370px;',
6924
                )
6925
            );
6926
        } else {
6927
6928
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE status = 1";
6929
            $rs = Database::query($sql);
6930
            $countUsers = Database::result($rs, 0, 0);
6931
6932
            if (intval($countUsers) < 50) {
6933
                $orderClause = "ORDER BY ";
6934
                $orderClause .= api_sort_by_first_name() ? "firstname, lastname, username" : "lastname, firstname, username";
6935
6936
                $sql = "SELECT user_id, lastname, firstname, username
6937
                        FROM $tbl_user
6938
                        WHERE status = '1' ".
6939
                        $orderClause;
6940
6941 View Code Duplication
                if (api_is_multiple_url_enabled()) {
6942
                    $userRelAccessUrlTable = Database::get_main_table(
6943
                        TABLE_MAIN_ACCESS_URL_REL_USER
6944
                    );
6945
                    $accessUrlId = api_get_current_access_url_id();
6946
6947
                    if ($accessUrlId != -1) {
6948
                        $sql = "SELECT user.user_id, username, lastname, firstname
6949
                        FROM $tbl_user user
6950
                        INNER JOIN $userRelAccessUrlTable url_user
6951
                        ON (url_user.user_id = user.user_id)
6952
                        WHERE
6953
                            access_url_id = $accessUrlId AND
6954
                            status = 1 "
6955
                            .$orderClause;
6956
                    }
6957
                }
6958
6959
                $result = Database::query($sql);
6960
                $coachesList = Database::store_result($result);
6961
6962
                $coachesOptions = array();
6963 View Code Duplication
                foreach ($coachesList as $coachItem) {
6964
                    $coachesOptions[$coachItem['user_id']] =
6965
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
6966
                }
6967
6968
                $form->addElement(
6969
                    'select',
6970
                    'coach_username',
6971
                    get_lang('CoachName'),
6972
                    $coachesOptions
6973
                );
6974
            } else {
6975
                $form->addElement(
6976
                    'select_ajax',
6977
                    'coach_username',
6978
                    get_lang('CoachName'),
6979
                    null,
6980
                    [
6981
                        'url' => api_get_path(WEB_AJAX_PATH) . 'session.ajax.php?a=search_general_coach',
6982
                        'width' => '100%',
6983
                    ]
6984
                );
6985
            }
6986
        }
6987
6988
        $form->addRule('coach_username', get_lang('ThisFieldIsRequired'), 'required');
6989
        $form->addHtml('<div id="ajax_list_coachs"></div>');
6990
6991
        $form->addButtonAdvancedSettings('advanced_params');
6992
        $form->addElement('html','<div id="advanced_params_options" style="display:none">');
6993
6994
        $form->addSelect(
6995
            'session_category',
6996
            get_lang('SessionCategory'),
6997
            $categoriesOptions,
6998
            array(
6999
                'id' => 'session_category',
7000
            )
7001
        );
7002
7003
        $form->addHtmlEditor(
7004
            'description',
7005
            get_lang('Description'),
7006
            false,
7007
            false,
7008
            array(
7009
                'ToolbarSet' => 'Minimal',
7010
            )
7011
        );
7012
7013
        $form->addElement('checkbox', 'show_description', null, get_lang('ShowDescription'));
7014
7015
        $visibilityGroup = array();
7016
        $visibilityGroup[] = $form->createElement('select', 'session_visibility', null, array(
7017
            SESSION_VISIBLE_READ_ONLY => get_lang('SessionReadOnly'),
7018
            SESSION_VISIBLE => get_lang('SessionAccessible'),
7019
            SESSION_INVISIBLE => api_ucfirst(get_lang('SessionNotAccessible')),
7020
        ));
7021
        $form->addGroup($visibilityGroup, 'visibility_group', get_lang('SessionVisibility'), null, false);
7022
7023
        $options = [
7024
            0 => get_lang('ByDuration'),
7025
            1 => get_lang('ByDates')
7026
        ];
7027
7028
        $form->addSelect('access', get_lang('Access'), $options, array(
7029
            'onchange' => 'accessSwitcher()',
7030
            'id' => 'access'
7031
        ));
7032
7033
        $form->addElement('html', '<div id="duration" style="display:none">');
7034
7035
        $form->addElement(
7036
            'number',
7037
            'duration',
7038
            array(
7039
                get_lang('SessionDurationTitle'),
7040
                get_lang('SessionDurationDescription'),
7041
            ),
7042
            array(
7043
                'maxlength' => 50,
7044
            )
7045
        );
7046
7047
        $form->addElement('html', '</div>');
7048
        $form->addElement('html', '<div id="date_fields" style="display:none">');
7049
7050
        // Dates
7051
        $form->addDateTimePicker(
7052
            'access_start_date',
7053
            array(get_lang('SessionStartDate'), get_lang('SessionStartDateComment')),
7054
            array('id' => 'access_start_date')
7055
        );
7056
7057
        $form->addDateTimePicker(
7058
            'access_end_date',
7059
            array(get_lang('SessionEndDate'), get_lang('SessionEndDateComment')),
7060
            array('id' => 'access_end_date')
7061
        );
7062
7063
        $form->addRule(
7064
            array('access_start_date', 'access_end_date'),
7065
            get_lang('StartDateMustBeBeforeTheEndDate'),
7066
            'compare_datetime_text',
7067
            '< allow_empty'
7068
        );
7069
7070
        $form->addDateTimePicker(
7071
            'display_start_date',
7072
            array(
7073
                get_lang('SessionDisplayStartDate'),
7074
                get_lang('SessionDisplayStartDateComment'),
7075
            ),
7076
            array('id' => 'display_start_date')
7077
        );
7078
        $form->addDateTimePicker(
7079
            'display_end_date',
7080
            array(
7081
                get_lang('SessionDisplayEndDate'),
7082
                get_lang('SessionDisplayEndDateComment'),
7083
            ),
7084
            array('id' => 'display_end_date')
7085
        );
7086
7087
        $form->addRule(
7088
            array('display_start_date', 'display_end_date'),
7089
            get_lang('StartDateMustBeBeforeTheEndDate'),
7090
            'compare_datetime_text',
7091
            '< allow_empty'
7092
        );
7093
7094
        $form->addDateTimePicker(
7095
            'coach_access_start_date',
7096
            array(
7097
                get_lang('SessionCoachStartDate'),
7098
                get_lang('SessionCoachStartDateComment'),
7099
            ),
7100
            array('id' => 'coach_access_start_date')
7101
        );
7102
7103
        $form->addDateTimePicker(
7104
            'coach_access_end_date',
7105
            array(
7106
                get_lang('SessionCoachEndDate'),
7107
                get_lang('SessionCoachEndDateComment'),
7108
            ),
7109
            array('id' => 'coach_access_end_date')
7110
        );
7111
7112
        $form->addRule(
7113
            array('coach_access_start_date', 'coach_access_end_date'),
7114
            get_lang('StartDateMustBeBeforeTheEndDate'),
7115
            'compare_datetime_text',
7116
            '< allow_empty'
7117
        );
7118
7119
        $form->addElement('html', '</div>');
7120
7121
        $form->addCheckBox(
7122
            'send_subscription_notification',
7123
            [
7124
                get_lang('SendSubscriptionNotification'),
7125
                get_lang('SendAnEmailWhenAUserBeingSubscribed')
7126
            ]
7127
        );
7128
7129
        // Extra fields
7130
        $extra_field = new ExtraFieldModel('session');
7131
        $extra = $extra_field->addElements($form, $sessionId);
7132
7133
        $form->addElement('html', '</div>');
7134
7135
        $js = $extra['jquery_ready_content'];
7136
7137
        return ['js' => $js];
7138
    }
7139
7140
    /**
7141
     * Gets the number of rows in the session table filtered through the given
7142
     * array of parameters
7143
     * @param array Array of options/filters/keys
7144
     * @return integer The number of rows, or false on wrong param
7145
     * @assert ('a') === false
7146
     */
7147
    static function get_count_admin_complete($options = array())
7148
    {
7149
        if (!is_array($options)) {
7150
            return false;
7151
        }
7152
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
7153
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7154
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7155
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7156
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7157
7158
        $where = 'WHERE 1 = 1 ';
7159
        $user_id = api_get_user_id();
7160
7161
        if (api_is_session_admin() &&
7162
            api_get_setting('allow_session_admins_to_see_all_sessions') == 'false'
7163
        ) {
7164
            $where.=" WHERE s.session_admin_id = $user_id ";
7165
        }
7166
7167 View Code Duplication
        if (!empty($options['where'])) {
7168
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
7169
            $options['where'] = str_replace("( session_active = '0' )", '1=1',  $options['where']);
7170
7171
            $options['where'] = str_replace(
7172
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
7173
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
7174
                , $options['where']
7175
            );
7176
7177
            $options['where'] = str_replace(
7178
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
7179
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
7180
                $options['where']
7181
            );
7182
7183
            if (!empty($options['extra'])) {
7184
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
7185
                $options['where'] = str_replace('AND', 'OR', $options['where']);
7186
7187
                foreach ($options['extra'] as $extra) {
7188
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
7189
                }
7190
            }
7191
            $where .= ' AND '.$options['where'];
7192
        }
7193
7194
        $today = api_get_utc_datetime();
7195
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.name,
7196
                        IF (
7197
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
7198
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
7199
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
7200
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
7201
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
7202
                        , 1, 0) as session_active
7203
                       FROM $tbl_session s
7204
                       LEFT JOIN  $tbl_session_category sc
7205
                       ON s.session_category_id = sc.id
7206
                       INNER JOIN $tbl_user u
7207
                       ON s.id_coach = u.user_id
7208
                       INNER JOIN $sessionCourseUserTable scu
7209
                       ON s.id = scu.session_id
7210
                       INNER JOIN $courseTable c
7211
                       ON c.id = scu.c_id
7212
                       $where ";
7213
7214
        if (api_is_multiple_url_enabled()) {
7215
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7216
            $access_url_id = api_get_current_access_url_id();
7217
            if ($access_url_id != -1) {
7218
                $where.= " AND ar.access_url_id = $access_url_id ";
7219
7220
                $query_rows = "SELECT count(*) as total_rows
7221
                               FROM $tbl_session s
7222
                               LEFT JOIN  $tbl_session_category sc
7223
                               ON s.session_category_id = sc.id
7224
                               INNER JOIN $tbl_user u
7225
                               ON s.id_coach = u.user_id
7226
                               INNER JOIN $table_access_url_rel_session ar
7227
                               ON ar.session_id = s.id $where ";
7228
            }
7229
        }
7230
7231
        $result = Database::query($query_rows);
7232
        $num = 0;
7233
        if (Database::num_rows($result)) {
7234
            $rows = Database::fetch_array($result);
7235
            $num = $rows['total_rows'];
7236
        }
7237
7238
        return $num;
7239
    }
7240
7241
    /**
7242
     * @param string $list_type
7243
     * @return array
7244
     */
7245
    public static function getGridColumns($list_type = 'simple')
7246
    {
7247
        // Column config
7248
        $operators = array('cn', 'nc');
7249
        $date_operators = array('gt', 'ge', 'lt', 'le');
7250
7251
        switch ($list_type) {
7252
            case 'simple':
7253
                $columns = array(
7254
                    get_lang('Name'),
7255
                    get_lang('Category'),
7256
                    get_lang('SessionDisplayStartDate'),
7257
                    get_lang('SessionDisplayEndDate'),
7258
                    //get_lang('Coach'),
7259
                    //get_lang('Status'),
7260
                    //get_lang('CourseTitle'),
7261
                    get_lang('Visibility'),
7262
                );
7263
                $column_model = array (
7264
                    array('name'=>'name', 'index'=>'s.name', 'width'=>'160',  'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
7265
                    array('name'=>'category_name', 'index'=>'category_name', 'width'=>'40',  'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
7266
                    array('name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'50',   'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_today', 'sopt' => $date_operators)),
7267
                    array('name'=>'display_end_date', 'index'=>'display_end_date', 'width'=>'50',   'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_one_month', 'sopt' => $date_operators)),
7268
                    array('name'=>'visibility', 'index'=>'visibility',      'width'=>'40',   'align'=>'left', 'search' => 'false'),
7269
                );
7270
                break;
7271
            case 'complete':
7272
                $columns = array(
7273
                    get_lang('Name'),
7274
                    get_lang('SessionDisplayStartDate'),
7275
                    get_lang('SessionDisplayEndDate'),
7276
                    get_lang('Coach'),
7277
                    get_lang('Status'),
7278
                    get_lang('Visibility'),
7279
                    get_lang('CourseTitle'),
7280
                );
7281
                $column_model = array (
7282
                    array('name'=>'name', 'index'=>'s.name', 'width'=>'200',  'align'=>'left', 'search' => 'true', 'searchoptions' => array('sopt' => $operators)),
7283
                    array('name'=>'display_start_date', 'index'=>'display_start_date', 'width'=>'70',   'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_today', 'sopt' => $date_operators)),
7284
                    array('name'=>'display_end_date', 'index'=>'display_end_date', 'width'=>'70',   'align'=>'left', 'search' => 'true', 'searchoptions' => array('dataInit' => 'date_pick_one_month', 'sopt' => $date_operators)),
7285
                    array('name'=>'coach_name', 'index'=>'coach_name',     'width'=>'70',   'align'=>'left', 'search' => 'false', 'searchoptions' => array('sopt' => $operators)),
7286
                    array('name'=>'session_active', 'index'=>'session_active', 'width'=>'25',   'align'=>'left', 'search' => 'true', 'stype'=>'select',
7287
                        // for the bottom bar
7288
                        'searchoptions' => array(
7289
                            'defaultValue'  => '1',
7290
                            'value'         => '1:'.get_lang('Active').';0:'.get_lang('Inactive')),
7291
                        // for the top bar
7292
                        'editoptions' => array('value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang('Inactive')),
7293
                    ),
7294
                    array('name'=>'visibility',     'index'=>'visibility',      'width'=>'40',   'align'=>'left', 'search' => 'false'),
7295
                    array('name'=>'course_title',    'index'=>'course_title',   'width'=>'50',   'hidden' => 'true', 'search' => 'true', 'searchoptions' => array('searchhidden' =>'true','sopt' => $operators)),
7296
                );
7297
                break;
7298
        }
7299
7300
        // Inject extra session fields
7301
        $session_field = new ExtraFieldModel('session');
7302
        $rules = $session_field->getRules($columns, $column_model);
7303
7304
        $column_model[] = array('name'=>'actions', 'index'=>'actions', 'width'=>'80',  'align'=>'left','formatter'=>'action_formatter','sortable'=>'false', 'search' => 'false');
7305
        $columns[] = get_lang('Actions');
7306
7307
        foreach ($column_model as $col_model) {
7308
            $simple_column_name[] = $col_model['name'];
7309
        }
7310
7311
        $return_array =  array(
7312
            'columns' => $columns,
7313
            'column_model' => $column_model,
7314
            'rules' => $rules,
7315
            'simple_column_name' => $simple_column_name,
7316
        );
7317
7318
        return $return_array;
7319
    }
7320
7321
    /**
7322
     * Converts all dates sent through the param array (given form) to correct dates with timezones
7323
     * @param array The dates The same array, with times converted
7324
     * @param boolean $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
7325
     * @return array The same array, with times converted
7326
     */
7327
    static function convert_dates_to_local($params, $applyFormat = false)
7328
    {
7329
        if (!is_array($params)) {
7330
            return false;
7331
        }
7332
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
7333
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
7334
7335
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
7336
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
7337
7338
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
7339
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
7340
7341
        if ($applyFormat) {
7342 View Code Duplication
            if (isset($params['display_start_date'])) {
7343
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
7344
            }
7345
7346 View Code Duplication
            if (isset($params['display_end_date'])) {
7347
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
7348
            }
7349
7350 View Code Duplication
            if (isset($params['access_start_date'])) {
7351
                $params[''] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
7352
            }
7353
7354 View Code Duplication
            if (isset($params['access_end_date'])) {
7355
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
7356
            }
7357
7358 View Code Duplication
            if (isset($params['coach_access_start_date'])) {
7359
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
7360
            }
7361
7362 View Code Duplication
            if (isset($params['coach_access_end_date'])) {
7363
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
7364
            }
7365
        }
7366
7367
        return $params;
7368
    }
7369
7370
    /**
7371
     * Gets the admin session list callback of the session/session_list.php
7372
     * page with all user/details in the right fomat
7373
     * @param array
7374
     * @result array Array of rows results
7375
     * @asset ('a') === false
7376
     */
7377
    public static function get_sessions_admin_complete($options = array())
7378
    {
7379
        if (!is_array($options)) {
7380
            return false;
7381
        }
7382
7383
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
7384
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7385
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7386
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7387
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
7388
7389
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7390
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7391
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
7392
7393
        $where = 'WHERE 1 = 1 ';
7394
        $user_id = api_get_user_id();
7395
7396 View Code Duplication
        if (!api_is_platform_admin()) {
7397
            if (api_is_session_admin() &&
7398
                api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
7399
            ) {
7400
                $where.=" AND s.session_admin_id = $user_id ";
7401
            }
7402
        }
7403
7404
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
7405
        if (api_is_western_name_order()) {
7406
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
7407
        }
7408
7409
        $today = api_get_utc_datetime();
7410
        $inject_extra_fields = null;
7411
        $extra_fields = array();
7412
        $extra_fields_info = array();
7413
7414
        //for now only sessions
7415
        $extra_field = new ExtraFieldModel('session');
7416
        $double_fields = array();
7417
        $extra_field_option = new ExtraFieldOption('session');
7418
7419
        if (isset($options['extra'])) {
7420
            $extra_fields = $options['extra'];
7421
            if (!empty($extra_fields)) {
7422
                foreach ($extra_fields as $extra) {
7423
                    $inject_extra_fields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
7424 View Code Duplication
                    if (isset($extra_fields_info[$extra['id']])) {
7425
                        $info = $extra_fields_info[$extra['id']];
7426
                    } else {
7427
                        $info = $extra_field->get($extra['id']);
7428
                        $extra_fields_info[$extra['id']] = $info;
7429
                    }
7430
7431
                    if ($info['field_type'] == ExtraField::FIELD_TYPE_DOUBLE_SELECT) {
7432
                        $double_fields[$info['id']] = $info;
7433
                    }
7434
                }
7435
            }
7436
        }
7437
7438
        $options_by_double = array();
7439 View Code Duplication
        foreach ($double_fields as $double) {
7440
            $my_options = $extra_field_option->get_field_options_by_field(
7441
                $double['id'],
7442
                true
7443
            );
7444
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
7445
        }
7446
7447
        //sc.name as category_name,
7448
        $select = "
7449
                SELECT * FROM (
7450
                    SELECT DISTINCT
7451
                         IF (
7452
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
7453
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
7454
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
7455
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
7456
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
7457
                        , 1, 0) as session_active,
7458
                s.name,
7459
                s.nbr_courses,
7460
                s.nbr_users,
7461
                s.display_start_date,
7462
                s.display_end_date,
7463
                $coach_name,
7464
                access_start_date,
7465
                access_end_date,
7466
                s.visibility,
7467
                u.user_id,
7468
                $inject_extra_fields
7469
                c.title as course_title,
7470
                s.id ";
7471
7472 View Code Duplication
        if (!empty($options['where'])) {
7473
            if (!empty($options['extra'])) {
7474
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
7475
                $options['where'] = str_replace('AND', 'OR', $options['where']);
7476
                foreach ($options['extra'] as $extra) {
7477
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
7478
                }
7479
            }
7480
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
7481
7482
            $options['where'] = str_replace("( session_active = '0' )", '1=1',  $options['where']);
7483
7484
            $options['where'] = str_replace(
7485
                array("AND session_active = '1'  )", " AND (  session_active = '1'  )"),
7486
                array(') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 " )
7487
                , $options['where']
7488
            );
7489
7490
            $options['where'] = str_replace(
7491
                array("AND session_active = '0'  )", " AND (  session_active = '0'  )"),
7492
                array(') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "),
7493
                $options['where']
7494
            );
7495
7496
7497
            $where .= ' AND '.$options['where'];
7498
        }
7499
7500
        if (!empty($options['limit'])) {
7501
            $where .= " LIMIT ".$options['limit'];
7502
        }
7503
        $query = "$select FROM $tbl_session s
7504
                    LEFT JOIN $tbl_session_field_values fv
7505
                    ON (fv.item_id = s.id)
7506
                    LEFT JOIN $extraFieldTable f
7507
                    ON f.id = fv.field_id
7508
                    LEFT JOIN $tbl_session_field_options fvo
7509
                    ON (fv.field_id = fvo.field_id)
7510
                    LEFT JOIN $tbl_session_rel_course src
7511
                    ON (src.session_id = s.id)
7512
                    LEFT JOIN $tbl_course c
7513
                    ON (src.c_id = c.id)
7514
                    LEFT JOIN $tbl_session_category sc
7515
                    ON (s.session_category_id = sc.id)
7516
                    INNER JOIN $tbl_user u
7517
                    ON (s.id_coach = u.user_id) ".
7518
            $where;
7519
7520 View Code Duplication
        if (api_is_multiple_url_enabled()) {
7521
            $table_access_url_rel_session= Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7522
            $access_url_id = api_get_current_access_url_id();
7523
            if ($access_url_id != -1) {
7524
                $where.= " AND ar.access_url_id = $access_url_id ";
7525
                $query = "$select
7526
                    FROM $tbl_session s
7527
                    LEFT JOIN $tbl_session_field_values fv ON (fv.session_id = s.id)
7528
                    LEFT JOIN $tbl_session_field_options fvo ON (fv.field_id = fvo.field_id)
7529
                    LEFT JOIN $tbl_session_rel_course src ON (src.id_session = s.id)
7530
                    LEFT JOIN $tbl_course c ON (src.c_id = c.id)
7531
                    LEFT JOIN $tbl_session_category sc ON (s.session_category_id = sc.id)
7532
                    INNER JOIN $tbl_user u ON (s.id_coach = u.user_id)
7533
                    INNER JOIN $table_access_url_rel_session ar ON (ar.session_id = s.id)
7534
                    $where";
7535
            }
7536
        }
7537
7538
        $query .= ") AS session_table";
7539
7540
        if (!empty($options['order'])) {
7541
            $query .= " ORDER BY ".$options['order'];
7542
        }
7543
7544
        $result = Database::query($query);
7545
        $formatted_sessions = array();
7546
7547
        if (Database::num_rows($result)) {
7548
            $sessions   = Database::store_result($result, 'ASSOC');
7549
            foreach ($sessions as $session) {
7550
                $session_id = $session['id'];
7551
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
7552
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
7553 View Code Duplication
                if ($session['session_active'] == 1) {
7554
                    $session['session_active'] = Display::return_icon('accept.png', get_lang('Active'), array(), ICON_SIZE_SMALL);
7555
                } else {
7556
                    $session['session_active'] = Display::return_icon('error.png', get_lang('Inactive'), array(), ICON_SIZE_SMALL);
7557
                }
7558
7559
                $session = self::convert_dates_to_local($session);
7560
7561 View Code Duplication
                switch ($session['visibility']) {
7562
                    case SESSION_VISIBLE_READ_ONLY: //1
7563
                        $session['visibility'] =  get_lang('ReadOnly');
7564
                        break;
7565
                    case SESSION_VISIBLE:           //2
7566
                    case SESSION_AVAILABLE:         //4
7567
                        $session['visibility'] =  get_lang('Visible');
7568
                        break;
7569
                    case SESSION_INVISIBLE:         //3
7570
                        $session['visibility'] =  api_ucfirst(get_lang('Invisible'));
7571
                        break;
7572
                }
7573
7574
                // Cleaning double selects
7575 View Code Duplication
                foreach ($session as $key => &$value) {
0 ignored issues
show
Bug introduced by
The expression $session of type false|array<string,null|...d_date":"string|null"}> 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...
7576
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
7577
                        $options = explode('::', $value);
7578
                    }
7579
                    $original_key = $key;
7580
7581
                    if (strpos($key, '_second') === false) {
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...
7582
                    } else {
7583
                        $key = str_replace('_second', '', $key);
7584
                    }
7585
7586
                    if (isset($options_by_double[$key])) {
7587
                        if (isset($options[0])) {
7588
                            if (isset($options_by_double[$key][$options[0]])) {
7589
                                if (strpos($original_key, '_second') === false) {
7590
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
7591
                                } else {
7592
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
7593
                                }
7594
                            }
7595
                        }
7596
                    }
7597
                }
7598
7599
                // Magic filter
7600
                if (isset($formatted_sessions[$session_id])) {
7601
                    $formatted_sessions[$session_id] = self::compareArraysToMerge($formatted_sessions[$session_id], $session);
0 ignored issues
show
Security Bug introduced by
It seems like $session defined by self::convert_dates_to_local($session) on line 7559 can also be of type false; however, SessionManager::compareArraysToMerge() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
7602
                } else {
7603
                    $formatted_sessions[$session_id] = $session;
7604
                }
7605
            }
7606
        }
7607
7608
        return $formatted_sessions;
7609
    }
7610
7611
    /**
7612
     * Compare two arrays
7613
     * @param array $array1
7614
     * @param array $array2
7615
     *
7616
     * @return array
7617
     */
7618
    static function compareArraysToMerge($array1, $array2)
7619
    {
7620
        if (empty($array2)) {
7621
            return $array1;
7622
        }
7623
        foreach ($array1 as $key => $item) {
7624
            if (!isset($array1[$key])) {
7625
                //My string is empty try the other one
7626
                if (isset($array2[$key]) && !empty($array2[$key])) {
7627
                    $array1[$key] = $array2[$key];
7628
                }
7629
            }
7630
        }
7631
        return $array1;
7632
    }
7633
7634
    /**
7635
     * Get link to the admin page for this session
7636
     * @param   int $id Session ID
7637
     * @return mixed    URL to the admin page to manage the session, or false on error
7638
     */
7639
    public static function getAdminPath($id)
7640
    {
7641
        $id = intval($id);
7642
        $session = self::fetch($id);
7643
        if (empty($session)) {
7644
            return false;
7645
        }
7646
        return api_get_path(WEB_CODE_PATH) . 'session/resume_session.php?id_session=' . $id;
7647
    }
7648
7649
    /**
7650
     * Get link to the user page for this session.
7651
     * If a course is provided, build the link to the course
7652
     * @param   int $id Session ID
7653
     * @param   int $courseId Course ID (optional) in case the link has to send straight to the course
7654
     * @return mixed    URL to the page to use the session, or false on error
7655
     */
7656
    public static function getPath($id, $courseId = 0)
7657
    {
7658
        $id = intval($id);
7659
        $session = self::fetch($id);
7660
        if (empty($session)) {
7661
            return false;
7662
        }
7663
        if (empty($courseId)) {
7664
            return api_get_path(WEB_CODE_PATH) . 'session/index.php?session_id=' . $id;
7665
        } else {
7666
            $courseInfo = api_get_course_info_by_id($courseId);
7667
            if ($courseInfo) {
7668
                return $courseInfo['course_public_url'].'?id_session='.$id;
7669
            }
7670
        }
7671
7672
        return false;
7673
    }
7674
7675
    /**
7676
     * Return an associative array 'id_course' => [id_session1, id_session2...]
7677
     * where course id_course is in sessions id_session1, id_session2
7678
     * for course where user is coach
7679
     * i.e. coach for the course or
7680
     * main coach for a session the course is in
7681
     * for a session category (or woth no session category if empty)
7682
     *
7683
     * @param $userId
7684
     *
7685
     * @return array
7686
     */
7687
    public static function getSessionCourseForUser($userId)
7688
    {
7689
        // list of COURSES where user is COURSE session coach
7690
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
7691
7692
        // list of courses where user is MAIN session coach
7693
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
7694
7695
        // merge these 2 array
7696
        $listResCourseSession = $listCourseCourseCoachSession;
7697
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
7698
            if (isset($listResCourseSession[$courseId2])) {
7699
                // if sessionId array exists for this course
7700
                // same courseId, merge the list of session
7701
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
7702
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
7703
                        $listResCourseSession[$courseId2][] = $sessionId2;
7704
                    }
7705
                }
7706
            } else {
7707
                $listResCourseSession[$courseId2] = $listSessionId2;
7708
            }
7709
        }
7710
7711
        return $listResCourseSession;
7712
    }
7713
7714
    /**
7715
     * Return an associative array 'id_course' => [id_session1, id_session2...]
7716
     * where course id_course is in sessions id_session1, id_session2
7717
     * @param $userId
7718
     *
7719
     * @return array
7720
     */
7721
    public static function getCoursesForCourseSessionCoach($userId)
7722
    {
7723
        $listResCourseSession = array();
7724
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
7725
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7726
7727
        $sql = "SELECT session_id, c_id, c.id
7728
                FROM $tblSessionRelCourseRelUser srcru
7729
                LEFT JOIN $tblCourse c
7730
                ON c.id = srcru.c_id
7731
                WHERE
7732
                    srcru.user_id =".intval($userId)." AND
7733
                    srcru.status = 2";
7734
7735
        $res = Database::query($sql);
7736
7737
        while ($data = Database::fetch_assoc($res)) {
7738
            if (api_get_session_visibility($data['session_id'])) {
7739
                if (!isset($listResCourseSession[$data['id']])) {
7740
                    $listResCourseSession[$data['id']] = array();
7741
                }
7742
                $listResCourseSession[$data['id']][] = $data['session_id'];
7743
            }
7744
        }
7745
7746
        return $listResCourseSession;
7747
    }
7748
7749
    /**
7750
     * Return an associative array 'id_course' => [id_session1, id_session2...]
7751
     * where course id_course is in sessions id_session1, id_session2
7752
     * @param $userId
7753
     *
7754
     * @return array
7755
     */
7756
    public static function getCoursesForMainSessionCoach($userId)
7757
    {
7758
        $listResCourseSession = array();
7759
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
7760
7761
        // list of SESSION where user is session coach
7762
        $sql = "SELECT id FROM $tblSession
7763
                WHERE id_coach = ".intval($userId);
7764
        $res = Database::query($sql);
7765
7766
        while ($data = Database::fetch_assoc($res)) {
7767
            $sessionId = $data['id'];
7768
            $listCoursesInSession = self::getCoursesInSession($sessionId);
7769
            foreach ($listCoursesInSession as $i => $courseId) {
7770
                if (api_get_session_visibility($sessionId)) {
7771
                    if (!isset($listResCourseSession[$courseId])) {
7772
                        $listResCourseSession[$courseId] = array();
7773
                    }
7774
                    $listResCourseSession[$courseId][] = $sessionId;
7775
                }
7776
            }
7777
        }
7778
7779
        return $listResCourseSession;
7780
    }
7781
7782
    /**
7783
     * Return an array of course_id used in session $sessionId
7784
     * @param $sessionId
7785
     *
7786
     * @return array
7787
     */
7788 View Code Duplication
    public static function getCoursesInSession($sessionId)
7789
    {
7790
        if (empty($sessionId)) {
7791
            return [];
7792
        }
7793
7794
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7795
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
7796
7797
        // list of course in this session
7798
        $sql = "SELECT session_id, c.id
7799
                FROM $tblSessionRelCourse src
7800
                LEFT JOIN $tblCourse c
7801
                ON c.id = src.c_id
7802
                WHERE session_id = ".intval($sessionId);
7803
        $res = Database::query($sql);
7804
7805
        $listResultsCourseId = array();
7806
        while ($data = Database::fetch_assoc($res)) {
7807
            $listResultsCourseId[] = $data['id'];
7808
        }
7809
7810
        return $listResultsCourseId;
7811
    }
7812
7813
    /**
7814
     * Return an array of courses in session for user
7815
     * and for each courses the list of session that use this course for user
7816
     *
7817
     * [0] => array
7818
     *      userCatId
7819
     *      userCatTitle
7820
     *      courseInUserCatList
7821
     *          [0] => array
7822
     *              courseId
7823
     *              title
7824
     *              courseCode
7825
     *              sessionCatList
7826
     *                  [0] => array
7827
     *                      catSessionId
7828
     *                      catSessionName
7829
     *                      sessionList
7830
     *                          [0] => array
7831
     *                              sessionId
7832
     *                              sessionName
7833
     *
7834
     * @param $userId
7835
     *
7836
     * @return array
7837
     *
7838
     */
7839
    public static function getNamedSessionCourseForCoach($userId)
7840
    {
7841
        $listResults = array();
7842
        $listCourseSession = self::getSessionCourseForUser($userId);
7843
        foreach ($listCourseSession as $courseId => $listSessionId) {
7844
            // Course info
7845
            $courseInfo = api_get_course_info_by_id($courseId);
7846
            $listOneCourse = array();
7847
            $listOneCourse['courseId'] = $courseId;
7848
            $listOneCourse['title'] = $courseInfo['title'];
7849
            //$listOneCourse['courseCode'] = $courseInfo['code'];
7850
            $listOneCourse['course'] = $courseInfo;
7851
            $listOneCourse['sessionCatList'] = array();
7852
            $listCat = array();
7853
            foreach ($listSessionId as $i => $sessionId) {
7854
                // here we got all session for this course
7855
                // lets check there session categories
7856
                $sessionInfo = SessionManager::fetch($sessionId);
7857
                $catId = $sessionInfo['session_category_id'];
7858
                if (!isset($listCat[$catId])) {
7859
                    $listCatInfo = self::get_session_category($catId);
7860
                    $listCat[$catId] = array();
7861
                    $listCat[$catId]['catSessionId'] = $catId;
7862
                    $listCat[$catId]['catSessionName'] = $listCatInfo['name'];
7863
                    $listCat[$catId]['sessionList'] = array();
7864
                }
7865
                $listSessionInfo = SessionManager::fetch($sessionId);
7866
                $listSessionIdName = array(
7867
                    "sessionId" => $sessionId,
7868
                    "sessionName" => $listSessionInfo['name'],
7869
                );
7870
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
7871
            }
7872
            // sort $listCat by catSessionName
7873
            usort($listCat, 'self::compareBySessionName');
7874
            // in each catSession sort sessionList by sessionName
7875
            foreach($listCat as $i => $listCatSessionInfo) {
7876
                $listSessionList = $listCatSessionInfo['sessionList'];
7877
                usort($listSessionList, 'self::compareCatSessionInfo');
7878
                $listCat[$i]['sessionList'] = $listSessionList;
7879
            }
7880
7881
            $listOneCourse['sessionCatList'] = $listCat;
7882
7883
            // user course category
7884
            list($userCatId, $userCatTitle) = CourseManager::getUserCourseCategoryForCourse(
7885
                $userId,
7886
                $courseId
7887
            );
7888
7889
            $userCatId = intval($userCatId);
7890
            $listResults[$userCatId]['courseInUserCategoryId'] =  $userCatId;
7891
            $listResults[$userCatId]['courseInUserCategoryTitle'] =  $userCatTitle;
7892
            $listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
7893
        }
7894
7895
        // sort by user course cat
7896
        uasort($listResults, 'self::compareByUserCourseCat');
7897
7898
        // sort by course title
7899
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
7900
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
7901
            uasort($courseInUserCatList, 'self::compareByCourse');
7902
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
7903
        }
7904
7905
        return $listResults;
7906
    }
7907
7908
    /**
7909
     * @param array $listA
7910
     * @param array $listB
7911
     * @return int
7912
     */
7913 View Code Duplication
    private static function compareCatSessionInfo($listA, $listB)
7914
    {
7915
        if ($listA['sessionName'] == $listB['sessionName']) {
7916
            return 0;
7917
        } else if($listA['sessionName'] > $listB['sessionName']) {
7918
            return 1;
7919
        } else {
7920
            return -1;
7921
        }
7922
    }
7923
7924
    /**
7925
     * @param array $listA
7926
     * @param array $listB
7927
     * @return int
7928
     */
7929
    private static function compareBySessionName($listA, $listB)
7930
    {
7931
        if ($listB['catSessionName'] == '') {
7932
            return -1;
7933
        } else if ($listA['catSessionName'] == '') {
7934
            return 1;
7935
        } else if ($listA['catSessionName'] == $listB['catSessionName']) {
7936
            return 0;
7937
        } else if($listA['catSessionName'] > $listB['catSessionName']) {
7938
            return 1;
7939
        } else {
7940
            return -1;
7941
        }
7942
    }
7943
7944
    /**
7945
     * @param array $listA
7946
     * @param array $listB
7947
     * @return int
7948
     */
7949 View Code Duplication
    private static function compareByUserCourseCat($listA, $listB)
7950
    {
7951
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
7952
            return 0;
7953
        } else if($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
7954
            return 1;
7955
        } else {
7956
            return -1;
7957
        }
7958
    }
7959
7960
    /**
7961
     * @param array $listA
7962
     * @param array $listB
7963
     * @return int
7964
     */
7965 View Code Duplication
    private static function compareByCourse($listA, $listB)
7966
    {
7967
        if ($listA['title'] == $listB['title']) {
7968
            return 0;
7969
        } else if($listA['title'] > $listB['title']) {
7970
            return 1;
7971
        } else {
7972
            return -1;
7973
        }
7974
    }
7975
7976
    /**
7977
     * Return HTML code for displaying session_course_for_coach
7978
     * @param $userId
7979
     * @return string
7980
     */
7981
    public static function getHtmlNamedSessionCourseForCoach($userId)
7982
    {
7983
        $htmlRes = '';
7984
7985
        $listInfo = self::getNamedSessionCourseForCoach($userId);
7986
        foreach ($listInfo as $i => $listCoursesInfo) {
7987
            $courseInfo = $listCoursesInfo['course'];
7988
            $courseCode = $listCoursesInfo['course']['code'];
7989
7990
            $listParamsCourse = array();
7991
            $listParamsCourse['icon'] = '<div style="float:left">
7992
                <input style="border:none;" type="button" onclick="$(\'#course-'.$courseCode.'\').toggle(\'fast\')" value="+" /></div>'.
7993
                Display::return_icon('blackboard.png', $courseInfo['title'], array(), ICON_SIZE_LARGE);
7994
            $listParamsCourse['link'] = '';
7995
            $listParamsCourse['title'] = Display::tag(
7996
                'a',
7997
                $courseInfo['title'],
7998
                array('href' => $listParamsCourse['link'])
7999
            );
8000
            $htmlCourse = '<div class="well" style="border-color:#27587D">'.
8001
                CourseManager::course_item_html($listParamsCourse, true);
8002
            // for each category of session
8003
            $htmlCatSessions = '';
8004
            foreach ($listCoursesInfo['sessionCatList'] as $j => $listCatSessionsInfo) {
8005
                // we got an array of session categories
8006
                $catSessionId = $listCoursesInfo['sessionCatList'][$j]['catSessionId'];
8007
                $catSessionName = $listCoursesInfo['sessionCatList'][$j]['catSessionName'];
8008
8009
                $listParamsCatSession['icon'] = Display::return_icon('folder_blue.png', $catSessionName, array(), ICON_SIZE_LARGE);
8010
                $listParamsCatSession['link'] = '';
8011
                $listParamsCatSession['title'] = $catSessionName;
8012
8013
                $marginShift = 20;
8014
                if ($catSessionName != '') {
8015
                    $htmlCatSessions .= '<div style="margin-left:'.$marginShift.'px;">' .
8016
                        CourseManager::course_item_html($listParamsCatSession, true) . '</div>';
8017
                    $marginShift = 40;
8018
                }
8019
8020
                // for each sessions
8021
                $listCatSessionSessionList = $listCoursesInfo['sessionCatList'][$j]['sessionList'];
8022
                $htmlSession = '';
8023
                foreach ($listCatSessionSessionList as $k => $listSessionInfo) {
8024
                    // we got an array of session info
8025
                    $sessionId = $listSessionInfo['sessionId'];
8026
                    $sessionName = $listSessionInfo['sessionName'];
8027
8028
                    $listParamsSession['icon'] = Display::return_icon('blackboard_blue.png', $sessionName, array(), ICON_SIZE_LARGE);
8029
                    $listParamsSession['link'] = '';
8030
                    $linkToCourseSession = $courseInfo['course_public_url'].'?id_session='.$sessionId;
8031
                    $listParamsSession['title'] =
8032
                        $sessionName.'<div style="font-weight:normal; font-style:italic">
8033
                            <a href="'.$linkToCourseSession.'">'.get_lang('GoToCourseInsideSession').'</a>
8034
                            </div>';
8035
                    $htmlSession .= '<div style="margin-left:'.$marginShift.'px;">'.
8036
                        CourseManager::course_item_html($listParamsSession, true).'</div>';
8037
                }
8038
                $htmlCatSessions .= $htmlSession;
8039
            }
8040
            $htmlRes .= $htmlCourse.'<div style="display:none" id="course-'.$courseCode.'">'.$htmlCatSessions.'</div></div>';
8041
        }
8042
8043
        return $htmlRes;
8044
    }
8045
8046
    /**
8047
     * @param int $userId
8048
     * @param int $courseId
8049
     *
8050
     * @return array
8051
     */
8052 View Code Duplication
    public static function searchCourseInSessionsFromUser($userId, $courseId)
8053
    {
8054
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8055
        $userId = (int) $userId;
8056
        $courseId = (int) $courseId;
8057
        if (empty($userId) || empty($courseId)) {
8058
            return [];
8059
        }
8060
8061
        $sql = "SELECT * FROM $table 
8062
                WHERE c_id = $courseId AND user_id = $userId";
8063
        $result = Database::query($sql);
8064
8065
        return Database::store_result($result, 'ASSOC');
8066
    }
8067
}
8068